问题模块

This commit is contained in:
pch 2025-02-21 09:12:15 +08:00
parent d8cc449bf5
commit 4f1bb23300
10 changed files with 748 additions and 32 deletions

3
.env
View File

@ -26,7 +26,8 @@ VITE_AI_URL = http://192.168.45.135:8000
#Onlyoffice相关
; VITE_ONLY_URL = http://140.143.164.40:48080
VITE_ONLY_URL = http://192.168.1.15:48080
VITE_ONLY_URL = http://192.168.1.44:48080
; VITE_ONLY_URL = http://192.168.1.15:48080
# 默认账户密码
VITE_APP_DEFAULT_LOGIN_TENANT = 君风科技

2
components.d.ts vendored
View File

@ -13,6 +13,7 @@ declare module 'vue' {
BpmnProcessDesignerPackageDesignerProcessDesigner: typeof import('./src/components/bpmnProcessDesigner/package/designer/ProcessDesigner.vue')['default']
BpmnProcessDesignerPackageDesignerProcessDesigner2: typeof import('./src/components/bpmnProcessDesigner/package/designer/ProcessDesigner2.vue')['default']
BpmnProcessDesignerPackageDesignerProcessViewer: typeof import('./src/components/bpmnProcessDesigner/package/designer/ProcessViewer.vue')['default']
BpmnProcessDesignerPackageDesignerProcessViewerForm: typeof import('./src/components/bpmnProcessDesigner/package/designer/ProcessViewerForm.vue')['default']
BpmnProcessDesignerPackagePaletteProcessPalette: typeof import('./src/components/bpmnProcessDesigner/package/palette/ProcessPalette.vue')['default']
BpmnProcessDesignerPackagePenalBaseElementBaseInfo: typeof import('./src/components/bpmnProcessDesigner/package/penal/base/ElementBaseInfo.vue')['default']
BpmnProcessDesignerPackagePenalCustomConfigComponentsBoundaryEventTimer: typeof import('./src/components/bpmnProcessDesigner/package/penal/custom-config/components/BoundaryEventTimer.vue')['default']
@ -143,7 +144,6 @@ declare module 'vue' {
RouterView: typeof import('vue-router')['RouterView']
SearchSrcSearch: typeof import('./src/components/Search/src/Search.vue')['default']
SelectBpmModelSelectModelForm: typeof import('./src/components/SelectBpmModel/SelectModelForm.vue')['default']
SelectMappingMultiple: typeof import('./src/components/SelectMappingMultiple/index.vue')['default']
SelectMappingSelectMapping: typeof import('./src/components/SelectMapping/SelectMapping.vue')['default']
ShortcutDateRangePicker: typeof import('./src/components/ShortcutDateRangePicker/index.vue')['default']
SimpleProcessDesignerSrcAddNode: typeof import('./src/components/SimpleProcessDesigner/src/addNode.vue')['default']

View File

@ -21,6 +21,7 @@ export interface FwglVO {
processInstanceId: string // 流程实例的编号
userId: number // 申请人的用户编号
status: number // 审批状态
createTime: number
startUserSelectAssignees:string | object //启动用户选择的用户信息
curfullpath:string // 当前表单路径
processDefinitionKey:string //流程定义的key

View File

@ -6,6 +6,7 @@ export interface QuestionVO {
userId: number // 申请人的用户编号
userName: string // 作者
typeId: number // 类型id
createTime: number
deptId: number // 部门id
deptName: string // 部门名字
title: string // 问题标题

View File

@ -0,0 +1,664 @@
<template>
<div class="my-process-designer">
<div class="my-process-designer__container">
<div class="my-process-designer__canvas" style="height: 760px" ref="bpmnCanvas"></div>
</div>
</div>
</template>
<script lang="ts" setup>
import BpmnViewer from 'bpmn-js/lib/Viewer'
import DefaultEmptyXML from './plugins/defaultEmpty'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import { isEmpty } from '@/utils/is'
defineOptions({ name: 'MyProcessViewer' })
const props = defineProps({
value: {
// BPMN XML
type: String,
default: ''
},
prefix: {
// 使
type: String,
default: 'camunda'
},
activityData: {
//
type: Array,
default: () => []
},
processInstanceData: {
//
type: Object,
default: () => {}
},
taskData: {
// UserTask
type: Array,
default: () => []
}
})
provide('configGlobal', props)
const emit = defineEmits(['destroy'])
let bpmnModeler
const xml = ref('')
const activityLists = ref<any[]>([])
const processInstance = ref<any>(undefined)
const taskList = ref<any[]>([])
const bpmnCanvas = ref()
// const element = ref()
const elementOverlayIds = ref<any>(null)
const overlays = ref<any>(null)
const initBpmnModeler = () => {
if (bpmnModeler) return
bpmnModeler = new BpmnViewer({
container: bpmnCanvas.value,
bpmnRenderer: {}
})
}
/* 创建新的流程图 */
const createNewDiagram = async (xml) => {
//
let newId = `Process_${new Date().getTime()}`
let newName = `业务流程_${new Date().getTime()}`
let xmlString = xml || DefaultEmptyXML(newId, newName, props.prefix)
try {
let { warnings } = await bpmnModeler.importXML(xmlString)
if (warnings && warnings.length) {
warnings.forEach((warn) => console.warn(warn))
}
//
await highlightDiagram()
const canvas = bpmnModeler.get('canvas')
canvas.zoom('fit-viewport', 'auto')
} catch (e) {
console.error(e)
// console.error(`[Process Designer Warn]: ${e?.message || e}`);
}
}
/* 高亮流程图 */
// TODO endActivity https://www.jdon.com/workflow/multi-events.html
const highlightDiagram = async () => {
const activityList = activityLists.value
if (activityList.length === 0) {
return
}
// https://gitee.com/tony2y/RuoYi-flowable/blob/master/ruoyi-ui/src/components/Process/index.vue#L222
//
let canvas = bpmnModeler.get('canvas')
let todoActivity: any = activityList.find((m: any) => !m.endTime) //
let endActivity: any = activityList[activityList.length - 1] //
let findProcessTask = false //
// key taskList Hover
let removeTaskDefinitionKeyList = []
// debugger
bpmnModeler.getDefinitions().rootElements[0].flowElements?.forEach((n: any) => {
let activity: any = activityList.find((m: any) => m.key === n.id) //
if (!activity) {
return
}
if (n.$type === 'bpmn:UserTask') {
//
//
const task: any = taskList.value.find((m: any) => m.id === activity.taskId) // taskId
if (!task) {
return
}
//
if (findProcessTask) {
removeTaskDefinitionKeyList.push(n.id)
return
}
//
canvas.addMarker(n.id, getResultCss(task.status))
//
if (task.status === 1) {
findProcessTask = true
}
// 线
if (task.status !== 2) {
return
}
// outgoing 线
const outgoing = getActivityOutgoing(activity)
outgoing?.forEach((nn: any) => {
// debugger
let targetActivity: any = activityList.find((m: any) => m.key === nn.targetRef.id)
// bpmn:SequenceFlow线
if (targetActivity) {
canvas.addMarker(nn.id, targetActivity.endTime ? 'highlight' : 'highlight-todo')
} else if (nn.targetRef.$type === 'bpmn:ExclusiveGateway') {
// TODO
canvas.addMarker(nn.id, activity.endTime ? 'highlight' : 'highlight-todo')
canvas.addMarker(nn.targetRef.id, activity.endTime ? 'highlight' : 'highlight-todo')
} else if (nn.targetRef.$type === 'bpmn:EndEvent') {
// TODO
if (!todoActivity && endActivity.key === n.id) {
canvas.addMarker(nn.id, 'highlight')
canvas.addMarker(nn.targetRef.id, 'highlight')
}
if (!activity.endTime) {
canvas.addMarker(nn.id, 'highlight-todo')
canvas.addMarker(nn.targetRef.id, 'highlight-todo')
}
}
})
} else if (n.$type === 'bpmn:ExclusiveGateway') {
//
// bpmn:ExclusiveGateway
canvas.addMarker(n.id, getActivityHighlightCss(activity))
// 线
let matchNN: any = undefined
let matchActivity: any = undefined
n.outgoing?.forEach((nn: any) => {
let targetActivity = activityList.find((m: any) => m.key === nn.targetRef.id)
if (!targetActivity) {
return
}
// endEvent ExclusiveGateway 2
// 1. UserTask => EndEvent
// 2. EndEvent
// 1 EndEvent 1 2
// matchActivity EndEvent ~~
if (!matchActivity || matchActivity.type === 'endEvent') {
matchNN = nn
matchActivity = targetActivity
}
})
if (matchNN && matchActivity) {
canvas.addMarker(matchNN.id, getActivityHighlightCss(matchActivity))
}
} else if (n.$type === 'bpmn:ParallelGateway') {
//
// bpmn:ParallelGateway
canvas.addMarker(n.id, getActivityHighlightCss(activity))
n.outgoing?.forEach((nn: any) => {
// 线
const targetActivity = activityList.find((m: any) => m.key === nn.targetRef.id)
if (targetActivity) {
canvas.addMarker(nn.id, getActivityHighlightCss(targetActivity)) // bpmn:SequenceFlow线
// ... ... bpm:UserTask bpm:UserTask
canvas.addMarker(nn.targetRef.id, getActivityHighlightCss(targetActivity))
}
})
} else if (n.$type === 'bpmn:StartEvent') {
//
canvas.addMarker(n.id, 'highlight')
n.outgoing?.forEach((nn) => {
// outgoing bpmn:SequenceFlow线
// 线
let targetActivity = activityList.find((m: any) => m.key === nn.targetRef.id)
if (targetActivity) {
canvas.addMarker(nn.id, 'highlight') // bpmn:SequenceFlow线
canvas.addMarker(n.id, 'highlight') // bpmn:StartEvent
}
})
} else if (n.$type === 'bpmn:EndEvent') {
//
if (!processInstance.value || processInstance.value.status === 1) {
return
}
canvas.addMarker(n.id, getResultCss(processInstance.value.status))
} else if (n.$type === 'bpmn:ServiceTask') {
//
if (activity.startTime > 0 && activity.endTime === 0) {
//
canvas.addMarker(n.id, getResultCss(1))
}
if (activity.endTime > 0) {
// , outgoing
canvas.addMarker(n.id, getResultCss(2))
const outgoing = getActivityOutgoing(activity)
outgoing?.forEach((out) => {
canvas.addMarker(out.id, getResultCss(2))
})
}
} else if (n.$type === 'bpmn:SequenceFlow') {
let targetActivity = activityList.find((m: any) => m.key === n.targetRef.id)
if (targetActivity) {
canvas.addMarker(n.id, getActivityHighlightCss(targetActivity))
}
}
})
if (!isEmpty(removeTaskDefinitionKeyList)) {
taskList.value = taskList.value.filter(
(item) => !removeTaskDefinitionKeyList.includes(item.taskDefinitionKey)
)
}
}
const getActivityHighlightCss = (activity) => {
return activity.endTime ? 'highlight' : 'highlight-todo'
}
const getResultCss = (status) => {
if (status === 1) {
//
return 'highlight-todo'
} else if (status === 2) {
//
return 'highlight'
} else if (status === 3) {
//
return 'highlight-reject'
} else if (status === 4) {
//
return 'highlight-cancel'
} else if (status === 5) {
// 退
return 'highlight-return'
} else if (status === 6) {
//
return 'highlight-todo'
} else if (status === 7) {
//
return 'highlight-todo'
} else if (status === 0) {
//
return 'highlight-todo'
}
return ''
}
const getActivityOutgoing = (activity) => {
// outgoing使
if (activity.outgoing && activity.outgoing.length > 0) {
return activity.outgoing
}
// bpmn:SequenceFlowbpmn-js UserTask outgoing
const flowElements = bpmnModeler.getDefinitions().rootElements[0].flowElements
const outgoing: any[] = []
flowElements.forEach((item: any) => {
if (item.$type !== 'bpmn:SequenceFlow') {
return
}
if (item.sourceRef.id === activity.key) {
outgoing.push(item)
}
})
return outgoing
}
const initModelListeners = () => {
const EventBus = bpmnModeler.get('eventBus')
//
EventBus.on('element.hover', function (eventObj) {
let element = eventObj ? eventObj.element : null
elementHover(element)
})
EventBus.on('element.out', function (eventObj) {
let element = eventObj ? eventObj.element : null
elementOut(element)
})
}
// hover
const elementHover = (element) => {
element.value = element
!elementOverlayIds.value && (elementOverlayIds.value = {})
!overlays.value && (overlays.value = bpmnModeler.get('overlays'))
//
// console.log(activityLists.value, 'activityLists.value')
// console.log(element.value, 'element.value')
const activity = activityLists.value.find((m) => m.key === element.value.id)
// console.log(activity, 'activityactivityactivityactivity')
if (!activity) {
return
}
if (!elementOverlayIds.value[element.value.id] && element.value.type !== 'bpmn:Process') {
let html = `<div class="element-overlays">
<p>Elemet id: ${element.value.id}</p>
<p>Elemet type: ${element.value.type}</p>
</div>` // 默认值
if (element.value.type === 'bpmn:StartEvent' && processInstance.value) {
html = `<p>发起人:${processInstance.value.startUser.nickname}</p>
<p>部门${processInstance.value.startUser.deptName}</p>
<p>创建时间${formatDate(processInstance.value.createTime)}`
} else if (element.value.type === 'bpmn:UserTask') {
let task = taskList.value.find((m) => m.id === activity.taskId) // taskId
if (!task) {
return
}
let optionData = getIntDictOptions(DICT_TYPE.BPM_TASK_STATUS)
let dataResult = ''
optionData.forEach((element) => {
if (element.value == task.status) {
dataResult = element.label
}
})
html = `<p>审批人:${task.assigneeUser.nickname}</p>
<p>部门${task.assigneeUser.deptName}</p>
<p>结果${dataResult}</p>
<p>创建时间${formatDate(task.createTime)}</p>`
// html = `<p>${task.assigneeUser.nickname}</p>
// <p>${task.assigneeUser.deptName}</p>
// <p>${getIntDictOptions(
// DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT,
// task.status
// )}</p>
// <p>${formatDate(task.createTime)}</p>`
if (task.endTime) {
html += `<p>结束时间:${formatDate(task.endTime)}</p>`
}
if (task.reason) {
html += `<p>审批建议:${task.reason}</p>`
}
} else if (element.value.type === 'bpmn:ServiceTask' && processInstance.value) {
if (activity.startTime > 0) {
html = `<p>创建时间:${formatDate(activity.startTime)}</p>`
}
if (activity.endTime > 0) {
html += `<p>结束时间:${formatDate(activity.endTime)}</p>`
}
console.log(html)
} else if (element.value.type === 'bpmn:EndEvent' && processInstance.value) {
let optionData = getIntDictOptions(DICT_TYPE.BPM_TASK_STATUS)
let dataResult = ''
optionData.forEach((element) => {
if (element.value == processInstance.value.status) {
dataResult = element.label
}
})
html = `<p>结果:${dataResult}</p>`
// html = `<p>${getIntDictOptions(
// DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT,
// processInstance.value.status
// )}</p>`
if (processInstance.value.endTime) {
html += `<p>结束时间:${formatDate(processInstance.value.endTime)}</p>`
}
}
// console.log(html, 'html111111111111111')
elementOverlayIds.value[element.value.id] = toRaw(overlays.value)?.add(element.value, {
position: { left: 0, bottom: 0 },
html: `<div class="element-overlays">${html}</div>`
})
}
}
// out
const elementOut = (element) => {
toRaw(overlays.value).remove({ element })
elementOverlayIds.value[element.id] = null
}
onMounted(() => {
xml.value = props.value
activityLists.value = props.activityData
//
initBpmnModeler()
createNewDiagram(xml.value)
//
initModelListeners()
})
onBeforeUnmount(() => {
// this.$once('hook:beforeDestroy', () => {
// })
if (bpmnModeler) bpmnModeler.destroy()
emit('destroy', bpmnModeler)
bpmnModeler = null
})
watch(
() => props.value,
(newValue) => {
xml.value = newValue
createNewDiagram(xml.value)
}
)
watch(
() => props.activityData,
(newActivityData) => {
activityLists.value = newActivityData
createNewDiagram(xml.value)
}
)
watch(
() => props.processInstanceData,
(newProcessInstanceData) => {
processInstance.value = newProcessInstanceData
createNewDiagram(xml.value)
}
)
watch(
() => props.taskData,
(newTaskListData) => {
taskList.value = newTaskListData
createNewDiagram(xml.value)
}
)
</script>
<style lang="scss">
/** 处理中 */
.highlight-todo.djs-connection > .djs-visual > path {
stroke: #1890ff !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
.highlight-todo.djs-shape .djs-visual > :nth-child(1) {
fill: #1890ff !important;
stroke: #1890ff !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
:deep(.highlight-todo.djs-connection > .djs-visual > path) {
stroke: #1890ff !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
marker-end: url('#sequenceflow-end-_E7DFDF-_E7DFDF-803g1kf6zwzmcig1y2ulm5egr');
}
:deep(.highlight-todo.djs-shape .djs-visual > :nth-child(1)) {
fill: #1890ff !important;
stroke: #1890ff !important;
stroke-dasharray: 4px !important;
fill-opacity: 0.2 !important;
}
/** 通过 */
.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:not(.djs-connection) .djs-visual > :nth-child(1) {
fill: green !important; /* color elements as green */
}
:deep(.highlight.djs-shape .djs-visual > :nth-child(1)) {
fill: green !important;
stroke: green !important;
fill-opacity: 0.2 !important;
}
:deep(.highlight.djs-shape .djs-visual > :nth-child(2)) {
fill: green !important;
}
:deep(.highlight.djs-shape .djs-visual > path) {
fill: green !important;
fill-opacity: 0.2 !important;
stroke: green !important;
}
:deep(.highlight.djs-connection > .djs-visual > path) {
stroke: green !important;
}
.djs-element.highlight > .djs-visual > path {
stroke: green !important;
}
/** 不通过 */
.highlight-reject.djs-shape .djs-visual > :nth-child(1) {
fill: red !important;
stroke: red !important;
fill-opacity: 0.2 !important;
}
.highlight-reject.djs-shape .djs-visual > :nth-child(2) {
fill: red !important;
}
.highlight-reject.djs-shape .djs-visual > path {
fill: red !important;
fill-opacity: 0.2 !important;
stroke: red !important;
}
.highlight-reject.djs-connection > .djs-visual > path {
stroke: red !important;
marker-end: url(#sequenceflow-end-white-success) !important;
}
.highlight-reject:not(.djs-connection) .djs-visual > :nth-child(1) {
fill: red !important; /* color elements as green */
}
:deep(.highlight-reject.djs-shape .djs-visual > :nth-child(1)) {
fill: red !important;
stroke: red !important;
fill-opacity: 0.2 !important;
}
:deep(.highlight-reject.djs-shape .djs-visual > :nth-child(2)) {
fill: red !important;
}
:deep(.highlight-reject.djs-shape .djs-visual > path) {
fill: red !important;
fill-opacity: 0.2 !important;
stroke: red !important;
}
:deep(.highlight-reject.djs-connection > .djs-visual > path) {
stroke: red !important;
}
/** 已取消 */
.highlight-cancel.djs-shape .djs-visual > :nth-child(1) {
fill: grey !important;
stroke: grey !important;
fill-opacity: 0.2 !important;
}
.highlight-cancel.djs-shape .djs-visual > :nth-child(2) {
fill: grey !important;
}
.highlight-cancel.djs-shape .djs-visual > path {
fill: grey !important;
fill-opacity: 0.2 !important;
stroke: grey !important;
}
.highlight-cancel.djs-connection > .djs-visual > path {
stroke: grey !important;
}
.highlight-cancel:not(.djs-connection) .djs-visual > :nth-child(1) {
fill: grey !important; /* color elements as green */
}
:deep(.highlight-cancel.djs-shape .djs-visual > :nth-child(1)) {
fill: grey !important;
stroke: grey !important;
fill-opacity: 0.2 !important;
}
:deep(.highlight-cancel.djs-shape .djs-visual > :nth-child(2)) {
fill: grey !important;
}
:deep(.highlight-cancel.djs-shape .djs-visual > path) {
fill: grey !important;
fill-opacity: 0.2 !important;
stroke: grey !important;
}
:deep(.highlight-cancel.djs-connection > .djs-visual > path) {
stroke: grey !important;
}
/** 回退 */
.highlight-return.djs-shape .djs-visual > :nth-child(1) {
fill: #e6a23c !important;
stroke: #e6a23c !important;
fill-opacity: 0.2 !important;
}
.highlight-return.djs-shape .djs-visual > :nth-child(2) {
fill: #e6a23c !important;
}
.highlight-return.djs-shape .djs-visual > path {
fill: #e6a23c !important;
fill-opacity: 0.2 !important;
stroke: #e6a23c !important;
}
.highlight-return.djs-connection > .djs-visual > path {
stroke: #e6a23c !important;
}
.highlight-return:not(.djs-connection) .djs-visual > :nth-child(1) {
fill: #e6a23c !important; /* color elements as green */
}
:deep(.highlight-return.djs-shape .djs-visual > :nth-child(1)) {
fill: #e6a23c !important;
stroke: #e6a23c !important;
fill-opacity: 0.2 !important;
}
:deep(.highlight-return.djs-shape .djs-visual > :nth-child(2)) {
fill: #e6a23c !important;
}
:deep(.highlight-return.djs-shape .djs-visual > path) {
fill: #e6a23c !important;
fill-opacity: 0.2 !important;
stroke: #e6a23c !important;
}
:deep(.highlight-return.djs-connection > .djs-visual > path) {
stroke: #e6a23c !important;
}
.element-overlays {
width: 200px;
padding: 8px;
color: #fafafa;
background: rgb(0 0 0 / 60%);
border-radius: 4px;
box-sizing: border-box;
}
</style>

View File

@ -1,6 +1,7 @@
import MyProcessDesigner from './designer'
import MyProcessPenal from './penal'
import MyProcessViewer from './designer/index2'
import MyProcessViewerForm from './designer/ProcessViewerForm.vue'
import './theme/index.scss'
import 'bpmn-js/dist/assets/diagram-js.css'
@ -8,4 +9,4 @@ import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
export { MyProcessDesigner, MyProcessPenal, MyProcessViewer }
export { MyProcessDesigner, MyProcessPenal, MyProcessViewer, MyProcessViewerForm }

View File

@ -102,12 +102,12 @@
</template>
<div class="form-scroll-area">
<ProcessInstanceBpmnViewer
v-show="
processDefinition.modelType && processDefinition.modelType === BpmModelType.BPMN
"
:loading="processInstanceLoading"
:model-view="processModelView"
<MyProcessViewerForm
key="designer"
v-model="bpmnXML"
:value="bpmnXML as any"
v-bind="bpmnControlForm"
:prefix="bpmnControlForm.prefix"
/>
</div>
</el-tab-pane>
@ -134,6 +134,8 @@ import ProcessInstanceSimpleViewer
import ProcessInstanceBpmnViewer
from "@/views/bpm/processInstance/detail/ProcessInstanceBpmnViewer.vue";
import * as ProcessInstanceApi from "@/api/bpm/processInstance";
import {MyProcessViewerForm} from "@/components/bpmnProcessDesigner/package";
import * as ModelApi from "@/api/bpm/model";
/** 请假管理 表单 */
defineOptions({ name: 'QjglCreate' })
@ -143,9 +145,19 @@ const { delView } = useTagsViewStore() // 视图操作
const { push, currentRoute } = useRouter() //
// const dialogVisible = ref(false) //
// const dialogTitle = ref('') //
const processDefinition = ref<any>({}) //
const processModelView = ref<any>({}) //
const processInstanceLoading = ref(false) //
/** 流程图的详情按钮操作 */
const bpmnDetailVisible = ref(false)
const bpmnXML = ref(null)
const bpmnControlForm = ref({
prefix: 'flowable'
})
const handleBpmnDetail = async (row) => {
const data = await ModelApi.getModel(row.id)
bpmnXML.value = data.bpmnXml || ''
bpmnDetailVisible.value = true
}
const formLoading = ref(false) // 12
const draftButton = ref(false)
@ -191,17 +203,7 @@ function formatDateHour(dat: number|Date) {
return date.getHours();
}
const getProcessModelView = async () => {
if (BpmModelType.BPMN === processDefinition.value?.modelType) {
// BPMN
processModelView.value = {
bpmnXml: ''
}
}
const data = await ProcessInstanceApi.getProcessInstanceBpmnModelView(processInstanceid)
if (data) {
processModelView.value = data
}
}
//
const queryParamsDate = reactive({
@ -476,7 +478,7 @@ console.log(processDefinitionDetail,"processDefinitionDetail")
//console.log(userList.value ,"userList.value")
}
await getNjglData()
await getProcessModelView()
await handleBpmnDetail()
})
</script>

View File

@ -65,7 +65,12 @@
</el-row>
<el-col :span="24">
<el-form-item label="文件路径" prop="filePath">
<UploadFile v-model="formData.filePath" :file-view="true"/>
<!-- <UploadFile v-model="formData.filePath" :file-view="true"/>-->
<UploadFile
v-model="formData.filePath"
:date="cmDate"
:file-view="true"
/>
</el-form-item>
</el-col>
@ -100,13 +105,21 @@ const formData = ref({
deptName: undefined,
title: undefined,
content: undefined,
createTime: 0,
status: undefined,
filePath: undefined,
filePath: [] as string[],
module: undefined
})
const formRules = reactive({
userName: [{ required: true, message: '作者不能为空', trigger: 'blur' }]
})
const nDate = ref()//
const cDate = ref()//
//
const cmDate = computed(() => {
return formData.value.createTime? cDate.value : nDate.value;
})
const formRef = ref() // Ref
const getUserInfo = async () => {
const users = await getUserProfile()
@ -123,19 +136,45 @@ console.log( users.dept.name )
formData.value.userName = users.nickname
}
}
const getNow = (date:number)=>{
const now = new Date(date);
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0'); // 0 +1
const day = String(now.getDate()).padStart(2, '0');
// console.log("getNow",`${year}-${month}-${day}`)
return `${year}-${month}-${day}`;
}
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
nDate.value = getNow(Date.now())//
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
await getUserInfo()
//
if (id) {
formLoading.value = true
try {
formData.value = await QuestionApi.getQuestion(id)
cDate.value = getNow(formData.value.createTime)//
//---------------------------
//
let pathLen = 0
if (formData.value.filePath && formData.value.filePath.length > 0) {
pathLen = formData.value.filePath.length;
}
if (pathLen === 1){
formData.value.filePath[0] = formData.value.filePath[0].substring(1)
formData.value.filePath[0] = formData.value.filePath[0].substring(0,formData.value.filePath[0].length-1)
}else if (pathLen >= 2){
formData.value.filePath[0] = formData.value.filePath[0].substring(1)
formData.value.filePath[pathLen-1] = formData.value.filePath[pathLen-1].substring(0,formData.value.filePath[pathLen-1].length-1)
}
} finally {
formLoading.value = false
}
@ -152,6 +191,12 @@ const submitForm = async () => {
formLoading.value = true
try {
const data = formData.value as unknown as QuestionVO
//
if (data.filePath &&data.filePath.length!==0){
//
data.filePath = data.filePath.map(path => path.trimStart());
}
if (formType.value === 'create') {
await QuestionApi.createQuestion(data)
message.success(t('common.createSuccess'))
@ -159,6 +204,7 @@ const submitForm = async () => {
await QuestionApi.updateQuestion(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')

View File

@ -172,9 +172,9 @@ const formData = ref({
fwglHqName: undefined,
createTime: 0,
fileStatus:undefined,
filePath: undefined,
filePath: [] as string[],
attachStatus: undefined,
attachPath: undefined,
attachPath: [] as string[],
deptId: undefined,
deptName: undefined,
processInstanceId: undefined,

View File

@ -68,7 +68,7 @@
</el-button>
</template>
</el-table-column>
<el-table-column label="流程名称2" align="center" prop="name" width="200">
<el-table-column label="流程名称3" align="center" prop="name" width="200">
<template #default="scope">
<el-button type="primary" link @click="handleBpmnDetail(scope.row)">
<span>{{ scope.row.name }}</span>
@ -224,7 +224,7 @@
<!-- 弹窗流程模型图的预览 -->
<Dialog title="流程图" v-model="bpmnDetailVisible" width="800">
<MyProcessViewer
<MyProcessViewerForm
key="designer"
v-model="bpmnXML"
:value="bpmnXML as any"
@ -236,7 +236,7 @@
<script lang="ts" setup>
import { dateFormatter, formatDate } from '@/utils/formatTime'
import { MyProcessViewer } from '@/components/bpmnProcessDesigner/package'
import { MyProcessViewerForm } from '@/components/bpmnProcessDesigner/package'
import * as ModelApi from '@/api/bpm/model'
import * as FormApi from '@/api/bpm/form'
import ModelForm from './ModelForm.vue'
@ -412,7 +412,7 @@ const bpmnControlForm = ref({
})
const handleBpmnDetail = async (row) => {
const data = await ModelApi.getModel(row.id)
console.log(data,"data-----")
bpmnXML.value = data.bpmnXml || ''
bpmnDetailVisible.value = true
}