提交代码

dev_xd
姜玉琦 2024-12-22 19:55:21 +08:00
parent 497177d521
commit dd887b0496
55 changed files with 3807 additions and 994 deletions

246
docsql/yz-views.sql 100644
View File

@ -0,0 +1,246 @@
##全部根据finishTime判断代办已办
DROP view vw_flow_all;
CREATE VIEW vw_flow_all AS (
SELECT
RES.ID_ AS procInsId,
DEF.DEPLOYMENT_ID_ AS deployId,
RES.START_TIME_ AS createTime,
RES.END_TIME_ AS finishTime,
CASE
WHEN RES.END_TIME_ IS NULL THEN
TIMESTAMPDIFF(
MINUTE,
RES.START_TIME_,
DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%S')
)
ELSE
TIMESTAMPDIFF(
MINUTE,
RES.START_TIME_,
RES.END_TIME_
)
END AS duration,
DEF.NAME_ AS procDefName,
DEF.VERSION_ AS procDefVersion,
DEF.CATEGORY_ AS category,
DEF.KEY_ AS procDefKey,
v1.TEXT_ AS startUserId,
v2.TEXT_ AS startUserName,
v3.TEXT_ AS startDeptName,
v4.TEXT_ AS startComId,
v5.TEXT_ AS startComName,
v6.TEXT_ AS startProId,
v7.TEXT_ AS startProName,
v8.TEXT_ AS businessKey,
RES.PROC_INST_ID_,
IFNULL(hr.ID_,ht.taskId) as taskId,
IFNULL(hr.NAME_,ht.taskName) as taskName,
IF(hr.ID_ IS NULL, ht.assigneeId, tu.user_id) as assigneeId,
IF(hr.ID_ IS NULL, ht.assigneeName, tu.nick_name) as assigneeName,
IF(hr.ID_ IS NULL, ht.assigneeDeptName, td.dept_name) as assigneeDeptName,
IF(hr.ID_ IS NULL, ht.taskComType, 0) as taskComType
FROM
ACT_HI_PROCINST RES
LEFT JOIN ACT_RE_PROCDEF DEF ON RES.PROC_DEF_ID_ = DEF.ID_
LEFT JOIN act_hi_varinst v1 ON v1.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v1.NAME_ = 'INITIATOR'
LEFT JOIN act_hi_varinst v2 ON v2.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v2.NAME_ = 'userName'
LEFT JOIN act_hi_varinst v3 ON v3.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v3.NAME_ = 'userDeptName'
LEFT JOIN act_hi_varinst v4 ON v4.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v4.NAME_ = 'comId'
LEFT JOIN act_hi_varinst v5 ON v5.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v5.NAME_ = 'comName'
LEFT JOIN act_hi_varinst v6 ON v6.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v6.NAME_ = 'proId'
LEFT JOIN act_hi_varinst v7 ON v7.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v7.NAME_ = 'proName'
LEFT JOIN act_hi_varinst v8 ON v8.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v8.NAME_ = 'businessKey'
LEFT JOIN act_ru_task hr ON hr.PROC_INST_ID_ = RES.PROC_INST_ID_
LEFT JOIN act_ru_actinst ra ON ra.TASK_ID_ = hr.ID_ AND ra.PROC_INST_ID_ = RES.PROC_INST_ID_
LEFT JOIN sys_user tu ON tu.user_id = ra.ASSIGNEE_
LEFT JOIN sys_dept td ON td.dept_id = tu.dept_id
LEFT JOIN (
SELECT
ht.ID_ AS taskId,
ht.NAME_ AS taskName,
tu.user_id AS assigneeId,
tu.nick_name AS assigneeName,
td.dept_name AS assigneeDeptName,
ht.PROC_INST_ID_,
ahc.TYPE_ as taskComType
FROM
act_hi_taskinst ht
LEFT JOIN sys_user tu ON tu.user_id = ht.ASSIGNEE_
LEFT JOIN sys_dept td ON td.dept_id = tu.dept_id
left join act_hi_comment ahc on ahc.TASK_ID_ = ht.ID_ AND ahc.PROC_INST_ID_ is not NULL
WHERE
ht.ID_ IN (
SELECT
MAX(ID_)
FROM
act_hi_taskinst
GROUP BY
PROC_INST_ID_
)
GROUP BY ht.PROC_INST_ID_
) ht ON ht.PROC_INST_ID_ = RES.PROC_INST_ID_
)
##待办
DROP view vw_flow_await;
CREATE VIEW vw_flow_await AS (
SELECT
RES.ID_ AS taskId,
RES.NAME_ AS taskName,
re.ID_ AS procInsId,
DEF.DEPLOYMENT_ID_ AS deployId,
DATE_FORMAT(re.START_TIME_, '%Y-%m-%d %H:%i:%S') AS createTime,
TIMESTAMPDIFF(
MINUTE,
re.START_TIME_,
DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%S')
) AS duration,
DEF.NAME_ AS procDefName,
DEF.VERSION_ AS procDefVersion,
DEF.CATEGORY_ AS category,
DEF.KEY_ AS procDefKey,
v1.TEXT_ AS startUserId,
v2.TEXT_ AS startUserName,
v3.TEXT_ AS startDeptName,
v4.TEXT_ AS startComId,
v5.TEXT_ AS startComName,
v6.TEXT_ AS startProId,
v7.TEXT_ AS startProName,
v8.TEXT_ AS businessKey,
RES.SUSPENSION_STATE_,
RES.ASSIGNEE_,
LINK.USER_ID_,
LINK.GROUP_ID_
FROM
ACT_RU_TASK RES
LEFT JOIN act_ru_execution re ON re.PARENT_ID_ IS NULL AND re.PROC_INST_ID_ = RES.PROC_INST_ID_
LEFT OUTER JOIN ACT_RE_PROCDEF DEF ON re.PROC_DEF_ID_ = DEF.ID_
LEFT JOIN act_hi_varinst v1 ON v1.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v1.NAME_ = 'INITIATOR'
LEFT JOIN act_hi_varinst v2 ON v2.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v2.NAME_ = 'userName'
LEFT JOIN act_hi_varinst v3 ON v3.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v3.NAME_ = 'userDeptName'
LEFT JOIN act_hi_varinst v4 ON v4.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v4.NAME_ = 'comId'
LEFT JOIN act_hi_varinst v5 ON v5.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v5.NAME_ = 'comName'
LEFT JOIN act_hi_varinst v6 ON v6.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v6.NAME_ = 'proId'
LEFT JOIN act_hi_varinst v7 ON v7.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v7.NAME_ = 'proName'
LEFT JOIN act_hi_varinst v8 ON v8.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v8.NAME_ = 'businessKey'
LEFT JOIN ACT_RU_IDENTITYLINK LINK on LINK.TASK_ID_ = RES.ID_ AND LINK.TYPE_ = 'candidate'
WHERE
RES.SUSPENSION_STATE_ = 1)
##下面是当前登录人代办查询条件
-- AND (
-- RES.ASSIGNEE_ = 1
-- OR (
-- RES.ASSIGNEE_ IS NULL
-- AND EXISTS (
-- SELECT
-- LINK.ID_
-- FROM
-- ACT_RU_IDENTITYLINK LINK
-- WHERE
-- LINK.TASK_ID_ = RES.ID_
-- AND LINK.TYPE_ = 'candidate'
-- AND (
-- LINK.USER_ID_ = 1
-- OR (
-- LINK.GROUP_ID_ IN (1, 42, 45, 46)
-- )
-- )
-- )
-- )
-- )
##审批意见
DROP view vw_flow_comment;
CREATE VIEW vw_flow_comment AS (
SELECT
hc.ID_ AS commentId,
hc.TYPE_ AS commentType,
ht.ID_ AS taskId,
ht.NAME_ AS taskName,
ht.REV_ AS rev,
CASE
WHEN hc.TYPE_ = 1 and ht.NAME_ !='提交申请' THEN
'通过'
WHEN hc.TYPE_ = 2 THEN
'退回'
WHEN hc.TYPE_ = 3 THEN
'驳回'
WHEN hc.TYPE_ = 4 THEN
'委派'
WHEN hc.TYPE_ = 5 THEN
'转办'
WHEN hc.TYPE_ = 6 THEN
'终止'
WHEN hc.TYPE_ = 7 THEN
'撤回'
END AS commentResult,
ht.PROC_INST_ID_ AS procInstId,
ht.TASK_DEF_KEY_ AS taskDefKey,
ht.EXECUTION_ID_ AS executionId,
ht.DELETE_REASON_ AS deleteReason,
DATE_FORMAT(
ht.START_TIME_,
'%Y-%m-%d %H:%i:%S'
) AS startTime,
DATE_FORMAT(
ht.END_TIME_,
'%Y-%m-%d %H:%i:%S'
) AS endTime,
ht.DURATION_ AS duration,
hc.MESSAGE_ AS message,
ru.nick_name AS assigneeName,
IF(ru.dept_id IS NOT NULL, rd.dept_name, ru.remark) as deptName,
sr.role_name as candidate
FROM
act_hi_taskinst ht
LEFT JOIN act_hi_comment hc ON hc.TASK_ID_ = ht.ID_ or (hc.TASK_ID_ is null and hc.PROC_INST_ID_ = ht.PROC_INST_ID_)
LEFT JOIN act_hi_identitylink hi on hi.TASK_ID_ = ht.ID_ and hi.TYPE_ = 'candidate'
left JOIN sys_role sr on sr.role_id = hi.group_Id_
LEFT JOIN sys_user ru ON ru.user_id = ht.ASSIGNEE_
LEFT JOIN sys_dept rd ON rd.dept_id = ru.dept_id
where hc.TYPE_ is null or hc.TYPE_!='event')
##已办
DROP view vw_flow_finished;
CREATE VIEW vw_flow_finished AS (
SELECT
RES.ID_ AS taskId,
RES.NAME_ AS taskName,
RES.PROC_INST_ID_ AS procInsId,
pd.DEPLOYMENT_ID_ as deployId,
DATE_FORMAT(RES.START_TIME_, '%Y-%m-%d %H:%i:%S') AS createTime,
DATE_FORMAT(RES.END_TIME_, '%Y-%m-%d %H:%i:%S') AS endTime,
TIMESTAMPDIFF(
MINUTE,
res.START_TIME_,
RES.END_TIME_
) AS duration,
DEF.END_TIME_ as finishTime,
pd.NAME_ AS procDefName,
pd.CATEGORY_ AS category,
pd.KEY_ AS procDefKey,
v1.TEXT_ AS startUserId,
v2.TEXT_ AS startUserName,
v3.TEXT_ AS startDeptName,
v4.TEXT_ AS startComId,
v5.TEXT_ AS startComName,
v6.TEXT_ AS startProId,
v7.TEXT_ AS startProName,
v8.TEXT_ AS businessKey,
RES.ASSIGNEE_,
ahc.TYPE_ as taskComType
FROM
act_hi_taskinst RES
LEFT OUTER JOIN act_hi_procinst DEF ON RES.PROC_INST_ID_ = DEF.PROC_INST_ID_
LEFT OUTER join act_re_procdef pd on RES.PROC_DEF_ID_ = pd.ID_
LEFT JOIN act_hi_varinst v1 ON v1.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v1.NAME_ = 'INITIATOR'
LEFT JOIN act_hi_varinst v2 ON v2.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v2.NAME_ = 'userName'
LEFT JOIN act_hi_varinst v3 ON v3.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v3.NAME_ = 'userDeptName'
LEFT JOIN act_hi_varinst v4 ON v4.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v4.NAME_ = 'comId'
LEFT JOIN act_hi_varinst v5 ON v5.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v5.NAME_ = 'comName'
LEFT JOIN act_hi_varinst v6 ON v6.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v6.NAME_ = 'proId'
LEFT JOIN act_hi_varinst v7 ON v7.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v7.NAME_ = 'proName'
LEFT JOIN act_hi_varinst v8 ON v8.PROC_INST_ID_ = RES.PROC_INST_ID_ AND v8.NAME_ = 'businessKey'
left join act_hi_comment ahc on ahc.TASK_ID_ = RES.ID_ AND ahc.PROC_INST_ID_ is not NULL
WHERE
RES.ASSIGNEE_ is not null and RES.END_TIME_ is not null)

View File

@ -3,6 +3,7 @@ package com.yanzhu.system.api;
import com.yanzhu.common.core.constant.SecurityConstants;
import com.yanzhu.common.core.constant.ServiceNameConstants;
import com.yanzhu.common.core.domain.R;
import com.yanzhu.common.core.web.domain.AjaxResult;
import com.yanzhu.system.api.domain.SysUser;
import com.yanzhu.system.api.factory.RemoteFileFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
@ -38,4 +39,14 @@ public interface RemoteProService
*/
@GetMapping("/proProjectInfoUsers/projects/{userId}")
public R<List<Map<String, Object>>> getProjects(@PathVariable("userId") Long userId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
*
*
* @param busKey
* @param source
* @return
*/
@GetMapping("/proProjectInfoSubdeptsUsers/approveSubDeptsUser/{busKey}")
public R<AjaxResult> approveSubDeptsUser(@PathVariable("busKey") Long busKey, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@ -1,6 +1,7 @@
package com.yanzhu.system.api.factory;
import com.yanzhu.common.core.domain.R;
import com.yanzhu.common.core.web.domain.AjaxResult;
import com.yanzhu.system.api.RemoteProService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -37,6 +38,12 @@ public class RemoteProFallbackFactory implements FallbackFactory<RemoteProServic
{
return R.fail("获取用户项目信息失败:" + throwable.getMessage());
}
@Override
public R<AjaxResult> approveSubDeptsUser(Long busKey, String source)
{
return R.fail("审批通过信息同步失败:" + throwable.getMessage());
}
};
}
}

View File

@ -56,7 +56,7 @@ public class BaseEntity implements Serializable
/** 选中项目 */
private String activeProjectName;
/** 选中页签 */
/** 选中用户 */
private Long currentUserId;
/** 数据来源 */

View File

