泛微E9二次开辟资料完备总结版

打印 上一主题 下一主题

主题 703|帖子 703|积分 2109

1、EC9体系阐明

如需本地版本,请移步下载资源
https://download.csdn.net/download/u010048119/86444408?spm=1001.2014.3001.5503
1.1、体系焦点框架




  • 后端增长了分层、AOP、IOC、interceptor的支持
  • 新架构要求service和Command层必须面向接口编程, 同时通过IOC和命令委托方式举行各层的解耦
  • 新架构还提供全局interceptor和局部interceptor、SERVICE-AOP、COMMAND-AOP的支持,可以举行比如日志记录、声明性事件、安全性,和缓存等等功能的实现和无侵入二开

1.2、体系目次结构

WEAVER
​ ecology
​ classbean 存放编译后的CLASS文件
​ WEB-INF
​ lib 体系依靠Jar文件目次
​ prop 体系配置文件存放
2、环境搭建

2.1、Ecology测试环境搭建

步骤1:从服务器上拷贝WEAVER/ecology代码
从服务器拷贝ecology相干代码到本地,目次服务器上文件如下图,需拷贝ecology、Resin/Resin4,假如本机已安装JDK则可以不需拷贝JDK

步骤2:代码复制至本地D:/WEAVER 文件夹下
步骤3:备份ecology数据库,还原到本地或测试数据库
请一定要记得修改数据库配置文件中的数据库配置,否则搭建的开辟环境也是连接到正式库,那就很有可能会导致正式库中的数据出错
配置文件:D:/weaver/ecology/WEB-INF/prop/weaver.properties
SQLServer
  1. DriverClasses = com.microsoft.sqlserver.jdbc.SQLServerDriver
  2. ecology.url = jdbc:sqlserver://192.168.4.246:1433;DatabaseName=ecology60
  3. ecology.user = sa
  4. ecology.password = ecology
复制代码
Oracle
  1. DriverClasses = oracle.jdbc.OracleDriver
  2. ecology.url = jdbc:oracle:thin:@192.168.4.238:1521:ecology
  3. ecology.user = nmsy
  4. ecology.password = ecology
复制代码
2.2、后端开辟环境搭建

https://e-cloudstore.com/doc.html?appId=c6a9ae6e47b74d4da04c935ed51d177a
2.3、ecode使用阐明

https://e-cloudstore.com/doc.html
2.4、e9技能站

https://e-cloudstore.com/e9/index2.html
2.5、后端代码目次结构







3、数据存储

3.1、流程数据存储

常用流程相干存储阐明,详情见表结构阐明文档
数据库表名中文阐明workflow_base流程根本信息workflow_bill流程表单信息workflow_billfield表单字段信息workflow_nodebase节点信息workflow_currentoperator请求节点操作人workflow_requestlog请求签字意见workflow_nownode请求当前节点workflow_selectitem下拉框信息 3.2、人力资源相干数据存储

以下只枚举一些常用表结构,更多表结构参考表建构文档。
表名阐明HrmResource人力资源根本信息表HrmResourceManager体系管理员信息表HrmDepartment人力资源部门表HrmSubCompany人力资源分部表hrmjobtitles岗位信息表 3.3、文档相干相干数据存储


以下只枚举一些常用表结构,更多表结构参考表建构文档。
表名阐明Docdetail文档信息表DocImageFile文档附件图片表ImageFile文件存放信息表DocShare文档共享信息表DocSecCategory文档子目次表 4、数据源 DataSource

   该接口主要用来在e-cology配置和异构体系的数据库的链接方式,通过此链接在e-cology中直接操作其他体系的数据。
  后台设置
路径:集成中心-功能集成– 数据源设置

步调调用
  1. //引入相关的类
  2. import java.sql.Connection;
  3. import java.sql.ResultSet;
  4. import java.sql.SQLException;
  5. import weaver.general.BaseBean;
  6. import weaver.general.StaticObj;
  7. import weaver.interfaces.datasource.DataSource;
  8. //调用数据源生成jdbc链接
  9. DataSource ds = (DataSource)StaticObj.getServiceByFullname(("datasource.NC"),DataSource.class);
  10. //local为配置的数据源标识
  11. Connection conn = null ;
  12.   try{
  13.     conn = ds.getConnection();
  14.     ResultSet rs = conn.createStatement().executeQuery("select top 10 lastname,password from           hrmresource");
  15.     while(rs.next()){
  16.       System.out.println("name-->"+rs.getString("lastname")+" pwd-->"+rs.getString("password"));
  17.     }
  18.     rs.close();
  19.   }catch(Exception e){
  20.     writeLog(e);
  21.   }finally{
  22.     try {
  23.       conn.close();
  24.     } catch (SQLException e) {
  25.     }
  26.   }
