jhprjv2/ruoyi-ui/src/views/flowable/task/myProcess/initLeaveTaskDrawer.vue

492 lines
16 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-container">
<el-drawer
v-if="onOpen"
:visible.sync="onOpen"
ref="drawer"
direction="rtl"
size="60%"
@close="closeCallBack"
>
<template slot="title">
<div>工程管理 【{{ title }}】</div>
</template>
<el-form
ref="form"
:model="form"
:rules="rules"
v-loading="loading"
label-width="120px"
style="padding-right: 35px;"
>
<div class="block containers">
<div class="canvas" ref="flowCanvas"></div>
<div class="maskLayer" />
</div>
<el-card class="box-card" style="margin-left:35px;">
<el-descriptions class="margin-top" :title="title" :column="2" size="medium" border>
<el-descriptions-item :span="2" prop="businessKey">
<template slot="label">
<i class="el-icon-map-location"></i>
所属项目<span class="cr"> *</span>
</template>
<el-select
v-model="form.businessKey"
placeholder="请选择所属项目"
style="width: 100%"
filterable
:disabled="disPro"
@change="projectChage"
>
<el-option
v-for="(item, index) in projectOptions"
:key="index"
:label="item.projectName"
:value="item.id"
>
</el-option>
</el-select>
</el-descriptions-item>
<el-descriptions-item :span="2" label-class-name="my-label" :labelStyle="labelStyle">
<template slot="label">
<i class="el-icon-school"></i>
申请单位
</template>
{{ deptName }}
</el-descriptions-item>
<el-descriptions-item :span="2" label-class-name="my-label" :labelStyle="labelStyle">
<template slot="label">
<i class="el-icon-collection-tag"></i>
申请事项
</template>
{{ title }}
</el-descriptions-item>
<el-descriptions-item label-class-name="my-label" :labelStyle="labelStyle">
<template slot="label">
<i class="el-icon-user"></i>
申请人
</template>
{{ nickName }}
</el-descriptions-item>
<el-descriptions-item label-class-name="my-label" :labelStyle="labelStyle">
<template slot="label">
<i class="el-icon-s-flag"></i>
申请日期
</template>
{{ form.date }}
</el-descriptions-item>
<el-descriptions-item label-class-name="my-label" :labelStyle="labelStyle">
<template slot="label">
<i class="el-icon-time"></i>
请假日期<span class="cr"> *</span>
</template>
<el-date-picker
v-model="daterangeMarksTime"
style="width: 400px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="checkTime"
></el-date-picker>
</el-descriptions-item>
<el-descriptions-item label-class-name="my-label" :labelStyle="labelStyle">
<template slot="label">
<i class="el-icon-tickets"></i>
请假时间
</template>
{{times}}
</el-descriptions-item>
<el-descriptions-item :span="2" label-class-name="my-label" :labelStyle="labelStyle">
<template slot="label">
<i class="el-icon-chat-dot-square"></i>
请假事由<span class="cr"> *</span>
</template>
<el-input
type="textarea"
v-model="form.remark"
placeholder="请输入申请说明"
rows="5"
max="1"
/>
</el-descriptions-item>
</el-descriptions>
<div style="text-align: center;margin-top: 30px;">
<el-button type="primary" @click="submitForm">提交申请</el-button>
<el-button @click="doCanel">取 消</el-button>
</div>
</el-card>
</el-form>
</el-drawer>
</div>
</template>
<script>
import store from "@/store";
import { definitionStart, flowXmlAndNode } from "@/api/flowable/definition";
import { CustomViewer as BpmnViewer } from "@/components/customBpmn";
import { complete, getNextFlowNodeByStart } from "@/api/flowable/todo";
import { findFormDatasByProcInsId } from "@/api/flowable/businessKey";
export default {
components: {},
props: {
closeCallBack: {
type: Function,
},
},
data() {
return {
// 抽屉层
onOpen: false,
// 遮罩层
loading: false,
// 标题
title: "",
// 表单参数
form: {
businessKey: "",
projectName: "",
files: "",
remark: "",
date:"",
},
// 表单校验
rules: {},
projectOptions: null,
deptName: null,
nickName: null,
disPro: false,
bpmnViewer: null,
options: {},
taskTitle: null,
taskOpen: false,
daterangeMarksTime: [],
//label样式
labelStyle: { width: "180px" },
times:"... ...",
date:null
};
},
computed: {},
watch: {},
created() {},
mounted() {},
beforeDestroy() {},
methods: {
// 查询和我相关的项目信息
initMyProject() {
// 获取项目列表的接口
this.$api.publics.getMyProjectList({}).then((response) => {
this.projectOptions = response.rows;
if (response.rows.length == 0) {
this.$message.error("未查询到和您关联项目,请联系子公司或管理员...");
} else if (response.rows.length == 1) {
// 这里只有一个项目,默认选中并只读
this.form.businessKey = response.rows[0].id;
this.form.projectName = response.rows[0].projectName;
}
});
},
// 项目选择
projectChage(val) {
let projectName = "";
this.projectOptions.forEach((item) => {
if ((item.id = val)) {
projectName = item.projectName;
return;
}
});
this.form.projectName = projectName;
},
doCanel() {
this.onOpen = false;
},
show(options) {
this.options = options;
this.form={};
if(options.procInsId){
this.title = options.procDefName;
this.initFormDate(options.procInsId);
this.onOpen = true;
flowXmlAndNode({ procInsId:options.procInsId, deployId: options.deployId }).then((res) => {
this.initFlowImage(res.data);
});
}else{
this.initMyProject();
this.title = options.name;
this.deptName = store.getters.dept.deptName;
this.nickName = store.getters.name;
this.form.date = this.$dt(new Date()).format("YYYY-MM-DD HH:mm");
this.onOpen = true;
flowXmlAndNode({ deployId: options.deploymentId }).then((res) => {
this.initFlowImage(res.data);
});
}
},
async initFlowImage(data) {
const self = this;
try {
self.bpmnViewer = new BpmnViewer({
container: this.$refs.flowCanvas,
height: "150px",
});
await self.bpmnViewer.importXML(data.xmlData);
// 自适应
self.bpmnViewer.get("canvas").zoom("fit-viewport", "auto");
if (data.nodeData !==undefined && data.nodeData.length > 0 ) {
self.fillColor(data.nodeData)
}
} catch (err) {
console.error(err.message, err.warnings);
}
},
/** 流程表单数据 */
initFormDate(procInsId, deployId) {
this.projectOptions=[{id:this.options.businessKey,projectName:this.options.businessKeyName}];
const params = {procInsId: procInsId}
findFormDatasByProcInsId(params).then(res => {
this.form = res.data;
this.deptName = this.options.startDeptName;
this.nickName = this.options.startUserName;
this.form.taskId = this.options.taskId;
this.form.taskName = this.options.taskName;
this.form.userId = store.getters.userId;
this.form.procInsId = this.options.procInsId;
this.form.instanceId = this.options.procInsId;
this.times = res.data.day;
this.daterangeMarksTime=[];
this.daterangeMarksTime[0]=new Date(res.data.beginDate);
this.daterangeMarksTime[1]=new Date(res.data.endDate);
}).catch(res => {
this.$message.error("数据异常,请联系管理员...");
})
},
checkTime(val) {
let time = new Date(val[1]).getTime()-new Date(val[0]).getTime();
let hours = time/3600000;
let day = (hours/24)+1;//这里默认加1天PS:2023-09-10 2023-09-11实际请假应该为2天而不是一天
if(hours%24>0) day++;
this.form.day=day;
this.times="共 "+day+" 天"
},
submitForm() {
this.$refs["form"].validate((valid) => {
if (valid) {
// 根据当前任务或者流程设计配置的下一步节点 todo 暂时未涉及到考虑网关、表达式和多节点情况
// getNextFlowNodeByStart({
// deploymentId: this.options.deploymentId,
// variables: this.form,
// }).then((res) => {
// const data = res.data;
// if (data) {
// console.log(data);
// this.loading = false;
// }
// });
// 启动流程并将表单数据加入流程变量
if(!this.form.businessKey){
this.$modal.msgWarning("请选择所属项目...");
return;
}
if (null != this.daterangeMarksTime && "" != this.daterangeMarksTime) {
this.form.beginDate = this.daterangeMarksTime[0];
this.form.endDate = this.daterangeMarksTime[1];
}else{
this.$modal.msgWarning("请选择请假日期...");
return;
}
if(!this.form.day){
this.$modal.msgWarning("请选择请假日期...");
return;
}
if(!this.form.remark){
this.$modal.msgWarning("请输入请假事由...");
return;
}
this.loading = true;
if(this.options.procInsId){
this.form.variables={
businessKey:this.form.businessKey,
projectName:this.form.projectName,
beginDate:this.form.beginDate,
endDate:this.form.endDate,
remark:this.form.remark,
day:this.form.day,
date:this.form.date,
INITIATOR:this.form.INITIATOR
}
complete(this.form).then(res => {
this.$store.dispatch('settingAwaitNum');
this.$modal.msgSuccess("任务提交成功");
this.loading = false;
//关闭并刷新列表
this.$refs.drawer.closeDrawer();
});
}else{
definitionStart(this.options.id, JSON.stringify(this.form)).then((res) => {
this.$modal.msgSuccess(res.msg);
this.loading = false;
//关闭并刷新列表
this.$refs.drawer.closeDrawer();
});
}
}
});
},
// 设置高亮颜色的
fillColor(nodeData) {
const canvas = this.bpmnViewer.get('canvas')
this.bpmnViewer.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
}
}
})
},
},
};
</script>
<style lang="scss">
.bjs-powered-by {
display: none !important;
}
.maskLayer {
width: 100%;
height: 150px;
position: absolute;
z-index: 9999;
top: 66px;
}
.cr{
font-weight: 700;
color: red;
}
.app-container{
.containers {
.canvas {
width: 100%;
height: 150px;
}
.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: 150px;
}
.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;
}
}
}
</style>