@ -19,9 +19,6 @@ public class FlowTaskEntity extends BaseEntity {
private String businessKey;
@ApiModelProperty("业务名称")
private String businessKeyName;
@ApiModelProperty("任务编号")
private String taskId;
@ -40,9 +37,6 @@ public class FlowTaskEntity extends BaseEntity {
@ApiModelProperty("部门名称")
private String deptName;
@ApiModelProperty("流程发起人部门名称")
private String startDeptName;
@ApiModelProperty("任务执行人名称")
private String assigneeName;
@ -55,6 +49,9 @@ public class FlowTaskEntity extends BaseEntity {
@ApiModelProperty("流程发起人名称")
private String startUserName;
@ApiModelProperty("流程发起人单位")
private String startDeptName;
@ApiModelProperty("流程类型")
private String category;
@ -91,10 +88,6 @@ public class FlowTaskEntity extends BaseEntity {
@ApiModelProperty("候选执行人")
private String candidate;
@ApiModelProperty("任务创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@ApiModelProperty("任务完成时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date finishTime;
@ -102,38 +95,24 @@ public class FlowTaskEntity extends BaseEntity {
@ApiModelProperty("任务完成类型")
private String taskComType;
private long deptId;
private long projectId;
@ApiModelProperty("公司主键")
private String startComId;
@ApiModelProperty("公司名称")
private String startComName;
@ApiModelProperty("项目单位")
private String startProId;
@ApiModelProperty("项目单位名称")
private String startProName;
@ApiModelProperty("单位祖籍列表")
private String deptAncestors;
public long getDeptId() {
return deptId;
}
public void setDeptId(long deptId) {
this.deptId = deptId;
}
public long getProjectId() {
return projectId;
}
public void setProjectId(long projectId) {
this.projectId = projectId;
}
@ApiModelProperty("角色列表")
private List<Long> roleIds;
public String getBusinessKeyName() {
return businessKeyName;
}
public void setBusinessKeyName(String businessKeyName) {
this.businessKeyName = businessKeyName;
}
public String getTaskId() {
return taskId;
}
@ -318,16 +297,6 @@ public class FlowTaskEntity extends BaseEntity {
this.candidate = candidate;
}
@Override
public Date getCreateTime() {
return createTime;
}
@Override
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getFinishTime() {
return finishTime;
}
@ -360,6 +329,38 @@ public class FlowTaskEntity extends BaseEntity {
this.taskComType = taskComType;
}
public String getStartComId() {
return startComId;
}
public void setStartComId(String startComId) {
this.startComId = startComId;
}
public String getStartComName() {
return startComName;
}
public void setStartComName(String startComName) {
this.startComName = startComName;
}
public String getStartProId() {
return startProId;
}
public void setStartProId(String startProId) {
this.startProId = startProId;
}
public String getStartProName() {
return startProName;
}
public void setStartProName(String startProName) {
this.startProName = startProName;
}
public String getDeptAncestors() {
return deptAncestors;
}
@ -367,4 +368,6 @@ public class FlowTaskEntity extends BaseEntity {
public void setDeptAncestors(String deptAncestors) {
this.deptAncestors = deptAncestors;
}
}

View File

@ -14,9 +14,15 @@ import lombok.Data;
@ApiModel("工作流任务相关--请求参数")
public class FlowQueryVo {
@ApiModelProperty("项目单位")
private String proName;
@ApiModelProperty("流程名称")
private String name;
@ApiModelProperty("流程分类")
private String category;
@ApiModelProperty("开始时间")
private String startTime;

View File

@ -1,7 +1,6 @@
package com.yanzhu.flowable.mapper;
import com.yanzhu.flowable.domain.my.FlowTaskEntity;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@ -25,13 +24,6 @@ public interface FlowBusinessKeyMapper {
*/
public FlowTaskEntity findFlowTaskByProcInsId(String procInsId);
/**
*
* @param proId
* @return
*/
public Map<String,Object> selectSurProjectById(Long proId);
/**
* Id
* @param procInsId
@ -74,39 +66,4 @@ public interface FlowBusinessKeyMapper {
*/
public List<Map<String, Object>> selectMyFinishedFlowTask(FlowTaskEntity flowTaskEntity);
public List<FlowTaskEntity> groupByCategory(FlowTaskEntity where);
public List<FlowTaskEntity> groupByUnit(FlowTaskEntity where);
public List<FlowTaskEntity> listByUnit(FlowTaskEntity where);
public List<FlowTaskEntity> listByState(FlowTaskEntity where);
public List<FlowTaskEntity> groupByUnitTotal(FlowTaskEntity where);
public List<FlowTaskEntity> groupByUnitFinish(FlowTaskEntity where);
public List<FlowTaskEntity> groupByProject(@Param("deptId")long deptId,@Param("proType")String proType);
/**
*
* @param flowTaskEntity
* @return
*/
public List<FlowTaskEntity> findSafetyWorkList(FlowTaskEntity flowTaskEntity);
public List<FlowTaskEntity> listByCategory(FlowTaskEntity where);
/**
* -
* @param where
* @return
*/
public List<FlowTaskEntity> groupFlowBySubDeptType(FlowTaskEntity where);
/**
* -
* @param where
* @return
*/
public List<FlowTaskEntity> listFlowBySubDeptType(FlowTaskEntity where);
}

View File

@ -77,12 +77,18 @@ public class BusTrainingVideoUser extends BaseEntity
private String trainTitle;
/** 培训类型 */
@Excel(name = "培训类型")
private String trainType;
/** 培训类型 */
@Excel(name = "培训类型")
private String trainTypeName;
/** 培训级别 */
private String trainLevel;
/** 培训级别 */
@Excel(name = "培训级别")
private String trainLevel;
private String trainLevelName;
/** 培训文件地址 */
@Excel(name = "培训文件地址")
@ -253,6 +259,22 @@ public class BusTrainingVideoUser extends BaseEntity
this.playDates = playDates;
}
public String getTrainTypeName() {
return trainTypeName;
}
public void setTrainTypeName(String trainTypeName) {
this.trainTypeName = trainTypeName;
}
public String getTrainLevelName() {
return trainLevelName;
}
public void setTrainLevelName(String trainLevelName) {
this.trainLevelName = trainLevelName;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -78,19 +78,19 @@ public class ProProjectInfoSubdepts extends BaseEntity
@Excel(name = "合同承包内容")
private String contractInfos;
/** 进场时间 */
/** 进时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "进场时间")
@Excel(name = "进时间")
private Date useDates;
/** 进场时间 */
/** 计划开工时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "进场时间")
@Excel(name = "计划开工时间")
private Date startWorkDates;
/** 进场时间 */
/** 计划完工时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "进场时间")
@Excel(name = "计划完工时间")
private Date endWorkDates;
/** 进场状态 */

View File

@ -57,6 +57,7 @@ public class ProProjectInfoSubdeptsUsers extends BaseEntity
/** 单位类型 */
private String subDeptType;
private String subDeptTypeName;
/** 用户主键 */
@ -139,6 +140,9 @@ public class ProProjectInfoSubdeptsUsers extends BaseEntity
/** 劳务人员学历 */
private String degreeGrade;
/** 劳务人员学历 */
private String degreeGradeName;
/**
*
*/
@ -483,6 +487,22 @@ public class ProProjectInfoSubdeptsUsers extends BaseEntity
this.qrCode = qrCode;
}
public String getSubDeptTypeName() {
return subDeptTypeName;
}
public void setSubDeptTypeName(String subDeptTypeName) {
this.subDeptTypeName = subDeptTypeName;
}
public String getDegreeGradeName() {
return degreeGradeName;
}
public void setDegreeGradeName(String degreeGradeName) {
this.degreeGradeName = degreeGradeName;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@ -4,47 +4,23 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yanzhu.flowable.mapper.FlowBusinessKeyMapper">
<!-- fa.procInsId,-->
<!-- fa.deployId,-->
<!-- fa.createTime,-->
<!-- fa.finishTime,-->
<!-- fa.duration,-->
<!-- fa.procDefKey,-->
<!-- fa.procDefName,-->
<!-- fa.procDefVersion,-->
<!-- fa.category,-->
<!-- fa.businessKey,-->
<!-- fa.businessDeptId,-->
<!-- fa.businessKeyName,-->
<!-- fa.startUserId,-->
<!-- fa.startUserName,-->
<!-- fa.startDeptName,-->
<!-- fa.taskId,-->
<!-- fa.taskName,-->
<!-- fa.assigneeId,-->
<!-- fa.assigneeName,-->
<!-- fa.assigneeDeptName-->
<select id="selectAllFlowTaskByParams" parameterType="FlowTaskEntity" resultType="FlowTaskEntity">
SELECT * FROM
vw_flow_all fa
SELECT * FROM vw_flow_all fa
<where>
<if test="taskName != null and taskName != ''"> and fa.taskName like concat('%', #{taskName}, '%')</if>
<if test="procDefName != null and procDefName != ''"> and fa.procDefName like concat('%', #{procDefName}, '%')</if>
<if test="procDefKey != null and procDefKey != ''"> and fa.procDefKey = #{procDefKey}</if>
<if test="businessKey != null and businessKey != ''"> and fa.businessKey = #{businessKey}</if>
<if test="startDeptName != null and startDeptName != ''"> and fa.startDeptName like concat('%', #{startDeptName}, '%')</if>
<if test="startUserId != null and startUserId != ''"> and fa.startUserId = #{startUserId}</if>
<if test="startUserName != null and startUserName != ''"> and fa.startUserName like concat('%', #{startUserName}, '%')</if>
<if test="businessKeyName != null and businessKeyName != ''"> and fa.businessKeyName like concat('%', #{businessKeyName}, '%')</if>
<if test="startDeptName != null and startDeptName != ''"> and fa.startDeptName like concat('%', #{startDeptName}, '%')</if>
<if test="category != null and category != ''"> and fa.category = #{category}</if>
<if test="params.beginDate != null and params.beginDate != '' and params.endDate != null and params.endDate != ''"> and fa.createTime between #{params.beginDate} and #{params.endDate}</if>
<if test="params.beginTime != null and params.beginTime != '' and params.endTime != null and params.endTime != ''"> and date(fa.createTime) between #{params.beginTime} and #{params.endTime}</if>
<!-- 查询条件-项目部门 -->
<if test="projectDeptId != null "> and fa.businessDeptId = #{projectDeptId}</if>
<!--子部门数据-->
<if test='nowRole == "4"'> and fa.businessDeptId = #{nowDept}</if>
<!--监理单位/总包公司/分包单位查询当前关联数据-->
<if test='nowRole == "5" or nowRole == "6" or nowRole == "7"'> and fa.businessKey in (select DISTINCT projectId from sur_project_unit_info where unitId=#{nowDept} and del_flag=0)</if>
<!--普通用户查询项目人员-->
<if test='nowRole == "15" or nowRole == "16" or nowRole == "17" or nowRole == "99"'> and fa.startUserId = #{nowUser}</if>
<if test="startComId != null and startComId != ''"> and fa.startComId = #{startComId}</if>
<if test="startComName != null and startComName != ''"> and fa.startComName like concat('%', #{startComName}, '%')</if>
<if test="startProId != null and startProId != ''"> and fa.startProId = #{startProId}</if>
<if test="startProName != null and startProName != ''"> and fa.startProName like concat('%', #{startProName}, '%')</if>
<if test='activeTags == "await"'> and fa.finishTime is null</if>
<if test='activeTags == "finished"'> and fa.finishTime is not null</if>
</where>
@ -53,581 +29,106 @@
<!--查询工作流任务-->
<select id="findFlowTaskByProcInsId" parameterType="string" resultType="FlowTaskEntity">
select vf.* as startUserPhone from vw_flow_all vf
where vf.procInsId = #{procInsId}
select * from vw_flow_all where procInsId = #{procInsId}
</select>
<!--查询工作流操作日志-->
<select id="selectCommentByProcInsId" parameterType="string" resultType="map">
<select id="selectCommentByProcInsId" parameterType="string" resultType="Map">
select * from vw_flow_comment where procInstId = #{procInstId} order by startTime DESC
</select>
<select id="selectLastCommentByProcInsId" parameterType="string" resultType="map">
<select id="selectLastCommentByProcInsId" parameterType="string" resultType="Map">
select * from vw_flow_comment where procInstId = #{procInstId} order by startTime DESC limit 1
</select>
<!--查询工作流携带的参数-->
<select id="selectFormDatasByProcInsId" parameterType="string" resultType="map">
<select id="selectFormDatasByProcInsId" parameterType="string" resultType="Map">
select hv.NAME_ as `name`,hv.TEXT_ as text from act_hi_varinst hv where hv.PROC_INST_ID_ = #{procInstId}
</select>
<!--查询我的代办任务-->
<select id="selectMyAwaitFlowTask" parameterType="FlowTaskEntity" resultType="map">
<select id="selectMyAwaitFlowTask" parameterType="FlowTaskEntity" resultType="Map">
select fa.* from vw_flow_await fa
where
1=1
fa.taskName != '申请人提交'
<if test="procDefName != null and procDefName != ''"> and fa.procDefName like concat('%', #{procDefName}, '%')</if>
<if test="businessKey != null and businessKey != ''"> and fa.businessKey = #{businessKey}</if>
<if test="businessKeyName != null and businessKeyName != ''"> and fa.businessKeyName like concat('%', #{businessKeyName}, '%')</if>
<if test="startUserId != null and startUserId != ''"> and fa.startUserId = #{startUserId}</if>
<if test="startUserName != null and startUserName != ''"> and fa.startUserName like concat('%', #{startUserName}, '%')</if>
<if test="startDeptName != null and startDeptName != ''"> and fa.startDeptName like concat('%', #{startDeptName}, '%')</if>
<if test="category != null and category != ''"> and fa.category = #{category}</if>
<if test="params.beginDate != null and params.beginDate != '' and params.endDate != null and params.endDate != ''"> and fa.createTime between #{params.beginDate} and #{params.endDate}</if>
<if test="params.beginTime != null and params.beginTime != '' and params.endTime != null and params.endTime != ''"> and date(fa.createTime) between #{params.beginTime} and #{params.endTime}</if>
<!-- 查询条件-项目部门 -->
<if test="projectDeptId != null "> and fa.businessDeptId = #{projectDeptId}</if>
<!--子部门数据-->
<if test='nowRole == "4"'> and fa.businessDeptId = #{nowDept}</if>
<!--监理单位/总包公司/分包单位查询当前关联数据-->
<if test='nowRole == "5" or nowRole == "6" or nowRole == "7"'> and fa.businessKey in (select DISTINCT projectId from sur_project_unit_info where unitId=#{nowDept} and del_flag=0)</if>
<!--普通用户查询项目人员-->
<if test='nowRole == "15" or nowRole == "16" or nowRole == "17" or nowRole == "99"'> and fa.businessKey in (select DISTINCT project_id from sur_project_userinfo where user_id=#{nowUser} and is_del=0)</if>
AND (fa.ASSIGNEE_ = #{nowUser}
OR (
fa.ASSIGNEE_ IS NULL
AND (
fa.USER_ID_ = #{nowUser}
<if test="startComId != null and startComId != ''"> and fa.startComId = #{startComId}</if>
<if test="startComName != null and startComName != ''"> and fa.startComName like concat('%', #{startComName}, '%')</if>
<if test="startProId != null and startProId != ''"> and fa.startProId = #{startProId}</if>
<if test="startProName != null and startProName != ''"> and fa.startProName like concat('%', #{startProName}, '%')</if>
<if test="assigneeId != null and roleIds != null and roleIds.size()>0">
AND (fa.ASSIGNEE_ = #{assigneeId}
OR (
fa.GROUP_ID_ IN
<foreach collection="roleIds" item="roleId" open="(" separator="," close=")">
#{roleId}
</foreach>
fa.ASSIGNEE_ IS NULL
AND (
fa.USER_ID_ = #{assigneeId}
OR (
fa.GROUP_ID_ IN
<foreach collection="roleIds" item="roleId" open="(" separator="," close=")">
#{roleId}
</foreach>
)
)
)
)
)
</if>
order by fa.createTime desc
</select>
<!--根据条件查询我的代办分组数量统计-->
<select id="findAwaitCountGroupByCategory" parameterType="FlowTaskEntity" resultType="map">
select fa.category,count(1) as total from vw_flow_await fa
where
1=1
<select id="findAwaitCountGroupByCategory" parameterType="FlowTaskEntity" resultType="Map">
select fa.category, count(1) as total from vw_flow_await fa where 1=1
<if test="procDefName != null and procDefName != ''"> and fa.procDefName like concat('%', #{procDefName}, '%')</if>
<if test="businessKey != null and businessKey != ''"> and fa.businessKey = #{businessKey}</if>
<if test="businessKeyName != null and businessKeyName != ''"> and fa.businessKeyName like concat('%', #{businessKeyName}, '%')</if>
<if test="params.beginDate != null and params.beginDate != '' and params.endDate != null and params.endDate != ''"> and fa.createTime between #{params.beginDate} and #{params.endDate}</if>
<if test="startUserId != null and startUserId != ''"> and fa.startUserId = #{startUserId}</if>
<if test="startUserName != null and startUserName != ''"> and fa.startUserName like concat('%', #{startUserName}, '%')</if>
<if test="startDeptName != null and startDeptName != ''"> and fa.startDeptName like concat('%', #{startDeptName}, '%')</if>
<if test="params.beginTime != null and params.beginTime != '' and params.endTime != null and params.endTime != ''"> and date(fa.createTime) between #{params.beginTime} and #{params.endTime}</if>
<!-- 查询条件-项目部门 -->
<if test="projectDeptId != null "> and fa.businessDeptId = #{projectDeptId}</if>
<!--子部门数据-->
<if test='nowRole == "4"'> and fa.businessDeptId = #{nowDept}</if>
<!--监理单位/总包公司/分包单位查询当前关联数据-->
<if test='nowRole == "5" or nowRole == "6" or nowRole == "7"'> and fa.businessKey in (select DISTINCT projectId from sur_project_unit_info where unitId=#{nowDept} and del_flag=0)</if>
<!--普通用户查询项目人员-->
<if test='nowRole == "15" or nowRole == "16" or nowRole == "17" or nowRole == "99"'> and fa.businessKey in (select DISTINCT project_id from sur_project_userinfo where user_id=#{nowUser} and is_del=0)</if>
AND (fa.ASSIGNEE_ = #{nowUser}
OR (
fa.ASSIGNEE_ IS NULL
AND (
fa.USER_ID_ = #{nowUser}
OR (
fa.GROUP_ID_ IN
<foreach collection="roleIds" item="roleId" open="(" separator="," close=")">
#{roleId}
</foreach>
)
)
)
)
<if test="startComId != null and startComId != ''"> and fa.startComId = #{startComId}</if>
<if test="startComName != null and startComName != ''"> and fa.startComName like concat('%', #{startComName}, '%')</if>
<if test="startProId != null and startProId != ''"> and fa.startProId = #{startProId}</if>
<if test="startProName != null and startProName != ''"> and fa.startProName like concat('%', #{startProName}, '%')</if>
AND (fa.ASSIGNEE_ = #{assigneeId}
OR (
fa.ASSIGNEE_ IS NULL
AND ( fa.USER_ID_ = #{assigneeId}
OR (
fa.GROUP_ID_ IN
<foreach collection="roleIds" item="roleId" open="(" separator="," close=")">
#{roleId}
</foreach>
)
)
)
)
group by fa.category
</select>
<!--查询我的已办任务-->
<select id="selectMyFinishedFlowTask" parameterType="FlowTaskEntity" resultType="map">
<select id="selectMyFinishedFlowTask" parameterType="FlowTaskEntity" resultType="Map">
select fa.* from vw_flow_finished fa
where
fa.ASSIGNEE_=#{nowUser}
fa.ASSIGNEE_=#{assigneeId}
<if test="procDefName != null and procDefName != ''"> and fa.procDefName like concat('%', #{procDefName}, '%')</if>
<if test="businessKey != null and businessKey != ''"> and fa.businessKey = #{businessKey}</if>
<if test="businessKeyName != null and businessKeyName != ''"> and fa.businessKeyName like concat('%', #{businessKeyName}, '%')</if>
<if test="startUserId != null and startUserId != ''"> and fa.startUserId = #{startUserId}</if>
<if test="startUserName != null and startUserName != ''"> and fa.startUserName like concat('%', #{startUserName}, '%')</if>
<if test="startDeptName != null and startDeptName != ''"> and fa.startDeptName like concat('%', #{startDeptName}, '%')</if>
<if test="category != null and category != ''"> and fa.category = #{category}</if>
<if test="params.beginDate != null and params.beginDate != '' and params.endDate != null and params.endDate != ''"> and fa.endTime between #{params.beginDate} and #{params.endDate}</if>
<if test="startComId != null and startComId != ''"> and fa.startComId = #{startComId}</if>
<if test="startComName != null and startComName != ''"> and fa.startComName like concat('%', #{startComName}, '%')</if>
<if test="startProId != null and startProId != ''"> and fa.startProId = #{startProId}</if>
<if test="startProName != null and startProName != ''"> and fa.startProName like concat('%', #{startProName}, '%')</if>
<if test="params.beginTime != null and params.beginTime != '' and params.endTime != null and params.endTime != ''"> and fa.endTime between #{params.beginTime} and #{params.endTime}</if>
order by fa.endTime desc
</select>
<select id="groupByCategory" parameterType="FlowTaskEntity" resultType="FlowTaskEntity">
SELECT a.dict_label taskName,b.cnt assigneeId,c.cnt procDefVersion FROM
( SELECT * FROM sys_dict_data WHERE dict_type = 'sys_process_category') a
LEFT JOIN (SELECT category,COUNT(1) cnt FROM vw_flow_all WHERE finishTime IS NOT NULL
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
GROUP BY category) b ON a.dict_value=b.category
LEFT JOIN (SELECT category,COUNT(1) cnt FROM vw_flow_all WHERE finishTime IS NULL and taskName!='提交申请'
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
GROUP BY category) c ON a.dict_value=c.category
</select>
<select id="groupByUnit" parameterType="FlowTaskEntity" resultType="FlowTaskEntity">
SELECT cat taskName, COUNT(1) assigneeId FROM (
SELECT *,'总包单位' cat FROM vw_flow_all WHERE finishTime IS NULL AND taskName LIKE '总包%'
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
UNION
SELECT *,'监理单位' cat FROM vw_flow_all WHERE finishTime IS NULL AND taskName LIKE '监理%'
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
UNION
SELECT *,'设计单位' cat FROM vw_flow_all WHERE finishTime IS NULL AND taskName LIKE '设计%'
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
UNION
SELECT *,'甲方代表' cat FROM vw_flow_all WHERE finishTime IS NULL AND taskName LIKE '甲方%'
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
UNION
SELECT *,'子公司' cat FROM vw_flow_all WHERE finishTime IS NULL AND taskName LIKE '工程%'
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
) a
GROUP BY cat
</select>
<select id="groupByUnitFinish" parameterType="FlowTaskEntity" resultType="FlowTaskEntity">
SELECT cat taskName, COUNT(1) assigneeId FROM (
SELECT *,'总包单位' cat FROM vw_flow_all WHERE taskName LIKE '总包%' AND taskName!='提交申请' and finishTime IS not NULL
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
UNION
SELECT *,'监理单位' cat FROM vw_flow_all WHERE taskName LIKE '监理%' AND taskName!='提交申请' and finishTime IS not NULL
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
UNION
SELECT *,'设计单位' cat FROM vw_flow_all WHERE taskName LIKE '设计%' AND taskName!='提交申请' and finishTime IS not NULL
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
UNION
SELECT *,'甲方代表' cat FROM vw_flow_all WHERE taskName LIKE '甲方%' AND taskName!='提交申请' and finishTime IS not NULL
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
UNION
SELECT *,'子公司' cat FROM vw_flow_all WHERE taskName LIKE '工程%' AND taskName!='提交申请' and finishTime IS not NULL
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
) a
GROUP BY cat
</select>
<select id="groupByUnitTotal" parameterType="FlowTaskEntity" resultType="FlowTaskEntity">
SELECT cat taskName, COUNT(1) assigneeId FROM (
SELECT *,'总包单位' cat FROM vw_flow_all WHERE taskName LIKE '总包%' AND taskName!='提交申请'
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
UNION
SELECT *,'监理单位' cat FROM vw_flow_all WHERE taskName LIKE '监理%' AND taskName!='提交申请'
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
UNION
SELECT *,'设计单位' cat FROM vw_flow_all WHERE taskName LIKE '设计%' AND taskName!='提交申请'
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
UNION
SELECT *,'甲方代表' cat FROM vw_flow_all WHERE taskName LIKE '甲方%' AND taskName!='提交申请'
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
UNION
SELECT *,'子公司' cat FROM vw_flow_all WHERE taskName LIKE '工程%' AND taskName!='提交申请'
<if test="projectDeptId !=null and projectDeptId!=''">and businessDeptId=#{projectDeptId}</if>
<if test="businessKey !=null and businessKey!=''">and businessKey=#{businessKey}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
) a
GROUP BY cat
</select>
<select id="listByCategory" parameterType="FlowTaskEntity" resultType="FlowTaskEntity">
SELECT * FROM vw_flow_all
<where>
<if test="category != null and category != ''"> and category = #{category}</if>
<if test="deptId !=null and deptId>0">and businessDeptId=#{deptId}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="projectId !=null and projectId>0">and businessKey=#{projectId}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
</where>
</select>
<select id="listByUnit" parameterType="FlowTaskEntity" resultType="FlowTaskEntity">
SELECT * FROM vw_flow_all WHERE finishTime IS NULL
<if test="taskId!=null">
<if test="taskId==1"> AND taskName LIKE '总包%' </if>
<if test="taskId==2"> AND taskName LIKE '监理%' </if>
<if test="taskId==3"> AND taskName LIKE '设计%' </if>
<if test="taskId==4"> AND taskName LIKE '甲方%' </if>
<if test="taskId==5"> AND taskName LIKE '工程%' </if>
</if>
<if test="deptId !=null and deptId>0">and businessDeptId=#{deptId}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="projectId !=null and projectId>0">and businessKey=#{projectId}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
</select>
<select id="listByState" parameterType="FlowTaskEntity" resultType="FlowTaskEntity">
SELECT * FROM vw_flow_all
<where>
<if test="taskId!=null">
<if test="taskId==1"> AND taskName!='提交申请' </if>
<if test="taskId==2"> AND finishTime IS NULL AND taskName!='提交申请' </if>
<if test="taskId==3"> AND finishTime IS NOT NULL </if>
</if>
<if test="deptId !=null and deptId>0">and businessDeptId=#{deptId}</if>
<if test="projectId !=null and projectId>0">and businessKey=#{projectId}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
<if test="prjIds !=null and prjIds.size()>0">
and businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
</where>
</select>
<select id="groupByProject" resultType="FlowTaskEntity" parameterType="long">
SELECT a.businessKey,a.cnt duration ,b.projectName businessKeyName FROM (
SELECT businessKey,COUNT(1) cnt FROM vw_flow_all WHERE taskName!='提交申请'
<if test="deptId !=null and deptId>0">and businessDeptId=#{deptId}</if>
<if test="proType != null and proType != ''"> and businessType = #{proType}</if>
GROUP BY businessKey ) a,sur_project b WHERE a.businessKey=b.id
ORDER BY a.cnt DESC
</select>
<select id="findSafetyWorkList" parameterType="FlowTaskEntity" resultType="FlowTaskEntity">
SELECT
fa.procInsId,
fa.deployId,
fa.createTime,
fa.finishTime,
fa.duration,
fa.procDefKey,
fa.procDefName,
fa.procDefVersion,
fa.category,
fa.businessKey,
fa.businessDeptId,
fa.businessKeyName,
fa.startUserId,
fa.startUserName,
fa.startDeptName,
fa.taskId,
fa.taskName,
fa.assigneeId,
fa.assigneeName,
fa.assigneeDeptName
FROM
vw_flow_all fa
<where>
<if test="proType != null and proType != ''"> and fa.businessType = #{proType}</if>
<if test="procDefKey != null and procDefKey != ''"> and fa.procDefKey = #{procDefKey}</if>
<if test="businessKey != null and businessKey != ''"> and fa.businessKey = #{businessKey}</if>
<!-- 查询条件-项目部门 -->
<if test="projectDeptId != null and projectDeptId != ''"> and fa.businessDeptId = #{projectDeptId}</if>
</where>
order by fa.createTime desc
</select>
<select id="selectSurProjectById" parameterType="Long" resultType="Map">
select * from sur_project where id = #{proId}
</select>
<select id="groupFlowBySubDeptType" parameterType="FlowTaskEntity" resultType="FlowTaskEntity">
select x.dict_label taskName,y.taskId from (
select dict_value,dict_label
from sys_dict_data where dict_type='flow_sub_dept_type'
) x left join (
SELECT d.dict_value, d.dict_label,count(1) taskId FROM
vw_flow_all a
LEFT JOIN act_hi_varinst b ON a.procInsId=b.PROC_INST_ID_ AND b.NAME_='subDeptType'
LEFT JOIN act_hi_varinst c ON a.procInsId=c.PROC_INST_ID_ AND c.NAME_='subDeptName'
LEFT JOIN sys_dict_data D ON b.TEXT_=d.dict_value and d.dict_type='flow_sub_dept_type'
left join sur_project sp on a.businesskey=sp.id
where a.procDefKey='flow_fbzzsp_fbszzsp'
AND (A.finishTime is null OR (A.finishTime is not null and A.taskComType =1))
and sp.progressVisible=0 and sp.isDel=0
<if test="deptId !=null and deptId>0">and a.businessDeptId=#{deptId}</if>
<if test="projectId !=null and projectId>0">and a.businessKey=#{projectId}</if>
<if test="prjIds !=null and prjIds.size()>0">
and a.businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
<if test="proType != null and proType != ''"> and sp.projectType = #{proType}</if>
group by d.dict_value,d.dict_label
) y on x.dict_value=y.dict_value
</select>
<select id="listFlowBySubDeptType" parameterType="FlowTaskEntity" resultType="FlowTaskEntity">
SELECT a.procInsId,a.deployId,a.createTime,a.finishTime,a.businessKey,a.businessKeyName,a.startDeptName,b.TEXT_ as taskId, c.TEXT_ as deptName,d.dict_label taskName FROM
vw_flow_all a
LEFT JOIN act_hi_varinst b ON a.procInsId=b.PROC_INST_ID_ AND b.NAME_='subDeptType'
LEFT JOIN act_hi_varinst c ON a.procInsId=c.PROC_INST_ID_ AND c.NAME_='subDeptName'
LEFT JOIN sys_dict_data D ON b.TEXT_=d.dict_value and d.dict_type='flow_sub_dept_type'
left join sur_project sp on a.businesskey=sp.id
where a.procDefKey='flow_fbzzsp_fbszzsp'
AND (A.finishTime is null OR (A.finishTime is not null and A.taskComType =1))
and sp.progressVisible=0 and sp.isDel=0
<if test="deptId !=null and deptId>0">and a.businessDeptId=#{deptId}</if>
<if test="projectId !=null and projectId>0">and a.businessKey=#{projectId}</if>
<if test="prjIds !=null and prjIds.size()>0">
and a.businessKey in
<foreach collection="prjIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
<if test="proType != null and proType != ''"> and sp.projectType = #{proType}</if>
</select>
<select id="selectDeployList" resultType="FlowProcDefDto">
SELECT
rp.id_ as id,
rp.deployment_id_ as deploymentId,
rd.name_ as name,
rd.category_ as category,
rp.key_ as flowKey,
rp.version_ as version,
rp.suspension_state_ as suspensionState,
rd.deploy_time_ as deploymentTime,
rpd.DEPT_ID_ as deptId,
sd.dept_name as deptName,
rpd.PROJ_ID_ as projectId,
spi.project_name as projectName
FROM
act_re_procdef rp
LEFT JOIN act_re_deployment rd ON rp.deployment_id_ = rd.id_
left join act_re_procdef_dept rpd on rp.id_ = rpd.PROCDEF_ID_
left join sys_dept sd on sd.dept_id = rpd.DEPT_ID_
left join pro_project_info spi on spi.id = rpd.PROJ_ID_
<where>
rp.SUSPENSION_STATE_ = 1
<if test="deptId != null">
and rpd.DEPT_ID_ = #{deptId}
</if>
<if test="deptName != null and deptName != ''">
and sd.dept_name like concat('%', #{deptName}, '%')
</if>
<if test="projectId != null">
and rpd.PROJ_ID_ = #{projectId}
</if>
<if test="projectName != null and projectName != ''">
and spi.project_name like concat('%', #{projectName}, '%')
</if>
<if test="name != null and name != ''">
and rd.name_ like concat('%', #{name}, '%')
</if>
<if test="category != null and category != ''">
and rd.category_ = #{category}
</if>
<if test="flowKey != null and flowKey != ''">
and rd.key_ = #{flowKey}
</if>
</where>
order by rpd.SORT_
</select>
<select id="selectMyDeployList" resultType="FlowProcDefDto">
SELECT * FROM (
SELECT
rp.id_ as id,
rp.deployment_id_ as deploymentId,
rd.name_ as name,
rd.category_ as category,
sdd.dict_label as categoryName,
rp.key_ as flowKey,
rp.version_ as version,
rp.suspension_state_ as suspensionState,
rd.deploy_time_ as deploymentTime,
ROW_NUMBER () OVER (
PARTITION BY rp.key_
ORDER BY
rp.version_ DESC
) AS rn
FROM
act_re_procdef rp
LEFT JOIN act_re_deployment rd ON rp.deployment_id_ = rd.id_
left join sys_dict_data sdd on sdd.dict_type='sys_process_category' and sdd.dict_value = rd.category_
left join act_re_procdef_role rpr on rp.key_ = rpr.PROCDEF_KEY_
left join sys_user_role sur on sur.role_id = rpr.ROLE_ID_
left join sys_user su on su.user_id = sur.user_id
<where>
rp.SUSPENSION_STATE_ = 1 and su.user_name = #{username}
<if test="name != null and name != ''">
and rd.name_ like concat('%', #{name}, '%')
</if>
<if test="category != null and category != ''">
and rd.category_ = #{category}
</if>
</where>
order by rd.deploy_time_ desc
) v WHERE v.rn = 1
</select>
<delete id="deleteDeployByRoleId" parameterType="string">
delete from act_re_procdef_role where ROLE_ID_ = #{roleId}
</delete>
<insert id="batchDeployRoleRole">
insert into act_re_procdef_role( PROCDEF_KEY_, ROLE_ID_) values
<foreach item="item" index="index" collection="list" separator=",">
( #{item.key}, #{item.roleId})
</foreach>
</insert>
<update id="updateProcKeyRoleSort">
update act_re_procdef_role set SORT_=#{sort} where PROCDEF_KEY_=#{key} and ROLE_ID_=#{roleId}
</update>
<!--新增项目单位流程关系-->
<insert id="insertActReProcdefDept" parameterType="FlowDeptVo">
insert into act_re_procdef_dept
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="procdefId != null">PROCDEF_ID_,</if>
<if test="prtype != null">TYPE_,</if>
<if test="deptId != null">DEPT_ID_,</if>
<if test="projId != null">PROJ_ID_,</if>
<if test="sort != null">SORT_,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="procdefId != null">#{procdefId},</if>
<if test="prtype != null">#{prtype},</if>
<if test="deptId != null">#{deptId},</if>
<if test="projId != null">#{projId},</if>
<if test="sort != null">#{sort},</if>
</trim>
</insert>
</mapper>

View File

@ -16,7 +16,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="videoId" column="video_id" />
<result property="trainTitle" column="train_title" />
<result property="trainType" column="train_type" />
<result property="trainTypeName" column="train_type_name" />
<result property="trainLevel" column="train_level" />
<result property="trainLevelName" column="train_level_name" />
<result property="trainFilePath" column="train_file_path" />
<result property="trainFileImage" column="train_file_image" />
<result property="playTimes" column="play_times" />
@ -33,12 +35,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<sql id="selectBusTrainingVideoUserVo">
select btvu.id, btvu.com_id, sd.dept_name as com_name, btvu.project_id, pi.project_name, btvu.user_id, su.nick_name as user_nick, su.user_name, btvu.video_id, btv.train_title,
btv.train_type, btv.train_level, btv.train_file_path, btv.train_file_image, btvu.play_times, btvu.play_dates,
btv.train_type, dic1.dict_label as train_type_name, btv.train_level, dic2.dict_label as train_level_name, btv.train_file_path, btv.train_file_image, btvu.play_times, btvu.play_dates,
btvu.play_status, btvu.sort_by, btvu.is_del, btvu.create_by, btvu.create_time, btvu.update_by, btvu.update_time, btvu.remark from bus_training_video_user btvu
left join bus_training_video btv on btv.id = btvu.video_id
left join pro_project_info pi on pi.id = btvu.project_id
left join sys_dept sd on sd.com_id = btvu.com_id
left join sys_user su on su.user_id = btvu.user_id
left join sys_dict_data dic1 ON btv.train_type = dic1.`dict_value` AND dic1.`dict_type`='edu_train_type'
left join sys_dict_data dic2 ON btv.train_level = dic2.`dict_value` AND dic2.`dict_type`='edu_train_level'
</sql>
<select id="selectBusTrainingVideoUserList" parameterType="BusTrainingVideoUser" resultMap="BusTrainingVideoUserResult">
@ -56,7 +60,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where>
order by btvu.id desc
</select>
<select id="selectBusTrainingVideoUserById" parameterType="Long" resultMap="BusTrainingVideoUserResult">
select * from bus_training_video_user where id = #{id}
</select>

View File

@ -13,6 +13,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="projectName" column="project_name" />
<result property="subDeptId" column="sub_dept_id" />
<result property="subDeptType" column="sub_dept_type" />
<result property="subDeptTypeName" column="sub_dept_type_name" />
<result property="subDeptName" column="sub_dept_name" />
<result property="subDeptPowerPath" column="sub_dept_power_path" />
<result property="userId" column="user_id" />
@ -42,6 +43,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="admitGuid" column="admitGuid"/>
<result property="remark" column="remark" />
<result property="degreeGrade" column="degree_grade" />
<result property="degreeGradeName" column="degree_grade_name" />
<association property="user" javaType="com.yanzhu.system.api.domain.SysUser" resultMap="ProSysUserResult"></association>
</resultMap>
@ -67,10 +69,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="loginDate" column="login_date" />
</resultMap>
<sql id="selectProProjectInfoSubdeptsUsersVo">
SELECT psu.id, psu.par_id, psu.com_id, psu.project_id, pi.project_name, psu.sub_dept_id, psu.sub_dept_type, psu.sub_dept_name, psu.sub_dept_power_path, psu.user_id, psu.sub_dept_group,
SELECT psu.id, psu.par_id, psu.com_id, psu.project_id, pi.project_name, psu.sub_dept_id, psu.sub_dept_type, dic3.dict_label as sub_dept_type_name, psu.sub_dept_name, psu.sub_dept_power_path, psu.user_id, psu.sub_dept_group,
psu.sub_dept_group_name, psu.user_post, psu.craft_type, psu.craft_post, psu.edu_status, psu.edu_file_path, psu.edu_sign_path, psu.edu_date, psu.approve_status,
psu.use_status, psu.qr_code, psu.sub_step, psu.illness_status, psu.sup_illness_status, psu.is_del, psu.create_by, psu.create_time, psu.update_by, psu.update_time,
psu.remark, psu.degree_grade, su.`user_name`,su.`nick_name`,su.`user_type`,su.`card_type`,su.`card_code`,su.admitGuid,su.admitGuid usAdmitGuid,
psu.remark, psu.degree_grade, dic4.dict_label as degree_grade_name, su.`user_name`,su.`nick_name`,su.`user_type`,su.`card_type`,su.`card_code`,su.admitGuid,su.admitGuid usAdmitGuid,
dic1.dict_label craft_type_name,dic2.dict_label craft_post_name,psu.enter_state,sd.dept_name comName,
su.`user_picture`, su.`card_img_inv`,su.`card_img_pos`,su.`user_infos`,su.`email`,su.`phonenumber`,su.`sex`,su.`avatar`,su.`login_ip`,su.`login_date`
FROM pro_project_info_subdepts_users psu
@ -79,6 +81,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
LEFT JOIN sys_dept sd ON sd.dept_id = pi.com_id
LEFT JOIN sys_dict_data dic1 ON psu.`craft_type`=dic1.`dict_value` AND dic1.`dict_type`='pro_craft_type'
LEFT JOIN sys_dict_data dic2 ON psu.`craft_post`=dic2.`dict_value` AND dic2.`dict_type`='pro_craft_post'
LEFT JOIN sys_dict_data dic3 ON psu.`sub_dept_type`=dic3.`dict_value` AND dic3.`dict_type`='sub_dept_type'
LEFT JOIN sys_dict_data dic4 ON psu.`degree_grade`=dic4.`dict_value` AND dic4.`dict_type`='educational_type'
</sql>
<select id="selectProProjectInfoSubdeptsUsersList" parameterType="ProProjectInfoSubdeptsUsers" resultMap="ProProjectInfoSubdeptsUsersResult">
@ -305,7 +309,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select>
<select id="findActReProcdefDept" resultType="Map">
select * from act_re_procdef_dept where PROJ_ID_ = #{proId} and TYPE_ = #{defType} order by SORT_ desc
select * from act_re_procdef rp
left join act_re_procdef_dept rpd on rpd.PROCDEF_ID_ = rp.ID_
where rp.SUSPENSION_STATE_ = 1 and PROJ_ID_ = #{proId} and TYPE_ = #{defType} order by SORT_ desc
</select>
</mapper>

View File

@ -103,6 +103,16 @@ public class SecurityUtils
return getLoginUser().getRoles().contains("gsAdmin");
}
/**
*
*
* @return
*/
public static boolean isXMAdmin()
{
return getLoginUser().getRoles().contains("xmAdmin");
}
/**
*
*

View File

@ -16,7 +16,8 @@ public enum FlowComment {
REJECT("3", "驳回意见"),
DELEGATE("4", "委派意见"),
ASSIGN("5", "转办意见"),
STOP("6", "终止流程");
STOP("6", "终止流程"),
REVOKE("7", "撤回流程");
/**
*

View File

@ -33,7 +33,6 @@ public class FlowableGlobalListenerConfig implements ApplicationListener<Context
* PROCESS_COMPLETED
*
*/
dispatcher.addEventListener(globalEventListener,FlowableEngineEventType.TASK_CREATED);
dispatcher.addEventListener(globalEventListener,FlowableEngineEventType.PROCESS_COMPLETED);
}

View File

@ -0,0 +1,12 @@
package com.yanzhu.flowable.constant;
/**
*
*/
public class FlowCacheConstants {
/**
*
*/
public static final String STOP_PROCESS = "STOP.PROCESS::";
}

View File

@ -1,12 +1,15 @@
package com.yanzhu.flowable.controller;
import com.yanzhu.common.core.text.Convert;
import com.yanzhu.common.core.utils.StringUtils;
import com.yanzhu.common.core.web.controller.BaseController;
import com.yanzhu.common.core.web.domain.AjaxResult;
import com.yanzhu.common.core.web.page.TableDataInfo;
import com.yanzhu.common.security.utils.SecurityUtils;
import com.yanzhu.flowable.domain.my.FlowTaskEntity;
import com.yanzhu.flowable.service.IFlowBusinessKeyService;
import com.yanzhu.system.api.domain.SysUser;
import com.yanzhu.system.api.domain.SysRole;
import com.yanzhu.system.api.model.LoginUser;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
@ -15,9 +18,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -28,8 +29,8 @@ import java.util.stream.Collectors;
* @author JiangYuQi
* @date 2024-04-03
*/
@Slf4j
@Api(tags = "业务工作流程")
@Slf4j
@RestController
@RequestMapping("/businessKey")
public class FlowBusinessKeyController extends BaseController {
@ -44,10 +45,26 @@ public class FlowBusinessKeyController extends BaseController {
*/
@GetMapping(value = "/allList")
public TableDataInfo allList(FlowTaskEntity flowTaskEntity) {
SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
//超管查询所有数据
if(!SecurityUtils.isAdmin(sysUser.getUserId())){
flowTaskEntity.setDeptAncestors(sysUser.getDept().getAncestors());
LoginUser loginUser = SecurityUtils.getLoginUser();
if(SecurityUtils.isAdmin(loginUser.getUserid())){
// TODO超管查询所有申请...
if(Objects.nonNull(loginUser.getProjectDeptId())){
flowTaskEntity.setStartComId(Convert.toStr(loginUser.getProjectDeptId()));
}
if(Objects.nonNull(loginUser.getProjectId())){
flowTaskEntity.setStartProId(Convert.toStr(loginUser.getProjectId()));
}
}else if(SecurityUtils.isGSAdmin()){
// 公司管理员查询公司内的所有申请...
flowTaskEntity.setStartComId(Convert.toStr(loginUser.getProjectDeptId()));
if(Objects.nonNull(loginUser.getProjectId())){
flowTaskEntity.setStartProId(Convert.toStr(loginUser.getProjectId()));
}
}else if(SecurityUtils.isXMAdmin()){
// 公司管理员查询公司内的所有申请...
flowTaskEntity.setStartProId(Convert.toStr(loginUser.getProjectId()));
}else{
flowTaskEntity.setStartUserId(Convert.toStr(loginUser.getUserid()));
}
startPage();
return getDataTable(flowBusinessKeyService.selectAllFlowTaskByParams(flowTaskEntity));
@ -60,10 +77,26 @@ public class FlowBusinessKeyController extends BaseController {
*/
@GetMapping(value = "/queryCount")
public AjaxResult queryCount(FlowTaskEntity flowTaskEntity) {
SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
//超管查询所有数据
if(!SecurityUtils.isAdmin(sysUser.getUserId())){
flowTaskEntity.setDeptAncestors(sysUser.getDept().getAncestors());
LoginUser loginUser = SecurityUtils.getLoginUser();
if(SecurityUtils.isAdmin(loginUser.getUserid())){
// TODO超管查询所有申请...
if(Objects.nonNull(loginUser.getProjectDeptId())){
flowTaskEntity.setStartComId(Convert.toStr(loginUser.getProjectDeptId()));
}
if(Objects.nonNull(loginUser.getProjectId())){
flowTaskEntity.setStartProId(Convert.toStr(loginUser.getProjectId()));
}
}else if(SecurityUtils.isGSAdmin()){
// 公司管理员查询公司内的所有申请...
flowTaskEntity.setStartComId(Convert.toStr(loginUser.getProjectDeptId()));
if(Objects.nonNull(loginUser.getProjectId())){
flowTaskEntity.setStartProId(Convert.toStr(loginUser.getProjectId()));
}
}else if(SecurityUtils.isXMAdmin()){
// 公司管理员查询公司内的所有申请...
flowTaskEntity.setStartProId(Convert.toStr(loginUser.getProjectId()));
}else{
flowTaskEntity.setStartUserId(Convert.toStr(loginUser.getUserid()));
}
return success(flowBusinessKeyService.quueryCount(flowTaskEntity));
}
@ -95,12 +128,27 @@ public class FlowBusinessKeyController extends BaseController {
*/
@GetMapping(value = "/myAwaitFlowTaskList")
public TableDataInfo myAwaitFlowTaskList(FlowTaskEntity flowTaskEntity) {
SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
//超管查询所有数据
if(!SecurityUtils.isAdmin(sysUser.getUserId())){
flowTaskEntity.setAssigneeId(sysUser.getUserId());
flowTaskEntity.setDeptAncestors(sysUser.getDept().getAncestors()+","+sysUser.getDeptId());
flowTaskEntity.setRoleIds(sysUser.getRoles().stream().map(role -> role.getRoleId()).collect(Collectors.toList()));
LoginUser loginUser = SecurityUtils.getLoginUser();
if(SecurityUtils.isAdmin(loginUser.getUserid())){
// TODO超管查询所有申请...
if(Objects.nonNull(loginUser.getProjectDeptId())){
flowTaskEntity.setStartComId(Convert.toStr(loginUser.getProjectDeptId()));
}
if(Objects.nonNull(loginUser.getProjectId())){
flowTaskEntity.setStartProId(Convert.toStr(loginUser.getProjectId()));
}
}else if(SecurityUtils.isGSAdmin()){
// 公司管理员查询公司内的所有申请...
flowTaskEntity.setStartComId(Convert.toStr(loginUser.getProjectDeptId()));
if(Objects.nonNull(loginUser.getProjectId())){
flowTaskEntity.setStartProId(Convert.toStr(loginUser.getProjectId()));
}
}else if(SecurityUtils.isXMAdmin()){
// 公司管理员查询公司内的所有申请...
flowTaskEntity.setStartProId(Convert.toStr(loginUser.getProjectId()));
}else{
flowTaskEntity.setAssigneeId(SecurityUtils.getUserId());
flowTaskEntity.setRoleIds(Arrays.asList(SecurityUtils.getLoginUser().getSysUser().getRoleIds()));
}
startPage();
return getDataTable(flowBusinessKeyService.selectMyAwaitFlowTask(flowTaskEntity));
@ -125,22 +173,24 @@ public class FlowBusinessKeyController extends BaseController {
@GetMapping(value = "/findMyTask")
public AjaxResult findMyTask() {
FlowTaskEntity flowTaskEntity = new FlowTaskEntity();
SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
//超管查询所有数据
if(!SecurityUtils.isAdmin(sysUser.getUserId())){
flowTaskEntity.setAssigneeId(sysUser.getUserId());
flowTaskEntity.setDeptAncestors(sysUser.getDept().getAncestors()+","+sysUser.getDeptId());
flowTaskEntity.setRoleIds(sysUser.getRoles().stream().map(role -> role.getRoleId()).collect(Collectors.toList()));
flowTaskEntity.setAssigneeId(SecurityUtils.getUserId());
List<SysRole> roles = SecurityUtils.getLoginUser().getSysUser().getRoles();
if(StringUtils.isNotEmpty(roles)){
List<Long> roleIds = roles.stream().map(SysRole::getRoleId).collect(Collectors.toList());
flowTaskEntity.setRoleIds(roleIds);
}else{
List<Long> roleIds = new ArrayList<>();
roleIds.add(0L);
flowTaskEntity.setRoleIds(roleIds);
}
List<Map<String, Object>> list = flowBusinessKeyService.selectMyAwaitFlowTask(flowTaskEntity);
Map<String,Object> data = new HashMap<>();
if(CollectionUtils.isNotEmpty(list)){
data.put("todo",list.size());
}else{
data.put("todo",0);
data.put("todo",5);
}
return success(data);
}
}

View File

@ -0,0 +1,373 @@
package com.yanzhu.flowable.flow;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
import org.flowable.common.engine.impl.util.io.StringStreamSource;
import java.util.*;
/**
* @author KonBAI
* @createTime 2022/3/26 19:04
*/
public class ModelUtils {
private static final BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter();
/**
* xmlbpmnModel
*
* @param xml xml
* @return bpmnModel
*/
public static BpmnModel getBpmnModel(String xml) {
return bpmnXMLConverter.convertToBpmnModel(new StringStreamSource(xml), false, false);
}
/**
* bpmnModelxml
*
* @deprecated bpmn 线
* @param bpmnModel bpmnModel
* @return xml
*/
@Deprecated
public static String getBpmnXmlStr(BpmnModel bpmnModel) {
return StrUtil.utf8Str(getBpmnXml(bpmnModel));
}
/**
* bpmnModelxml
*
* @deprecated bpmn 线
* @param bpmnModel bpmnModel
* @return xml
*/
@Deprecated
public static byte[] getBpmnXml(BpmnModel bpmnModel) {
return bpmnXMLConverter.convertToXML(bpmnModel);
}
/**
* 线
*
* @param source
* @return 线
*/
public static List<SequenceFlow> getElementIncomingFlows(FlowElement source) {
List<SequenceFlow> sequenceFlows = new ArrayList<>();
if (source instanceof FlowNode) {
sequenceFlows = ((FlowNode) source).getIncomingFlows();
}
return sequenceFlows;
}
/**
* 线
*
* @param source
* @return 线
*/
public static List<SequenceFlow> getElementOutgoingFlows(FlowElement source) {
List<SequenceFlow> sequenceFlows = new ArrayList<>();
if (source instanceof FlowNode) {
sequenceFlows = ((FlowNode) source).getOutgoingFlows();
}
return sequenceFlows;
}
/**
*
*
* @param model bpmnModel
* @return null
*/
public static StartEvent getStartEvent(BpmnModel model) {
Process process = model.getMainProcess();
FlowElement startElement = process.getInitialFlowElement();
if (startElement instanceof StartEvent) {
return (StartEvent) startElement;
}
return getStartEvent(process.getFlowElements());
}
/**
*
*
* @param flowElements
* @return null
*/
public static StartEvent getStartEvent(Collection<FlowElement> flowElements) {
for (FlowElement flowElement : flowElements) {
if (flowElement instanceof StartEvent) {
return (StartEvent) flowElement;
}
}
return null;
}
/**
*
*
* @param model bpmnModel
* @return null
*/
public static EndEvent getEndEvent(BpmnModel model) {
Process process = model.getMainProcess();
return getEndEvent(process.getFlowElements());
}
/**
*
*
* @param flowElements
* @return null
*/
public static EndEvent getEndEvent(Collection<FlowElement> flowElements) {
for (FlowElement flowElement : flowElements) {
if (flowElement instanceof EndEvent) {
return (EndEvent) flowElement;
}
}
return null;
}
public static UserTask getUserTaskByKey(BpmnModel model, String taskKey) {
Process process = model.getMainProcess();
FlowElement flowElement = process.getFlowElement(taskKey);
if (flowElement instanceof UserTask) {
return (UserTask) flowElement;
}
return null;
}
/**
*
*
* @param model bpmnModel
* @param flowElementId ID
* @return
*/
public static FlowElement getFlowElementById(BpmnModel model, String flowElementId) {
Process process = model.getMainProcess();
return process.getFlowElement(flowElementId);
}
/**
* Key
*
* @param flowElement
* @return Key
*/
public static String getFormKey(FlowElement flowElement) {
if (flowElement != null) {
if (flowElement instanceof StartEvent) {
return ((StartEvent) flowElement).getFormKey();
} else if (flowElement instanceof UserTask) {
return ((UserTask) flowElement).getFormKey();
}
}
return null;
}
/**
*
* @param model bpmnModel
* @param name
* @return
*/
public static String getStartEventAttributeValue(BpmnModel model, String name) {
StartEvent startEvent = getStartEvent(model);
return getElementAttributeValue(startEvent, name);
}
/**
*
* @param model bpmnModel
* @param name
* @return
*/
public static String getEndEventAttributeValue(BpmnModel model, String name) {
EndEvent endEvent = getEndEvent(model);
return getElementAttributeValue(endEvent, name);
}
/**
*
* @param model bpmnModel
* @param taskKey Key
* @param name
* @return
*/
public static String getUserTaskAttributeValue(BpmnModel model, String taskKey, String name) {
UserTask userTask = getUserTaskByKey(model, taskKey);
return getElementAttributeValue(userTask, name);
}
/**
*
* @param baseElement
* @param name
* @return
*/
public static String getElementAttributeValue(BaseElement baseElement, String name) {
if (baseElement != null) {
List<ExtensionAttribute> attributes = baseElement.getAttributes().get(name);
if (attributes != null && !attributes.isEmpty()) {
attributes.iterator().next().getValue();
Iterator<ExtensionAttribute> attrIterator = attributes.iterator();
if(attrIterator.hasNext()) {
ExtensionAttribute attribute = attrIterator.next();
return attribute.getValue();
}
}
}
return null;
}
public static boolean isMultiInstance(BpmnModel model, String taskKey) {
UserTask userTask = getUserTaskByKey(model, taskKey);
if (ObjectUtil.isNotNull(userTask)) {
return userTask.hasMultiInstanceLoopCharacteristics();
}
return false;
}
/**
*
*
* @param model bpmnModel
* @return
*/
public static Collection<UserTask> getAllUserTaskEvent(BpmnModel model) {
Process process = model.getMainProcess();
Collection<FlowElement> flowElements = process.getFlowElements();
return getAllUserTaskEvent(flowElements, null);
}
/**
*
* @param flowElements
* @param allElements
* @return
*/
public static Collection<UserTask> getAllUserTaskEvent(Collection<FlowElement> flowElements, Collection<UserTask> allElements) {
allElements = allElements == null ? new ArrayList<>() : allElements;
for (FlowElement flowElement : flowElements) {
if (flowElement instanceof UserTask) {
allElements.add((UserTask) flowElement);
}
if (flowElement instanceof SubProcess) {
// 继续深入子流程,进一步获取子流程
allElements = getAllUserTaskEvent(((SubProcess) flowElement).getFlowElements(), allElements);
}
}
return allElements;
}
/**
*
* @param source
* @return
*/
public static List<UserTask> findNextUserTasks(FlowElement source) {
return findNextUserTasks(source, null, null);
}
/**
*
* @param source
* @param hasSequenceFlow 线 ID线
* @param userTaskList
* @return
*/
public static List<UserTask> findNextUserTasks(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
hasSequenceFlow = Optional.ofNullable(hasSequenceFlow).orElse(new HashSet<>());
userTaskList = Optional.ofNullable(userTaskList).orElse(new ArrayList<>());
// 获取出口连线
List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
if (!sequenceFlows.isEmpty()) {
for (SequenceFlow sequenceFlow : sequenceFlows) {
// 如果发现连线重复,说明循环了,跳过这个循环
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
continue;
}
// 添加已经走过的连线
hasSequenceFlow.add(sequenceFlow.getId());
FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement();
if (targetFlowElement instanceof UserTask) {
// 若节点为用户任务,加入到结果列表中
userTaskList.add((UserTask) targetFlowElement);
} else {
// 若节点非用户任务,继续递归查找下一个节点
findNextUserTasks(targetFlowElement, hasSequenceFlow, userTaskList);
}
}
}
return userTaskList;
}
/**
*
* 退
* @param source
* @param target
* @param visitedElements 线 ID线
* @return
*/
public static boolean isSequentialReachable(FlowElement source, FlowElement target, Set<String> visitedElements) {
visitedElements = visitedElements == null ? new HashSet<>() : visitedElements;
if (source instanceof StartEvent && isInEventSubprocess(source)) {
return false;
}
// 根据类型,获取入口连线
List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
if (sequenceFlows != null && sequenceFlows.size() > 0) {
// 循环找到目标元素
for (SequenceFlow sequenceFlow: sequenceFlows) {
// 如果发现连线重复,说明循环了,跳过这个循环
if (visitedElements.contains(sequenceFlow.getId())) {
continue;
}
// 添加已经走过的连线
visitedElements.add(sequenceFlow.getId());
FlowElement sourceFlowElement = sequenceFlow.getSourceFlowElement();
// 这条线路存在目标节点,这条线路完成,进入下个线路
if (target.getId().equals(sourceFlowElement.getId())) {
continue;
}
// 如果目标节点为并行网关,则不继续
if (sourceFlowElement instanceof ParallelGateway) {
return false;
}
// 否则就继续迭代
boolean isSequential = isSequentialReachable(sourceFlowElement, target, visitedElements);
if (!isSequential) {
return false;
}
}
}
return true;
}
protected static boolean isInEventSubprocess(FlowElement flowElement) {
FlowElementsContainer flowElementsContainer = flowElement.getParentContainer();
while (flowElementsContainer != null) {
if (flowElementsContainer instanceof EventSubProcess) {
return true;
}
if (flowElementsContainer instanceof FlowElement) {
flowElementsContainer = ((FlowElement) flowElementsContainer).getParentContainer();
} else {
flowElementsContainer = null;
}
}
return false;
}
}

View File

@ -1,13 +1,19 @@
package com.yanzhu.flowable.listener;
import com.yanzhu.common.core.constant.SecurityConstants;
import com.yanzhu.common.core.text.Convert;
import com.yanzhu.common.redis.service.RedisService;
import com.yanzhu.flowable.constant.FlowCacheConstants;
import com.yanzhu.system.api.RemoteProService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
@ -23,10 +29,11 @@ public class GlobalEventListener extends AbstractFlowableEngineEventListener {
private RedisService redisService;
@Autowired
private TaskService taskService;
private RuntimeService runtimeService;
@Autowired
private RuntimeService runtimeService;
@Lazy
private RemoteProService remoteProService;
@Autowired
private RepositoryService repositoryService;
@ -35,6 +42,16 @@ public class GlobalEventListener extends AbstractFlowableEngineEventListener {
protected void processCompleted(FlowableEngineEntityEvent event) {
log.info("任务流程审批完成...{}",event.getProcessInstanceId());
super.processCompleted(event);
Boolean isCompleted = Convert.toBool(redisService.getCacheObject(FlowCacheConstants.STOP_PROCESS+event.getProcessInstanceId()),true);
if(isCompleted){
// 获取流程定义对象
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(event.getProcessInstanceId()).singleResult();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(event.getProcessDefinitionId()).singleResult();
log.info("同步修改审批信息...Category...{}...BusinessKey...{}",processDefinition.getCategory(),processInstance.getBusinessKey());
if(Convert.toInt(processDefinition.getCategory())<5){
remoteProService.approveSubDeptsUser(Convert.toLong(processInstance.getBusinessKey()), SecurityConstants.INNER);
}
}
}
}

View File

@ -40,7 +40,7 @@ public interface IFlowBusinessKeyService {
public Map<String, Object> selectFormDatasByProcInsId(String procInsId);
/**
*
*
* @param flowTaskEntity
* @return
*/

View File

@ -19,8 +19,8 @@ import java.util.Map;
* @author Tony
* @date 2021-04-03
*/
@Service
@Slf4j
@Service
public class FlowBusinessKeyServiceImpl implements IFlowBusinessKeyService {
@Resource

View File

@ -32,7 +32,6 @@ public class FlowInstanceServiceImpl extends FlowServiceFactory implements IFlow
@Override
public void stopProcessInstance(FlowTaskVo vo) {
String taskId = vo.getTaskId();
}
/**
@ -63,7 +62,6 @@ public class FlowInstanceServiceImpl extends FlowServiceFactory implements IFlow
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(String instanceId, String deleteReason) {
// 查询历史数据
HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(instanceId);
if (historicProcessInstance.getEndTime() != null) {

View File

@ -1,14 +1,18 @@
package com.yanzhu.flowable.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.github.pagehelper.PageInfo;
import com.yanzhu.common.core.exception.base.BaseException;
import com.yanzhu.common.core.web.domain.AjaxResult;
import com.yanzhu.common.redis.service.RedisService;
import com.yanzhu.common.security.utils.SecurityUtils;
import com.yanzhu.flowable.common.constant.ProcessConstants;
import com.yanzhu.flowable.common.enums.FlowComment;
import com.yanzhu.flowable.constant.FlowCacheConstants;
import com.yanzhu.flowable.domain.SysForm;
import com.yanzhu.flowable.domain.dto.FlowCommentDto;
import com.yanzhu.flowable.domain.dto.FlowNextDto;
@ -20,6 +24,7 @@ import com.yanzhu.flowable.factory.FlowServiceFactory;
import com.yanzhu.flowable.flow.CustomProcessDiagramGenerator;
import com.yanzhu.flowable.flow.FindNextNodeUtil;
import com.yanzhu.flowable.flow.FlowableUtils;
import com.yanzhu.flowable.flow.ModelUtils;
import com.yanzhu.flowable.rpc.RemoteSystemService;
import com.yanzhu.flowable.service.IFlowTaskService;
import com.yanzhu.flowable.service.ISysDeployFormService;
@ -35,6 +40,7 @@ import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
@ -52,6 +58,7 @@ import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -61,6 +68,7 @@ import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@ -73,13 +81,18 @@ import java.util.stream.Collectors;
@Slf4j
public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTaskService {
@Resource
private RemoteSystemService remoteSystemService;
@Resource
private ISysDeployFormService sysInstanceFormService;
@Autowired
private RedisService redisService;
@Resource
private ISysFormService sysFormService;
@Resource
private RemoteSystemService remoteSystemService;
@Resource
private ISysDeployFormService sysInstanceFormService;
/**
*
*
@ -92,13 +105,18 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
if (Objects.isNull(task)) {
return AjaxResult.error("任务不存在");
}
String userId = taskVo.getUserId();
if (DelegationState.PENDING.equals(task.getDelegationState())) {
taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.DELEGATE.getType(), taskVo.getComment());
taskService.resolveTask(taskVo.getTaskId(), taskVo.getVariables());
} else {
if(StringUtils.isNotEmpty(taskVo.getComment())){
taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.NORMAL.getType(), taskVo.getComment());
}else{
taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.NORMAL.getType(), taskVo.getAssignee()+"重新提交流程申请!!");
}
taskService.addComment(taskVo.getTaskId(), taskVo.getInstanceId(), FlowComment.NORMAL.getType(), taskVo.getComment());
Long userId = SecurityUtils.getLoginUser().getUserid();
taskService.setAssignee(taskVo.getTaskId(), userId.toString());
taskService.setAssignee(taskVo.getTaskId(), userId);
taskService.complete(taskVo.getTaskId(), taskVo.getVariables());
}
return AjaxResult.success();
@ -577,6 +595,8 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
*/
@Override
public AjaxResult stopProcess(FlowTaskVo flowTaskVo) {
// 将终止的实例加入到缓存
redisService.setCacheObject(FlowCacheConstants.STOP_PROCESS+flowTaskVo.getInstanceId(),false,2L, TimeUnit.MINUTES);
List<Task> task = taskService.createTaskQuery().processInstanceId(flowTaskVo.getInstanceId()).list();
if (CollectionUtils.isEmpty(task)) {
throw new BaseException("流程未启动或已执行完成,取消申请失败");
@ -590,12 +610,10 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
Process process = bpmnModel.getMainProcess();
List<EndEvent> endNodes = process.findFlowElementsOfType(EndEvent.class, false);
if (CollectionUtils.isNotEmpty(endNodes)) {
// TODO 取消流程为什么要设置流程发起人?
// SysUser loginUser = SecurityUtils.getLoginUser().getUser();
// Authentication.setAuthenticatedUserId(loginUser.getUserId().toString());
// taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.STOP.getType(),
// StringUtils.isBlank(flowTaskVo.getComment()) ? "取消申请" : flowTaskVo.getComment());
// 设置流程终止人
Authentication.setAuthenticatedUserId(flowTaskVo.getUserId());
taskService.addComment(flowTaskVo.getTaskId(), processInstance.getProcessInstanceId(), FlowComment.STOP.getType(),
StringUtils.isBlank(flowTaskVo.getComment()) ? "取消申请" : flowTaskVo.getComment());
// 获取当前流程最后一个节点
String endId = endNodes.get(0).getId();
List<Execution> executions = runtimeService.createExecutionQuery()
@ -619,50 +637,64 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
*/
@Override
public AjaxResult revokeProcess(FlowTaskVo flowTaskVo) {
Task task = taskService.createTaskQuery()
.processInstanceId(flowTaskVo.getInstanceId())
String procInsId = flowTaskVo.getInstanceId();
String taskId = flowTaskVo.getTaskId();
// 校验流程是否结束
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(procInsId)
.active()
.singleResult();
if (task == null) {
throw new BaseException("流程未启动或已执行完成,无法撤回");
if(ObjectUtil.isNull(processInstance)) {
throw new RuntimeException("流程已结束或已挂起,无法执行撤回操作");
}
// 获取待撤回任务实例
HistoricTaskInstance currTaskIns = historyService.createHistoricTaskInstanceQuery()
.taskId(taskId)
.taskAssignee(flowTaskVo.getUserId())
.singleResult();
if (ObjectUtil.isNull(currTaskIns)) {
throw new RuntimeException("当前任务无法执行撤回操作或不存在。");
}
// 获取 bpmn 模型
BpmnModel bpmnModel = repositoryService.getBpmnModel(currTaskIns.getProcessDefinitionId());
UserTask currUserTask = ModelUtils.getUserTaskByKey(bpmnModel, currTaskIns.getTaskDefinitionKey());
// 查找下一级用户任务列表
List<UserTask> nextUserTaskList = ModelUtils.findNextUserTasks(currUserTask);
List<String> nextUserTaskKeys = nextUserTaskList.stream().map(UserTask::getId).collect(Collectors.toList());
SysUser loginUser = SecurityUtils.getLoginUser().getSysUser();
List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(task.getProcessInstanceId())
.orderByTaskCreateTime()
.asc()
// 获取当前节点之后已完成的流程历史节点
List<HistoricTaskInstance> finishedTaskInsList = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(procInsId)
.taskCreatedAfter(currTaskIns.getEndTime())
.finished()
.list();
String myTaskId = null;
for (HistoricTaskInstance hti : htiList) {
if (loginUser.getUserId().toString().equals(hti.getAssignee())) {
myTaskId = hti.getId();
break;
for (HistoricTaskInstance finishedTaskInstance : finishedTaskInsList) {
// 检查已完成流程历史节点是否存在下一级中
if (CollUtil.contains(nextUserTaskKeys, finishedTaskInstance.getTaskDefinitionKey())) {
throw new RuntimeException("下一流程已处理,无法执行撤回操作");
}
}
if (null == myTaskId) {
throw new BaseException("该任务非当前用户提交,无法撤回");
}
List<HistoricTaskInstance> historicTaskInstanceList = historyService
.createHistoricTaskInstanceQuery()
.processInstanceId(task.getProcessInstanceId())
.orderByHistoricTaskInstanceStartTime()
.asc()
.list();
Iterator<HistoricTaskInstance> it = historicTaskInstanceList.iterator();
//循环节点获取当前节点的上一节点的key
String tarKey = "";
while (it.hasNext()) {
HistoricTaskInstance his = it.next();
if (!task.getTaskDefinitionKey().equals(his.getTaskDefinitionKey())) {
tarKey = his.getTaskDefinitionKey();
// 获取所有激活的任务节点,找到需要撤回的任务
List<Task> activateTaskList = taskService.createTaskQuery().processInstanceId(procInsId).list();
List<String> revokeExecutionIds = new ArrayList<>();
for (Task task : activateTaskList) {
// 检查激活的任务节点是否存在下一级中,如果存在,则加入到需要撤回的节点
if (CollUtil.contains(nextUserTaskKeys, task.getTaskDefinitionKey())) {
// 添加撤回审批信息
taskService.setAssignee(task.getId(), flowTaskVo.getUserId());
taskService.addComment(task.getId(), task.getProcessInstanceId(), FlowComment.REVOKE.getType(), flowTaskVo.getAssignee() + "撤回流程审批");
revokeExecutionIds.add(task.getExecutionId());
}
}
// 跳转节点
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(flowTaskVo.getInstanceId())
.moveActivityIdTo(task.getTaskDefinitionKey(), tarKey)
.changeState();
try {
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(procInsId)
.moveExecutionsToSingleActivityId(revokeExecutionIds, currTaskIns.getTaskDefinitionKey()).changeState();
} catch (FlowableObjectNotFoundException e) {
throw new RuntimeException("未找到流程实例,流程可能已发生变化");
} catch (FlowableException e) {
throw new RuntimeException("执行撤回操作失败");
}
return AjaxResult.success();
}

View File

@ -1,5 +1,6 @@
package com.yanzhu.manage.controller;
import com.yanzhu.common.core.utils.StringUtils;
import com.yanzhu.common.core.utils.poi.ExcelUtil;
import com.yanzhu.common.core.web.controller.BaseController;
import com.yanzhu.common.core.web.domain.AjaxResult;
@ -63,6 +64,22 @@ public class BusExamUserController extends BaseController
return success(busExamUserService.selectBusExamUserById(id));
}
/**
*
* @RequiresPermissions("manage:busExamUser:query")
*/
@GetMapping(value = "/last/{userId}")
public AjaxResult findBusExamUserList(@PathVariable("userId") Long userId)
{
BusExamUser query = new BusExamUser();
query.setUserId(userId);
List<BusExamUser> list = busExamUserService.selectBusExamUserList(query);
if(StringUtils.isNotEmpty(list)){
return success(busExamUserService.selectBusExamUserById(list.get(0).getId()));
}
return success();
}
/**
*
*/

View File

@ -63,6 +63,18 @@ public class BusTrainingVideoUserController extends BaseController
return success(busTrainingVideoUserService.selectBusTrainingVideoUserById(id));
}
/**
*
* @RequiresPermissions("manage:busTrainingVideoUser:query")
*/
@GetMapping(value = "/last/{userId}")
public AjaxResult findBusTrainingVideoUserLast(@PathVariable("userId") Long userId)
{
BusTrainingVideoUser query = new BusTrainingVideoUser();
query.setUserId(userId);
return success(busTrainingVideoUserService.selectBusTrainingVideoUserList(query));
}
/**
*
*/

View File

@ -55,8 +55,8 @@ public class ProProjectInfoSubdeptsController extends BaseController
/**
*
* @RequiresPermissions("manage:proProjectInfoSubdepts:query")
*/
@RequiresPermissions("manage:proProjectInfoSubdepts:query")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{

View File

@ -1,14 +1,13 @@
package com.yanzhu.manage.controller;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A;
import com.yanzhu.common.core.utils.DateUtils;
import com.yanzhu.common.core.utils.poi.ExcelUtil;
import com.yanzhu.common.core.web.controller.BaseController;
import com.yanzhu.common.core.web.domain.AjaxResult;
import com.yanzhu.common.core.web.page.TableDataInfo;
import com.yanzhu.common.log.annotation.Log;
import com.yanzhu.common.log.enums.BusinessType;
import com.yanzhu.common.security.annotation.InnerAuth;
import com.yanzhu.common.security.annotation.RequiresPermissions;
import com.yanzhu.manage.domain.ProProjectInfoSubdeptsUsers;
import com.yanzhu.manage.service.IProProjectInfoSubdeptsUsersService;
@ -18,7 +17,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
@ -97,8 +95,8 @@ public class ProProjectInfoSubdeptsUsersController extends BaseController
/**
*
* @RequiresPermissions("manage:proProjectInfoSubdeptsUsers:query")
*/
@RequiresPermissions("manage:proProjectInfoSubdeptsUsers:query")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
@ -137,6 +135,24 @@ public class ProProjectInfoSubdeptsUsersController extends BaseController
{
return toAjax(proProjectInfoSubdeptsUsersService.deleteProProjectInfoSubdeptsUsersByIds(ids));
}
/**
*
*/
@InnerAuth
@GetMapping("/approveSubDeptsUser/{busKey}")
public AjaxResult approveSubDeptsUser(@PathVariable("busKey") Long busKey)
{
proProjectInfoSubdeptsUsersService.approveSubDeptsUser(busKey);
return success();
}
/**
*
* @param ids
* @param state
* @return
*/
@RequiresPermissions("manage:proProjectInfoSubdeptsUsers:remove")
@PostMapping("/enterState/{state}")
public AjaxResult updateEnterState(@RequestBody List<Long> ids,@PathVariable int state){

View File

@ -188,4 +188,14 @@ public class WxController extends BaseController {
{
return success(proProjectInfoSubdeptsUsersService.submitUserSignets(signetFileVo));
}
/**
*
*/
@GetMapping("/v1/startFlowableProcess")
public AjaxResult startFlowableProcess()
{
proProjectInfoSubdeptsUsersService.startFlowableProcess();
return success();
}
}

View File

@ -77,4 +77,5 @@ public interface IBusTrainingVideoUserService
* @param id
*/
public int finishEduVideo(Long id);
}

View File

@ -13,6 +13,7 @@ import com.yanzhu.manage.domain.ProProjectInfoSubdepts;
*/
public interface IProProjectInfoSubdeptsService
{
/**
*
*

View File

@ -1,11 +1,10 @@
package com.yanzhu.manage.service;
import java.util.List;
import java.util.Map;
import com.yanzhu.manage.domain.ProProjectInfoSubdeptsUsers;
import com.yanzhu.manage.domain.SignetFileVo;
import java.util.List;
/**
* Service
*
@ -14,6 +13,7 @@ import com.yanzhu.manage.domain.SignetFileVo;
*/
public interface IProProjectInfoSubdeptsUsersService
{
/**
*
*
@ -93,6 +93,17 @@ public interface IProProjectInfoSubdeptsUsersService
*/
public ProProjectInfoSubdeptsUsers submitUserSignets(SignetFileVo signetFileVo);
/**
* ...
*/
public void startFlowableProcess();
/**
*
* @param id
*/
public void approveSubDeptsUser(Long id);
/**
* --
* @param proProjectInfoSubdeptsUsers

View File

@ -235,7 +235,6 @@ public class BusExamUserServiceImpl implements IBusExamUserService
busExamUser.setCreateTime(DateUtils.getNowDate());
busExamUser.setFullMark(findExamInfo.getFullMark());
busExamUser.setPassMark(findExamInfo.getPassMark());
busExamUser.setUseTimes(DateUtils.getTime());
busExamUserMapper.insertBusExamUser(busExamUser);
List<BusExamUserResult> busExamUserResultList = new ArrayList<>();
@ -442,6 +441,9 @@ public class BusExamUserServiceImpl implements IBusExamUserService
}
}
busExamUser.setUserMark(mark);
long stimes = busExamUser.getCreateTime().getTime();
long etimes = DateUtils.getNowDate().getTime();
busExamUser.setUseTimes(Convert.toStr(etimes-stimes));
if(busExamUser.getPassMark()>mark){
busExamUser.setResStatus(ShiFouEnums.FOU.getCode());
}else{

View File

@ -1,27 +1,21 @@
package com.yanzhu.manage.service.impl;
import com.alibaba.fastjson.JSON;
import com.deepoove.poi.data.PictureRenderData;
import com.yanzhu.common.core.constant.SecurityConstants;
import com.yanzhu.common.core.domain.R;
import com.yanzhu.common.core.enums.*;
import com.yanzhu.common.core.exception.ServiceException;
import com.yanzhu.common.core.text.Convert;
import com.yanzhu.common.core.utils.DateUtils;
import com.yanzhu.common.core.utils.StringUtils;
import com.yanzhu.common.core.web.domain.AjaxResult;
import com.yanzhu.common.security.utils.DictUtils;
import com.yanzhu.common.security.utils.SecurityUtils;
import com.yanzhu.manage.config.ProfileConfig;
import com.yanzhu.manage.domain.BasTemplate;
import com.yanzhu.manage.domain.ProProjectInfoSubdeptsGroup;
import com.yanzhu.manage.domain.ProProjectInfoSubdeptsUsers;
import com.yanzhu.manage.domain.SignetFileVo;
import com.yanzhu.manage.domain.*;
import com.yanzhu.manage.enums.CraftTypeEnums;
import com.yanzhu.manage.enums.SignetKeyEnums;
import com.yanzhu.manage.enums.UserPostEnums;
import com.yanzhu.manage.mapper.BasTemplateMapper;
import com.yanzhu.manage.mapper.ProProjectInfoSubdeptsGroupMapper;
import com.yanzhu.manage.mapper.ProProjectInfoSubdeptsMapper;
import com.yanzhu.manage.mapper.ProProjectInfoSubdeptsUsersMapper;
import com.yanzhu.manage.service.IProProjectInfoSubdeptsUsersService;
import com.yanzhu.manage.service.IUniService;
@ -38,8 +32,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.*;
@ -69,11 +61,14 @@ public class ProProjectInfoSubdeptsUsersServiceImpl implements IProProjectInfoSu
private RemoteFlowService remoteFlowService;
@Autowired
private ProProjectInfoSubdeptsUsersMapper proProjectInfoSubdeptsUsersMapper;
private ProProjectInfoSubdeptsMapper proProjectInfoSubdeptsMapper;
@Autowired
private ProProjectInfoSubdeptsGroupMapper proProjectInfoSubdeptsGroupMapper;
@Autowired
private ProProjectInfoSubdeptsUsersMapper proProjectInfoSubdeptsUsersMapper;
private static final Logger log = LoggerFactory.getLogger(ProProjectInfoSubdeptsUsersServiceImpl.class);
/**
@ -212,6 +207,7 @@ public class ProProjectInfoSubdeptsUsersServiceImpl implements IProProjectInfoSu
user.setSex(StringUtils.judgeGender(user.getCardCode()));
user.setCreateBy(DataSourceEnuns.APP.getInfo());
user.setCreateTime(DateUtils.getNowDate());
user.setRemark(proProjectInfoSubdeptsUsers.getSubDeptName());
Long userId = remoteUserService.registerUserInfo(user, SecurityConstants.INNER).getData();
proProjectInfoSubdeptsUsers.setUserId(userId);
proProjectInfoSubdeptsUsersMapper.insertProProjectInfoSubdeptsUsers(proProjectInfoSubdeptsUsers);
@ -352,6 +348,7 @@ public class ProProjectInfoSubdeptsUsersServiceImpl implements IProProjectInfoSu
user.setSex(StringUtils.judgeGender(user.getCardCode()));
user.setUpdateBy(DataSourceEnuns.APP.getInfo());
user.setUpdateTime(DateUtils.getNowDate());
user.setRemark(proProjectInfoSubdeptsUsers.getSubDeptName());
Long userId = remoteUserService.registerUserInfo(user, SecurityConstants.INNER).getData();
proProjectInfoSubdeptsUsers.setUserId(userId);
proProjectInfoSubdeptsUsersMapper.updateProProjectInfoSubdeptsUsers(proProjectInfoSubdeptsUsers);
@ -482,12 +479,56 @@ public class ProProjectInfoSubdeptsUsersServiceImpl implements IProProjectInfoSu
Map<String, Object> variables = new HashMap<>();
variables.put("INITIATOR",proSubdeptsUser.getUserId());
variables.put("userName",proSubdeptsUser.getUser().getNickName());
variables.put("userDeptName",proSubdeptsUser.getSubDeptName());
variables.put("comId",proSubdeptsUser.getComId());
variables.put("comName",proSubdeptsUser.getComName());
variables.put("proId",proSubdeptsUser.getProjectId());
variables.put("proName",proSubdeptsUser.getProjectName());
variables.put("businessKey",proSubdeptsUser.getId());
remoteFlowService.startDefinitionByParams(procDefId,variables,SecurityConstants.INNER);
}
return proSubdeptsUser;
}
/**
* ...
*/
@Override
public void startFlowableProcess(){
String procDefId = Convert.toStr("flow_bg7gh1jg:1:102504");
// 启动工作流审批节点...
Map<String, Object> variables = new HashMap<>();
variables.put("INITIATOR",17);
variables.put("userName","姜玉琦_TEST");
variables.put("userDeptName","中国西电集团_TEST");
variables.put("comId","101");
variables.put("comName","建安公司");
variables.put("proId","116");
variables.put("proName","泾河新城");
variables.put("businessKey",12);
remoteFlowService.startDefinitionByParams(procDefId,variables,SecurityConstants.INNER);
}
/**
*
* @param id
*/
@Override
public void approveSubDeptsUser(Long id){
ProProjectInfoSubdeptsUsers proProjectInfoSubdeptsUsers = proProjectInfoSubdeptsUsersMapper.selectProProjectInfoSubdeptsUsersById(id);
if(Objects.equals(proProjectInfoSubdeptsUsers.getUserPost(),UserPostEnums.WTDL.getCode())){
ProProjectInfoSubdepts proProjectInfoSubdepts = proProjectInfoSubdeptsMapper.selectProProjectInfoSubdeptsById(proProjectInfoSubdeptsUsers.getSubDeptId());
proProjectInfoSubdepts.setApproveStatus(ApproveStatus.exempt.getCode());
proProjectInfoSubdeptsMapper.updateProProjectInfoSubdepts(proProjectInfoSubdepts);
}else if(Objects.equals(proProjectInfoSubdeptsUsers.getUserPost(),UserPostEnums.BZZ.getCode())){
ProProjectInfoSubdeptsGroup proProjectInfoSubdeptsGroup = proProjectInfoSubdeptsGroupMapper.selectProProjectInfoSubdeptsGroupById(proProjectInfoSubdeptsUsers.getSubDeptGroup());
proProjectInfoSubdeptsGroup.setApproveStatus(ApproveStatus.exempt.getCode());
proProjectInfoSubdeptsGroupMapper.updateProProjectInfoSubdeptsGroup(proProjectInfoSubdeptsGroup);
}
proProjectInfoSubdeptsUsers.setApproveStatus(ApproveStatus.exempt.getCode());
proProjectInfoSubdeptsUsersMapper.updateProProjectInfoSubdeptsUsers(proProjectInfoSubdeptsUsers);
}
/**
* ...
* @return

View File

@ -135,7 +135,7 @@ Page({
console.log(options);
if (options && options.SIGID && options.QRPID) {
this.getDictCache(options.SIGID);
//this.getMaOpenId();
this.getMaOpenId();
this.getProjectInfo(options.QRPID);
if (options.PARID) {
this.setData({
@ -179,9 +179,6 @@ Page({
userPostList: _userPostList,
"form.projectId": options.QRPID,
});
this.getPhoneNumber({
'data': '18189138538'
});
} else {
app.toast("请求参数异常,请重新扫码...");
// wx.redirectTo({
@ -272,126 +269,125 @@ Page({
* @param {*} e
*/
getPhoneNumber(e) {
// if (e.detail.code) {
// let data = {
// openId: getOpenId(),
// sessionKey: getSessionKey(),
// iv: e.detail.iv,
// encryptedData: e.detail.encryptedData
// }
// getMaPhoneNumber(data).then(res => {
// if (res.code == 200) {
//let phoneNumber = res.data;
let phoneNumber = e.data;
//使用手机号码查询详情
if (this.data.userPost == "1") {
findProSubDeptsInfo(this.data.proId, phoneNumber).then(deptRes => {
if (deptRes.code == 200 && deptRes.data) {
deptRes.data.subDeptLeaderPhone = phoneNumber;
deptRes.data.leaderDegreeGrade = deptRes.data.proProjectInfoSubdeptsUsers.degreeGrade;
deptRes.data.eduFilePath = deptRes.data.proProjectInfoSubdeptsUsers.eduFilePath;
deptRes.data.subStep = deptRes.data.proProjectInfoSubdeptsUsers.subStep;
if (deptRes.data.subDeptInfos) {
let subDeptInfosJSON = JSON.parse(deptRes.data.subDeptInfos);
deptRes.data.subDeptInfos = subDeptInfosJSON;
if (deptRes.data.subDeptInfos.legalPersonCardImgPos) {
deptRes.data.subDeptInfos.legalPersonCardImgPos = (this.data.imgBase + deptRes.data.subDeptInfos.legalPersonCardImgPos).split(',');
}
if (deptRes.data.subDeptInfos.legalPersonCardImgInv) {
deptRes.data.subDeptInfos.legalPersonCardImgInv = (this.data.imgBase + deptRes.data.subDeptInfos.legalPersonCardImgInv).split(',');
}
if (e.detail.code) {
let data = {
openId: getOpenId(),
sessionKey: getSessionKey(),
iv: e.detail.iv,
encryptedData: e.detail.encryptedData
}
getMaPhoneNumber(data).then(res => {
if (res.code == 200) {
let phoneNumber = res.data;
//使用手机号码查询详情
if (this.data.userPost == "1") {
findProSubDeptsInfo(this.data.proId, phoneNumber).then(deptRes => {
if (deptRes.code == 200 && deptRes.data) {
deptRes.data.subDeptLeaderPhone = phoneNumber;
deptRes.data.leaderDegreeGrade = deptRes.data.proProjectInfoSubdeptsUsers.degreeGrade;
deptRes.data.eduFilePath = deptRes.data.proProjectInfoSubdeptsUsers.eduFilePath;
deptRes.data.subStep = deptRes.data.proProjectInfoSubdeptsUsers.subStep;
if (deptRes.data.subDeptInfos) {
let subDeptInfosJSON = JSON.parse(deptRes.data.subDeptInfos);
deptRes.data.subDeptInfos = subDeptInfosJSON;
if (deptRes.data.subDeptInfos.legalPersonCardImgPos) {
deptRes.data.subDeptInfos.legalPersonCardImgPos = (this.data.imgBase + deptRes.data.subDeptInfos.legalPersonCardImgPos).split(',');
}
if (deptRes.data.subDeptInfos.legalPersonCardImgInv) {
deptRes.data.subDeptInfos.legalPersonCardImgInv = (this.data.imgBase + deptRes.data.subDeptInfos.legalPersonCardImgInv).split(',');
}
}
if (deptRes.data.proProjectInfoSubdeptsUsers && deptRes.data.proProjectInfoSubdeptsUsers.user) {
if (deptRes.data.proProjectInfoSubdeptsUsers.user.cardImgPos) {
deptRes.data.leaderCardImgPos = (this.data.imgBase + deptRes.data.proProjectInfoSubdeptsUsers.user.cardImgPos).split(',');
}
if (deptRes.data.proProjectInfoSubdeptsUsers.user.cardImgInv) {
deptRes.data.leaderCardImgInv = (this.data.imgBase + deptRes.data.proProjectInfoSubdeptsUsers.user.cardImgInv).split(',');
}
if (deptRes.data.proProjectInfoSubdeptsUsers.user.userPicture) {
deptRes.data.leaderUserPicture = (this.data.imgBase + deptRes.data.proProjectInfoSubdeptsUsers.user.userPicture).split(',');
}
if (deptRes.data.proProjectInfoSubdeptsUsers.subDeptPowerPath) {
deptRes.data.subDeptLeaderPowerPath = (this.data.imgBase + deptRes.data.proProjectInfoSubdeptsUsers.subDeptPowerPath).split(',');
}
if (deptRes.data.businessLicensePath) {
deptRes.data.businessLicensePath = (this.data.imgBase + deptRes.data.businessLicensePath).split(',');
}
}
this.setData({
form: deptRes.data,
userPhoneNumber: phoneNumber,
active: deptRes.data.subStep
});
if (deptRes.data.proProjectInfoSubdeptsUsers.subStep == 1) {
this.initBusEduVideos(false);
} else if (deptRes.data.proProjectInfoSubdeptsUsers.subStep == 2) {
this.initBusEduQuestion(false);
} else if (deptRes.data.proProjectInfoSubdeptsUsers.subStep == 3) {
this.startSignFile(false);
}
} else {
this.setData({
userPhoneNumber: phoneNumber,
"form.subDeptLeaderPhone": phoneNumber,
});
}
});
} else {
findProSubDeptsUser(this.data.proId, phoneNumber).then(userRes => {
if (userRes.code == 200 && userRes.data) {
if (userRes.data.user) {
if (userRes.data.user.userInfos) {
let userInfosJSON = JSON.parse(userRes.data.user.userInfos);
userRes.data.user.phonenumber = userInfosJSON.phoneNumber;
userRes.data.user.nativePlace = userInfosJSON.nativePlace;
userRes.data.user.address = userInfosJSON.address;
userRes.data.user.emergencyContact = userInfosJSON.emergencyContact;
userRes.data.user.contactPhone = userInfosJSON.contactPhone;
userRes.data.user.bankName = userInfosJSON.bankName;
userRes.data.user.bankOffice = userInfosJSON.bankOffice;
userRes.data.user.bankCardNo = userInfosJSON.bankCardNo;
}
if (userRes.data.user.cardImgPos) {
userRes.data.user.cardImgPos = (this.data.imgBase + userRes.data.user.cardImgPos).split(',');
}
if (userRes.data.user.cardImgInv) {
userRes.data.user.cardImgInv = (this.data.imgBase + userRes.data.user.cardImgInv).split(',');
}
if (userRes.data.user.userPicture) {
userRes.data.user.userPicture = (this.data.imgBase + userRes.data.user.userPicture).split(',');
}
if (userRes.data.subDeptPowerPath) {
userRes.data.subDeptPowerPath = (this.data.imgBase + userRes.data.subDeptPowerPath).split(',');
}
}
this.setData({
form: userRes.data,
userPhoneNumber: phoneNumber,
"form.phoneNumber": phoneNumber,
active: userRes.data.subStep
});
if (userRes.data.subStep == 1) {
this.initBusEduVideos(false);
} else if (userRes.data.subStep == 2) {
this.initBusEduQuestion(false);
} else if (userRes.data.subStep == 3) {
this.startSignFile(false);
}
} else {
this.setData({
userPhoneNumber: phoneNumber,
"form.phoneNumber": phoneNumber,
});
}
});
}
if (deptRes.data.proProjectInfoSubdeptsUsers && deptRes.data.proProjectInfoSubdeptsUsers.user) {
if (deptRes.data.proProjectInfoSubdeptsUsers.user.cardImgPos) {
deptRes.data.leaderCardImgPos = (this.data.imgBase + deptRes.data.proProjectInfoSubdeptsUsers.user.cardImgPos).split(',');
}
if (deptRes.data.proProjectInfoSubdeptsUsers.user.cardImgInv) {
deptRes.data.leaderCardImgInv = (this.data.imgBase + deptRes.data.proProjectInfoSubdeptsUsers.user.cardImgInv).split(',');
}
if (deptRes.data.proProjectInfoSubdeptsUsers.user.userPicture) {
deptRes.data.leaderUserPicture = (this.data.imgBase + deptRes.data.proProjectInfoSubdeptsUsers.user.userPicture).split(',');
}
if (deptRes.data.proProjectInfoSubdeptsUsers.subDeptPowerPath) {
deptRes.data.subDeptLeaderPowerPath = (this.data.imgBase + deptRes.data.proProjectInfoSubdeptsUsers.subDeptPowerPath).split(',');
}
if (deptRes.data.businessLicensePath) {
deptRes.data.businessLicensePath = (this.data.imgBase + deptRes.data.businessLicensePath).split(',');
}
}
this.setData({
form: deptRes.data,
userPhoneNumber: phoneNumber,
active: deptRes.data.subStep
});
if (deptRes.data.proProjectInfoSubdeptsUsers.subStep == 1) {
this.initBusEduVideos(false);
} else if (deptRes.data.proProjectInfoSubdeptsUsers.subStep == 2) {
this.initBusEduQuestion(false);
} else if (deptRes.data.proProjectInfoSubdeptsUsers.subStep == 3) {
this.startSignFile(false);
}
} else {
this.setData({
userPhoneNumber: phoneNumber,
"form.subDeptLeaderPhone": phoneNumber,
});
}
});
})
} else {
findProSubDeptsUser(this.data.proId, phoneNumber).then(userRes => {
if (userRes.code == 200 && userRes.data) {
if (userRes.data.user) {
if (userRes.data.user.userInfos) {
let userInfosJSON = JSON.parse(userRes.data.user.userInfos);
userRes.data.user.phonenumber = userInfosJSON.phoneNumber;
userRes.data.user.nativePlace = userInfosJSON.nativePlace;
userRes.data.user.address = userInfosJSON.address;
userRes.data.user.emergencyContact = userInfosJSON.emergencyContact;
userRes.data.user.contactPhone = userInfosJSON.contactPhone;
userRes.data.user.bankName = userInfosJSON.bankName;
userRes.data.user.bankOffice = userInfosJSON.bankOffice;
userRes.data.user.bankCardNo = userInfosJSON.bankCardNo;
}
if (userRes.data.user.cardImgPos) {
userRes.data.user.cardImgPos = (this.data.imgBase + userRes.data.user.cardImgPos).split(',');
}
if (userRes.data.user.cardImgInv) {
userRes.data.user.cardImgInv = (this.data.imgBase + userRes.data.user.cardImgInv).split(',');
}
if (userRes.data.user.userPicture) {
userRes.data.user.userPicture = (this.data.imgBase + userRes.data.user.userPicture).split(',');
}
if (userRes.data.subDeptPowerPath) {
userRes.data.subDeptPowerPath = (this.data.imgBase + userRes.data.subDeptPowerPath).split(',');
}
}
this.setData({
form: userRes.data,
userPhoneNumber: phoneNumber,
"form.phoneNumber": phoneNumber,
active: userRes.data.subStep
});
if (userRes.data.subStep == 1) {
this.initBusEduVideos(false);
} else if (userRes.data.subStep == 2) {
this.initBusEduQuestion(false);
} else if (userRes.data.subStep == 3) {
this.startSignFile(false);
}
} else {
this.setData({
userPhoneNumber: phoneNumber,
"form.phoneNumber": phoneNumber,
});
}
});
//用户决绝授权
app.toast("请允许微信手机号一键登录");
}
// }
// })
// } else {
// //用户决绝授权
// app.toast("请允许微信手机号一键登录");
// }
},
/**
@ -1051,7 +1047,7 @@ Page({
onChageCraftType(e) {
//设置工种岗位
let craftPostList = [];
console.log("this.data.craftPostAllOrginList",this.data.craftPostAllOrginList)
console.log("this.data.craftPostAllOrginList", this.data.craftPostAllOrginList)
this.data.craftPostAllOrginList.forEach(item => {
if (item.remark == e.detail.id) {
craftPostList.push({

View File

@ -11,7 +11,7 @@
{
"name": "pages/project_qr/index",
"pathName": "pages/project_qr/index",
"query": "QRPID=116&SIGID=3&PARID=16",
"query": "QRPID=116&SIGID=1",
"launchMode": "default",
"scene": null
},

View File

@ -22,5 +22,48 @@ onMounted(() => {
.el-pagination {
right: 20px;
}
}
.el-sub-menu__title{
position: relative;
.todo_num_tips{
top:20px;
position: absolute;
right: 36px;
background-color: #f56c6c;
border-radius: 10px;
color: #fff;
display: inline-block;
font-size: 12px;
height: 18px;
line-height: 18px;
padding: 0 6px;
text-align: center;
white-space: nowrap;
border: 1px solid #fff;
cursor: pointer;
top: 16px;
display: none;
}
}
.nest-menu{
position: relative;
.todo_num_tips{
position: absolute;
right: 18px;
background-color: #f56c6c;
border-radius: 10px;
color: #fff;
display: inline-block;
font-size: 12px;
height: 18px;
line-height: 18px;
padding: 0 6px;
text-align: center;
white-space: nowrap;
border: 1px solid #fff;
cursor: pointer;
top: 16px;
display: none;
}
}
</style>

View File

@ -0,0 +1,64 @@
import request from '@/utils/request'
// 查询业务流程列表
export function allList(query) {
return request({
url: '/flowable/businessKey/allList',
method: 'get',
params: query
})
}
// 统计业务流程列表
export function queryCount(query) {
return request({
url: '/flowable/businessKey/queryCount',
method: 'get',
params: query
})
}
// 统计业务流程列表
export function findMyTasks() {
return request({
url: '/flowable/businessKey/findMyTask',
method: 'get'
})
}
// 根据业务流程查询操作日志
export function findCommentByProcInsId(query) {
return request({
url: '/flowable/businessKey/findCommentByProcInsId',
method: 'get',
params: query
})
}
// 根据业务流程查询表单数据
export function findFormDatasByProcInsId(query) {
return request({
url: '/flowable/businessKey/findFormDatasByProcInsId',
method: 'get',
params: query
})
}
// 根据条件查询我的代办任务
export function myAwaitFlowTaskList(query) {
return request({
url: '/flowable/businessKey/myAwaitFlowTaskList',
method: 'get',
params: query
})
}
// 根据条件查询我的已办任务
export function myFinishedFlowTaskList(query) {
return request({
url: '/flowable/businessKey/myFinishedFlowTaskList',
method: 'get',
params: query
})
}

View File

@ -17,6 +17,14 @@ export function getBusExamUser(id) {
})
}
// 查询用户试卷详细
export function getBusExamUserLast(userId) {
return request({
url: '/manage/busExamUser/last/' + userId,
method: 'get'
})
}
// 新增用户试卷
export function addBusExamUser(data) {
return request({

View File

@ -17,6 +17,14 @@ export function getBusTrainingVideoUser(id) {
})
}
// 查询用户培训视频详细
export function getBusTrainingVideoUserLast(id) {
return request({
url: '/manage/busTrainingVideoUser/last/' + id,
method: 'get'
})
}
// 新增用户培训视频
export function addBusTrainingVideoUser(data) {
return request({

View File

@ -59,7 +59,8 @@ const userStore = useUserStore()
const settingsStore = useSettingsStore()
function toggleSideBar() {
appStore.toggleSideBar()
appStore.toggleSideBar();
userStore.getTasks(); //
}
function handleCommand(command) {

View File

@ -4,6 +4,7 @@
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }">
<svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"/>
<span v-if="onlyOneChild.name && taskMenus.includes(onlyOneChild.name)" :class="'todo_num_tips tips_'+onlyOneChild.name">0</span>
<template #title><span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span></template>
</el-menu-item>
</app-link>
@ -12,6 +13,7 @@
<el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
<template v-if="item.meta" #title>
<svg-icon :icon-class="item.meta && item.meta.icon" />
<span v-if="item.name && taskMenus.includes(item.name)" :class="'todo_num_tips tips_'+item.name">0</span>
<span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span>
</template>
@ -49,6 +51,7 @@ const props = defineProps({
})
const onlyOneChild = ref({});
const taskMenus = ref(['Task','Todo']);
function hasOneShowingChild(children = [], parent) {
if (!children) {

View File

@ -24,7 +24,7 @@ import elementIcons from '@/components/SvgIcon/svgicon'
import './permission' // permission control
import { useDict } from '@/utils/dict'
import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi'
import { parseTime, resetForm, addDateRange, formatDuraDate, formatDuraTime, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi'
// 分页组件
import Pagination from '@/components/Pagination'
@ -55,6 +55,8 @@ app.config.globalProperties.parseTime = parseTime
app.config.globalProperties.resetForm = resetForm
app.config.globalProperties.handleTree = handleTree
app.config.globalProperties.addDateRange = addDateRange
app.config.globalProperties.formatDuraDate = formatDuraDate
app.config.globalProperties.formatDuraTime = formatDuraTime
app.config.globalProperties.selectDictLabel = selectDictLabel
app.config.globalProperties.selectDictLabels = selectDictLabels
app.config.globalProperties.$tryToJson=(str,df)=>{

View File

@ -31,9 +31,10 @@ router.beforeEach((to, from, next) => {
// 根据roles权限生成可访问的路由表
accessRoutes.forEach(route => {
if (!isHttp(route.path)) {
router.addRoute(route) // 动态添加可访问路由表
router.addRoute(route); // 动态添加可访问路由表
}
})
useUserStore().getTasks(); // 动态获取用户代办任务
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})
}).catch(err => {

View File

@ -1,4 +1,5 @@
import { login, logout, getInfo } from '@/api/login'
import { findMyTasks } from '@/api/flowable/businessKey'
import { getToken, setToken, removeToken } from '@/utils/auth'
import defAva from '@/assets/images/profile.jpg'
@ -7,7 +8,9 @@ const useUserStore = defineStore(
{
state: () => ({
token: getToken(),
uid: '',
name: '',
nickName: '',
avatar: '',
compInfo:{},
roles: [],
@ -48,7 +51,9 @@ const useUserStore = defineStore(
} else {
this.roles = ['ROLE_DEFAULT']
}
this.uid = user.userId;
this.name = user.userName;
this.nickName = user.nickName;
this.compInfo=user.comp;
this.avatar = avatar;
this.currentComId = user.activeComId;
@ -61,6 +66,38 @@ const useUserStore = defineStore(
})
})
},
// 获取用户代办
getTasks(){
return new Promise((resolve, reject) => {
findMyTasks().then(response => {
let todos = document.querySelectorAll(".tips_Todo");
let tasks = document.querySelectorAll(".tips_Task");
if (todos.length > 0) {
todos.forEach(el => {
el.innerHTML = response.data.todo;
if (response.data.todo > 0) {
el.style.display = "inline";
} else {
el.style.display = "none";
}
});
}
if (tasks.length > 0) {
tasks.forEach(el => {
el.innerHTML = response.data.todo;
if (response.data.todo > 0) {
el.style.display = "inline";
} else {
el.style.display = "none";
}
});
}
resolve(response)
}).catch(error => {
reject(error)
})
})
},
// 退出系统
logOut() {
return new Promise((resolve, reject) => {

View File

@ -201,6 +201,85 @@ export function handleTree(data, id, parentId, children) {
return tree;
}
/**
* 时间格式化为时间差
* @param {*} duration 时间分钟
*/
export function formatDuraDate(duration){
let day = 0;
let hours = 0;
let min = parseInt(duration);
if (min > 1440) {
day = parseInt(min / 1440);
min = min % 1440;
if (min > 60) {
hours = parseInt(min / 60);
min = min % 60;
}
} else if (min > 60) {
hours = parseInt(min / 60);
min = min % 60;
}
if (day > 0) {
if (day < 10) day = "0" + day;
if (hours < 10) hours = "0" + hours;
if (min < 10) min = "0" + min;
return day + "天" + hours + "小时" + min + "分钟";
}
if (hours > 0) {
if (hours < 10) hours = "0" + hours;
if (min < 10) min = "0" + min;
return hours + "小时" + min + "分钟";
}
if (min > 0) {
if (min < 10) min = "0" + min;
return min + "分钟";
}
if (min == 0) {
return "1分钟";
}
}
/**
* 时间格式化为时间差
* @param {*} val 时间
*/
export function formatDuraTime(val){
// 计算出相差天数
let days = Math.floor(val / (24 * 3600 * 1000));
// 计算出小时数
let leave1 = val % (24 * 3600 * 1000); // 计算天数后剩余的毫秒数
let hours = Math.floor(leave1 / (3600 * 1000));
// 计算相差分钟数
let leave2 = leave1 % (3600 * 1000); // 计算小时数后剩余的毫秒数
let minutes = Math.floor(leave2 / (60 * 1000));
// 计算相差秒数
let leave3 = leave2 % (60 * 1000); // 计算分钟数后剩余的毫秒数
let seconds = Math.round(leave3 / 1000);
if (days > 0) {
if (days < 10) days = "0" + days;
if (hours < 10) hours = "0" + hours;
if (minutes < 10) minutes = "0" + minutes;
if (seconds < 10) seconds = "0" + seconds;
return days + "天" + hours + "小时" + minutes + "分钟" + seconds + "秒";
}
if (hours > 0) {
if (hours < 10) hours = "0" + hours;
if (minutes < 10) minutes = "0" + minutes;
if (seconds < 10) seconds = "0" + seconds;
return hours + "小时" + minutes + "分钟" + seconds + "秒";
}
if (minutes > 0) {
if (minutes < 10) minutes = "0" + minutes;
if (seconds < 10) seconds = "0" + seconds;
return minutes + "分钟" + seconds + "秒";
}
if (seconds > 0) {
if (seconds < 10) seconds = "0" + seconds;
return seconds + "秒";
}
}
/**
* 参数处理
* @param {*} params 参数

View File

@ -17,7 +17,7 @@
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="流程分类" prop="category" v-if="false">
<el-form-item label="流程分类" prop="category">
<el-select v-model="queryParams.category" placeholder="请选择流程分类" clearable>
<el-option
v-for="dict in sys_process_category"
@ -284,6 +284,10 @@ function handleSelectionChange(selection) {
/** 跳转到流程设计页面 */
function handleLoadXml(row){
if(!userStore.currentProId){
proxy.$modal.msgWarning("请切换到项目数据!!!");
return false;
}
router.push({ path: '/flowable/definition/model',query: { deployId: row.deploymentId }})
}

View File

@ -1,7 +1,7 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="名称" prop="name">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="88px">
<el-form-item label="表达式名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入表达式名称"

View File

@ -1,10 +1,10 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="名称" prop="name">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="88px">
<el-form-item label="监听器名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入名称"
placeholder="请输入监听器名称"
clearable
@keyup.enter="handleQuery"
/>

View File

@ -1,12 +1,42 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="名称" prop="name">
<el-form-item label="项目名称" prop="startProName" v-if="!userStore.currentProId">
<el-input
v-model="queryParams.name"
placeholder="请输入名称"
clearable
@keyup.enter="handleQuery"
v-model="queryParams.startProName"
placeholder="请输入项目名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="流程名称" prop="procDefName">
<el-input
v-model="queryParams.procDefName"
placeholder="请输入流程名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="流程分类" prop="category">
<el-select v-model="queryParams.category" placeholder="请选择流程分类" clearable>
<el-option
v-for="dict in sys_process_category"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="申请时间">
<el-date-picker
v-model="daterangeTimes"
type="daterange"
unlink-panels
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
:shortcuts="shortcuts"
/>
</el-form-item>
<el-form-item>
@ -15,7 +45,7 @@
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-row :gutter="10" class="mb8" v-if="false">
<el-col :span="1.5">
<el-button
type="danger"
@ -29,28 +59,45 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="finishedListData" border @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="任务编号" align="center" prop="taskId" :show-overflow-tooltip="true"/>
<el-table v-loading="loading" :data="finishedListData" border>
<el-table-column label="任务编号" align="center" prop="taskId" width="88"/>
<!-- <el-table-column label="所属公司" align="center" prop="startComName" :show-overflow-tooltip="true"/> -->
<el-table-column label="项目单位" align="center" prop="startProName" :show-overflow-tooltip="true"/>
<el-table-column label="流程名称" align="center" prop="procDefName" :show-overflow-tooltip="true"/>
<el-table-column label="流程分类" align="center" prop="category" width="180">
<template #default="scope">
<dict-tag
:options="sys_process_category"
:value="scope.row.category"
/>
</template>
</el-table-column>
<el-table-column label="任务节点" align="center" prop="taskName" />
<el-table-column label="流程发起人" align="center">
<el-table-column label="流程发起人" align="center" width="220">
<template #default="scope">
<label>{{scope.row.startUserName}} <el-tag type="info" size="small">{{scope.row.startDeptName}}</el-tag></label>
</template>
</el-table-column>
<el-table-column label="接收时间" align="center" prop="createTime" width="180"/>
<el-table-column label="审批时间" align="center" prop="finishTime" width="180"/>
<el-table-column label="耗时" align="center" prop="duration" width="180"/>
<el-table-column label="操作" width="150" fixed="right" class-name="small-padding fixed-width">
<el-table-column label="接收时间" align="center" prop="createTime" width="160"/>
<el-table-column label="审批时间" align="center" prop="finishTime" width="160">
<template #default="scope">
<span>{{ parseTime(scope.row.finishTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="流程耗时" align="center" prop="duration" width="120">
<template #default="scope">
<span>{{ formatDuraTime(scope.row.duration) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="150" align="center" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<el-button
link
size="small"
type="primary"
icon="Tickets"
icon="Warning"
@click="handleFlowRecord(scope.row)"
>流转记录</el-button>
>详情</el-button>
<el-button
link
size="small"
@ -70,14 +117,23 @@
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<detailProcess ref="detailProcessRef"/>
</div>
</template>
<script setup name="Finished">
import { finishedList, delDeployment, revokeProcess } from "@/api/flowable/finished";
import { myFinishedFlowTaskList } from "@/api/flowable/businessKey";
import router from "@/router";
import useUserStore from '@/store/modules/user'
import detailProcess from "@/views/flowable/task/myProcess/detail/indexDrawer.vue";
const { proxy } = getCurrentInstance();
const { sys_process_category } = proxy.useDict('sys_process_category');
const userStore = useUserStore()
const detailProcessRef = ref("");
//
const loading = ref(true);
//
@ -92,17 +148,48 @@ const showSearch = ref(true);
const total = ref(0);
//
const finishedListData = ref([]);
const daterangeTimes = ref([]);
//
const title = ref("");
//
const open = ref(false);
const shortcuts = [
{
text: '最近一周',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
return [start, end]
},
},
{
text: '最近一个月',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
return [start, end]
},
},
{
text: '最近三个月',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
return [start, end]
},
},
];
const data = reactive({
//
queryParams: {
pageNum: 1,
pageSize: 10,
name: null
startProName: null,
procDefName: null,
category: null
},
});
@ -111,7 +198,7 @@ const { queryParams } = toRefs(data);
/** 查询流程定义列表 */
function getList() {
loading.value = true;
finishedList(queryParams.value).then(response => {
myFinishedFlowTaskList(proxy.addDateRange(queryParams.value, daterangeTimes.value)).then(response => {
finishedListData.value = response.rows;
total.value = response.total;
loading.value = false;
@ -139,22 +226,36 @@ function handleSelectionChange(selection) {
/** 流程流转记录 */
function handleFlowRecord(row){
router.push({ path: '/flowable/task/finished/detail/index',
query: {
procInsId: row.procInsId,
deployId: row.deployId,
taskId: row.taskId,
}})
detailProcessRef.value.show(row);
// router.push({ path: '/flowable/task/finished/detail/index',
// query: {
// procInsId: row.procInsId,
// deployId: row.deployId,
// taskId: row.taskId,
// }})
}
/** 撤回任务 */
function handleRevoke(row){
const params = {
instanceId: row.procInsId
procInsId: row.procInsId,
instanceId: row.procInsId,
taskId:row.taskId,
userId:userStore.uid,
assignee:userStore.nickName
}
revokeProcess(params).then( res => {
proxy.$modal.msgSuccess(res.msg);
proxy.$confirm('是否确认撤回任务流程编号为"' + row.taskId + '"的数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
loading.value = true;
return revokeProcess(params);
}).then(() => {
getList();
proxy.$modal.msgSuccess("撤回成功");
}).catch(() => {
loading.value = false;
});
}

View File

@ -0,0 +1,834 @@
<template>
<div class="app-detailDrawer">
<el-drawer v-model="onOpen" :show-close="true" size="80%">
<template #header>
<h4>流程详情 {{ title }} - 当前进度{{ jdtitle }}<span v-if="showjd">
- 当前节点{{ dataOptions.taskName }}</span
></h4>
</template>
<div class="drawer">
<div class="drawerLeft">
<div class="block containers">
<div class="canvas" ref="flowCanvas"></div>
<div class="maskLayer" />
</div>
<el-timeline style="padding: 5px;">
<el-timeline-item
v-for="(item, index) in flowRecordList"
:key="index"
:icon="setIcon(item)"
:color="setColor(item)"
>
<p style="font-weight: 700">
{{ getSort(index) }}{{ item.taskName }}{{ item.commentResult }}
</p>
<el-card style="margin-top: 5px;">
<el-descriptions class="margin-top" :column="1" size="small" border>
<el-descriptions-item
v-if="item.assigneeName"
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><User /></el-icon></div>
</template>
{{ item.assigneeName }}
<el-tag type="info" size="small">{{ item.deptName }}</el-tag>
</el-descriptions-item>
<el-descriptions-item
v-if="item.candidate"
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><UserFilled /></el-icon></div>
</template>
{{ item.candidate }}
</el-descriptions-item>
<el-descriptions-item
v-if="item.deleteReason"
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><Operation /></el-icon></div>
</template>
{{ getDeleteReason(item.deleteReason) }}
</el-descriptions-item>
<el-descriptions-item
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><Clock /></el-icon></div>
</template>
{{ item.startTime }}
</el-descriptions-item>
<el-descriptions-item
v-if="item.endTime"
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><Clock /></el-icon></div>
</template>
{{ item.endTime }}
</el-descriptions-item>
<el-descriptions-item
v-if="item.duration"
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><Timer /></el-icon></div>
</template>
{{ formatDuraTime(item.duration) }}
</el-descriptions-item>
<el-descriptions-item
v-if="item.message"
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><Warning /></el-icon></div>
</template>
{{ item.message }}
</el-descriptions-item>
</el-descriptions>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
<div class="drawerRight">
<el-tabs v-model="activeName" type="card" class="demo-tabs">
<el-tab-pane label="单位信息" name="base" v-if="dataOptions.category=='1'">
<el-form label-width="100px" size="small" >
<el-form-item label="单位类型">
<el-tag effect="dark">{{ initData.subDeptTypeName }}</el-tag>
</el-form-item>
<el-form-item label="单位名称">
{{ initData.subDeptName }} <el-tag type="info">{{ parData.subDeptCode }}</el-tag>
</el-form-item>
<el-form-item label="进入场地时间" v-if="dataOptions.category=='1'">
{{ parseTime(parData.useDates, '{y}-{m}-{d}') }}
</el-form-item>
<el-row v-if="dataOptions.category=='1'">
<el-col :span="12">
<el-form-item label="计划开工时间">
{{ parseTime(parData.startWorkDates, '{y}-{m}-{d}') }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划完工时间">
{{ parseTime(parData.endWorkDates, '{y}-{m}-{d}') }}
</el-form-item>
</el-col>
</el-row>
<el-form-item label="营业执照">
<ImagePreview :src="parData.businessLicensePath" :width="120" :height="70"/>
</el-form-item>
<el-form-item label="合同约定范围">
{{ parData.contractInfos }}
</el-form-item>
<el-form-item label="法人身份证">
<ImagePreview :src="parData.subDeptInfos.legalPersonCardImgPos" :width="120" :height="70"/>
<ImagePreview :src="parData.subDeptInfos.legalPersonCardImgInv" :width="120" :height="70" style="margin-left: 20px;"/>
</el-form-item>
<el-form-item label="法人姓名">
{{ parData.subDeptInfos.legalPerson }}
</el-form-item>
<el-form-item label="法人身份证号">
{{ parData.subDeptInfos.legalPersonCard }}
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="人员信息" name="users" v-if="dataOptions.category=='1' || dataOptions.category=='2' || dataOptions.category=='3' || dataOptions.category=='4'">
<el-form label-width="100px" size="small" >
<el-form-item label="代理人身份证" v-if="dataOptions.category=='1'">
<ImagePreview :src="initData.user.cardImgPos" :width="120" :height="70"/>
<ImagePreview :src="initData.user.cardImgInv" :width="120" :height="70" style="margin-left: 20px;"/>
</el-form-item>
<el-form-item label="入场肖像近照" v-if="dataOptions.category=='1'">
<ImagePreview :src="initData.user.userPicture" :width="120" :height="70"/>
</el-form-item>
<el-form-item label="单位委托证明" v-if="dataOptions.category=='1'">
<ImagePreview :src="initData.subDeptPowerPath" :width="120" :height="70"/>
</el-form-item>
<el-form-item label="委托人姓名" v-if="dataOptions.category=='1'">
{{ initData.user.nickName }} <el-tag type="info">{{ initData.user.cardCode }}</el-tag>
</el-form-item>
<el-form-item label="联系电话">
{{ initData.user.userName }}
</el-form-item>
<el-form-item label="文化程度">
<el-tag effect="dark">{{ initData.degreeGradeName }}</el-tag>
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item label="身体健康问题">
<el-tag effect="dark" :type="initData.illnessStatus==0?'success':'danger'">{{ initData.illnessStatus==0?'无':'有' }}</el-tag>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="严重疾病情况">
<el-tag effect="dark" :type="initData.supIllnessStatus==0?'success':'danger'">{{ initData.supIllnessStatus==0?'无':'有' }}</el-tag>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="安全培训承诺书">
<el-button link type="primary" icon="Link" @click="handleDownloadEduFile(initData.eduFilePath)"></el-button>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="视频培训" name="video" v-if="dataOptions.category=='1' || dataOptions.category=='2' || dataOptions.category=='3' || dataOptions.category=='4'">
<el-table :data="userEduVideoList">
<el-table-column label="播放时间" align="center" prop="playDates" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.playDates, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="播放时长" align="center" prop="playTimes" width="100">
<template #default="scope">
<span>{{ (scope.row.playTimes/1000).toFixed(2)+' 秒' }}</span>
</template>
</el-table-column>
<el-table-column label="培训名称" align="center" prop="trainTitle" :show-overflow-tooltip="true"/>
<el-table-column label="培训类型" align="center" prop="trainTypeName"/>
<el-table-column label="培训级别" align="center" prop="trainLevelName"/>
</el-table>
</el-tab-pane>
<el-tab-pane label="考试情况" name="exams" v-if="dataOptions.category=='1' || dataOptions.category=='2' || dataOptions.category=='3' || dataOptions.category=='4'">
<el-row class="task_panel">
<el-col :span="6">
<el-statistic class="statistic_div">
<template #title>
<div style="display: inline-flex; align-items: center">
<el-icon style="margin-right: 4px; color: #409eff" :size="12">
<InfoFilled />
</el-icon>
<strong>考试结果</strong>
</div>
</template>
</el-statistic>
<div v-if="userEduExamInfos.resStatus == '0'" class="countdown-footer">
<strong style="font-size: 16px; color: #909399; font-weight: 800;">未提交</strong>
</div>
<div v-if="userEduExamInfos.resStatus == '1'" class="countdown-footer">
<strong style="font-size: 16px; color: #67c23a; font-weight: 800;">已通过</strong>
</div>
<div v-if="userEduExamInfos.resStatus == '2'" class="countdown-footer">
<strong style="font-size: 16px; color: #f56c6c; font-weight: 800;">不通过</strong>
</div>
</el-col>
<el-col :span="6">
<el-statistic class="statistic_div">
<template #title>
<div style="display: inline-flex; align-items: center">
<el-icon style="margin-right: 4px; color: #67c23a" :size="12">
<TrendCharts />
</el-icon>
<strong>考试分数</strong>
</div>
</template>
</el-statistic>
<div class="countdown-footer">
<strong style="font-size: 16px; color: #909399">{{userEduExamInfos.userMark!=null?userEduExamInfos.userMark:'-'}}</strong>
</div>
</el-col>
<el-col :span="6">
<el-statistic class="statistic_div">
<template #title>
<div style="display: inline-flex; align-items: center">
<el-icon style="margin-right: 4px; color: #409eff" :size="12">
<InfoFilled />
</el-icon>
<strong>答题耗时</strong>
</div>
</template>
</el-statistic>
<div class="countdown-footer">
<strong style="font-size: 16px; color: #909399" v-if="userEduExamInfos.useTimes">{{formatDuraTime(userEduExamInfos.useTimes)}}</strong>
<strong style="font-size: 16px; color: #909399" v-if="!userEduExamInfos.useTimes"> - </strong>
</div>
</el-col>
<el-col :span="6">
<el-statistic class="statistic_div">
<template #title>
<div style="display: inline-flex; align-items: center">
<el-icon style="margin-right: 4px" :size="12">
<Calendar />
</el-icon>
答题时间
</div>
</template>
</el-statistic>
<div class="countdown-footer">
<strong>{{ parseTime(userEduExamInfos.createTime, "{y}-{m}-{d} {h}:{i}") }}</strong>
</div>
</el-col>
</el-row>
<div class="startExamination">
<ul>
<li v-for="(item,idx) in userEduQuestionList" :key="item.id">
<div class="topicTilte" style="font-weight: bold" ref="topicTilte">
{{ idx + 1 }}<span class="score">[{{ item.questionType==1?'单选题':(item.questionType==2?'多选题':'判断题')}}]</span>{{ item.questionTitle }}
</div>
<template v-if="item.questionType === 1">
<el-radio-group v-model="item.userAnswer" class="ml-4 Selected_item_radio" style="width: 100%">
<div v-for="(option,ox) in item.questionOption" class="Selected_item">
<el-radio :label="option.opt" disabled> {{ option.result }} </el-radio>
</div>
</el-radio-group>
<div :class="item.answer == item.userAnswer?'answer':'error'">
<div class="correctAnswer">正确答案{{ item.answer }}</div>
<div class="testAnswers">试卷答案{{ item.userAnswer }}</div>
</div>
</template>
<template v-if="item.questionType === 2">
<el-checkbox-group v-model="item.userAnswerValues" class="ml-4 Selected_item_radio" style="width: 100%">
<div v-for="option in item.questionOption" class="Selected_item">
<el-checkbox :label="option.opt" disabled> {{ option.result }} </el-checkbox>
</div>
</el-checkbox-group>
<div :class="item.answer == item.userAnswer?'answer':'error'">
<div class="correctAnswer">正确答案{{ item.answer }}</div>
<div class="testAnswers">试卷答案{{ item.userAnswer }}</div>
</div>
</template>
<template v-if="item.questionType === 3">
<el-checkbox-group v-model="item.userAnswerValues" class="ml-4 Selected_item_radio" style="width: 100%">
<div v-for="option in item.questionOption" class="Selected_item">
<el-checkbox :label="option.opt" disabled> {{ option.result }} </el-checkbox>
</div>
</el-checkbox-group>
<div :class="item.answer == item.userAnswer?'answer':'error'">
<div class="correctAnswer">正确答案{{ item.answer }}</div>
<div class="testAnswers">试卷答案{{ item.userAnswer }}</div>
</div>
</template>
</li>
</ul>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</el-drawer>
</div>
</template>
<script setup name="myProcessDrawer">
import { flowXmlAndNode } from "@/api/flowable/definition";
import { CustomViewer as BpmnViewer } from "@/components/Process/common";
import { Clock, Select, CloseBold } from '@element-plus/icons-vue'
import {
findCommentByProcInsId,
} from "@/api/flowable/businessKey";
import { getProProjectInfoSubdepts } from "@/api/manage/proProjectInfoSubdepts";
import { getProProjectInfoSubdeptsUsers } from "@/api/manage/proProjectInfoSubdeptsUsers";
import { getBusExamUserLast } from "@/api/manage/busExamUser";
import { getBusTrainingVideoUserLast } from "@/api/manage/busTrainingVideoUser";
const { proxy } = getCurrentInstance();
const onOpen = ref(false);
const bpmnViewer = ref(null);
const title = ref("");
const jdtitle = ref("");
const showjd = ref(false);
const dataOptions = ref({});
const activeName = ref("");
const flowRecordList = ref([]);
const userEduVideoList = ref([]);
const userEduExamInfos = ref({});
const userEduQuestionList = ref([]);
const data = reactive({
parData: {
subDeptInfos:{}
},
initData: {
user: {}
},
});
const { parData, initData } = toRefs(data);
/** 获取节点图标 */
const setIcon = (row) => {
if (row.endTime) {
if (row.commentResult == "驳回") {
return CloseBold;
} else {
return Select;
}
} else {
return Clock;
}
};
/** 获取节点颜色 */
const setColor = (row) => {
if (row.endTime) {
if (row.commentResult == "驳回") {
return "#f56c6c";
} else {
return "#2bc418";
}
} else {
return "#409eff";
}
};
/** 获取节点排序 */
const getSort = (i) => {
let num = flowRecordList.value.length - i;
if (num < 10) {
num = "0" + num;
}
return num + ". ";
};
const doCanel = () => {
onOpen.value = false;
};
/** 显示流程详情 */
const show = (options) => {
dataOptions.value = options;
title.value = options.procDefName;
onOpen.value = true;
showjd.value = false;
if (options.finishTime == null) {
jdtitle.value = "进行中";
showjd.value = true;
} else if (options.finishTime!= null && options.assigneeId == null) {
jdtitle.value = "已终止";
} else {
jdtitle.value = "已完成";
}
activeName.value = "base";
initFormValues();
getFlowRecordList(options.procInsId, options.deployId);
flowXmlAndNode({ procInsId: options.procInsId, deployId: options.deployId }).then(
(res) => {
initFlowImage(res.data);
}
);
};
/** 初始化工作流 */
const initFlowImage = async (data) => {
try {
bpmnViewer.value && bpmnViewer.value.destroy();
bpmnViewer.value = new BpmnViewer({
container: proxy.$refs.flowCanvas,
height: '90px',
});
await bpmnViewer.value.importXML(data.xmlData);
//
bpmnViewer.value.get("canvas").zoom("fit-viewport", "auto");
// 线
if (data.nodeData !== undefined && data.nodeData.length > 0) {
await fillColor(data.nodeData);
}
} catch (err) {
console.error(err.message, err.warnings);
}
};
/** 获取流程节点 */
const getFlowRecordList = (procInsId, deployId) => {
const params = { procInsId: procInsId };
findCommentByProcInsId(params)
.then((res) => {
flowRecordList.value = res.data;
})
.catch((res) => {
console.error("数据异常,请联系管理员...");
});
};
/** 获取表单数据 */
const initFormValues = () => {
let category = parseInt(dataOptions.value.category);
if(category==1 || category==2 || category==3 || category==4){
getProProjectInfoSubdeptsUsers(dataOptions.value.businessKey).then(res =>{
if(res.data.user.userInfos){
res.data.user.userInfos = JSON.parse(res.data.user.userInfos);
}
initData.value = res.data ;
getProProjectInfoSubdepts(res.data.subDeptId).then(parRes =>{
if(parRes.data.subDeptInfos){
parRes.data.subDeptInfos = JSON.parse(parRes.data.subDeptInfos);
}
parData.value = parRes.data;
});
});
findEduVideos();
findEduExams();
}
};
/** 用户视频培训 */
function findEduVideos(){
getBusTrainingVideoUserLast(dataOptions.value.startUserId).then(res =>{
userEduVideoList.value = res.data||[]
});
}
/** 用户考试情况 */
function findEduExams(){
getBusExamUserLast(dataOptions.value.startUserId).then(res =>{
if(res.code==200 && res.data){
userEduExamInfos.value = res.data;
let list = res.data.busExamUserResultList;
list.forEach(item => {
if(item.questionType===2){
if(item.userAnswer==null){
item.userAnswer = "";
}
item.userAnswerValues = item.userAnswer.split(',');
}
item.questionOption = JSON.parse(item.questionOption);
});
userEduQuestionList.value = list;
}
});
}
/** 下载培训承诺书 */
function handleDownloadEduFile(filePath){
proxy.$download.resource(filePath);
};
/** 设置高亮颜色的 */
function fillColor(nodeData) {
const canvas = bpmnViewer.value.get('canvas')
bpmnViewer.value.getDefinitions().rootElements[0].flowElements.forEach(n => {
const completeTask = nodeData.find(m => m.key === n.id)
const todoTask = nodeData.find(m => !m.completed)
const endTask = nodeData[nodeData.length - 1]
if (n.$type === 'bpmn:UserTask') {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
if (todoTask && completeTask.key === todoTask.key && !todoTask.completed){
canvas.addMarker(nn.id, todoTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, todoTask.completed ? 'highlight' : 'highlight-todo')
}else {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo')
}
}
})
}
}
//
else if (n.$type === 'bpmn:ExclusiveGateway') {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo')
}
})
}
}
//
else if (n.$type === 'bpmn:ParallelGateway') {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo')
}
})
}
}
else if (n.$type === 'bpmn:StartEvent') {
n.outgoing.forEach(nn => {
const completeTask = nodeData.find(m => m.key === nn.targetRef.id)
if (completeTask) {
canvas.addMarker(nn.id, 'highlight')
canvas.addMarker(n.id, 'highlight')
return;
}
})
}
else if (n.$type === 'bpmn:EndEvent') {
if (endTask.key === n.id && endTask.completed) {
canvas.addMarker(n.id, 'highlight')
return;
}
}
})
}
/** 获取审批节点 */
const getDeleteReason = (val) => {
val = val.replace("Change activity to ", "");
let flowRecordList = this.flowRecordList;
for (let i = 0; i < flowRecordList.length; i++) {
if (flowRecordList[i].taskDefKey == val) {
return "驳回至" + flowRecordList[i].taskName;
}
}
};
/** 暴露组件 */
defineExpose({
show
});
</script>
<style lang="scss">
.app-detailDrawer {
.el-drawer__header{
margin-bottom: 0 !important;
}
.drawer {
width: 100%;
height: 100%;
padding-left: 20px;
padding-right: 20px;
padding-bottom: 20px;
.drawerLeft {
width: 50%;
min-width: 280px;
height: 100%;
float: left;
border-right: 1px solid #dcdfe6;
overflow-y: scroll;
padding-right: 20px;
.bjs-powered-by {
display: none !important;
}
.maskLayer {
width: 50%;
height: 90px;
position: absolute;
z-index: 9999;
top: 77px;
}
.el-timeline-item{
.el-timeline-item__node{
width: 20px;
height: 20px;
margin-top: -4px;
.el-timeline-item__icon{
font-size: 16px !important;
}
}
}
}
.drawerRight {
width: 50%;
min-width: 400px;
height: 100%;
float: left;
padding-left: 20px;
.el-link_div {
width: 100%;
overflow: hidden;
}
.el-form-item__content{
.el-tag--info{
margin-left: 5px;
}
}
}
}
.containers {
width: 100%;
height: 90px;
.canvas {
width: 100%;
height: 100px;
}
.panel {
position: absolute;
right: 0;
top: 50px;
width: 300px;
}
.load {
margin-right: 10px;
}
.el-form-item__label {
font-size: 13px;
}
.djs-palette {
left: 0px !important;
top: 0px;
border-top: none;
}
.djs-container svg {
min-height: 90px;
}
.highlight.djs-shape .djs-visual > :nth-child(1) {
fill: green !important;
stroke: green !important;
fill-opacity: 0.2 !important;
}
.highlight.djs-shape .djs-visual > :nth-child(2) {
fill: green !important;
}
.highlight.djs-shape .djs-visual > path {
fill: green !important;
fill-opacity: 0.2 !important;
stroke: green !important;
}
.highlight.djs-connection > .djs-visual > path {
stroke: green !important;
}
.highlight-todo.djs-connection > .djs-visual > path {
stroke: orange !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
.highlight-todo.djs-shape .djs-visual > :nth-child(1) {
fill: orange !important;
stroke: orange !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
.overlays-div {
font-size: 10px;
color: red;
width: 100px;
top: -20px !important;
}
}
}
.mytags{
float:left;
margin-right: 6px;
}
.d-it-label{
width: 150px;
.my-label{
display: flex;
align-items: center;
.el-icon{
margin-right: 5px;
}
}
}
.el-divider__text{
color: #409eff;
font-weight: 800;
}
.task_panel {
text-align: center;
margin-bottom: 20px;
margin-top: 10px;
}
.statistic_div {
.el-statistic__content {
display: none;
}
}
.startExamination {
padding: 0px 20px;
ul {
margin: 30px 0;
li {
list-style: none;
margin-top: 10px;
.Selected_item_radio {
display: block;
flex: none;
}
.topicTilte {
.score {
display: inline-block;
margin-right: 10px;
}
}
.Selected_item_fill {
height: 45px;
display: flex;
align-items: center;
}
.answer {
height: 30px;
display: flex;
align-items: center;
border: 1px solid #e1f3d8;
color: #67c23a;
padding: 0 15px;
//margin: 10px 20px 10px 0;
background-color: #f0f9eb;
.correctAnswer {
margin-right: 40px;
}
}
.error {
height: 30px;
display: flex;
align-items: center;
padding: 0 15px;
//margin: 10px 20px 10px 0;
background: #fdf6ec;
border: 1px solid #faecd8;
color: #f56c6c;
.correctAnswer {
margin-right: 40px;
}
}
.CompletionAnswer {
height: 80px;
display: flex;
align-items: center;
border: 1px solid #e1f3d8;
color: #67c23a;
padding: 0 15px;
margin: 10px 20px 10px 0;
background-color: #f0f9eb;
.CompletionAnswerIndex {
width: 50px;
height: 100%;
display: flex;
align-items: center;
border-right: 1px solid #e1f3d8;
margin-right: 20px;
}
.correctAnswer {
margin-right: 40px;
}
}
.CompletionError {
height: 80px;
display: flex;
align-items: center;
padding: 0 15px;
margin: 10px 20px 10px 0;
background: #fdf6ec;
border: 1px solid #faecd8;
color: #f56c6c;
.CompletionAnswerIndex {
width: 25px;
height: 100%;
display: flex;
align-items: center;
border-right: 1px solid #faecd8;
margin-right: 20px;
}
.correctAnswer {
height: 40px;
margin-right: 40px;
}
}
}
}
}
.el-alert {
margin: 20px 0 0;
}
.el-alert:first-child {
margin: 0;
}
</style>

View File

@ -1,21 +1,51 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="名称" prop="name">
<el-form-item label="项目名称" prop="startProName" v-if="!userStore.currentProId">
<el-input
v-model="queryParams.name"
placeholder="请输入名称"
v-model="queryParams.startProName"
placeholder="请输入项目名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="流程名称" prop="procDefName">
<el-input
v-model="queryParams.procDefName"
placeholder="请输入流程名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="流程分类" prop="category">
<el-select v-model="queryParams.category" placeholder="请选择流程分类" clearable>
<el-option
v-for="dict in sys_process_category"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="申请时间">
<el-date-picker
v-model="daterangeTimes"
type="daterange"
unlink-panels
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
:shortcuts="shortcuts"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"></el-button>
<el-button icon="Refresh" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-row :gutter="10" class="mb8" v-if="false">
<el-col :span="1.5">
<el-button
type="primary"
@ -38,35 +68,60 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="myProcessData" border @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="流程编号" align="center" prop="procInsId" :show-overflow-tooltip="true"/>
<el-tabs
v-model="queryParams.activeTags"
type="card"
class="demo-tabs"
@tab-change="getList"
>
<el-tab-pane :label="'全部申请(' + tabs.all + ''" name="all"></el-tab-pane>
<el-tab-pane :label="'进行中(' + tabs.await + ''" name="await"></el-tab-pane>
<el-tab-pane :label="'已完成(' + tabs.finished + ''" name="finished"></el-tab-pane>
</el-tabs>
<el-table v-loading="loading" :data="myProcessData" border >
<el-table-column label="流程编号" align="center" prop="procInsId" width="88px" :show-overflow-tooltip="true"/>
<!-- <el-table-column label="所属公司" align="center" prop="startComName" :show-overflow-tooltip="true"/> -->
<el-table-column label="项目单位" align="center" prop="startProName" :show-overflow-tooltip="true"/>
<el-table-column label="流程名称" align="center" prop="procDefName" :show-overflow-tooltip="true"/>
<el-table-column label="流程类别" align="center" prop="category" width="100px" />
<el-table-column label="流程分类" align="center" prop="category" width="150px" >
<template #default="scope">
<dict-tag :options="sys_process_category" :value="scope.row.category"/>
</template>
</el-table-column>
<el-table-column label="流程版本" align="center" width="80px">
<template #default="scope">
<el-tag size="small" >v{{ scope.row.procDefVersion }}</el-tag>
</template>
</el-table-column>
<el-table-column label="提交时间" align="center" prop="createTime" width="180"/>
<el-table-column label="流程状态" align="center" width="100">
<el-table-column label="提交时间" align="center" prop="createTime" width="150">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="流程状态" align="center" width="80">
<template #default="scope">
<el-tag v-if="scope.row.finishTime == null" size="small"></el-tag>
<el-tag type="success" v-if="scope.row.finishTime != null" size="small"></el-tag>
<el-tag type="success" v-if="scope.row.finishTime != null && scope.row.assigneeId != null" size="small"></el-tag>
<el-tag type="danger" v-if="scope.row.finishTime != null && scope.row.assigneeId == null" size="small"></el-tag>
</template>
</el-table-column>
<el-table-column label="耗时" align="center" prop="duration" width="180"/>
<el-table-column label="当前节点" align="center" prop="taskName"/>
<el-table-column label="办理人" align="center">
<el-table-column label="耗时" align="center" prop="duration" width="150">
<template #default="scope">
<span>{{ formatDuraDate(scope.row.duration) }}</span>
</template>
</el-table-column>
<el-table-column label="当前节点" align="center" prop="taskName" width="120" :show-overflow-tooltip="true"/>
<el-table-column label="办理人" align="center" width="200">
<template #default="scope">
<label v-if="scope.row.assigneeName">{{scope.row.assigneeName}} <el-tag type="info" size="small">{{scope.row.assigneeDeptName}}</el-tag></label>
<!-- <label v-if="scope.row.candidate">{{scope.row.candidate}}</label>-->
<!--<label v-if="scope.row.candidate">{{scope.row.candidate}}</label>-->
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right" class-name="small-padding fixed-width">
<el-table-column label="操作" width="160" align="center" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<!-- <el-button v-if="getActivate(scope.row)" @click="handleFlowRecord(scope.row)" link type="primary" size="small"></el-button> -->
<el-button @click="handleFlowRecord(scope.row)" link type="primary" size="small">详情</el-button>
<el-button @click="handleStop(scope.row)" link type="primary" size="small">取消申请</el-button>
<el-button @click="handleStop(scope.row)" link type="primary" size="small">终止</el-button>
<el-button @click="handleDelete(scope.row)" link type="primary" size="small" v-hasPermi="['system:deployment:remove']"></el-button>
</template>
</el-table-column>
@ -124,6 +179,27 @@
/>
</el-dialog>
<!-- 中止流程 -->
<el-dialog :title="stopTitle" v-model="stopOpen" width="680" append-to-body>
<el-form :model="stopProcessForm" ref="stopProcessFormRef" :rules="stopProcessRules" label-width="88px">
<el-form-item label="终止原因" prop="comment">
<el-input
v-model="stopProcessForm.comment"
placeholder="请输入流程终止原因"
type="textarea"
rows="5"
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" icon="Finished" @click="handleProcessStop"> </el-button>
<el-button @click="stopOpen=false"> </el-button>
</div>
</template>
</el-dialog>
<detailProcess ref="detailProcessRef"/>
</div>
</template>
@ -131,10 +207,16 @@
import { delDeployment, flowRecord } from "@/api/flowable/finished";
import { myProcessList,stopProcess } from "@/api/flowable/process";
import { listDefinition } from "@/api/flowable/definition";
import { allList, queryCount } from "@/api/flowable/businessKey";
import router from "@/router";
import useUserStore from '@/store/modules/user'
import detailProcess from "@/views/flowable/task/myProcess/detail/indexDrawer.vue";
const { proxy } = getCurrentInstance();
const { sys_process_category } = proxy.useDict('sys_process_category');
const userStore = useUserStore()
const detailProcessRef = ref("");
//
const loading = ref(true);
const processLoading = ref(true);
@ -155,22 +237,65 @@ const myProcessData = ref([]);
const title = ref("");
//
const open = ref(false);
const src = ref("");
const definitionList = ref([]);
const daterangeTimes = ref([]);
const tabs = ref({
all:0,
await:0,
finished:0
});
const shortcuts = [
{
text: '最近一周',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
return [start, end]
},
},
{
text: '最近一个月',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
return [start, end]
},
},
{
text: '最近三个月',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
return [start, end]
},
},
];
//
const stopTitle = ref("终止流程申请");
//
const stopOpen = ref(false);
//
const stopProcessForm = ref({});
const stopProcessRules = ref({
comment: [{ required: true, message: "流程终止原因不能为空", trigger: "blur" },
{
max: 500,
message: "终止原因最多输入500字",
trigger: "blur",
}]
});
const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 10,
name: null,
startProName: null,
procDefName: null,
category: null,
key: null,
tenantId: null,
deployTime: null,
derivedFrom: null,
derivedFromRoot: null,
parentDeploymentId: null,
engineVersion: null
activeTags: "await"
},
//
queryProcessParams: {
@ -193,13 +318,31 @@ const { queryParams, queryProcessParams } = toRefs(data);
/** 查询流程定义列表 */
function getList() {
loading.value = true;
myProcessList(queryParams.value).then(response => {
getQueryCount();
allList(proxy.addDateRange(queryParams.value, daterangeTimes.value)).then((response) => {
myProcessData.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
/** 统计流程定义数量 */
function getQueryCount() {
queryCount(proxy.addDateRange(queryParams.value, daterangeTimes.value)).then((response) => {
let _tabs = {
all:0,
await:0,
finished:0
}
if(response.code==200){
_tabs.all = parseInt(response.data.await) + parseInt(response.data.finished);
_tabs.await = response.data.await;
_tabs.finished = response.data.finished;
}
tabs.value = _tabs;
});
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
@ -258,23 +401,51 @@ function handleStartProcess(row){
/** 取消流程申请 */
function handleStop(row){
const params = {
instanceId: row.procInsId
}
stopProcess(params).then( res => {
proxy.$modal.msgSuccess(res.msg);
getList();
stopProcessForm.value.taskId = row.taskId;
stopProcessForm.value.userId = userStore.uid;
stopProcessForm.value.instanceId = row.procInsId;
stopOpen.value = true;
}
/** 中止流程申请 */
function handleProcessStop(){
proxy.$refs["stopProcessFormRef"].validate(valid => {
if (valid) {
proxy.$confirm('是否确认终止流程定义编号为"' + stopProcessForm.value.instanceId + '"的数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
loading.value = true;
stopOpen.value = false;
return stopProcess(stopProcessForm.value);
}).then(() => {
stopProcessForm.value.comment="";
getList();
proxy.$modal.msgSuccess("终止成功");
})
}
});
}
/** 判断是否继续办理 */
function getActivate(row) {
if (row.taskName == "提交申请" && row.assigneeId == userStore.uid) {
return true;
} else {
return false;
}
}
/** 流程流转记录 */
function handleFlowRecord(row){
router.push({ path: '/flowable/task/myProcess/detail/index',
query: {
procInsId: row.procInsId,
deployId: row.deployId,
taskId: row.taskId
}})
detailProcessRef.value.show(row);
// router.push({ path: '/flowable/task/myProcess/detail/index',
// query: {
// procInsId: row.procInsId,
// deployId: row.deployId,
// taskId: row.taskId
// }})
}
/** 删除按钮操作 */

View File

@ -0,0 +1,990 @@
<template>
<div class="app-detailDrawer">
<el-drawer v-model="onOpen" :show-close="true" size="80%">
<template #header>
<h4>流程详情 {{ title }} - 当前进度{{ jdtitle }}<span v-if="showjd">
- 当前节点{{ dataOptions.taskName }}</span
></h4>
</template>
<div class="drawer" v-loading="loading">
<div class="drawerLeft">
<div class="block containers">
<div class="canvas" ref="flowCanvas"></div>
<div class="maskLayer" />
</div>
<el-timeline style="padding: 5px;">
<el-timeline-item
v-for="(item, index) in flowRecordList"
:key="index"
:icon="setIcon(item)"
:color="setColor(item)"
>
<p style="font-weight: 700">
{{ getSort(index) }}{{ item.taskName }}{{ item.commentResult }}
</p>
<el-card style="margin-top: 5px;">
<el-descriptions class="margin-top" :column="1" size="small" border>
<el-descriptions-item
v-if="item.assigneeName"
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><User /></el-icon></div>
</template>
{{ item.assigneeName }}
<el-tag type="info" size="small">{{ item.deptName }}</el-tag>
</el-descriptions-item>
<el-descriptions-item
v-if="item.candidate"
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><UserFilled /></el-icon></div>
</template>
{{ item.candidate }}
</el-descriptions-item>
<el-descriptions-item
v-if="item.deleteReason"
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><Operation /></el-icon></div>
</template>
{{ getDeleteReason(item.deleteReason) }}
</el-descriptions-item>
<el-descriptions-item
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><Clock /></el-icon></div>
</template>
{{ item.startTime }}
</el-descriptions-item>
<el-descriptions-item
v-if="item.endTime"
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><Clock /></el-icon></div>
</template>
{{ item.endTime }}
</el-descriptions-item>
<el-descriptions-item
v-if="item.duration"
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><Timer /></el-icon></div>
</template>
{{ formatDuraTime(item.duration) }}
</el-descriptions-item>
<el-descriptions-item
v-if="item.message"
label-class-name="d-it-label"
>
<template #label>
<div class="my-label"><el-icon><Warning /></el-icon></div>
</template>
{{ item.message }}
</el-descriptions-item>
</el-descriptions>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
<div class="drawerRight">
<el-tabs v-model="activeName" type="card" class="demo-tabs">
<el-tab-pane label="单位信息" name="base" v-if="dataOptions.category=='1'">
<el-form label-width="100px" size="small" >
<el-form-item label="单位类型">
<el-tag effect="dark">{{ initData.subDeptTypeName }}</el-tag>
</el-form-item>
<el-form-item label="单位名称">
{{ initData.subDeptName }} <el-tag type="info">{{ parData.subDeptCode }}</el-tag>
</el-form-item>
<el-form-item label="进入场地时间" v-if="dataOptions.category=='1'">
{{ parseTime(parData.useDates, '{y}-{m}-{d}') }}
</el-form-item>
<el-row v-if="dataOptions.category=='1'">
<el-col :span="12">
<el-form-item label="计划开工时间">
{{ parseTime(parData.startWorkDates, '{y}-{m}-{d}') }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划完工时间">
{{ parseTime(parData.endWorkDates, '{y}-{m}-{d}') }}
</el-form-item>
</el-col>
</el-row>
<el-form-item label="营业执照">
<ImagePreview :src="parData.businessLicensePath" :width="120" :height="70"/>
</el-form-item>
<el-form-item label="合同约定范围">
{{ parData.contractInfos }}
</el-form-item>
<el-form-item label="法人身份证">
<ImagePreview :src="parData.subDeptInfos.legalPersonCardImgPos" :width="120" :height="70"/>
<ImagePreview :src="parData.subDeptInfos.legalPersonCardImgInv" :width="120" :height="70" style="margin-left: 20px;"/>
</el-form-item>
<el-form-item label="法人姓名">
{{ parData.subDeptInfos.legalPerson }}
</el-form-item>
<el-form-item label="法人身份证号">
{{ parData.subDeptInfos.legalPersonCard }}
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="人员信息" name="users" v-if="dataOptions.category=='1' || dataOptions.category=='2' || dataOptions.category=='3' || dataOptions.category=='4'">
<el-form label-width="100px" size="small" >
<el-form-item label="代理人身份证" v-if="dataOptions.category=='1'">
<ImagePreview :src="initData.user.cardImgPos" :width="120" :height="70"/>
<ImagePreview :src="initData.user.cardImgInv" :width="120" :height="70" style="margin-left: 20px;"/>
</el-form-item>
<el-form-item label="入场肖像近照" v-if="dataOptions.category=='1'">
<ImagePreview :src="initData.user.userPicture" :width="120" :height="70"/>
</el-form-item>
<el-form-item label="单位委托证明" v-if="dataOptions.category=='1'">
<ImagePreview :src="initData.subDeptPowerPath" :width="120" :height="70"/>
</el-form-item>
<el-form-item label="委托人姓名" v-if="dataOptions.category=='1'">
{{ initData.user.nickName }} <el-tag type="info">{{ initData.user.cardCode }}</el-tag>
</el-form-item>
<el-form-item label="联系电话">
{{ initData.user.userName }}
</el-form-item>
<el-form-item label="文化程度">
<el-tag effect="dark">{{ initData.degreeGradeName }}</el-tag>
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item label="身体健康问题">
<el-tag effect="dark" :type="initData.illnessStatus==0?'success':'danger'">{{ initData.illnessStatus==0?'无':'有' }}</el-tag>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="严重疾病情况">
<el-tag effect="dark" :type="initData.supIllnessStatus==0?'success':'danger'">{{ initData.supIllnessStatus==0?'无':'有' }}</el-tag>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="安全培训承诺书">
<el-button link type="primary" icon="Link" @click="handleDownloadEduFile(initData.eduFilePath)"></el-button>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="视频培训" name="video" v-if="dataOptions.category=='1' || dataOptions.category=='2' || dataOptions.category=='3' || dataOptions.category=='4'">
<el-table :data="userEduVideoList">
<el-table-column label="播放时间" align="center" prop="playDates" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.playDates, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="播放时长" align="center" prop="playTimes" width="100">
<template #default="scope">
<span>{{ (scope.row.playTimes/1000).toFixed(2)+' 秒' }}</span>
</template>
</el-table-column>
<el-table-column label="培训名称" align="center" prop="trainTitle" :show-overflow-tooltip="true"/>
<el-table-column label="培训类型" align="center" prop="trainTypeName"/>
<el-table-column label="培训级别" align="center" prop="trainLevelName"/>
</el-table>
</el-tab-pane>
<el-tab-pane label="考试情况" name="exams" v-if="dataOptions.category=='1' || dataOptions.category=='2' || dataOptions.category=='3' || dataOptions.category=='4'">
<el-row class="task_panel">
<el-col :span="6">
<el-statistic class="statistic_div">
<template #title>
<div style="display: inline-flex; align-items: center">
<el-icon style="margin-right: 4px; color: #409eff" :size="12">
<InfoFilled />
</el-icon>
<strong>考试结果</strong>
</div>
</template>
</el-statistic>
<div v-if="userEduExamInfos.resStatus == '0'" class="countdown-footer">
<strong style="font-size: 16px; color: #909399; font-weight: 800;">未提交</strong>
</div>
<div v-if="userEduExamInfos.resStatus == '1'" class="countdown-footer">
<strong style="font-size: 16px; color: #67c23a; font-weight: 800;">已通过</strong>
</div>
<div v-if="userEduExamInfos.resStatus == '2'" class="countdown-footer">
<strong style="font-size: 16px; color: #f56c6c; font-weight: 800;">不通过</strong>
</div>
</el-col>
<el-col :span="6">
<el-statistic class="statistic_div">
<template #title>
<div style="display: inline-flex; align-items: center">
<el-icon style="margin-right: 4px; color: #67c23a" :size="12">
<TrendCharts />
</el-icon>
<strong>考试分数</strong>
</div>
</template>
</el-statistic>
<div class="countdown-footer">
<strong style="font-size: 16px; color: #909399">{{userEduExamInfos.userMark!=null?userEduExamInfos.userMark:'-'}}</strong>
</div>
</el-col>
<el-col :span="6">
<el-statistic class="statistic_div">
<template #title>
<div style="display: inline-flex; align-items: center">
<el-icon style="margin-right: 4px; color: #409eff" :size="12">
<InfoFilled />
</el-icon>
<strong>答题耗时</strong>
</div>
</template>
</el-statistic>
<div class="countdown-footer">
<strong style="font-size: 16px; color: #909399" v-if="userEduExamInfos.useTimes">{{formatDuraTime(userEduExamInfos.useTimes)}}</strong>
<strong style="font-size: 16px; color: #909399" v-if="!userEduExamInfos.useTimes"> - </strong>
</div>
</el-col>
<el-col :span="6">
<el-statistic class="statistic_div">
<template #title>
<div style="display: inline-flex; align-items: center">
<el-icon style="margin-right: 4px" :size="12">
<Calendar />
</el-icon>
答题时间
</div>
</template>
</el-statistic>
<div class="countdown-footer">
<strong>{{ parseTime(userEduExamInfos.createTime, "{y}-{m}-{d} {h}:{i}") }}</strong>
</div>
</el-col>
</el-row>
<div class="startExamination">
<ul>
<li v-for="(item,idx) in userEduQuestionList" :key="item.id">
<div class="topicTilte" style="font-weight: bold" ref="topicTilte">
{{ idx + 1 }}<span class="score">[{{ item.questionType==1?'单选题':(item.questionType==2?'多选题':'判断题')}}]</span>{{ item.questionTitle }}
</div>
<template v-if="item.questionType === 1">
<el-radio-group v-model="item.userAnswer" class="ml-4 Selected_item_radio" style="width: 100%">
<div v-for="(option,ox) in item.questionOption" class="Selected_item">
<el-radio :label="option.opt" disabled> {{ option.result }} </el-radio>
</div>
</el-radio-group>
<div :class="item.answer == item.userAnswer?'answer':'error'">
<div class="correctAnswer">正确答案{{ item.answer }}</div>
<div class="testAnswers">试卷答案{{ item.userAnswer }}</div>
</div>
</template>
<template v-if="item.questionType === 2">
<el-checkbox-group v-model="item.userAnswerValues" class="ml-4 Selected_item_radio" style="width: 100%">
<div v-for="option in item.questionOption" class="Selected_item">
<el-checkbox :label="option.opt" disabled> {{ option.result }} </el-checkbox>
</div>
</el-checkbox-group>
<div :class="item.answer == item.userAnswer?'answer':'error'">
<div class="correctAnswer">正确答案{{ item.answer }}</div>
<div class="testAnswers">试卷答案{{ item.userAnswer }}</div>
</div>
</template>
<template v-if="item.questionType === 3">
<el-checkbox-group v-model="item.userAnswerValues" class="ml-4 Selected_item_radio" style="width: 100%">
<div v-for="option in item.questionOption" class="Selected_item">
<el-checkbox :label="option.opt" disabled> {{ option.result }} </el-checkbox>
</div>
</el-checkbox-group>
<div :class="item.answer == item.userAnswer?'answer':'error'">
<div class="correctAnswer">正确答案{{ item.answer }}</div>
<div class="testAnswers">试卷答案{{ item.userAnswer }}</div>
</div>
</template>
</li>
</ul>
</div>
</el-tab-pane>
</el-tabs>
<el-form ref="approveProcessRef" :model="form" :rules="rules" label-width="100px" size="small" >
<el-form-item label="审批意见" prop="comment">
<el-input
type="textarea"
v-model="form.comment"
placeholder="请输入审批意见最多500字"
:rows="5"
/>
</el-form-item>
<div style="text-align: center">
<el-button
v-if="returnTaskBtn"
icon="CircleCloseFilled"
type="danger"
size="small"
@click="handleReturn"
>驳回申请</el-button
>
<el-button
icon="WarningFilled"
type="warning"
size="small"
@click="handleReject"
>驳回上级</el-button
>
<el-button
icon="Finished"
type="success"
size="small"
@click="handlePass"
>审批通过</el-button
>
</div>
</el-form>
<div class="page-warning">
<p v-if="returnTaskBtn">
<strong style="color: #f56c6c">驳回申请</strong>
操作后代表您对当前任务不满意任务退回给申请人处理
</p>
<p>
<strong style="color: #e6a23c">驳回上级</strong>
操作后代表您对当前任务不满意任务退回到上一阶段继续处理
</p>
<p>
<strong style="color: #67c23a">审批通过</strong>
操作后代表您对当前任务满意任务进入下一阶段
</p>
</div>
</div>
</div>
</el-drawer>
</div>
</template>
<script setup name="approveProcessDrawer">
import { flowXmlAndNode } from "@/api/flowable/definition";
import { CustomViewer as BpmnViewer } from "@/components/Process/common";
import { Clock, Select, CloseBold } from '@element-plus/icons-vue';
import { complete, rejectTask, returnTask, returnList } from "@/api/flowable/todo";
import {
findCommentByProcInsId,
} from "@/api/flowable/businessKey";
import { getProProjectInfoSubdepts } from "@/api/manage/proProjectInfoSubdepts";
import { getProProjectInfoSubdeptsUsers } from "@/api/manage/proProjectInfoSubdeptsUsers";
import { getBusExamUserLast } from "@/api/manage/busExamUser";
import { getBusTrainingVideoUserLast } from "@/api/manage/busTrainingVideoUser";
import useUserStore from '@/store/modules/user'
const { proxy } = getCurrentInstance();
const userStore = useUserStore()
const onOpen = ref(false);
const loading = ref(false);
const bpmnViewer = ref(null);
const title = ref("");
const jdtitle = ref("");
const showjd = ref(false);
const dataOptions = ref({});
const activeName = ref("");
const returnTaskBtn = ref(false);
const flowRecordList = ref([]);
const userEduVideoList = ref([]);
const userEduExamInfos = ref({});
const userEduQuestionList = ref([]);
const data = reactive({
parData: {
subDeptInfos:{}
},
initData: {
user: {}
},
form: {
},
rules: {
comment: [{ required: true, message: "审批意见不能为空", trigger: "blur" },
{
max: 500,
message: "审批意见最多输入500字",
trigger: "blur",
}
]
}
});
const { parData, initData, form, rules } = toRefs(data);
const emit = defineEmits(["handle"]);
/** 获取节点图标 */
const setIcon = (row) => {
if (row.endTime) {
if (row.commentResult == "驳回") {
return CloseBold;
} else {
return Select;
}
} else {
return Clock;
}
};
/** 获取节点颜色 */
const setColor = (row) => {
if (row.endTime) {
if (row.commentResult == "驳回") {
return "#f56c6c";
} else {
return "#2bc418";
}
} else {
return "#409eff";
}
};
/** 获取节点排序 */
const getSort = (i) => {
let num = flowRecordList.value.length - i;
if (num < 10) {
num = "0" + num;
}
return num + ". ";
};
const doCanel = () => {
onOpen.value = false;
};
/** 审批通过 */
function handlePass() {
proxy.$refs["approveProcessRef"].validate((valid) => {
if (valid) {
loading.value = true;
proxy.$modal.confirm('是否确认审批通过流程编号为"' + dataOptions.value.taskId + '"的数据项?').then(function() {
return complete(form.value);
}).then(() => {
doCanel();
emit('handle');
proxy.$modal.msgSuccess("审批成功");
}).catch(() => {});
}
});
}
/** 驳回上级 */
function handleReject() {
proxy.$refs["approveProcessRef"].validate((valid) => {
if (valid) {
loading.value = true;
proxy.$modal.confirm('是否确认审批驳回流程编号为"' + dataOptions.value.taskId + '"的数据项?').then(function() {
return rejectTask(form.value);
}).then(() => {
doCanel();
emit('handle');
proxy.$modal.msgSuccess("审批成功");
}).catch(() => {});
}
});
}
/** 驳回申请 */
function handleReturn() {
proxy.$refs["approveProcessRef"].validate((valid) => {
if (valid) {
loading.value = true;
proxy.$modal.confirm('是否确认审批驳回流程编号为"' + dataOptions.value.taskId + '"的数据项至申请人?').then(function() {
return returnTask(form.value);
}).then(() => {
doCanel();
emit('handle');
proxy.$modal.msgSuccess("审批成功");
}).catch(() => {});
}
});
}
/** 显示流程详情 */
const show = (options) => {
dataOptions.value = options;
title.value = options.procDefName;
onOpen.value = true;
showjd.value = false;
if (options.finishTime == null) {
jdtitle.value = "进行中";
showjd.value = true;
} else if (options.finishTime!= null && options.assigneeId == null) {
jdtitle.value = "已终止";
} else {
jdtitle.value = "已完成";
}
activeName.value = "base";
initFormDate();
initFormValues();
getFlowRecordList(options.procInsId, options.deployId);
flowXmlAndNode({ procInsId: options.procInsId, deployId: options.deployId }).then(
(res) => {
initFlowImage(res.data);
}
);
};
/** 初始化表单数据 */
const initFormDate = () => {
form.value.taskId = dataOptions.value.taskId;
form.value.taskName = dataOptions.value.taskName;
form.value.userId = userStore.uid;
form.value.deployId = dataOptions.value.deployId;
form.value.procInsId = dataOptions.value.procInsId;
form.value.instanceId = dataOptions.value.procInsId;
form.value.executionId = dataOptions.value.procInsId;
form.value.comment = "";
returnTaskBtn.value = true;
loading.value = false;
initReturnList();
}
/** 初始化流程节点 */
const initReturnList = () => {
returnList(form.value).then((res) => {
//退>1退
if (res.data.length == 0) {
returnTaskBtn.value = false;
}else{
form.value.targetKey = res.data[0].id;
}
});
}
/** 初始化工作流 */
const initFlowImage = async (data) => {
try {
bpmnViewer.value && bpmnViewer.value.destroy();
bpmnViewer.value = new BpmnViewer({
container: proxy.$refs.flowCanvas,
height: '90px',
});
await bpmnViewer.value.importXML(data.xmlData);
//
bpmnViewer.value.get("canvas").zoom("fit-viewport", "auto");
// 线
if (data.nodeData !== undefined && data.nodeData.length > 0) {
await fillColor(data.nodeData);
}
} catch (err) {
console.error(err.message, err.warnings);
}
};
/** 获取流程节点 */
const getFlowRecordList = (procInsId, deployId) => {
const params = { procInsId: procInsId };
findCommentByProcInsId(params)
.then((res) => {
flowRecordList.value = res.data;
})
.catch((res) => {
console.error("数据异常,请联系管理员...");
});
};
/** 获取表单数据 */
const initFormValues = () => {
let category = parseInt(dataOptions.value.category);
if(category==1 || category==2 || category==3 || category==4){
getProProjectInfoSubdeptsUsers(dataOptions.value.businessKey).then(res =>{
if(res.data.user.userInfos){
res.data.user.userInfos = JSON.parse(res.data.user.userInfos);
}
initData.value = res.data ;
getProProjectInfoSubdepts(res.data.subDeptId).then(parRes =>{
if(parRes.data.subDeptInfos){
parRes.data.subDeptInfos = JSON.parse(parRes.data.subDeptInfos);
}
parData.value = parRes.data;
});
});
findEduVideos();
findEduExams();
}
};
/** 用户视频培训 */
function findEduVideos(){
getBusTrainingVideoUserLast(dataOptions.value.startUserId).then(res =>{
userEduVideoList.value = res.data||[]
});
}
/** 用户考试情况 */
function findEduExams(){
getBusExamUserLast(dataOptions.value.startUserId).then(res =>{
if(res.code==200 && res.data){
userEduExamInfos.value = res.data;
let list = res.data.busExamUserResultList;
list.forEach(item => {
if(item.questionType===2){
if(item.userAnswer==null){
item.userAnswer = "";
}
item.userAnswerValues = item.userAnswer.split(',');
}
item.questionOption = JSON.parse(item.questionOption);
});
userEduQuestionList.value = list;
}
});
}
/** 下载培训承诺书 */
function handleDownloadEduFile(filePath){
proxy.$download.resource(filePath);
};
/** 设置高亮颜色的 */
function fillColor(nodeData) {
const canvas = bpmnViewer.value.get('canvas')
bpmnViewer.value.getDefinitions().rootElements[0].flowElements.forEach(n => {
const completeTask = nodeData.find(m => m.key === n.id)
const todoTask = nodeData.find(m => !m.completed)
const endTask = nodeData[nodeData.length - 1]
if (n.$type === 'bpmn:UserTask') {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
if (todoTask && completeTask.key === todoTask.key && !todoTask.completed){
canvas.addMarker(nn.id, todoTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, todoTask.completed ? 'highlight' : 'highlight-todo')
}else {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo')
}
}
})
}
}
//
else if (n.$type === 'bpmn:ExclusiveGateway') {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo')
}
})
}
}
//
else if (n.$type === 'bpmn:ParallelGateway') {
if (completeTask) {
canvas.addMarker(n.id, completeTask.completed ? 'highlight' : 'highlight-todo')
n.outgoing?.forEach(nn => {
const targetTask = nodeData.find(m => m.key === nn.targetRef.id)
if (targetTask) {
canvas.addMarker(nn.id, targetTask.completed ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, targetTask.completed ? 'highlight' : 'highlight-todo')
}
})
}
}
else if (n.$type === 'bpmn:StartEvent') {
n.outgoing.forEach(nn => {
const completeTask = nodeData.find(m => m.key === nn.targetRef.id)
if (completeTask) {
canvas.addMarker(nn.id, 'highlight')
canvas.addMarker(n.id, 'highlight')
return;
}
})
}
else if (n.$type === 'bpmn:EndEvent') {
if (endTask.key === n.id && endTask.completed) {
canvas.addMarker(n.id, 'highlight')
return;
}
}
})
}
/** 获取审批节点 */
const getDeleteReason = (val) => {
val = val.replace("Change activity to ", "");
let flowRecordList = this.flowRecordList;
for (let i = 0; i < flowRecordList.length; i++) {
if (flowRecordList[i].taskDefKey == val) {
return "驳回至" + flowRecordList[i].taskName;
}
}
};
/** 暴露组件 */
defineExpose({
show
});
</script>
<style lang="scss">
.app-detailDrawer {
.el-drawer__header{
margin-bottom: 0 !important;
}
.drawer {
width: 100%;
height: 100%;
padding-left: 20px;
padding-right: 20px;
padding-bottom: 20px;
.drawerLeft {
width: 50%;
min-width: 280px;
height: 100%;
float: left;
border-right: 1px solid #dcdfe6;
overflow-y: scroll;
padding-right: 20px;
.bjs-powered-by {
display: none !important;
}
.maskLayer {
width: 50%;
height: 90px;
position: absolute;
z-index: 9999;
top: 77px;
}
.el-timeline-item{
.el-timeline-item__node{
width: 20px;
height: 20px;
margin-top: -4px;
.el-timeline-item__icon{
font-size: 16px !important;
}
}
}
}
.drawerRight {
width: 50%;
min-width: 400px;
height: 100%;
float: left;
padding-left: 20px;
.el-link_div {
width: 100%;
overflow: hidden;
}
.el-form-item__content{
.el-tag--info{
margin-left: 5px;
}
}
}
}
.containers {
width: 100%;
height: 90px;
.canvas {
width: 100%;
height: 100px;
}
.panel {
position: absolute;
right: 0;
top: 50px;
width: 300px;
}
.load {
margin-right: 10px;
}
.el-form-item__label {
font-size: 13px;
}
.djs-palette {
left: 0px !important;
top: 0px;
border-top: none;
}
.djs-container svg {
min-height: 90px;
}
.highlight.djs-shape .djs-visual > :nth-child(1) {
fill: green !important;
stroke: green !important;
fill-opacity: 0.2 !important;
}
.highlight.djs-shape .djs-visual > :nth-child(2) {
fill: green !important;
}
.highlight.djs-shape .djs-visual > path {
fill: green !important;
fill-opacity: 0.2 !important;
stroke: green !important;
}
.highlight.djs-connection > .djs-visual > path {
stroke: green !important;
}
.highlight-todo.djs-connection > .djs-visual > path {
stroke: orange !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
.highlight-todo.djs-shape .djs-visual > :nth-child(1) {
fill: orange !important;
stroke: orange !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
.overlays-div {
font-size: 10px;
color: red;
width: 100px;
top: -20px !important;
}
}
}
.mytags{
float:left;
margin-right: 6px;
}
.d-it-label{
width: 150px;
.my-label{
display: flex;
align-items: center;
.el-icon{
margin-right: 5px;
}
}
}
.el-divider__text{
color: #409eff;
font-weight: 800;
}
.task_panel {
text-align: center;
margin-bottom: 20px;
margin-top: 10px;
}
.statistic_div {
.el-statistic__content {
display: none;
}
}
.startExamination {
padding: 0px 20px;
ul {
margin: 30px 0;
li {
list-style: none;
margin-top: 10px;
.Selected_item_radio {
display: block;
flex: none;
}
.topicTilte {
.score {
display: inline-block;
margin-right: 10px;
}
}
.Selected_item_fill {
height: 45px;
display: flex;
align-items: center;
}
.answer {
height: 30px;
display: flex;
align-items: center;
border: 1px solid #e1f3d8;
color: #67c23a;
padding: 0 15px;
//margin: 10px 20px 10px 0;
background-color: #f0f9eb;
.correctAnswer {
margin-right: 40px;
}
}
.error {
height: 30px;
display: flex;
align-items: center;
padding: 0 15px;
//margin: 10px 20px 10px 0;
background: #fdf6ec;
border: 1px solid #faecd8;
color: #f56c6c;
.correctAnswer {
margin-right: 40px;
}
}
.CompletionAnswer {
height: 80px;
display: flex;
align-items: center;
border: 1px solid #e1f3d8;
color: #67c23a;
padding: 0 15px;
margin: 10px 20px 10px 0;
background-color: #f0f9eb;
.CompletionAnswerIndex {
width: 50px;
height: 100%;
display: flex;
align-items: center;
border-right: 1px solid #e1f3d8;
margin-right: 20px;
}
.correctAnswer {
margin-right: 40px;
}
}
.CompletionError {
height: 80px;
display: flex;
align-items: center;
padding: 0 15px;
margin: 10px 20px 10px 0;
background: #fdf6ec;
border: 1px solid #faecd8;
color: #f56c6c;
.CompletionAnswerIndex {
width: 25px;
height: 100%;
display: flex;
align-items: center;
border-right: 1px solid #faecd8;
margin-right: 20px;
}
.correctAnswer {
height: 40px;
margin-right: 40px;
}
}
}
}
}
.el-alert {
margin: 20px 0 0;
}
.el-alert:first-child {
margin: 0;
}
.page-warning {
padding: 8px 16px;
background-color: #f0f9eb;
border-radius: 4px;
border-left: 5px solid #67c23a;
margin: 20px 0;
font-size: 13px;
margin-top: 30px;
color: darkkhaki;
p{
margin-bottom: 5px;
}
}
</style>

View File

@ -1,21 +1,51 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="名称" prop="name">
<el-form-item label="项目名称" prop="startProName" v-if="!userStore.currentProId">
<el-input
v-model="queryParams.name"
placeholder="请输入名称"
v-model="queryParams.startProName"
placeholder="请输入项目名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="流程名称" prop="procDefName">
<el-input
v-model="queryParams.procDefName"
placeholder="请输入流程名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="流程分类" prop="category">
<el-select v-model="queryParams.category" placeholder="请选择流程分类" clearable>
<el-option
v-for="dict in sys_process_category"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="接受时间">
<el-date-picker
v-model="daterangeTimes"
type="daterange"
unlink-panels
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
:shortcuts="shortcuts"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"></el-button>
<el-button icon="Refresh" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-row :gutter="10" class="mb8" v-if="false">
<el-col :span="1.5">
<el-button
type="danger"
@ -30,17 +60,26 @@
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="todoListData" border @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="任务编号" align="center" prop="taskId" :show-overflow-tooltip="true"/>
<el-table v-loading="loading" :data="todoListData" border>
<el-table-column label="任务编号" align="center" prop="taskId" width="88px" :show-overflow-tooltip="true"/>
<!-- <el-table-column label="所属公司" align="center" prop="startComName" :show-overflow-tooltip="true"/> -->
<el-table-column label="项目单位" align="center" prop="startProName" :show-overflow-tooltip="true"/>
<el-table-column label="流程名称" align="center" prop="procDefName"/>
<el-table-column label="流程分类" align="center" prop="category" width="180">
<template #default="scope">
<dict-tag
:options="sys_process_category"
:value="scope.row.category"
/>
</template>
</el-table-column>
<el-table-column label="当前节点" align="center" prop="taskName"/>
<el-table-column label="流程版本" align="center">
<el-table-column label="流程版本" align="center" width="80">
<template #default="scope">
<el-tag size="small" >v{{scope.row.procDefVersion}}</el-tag>
</template>
</el-table-column>
<el-table-column label="流程发起人" align="center">
<el-table-column label="流程发起人" align="center" width="220">
<template #default="scope">
<label>{{scope.row.startUserName}} <el-tag type="info" size="small">{{scope.row.startDeptName}}</el-tag></label>
</template>
@ -52,7 +91,7 @@
link
size="small"
type="primary"
icon="Pointer"
icon="Finished"
@click="handleProcess(scope.row)"
>处理
</el-button>
@ -67,15 +106,23 @@
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<approveProcess ref="approveProcessRef" @handle="handleSuccess"/>
</div>
</template>
<script setup name="Todo">
import { todoList, delDeployment } from "@/api/flowable/todo";
import { myAwaitFlowTaskList } from "@/api/flowable/businessKey";
import useUserStore from '@/store/modules/user'
import router from "@/router";
import approveProcess from "@/views/flowable/task/todo/detail/indexDrawer.vue";
const { proxy } = getCurrentInstance();
const { sys_process_category } = proxy.useDict('sys_process_category');
const userStore = useUserStore()
const approveProcessRef = ref("");
//
const loading = ref(true);
//
@ -94,13 +141,44 @@ const todoListData = ref([]);
const title = ref("");
//
const open = ref(false);
const daterangeTimes = ref([]);
const shortcuts = [
{
text: '最近一周',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
return [start, end]
},
},
{
text: '最近一个月',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
return [start, end]
},
},
{
text: '最近三个月',
value: () => {
const end = new Date()
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
return [start, end]
},
},
];
const data = reactive({
//
queryParams: {
pageNum: 1,
pageSize: 10,
name: null,
startProName: null,
procDefName: null,
category: null
},
});
@ -110,24 +188,31 @@ const { queryParams } = toRefs(data);
/** 查询流程定义列表 */
function getList() {
loading.value = true;
todoList(queryParams.value).then(response => {
myAwaitFlowTaskList(proxy.addDateRange(queryParams.value, daterangeTimes.value)).then(response => {
todoListData.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
/** 处理成功 */
function handleSuccess(){
getList();
userStore.getTasks(); //
}
/** 跳转到流程处理页面 */
function handleProcess(row){
router.push({ path: '/flowable/task/todo/detail/index',
query: {
procInsId: row.procInsId,
executionId: row.executionId,
deployId: row.deployId,
taskId: row.taskId,
taskName: row.taskName,
startUser: row.startUserName + '-' + row.startDeptName,
}})
approveProcessRef.value.show(row);
// router.push({ path: '/flowable/task/todo/detail/index',
// query: {
// procInsId: row.procInsId,
// executionId: row.executionId,
// deployId: row.deployId,
// taskId: row.taskId,
// taskName: row.taskName,
// startUser: row.startUserName + '-' + row.startDeptName,
// }})
}
/** 搜索按钮操作 */

View File

@ -206,7 +206,8 @@
</template>
</el-statistic>
<div class="countdown-footer">
<strong style="font-size: 16px; color: #909399">{{form.useTimes?form.useTimes:'-'}}</strong>
<strong style="font-size: 16px; color: #909399" v-if="form.useTimes">{{formatDuraTime(form.useTimes)}}</strong>
<strong style="font-size: 16px; color: #909399" v-if="!form.useTimes"> - </strong>
</div>
</el-col>
<el-col :span="6">
@ -409,7 +410,6 @@ function handleDetail(row) {
}
item.questionOption = JSON.parse(item.questionOption);
});
console.log("LIST",list);
useQuestionList.value = list;
form.value = response.data;
open.value = true;