1. 说明
依托流程定制工具实现业务依照流程进行审批办理的要求,依据不同业务的需要其流程可以满足单项目流程定义和全局流程定义功能。
通过流程工具设置中所属项目决定是否是项目流程。
1.1 添加流程分类
在系统管理
=> 通用属性
=> 通用
组中的流程分类
下,增加一个属性, 这样后面添加流程时就可以选择这个分组了
1.2 创建流程
在上报设置
=>其他流程设置
菜单下点击新增
,在弹出框中,选择对应的分组,这里我们选择上面一步添加的科研
,然后输入流程编码,如这里的APPLYESTABLISH
,这两个值只是会用来确定最终在数据库里面生成的记录流程的表格的名字,点击保存
1.3 发布流程
流程定义成功后需要生成对应的流程审批记录表,通过点击发布图标,如下图:生成,需要重启服务器方可使用。对应的流程记录表生成规则:表名+流程编号+项目编号。
注:点击该图标("发布“)后,IDEA会在target/opms-science-web-1.0.0/WEB-INF/classes/hpms/entity/flow/
下生成一个FlowRecordSCIENCEAPPLYESTABLISH.hbm.xml
(即 FlowRecord
+1.1里面添加的流程分组码
+1.2中创建的流程编码
)文件,这也就是需要重启的原因,还有如果后面手动删掉了target也是需要再次点击这个“发布”图标的。重启后如果数据库没有对应表格,则会创建。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class entity-name="FlowRecordSCIENCEAPPLYESTABLISH" table="flow_record_SCIENCEAPPLYESTABLISH">
<id type="java.lang.String" name="id">
<column length="36" name="id"/>
<generator class="assigned"/>
</id>
<property type="java.lang.String" name="linkId">
<column length="36" name="linkId"/>
</property>
<property type="java.lang.String" name="linkName">
<column length="50" name="linkName"/>
</property>
<property type="java.lang.String" name="busId">
<column length="36" name="busId"/>
</property>
<property type="java.lang.String" name="submitId">
<column length="36" name="submitId"/>
</property>
<property type="java.lang.String" name="submitter">
<column length="50" name="submitter"/>
</property>
<property type="java.lang.String" name="submitterunitId">
<column length="36" name="submitterunitId"/>
</property>
<property type="java.lang.String" name="submitterunit">
<column length="100" name="submitterunit"/>
</property>
<property type="java.lang.String" name="approverId">
<column length="36" name="approverId"/>
</property>
<property type="java.lang.String" name="approver">
<column length="50" name="approver"/>
</property>
<property type="java.lang.String" name="approverunitId">
<column length="36" name="approverunitId"/>
</property>
<property type="java.lang.String" name="approverunit">
<column length="100" name="approverunit"/>
</property>
<property type="java.lang.Long" name="subdate">
<column name="subdate"/>
</property>
<property type="java.lang.Long" name="appdate">
<column name="appdate"/>
</property>
<property type="text" name="remark">
<column name="remark"/>
</property>
<property type="java.lang.Integer" name="sort">
<column name="sort"/>
</property>
</class>
</hibernate-mapping>
1.4 流程设置
1.4.1 修改流程节点
如图,点击设置后会弹出维护信息的弹窗,可以看到已经自动添加了一个开始
和一个 结束
流程节点,此处我们点击开始
节点并修改其属性
这样就修改好了第一个节点
1.4.2 添加流程节点
先选中“任务结点”图标,然后在右边区域里面空白处点击鼠标左键,即可添加一个新的节点了
1.4.3 流程连接
这样就确定了流程的上下游关系了
2. 业务整合说明
2.1. 第一步:业务中增加辅助字段
对应业务表中必须增加辅助字段,方便统一的权限控制和流程使用需要。
Name | Code | Data Type | 备注 |
---|---|---|---|
是否通过 | isadopt | int | 0:未通过 1:通过 |
上报状态 | reportStatus | int | 0:未上报 1:已上报 2:完成 |
项目编号 | proCode | varchar(50) | 允许为空 |
当前流程记录ID | flowRecordId | varchar(36) | 对应record表的id |
流程编号 | flowCode | varchar(50) | 对应流程设置的编号 |
当前环节ID | linkId | varchar(36) | 对应settings表的id |
当前流程名称 | linkName | varchar(50) | 对应环节名称 |
流转步骤次数 | linkcount | int | 累计流转次数 |
当前环节人ID | linkUserId | varchar(36) | |
当前环节人名称 | linkUserName | varchar(100) | |
当前环节人机构ID | linkOrgId | varchar(36) | |
当前环节人机构ID名称 | linkOrgName | varchar(100) |
对应实体类中需要新加的代码
private Integer isadopt;
private Integer reportStatus;
private String flowRecordId;
private String flowCode;
private String linkId;
private String linkName;
private Integer linkcount;
private String linkUserId;
private String linkUserName;
private String linkOrgId;
private String linkOrgName;
对应hbm.xml
文件中新添加的代码
<property type="java.lang.Integer" name="isadopt">
<column name="[isadopt]" />
</property>
<property type="java.lang.Integer" name="reportStatus">
<column name="[report_status]" />
</property>
<property type="java.lang.String" name="flowRecordId">
<column length="36" name="[flow_record_id]" />
</property>
<property type="java.lang.String" name="flowCode">
<column length="50" name="[flow_code]" />
</property>
<property type="java.lang.String" name="linkId">
<column length="36" name="[link_id]" />
</property>
<property type="java.lang.String" name="linkName">
<column length="50" name="[link_name]" />
</property>
<property type="java.lang.Integer" name="linkcount">
<column name="[linkcount]" />
</property>
<property type="java.lang.String" name="linkUserId">
<column length="36" name="[link_user_id]" />
</property>
<property type="java.lang.String" name="linkUserName">
<column length="100" name="[link_user_name]" />
</property>
<property type="java.lang.String" name="linkOrgId">
<column length="36" name="[link_org_id]" />
</property>
<property type="java.lang.String" name="linkOrgName">
<column length="100" name="[link_org_name]" />
</property>
2.2. 第二步:业务新增时同步保存初始流程状态
2.2.1 方式一:后端实现
- 添加接口(非必须,但建议)
/**
* 提供给流程设置用的,主要是用来提供一个通用的访问方式,以方便参数的传递
*/
public interface FlowEntityInterface {
String getId();
void setLinkcount(Integer linkCount);
Integer getLinkcount();
void setFlowRecordId(String flowRecordId);
void setFlowCode(String flowCode);
void setLinkUserId(String linkUserId);
void setLinkUserName(String linkUserName);
void setLinkOrgId(String linkOrgId);
void setLinkOrgName(String linkOrgName);
void setLinkId(String linkId);
void setLinkName(String linkName);
}
然后修改对应的实体类,实现该接口,implements FlowEntityInterface
如
/**
* science_apply_establish 项目申请/立项表 entity
* @author zqq
*/
@Component(value="scienceApplyEstablish")
@Data
@EqualsAndHashCode(callSuper=false)
public class ScienceApplyEstablish extends MaintainEntity implements FlowEntityInterface {
//添加接口实现:implements FlowEntityInterface
}
- 添加工具类
import cn.hutool.core.util.StrUtil;
import core.utils.MySession;
import core.utils.type.FlowUser;
import core.utils.type.MyUser;
import org.hq.common.sys.service.SysFlowSettingsService;
import org.hq.opms.science.service.FlowEntityInterface;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class FlowUtil {
@Autowired
private SysFlowSettingsService sysFlowSettingsService;
/**
* 获取业务实体对象里面的id和linkcount的值
* 然后创建流程的第一个环节保存后将该环节相关的信息设置到该实体对象中
* @param flowEntity
*/
public void handFlow(FlowEntityInterface flowEntity,String flowCode) {
// 这里实际上是1.1中创建完流程后的那个流程识别码的值
// String flowCode = "SCIENCEAPPLYESTABLISH";
// 把对象包含的属性和值转成map
Map<Object, Object> formData = new HashMap<>();
formData.put("id", flowEntity.getId());
formData.put("linkcount", flowEntity.getLinkcount());
// 调用上一步添加的方法进行流程信息登记
setStartFlowNode(flowCode,formData);
// 上一行的方法完成后会在formData中添加两个键对,flowRecordId和flowCode,对应的设置到实体对象中
// 目的是保存 记录当前实体数据所处流程状态 的那条记录对应的ID和所在表格的名称
flowEntity.setFlowRecordId(StrUtil.toString(formData.get("flowRecordId")));
flowEntity.setFlowCode(StrUtil.toString(formData.get("flowCode")));
flowEntity.setLinkUserId(StrUtil.toString(formData.get("linkUserId")));
flowEntity.setLinkUserName(StrUtil.toString(formData.get("linkUserName")));
flowEntity.setLinkOrgId(StrUtil.toString(formData.get("linkOrgId")));
flowEntity.setLinkOrgName(StrUtil.toString(formData.get("linkOrgName")));
flowEntity.setLinkId(StrUtil.toString(formData.get("linkId")));
flowEntity.setLinkName(StrUtil.toString(formData.get("linkName")));
}
/**
* 为指定的实体数据及对应的第一个环节信息记录到 flow_record_${flowCode}_${proCode}的表格中
* @param flowCode 流程分类编号,对应根据业务人为的设置一个固定的值就可以了
* @param fromData
*/
private void setStartFlowNode(String flowCode,Map fromData) {
MyUser myUser = MySession.getSessionValues();//当前用户信息
// proCode:项目编号,可以为空,会根据flowCode和proCode在sysFlow表中查找对应的记录的id,或只根据flowCode查询,tableName直接就是flowCode+proCode
String proCode = myUser.getProCode();//项目编号
fromData.put("linkUserId", myUser.getUserId());//创建人ID
fromData.put("linkUserName", myUser.getUserName());//编辑人
fromData.put("linkOrgId", myUser.getOrgId());//编辑人所在单位ID
fromData.put("linkOrgName", myUser.getOrgName());//编辑人所在单位
// 如果是有项目编号的话,可以使用这种方式
// flowInfo:{id:在sysFlow表格中对应记录的id,tableName:flowCode+proCode}
// 该方法的第二个参数是proCode,需要就传,不需的话就传空字符串即可
//HashMap flowInfo = sysFlowSettingsService.getFlowInfo(flowCode, "");
// flowId : 流程ID,即在sysFlow表格中该flowCode对应的记录的id
//String flowId = flowInfo.get("id").toString();
// 如果没有项目编号的话,直接使用这个重载的方法获取就可以了
String flowId = sysFlowSettingsService.getFlowInfo(flowCode);
// 根据情况可以从中那第一个环节的相关信息进行赋值
// 从sys_flow_settings表中查询 {type:'start',model:'node',flowId:flowId}对应的记录
// 然后顺带着还把proCode也查出来了,因此flowNode里面的信息应该是sys_flow_settings表中记录所有的值及proCode
HashMap flowNode = (HashMap) sysFlowSettingsService.getStartNode(flowId);
//当前人信息
FlowUser flowUser = MySession.getFlowUser();
// fromData: 具体业务的信息,其中会用到ID和linkCount
//注意事项:ID一定要在调用本方法前赋值,linkCount默认值为1
/* {
flowNode:{id:linkId,name:linkName},
fromData:{id:busId,linkcount:sort},
flowUser:{userId:submitId,userName:submitter,orgId:submitterunitId,orgName:submitterunit},
DateTimeUtil.getDateToLong():subdate
}
*/
String flowRecordId = sysFlowSettingsService.addFLowNode(flowNode, flowCode, fromData, flowUser).toString();
// 保存信息到主表业务中用于判断使用
fromData.put("flowRecordId", flowRecordId);
//如果是有项目编号的可以使用这种方式
//fromData.put("flowCode", flowInfo.get("tableName"));
//没有项目编号的使用下面这种方式来获取tableName
fromData.put("flowCode", flowCode);
fromData.put("linkId", flowNode.get("id"));
fromData.put("linkName", flowNode.get("name"));
}
}
impl
服务层的实现类中
注入工具类
@Autowired
private FlowUtil flowUtil;
由于是初始环节,人员和机构进行判断是否具备流程操作权限(通过当前人、当前机构、当前角色判断)
绑定业务对象
第一个流程应该设置在新增业务时,在baseDAO.add(entity);方法的前面(注:添加在此处是因为需要实体对象的id
属性已经有值,确保不为null
),添加如下代码,这里的applyEstablish
变量是业务实体对象,其他的类中只要替换掉这个对象就可以了。
注意:需要修改下面的flowUtil.handFlow(FlowEntityInterface flowEntity,Strig flowCode)
方法的flowCode
参数的值为对应的实际流程的fullFlowCode
,就是1.2中创建流程界面中的那个“流程识别编码”,比如这里的"SCIENCEAPPLYESTABLISH"
// 流程里面需要用到这个数据,所以需要先赋值
applyEstablish.setLinkcount(1);
flowUtil.handFlow(applyEstablish,"SCIENCEAPPLYESTABLISH");//由于实现类已实现该接口,所以可以传
前端form
表单如果需要增加流程所需属性时可以添加如下代码
<input id="isadopt" name="isadopt" class="mini-textbox" emptyText="是否通过" visible="false" />
<input id="reportStatus" name="reportStatus" class="mini-textbox" emptyText="上报状态" visible="false" />
<input id="proCode" name="proCode" class="mini-textbox" emptyText="项目编号" visible="false" />
<input id="flowRecordId" name="flowRecordId" class="mini-textbox" emptyText="流程记录ID" visible="false"/>
<input id="flowCode" name="flowCode" class="mini-textbox" emptyText="流程编号" visible="false"/>
<input id="linkId" name="linkId" class="mini-textbox" emptyText="环节ID" visible="false"/>
<input id="linkName" name="linkName" class="mini-textbox" emptyText="环节名称" visible="false"/>
<input id="linkcount" name="linkcount" class="mini-textbox" emptyText="流程记录数量" visible="false" />
<input id="linkUserId" name="linkUserId" class="mini-textbox" visible="false" />
<input id="linkUserName" name="linkUserName" class="mini-textbox" visible="false" />
<input id="linkOrgId" name="linkOrgId" class="mini-textbox" visible="false" />
<input id="linkOrgName" name="linkOrgName" class="mini-textbox" visible="faltruese" />
前端grid
的如果需要添加流程所需属性时,可以在columns
配置中添加如下代码段
{ field: "flowRecordId",header: "当前流程记录ID",visible:false},
{ field: "linkId",header: "当前环节ID",visible:false},
{ field: "linkName",header: "当前环节名称",visible:false},
{ field: "isadopt",header: "是否通过",visible:false},
业务修改操作注意事项
//如果业务存在审批的历史记录表,可以通过本方法获取当前流程的审批记录表信息,用于添加新的历史信息
HashMap flowNode =
(HashMap)sysFlowSettingsService.getCurrentNode(fromData.get("linkId").toString());//根据主表记录的环节ID获取环节详细信息
2.2.2 方式二:业务已经存在,可以单独去设置第一个环节的信息
注意事项:
- id 可以在js端初始化,如果不设置,则在服务器端初始化;
- 返回的是环节的信息,可以根据实际情况初始化前端信息;
var id = myGuid();
var key=mini.encode({id:id,flowId:item.flowId,flowCode:item.flowCode,busId:item.id});
commons.myAjax({url:"saveStartFlowSysFlowSettings.action",json:{data:key}},function(text){
var key = mini.decode(text);
if(key.code=="1"){
var data = key.data;
mini.get("flowRecordId").setValue(id);
mini.get("linkId").setValue(data.linkId);
mini.get("linkName").setValue(data.linkName);
mini.get("linkUserId").setValue(cookie.get("userId"));
mini.get("linkUserName").setValue(cookie.get("userName"));
mini.get("linkOrgId").setValue(cookie.get("userOrgId"));
mini.get("linkOrgName").setValue(cookie.get("userOrgName"));
mini.get("linkcount").setValue(1);
}else{
myMessage.errTips("初始化流程信息失败,请重新尝试后联系管理员");
}
2.3. 第三步:JS端调用流程相关的按钮
JS端代码:在grid
表格的操作那一列的renderer
函数内调用myFlow.getFLowBtns(e,isShowStatusBtn);
添加流程相关的按钮
//绑定操作列事件
function onActionRenderer(e) {
var grid = e.sender;
var record = e.record;
var uid = record._uid;
//配置获取菜单
var s = "";
//配置获取菜单
if (!record.reportStatus) {
// 只有处于未上报时,才可以进行编辑等操作
// 流程上处于已上报后,这里就不显示修改、删除等操作的按钮了
s= toolsBtn.getRowAllButtoms(e, grid, buttonTools, uid);
}
//由于业务表格中只存储了linkId,所以需要根据该id查询对应的流程信息
commons.myAjax({
url: "getFromSysFlowSettings.action",
json: {data: e.record.linkId},
async: false
}, function (res) {
// 拷贝对象,防止篡改原有数据
var copyRecord = JSON.parse(JSON.stringify(record));
var esRecord = Object.assign(copyRecord, res.data);
var obj = {record: esRecord}
// 拼接上流程处理的按钮
s += myFlow.getFLowBtns(obj, false);
})
return s;
}
备注:isShowStatusBtn
是否设置审核按钮,默认 true
,只有在特殊业务不需要系统生成审核按钮,则设置 false
,例如中期支付证书功能;
2.4. 第四步:上报和退回整合
JS端代码:
对应业务页面实现flowBtnOperation(action)方法,例如:
function flowBtnOperation(action){
myFlow.nextStep({
action:action,
grid:grid,
key:{"package":"org.hq.opms.science.entity.ScienceApplyEstablish"},
tb:"ScienceApplyEstablish"//业务类
});
}
action
: 上报:report
退回:return
grid
: 对应业务的表格控件
key
: 添加补充的参数 json格式
tb
:对应的业务类,与hbm文件名相同,用于处理业务中的流程信息记录。
备注:实体类业务需要调整参数
{
key:{"package":"org.hq.pro.qilu.rating.entity.RatingPersonnelEvaluation"},
tb:"rating_personnelEvaluation"//业务类
}
package
:对应实体类的包路径;
tb
:对应sql表名;
2.5. 第五步:结束流程整合
JS端代码:实现 flowComplete()方法
function flowComplete(){
//弹出一个结束确认页面
myFlow.endStep({
grid:grid,
key:key,
optionDisplay:false,//不显示是否同意选项 默认同意
tb:"ConAltercontract"//业务类
},function(info){
if(info.message==messageText.success){
//同意申请
if(info.isadopt==1){
//处理业务的特殊需求
issuedRow();
}else{
cancelRow();//作废
}
}
});
}
结束环节会约束是否同意流程的办理,如果业务需要根据这个进行差异判断处理,可以在流程处理完成后进行业务的处理;
info.isadopt
:1
同意 0
不同意
optionDisplay
:false
不显示是否同意, true
显示是否同意,默认true
备注:实体类业务需要调整参数
{
key:{"package":"org.hq.pro.qilu.rating.entity.RatingPersonnelEvaluation"},
tb:"rating_personnelEvaluation"//实体类的类名,流程处理那边会把这个做为表名去查询数据
}
package
:对应实体类的包路径;
tb
:对应sql表名;
2.6. 第六步:审核操作整合
JS端代码:实现completeRow()
方法
审核操作一般等同于对应业务的修改操作;
//审核操作
function completeRow(){
var row =grid.getSelected();
var url = "editRatingEnterpriseEvaluation.action";
var rowData={id:row.id,proCode:row.proCode,action:"complete"};
var data = {grid:grid,url:url,titleName:"审批人员评价",width:"90%",height:"90%",data:rowData};
commons.intricateEdit(data);
}
2.7 第七步: 流程办理历史记录查看
在页面的js文件中的init方法中添加如下语句
myFlow.createHistoryWindow();//创建一个流程查看记录窗体
然后在需要的提供查看历史记录的grid中添加这么一列,
{ field: "linkName",header: "办理进度",width: 120, headerAlign: "center", align: "center", allowSort: true,visible:true,renderer:"myFlow.flowRenderer"},
当然了,也可以直接使用myFlow.flowRenderer
方法自行处理业务逻辑,如下面这个是
{header: "状态",renderer: "onStatusRenderer",width: 100,headerAlign: "center",align: "center"}
这个列的renderer
函数的实现
//由于该列没有field,所以根据列名判断
if (e.column.header === "状态") {
// 状态栏的值是根据linkcount和linkName来确定的,也就是流程那边的状态,也可以只根据reportStatus判断
let record = e.record;
let statusText = "";
if (record.reportStatus == 0 && record.linkcount > 1) {
statusText = "已退回";
} else{
//这步是为了兼容未处理流程控制的或是发生异常时返回的数据
if(record.linkName){
statusText = record.linkName;
}else{
return "状态异常";
}
}
//克隆对象,防止污染原数据
let copyRecord = JSON.parse(JSON.stringify(e.record));
//这里是手动指定渲染出来的被a标签包裹的内容
copyRecord.linkName = statusText;
return myFlow.flowRenderer({record:copyRecord});
}
该函数最终生成的代码如下
<a href="javascript:myFlow.history('SCIENCEAPPLYESTABLISH','959e3107-c32a-4556-bdb8-9183df3886a2')">未通过</a>
myFlow.history(fullFlowCode,busId)
,其中busId
应该是当前行的实体记录的id值
3. 流程使用
新增记录后,在有权限的人员的列表中已经可以看到这个上报按钮了,点击上报按钮后,填写信息,点确定
然后使用审核节点对应的用户,登陆系统,就可以看到我们设置的退回
、审核
、结束
这三个按钮了
点击审核时
点击退回时
点击结束时
以上就是流程相关的内容了,细节方面根据自己的实际业务修改即可。
源码中可能存在的问题:
org.hq.common.sys.service.impl.SysFlowSettingsServiceImpl:440
439: //查看指定的流程项目是否有独立流程设置
440: String hsql="FROM SysFlow WHERE flowCode='"+flowCode+"' AND proCode='"+proCode+"'";
此入首先是想查独立流程,但是使用的是flowCode进行筛选,而实际表格中flowCode存储的是流程分组编码,也就是说该流程组内只能有一个流程生效了
4 优化
1.页面查询次数
说明按上面的方式配置完成后可以发现,每条记录加载流程相关的按钮时,都需要单独发起一次请求,是因为需要去查询当前记录的所处的流程信息,因此我们可以直接在查询列表时就把这些信息带过来,这样就不需要每条记录都要去查一次数据库了。
- 在
action.getDataList
方法中添加如下SQL
td.isreport,td.reportTitle,td.reportWhere,td.isreturn,td.returnTitle,td.returnWhere,td.isend,td.endTitle,td.endWhere,td.isReturnStart,td.isProOrgTofilter,td.whereType
left join sys_flow_settings as td on ta.link_id = td.id
然后在页面添加
/**
* 流程相关的按钮渲染函数,此函数要求grid的row里面包含了记录对应的sys_flow_settings里面的信息
* @param e
* @param imgBtn 是否图标按钮,默认是图标
* @returns {string}
*/
function btnRendererWithFullMessage(e, imgBtn) {
var grid = e.sender;
var record = e.record;
var uid = record._uid;
//配置获取菜单
var s = "";
// 经观察,当该状态为未上报时,是可以编辑的,0:未上报 1:已上报 2:完成
if (!record.reportStatus) {
s = toolsBtn.getRowAllButtoms(e, grid, buttonTools, uid);
}
// 拷贝对象,防止篡改原有数据
var copyRecord = JSON.parse(JSON.stringify(record));
var flowBtnHtml = myFlow.getFLowBtns({record:copyRecord}, false);
s += imgBtn ? flowBtnHtml : flowUtil.transferFlowBtnToText(flowBtnHtml);
return s;
}
操作列渲染函数修改为
//绑定操作列事件
function onActionRenderer(e) {
var uid = e.record._uid;
var s = flowUtil.btnRendererWithFullMessage(e);
// 增加报表按钮,该分组按钮只要有权限即可显示,不受状态影响
var values = toolsBtn.rowButton(buttonTools.btns1, e, true);
s += values?values.replace(/uid/g, "'" + uid + "'"):"";
return s;
}
上页代码中需要的flowUtil
对象代码如下
var flowUtil = new Object({
/**
* 把流程相关的图标按钮转成文字按钮
* @param btnHtml
* @returns {string}
*/
transferFlowBtnToText: function (btnHtml, btnColorString) {
var alinks = $(btnHtml);
var s = "";
if (alinks.length && alinks.length > 0) {
for (let i = 0; i < alinks.length; i++) {
let alink = $(alinks[i]);
let atitle = alink.attr("title");
alink.attr("class", btnColorString ? btnColorString : (atitle.toString().indexOf("退回") > -1 ? btnColor.red : btnColor.blue));
alink.attr("style", "margin:0 5px 0 0; font-weight:bolder;");
alink.text(atitle);
s += alink[0].outerHTML;
}
}
return s;
},
/**
* 流程相关的按钮渲染函数
* @param e
* @param imgBtn 是否图标按钮,默认是图标
* @returns {string}
*/
btnRenderer: function (e, imgBtn) {
var grid = e.sender;
var record = e.record;
var uid = record._uid;
//配置获取菜单
var s = "";
// 经观察,当该状态为未上报时,是可以编辑的,0:未上报 1:已上报 2:完成
if (!record.reportStatus) {
s = toolsBtn.getRowAllButtoms(e, grid, buttonTools, uid);
}
commons.myAjax({
url: "getFromSysFlowSettings.action",
json: {data: e.record.linkId},
async: false
}, function (res) {
// 拷贝对象,防止篡改原有数据
var copyRecord = JSON.parse(JSON.stringify(record));
var esRecord = Object.assign(copyRecord, res.data);
var obj = {record: esRecord}
var flowBtnHtml = myFlow.getFLowBtns(obj, false);
s += imgBtn ? flowBtnHtml : flowUtil.transferFlowBtnToText(flowBtnHtml);
})
return s;
},
/**
* 流程相关的按钮渲染函数,此函数要求grid的row里面包含了记录对应的sys_flow_settings里面的信息
* @param e
* @param imgBtn 是否图标按钮,默认是图标
* @returns {string}
*/
btnRendererWithFullMessage: function (e, imgBtn) {
var grid = e.sender;
var record = e.record;
var uid = record._uid;
//配置获取菜单
var s = "";
// 经观察,当该状态为未上报时,是可以编辑的,0:未上报 1:已上报 2:完成
if (!record.reportStatus) {
s = toolsBtn.getRowAllButtoms(e, grid, buttonTools, uid);
}
// 拷贝对象,防止篡改原有数据
var copyRecord = JSON.parse(JSON.stringify(record));
var flowBtnHtml = myFlow.getFLowBtns({record:copyRecord}, false);
s += imgBtn ? flowBtnHtml : flowUtil.transferFlowBtnToText(flowBtnHtml);
return s;
},
createHistoryWindow: function () {
var win = new mini.Window();
win.set({
id: "editWindow",
title: "审批流程记录",
style: "width:80%; height:80%",
showModal: "true", allowResize: "true", allowDrag: "true"
});
var flowGrid = new mini.DataGrid();
flowGrid.set({
id: "flowGridList"
});
var colunms = [
{field: "sort", header: "序号", headerAlign: "center", align: "center", allowSort: true, width: 20},
{
field: "linkName",
header: "流程",
width: 100,
headerAlign: "center",
align: "center",
visible: false,
allowSort: true
},
{
field: "submitterunit",
header: "发送单位",
width: 100,
headerAlign: "center",
align: "center",
visible: false,
allowSort: true
},
{field: "submitter", header: "发送人", width: 80, headerAlign: "center", visible: false, allowSort: true},
{
field: "subdate",
header: "发送时间",
width: 100,
headerAlign: "center",
align: "center",
visible: false,
allowSort: true,
renderer: "myDate.gridLongDateFormatAll"
},
{
field: "approverunit",
header: "审批单位",
width: 100,
headerAlign: "center",
align: "center",
allowSort: true
},
{field: "approver", header: "审批人", width: 80, headerAlign: "center", align: "center", allowSort: true},
{
field: "remark",
header: "审批意见",
width: 200,
headerAlign: "center",
align: "center",
allowCellWrap: true,
allowSort: true
},
{
field: "appdate",
header: "审核时间",
width: 100,
headerAlign: "center",
align: "center",
allowSort: true,
renderer: "myDate.gridLongDateFormatAll"
}
];
var data = {
grid: flowGrid,
url: "getRecordListSysFlowSettings.action",
columns: colunms,
idField: "id",
sortField: null,
sortOrder: null,
showPager: false,
multiSelect: true,
allowCellWrap: true,
allowHeaderWrap: true,
allowResize: true
};
myGrid.gridConfig(data);
flowGrid.on("load", function (e) {
var data = e.sender.data;
data.forEach(row => {
if (!row.approverId) {
flowGrid.removeRow(row);
}
});
});
win.setBody(flowGrid.getEl());
},
history: function (flowCode, id) {
var key = mini.encode({busId: id, flowCode: flowCode, approverId: "!@"});
var editWindow = mini.get("editWindow");
editWindow.show();
mini.get("flowGridList").load({key: key});
},
flowRenderer: function (e) {
var row = e.record;
var s = '<a href="javascript:flowUtil.history(\'' + row.flowCode + '\',\'' + row.id + '\')">' + row.linkName + '</a>';
return s;
}
})