1029 lines
41 KiB
Vue
1029 lines
41 KiB
Vue
<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> |