YZProjectCloud/yanzhu-ui-vue3/src/views/flowable/task/todo/detail/indexDrawer.vue

1029 lines
41 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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' || dataOptions.category=='5' || dataOptions.category=='6' || dataOptions.category=='8'">
<el-form label-width="100px" size="small" >
<el-form-item label="代理人身份证" v-if="dataOptions.category=='1'">
<ImagePreview :src="initData.userInfos.cardImgPos" :width="120" :height="70"/>
<ImagePreview :src="initData.userInfos.cardImgInv" :width="120" :height="70" style="margin-left: 20px;"/>
</el-form-item>
<el-form-item label="入场肖像近照" v-if="dataOptions.category=='1'">
<ImagePreview :src="initData.userPicture" :width="120" :height="70"/>
</el-form-item>
<el-form-item label="单位委托证明" v-if="dataOptions.category!='3' && dataOptions.category!='4' && dataOptions.category!='5' && dataOptions.category!='8'">
<ImagePreview :src="initData.subDeptPowerPath" :width="120" :height="70"/>
</el-form-item>
<el-form-item label="委托人姓名" v-if="dataOptions.category=='1'">
{{ initData.userName }} <el-tag type="info">{{ initData.cardCode }}</el-tag>
</el-form-item>
<el-form-item label="人员姓名" v-if="dataOptions.category!='1'">
{{ initData.userName }} <el-tag type="info">{{ initData.cardCode }}</el-tag>
</el-form-item>
<el-form-item label="工种岗位" v-if="dataOptions.category!='1'">
{{ initData.craftPostName }}
</el-form-item>
<el-form-item label="工种班组" v-if="dataOptions.category!='1' && dataOptions.category!='2'">
{{ initData.subDeptGroupName }}
</el-form-item>
<el-form-item label="民族" v-if="dataOptions.category!='1'">
{{ initData.userInfos.nation }}
</el-form-item>
<el-form-item label="籍贯" v-if="dataOptions.category!='1'">
{{ initData.userInfos.nativePlace }}
</el-form-item>
<el-form-item label="详细地址" v-if="dataOptions.category!='1'">
{{ initData.userInfos.address }}
</el-form-item>
<el-form-item label="身份证照片" v-if="dataOptions.category!='1'">
<ImagePreview :src="initData.userInfos.cardImgPos" :width="120" :height="70"/>
<ImagePreview :src="initData.userInfos.cardImgInv" :width="120" :height="70" style="margin-left: 20px;"/>
</el-form-item>
<el-form-item label="入场肖像近照" v-if="dataOptions.category!='1'">
<ImagePreview :src="initData.userPicture" :width="120" :height="70"/>
</el-form-item>
<el-form-item label="紧急联系人" v-if="dataOptions.category!='1'">
{{ initData.userInfos.emergencyContact }} <el-tag type="info">{{ initData.userInfos.contactPhone }}</el-tag>
</el-form-item>
<el-form-item label="开户行名称" v-if="dataOptions.category=='4'">
{{ initData.userInfos.bankName }}
</el-form-item>
<el-form-item label="开户行网点" v-if="dataOptions.category=='4'">
{{ initData.userInfos.bankName }}
</el-form-item>
<el-form-item label="工资银行卡号" v-if="dataOptions.category=='4'">
{{ initData.userInfos.bankName }}
</el-form-item>
<el-form-item label="联系电话">
{{ initData.userPhone }}
</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' || dataOptions.category=='5' || dataOptions.category=='46' || dataOptions.category=='8'">
<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' || dataOptions.category=='5' || dataOptions.category=='6' || dataOptions.category=='8'">
<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
v-if="false"
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 v-if="false">
<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, editApproveStatus } 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: {
userInfos: {}
},
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(() => {
editApproveStatus(dataOptions.value.businessKey);
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 = "users";
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 || category==5 || category==6 || category==8){
getProProjectInfoSubdeptsUsers(dataOptions.value.businessKey).then(res =>{
if(res.data.userInfos){
res.data.userInfos = JSON.parse(res.data.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.startProId, dataOptions.value.startUserId).then(res =>{
userEduVideoList.value = res.data||[]
});
}
/** 用户考试情况 */
function findEduExams(){
getBusExamUserLast(dataOptions.value.startProId, 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>