利用WebServices实现泛微OA周期待办任务提醒
项目背景
需要OA系统在特定时间点提醒一人或多人进行某项工作。
OA系统现在的周期待办在时间上有限制,只能实现按月、按天为周期进行触发;不能实现按多个月,比如每两个月或者每三个月触发一次,也不能实现按年进行触发。
实现思路
OA 泛微9.0
前期测试过,通过WebServices接口可以用程序实现流程的创建工作。
1、创建自动生成流程的WebServices
创建一个新的OA周期待办提醒流程模版,流程的关键信息包括(提醒标题、提醒人、提醒内容)。由这些关键信息创建一个OA周期待办提醒。
2、创建一个周期待办提醒列表
将待办事宜做成一个可维护的列表,列表中包含前面提到的提醒关键信息(提醒标题、提醒人、提醒内容)以及时间节点、定期推送周期、任务状态。
3、创建操作系统的定时任务
每天运行的定时任务,检测当前的日期和待办提醒的列表的时间节点日期是否一致,如果一直就启用WebServices创建流程,推送提醒。
4、存储过程实现时间节点的迭代
时间节点的迭代是指要实现待办列表中的时间节点,在下一个周期日能够顺利被触发。
比如提醒列表中某一天提醒的时间节点是2022-10-22,定期推送周期为2个月,存储过程要实现在2022-12-22日当前运行定时任务是可以推送这条提醒。
项目实现
一、WebServices创建OA流程
1、获取WebService客户端程序
-
登录OA
-
打开http://192.168.0.72:8080/services
-
点击wsdl打开wsdl文件并在浏览器中获取的wsdl-url
http://192.168.0.72:8080/services/WorkflowService?wsdl
-
由wsdl文件或wsdl-web地址获取客户端开发代码
webservice通过wsdl生成客户端代码的几种实现方式
wsdl2java -encoding utf-8 -d src http://192.168.0.72:8080/services/WorkflowService?wsdl
z这种方式是用的 Apache-cxf的wsdl2java方式 在上面的几种实现方式中有详细的介绍
-
关于cxf生成客户端代码中的JAXBElement
wsdl2java -b “1.txt” -encoding utf-8 -d src http://192.168.0.45:8080/services/WorkflowService?wsdl
1.txt
<jaxb:bindings version="2.1" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <jaxb:globalBindings generateElementProperty="false"/> </jaxb:bindings>
2、创建生成OA流程的java文件
将得到的Webservices客户端代码引入到新创建的Java项目中(如WebServices)
- 创建用于数据库连接的com.util. DBconn.java
package com.util;
import java.io.InputStream;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import weaver.worktask.timedtask.DoCreateRequest123;
/**
* @Description: jdbc连接类
* @Author :xiacong
* @Date 2022-12-19 16:06
*/
public class DBconn {
//--mysql 连接参数
// static String url="jdbc:mysql://localhost:3306/bluesoft?useUnicode=true&characterEncoding=utf8";
// static String username = "root";
// static String password = "root";
//--sqlserver 连接参数
// static String url="jdbc:sqlserver://192.168.1.127:1433;DatabaseName=bluesoft";
// static String username = "sa";
// static String password = "xia123";
// 表示定义数据库的用户名
private static String USERNAME ;
// 定义数据库的密码
private static String PASSWORD;
// 定义数据库的驱动信息
private static String DRIVER;
// 定义访问数据库的地址
private static String URL;
static Connection conn = null;
static ResultSet rs = null;
static PreparedStatement ps = null;
static{
//加载数据库配置信息,并给相关的属性赋值
loadConfig();
}
/**
* 加载数据库配置信息,并给相关的属性赋值
*/
public static void loadConfig() {
try {
InputStream inStream = DBconn.class
.getResourceAsStream("/jdbc.properties");
Properties prop = new Properties();
prop.load(inStream);
USERNAME = prop.getProperty("jdbc.username");
PASSWORD = prop.getProperty("jdbc.password");
DRIVER= prop.getProperty("jdbc.driver");
URL = prop.getProperty("jdbc.url");
} catch (Exception e) {
throw new RuntimeException("读取数据库配置文件异常!", e);
}
}
//初始化,连接数据库
public static void init() {
try {
//--mysql
//Class.forName("com.mysql.jdbc.Driver");
//--sqlserver
Class.forName(DRIVER);
conn = DriverManager.getConnection(URL,USERNAME,PASSWORD);
} catch (Exception e) {
System.out.println("初始化失败");
e.printStackTrace();
}
}
/**
* 增加删除修噶操作
* @param sql
* @return
*/
public static int addUPDel(String sql) {
int i = 0;
try {
PreparedStatement ps = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
i = ps.executeUpdate();
} catch (Exception e) {
System.out.println("sql数据库增删改异常");
e.printStackTrace();
}
return i;
}
public static ResultSet selectSql(String sql) {
try {
ps = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs = ps.executeQuery();
} catch (Exception e) {
// TODO: handle exception
System.out.println("sql数据库查询异常");
e.printStackTrace();
}
return rs;
}
/**
* 执行查询语句
* @param preparedSql
* @param param
* @return
*/
public static ResultSet executeQuery(String preparedSql, String[] param) {
try {
ps = conn.prepareStatement(preparedSql);
if (param != null) {
for (int i = 0; i < param.length; i++) {
ps.setString(i + 1, param[i]);
}
}
rs = ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
public static int executeUpdate(String preparedSql, String[] param) {
int num = 0;
try {
ps = conn.prepareStatement(preparedSql);
if (param != null) {
for (int i = 0; i < param.length; i++) {
ps.setString(i + 1, param[i]);
}
}
num = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
return num;
}
/**
* 调用存储过程 callProcedure("{call Prj_DZFP(?,?)}", paramList)
* @param proName
* @param params
* @return 结果集
* @throws SQLException
*/
public static CallableStatement callProcedure(String proName,List<?> params) throws SQLException{
int index = 1;
CallableStatement callableStatement = conn.prepareCall(proName);
if (params != null && !params.isEmpty()) {
for (int i = 0; i < params.size(); i++) {
callableStatement.setString(index++, params.get(i).toString());
}
}
callableStatement.registerOutParameter(params.size()+1, Types.NVARCHAR);
callableStatement.registerOutParameter(params.size()+2, Types.NVARCHAR);
return callableStatement;
}
public static void closeConn() {
try {
conn.close();
} catch (Exception e) {
// TODO: handle exception
System.out.println("sql数据库关闭异常");
e.printStackTrace();
}
}
// public static void main(String[] args) {
// DBconn.init();
// List<Object> paramList = new ArrayList<Object>();
// paramList.add("123");
// try {
//
// CallableStatement stmt = DBconn.callProcedure("{call pro_periodicremind(?,?,?)}", paramList);
//
// boolean hasMore = stmt.execute();
// while(true){
// if(hasMore){
// rs = stmt.getResultSet();
// while(rs.next()){
// DoCreateRequest123 doreq123 = new DoCreateRequest123();
// doreq123.execute1(rs.getString("rwmc"), rs.getString("txnr"), rs.getString("txr"));
// }
// }else{
// int count = stmt.getUpdateCount();
// if(count == -1){
// //当count为-1时则结果集为最后一条数据
// System.out.println("最后一条数据");
// break;
// }
// }
// hasMore = stmt.getMoreResults();
// }
// } catch (SQLException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// }
}
- 创建流程DoCreateRequest123.java
package weaver.worktask.timedtask;
import cn.com.weaver.services.webservices.WorkflowService;
import weaver.workflow.webservices.*;
/**
* @Description: create OA workflow
* @Author :xiacong
* @Date 2022-12-23 16:00
*/
public class DoCreateRequest123 {
// public static void main(String[] args) {
// try {
// String rwmc ="流程请求标题-周期代表任务提醒";
// String txnr = "这是被提醒的内容2-测试345";
// String btxr = "1994";
//
// DBconn.init();
// ResultSet rs = DBconn.selectSql("select rwmc,txnr,btxr from T_timedtask");
// while(rs.next()){
// rwmc = rs.getString("rwmc");
// txnr = rs.getString("txnr");
// btxr = rs.getString("btxr");
// new DoCreateRequest123().execute1(rwmc,txnr,btxr);
// }
//
// new DoCreateRequest123().execute1(rwmc,txnr,btxr);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
public void execute1(String rwmc,String txnr,String btxr){
ObjectFactory factory = new ObjectFactory();
WorkflowService service = new WorkflowService();
WorkflowRequestInfo workflowRequestInfo = new WorkflowRequestInfo();//工作流程请求信息
workflowRequestInfo.setCanView(true);//显示
workflowRequestInfo.setCanEdit(true);//可编辑
int userid = 1;
workflowRequestInfo.setRequestName(rwmc);
workflowRequestInfo.setRequestLevel("0");//请求重要级别 0:正常 1:重要 2:紧急
workflowRequestInfo.setCreatorId("1");//创建者ID 创建流程时为必输项
WorkflowBaseInfo workflowBaseInfo = new WorkflowBaseInfo();//工作流信息
workflowBaseInfo.setWorkflowId("328");//流程ID
workflowBaseInfo.setWorkflowName("周期待办任务提醒");//流程名称
// workflowBaseInfo.setWorkflowTypeId("1951");//流程类型id
workflowBaseInfo.setWorkflowTypeName("测试");//流程类型名称
workflowRequestInfo.setWorkflowBaseInfo(workflowBaseInfo);
//主表信息
WorkflowMainTableInfo workflowMainTableInfo = new WorkflowMainTableInfo();//主表
WorkflowRequestTableRecord[] workflowRequestTableRecord = new WorkflowRequestTableRecord[1];//主表字段只有一条记录
WorkflowRequestTableField[] WorkflowRequestTableField = new WorkflowRequestTableField[3];//主的4个字段
//---主表字段
WorkflowRequestTableField[0] = new WorkflowRequestTableField();
WorkflowRequestTableField[0].setFieldName("txcjr");
WorkflowRequestTableField[0].setFieldValue("1");
WorkflowRequestTableField[0].setView(true);
WorkflowRequestTableField[0].setEdit(true);
WorkflowRequestTableField[1] = new WorkflowRequestTableField();
WorkflowRequestTableField[1].setFieldName("txnr");
WorkflowRequestTableField[1].setFieldValue(txnr);
WorkflowRequestTableField[1].setView(true);
WorkflowRequestTableField[1].setEdit(true);
WorkflowRequestTableField[2]= new WorkflowRequestTableField();
WorkflowRequestTableField[2].setFieldName("btxr");//附件
//WorkflowRequestTableField[2].setFieldValue("http://www.dssun.com/templates/default/img/img1.png");
//WorkflowRequestTableField[2].setFieldValue("C:\\temp\\img1.png");
WorkflowRequestTableField[2].setFieldValue(btxr);
WorkflowRequestTableField[2].setView(true);
WorkflowRequestTableField[2].setEdit(true);
//
ArrayOfWorkflowRequestTableField arrayOfWorkflowRequestTableField = new ArrayOfWorkflowRequestTableField();
arrayOfWorkflowRequestTableField.getWorkflowRequestTableField().add(WorkflowRequestTableField[0]);
arrayOfWorkflowRequestTableField.getWorkflowRequestTableField().add(WorkflowRequestTableField[1]);
arrayOfWorkflowRequestTableField.getWorkflowRequestTableField().add(WorkflowRequestTableField[2]);
//--主表记录
workflowRequestTableRecord[0] = new WorkflowRequestTableRecord();
workflowRequestTableRecord[0].setWorkflowRequestTableFields(arrayOfWorkflowRequestTableField);
ArrayOfWorkflowRequestTableRecord arrayOfWorkflowRequestTableRecord = new ArrayOfWorkflowRequestTableRecord();
arrayOfWorkflowRequestTableRecord.getWorkflowRequestTableRecord().add(workflowRequestTableRecord[0]);
workflowMainTableInfo.setRequestRecords(arrayOfWorkflowRequestTableRecord);
workflowRequestInfo.setWorkflowMainTableInfo(workflowMainTableInfo);
String response = service.getWorkflowServiceHttpPort().doCreateWorkflowRequest(workflowRequestInfo,userid);
System.out.println("返回结果:"+response);
}
}
-
调用创建流程TimedTask.java
也是WebServices项目的主程序入口
package weaver.worktask.timedtask;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.util.*;
public class TimedTask {
ResultSet rs = null;
String rwmc = null;
String txnr = null;
String btxr = null;
private void timedtask(){
DBconn.init();
List<Object> paramList = new ArrayList<Object>();
paramList.add("123");
try {
CallableStatement stmt = DBconn.callProcedure("{call pro_periodicremind(?,?,?)}", paramList);
boolean hasMore = stmt.execute();
while(true){
if(hasMore){
rs = stmt.getResultSet();
while(rs.next()){
rwmc = rs.getString("rwmc");
txnr = rs.getString("txnr");
btxr = rs.getString("txr");
DoCreateRequest123 dorequest = new DoCreateRequest123();
dorequest.execute1(rwmc, txnr, btxr);
System.out.println("rwmc:"+rwmc+"txnr:"+txnr+"btxr:"+btxr);
}
}else{
int count = stmt.getUpdateCount();
if(count == -1){
//当count为-1时则结果集为最后一条数据
System.out.println("最后一条数据");
break;
}
}
hasMore = stmt.getMoreResults();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TimedTask tt = new TimedTask();
tt.timedtask();
}
}
3、将Webservices项目打包成可以执行Jar
MANIFEST.MF
Manifest-Version: 1.0
Class-Path: lib/sqljdbc4-2.0.jar
Main-Class: weaver.worktask.timedtask.TimedTask
把lib包放到导出的jar文件的同一目录
4、创建bat文件
D:
cd D:\webservices-OA\timedtask
java -jar OATimedTask.jar
二、创建周期待办提醒列表
OA-后台-流程引擎-路径管理 -运维台帐
三、创建操作系统的定时任务
在操作系统的“任务计划程序”中定义,设置成每天05:02运行bat文件,bat文件运行可执行jar包
四、存储过程实现时间节点迭代
在数据库中创建存储过程:pro_periodicremind.sql
-
定时推送周期
0 - 不建立周期推送
1- 3个月
2 - 半年(6个月)
3 - 年
4 - 5年
-
任务状态
0 - 启用
1 - 封存
ALTER procedure pro_periodicremind
@ids [int] , @flag [int] output, @msg varchar(4000) output
as
SET NOCOUNT ON
begin
create table #temp99(id int)
declare @cdate varchar(10)
set @cdate = convert(varchar(10),GETDATE(),120)
-------------游标处理
declare @ID int --接收游标值的变量
declare cur_ID cursor
for (select id from uf_dsPeriodicTask where rwzt = 0 and DATEDIFF(day, @cdate, sjjd) <=0)--创建游标列表
open cur_ID
fetch next from cur_ID into @ID
while @@FETCH_STATUS = 0
begin
--进行数据处理
declare @sjjd varchar(10),@dqtszq int
select @sjjd = sjjd,@dqtszq = dqtszq from uf_dsperiodicTask where id = @ID
while DATEDIFF(day, @cdate, @sjjd) <=0
begin
if DATEDIFF(day, @cdate, @sjjd) = 0 --时间节点 = 当前日期 保存记录ID且跳出循环
begin
insert into #temp99 values(@ID)
break;
end
else --时间节点 < 当前日期
begin
if @dqtszq = 0 --不建立周期推送的 跳出循环
break;
else
select @sjjd = case @dqtszq
when 1 then DATEADD(month, 3, @sjjd)
when 2 then DATEADD(month, 6, @sjjd)
when 3 then DATEADD(year, 1, @sjjd)
when 4 then DATEADD(year, 5, @sjjd) end
end
end
fetch next from cur_ID into @ID; --移动游标,将下一个值赋给接收游标值得变量
end
CLOSE cur_ID; --关闭游标
DEALLOCATE cur_ID; --释放游标
select id,rwmc,txnr,txr,sjjd,dqtszq,rwzt from uf_dsperiodicTask where id in (select id from #temp99);
set @flag = 0 set @msg = 'OK!'
end