复制代码
5、流程自界说接口动作

5.1、流程流转过程理解

   这是一个简单的流程图
  

   对应实际的流程流转过程
  

5.2、自界说接口动作示例代码

该接口主要实现在流程的流转当中,实时通过自界说的动作去操作异构形体体系的数据或者是其他一些特定的操作。
在流程的每个出口或者节点都可以界说这样的自界说动作,从而实现在流程流转过程导入,导出流程的相干信息,或者将流程信息和
其他应用相联合举行数据交互。
注意自界说接口动作代码在退回到第一节点前是见效的,创建时不会见效
编写Action
新建Action实现类必须实现接口weaver.interfaces.workflow.action方法
public String execute(RequestInfo request)。
  1. package weaver.interfaces.workflow.action;
  2. import weaver.general.BaseBean;
  3. import weaver.soa.workflow.request.DetailTableInfo;
  4. import weaver.soa.workflow.request.MainTableInfo;
  5. import weaver.soa.workflow.request.Property;
  6. import weaver.soa.workflow.request.RequestInfo;
  7. public class TestAction extends BaseBean implements Action {
  8.     public String p1; //自定义参数1
  9.     public String p2; //自定义参数2
  10.         public String getP1() {
  11.         return p1;
  12.     }
  13.     public void setP1(String p1) {
  14.         this.p1 = p1;
  15.     }
  16.     public String getP2() {
  17.         return p2;
  18.     }
  19.     public void setP2(String p2) {
  20.         this.p2 = p2;
  21.     }
  22.     public String execute(RequestInfo requestinfo) {
  23.         System.out.println("进入Action requestid="+requestinfo.getRequestid());
  24.         //请求ID
  25.         String requestid = requestinfo.getRequestid();
  26.         //请求紧急程度
  27.         String requestlevel = requestinfo.getRequestlevel();
  28.          //当前操作类型 submit:提交/reject:退回
  29.         String src = requestinfo.getRequestManager().getSrc();
  30.         //流程ID
  31.         String workflowid = requestinfo.getWorkflowid();
  32.         //表单名称 主表
  33.         String tablename = requestinfo.getRequestManager().getBillTableName();
  34.         //  tablename 中的id
  35.         int billid = requestinfo.getRequestManager().getBillid();//表单数据ID
  36.         //获取当前操作用户对象
  37.         User usr = requestinfo.getRequestManager().getUser();
  38.         //请求标题
  39.         String requestname = requestinfo.getRequestManager().getRequestname();
  40.         //当前用户提交时的签字意见
  41.         String remark = requestinfo.getRequestManager().getRemark();
  42.         //表单ID
  43.         int formid = requestinfo.getRequestManager().getFormid();
  44.         //是否是自定义表单
  45.         int isbill = requestinfo.getRequestManager().getIsbill();
  46.         //取主表数据
  47.         Property[] properties = request.getMainTableInfo().getProperty();
  48.         // 获取表单主字段信息
  49.         for (int i = 0; i < properties.length; i++) {
  50.             // 主字段名称
  51.             String name = properties[i].getName();
  52.             // 主字段对应的值
  53.             String value = Util.null2String(properties[i].getValue());
  54.             System.out.println(name + " " + value);
  55.         }
  56.         //取明细数据
  57.         DetailTable[] detailtable = request.getDetailTableInfo().getDetailTable();
  58.         if (detailtable.length > 0) {
  59.             // 获取所有明细表
  60.             for (int i = 0; i < detailtable.length; i++) {
  61.                 // 指定明细表
  62.                 DetailTable dt = detailtable[i];
  63.                 // 当前明细表的所有数据,按行存储
  64.                 Row[] s = dt.getRow();
  65.                 for (int j = 0; j < s.length; j++) {
  66.                     // 指定行
  67.                     Row r = s[j];
  68.                     // 每行数据再按列存储
  69.                     Cell c[] = r.getCell();
  70.                     for (int k = 0; k < c.length; k++) {
  71.                         // 指定列
  72.                         Cell c1 = c[k];
  73.                         // 明细字段名称
  74.                         String name = c1.getName();
  75.                         // 明细字段的值
  76.                         String value = c1.getValue();
  77.                         System.out.println(name + " " + value);
  78.                     }
  79.                 }
  80.             }
  81.         }
  82.         //控制流程流转,增加以下两行,流程不会向下流转,表单上显示返回的自定义错误信息
  83.         requestinfo.getRequestManager().setMessageid(System.currentTimeMillis() + "");
  84.         requestinfo.getRequestManager().setMessagecontent("返回自定义的错误信息");
  85.         //必须返回false,否则流程会提交下去
  86.                     FAILURE_AND_CONTINUE;
  87.         System.out.println("Action执行完成 传入参数p1="+this.getP1()+"  p2="+this.getP2());
  88.                 //return返回固定返回`SUCCESS`
  89.         return SUCCESS ;
  90.     }
  91. }
