添加工作流 设计器

This commit is contained in:
GGJ
2024-04-16 08:41:41 +08:00
parent 071ee4d2b5
commit ecb649dc47
79 changed files with 11162 additions and 207 deletions

View File

@@ -27,50 +27,81 @@
<el-divider content-position="left" style="font-size: 18px; font-weight: bolder">填报流程</el-divider>
<el-steps :active="active" finish-status="success" class="mb10" simple>
<el-step v-for="(item, i) in stepTitle">
<template #title>
<span @click="step(i)">{{ item }}</span>
</template>
</el-step>
</el-steps>
<el-tabs v-model="activeName" type="border-card">
<el-tab-pane label="原因分析" name="0">
<process1
:addData="addData"
:List="List"
:disabled="disabled"
ref="process0Ref"
@handleClose="handleClose"
/>
</el-tab-pane>
<el-tab-pane label="计划整改措施" name="1">
<process2
:addData="addData"
:List="List"
:disabled="disabled"
ref="process1Ref"
@handleClose="handleClose"
/>
</el-tab-pane>
<el-tab-pane label="实际采取措施" name="2">
<process3
:addData="addData"
:List="List"
:disabled="disabled"
ref="process2Ref"
@handleClose="handleClose"
/>
</el-tab-pane>
<el-tab-pane label="成效分析" name="3">
<process4
:addData="addData"
:List="List"
:disabled="disabled"
ref="process3Ref"
@handleClose="handleClose"
/>
</el-tab-pane>
</el-tabs>
<!-- 原因分析 0 -->
<process1
<!-- <process1
v-if="control == 0"
:addData="addData"
:List="List"
:disabled="disabled"
ref="process0Ref"
@handleClose="handleClose"
/>
/> -->
<!-- 计划整改措施 1-->
<process2
<!-- <process2
v-if="control == 1"
:addData="addData"
:List="List"
:disabled="disabled"
ref="process1Ref"
@handleClose="handleClose"
/>
/> -->
<!-- 实际采取措施 2 -->
<process3
<!-- <process3
v-if="control == 2"
:addData="addData"
:List="List"
:disabled="disabled"
ref="process2Ref"
@handleClose="handleClose"
/>
/> -->
<!-- 成效分析 3 -->
<process4
<!-- <process4
v-if="control == 3"
:addData="addData"
:List="List"
:disabled="disabled"
ref="process3Ref"
@handleClose="handleClose"
/>
/> -->
<!-- 填报 -->
<div style="display: flex; justify-content: center; margin-top: 10px" v-show="!disabled">
@@ -126,7 +157,7 @@ const List: any = ref({})
const active = ref(4)
const control = ref()
const ruleFormRef = ref()
const stepTitle = ['原因分析', '计划整改措施', '实际采取措施', '成效分析']
const activeName = ref('0')
const process0Ref = ref()
const process1Ref = ref()
const process2Ref = ref()
@@ -257,4 +288,7 @@ defineExpose({ open })
:deep(.el-upload-list__item) {
width: 400px;
}
:deep(.el-tabs__content) {
height: auto !important;
}
</style>

View File

@@ -20,8 +20,7 @@ defineOptions({
name: 'Processsupervision/electricitymanagement'
})
const activeName = ref('1')
const Statistics = ref()
const compatibility = ref()
const layout = mainHeight(63) as any
</script>

View File

