提交 c90615cf authored 作者: kxjia's avatar kxjia

工作流添加了 多实例,修改了扩展属性

上级 e2396e12
......@@ -320,6 +320,21 @@
"isAttr": true,
"type": "Boolean"
},
{
"name": "isTransmit",
"isAttr": true,
"type": "Boolean"
},
{
"name": "isReject",
"isAttr": true,
"type": "Boolean"
},
{
"name": "isSend",
"isAttr": true,
"type": "Boolean"
},
{
"name": "followUpDate",
"isAttr": true,
......
......@@ -24,6 +24,17 @@
</template>
<user-task-panel :id="elementId" />
</a-tab-pane>
<!-- 多实例配置 -->
<a-tab-pane
v-if="elementType.indexOf('Task') !== -1"
key="multiInstance"
tab="多实例"
>
<template #tab>
<span><block-outlined /> 多实例</span>
</template>
<multi-instance-panel :id="elementId" />
</a-tab-pane>
<!-- 表单 -->
<a-tab-pane
......@@ -69,7 +80,9 @@ import { ref, watch, onMounted, onUnmounted, computed } from 'vue'
import {
InfoCircleOutlined,
ContainerOutlined,
FormOutlined
FormOutlined,
TeamOutlined,
BlockOutlined
} from '@ant-design/icons-vue'
import CommonPanel from './panel/commonPanel.vue'
......@@ -77,6 +90,8 @@ import PropertiesPanel from './panel/PropertiesPanel.vue'
import UserTaskPanel from './panel/taskPanel.vue'
import FormPanel from './panel/formPanel.vue'
import ConditionPanel from './panel/conditionPanel.vue'
import CandidateGroupPanel from './panel/candidateGroupPanel.vue'
import MultiInstancePanel from './panel/multiInstance.vue'
import { translateNodeName } from "./common/bpmnUtils"
import { useModelerStore } from './store/modeler-store.js'
......@@ -138,30 +153,27 @@ const getActiveElement = () => {
}
const initFormOnChanged = (element: any) => {
let activatedElement = element
if (!activatedElement && modelerStore.elRegistry) {
activatedElement = modelerStore.elRegistry.find((el: any) => el.type === "bpmn:Process") ??
modelerStore.elRegistry.find((el: any) => el.type === "bpmn:Collaboration")
}
if (!activatedElement) {
console.log('[designer] initFormOnChanged:', element?.id, element?.type)
if (!element) {
elementId.value = ""
elementType.value = ""
formVisible.value = false
return
}
modelerStore.setElement(activatedElement)
elementId.value = activatedElement.id
elementType.value = activatedElement.type.split(":")[1] || ""
// Process 或 Collaboration 不设置 elementId,但保留之前的值
if (element.type === 'bpmn:Process' || element.type === 'bpmn:Collaboration') {
return
}
modelerStore.setElement(element)
elementId.value = element.id
elementType.value = element.type.split(":")[1] || ""
// 表单配置只对特定元素可见
formVisible.value = elementType.value === "UserTask" || elementType.value === "StartEvent"
console.log('当前选中元素:', {
id: elementId.value,
type: elementType.value,
element: activatedElement
})
console.log('[designer] elementId:', elementId.value, 'elementType:', elementType.value)
}
</script>
......
<template>
<div class="panel-tab__content">
<a-form layout="vertical" @submit.prevent size="small">
<a-form-item label="人员模式">
<a-select v-model:value="assignMode" @change="changeAssignMode">
<a-select-option value="direct">指定人员</a-select-option>
<a-select-option value="candidate">候选人员(抢单模式)</a-select-option>
</a-select>
</a-form-item>
<template v-if="assignMode === 'candidate'">
<a-form-item label="候选人员">
<a-select
v-model:value="candidateUsers"
mode="multiple"
placeholder="请选择候选人员"
:disabled="readonly"
:options="userOptions"
@change="updateCandidateUsers"
/>
</a-form-item>
<a-form-item label="候选角色">
<a-select
v-model:value="candidateRoles"
mode="multiple"
placeholder="请选择候选角色"
:disabled="readonly"
:options="roleOptions"
@change="updateCandidateRoles"
/>
</a-form-item>
</template>
<template v-else>
<a-form-item label="指定人员">
<a-select
v-model:value="directAssignee"
placeholder="请选择指定人员"
:disabled="readonly"
show-search
:options="userOptions"
@change="updateDirectAssignee"
/>
</a-form-item>
</template>
</a-form>
</div>
</template>
<script lang="ts" setup>
import { ref, watch, computed, nextTick } from 'vue'
import { StrUtil } from '../common/StrUtil'
import { useModelerStore } from '../store/modeler-store.js'
import { defHttp } from '/@/utils/http/axios'
const props = defineProps<{
id: string
readonly?: boolean
}>()
const modelerStore = useModelerStore()
const currentElement = computed(() => modelerStore.element)
const assignMode = ref('direct')
const candidateUsers = ref<string[]>([])
const candidateRoles = ref<string[]>([])
const directAssignee = ref<string>('')
const userOptions = ref<{label: string, value: string}[]>([])
const roleOptions = ref<{label: string, value: string}[]>([])
watch(() => props.id, (newVal) => {
if (StrUtil.isNotBlank(newVal) && currentElement.value) {
nextTick(() => loadElementData())
}
}, { immediate: true })
watch(() => currentElement.value, () => {
if (props.id) {
loadElementData()
}
}, { deep: true })
const loadUsers = async () => {
try {
const result = await defHttp.get({ url: '/sys/user/list', params: { pageSize: 1000 } })
if (result?.records) {
userOptions.value = result.records.map((u: any) => ({ label: u.realname, value: u.id }))
}
} catch (error) {
console.error('加载用户列表失败:', error)
}
}
const loadRoles = async () => {
try {
const result = await defHttp.get({ url: '/sys/role/queryall' })
if (result) {
roleOptions.value = result.map((r: any) => ({ label: r.roleName, value: r.id }))
}
} catch (error) {
console.error('加载角色列表失败:', error)
}
}
loadUsers()
loadRoles()
const loadElementData = () => {
const el = currentElement.value
if (!el?.businessObject) return
const bo = el.businessObject
assignMode.value = (bo.candidateUsers || bo.candidateGroups) ? 'candidate' : 'direct'
candidateUsers.value = bo.candidateUsers ? bo.candidateUsers.split(',') : []
candidateRoles.value = bo.candidateGroups ? bo.candidateGroups.split(',') : []
directAssignee.value = bo.assignee || ''
}
const changeAssignMode = (mode: string) => {
if (mode === 'direct') {
candidateUsers.value = []
candidateRoles.value = []
updateElementProperty('candidateUsers', '')
updateElementProperty('candidateGroups', '')
}
}
const updateCandidateUsers = (values: string[]) => {
candidateUsers.value = values
updateElementProperty('candidateUsers', values.join(','))
}
const updateCandidateRoles = (values: string[]) => {
candidateRoles.value = values
updateElementProperty('candidateGroups', values.join(','))
}
const updateDirectAssignee = (value: string) => {
directAssignee.value = value
updateElementProperty('assignee', value)
}
const updateElementProperty = (key: string, value: string) => {
if (!modelerStore.modeler || !currentElement.value) return
try {
const modeling = modelerStore.modeler.get('modeling')
modeling.updateProperties(currentElement.value, { [key]: value || undefined })
} catch (error) {
console.error('更新属性失败:', error)
}
}
</script>
<style lang="scss">
.panel-tab__content {
.ant-select {
width: 100%;
}
}
</style>
\ No newline at end of file
<template>
<div class="panel-tab__content">
<a-form layout="vertical" @submit.prevent size="small">
<a-form layout="horizontal" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }" @submit.prevent size="small">
<a-form-item label="参数说明">
<a-button size="small" type="primary" @click="dialogVisible = true">查看</a-button>
</a-form-item>
......@@ -14,6 +14,13 @@
<a-select-option value="Null"></a-select-option>
</a-select>
</a-form-item>
<a-form-item label="多实例模式" v-if="loopCharacteristics !== 'Null' && loopCharacteristics !== 'StandardLoop'">
<a-radio-group v-model:value="multiInstanceMode" @change="changeMultiInstanceMode">
<a-radio value="counterSign">会签(全部完成)</a-radio>
<a-radio value="orSign">或签(任一完成)</a-radio>
<a-radio value="normal">普通</a-radio>
</a-radio-group>
</a-form-item>
<template v-if="loopCharacteristics === 'ParallelMultiInstance' || loopCharacteristics === 'SequentialMultiInstance'">
<a-form-item label="循环基数" key="loopCardinality">
<a-input v-model:value="loopInstanceForm.loopCardinality" allow-clear @change="updateLoopCardinality" />
......@@ -77,8 +84,9 @@
</template>
<script lang="ts" setup>
import { ref, watch, reactive } from 'vue'
import { ref, watch, reactive, nextTick, onMounted } from 'vue'
import { StrUtil } from '../common/StrUtil'
import { useModelerStore } from '../store/modeler-store.js'
interface LoopInstanceForm {
completionCondition?: string
......@@ -95,11 +103,15 @@ interface LoopInstanceForm {
const props = defineProps<{
id: string
readonly?: boolean
}>()
const modelerStore = useModelerStore()
// 响应式数据
const dialogVisible = ref(false)
const loopCharacteristics = ref("")
const multiInstanceMode = ref("normal")
const loopInstanceForm = reactive<LoopInstanceForm>({})
const multiLoopInstance = ref<any>(null)
......@@ -112,25 +124,25 @@ const defaultLoopInstanceForm: LoopInstanceForm = {
exclusive: false
}
// 假设这是从其他地方引入的 store
const modelerStore = {
element: {} as any,
modeling: {
updateProperties: (element: any, properties: any) => {},
updateModdleProperties: (element: any, property: any, values: any) => {}
},
moddle: {
create: (type: string, values: any) => ({})
}
}
// 监听 id 变化
watch(() => props.id, (newVal) => {
if (StrUtil.isNotBlank(newVal)) {
getElementLoop(modelerStore.element.businessObject)
console.log('[multiInstance] id changed:', newVal, 'store element:', modelerStore.element?.id)
if (StrUtil.isNotBlank(newVal) && modelerStore.element) {
nextTick(() => {
getElementLoop(modelerStore.element.businessObject)
})
}
}, { immediate: true })
onMounted(() => {
console.log('[multiInstance] mounted, id:', props.id, 'store element:', modelerStore.element?.id)
if (props.id && modelerStore.element) {
getElementLoop(modelerStore.element.businessObject)
}
})
// 获取元素循环配置
const getElementLoop = (businessObject: any) => {
if (!businessObject.loopCharacteristics) {
......@@ -159,6 +171,20 @@ const getElementLoop = (businessObject: any) => {
loopCardinality: businessObject.loopCharacteristics?.loopCardinality?.body ?? ""
})
// 读取多实例模式
if (businessObject.loopCharacteristics?.completionCondition) {
const condition = businessObject.loopCharacteristics.completionCondition?.body || ''
if (condition.includes('${nrOfCompletedInstances') && condition.includes('nrOfInstances')) {
multiInstanceMode.value = 'counterSign'
} else if (condition.includes('${nrOfActiveInstances') === 0) {
multiInstanceMode.value = 'orSign'
} else {
multiInstanceMode.value = 'normal'
}
} else {
multiInstanceMode.value = 'normal'
}
// 保留当前元素 businessObject 上的 loopCharacteristics 实例
multiLoopInstance.value = businessObject.loopCharacteristics
......@@ -207,6 +233,28 @@ const changeLoopCharacteristicsType = (type: string) => {
})
}
// 改变多实例模式
const changeMultiInstanceMode = (mode: string) => {
if (!multiLoopInstance.value) return
let condition = null
if (mode === 'counterSign') {
// 会签: 全部人完成才结束
condition = modelerStore.moddle.create("bpmn:FormalExpression", {
body: '${nrOfCompletedInstances >= nrOfInstances}'
})
} else if (mode === 'orSign') {
// 或签: 任一人完成就结束
condition = modelerStore.moddle.create("bpmn:FormalExpression", {
body: '${nrOfActiveInstances == 0}'
})
}
modelerStore.modeling.updateModdleProperties(modelerStore.element, multiLoopInstance.value, {
completionCondition: condition
})
}
// 循环基数
const updateLoopCardinality = (cardinality: string) => {
let loopCardinality = null
......
......@@ -48,10 +48,10 @@
const bpmnFormData = reactive<BpmnFormData>({
async: false,
userType: 'user',
isTransmit: true,
isReject: true,
isSend: true,
isRead: true,
isTransmit: undefined,
isReject: undefined,
isSend: undefined,
isRead: undefined,
});
const selectData = reactive<SelectData>({})
......@@ -252,14 +252,14 @@
label: '是否转阅',
field: 'isRead',
component: 'RadioGroup',
defaultValue: true,
componentProps: {
options: [
{ label: '是', value: true },
{ label: '否', value: false },
],
disabled: props.readonly,
onChange: (isRead: boolean) => {
onChange: (e) => {
const isRead = e.target.value
bpmnFormData.isRead = isRead
updateCustomElement("isRead", isRead)
emit('update', { isRead })
......@@ -270,14 +270,14 @@
label: '是否转办',
field: 'isTransmit',
component: 'RadioGroup',
defaultValue: true,
componentProps: {
options: [
{ label: '是', value: true },
{ label: '否', value: false },
],
disabled: props.readonly,
onChange: (isTransmit: boolean) => {
onChange: (e) => {
const isTransmit = e.target.value
bpmnFormData.isTransmit = isTransmit
updateCustomElement("isTransmit", isTransmit)
emit('update', { isTransmit })
......@@ -288,14 +288,14 @@
label: '是否可退',
field: 'isReject',
component: 'RadioGroup',
defaultValue: true,
componentProps: {
options: [
{ label: '是', value: true },
{ label: '否', value: false },
],
disabled: props.readonly,
onChange: (isReject: boolean) => {
onChange: (e) => {
const isReject = e.target.value
bpmnFormData.isReject = isReject
updateCustomElement("isReject", isReject)
emit('update', { isReject })
......@@ -306,14 +306,14 @@
label: '是否发送',
field: 'isSend',
component: 'RadioGroup',
defaultValue: true,
componentProps: {
options: [
{ label: '是', value: true },
{ label: '否', value: false },
],
disabled: props.readonly,
onChange: (isSend: boolean) => {
onChange: (e) => {
const isSend = e.target.value
bpmnFormData.isSend = isSend
updateCustomElement("isSend", isSend)
emit('update', { isSend })
......@@ -410,7 +410,7 @@
try {
// BPMN 标准属性列表(这些可以直接更新)
const standardProps = ['async', 'dueDate', 'priority', 'assignee', 'candidateGroups', 'userType']
const standardProps = ['async', 'dueDate', 'priority', 'assignee', 'candidateGroups', 'userType', 'isRead', 'isTransmit', 'isReject', 'isSend']
if (standardProps.includes(key)) {
// 标准属性直接更新
......@@ -441,16 +441,8 @@
return false
}
// 获取原始对象,避免 Vue 响应式代理问题
let targetElement = element
// 如果是 Vue 代理对象,获取原始对象
if (isProxy(element)) {
targetElement = toRaw(element)
}
// 执行更新
modeling.updateProperties(targetElement, properties)
modeling.updateProperties(element, properties)
return true
} catch (error) {
......@@ -477,11 +469,11 @@
candidateGroups: businessObject.candidateGroups || '',
dueDate: businessObject.dueDate || '',
priority: businessObject.priority || 'medium',
// 从自定义属性中读取
isRead: customProps.isRead !== undefined ? customProps.isRead : true,
isTransmit: customProps.isTransmit !== undefined ? customProps.isTransmit : true,
isReject: customProps.isReject !== undefined ? customProps.isReject : true,
isSend: customProps.isSend !== undefined ? customProps.isSend : true
// 从 BPMN 属性中读取
isRead: businessObject.isRead === true,
isTransmit: businessObject.isTransmit === true,
isReject: businessObject.isReject === true,
isSend: businessObject.isSend === true
}
isUser.value = formData.userType === "user"
......
<template>
<div>
<component :is="loadComponent(mainFormListUrl)"
:ref="(el) => setFormComponentRef(el, 1)"
:ref="(el) => setFormComponentRef(el, 0)"
@startWorkFlow="handleDefinitionStart"
@sendWorkFlow="handleDefinitionSend"
@endWorkFlow="handleDefinitionEnd"
@open-multi-form="handleOpenMultiForm"
@open-flow-form="handleOpenFlowForm"
:todo-list="todoList"
/>
<WorkFlowFormDrawer
......@@ -113,10 +114,13 @@
}
const handleDefinitionStart = async (data) => {
if (data.procInsId) {
return;
}
const formData = { dataId: data.id, dataName: 'id' };
const nodeDeployId = currentNode.value.deployId || '';
const startResRaw = await definitionStartByDeployId(nodeDeployId, formData);
if (startResRaw?.instanceId) {
procInsId.value = startResRaw.instanceId;
taskId.value = startResRaw.taskId;
......@@ -145,10 +149,10 @@
};
const handleDefinitionSend = async (data) => {
if(currentMultiFormIndex.value <=1){
if (!data.procInsId) {
await handleDefinitionStart(data)
}
}
dataId.value = data.id;
deployId.value = currentNode.value.deployId || '';
......@@ -263,7 +267,9 @@
nextTick(() => {
if(resData.formUrl) {
mainFormUrl.value = resData.formUrl
alert(mainFormUrl.value)
mainFormListUrl.value = resData.formListurl || ''
alert(mainFormListUrl.value)
} else {
mainFormUrl.value = ""
refInnerForm.value.iniData(resData)
......@@ -288,7 +294,6 @@
try {
const nodes = await getNodesByTableName(formTableName);
todoaLLList.value = await todoList(queryParams);
alert(JSON.stringify(todoaLLList.value))
workflowNodes.value = nodes;
if (workflowNodes.value?.length > 0) {
......
<template>
<a-drawer :title="drawerTitle" placement="right" width="100%" :visible="isVisible" @close="closeDrawer" style="margin: 10px;">
<template #extra>
<!-- <a-button type="primary" @click="saveDataAndClose" :disabled="!curTask||!curTpl" style="margin-right: 10px;">分配并关闭</a-button> -->
<a-button type="primary" @click="saveData" :disabled="!curTask||!curTpl" style="margin-right: 60px;">分配用户</a-button>
<a-button type="primary" @click="clearAllocUser" :disabled="!curTask||!curTpl" tyle="margin-right: 10px;">清除分配</a-button>
<a-button @click="closeDrawer" style="margin-left: 20px;">关闭</a-button>
</template>
<a-layout style="height:85vh">
<a-layout-sider width="500" :style="{ backgroundColor: '#fff', overflow: 'hidden',margin:'10px 0px 10px 10px' }">
<Tpl ref ="refTpl" @callback="callBackTpl"/>
</a-layout-sider>
<a-layout-content>
<div style="height:83vh;padding: 10px">
<a-row :gutter="10">
<a-col :span="12">
<a-card title="请选择任务项" :bordered="false" style="height:83vh;">
<TplItem ref="refTplItem"></TplItem>
</a-card>
</a-col>
<a-col :span="12">
<a-card title="请选择填写人" :bordered="false" style="height:83vh;">
<UserList ref="refUserList" @callback="userCallBack"></UserList>
</a-card>
</a-col>
</a-row>
</div>
</a-layout-content>
</a-layout>
</a-drawer>
</template>
<script lang="ts" setup>
import { ref, nextTick } from 'vue';
import Tpl from '../../components/Tpl.vue';
import TplItem from './TplItem.vue';
import UserList from './UserList.vue';
import { saveOrUpdateBatch } from '../../alloc/BaosongTaskAlloc.api';
const emit = defineEmits(['callback']);
const isVisible = ref(false)
const refTpl = ref()
const refTplItem = ref()
const refUserList = ref()
const drawerTitle= ref();
const curTask = ref()
const curTpl = ref()
function closeDrawer() {
isVisible.value = false
emit("callback")
}
function setIniData(task) {
drawerTitle.value="任务分配【"+task.name+"】"
curTask.value = task
isVisible.value = true
nextTick(async () => {
await refTplItem.value.setCurTaskHaveAllocUser(task)
await refTpl.value.setData(task.tp);
await refUserList.value.setData()
});
}
function callBackTpl(Tpl) {
curTpl.value = Tpl;
refTplItem.value.setData(Tpl)
}
async function saveData() {
let allocObj = {taskid:curTask.value?.id};
allocObj["tplid"] = curTpl.value?.id;
allocObj["itemids"] = await refTplItem.value.getSelectIds();
const user =refUserList.value.getSelUser();
allocObj["fillUser"]= user?.id
if(!allocObj["fillUser"]) {
VXETable.modal.message({ content: '请选择用户', status: 'warning' });
return false ;
}
if(allocObj["itemids"].length==0) {
VXETable.modal.message({ content: '请选择任务', status: 'warning' });
return false ;
}
await saveOrUpdateBatch(allocObj)
await refTplItem.value.clearSelect()
await refUserList.value.clearSelect()
emit("callback")
return true
}
async function saveDataAndClose(){
let ret = await saveData();
if(ret) {
closeDrawer();
}
}
async function userCallBack(user){
await refTplItem.value.setSelUser(user);
}
async function clearAllocUser() {
let allocObj = {taskid:curTask.value?.id};
allocObj["tplid"] = curTpl.value?.id;
allocObj["itemids"] = await refTplItem.value.getSelectIds();
if(allocObj["itemids"]&& allocObj["itemids"].length>0) {
await saveOrUpdateBatch(allocObj)
await refTplItem.value.clearSelect()
await refUserList.value.clearSelect()
await refTplItem.value.setCurTaskHaveAllocUser(curTask.value)
await refTplItem.value.setData(Tpl)
} else {
VXETable.modal.message({ content: '请选择记录', status: 'warning' });
return false ;
}
}
defineExpose({
setIniData,
});
</script>
<style scoped></style>
<template>
<a-drawer :title="drawerTitle" placement="right" width="100%" :visible="isVisible" @close="closeDrawer" style="margin: 10px;">
<template #extra>
<!-- <a-button type="primary" @click="saveDataAndClose" :disabled="!curTask||!curTpl" style="margin-right: 10px;">分配并关闭</a-button> -->
<a-button type="primary" @click="saveData" :disabled="!curTask||!curTpl" style="margin-right: 60px;">分配用户</a-button>
<a-button type="primary" @click="clearAllocUser" :disabled="!curTask||!curTpl" tyle="margin-right: 10px;">清除分配</a-button>
<a-button @click="closeDrawer" style="margin-left: 20px;">关闭</a-button>
</template>
<a-layout style="height:85vh">
<a-layout-sider width="500" :style="{ backgroundColor: '#fff', overflow: 'hidden',margin:'10px 0px 10px 10px' }">
<Tpl ref ="refTpl" @callback="callBackTpl"/>
</a-layout-sider>
<a-layout-content>
<div style="height:83vh;padding: 10px">
<a-row :gutter="10">
<a-col :span="12">
<a-card title="请选择任务项" :bordered="false" style="height:83vh;">
<TplItem ref="refTplItem"></TplItem>
</a-card>
</a-col>
<a-col :span="12">
<a-card title="请选择填写人" :bordered="false" style="height:83vh;">
<UserList ref="refUserList" @callback="userCallBack"></UserList>
</a-card>
</a-col>
</a-row>
</div>
</a-layout-content>
</a-layout>
</a-drawer>
</template>
<script lang="ts" setup>
import { ref, nextTick } from 'vue';
import Tpl from '../../components/Tpl.vue';
import TplItem from './TplItem.vue';
import UserList from './UserList.vue';
import { saveOrUpdateBatch } from '../../alloc/BaosongTaskAlloc.api';
import { VXETable } from 'vxe-table';
const emit = defineEmits(['callback']);
const isVisible = ref(false)
const refTpl = ref()
const refTplItem = ref()
const refUserList = ref()
const drawerTitle= ref();
const curTask = ref()
const curTpl = ref()
function closeDrawer() {
isVisible.value = false
emit("callback")
}
function setIniData(task) {
drawerTitle.value="任务分配【"+task.name+"】"
curTask.value = task
isVisible.value = true
nextTick(async () => {
await refTplItem.value.setCurTaskHaveAllocUser(task)
await refTpl.value.setData(task.tp);
await refUserList.value.setData()
});
}
function callBackTpl(Tpl) {
curTpl.value = Tpl;
refTplItem.value.setData(Tpl)
}
async function saveData() {
let allocObj = {taskid:curTask.value?.id};
allocObj["tplid"] = curTpl.value?.id;
allocObj["itemids"] = await refTplItem.value.getSelectIds();
const user =refUserList.value.getSelUser();
allocObj["fillUser"]= user?.id
if(!allocObj["fillUser"]) {
VXETable.modal.message({ content: '请选择用户', status: 'warning' });
return false ;
}
if(allocObj["itemids"].length==0) {
VXETable.modal.message({ content: '请选择任务', status: 'warning' });
return false ;
}
await saveOrUpdateBatch(allocObj)
await refTplItem.value.clearSelect()
await refUserList.value.clearSelect()
emit("callback")
return true
}
async function saveDataAndClose(){
let ret = await saveData();
if(ret) {
closeDrawer();
}
}
async function userCallBack(user){
await refTplItem.value.setSelUser(user);
}
async function clearAllocUser() {
let allocObj = {taskid:curTask.value?.id};
allocObj["tplid"] = curTpl.value?.id;
allocObj["itemids"] = await refTplItem.value.getSelectIds();
if(allocObj["itemids"]&& allocObj["itemids"].length>0) {
await saveOrUpdateBatch(allocObj)
await refTplItem.value.clearSelect()
await refUserList.value.clearSelect()
await refTplItem.value.setCurTaskHaveAllocUser(curTask.value)
await refTplItem.value.setData(Tpl)
} else {
VXETable.modal.message({ content: '请选择记录', status: 'warning' });
return false ;
}
}
defineExpose({
setIniData,
});
</script>
<style scoped></style>
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit" okText="确定">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { formSchemaApprove } from '../data/BaosongTaskReview.data';
import { saveOrUpdate } from '../api/BaosongTaskReview.api';
const { createConfirm } = useMessage();
// Emits声明
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
//表单配置
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
//labelWidth: 150,
schemas: formSchemaApprove,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
///const recordTp = ref()
//表单赋值
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await resetFields();
isUpdate.value = !!data?.isUpdate;
if (isUpdate.value) {
data.record.tp = '' + data.record.tp;
}
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
//recordTp.value = data.record.tp
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter });
if (unref(isUpdate)) {
await setFieldsValue({
...data.record,
});
}
});
const title = '审批';
async function handleSubmit() {
try {
let values = await validate();
createConfirm({
iconType: 'warning',
title: '确认',
content: '是否完成审批并确认无误?',
okText: '确认',
cancelText: '取消',
onOk: async () => {
console.log('values', values);
setModalProps({ confirmLoading: true });
await saveOrUpdate(values, true);
await resetFields();
closeModal();
emit('success');
},
});
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-calendar-picker) {
width: 100%;
}
</style>
<template>
<div style="min-height: 400px">
<BasicForm @register="registerForm"></BasicForm>
<div style="width: 100%;text-align: center" v-if="!formDisabled">
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button>
</div>
</div>
<a-layout style="height:85vh">
<a-layout-sider width="500" :style="{ backgroundColor: '#fff', overflow: 'hidden', margin: '10px 0px 10px 10px' }">
<Tpl ref="refTpl" @callback="callBackTpl" />
</a-layout-sider>
<a-layout-content>
<div style="height:83vh; padding: 10px">
<a-row :gutter="10">
<a-col :span="12">
<a-card title="请选择任务项" :bordered="false" style="height:83vh;">
<TplItem ref="refTplItem" />
</a-card>
</a-col>
<a-col :span="12">
<a-card title="请选择填写人" :bordered="false" style="height:83vh;">
<UserList ref="refUserList" @callback="userCallBack" />
</a-card>
</a-col>
</a-row>
</div>
</a-layout-content>
</a-layout>
</template>
<script lang="ts">
import {BasicForm, useForm} from '/@/components/Form/index';
import {computed, defineComponent} from 'vue';
import {defHttp} from '/@/utils/http/axios';
import { propTypes } from '/@/utils/propTypes';
import {getBpmFormSchema} from '../BaosongTaskAlloc.data';
import {saveOrUpdate} from '../BaosongTaskAlloc.api';
export default defineComponent({
name: "BaosongTaskAllocForm",
components:{
BasicForm
},
props:{
formData: propTypes.object.def({}),
formBpm: propTypes.bool.def(true),
},
setup(props){
const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({
labelWidth: 150,
schemas: getBpmFormSchema(props.formData),
showActionButtonGroup: false,
baseColProps: {span: 24}
});
<script lang="ts" setup>
import { ref, nextTick } from 'vue';
import Tpl from '../../components/Tpl.vue';
import TplItem from './TplItem.vue';
import UserList from './UserList.vue';
import { saveOrUpdateBatch } from '../../alloc/BaosongTaskAlloc.api';
import { VXETable } from 'vxe-table';
const formDisabled = computed(()=>{
if(props.formData.disabled === false){
return false;
}
return true;
});
const emit = defineEmits(['callback']);
let formData = {};
const queryByIdUrl = '/baosong/baosongTaskAlloc/queryById';
async function initFormData(){
let params = {id: props.formData.dataId};
const data = await defHttp.get({url: queryByIdUrl, params});
formData = {...data}
//设置表单的值
await setFieldsValue(formData);
//默认是禁用
await setProps({disabled: formDisabled.value})
}
const refTpl = ref();
const refTplItem = ref();
const refUserList = ref();
async function submitForm() {
let data = getFieldsValue();
let params = Object.assign({}, formData, data);
console.log('表单数据', params)
const isUpdate = params.id?true:false
await saveOrUpdate(params, false)
}
const curTask = ref();
const curTpl = ref();
//initFormData();
return {
registerForm,
formDisabled,
submitForm,
}
}
});
</script>
\ No newline at end of file
function setIniData(task) {
curTask.value = task;
nextTick(async () => {
await refTplItem.value.setCurTaskHaveAllocUser(task);
await refTpl.value.setData(task.tp);
await refUserList.value.setData();
});
}
function callBackTpl(Tpl) {
curTpl.value = Tpl;
refTplItem.value.setData(Tpl);
}
async function saveData() {
const allocObj = { taskid: curTask.value?.id };
allocObj.tplid = curTpl.value?.id;
allocObj.itemids = await refTplItem.value.getSelectIds();
const user = refUserList.value.getSelUser();
allocObj.fillUser = user?.id;
if (!allocObj.fillUser) {
VXETable.modal.message({ content: '请选择用户', status: 'warning' });
return false;
}
if (allocObj.itemids.length === 0) {
VXETable.modal.message({ content: '请选择任务', status: 'warning' });
return false;
}
await saveOrUpdateBatch(allocObj);
await refTplItem.value.clearSelect();
await refUserList.value.clearSelect();
emit('callback');
return true;
}
async function userCallBack(user) {
await refTplItem.value.setSelUser(user);
}
async function clearAllocUser() {
const allocObj = { taskid: curTask.value?.id };
allocObj.tplid = curTpl.value?.id;
allocObj.itemids = await refTplItem.value.getSelectIds();
if (allocObj.itemids && allocObj.itemids.length > 0) {
await saveOrUpdateBatch(allocObj);
await refTplItem.value.clearSelect();
await refUserList.value.clearSelect();
await refTplItem.value.setCurTaskHaveAllocUser(curTask.value);
await refTplItem.value.setData(curTpl.value);
} else {
return false;
}
}
defineExpose({
setIniData,
saveData,
clearAllocUser,
});
</script>
<style scoped></style>
\ No newline at end of file
......@@ -12,8 +12,8 @@
import {computed, defineComponent} from 'vue';
import {defHttp} from '/@/utils/http/axios';
import { propTypes } from '/@/utils/propTypes';
import {getBpmFormSchema} from '../BaosongTask.data';
import {saveOrUpdate} from '../BaosongTask.api';
import {getBpmFormSchema} from '../data/BaosongTask.data';
import {saveOrUpdate} from '../api/BaosongTask.api';
export default defineComponent({
name: "BaosongTaskForm",
......
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit" :centered="true">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { formImportDataSchema } from '../data/BaosongTask.data';
import { saveOrUpdate,importData } from '../api/BaosongTask.api';
// Emits声明
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
const curTask = ref({});
//表单配置
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
//labelWidth: 150,
schemas: formImportDataSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
//表单赋值
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
curTask.value = data.record
if (unref(isUpdate)) {
//表单赋值
await setFieldsValue({
...data.record,
});
}
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter });
});
//设置标题
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
//表单提交事件
async function handleSubmit(v) {
try {
let values = await validate();
values["taskId"] =curTask.value.id
setModalProps({ confirmLoading: true });
//提交表单
await importData(values, handleSuccess);
//关闭弹窗
closeModal();
//刷新列表
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
}
async function handleSuccess() {
emit("success")
}
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-calendar-picker) {
width: 100%;
}
</style>
......@@ -12,8 +12,8 @@
import {computed, defineComponent} from 'vue';
import {defHttp} from '/@/utils/http/axios';
import { propTypes } from '/@/utils/propTypes';
import {getBpmFormSchema} from '../BaosongTaskRecord.data';
import {saveOrUpdate} from '../BaosongTaskRecord.api';
import {getBpmFormSchema} from '../data/BaosongTaskRecord.data';
import {saveOrUpdate} from '../api/BaosongTaskRecord.api';
export default defineComponent({
name: "BaosongTaskRecordForm",
......
......@@ -12,8 +12,8 @@
import {computed, defineComponent} from 'vue';
import {defHttp} from '/@/utils/http/axios';
import { propTypes } from '/@/utils/propTypes';
import {getBpmFormSchema} from '../BaosongTaskReview.data';
import {saveOrUpdate} from '../BaosongTaskReview.api';
import {getBpmFormSchema} from '../data/BaosongTaskReview.data';
import {saveOrUpdate} from '../api/BaosongTaskReview.api';
export default defineComponent({
name: "BaosongTaskReviewForm",
......
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
<BasicForm @register="registerForm"/>
</BasicModal>
</template>
<script lang="ts" setup>
import {ref, computed, unref} from 'vue';
import {BasicModal, useModalInner} from '/@/components/Modal';
import {BasicForm, useForm} from '/@/components/Form/index';
import {formSchema} from '../data/BaosongTaskReview.data';
import {saveOrUpdate} from '../api/BaosongTaskReview.api';
// Emits声明
const emit = defineEmits(['register','success']);
const isUpdate = ref(true);
//表单配置
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
//labelWidth: 150,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: {span: 24}
});
//表单赋值
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({confirmLoading: false,showCancelBtn:!!data?.showFooter,showOkBtn:!!data?.showFooter});
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
//表单赋值
await setFieldsValue({
...data.record,
});
}
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter })
});
//设置标题
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
//表单提交事件
async function handleSubmit(v) {
try {
let values = await validate();
setModalProps({confirmLoading: true});
//提交表单
await saveOrUpdate(values, isUpdate.value);
//关闭弹窗
closeModal();
//刷新列表
emit('success');
} finally {
setModalProps({confirmLoading: false});
}
}
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number){
width: 100%
}
:deep(.ant-calendar-picker){
width: 100%
}
</style>
\ No newline at end of file
<template>
<div style="height:73vh">
<vxe-toolbar ref="toolbarRef" export print custom :refresh="{ queryMethod }">
<template #buttons >
<vxe-button @click="expandAllEvent">展开所有</vxe-button>
<vxe-button @click="clearExpandEvent">关闭所有</vxe-button>
</template>
</vxe-toolbar>
<vxe-table
border
show-overflow
keep-source
height="auto"
ref="tableRef"
:columnConfig="{ resizable: true }"
:row-config="{keyField: 'id'}"
:edit-config="{trigger: 'click', mode: 'row', showStatus: true}"
:tree-config="{transform: true, rowField: 'code', parentField: 'pcode'}"
:checkbox-config="{highlight: true}"
@checkbox-change="selectChangeEvent"
@checkbox-all="selectAllEvent"
:data="tableData">
<vxe-column type="checkbox" width="50" fixed="left">
</vxe-column>
<vxe-column field="title" title="标题" width="50%" tree-node fixed="left">
</vxe-column>
<vxe-column field="code" title="编码">
</vxe-column>
<vxe-column field="fillUserName" title="填报人">
</vxe-column>
<vxe-column field="fillUser" title="填报人" :visible="false">
</vxe-column>
</vxe-table>
</div>
</template>
<script lang="ts" setup>
import { ref,nextTick } from 'vue'
import { VxeTableEvents } from 'vxe-table'
import { allTplItems } from '../../tpl/BaosongTplItem.api';
import { queryCurTaskAllocUser } from '../../alloc/BaosongTaskAlloc.api';
interface RowVO {
id: number
title: string
tp: number
pcode: string
code: string
childNum: number
hasChild?: boolean
fillUserName?:string
fillUser?:string
}
const curTpl = ref()
const loading = ref(false)
const tableRef = ref()
const tableData = ref<RowVO>()
const itemUserNameMap= ref({})
const curSelUser= ref()
async function setData(tplData){
loading.value =true
curTpl.value = tplData
tableData.value = await allTplItems({tplid:tplData.id});
loading.value =false
const $table = tableRef.value;
nextTick(async ()=>{
if(!tableData.value||!Array.isArray(tableData.value)){
return ;
}
tableData.value.forEach((item)=>{
if(itemUserNameMap.value[item.id]) {
item['fillUserName'] = itemUserNameMap.value[item.id]
$table.setCheckboxRow(item, true)
} else {
item['fillUserName'] = ""
$table.setCheckboxRow(item, false)
}
})
})
}
function getSelectIds() {
let ids = [];
const $table = tableRef.value;
if ($table) {
const selRecords = $table.getCheckboxRecords();
selRecords.forEach(function (ele) {
if(ele.childNum==0) {
ids.push(ele.id);
}
});
}
return ids;
}
function getSelectDatas() {
const $table = tableRef.value;
const selRecords = $table?.getCheckboxRecords();
return selRecords;
}
const selectChangeEvent: VxeTableEvents.CheckboxChange<RowVO> = ({ $table }) => {
const records = $table.getCheckboxRecords()
records.forEach(record => {
$table.setTreeExpand(record, true)
})
return records;
}
function setSelUser(user) {
curSelUser.value = user
const $table = tableRef.value;
const selRecords = $table?.getCheckboxRecords();
selRecords.forEach((item)=>{
item["fillUserName"] = user.realname
item["fillUser"] = user.id
})
}
const clearSelect = () => {
const $table = tableRef.value
if ($table) {
$table.clearCheckboxRow()
}
}
async function setCurTaskHaveAllocUser(task) {
let retData = await queryCurTaskAllocUser(task);
if(!retData||retData.length==0) return
retData.forEach((item)=>{
itemUserNameMap.value[item.itemid] = item.realname
})
}
const expandAllEvent = () => {
const $table = tableRef.value
if ($table) {
$table.setAllTreeExpand(true)
}
}
const clearExpandEvent = () => {
const $table = tableRef.value
if ($table) {
$table.clearTreeExpand()
}
}
const selectAllEvent: VxeTableEvents.CheckboxChange<RowVO> = ({ $table }) => {
if ($table) {
$table.setAllTreeExpand(true)
}
}
defineExpose({
clearSelect,
setData,
setSelUser,
getSelectDatas,
getSelectIds,
setCurTaskHaveAllocUser
});
</script>
<template>
<div style="height:73vh;">
<vxe-grid ref="tableRef"
v-bind="gridOptions"
:radio-config="{highlight: true}"
v-on="gridEvents"
:columnConfig="{ resizable: true }"
:row-config="{ isCurrent: true, isHover: true }"
>
</vxe-grid>
</div>
</template>
<script lang="ts" setup>
import { reactive,ref } from 'vue'
import { VxeGridProps,VxeGridListeners } from 'vxe-table'
import { defHttp } from '/@/utils/http/axios';
const emit = defineEmits(['callback']);
interface RowVO {
id: string
username: string
nickname: string
}
interface SrhParam {
username: string
column:string
order:string
pageNo:number
pageSize:number
}
const tableRef = ref();
const selectRow = ref<RowVO | null>(null)
const srhParams = ref<SrhParam>({
username: '',
column: '',
order: '',
pageNo: 1,
pageSize: 30
});
const gridOptions = reactive<VxeGridProps<RowVO>>({
border: true,
height:"auto",
rowConfig: {
keyField: 'id'
},
columnConfig: {
resizable: true
},
radioConfig: {
highlight: true,
},
pagerConfig: {
enabled: true,
pageSize: srhParams.value.pageSize
},
columns: [
{ type: 'radio', width: 50},
{ type: 'seq', width: 60 },
{ field: 'username', title: '用户账号'},
{ field: 'realname', title: '用户名称' }
],
proxyConfig: {
seq: true,
props: {
result: 'result',
total: 'page.total'
},
ajax: {
query: ({ page }) => {
return findPageList(page.currentPage, page.pageSize)
}
}
}
})
const findPageList = async (currentPage: number, pageSize: number) => {
srhParams.value.pageNo = currentPage;
srhParams.value.pageSize = pageSize
const retData = await setUserData();
return {
page: {
total: retData.total
},
result: retData.records
};
};
async function setData() {
findPageList(1,srhParams.value.pageSize)
}
async function setUserData() {
return await defHttp.get({url: "/sys/user/list", params:srhParams.value})
}
function getSelUser() {
const $table = tableRef.value;
if ($table) {
const currRow = $table.getRadioRecord()
return currRow
}
return null
}
const gridEvents: VxeGridListeners<RowVO> = {
cellClick ({ row, column }) {
selectRow.value = row
setSelectRow(row)
emit("callback",row)
},
cellDblclick ({ row, column }) {
},
radioChange({ row }) {
selectRow.value = row;
setSelectRow(row);
emit("callback", row);
}
}
const setSelectRow = (row) => {
const $table = tableRef.value
if ($table) {
$table.setRadioRow(row)
}
}
const clearSelect = () => {
const $table = tableRef.value
if ($table) {
selectRow.value = null
$table.clearRadioRow()
}
}
defineExpose({
clearSelect,
setData,
getSelUser
});
</script>
......@@ -5,7 +5,7 @@
</div>
</template>
<script lang="ts" name="baosong-baosongTaskAlloc" setup>
<script lang="ts" setup>
import {BasicTable} from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage'
import {columns, searchFormSchema} from '../data/BaosongTaskAlloc.data';
......
......@@ -43,12 +43,12 @@
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import BaosongTaskModal from './components/BaosongTaskModal.vue';
import BaosongTaskDrawer from './components/BaosongTaskDrawer.vue';
import BaosongTaskImportDataModal from './components/BaosongTaskImportDataModal.vue';
import BaosongTaskModal from '../../task/components/BaosongTaskModal.vue';
import BaosongTaskDrawer from '../../task/components/BaosongTaskDrawer.vue';
import BaosongTaskImportDataModal from '../form/BaosongTaskImportDataModal.vue';
import { columns, searchFormSchema } from '../data/BaosongTask.data';
import { list, deleteOne, batchDelete, addApproval, saveOrUpdate, importData } from '../api/BaosongTask.api';
import { useMessage } from '/@/hooks/web/useMessage';
const { createMessage } = useMessage();
......
......@@ -20,18 +20,22 @@
</template>
</BasicTable>
<BaosongTaskModal @register="registerModal" @success="handleSuccess" />
<BaosongAllocDrawer ref="refAllocDrawer" @callback="handleSuccess" />
</div>
</template>
<script lang="ts" name="baosong-baosongTask" setup>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import BaosongTaskModal from '../form/BaosongTaskModal.vue';
import { columns, searchFormSchema } from '../data/BaosongTask.data';
import { list, deleteOne, batchDelete, saveOrUpdate } from '../api/BaosongTask.api';
import BaosongAllocDrawer from '../form/BaosongAllocDrawer.vue';
const [registerModal, { openModal }] = useModal();
const refAllocDrawer = ref<InstanceType<typeof BaosongAllocDrawer>>();
const { tableContext } = useListPage({
tableProps: {
......@@ -61,6 +65,11 @@
});
}
function handleAlloc(record: Recordable) {
refAllocDrawer.value.setIniData(record);
}
function handleEdit(record: Recordable) {
openModal(true, {
record,
......@@ -92,10 +101,18 @@
function getTableAction(record: Recordable) {
return [
{
label: '分配',
onClick: handleAlloc.bind(null, record),
},
{
label: '提交',
onClick: () => emit('sendWorkFlow', record),
},
{
label: '待办',
onClick: () => emit('open-multi-form', record),
},
];
}
......@@ -119,7 +136,7 @@
];
}
const emit = defineEmits(['sendWorkFlow']);
const emit = defineEmits(['sendWorkFlow', 'open-multi-form']);
const handleUpdate = async (dataId: string, flowNode: Recordable) => {
const record = {
......
......@@ -27,8 +27,8 @@
import { listForFillData } from '../api/BaosongTask.api';
import { updateFillStaBatch } from '../api/BaosongTaskAlloc.api';
import RecordDrawer from './components/RecordDrawer.vue';
import RecordDrawer2 from './components/RecordDrawer2.vue';
import RecordDrawer from '../../components/CommonForm.vue';
import RecordDrawer2 from '../../components/CommonTable.vue';
import FileViewerDrawer from '/@/components/onlinePreview/FileViewerDrawer.vue';
import { useRouter } from 'vue-router';
......
......@@ -19,7 +19,7 @@
import { useListPage } from '/@/hooks/system/useListPage';
import { columns, searchFormSchema } from '../data/BaosongTaskReview.data';
import { list, deleteOne, batchDelete, downLoadTaskXml, saveOrUpdate } from '../api/BaosongTaskReview.api';
import BaosongApproveModal from './components/BaosongApproveModal.vue';
import BaosongApproveModal from '../form/BaosongApproveModal.vue';
import { useRoute,useRouter } from 'vue-router';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils.js';
......
<template>
<div>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle></template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
</div>
</template>
<script lang="ts" name="problem-stProblemCheck" setup>
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { columns } from './StProblemCheck.data';
import { list, saveOrUpdate } from './StProblemCheck.api';
const props = defineProps({
beforeFlowNode: { type: Object, default: () => ({}) },
currentFlowNode: { type: Object, default: () => ({}) },
nextFlowNode: { type: Object, default: () => ({}) },
});
const emit = defineEmits(['callback', 'sendWorkFlow', 'openMultiForm']);
const { tableContext } = useListPage({
tableProps: {
title: '问题整改',
api: list,
columns,
canResize: true,
beforeFetch(params) {
params['bpmNodeId'] = props.currentFlowNode.id;
},
actionColumn: { width: 200, fixed: 'right' },
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
function handleExecute(record: Recordable) {
emit('openMultiForm', record);
}
function handleSendNext(record: Recordable) {
emit('sendWorkFlow', record);
}
function handleSuccess() {
selectedRowKeys.value = [];
reload();
}
function getTableAction(record) {
return [
{ label: '整改执行', onClick: handleExecute.bind(null, record) },
{ label: '提交', onClick: handleSendNext.bind(null, record) },
];
}
async function handleUpdate(dataId, flowNode) {
const record = { bpmNodeId: flowNode.id, deployId: flowNode.deployId, bpmStatus: 2, id: dataId };
await saveOrUpdate(record, true);
handleSuccess();
}
defineExpose({ handleUpdate });
</script>
<style scoped></style>
......@@ -124,6 +124,11 @@
}
const handleDefinitionStart = async (data) => {
if (data.procInsId) {
return;
}
const formData = { dataId: data.id, dataName: 'id' };
const nodeDeployId = currentNode.value.deployId || '';
const startResRaw = await definitionStartByDeployId(nodeDeployId, formData);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论