复制代码
  编译好class后开始注册配置Action设置
  


6、流程表单代码块

   流程前端API在线阐明文档
  https://e-cloudstore.com/doc.html?appId=98cb7a20fae34aa3a7e3a3381dd8764e
  7、发布webservice

编写接口和实现类
   发布自己的WebService接口,只要实现对应的接口和实现类即可。
  以下以一个简单的输入输出为例:
  编写接口
  1. /**
  2. * 自定义的WebService接口
  3. */
  4. package weaver.oatest.webservices;
  5. public interface TestService {
  6.     /**
  7.      * 输出接收的参数
  8.      * @param param
  9.      * @return
  10.      */
  11.     public String TestMethod(String... param);
  12. }
复制代码
实现类
  1. package weaver.oatest.webservices;
  2. import org.apache.commons.lang.StringUtils;
  3. import weaver.general.BaseBean;
  4. public class TestServiceImpl extends BaseBean implements TestService  {
  5.     public String TestMethod(String... param) {
  6.         return "接收到的参数为:"+StringUtils.join(param,",");
  7.     }
  8. }
复制代码
  这样接口就编写好了,下一步就到发布接口。
  发布接口
修改==./ecology/classbean/META-INF/xfire/services.xml==文件增长要发布的接口,增长下面内容 :
name:为接口名称
namespace:命名空间
serviceClass:接口的报名加类名
implementationClass:接口的实现包名加类名`
  1. <service>
  2.     <name>TestService</name>
  3.     <namespace>webservices.test.weaver.com.cn</namespace>
  4.     <serviceClass>weaver.oatest.webservices.TestService</serviceClass>
  5.     <implementationClass>weaver.oatest.webservices.TestServiceImpl</implementationClass>
  6. </service>
复制代码
  接口发布后,访问http://ip/services 可以看到发布的TestService
  8、计划使命 CronJob

   该接口用来用户在e-cology体系自由界说一些必要定时实行的操作,它是由Quartz这一个开源的作业调度框架来实现;该接口通过配置调度时间和自行开辟调度动作来实现必要定时实行的使命。
该接口提供了两种调度方式:
  

  • CronJob接口,此接口在指定的时间点实行 ,BaseCronJob是体系默认的实现了CronJob的实现类,可以直接继承。
在开辟调度动作必要实现e-cology提供的自界说动作接口。
  1. package weaver.interfaces.schedule;
  2. import weaver.conn.RecordSet;
  3. import weaver.workflow.request.MailAndMessage;
  4. import java.util.ArrayList;
  5. public class SyncRequestTitleJob extends BaseCronJob {
  6. public void execute() {
  7.        //实际执行的业务逻辑
  8.     }
  9. }
复制代码
配置计划使命
   在后台集成中心–计划使命中添加计划使命类和实行时间,如:每30分钟同步一次请求标题。计划使命标识必须唯一不能重复。
  
9、自界说短信接口

9.1、短信接口

短信集成必要实现接口
   e-cology的短信接口除了提供了写中心表的方式发送短信外,还提供了通过步调实现短信接口的方式发送短信。自界说接口的接口类和属性根据必要举行设置。
  自界说接口类必须实现接口weaver.sms.SmsService的方法
  public boolean sendSMS(String smsId,String number,String msg)
  1. package weaver.interfaces.sms;
  2. import weaver.general.TimeUtil;
  3. import weaver.sms.SmsService;
  4. public class TestSms implements SmsService {
  5.     //smsId 没用
  6.     //phoneno  手机号
  7.     //msg  短信内容
  8.     public boolean sendSMS(String smsId, String phoneno, String msg) {        
  9.         //实现相应的短信平台的API进行发送        
  10.          doSend(phoneno,msg);
  11.         return true;   
  12.     }
  13. }
复制代码
自界说接口配置:

9.2、消息接口

https://www.showdoc.com.cn/p/f217b01ce7c26aa9303ab93fe74eccb7
10、restful创建流程接口&鉴权

https://e-cloudstore.com/ec/api/applist/index.html#/
11、构造结构同步

https://e-cloudstore.com/doc.html?appId=c373a4b01fb74d098b62e2b969081d2d
12、免密登录OA

   1、实用于第三方体系单点登录方式进入泛微Ecology8和Ecology9体系。
2、单点登录OA体系为令牌方式,即第三方体系请求OA体系传入应用标识即员工登录账号,OA体系返回一个令牌串。
3、第三方体系按照规则拼接令牌串则可以访问OA电脑和手机端的页面地址。
  12.1、条件条件

   1、两套体系的人员登录账号一致
​2、假如为Ec8体系,请确认kb版本是否为1806以上,kb低于此版本不支持该方案单点登录
  12.2、OA体系检查配置

12.2.1、接口发布相干

在ecology\WEB-INF\web.xml末了面配置,假如有该配置,请忽略
  1. <servlet>
  2.     <servlet-name>getToken</servlet-name>
  3.     <servlet-class>weaver.weaversso.GetToken</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6.     <servlet-name>getToken</servlet-name>
  7.     <url-pattern>/ssologin/getToken</url-pattern>
  8. </servlet-mapping>
  9. <servlet>
  10.         <servlet-name>CheckToken</servlet-name>  
  11.         <servlet-class>weaver.weaversso.CheckToken</servlet-class>
  12.     </servlet>  
  13.     <servlet-mapping>
  14.         <servlet-name>CheckToken</servlet-name>  
  15.         <url-pattern>/ssologin/checkToken</url-pattern>
  16.     </servlet-mapping>
复制代码
在ecology\WEB-INF\web.xml中配置:(必要放在安全补丁包的后面)
  1. <filter>
  2.     <filter-name>WeaverLoginFilter</filter-name>
  3.     <filter-class>weaver.weaversso.WeaverLoginFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6.     <filter-name>WeaverLoginFilter</filter-name>
  7.     <url-pattern>*.html</url-pattern>
  8.     <url-pattern>*.jsp</url-pattern>
  9. </filter-mapping>
复制代码
12.2.2、集成的应用配置相干

必要配置ecology\WEB-INF\prop\WeaverLoginClient.properties文件ssss=127.0.0.1
   配置阐明:
1、左侧配置单点登录OA标识,右侧配置允许单点登录OA的物理IP地址,多个以逗号分隔。
  2、若有OA为Nginx集群的环境,必要在WeaverLoginClient.properties配置上nginx服务的ip。
  3、假如访问接口时返回ip非法之类的,请检查/log/integration/integration.log日志里的requestip输出,确认是否有配置到。
  4、E9新版本kb下,可以直接在同一认证中心配置,不必要在ecology\WEB-INF\prop\WeaverLoginClient.properties中配置集成应用的相干信息。
  


##12.3、获取token的接口
功能阐明获取用户登录token接口地址http://OA的pc端访问地址/ssologin/getToken调用方式POST 参数阐明appid应用标识(WeaverLoginClient.properties文件中左侧标识)loginidOA登录账号 返回值阐明用户登录令牌令牌生成规则AES(loginid+“|”+ts+“|”+appid) 生成的令牌要保存到数据库中securityfilter里必要配置第三方访问oa的服务器白名单,方能确保该方案正常使用
请检查ecology\WEB-INF\weaver_security_config.xml文件是否有is-login-check配置,若没有,则添加;若有,请调整为false

  1. <is-login-check>false</is-login-check>
复制代码
Token参数只有一次有用,若已被使用,再次使用时,会直接跳转到OA登录页面。
12.3.1、postman请求示例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uxTlRjk7-1679280813349)(E9开辟培训.assets/2bdb329b-4aef-4c6b-a00e-bf9e1608d9e0-164969218392812.png)]
12.4、单点登录跳转地址拼接

###12.4.1、pc下的地址拼接
携带拼接ssoToken时,注意拼接位置,E9的很多页面是单页面,不要拼在#路由地址后面,如:
http://192.168.95.101:8088/wui/index.html#/main?ssoToken=XXX
这是错的,必要这样拼:
http://192.168.95.101:8088/wui/index.html?ssoToken=XXX#/main
测试例子:
OA中人员cs001有requestid=5074的流程,对于PC端,流程路径配置:
将上面获取到token值拼接到地址中:
http://192.168.95.101:8088/spa/workflow/index_form.jsp?ssoToken=B4E721CCC7F210D5A44B3F5AF2046315BC314D205967E6911FCA4361BBA5851A#/main/workflow/req?requestid=5074
直接访问,可直接单点登录进入流程页面:

12.4.2、EM7的地址拼接

重新申请token值,举行拼接:
http://192.168.95.101:8088/spa/workflow/static4mobileform/index.html?ssoToken=9B3E7C2D58FED69547850D7002549C80541ED138EE450C17C75B25A9996FC846#/req?requestid=5074
移动端访问,也可直接单点登录打开流程页面:

13、注意事项

13.1、System.out

   正式代码中严禁使用 System.out 举行日志的输出,原因是这个语句的性能非常低,一旦调用的非常频仍, 就会成为性能瓶颈。
  13.2、BaseBean

  1. import weaver.general.BaseBean;
  2. BaseBean baseBean = new BaseBean();
  3. //日志打印
  4. baseBean.writeLog("xxx");
  5. //读取.properties配置文件的值
  6. //.properties配置文件路径 /ecology/WEB-INF/prop目录下
  7. baseBean.getPropValue("配置文件名(不含.properties)","键名");
复制代码
13.3、数据库操作

13.3.1、RecordSet和RecordSetTrans

   目前RecordSet和RecordSetTrans提供的execute和executeSql方法采用SQL拼接方法来实行SQL,这样会产生SQL注入安全威胁。
  请大家以后写SQL语句时,使用以下两个方法来替换原来的拼接SQL的方式,以避免SQL渗出威胁。
  RecordSet不要在循环体里new。
  不做多方法传递。
  现在提供以下两个方法来替换execute和executeSql。
方法名参数阐明(示例)executeQuery(String sql,Object… params)sql:待实行的SQL语句params:用于替换sql中的?的参数,可以是0个或多个该方法用于查询,RecordSet中实行完毕后会返回true|false,
RecordSetTrans实行失败会抛出异常。同时会保留结果集供使用。
遍历结果集的方法和executeSql实行后遍历一样。
示例:
rs.executeQuery(“select id,loginid from hrmresource where lastname like ?”,”%王%”)rs.executeQuery(“select id,loginid from hrmresource where lastname like ? and seclevel >= ?”,”%王%”,30)executeUpdate(String sql,Object… params)sql:待实行的SQL语句params:用于替换sql中的?的参数,可以是0个或多个该方法用于更新记录
RecordSet中实行完毕后会返回true|false,
RecordSetTrans实行失败会抛出异常。
示例:
rs.executeUpdate(“insert into hrmresource(loginid,lastname) values(?,?)”,”wangxin”,”王鑫”)
rs.executeUpdate(“delete from hrmresource where id=?”,id) 13.3.2、数据库使用事件

使用 weaver.conn.RecordSetTrans 可以对数据库举行事件操作
参考代码
  1. RecordSetTrans rst = new RecordSetTrans();
  2. // 开启事务
  3. rst.setAutoCommit(false);
  4. String sql = "update hrmresource lastname=? where id=?";
  5. try {
  6.         int a = 1/0;
  7.         rst.executeUpdate(sql, "猪八戒", 2);
  8.         // 提交事务
  9.         rst.commit();
  10. } catch (Exception e) {
  11.         e.printStackTrace();
  12.         // 事务回滚
  13.         rst.rollback();
  14. }
复制代码
13.3、获取体系配置的访问地址


  1. SystemComInfo system = new SystemComInfo();
  2. //OA访问地址
  3. String intranet = system.getOaaddress();
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

梦应逍遥

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表