13 changed files with 564 additions and 178 deletions
@ -0,0 +1,118 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<BasicTable @register="registerTable"> |
||||||
|
<template #bodyCell="{ column, record }"> |
||||||
|
<template v-if="column.key === 'action'"> |
||||||
|
<TableAction :actions="[ |
||||||
|
{ |
||||||
|
label: '办理', |
||||||
|
icon: 'fa6-regular:pen-to-square', |
||||||
|
onClick: handleTodo.bind(null, record) |
||||||
|
}, |
||||||
|
{ |
||||||
|
label: '进度', |
||||||
|
icon: 'fa6-solid:bars-progress', |
||||||
|
onClick: handleTrace.bind(null, record) |
||||||
|
}]" |
||||||
|
/> |
||||||
|
</template> |
||||||
|
</template> |
||||||
|
</BasicTable> |
||||||
|
<WorkflowChartModal @register="registerModal"/> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script lang="ts"> |
||||||
|
/** |
||||||
|
* 提供模板规范代码参考,请尽量保证编写代码风格跟模板规范代码一致 |
||||||
|
* 采用vben-动态表格表单封装组件编写,不采用 setup 写法 |
||||||
|
* Copyright © 2023-2023 <a href="https://godolphinx.org">海豚生态开源社区</a> All rights reserved. |
||||||
|
* author wangxiang4 |
||||||
|
*/ |
||||||
|
import { defineComponent } from 'vue'; |
||||||
|
import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
||||||
|
import { useModal } from '/@/components/Modal'; |
||||||
|
import { columns, searchFormSchema } from './task.data'; |
||||||
|
import { listTodoTask, getTaskDefinition } from '/@/api/platform/workflow/controller/task'; |
||||||
|
import { PageEnum } from '/@/enums/workflowEnum'; |
||||||
|
import { useRouter } from 'vue-router'; |
||||||
|
import WorkflowChartModal from './popups/WorkflowChartModal.vue'; |
||||||
|
|
||||||
|
export default defineComponent({ |
||||||
|
name: 'WorkflowTodoTask', |
||||||
|
components: { |
||||||
|
WorkflowChartModal, |
||||||
|
BasicTable, |
||||||
|
TableAction, |
||||||
|
}, |
||||||
|
setup() { |
||||||
|
const [registerModal, { openModal }] = useModal(); |
||||||
|
const { push } = useRouter(); |
||||||
|
const [registerTable] = useTable({ |
||||||
|
api: listTodoTask, |
||||||
|
rowKey: 'id', |
||||||
|
columns, |
||||||
|
formConfig: { |
||||||
|
compact: true, |
||||||
|
labelWidth: 100, |
||||||
|
schemas: searchFormSchema, |
||||||
|
autoSubmitOnEnter: true, |
||||||
|
showAdvancedButton: true, |
||||||
|
autoAdvancedLine: 3, |
||||||
|
fieldMapToTime: [['dateRange', ['beginTime', 'endTime'], 'YYYY-MM-DD']] |
||||||
|
}, |
||||||
|
useSearchForm: true, |
||||||
|
showTableSetting: true, |
||||||
|
bordered: true, |
||||||
|
clickToRowSelect: false, |
||||||
|
showIndexColumn: false, |
||||||
|
actionColumn: { |
||||||
|
width: 240, |
||||||
|
title: '操作', |
||||||
|
dataIndex: 'action', |
||||||
|
fixed: false |
||||||
|
}, |
||||||
|
}); |
||||||
|
|
||||||
|
async function handleTodo(record: Recordable) { |
||||||
|
const { taskInfo, vars } = record; |
||||||
|
const task = await getTaskDefinition({ |
||||||
|
taskId: taskInfo.id, |
||||||
|
taskName: taskInfo.name, |
||||||
|
taskDefKey: taskInfo.taskDefKey, |
||||||
|
processInsId: taskInfo.processInsId, |
||||||
|
processDefId: taskInfo.processDefId, |
||||||
|
processDefKey: taskInfo.processDefKey |
||||||
|
}); |
||||||
|
await push({ |
||||||
|
path: PageEnum.TASK_FORM_PAGE, |
||||||
|
query: { |
||||||
|
_meta: 'y', |
||||||
|
title: `审批【${taskInfo.name || ''}】`, |
||||||
|
formTitle: `${vars.title}`, |
||||||
|
formType: task.formType, |
||||||
|
formKey: task.formKey, |
||||||
|
formReadOnly: String(task.formReadOnly), |
||||||
|
processInsId: task.processInsId, |
||||||
|
processDefId: task.processDefId, |
||||||
|
processDefKey: task.processDefKey, |
||||||
|
taskId: task.taskId, |
||||||
|
taskDefKey: task.taskDefKey, |
||||||
|
businessId: task.businessId |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function handleTrace(record: Recordable) { |
||||||
|
openModal(true, { record: record.taskInfo }); |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
handleTodo, |
||||||
|
handleTrace, |
||||||
|
registerTable, |
||||||
|
registerModal, |
||||||
|
}; |
||||||
|
} |
||||||
|
}); |
||||||
|
</script> |
@ -0,0 +1,119 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<BasicTable @register="registerTable"> |
||||||
|
<template #bodyCell="{ column, record }"> |
||||||
|
<template v-if="column.key === 'action'"> |
||||||
|
<TableAction |
||||||
|
:actions="[ |
||||||
|
{ |
||||||
|
label: '办理', |
||||||
|
icon: 'fa6-regular:pen-to-square', |
||||||
|
onClick: handleTodo.bind(null, record) |
||||||
|
}, |
||||||
|
{ |
||||||
|
label: '进度', |
||||||
|
icon: 'fa6-solid:bars-progress', |
||||||
|
onClick: handleTrace.bind(null, record) |
||||||
|
}]" |
||||||
|
/> |
||||||
|
</template> |
||||||
|
</template> |
||||||
|
</BasicTable> |
||||||
|
<WorkflowChartModal @register="registerModal"/> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script lang="ts"> |
||||||
|
/** |
||||||
|
* 提供模板规范代码参考,请尽量保证编写代码风格跟模板规范代码一致 |
||||||
|
* 采用vben-动态表格表单封装组件编写,不采用 setup 写法 |
||||||
|
* Copyright © 2023-2023 <a href="https://godolphinx.org">海豚生态开源社区</a> All rights reserved. |
||||||
|
* author wangxiang4 |
||||||
|
*/ |
||||||
|
import { defineComponent } from 'vue'; |
||||||
|
import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
||||||
|
import { useModal } from '/@/components/Modal'; |
||||||
|
import { columns, searchFormSchema } from './task.data'; |
||||||
|
import { listTodoTask, getTaskDefinition } from '/@/api/platform/workflow/controller/task'; |
||||||
|
import { PageEnum } from '/@/enums/workflowEnum'; |
||||||
|
import { useRouter } from 'vue-router'; |
||||||
|
import WorkflowChartModal from './popups/WorkflowChartModal.vue'; |
||||||
|
|
||||||
|
export default defineComponent({ |
||||||
|
name: 'WorkflowTodoTask', |
||||||
|
components: { |
||||||
|
WorkflowChartModal, |
||||||
|
BasicTable, |
||||||
|
TableAction, |
||||||
|
}, |
||||||
|
setup() { |
||||||
|
const [registerModal, { openModal }] = useModal(); |
||||||
|
const { push } = useRouter(); |
||||||
|
const [registerTable] = useTable({ |
||||||
|
api: listTodoTask, |
||||||
|
rowKey: 'id', |
||||||
|
columns, |
||||||
|
formConfig: { |
||||||
|
compact: true, |
||||||
|
labelWidth: 100, |
||||||
|
schemas: searchFormSchema, |
||||||
|
autoSubmitOnEnter: true, |
||||||
|
showAdvancedButton: true, |
||||||
|
autoAdvancedLine: 3, |
||||||
|
fieldMapToTime: [['dateRange', ['beginTime', 'endTime'], 'YYYY-MM-DD']] |
||||||
|
}, |
||||||
|
useSearchForm: true, |
||||||
|
showTableSetting: true, |
||||||
|
bordered: true, |
||||||
|
clickToRowSelect: false, |
||||||
|
showIndexColumn: false, |
||||||
|
actionColumn: { |
||||||
|
width: 240, |
||||||
|
title: '操作', |
||||||
|
dataIndex: 'action', |
||||||
|
fixed: false |
||||||
|
}, |
||||||
|
}); |
||||||
|
|
||||||
|
async function handleTodo(record: Recordable) { |
||||||
|
const { taskInfo, vars } = record; |
||||||
|
const task = await getTaskDefinition({ |
||||||
|
taskId: taskInfo.id, |
||||||
|
taskName: taskInfo.name, |
||||||
|
taskDefKey: taskInfo.taskDefKey, |
||||||
|
processInsId: taskInfo.processInsId, |
||||||
|
processDefId: taskInfo.processDefId, |
||||||
|
processDefKey: taskInfo.processDefKey |
||||||
|
}); |
||||||
|
await push({ |
||||||
|
path: PageEnum.TASK_FORM_PAGE, |
||||||
|
query: { |
||||||
|
_meta: 'y', |
||||||
|
title: `审批【${taskInfo.name || ''}】`, |
||||||
|
formTitle: `${vars.title}`, |
||||||
|
formType: task.formType, |
||||||
|
formKey: task.formKey, |
||||||
|
formReadOnly: String(task.formReadOnly), |
||||||
|
processInsId: task.processInsId, |
||||||
|
processDefId: task.processDefId, |
||||||
|
processDefKey: task.processDefKey, |
||||||
|
taskId: task.taskId, |
||||||
|
taskDefKey: task.taskDefKey, |
||||||
|
businessId: task.businessId |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function handleTrace(record: Recordable) { |
||||||
|
openModal(true, { record: record.taskInfo }); |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
handleTodo, |
||||||
|
handleTrace, |
||||||
|
registerTable, |
||||||
|
registerModal, |
||||||
|
}; |
||||||
|
} |
||||||
|
}); |
||||||
|
</script> |
@ -0,0 +1,88 @@ |
|||||||
|
<template> |
||||||
|
<BasicModal |
||||||
|
v-bind="$attrs" |
||||||
|
defaultFullscreen |
||||||
|
:canFullscreen="false" |
||||||
|
:showCancelBtn="false" |
||||||
|
:showOkBtn="false" |
||||||
|
@register="registerModal" |
||||||
|
@visible-change="handleVisibleChange" |
||||||
|
> |
||||||
|
<div id="workflowChart"/> |
||||||
|
</BasicModal> |
||||||
|
</template> |
||||||
|
<script lang="ts" setup> |
||||||
|
import { reactive } from 'vue'; |
||||||
|
import { loadMicroApp, MicroApp } from 'qiankun'; |
||||||
|
import { getSubDefineProps } from '/@/qiankun/state'; |
||||||
|
import { GlStateEnum, WORKFLOW_DESIGN_APP_COMPONENTS } from '/@/enums/microAppEnum'; |
||||||
|
import { useMicroAppStore } from '/@/store/modules/microApp'; |
||||||
|
import { apps } from '/@/qiankun/apps'; |
||||||
|
import { getFlowChart as getProcessDefFlowChart } from '/@/api/platform/workflow/controller/process'; |
||||||
|
import { getFlowChart as getProcessInsFlowChart } from '/@/api/platform/workflow/controller/task'; |
||||||
|
import { BasicModal, ModalProps, useModalInner } from '/@/components/Modal'; |
||||||
|
import { useMessage } from '/@/hooks/web/useMessage'; |
||||||
|
|
||||||
|
interface WindowState { |
||||||
|
workflowDesignApp: MicroApp; |
||||||
|
bpmnData: Recordable; |
||||||
|
} |
||||||
|
|
||||||
|
const state = reactive<WindowState>({ |
||||||
|
workflowDesignApp: undefined!, |
||||||
|
bpmnData: {}, |
||||||
|
}); |
||||||
|
|
||||||
|
const workflowDesignProps = { |
||||||
|
style: { 'min-height': '100vh' }, |
||||||
|
}; |
||||||
|
const emit = defineEmits(['register']); |
||||||
|
const microAppStore = useMicroAppStore(); |
||||||
|
const { createMessage } = useMessage(); |
||||||
|
const [registerModal, { setModalProps, closeModal, changeLoading }] = useModalInner(async (data: BoxPayload = { _tag: '' }) => { |
||||||
|
const props: Partial<ModalProps> = { title: '查看进度' }; |
||||||
|
const { processInsId, processDefId } = data.record || {}; |
||||||
|
if (processInsId || processDefId) { |
||||||
|
changeLoading(); |
||||||
|
try { |
||||||
|
if (processInsId) { |
||||||
|
state.bpmnData = await getProcessInsFlowChart(processInsId); |
||||||
|
} else { |
||||||
|
const bpmnXml = await getProcessDefFlowChart(processDefId); |
||||||
|
state.bpmnData = { bpmnXml }; |
||||||
|
} |
||||||
|
state.workflowDesignApp = loadMicroApp(Object.assign({} , apps.find(item => item.name == 'workflow-design'), { |
||||||
|
container: '#workflowChart', |
||||||
|
props: { |
||||||
|
...getSubDefineProps(), |
||||||
|
mountApp: WORKFLOW_DESIGN_APP_COMPONENTS.CHART, |
||||||
|
[GlStateEnum.WORKFLOW_DESIGN_APP_PROPS_KEY]: workflowDesignProps |
||||||
|
} |
||||||
|
}), { sandbox: { experimentalStyleIsolation: true }}); |
||||||
|
state.workflowDesignApp.mountPromise.then(() => { |
||||||
|
const workflowChartApp: Recordable = microAppStore.getWorkflowDesignApp(WORKFLOW_DESIGN_APP_COMPONENTS.CHART), |
||||||
|
workflowRef: Recordable = workflowChartApp.getRef().$refs['workflow-chart']; |
||||||
|
workflowRef.setHighlightImportDiagram(state.bpmnData); |
||||||
|
changeLoading(false); |
||||||
|
}); |
||||||
|
} catch(e: any) { |
||||||
|
createMessage.error(e); |
||||||
|
changeLoading(false); |
||||||
|
} |
||||||
|
} else createMessage.error('无法打开流程图,没有关联流程图ID!'); |
||||||
|
setModalProps(props); |
||||||
|
}); |
||||||
|
|
||||||
|
function handleVisibleChange(visible: boolean) { |
||||||
|
!visible && state.workflowDesignApp?.unmount(); |
||||||
|
} |
||||||
|
|
||||||
|
</script> |
||||||
|
<style lang="less"> |
||||||
|
.ant-modal { |
||||||
|
.ant-modal-body > .scrollbar { |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
@ -0,0 +1,58 @@ |
|||||||
|
import { BasicColumn, FormSchema } from '/@/components/Table'; |
||||||
|
import { h } from 'vue'; |
||||||
|
import { Tag } from 'ant-design-vue'; |
||||||
|
|
||||||
|
export const columns: BasicColumn[] = [ |
||||||
|
{ |
||||||
|
title: '流程标题', |
||||||
|
dataIndex: ['vars', 'title'], |
||||||
|
width: 200, |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: '流程名称', |
||||||
|
dataIndex: 'processDefName', |
||||||
|
width: 200, |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: '当前环节', |
||||||
|
dataIndex: ['taskInfo', 'name'], |
||||||
|
width: 150, |
||||||
|
customRender: ({ record }) => { |
||||||
|
const taskName = record.taskInfo?.name; |
||||||
|
return h(Tag, { color: 'processing' }, () => taskName); |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: '流程发起人', |
||||||
|
dataIndex: ['vars', 'userName'], |
||||||
|
width: 150 |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: '创建时间', |
||||||
|
dataIndex: ['taskInfo', 'createTime'], |
||||||
|
width: 200 |
||||||
|
} |
||||||
|
]; |
||||||
|
|
||||||
|
export const searchFormSchema: FormSchema[] = [ |
||||||
|
{ |
||||||
|
field: 'title', |
||||||
|
label: '流程标题', |
||||||
|
component: 'Input', |
||||||
|
componentProps: { |
||||||
|
placeholder: '请输入流程标题', |
||||||
|
}, |
||||||
|
colProps: { span: 8 } |
||||||
|
}, |
||||||
|
{ |
||||||
|
field: 'dateRange', |
||||||
|
label: '创建时间', |
||||||
|
component: 'RangePicker', |
||||||
|
componentProps: { |
||||||
|
style: { width:'100%' }, |
||||||
|
valueFormat: 'YYYY-MM-DD', |
||||||
|
placeholder: ['开始日期','结束日期'] |
||||||
|
}, |
||||||
|
colProps: { span: 8 } |
||||||
|
} |
||||||
|
]; |
Loading…
Reference in new issue