@@ -18,7 +18,7 @@
<planAdd ref="planAddRef" @onsubmit="tableStore.index()" />
<!-- 选择审核人 -->
<el-dialog v-model="dialogVisible" title="审核" width="300" :before-close="handleClose">
<el-dialog draggable v-model="dialogVisible" title="审核" width="300" :before-close="handleClose">
选择审核人: <el-select v-model="auditUser" clearable placeholder="请选择计划状态">
<el-option v-for="item in auditList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
@@ -40,7 +40,7 @@ import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { planStatus } from '@/api/process-boot/generalTest'
import { submitAuditUser } from '@/api/process-boot/generalTest'
import planAdd from './planAdd.vue'
import { useDictData } from '@/stores/dictData'
@@ -190,13 +190,20 @@ const submit = () => {
}
// 提交审核
const planReviewFn = () => {
if(auditUser.value == ''){
return ElMessage.warning('请选择审核人')
}
let planNo: any = []
tableStore.table.selection.forEach(item => {
if (item.status == 0 || item.status == 2) {
planNo.push(item.planNo)
}
})
planStatus(planNo).then(res => {
submitAuditUser({
auditUser: auditUser.value,
planIds: planNo
}).then(res => {
dialogVisible.value = false
ElMessage.success('提交成功!')
tableStore.index()
})

View File

@@ -19,9 +19,9 @@
></el-input>
</el-form-item>
</template>
<template #operation>
<!-- <template #operation>
<el-button icon="el-icon-Stamp" type="primary">审核</el-button>
</template>
</template> -->
</TableHeader>
<Table ref="tableRef" />
<!-- 审核 -->
@@ -36,7 +36,7 @@ import TableHeader from '@/components/table/header/index.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { mainHeight } from '@/utils/layout'
import { useDictData } from '@/stores/dictData'
import Audit from './audit.vue'
import Audit from '../undocumented/audit.vue'
const dictData = useDictData()
const interferenceType = dictData.getBasicData('Interference_Source')
@@ -82,7 +82,7 @@ const tableStore = new TableStore({
beforeSearchFun: () => {
tableStore.table.params.orgNo = tableStore.table.params.deptIndex
tableStore.table.params.checkType = 1
// tableStore.table.params.checkType = 1
}
})

View File

@@ -1,4 +1,5 @@
<template>
<!-- 上传 -->
<el-dialog draggable :title="title" v-model="uploadConclusions" width="1500px" :before-close="cancel">
<el-divider content-position="left">基本信息</el-divider>
@@ -8,8 +9,7 @@
:model="addForm"
label-width="auto"
:rules="rules"
class
:disabled="title == '未建档干扰源用户详情'"
:disabled="title == '未建档干扰源用户详情' || title == '入网评估报告审核'"
>
<el-form-item label="所属单位:">
<Area v-model="addForm.orgNo" disabled />
@@ -63,7 +63,7 @@
<el-radio v-model="addForm.iIsOverLimit" :label="1"></el-radio>
<el-radio v-model="addForm.iIsOverLimit" :label="0"></el-radio>
</el-form-item>
<br v-if="show"/>
<br v-if="show" />
<el-form-item label="超标指标:" style="margin-top: 10px" prop="IOverLimitTarget" v-if="show">
<el-checkbox-group v-model="addForm.IOverLimitTarget">
<el-checkbox v-for="(item, ind) in exceeded" :label="item.id">
@@ -71,7 +71,7 @@
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<br v-if="show"/>
<br v-if="show" />
<el-form-item label="计划采取措施:" style="margin-top: 10px" prop="IPlanStep" v-if="show">
<el-select v-model="addForm.IPlanStep" placeholder="请选择">
<el-option
@@ -89,15 +89,45 @@
:autosize="{ minRows: 2, maxRows: 4 }"
placeholder="请输入入网详情"
type="textarea"
style="width: 500px"
style="width: 400px"
></el-input>
</el-form-item>
<el-form
:inline="true"
:model="addForm"
label-width="auto"
ref="form1Ref"
style="margin-left: 32px;"
:rules="rules"
v-if="title == '入网评估报告审核'"
>
<el-divider content-position="left" style="font-size: 18px; font-weight: bolder">审核意见</el-divider>
<el-form-item label="审核意见:" prop="checkComment">
<el-input
type="textarea"
style="width: 400px"
placeholder="请输入审核意见"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="addForm.checkComment"
></el-input>
</el-form-item>
</el-form>
</el-form>
<div style="display: flex; justify-content: center; margin-top: 30px" v-if="title != '未建档干扰源用户详情'">
<div
style="display: flex; justify-content: center; margin-top: 30px"
v-if="title != '未建档干扰源用户详情' && title != '入网评估报告审核'"
>
<el-button type="primary" class="ml20" @click="submit(1)">审核</el-button>
<el-button type="primary" class="ml20" @click="submit(2)">保存</el-button>
<el-button type="primary" class="ml20" @click="cancel">取消</el-button>
</div>
<div style="display: flex; justify-content: center; margin-top: 30px" v-if="title == '入网评估报告审核'">
<el-button type="primary" class="ml20" @click="audit(1)">通过</el-button>
<el-button type="primary" class="ml20" @click="audit(0)">不通过</el-button>
<el-button type="primary" class="ml20" @click="cancel">取消</el-button>
</div>
</el-dialog>
</template>
<script setup lang="ts">
@@ -106,7 +136,7 @@ import { useDictData } from '@/stores/dictData'
import Area from '@/components/form/area/index.vue'
import { UploadInstance, UploadProps, UploadRawFile, ElMessage, ElMessageBox } from 'element-plus'
import { genFileId } from 'element-plus'
import { uploadLoadTypeUserI, getLoadTypeUserById } from '@/api/process-boot/interference'
import { uploadLoadTypeUserI, getLoadTypeUserById, checkLoadTypeUserI } from '@/api/process-boot/interference'
const dictData = useDictData()
const exceeded = dictData.getBasicData('Steady_Statis')
@@ -134,10 +164,13 @@ const rules = {
iIsOverLimit: [{ required: true, message: '请选择是否超标', trigger: 'change' }],
IDescription: [{ required: true, message: '请输入入网详情', trigger: 'blur' }],
IPlanStep: [{ required: true, message: '请选择计划采取措施', trigger: 'change' }],
IOverLimitTarget: [{ required: true, message: '请选择超标指标', trigger: 'change' }]
IOverLimitTarget: [{ required: true, message: '请选择超标指标', trigger: 'change' }],
checkComment: [{ required: true, message: '请输入入网详情', trigger: 'blur' }]
}
const formRef = ref()
const form1Ref = ref()
// 填报 审核
const submit = (flag: any) => {
formRef.value.validate((valid: any) => {
if (valid) {
@@ -165,6 +198,23 @@ const submit = (flag: any) => {
}
})
}
// 入网审核
const audit = (flag: any) => {
form1Ref.value?.validate((valid: any) => {
if (valid) {
checkLoadTypeUserI({
checkComment: addForm.value.checkComment,
checkPerson: dictData.state.area[0].id,
checkResult: flag,
id: addForm.value.id
}).then((res: any) => {
ElMessage.success('操作成功')
cancel()
emit('onSubmit')
})
}
})
}
const handleExceed: UploadProps['onExceed'] = files => {
upload.value!.clearFiles()
const file = files[0] as UploadRawFile
@@ -191,8 +241,8 @@ const cancel = () => {
const open = (text: string, row: any) => {
title.value = text
getLoadTypeUserById({ id: row.id }).then((res: any) => {
uploadConclusions.value = true
addForm.value = {
id: res.data.id,
orgNo: res.data.orgNo,
@@ -207,9 +257,8 @@ const open = (text: string, row: any) => {
ifilePathName: res.data.ifilePathName ? res.data.ifilePathName : '',
ifile: res.data.ifile
}
res.data.iisOverLimit == 0 ? (show.value = false) : (show.value = true)
})
uploadConclusions.value = true
}
const changeOverLimit = (e: any) => {
if (e.target.value == 0) {

View File

@@ -0,0 +1,224 @@
<template>
<div class="default-main">
<TableHeader area datePicker ref="TableHeaderRef">
<template #select>
<el-form-item label="问题来源">
<el-select v-model="tableStore.table.params.problemSources" clearable placeholder="请选择问题来源">
<el-option
v-for="item in problemData"
:key="item.code"
:label="item.name"
:value="item.code"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="填报进度">
<el-select v-model="tableStore.table.params.reportProcess" clearable placeholder="请选择填报进度">
<el-option
v-for="item in fillingProgress"
:key="item.code"
:label="item.name"
:value="item.code"
></el-option>
</el-select>
</el-form-item>
</template>
<template #operation>
<el-button icon="el-icon-Plus" type="primary" @click="add">新增</el-button>
</template>
</TableHeader>
<Table ref="tableRef" />
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, provide, nextTick } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { deleteIssues, archive } from '@/api/process-boot/electricitymanagement'
import { useDictData } from '@/stores/dictData'
const dictData = useDictData()
const FillingRef = ref()
const showNewlyAdded = ref(false)
const dialogVisible = ref(false)
const recordingRef = ref(false)
const TableHeaderRef = ref()
const detailRef = ref()
const problemData = dictData.getBasicData('Problem_Sources')
const fillingProgress = dictData.getBasicData('Fill_Progress')
const auditStatus = dictData.getBasicData('Audit_Status')
defineOptions({
name: '/Processsupervision/retire'
})
const tableStore: any = new TableStore({
url: '/process-boot/electricityQuality/getIssues',
method: 'POST',
column: [
// { width: '60', type: 'checkbox' },
{
field: 'index',
title: '序号',
width: '60',
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ field: 'orgName', title: '所属单位' },
{
field: 'problemSources',
title: '问题来源'
},
{ field: 'powerQualityProblemNo', title: '问题编号' },
{ field: 'problemName', title: '问题名称' },
{ field: 'dataDate', title: '问题新建时间' },
{
field: 'reportProcess',
title: '填报进度',
formatter: (row: any) => {
return fillingProgress.filter(item => item.code == row.cellValue)[0]?.name
}
},
{
field: 'reportProcessStatus',
title: '审核状态',
formatter: (row: any) => {
return auditStatus.filter(item => item.code == row.cellValue)[0]?.name
}
},
{
title: '操作',
width: '180',
render: 'buttons',
buttons: [
{
name: 'edit',
title: '查看',
type: 'primary',
disabled: row => {
return row.reportProcessStatus == 'Init'
},
icon: 'el-icon-Plus',
render: 'basicButton',
click: async row => {
detailRef.value.open(row)
}
},
{
name: 'edit',
title: '填报',
disabled: row => {
return (
row.reportProcessStatus == 'Auditt' ||
(row.reportProcess == 'Insights' && row.reportProcessStatus == 'Success') ||
row.reportProcess == 'Archived'
)
},
type: 'primary',
icon: 'el-icon-Plus',
render: 'basicButton',
click: row => {
dialogVisible.value = true
setTimeout(() => {
FillingRef.value.open(row)
}, 10)
}
},
{
name: 'edit',
title: '归档',
disabled: row => {
return !(row.reportProcess == 'Insights' && row.reportProcessStatus == 'Success')
},
type: 'primary',
icon: 'el-icon-SuccessFilled',
render: 'basicButton',
popconfirm: {
confirmButtonText: '确认',
cancelButtonText: '取消',
confirmButtonType: 'danger',
title: '确定归档?'
},
click: row => {
archive(row.powerQualityProblemNo).then(() => {
ElMessage.success('归档成功!')
tableStore.index()
})
}
},
{
name: 'edit',
title: '审核记录',
type: 'primary',
disabled: row => {
return row.reportProcessStatus == 'Init'
},
icon: 'el-icon-PieChart',
render: 'basicButton',
click: row => {
recordingRef.value.open(row)
}
},
{
name: 'del',
text: '删除',
type: 'danger',
icon: 'el-icon-Delete',
render: 'confirmButton',
popconfirm: {
confirmButtonText: '确认',
cancelButtonText: '取消',
confirmButtonType: 'danger',
title: '确定删除?'
},
disabled: row => {
return row.reportProcess == 'Archived'
},
click: row => {
deleteIssues(row.powerQualityProblemNo).then(() => {
ElMessage.success('删除成功')
tableStore.index()
})
}
}
]
}
],
beforeSearchFun: () => {
tableStore.table.params.orgNo = tableStore.table.params.deptIndex
tableStore.table.params.dataDate = tableStore.table.params.searchBeginTime
tableStore.table.params.dataType = TableHeaderRef.value.datePickerRef.interval
}
})
tableStore.table.params.problemName = ''
tableStore.table.params.problemSources = ''
tableStore.table.params.reportProcess = ''
tableStore.table.params.reportProcessStatus = ''
provide('tableStore', tableStore)
onMounted(() => {
TableHeaderRef.value.setDatePicker([
{ label: '年', value: 1 },
{ label: '季', value: 2 },
{ label: '月', value: 3 }
])
tableStore.index()
})
// 新增
const add = () => {
showNewlyAdded.value = true
}
// 关闭弹框
const handleClose = () => {
showNewlyAdded.value = false
}
// 关闭 填报
const beforeClose = () => {
dialogVisible.value = false
tableStore.index()
}
</script>

View File

@@ -1,73 +0,0 @@
<template>
<div class="containerBox" style="position: relative">
<div id="container" style="width: calc(100vw - 750px); height: calc(100vh - 150px)"></div>
<div id="js-properties-panel" class="panel"></div>
</div>
</template>
<script setup lang="ts">
import { onMounted, markRaw } from 'vue'
import 'bpmn-js/dist/assets/diagram-js.css' // 左边工具栏以及编辑节点的样式
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
import BpmnModeler from 'bpmn-js/lib/Modeler'
// bpmn-js-properties-panel相关
import 'bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css'
import propertiesPanelModule from 'bpmn-js-properties-panel'
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
import translate from '@/assets/bpmn/translate'
onMounted(() => {
const containerEl = document.getElementById('container')
const bpmnModeler = markRaw(
new BpmnModeler({
container: containerEl,
// 添加控制板
propertiesPanel: {
parent: '#js-properties-panel'
},
// 右侧属性面板
additionalModules: [propertiesPanelModule, propertiesProviderModule],
moddleExtensions: {
camunda: camundaModdleDescriptor
}
})
)
bpmnModeler.createDiagram(() => {
bpmnModeler.get('canvas').zoom('fit-viewport')
})
})
var customTranslateModule = {
translate: ['value', translate]
}
const bpmnModeler = new BpmnModeler({
additionalModules: [customTranslateModule]
})
</script>
<style lang="scss" scoped>
.containerBox {
height: calc(100vh - 160px);
margin-top: 30px;
}
.containerBox #container {
height: calc(100vh - 160px);
border: 1px solid rgb(121, 121, 121);
}
.bpp-properties-panel [type='text'] {
box-sizing: border-box;
}
.panel {
width: 400px;
position: absolute;
top: 1px;
right: 1px;
height: 100%;
overflow: auto;
}
/* 右下角logo */
.bjs-powered-by {
display: none;
}
</style>

View File

@@ -1,19 +0,0 @@
<template>
<div class="default-main" :style="layout">
<!-- <work /> -->
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref, provide } from 'vue'
// import work from './work.vue'
import { mainHeight } from '@/utils/layout'
defineOptions({
name: 'Workflow/Designer/tools'
})
const layout = mainHeight(20)
</script>
<style lang="scss" scoped></style>

View File

@@ -1,11 +0,0 @@
<template>
<div> </div>
</template>
<script setup lang='ts'>
import { ref, reactive } from 'vue'
</script>
<style lang="scss" scoped>
</style>

View File

@@ -1,72 +0,0 @@
import type { XmlMetaInfo } from "@/api/activiti/modeler";
/**
* bpmn2.0标准
* activiti标准转化为camunda标准
* @param xml
*/
export const activitiToCamundaXml = (xml: string, metaInfo?: XmlMetaInfo) => {
//替换activiti标准
xml = xml.replace("xmlns:activiti", "xmlns:camunda");
xml = xml.replace("http://activiti.org/bpmn", "http://camunda.org/schema/1.0/bpmn");
xml = xml.replaceAll("activiti:", "camunda:");
//显示版本信息
if (metaInfo && metaInfo.version) {
xml.replace("<bpmn2:process", `<bpmn:process camunda:versionTag="${metaInfo.version}"`);
}
return xml;
};
/**
* bpmn2.0标准
* camunda标准转化为activiti标准
* @param xml
*/
export const camundaToActivitiXml = (xml: string) => {
//追加头部信息
xml = xml.replace(
"<bpmn2:definitions",
`<bpmn2:definitions typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath"`
);
//删除版本号
// xml = xml.replace(/camunda:versionTag="*"/, "");
//替换camunda标准
xml = xml.replace("xmlns:camunda", "xmlns:activiti");
xml = xml.replace("http://camunda.org/schema/1.0/bpmn", "http://activiti.org/bpmn");
xml = xml.replaceAll("camunda:", "activiti:");
return xml;
};
/**
* bpmn2.0标准
* 初始化一个camunda标准的xml
* @param {XmlMetaInfo} metaInfo
* @returns {string}
*/
const createBpmnXml = ({ key, name, description, version }: XmlMetaInfo) => {
const keyStr = key ? key : "Process_1";
const nameStr = name ? name : "";
const descriptionStr = description ? `<bpmn2:documentation>${description}</bpmn2:documentation>` : "";
const versionStr = version ? version : 1;
const xmlStr = `<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.activiti.org/test">
<bpmn2:process id="${keyStr}" name="${nameStr}" isExecutable="true" camunda:versionTag="${versionStr}" >
${descriptionStr}
</bpmn2:process>
<bpmndi:BPMNDiagram id="BpmnDiagram_1">
<bpmndi:BPMNPlane id="BpmnPlane_1" bpmnElement="${keyStr}" />
</bpmndi:BPMNDiagram>
</bpmn2:definitions>`;
return xmlStr;
};
export default createBpmnXml;