提交 19686bd7 authored 作者: kxjia's avatar kxjia

完善代码

上级 385fe3aa
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
@sendWorkFlow="handleDefinitionSend" @sendWorkFlow="handleDefinitionSend"
@endWorkFlow="handleDefinitionEnd" @endWorkFlow="handleDefinitionEnd"
@open-multi-form="handleOpenMultiForm" @open-multi-form="handleOpenMultiForm"
:todo-list="todoList" :todoList="todoList"
/> />
<WorkFlowFormDrawer <WorkFlowFormDrawer
v-model:visible="drawerVisible" v-model:visible="drawerVisible"
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
:external-form-data="externalFormData" :external-form-data="externalFormData"
:proc-def-id="currentProcDefId" :proc-def-id="currentProcDefId"
:proc-ins-id="procInsId" :proc-ins-id="procInsId"
:show-history-form-data="true" :show-history-form-data="false"
:data-id="dataId" :data-id="dataId"
:deploy-id="deployId" :deploy-id="deployId"
:task-id="taskId" :task-id="taskId"
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
const formComponentRefs = ref<Map<number, any>>(new Map()); const formComponentRefs = ref<Map<number, any>>(new Map());
const assignee = ref<any>(""); const assignee = ref<any>("");
const userType = ref<any>(""); const userType = ref<any>("");
const todoaLLList = ref<any[]>([]); const todoList= ref<any[]>([]);
const drawerVisible = ref(false); const drawerVisible = ref(false);
const drawerTitle = ref('表单处理'); const drawerTitle = ref('表单处理');
const currentMultiFormIndex = ref(1); const currentMultiFormIndex = ref(1);
...@@ -148,11 +148,8 @@ ...@@ -148,11 +148,8 @@
}; };
const handleDefinitionSend = async (data) => { const handleDefinitionSend = async (data) => {
if (!data.procInsId) { await setCurrentNodeById(data.bpmNodeId);
await handleDefinitionStart(data) alert(1111)
}
await setCurrentNodeById(data);
dataId.value = data.id; dataId.value = data.id;
deployId.value = currentNode.value.deployId || ''; deployId.value = currentNode.value.deployId || '';
...@@ -247,6 +244,7 @@ ...@@ -247,6 +244,7 @@
} }
async function handleOpenMultiForm(data: any) { async function handleOpenMultiForm(data: any) {
await setCurrentNodeById(data.bpmNodeId);
deployId.value = currentNode.value.deployId || ''; deployId.value = currentNode.value.deployId || '';
procInsId.value = data.procInsId || ''; procInsId.value = data.procInsId || '';
...@@ -271,6 +269,7 @@ ...@@ -271,6 +269,7 @@
if(resData.formUrl) { if(resData.formUrl) {
mainFormUrl.value = resData.formUrl mainFormUrl.value = resData.formUrl
mainFormListUrl.value = resData.formListurl || '' mainFormListUrl.value = resData.formListurl || ''
} else { } else {
mainFormUrl.value = "" mainFormUrl.value = ""
refInnerForm.value.iniData(resData) refInnerForm.value.iniData(resData)
...@@ -296,15 +295,13 @@ ...@@ -296,15 +295,13 @@
currentMultiFormIndex.value = index; currentMultiFormIndex.value = index;
currentNode.value = nodes[index]; currentNode.value = nodes[index];
} }
} }
onMounted(async () => { onMounted(async () => {
await nextTick(); await nextTick();
try { try {
todoList.value = await todoListAll();
const nodes = await getNodesByTableName(formTableName); const nodes = await getNodesByTableName(formTableName);
todoaLLList.value = await todoList(queryParams);
workflowNodes.value = nodes; workflowNodes.value = nodes;
if (workflowNodes.value?.length > 0) { if (workflowNodes.value?.length > 0) {
workflowNodes.value.forEach(node => { workflowNodes.value.forEach(node => {
......
...@@ -28,7 +28,7 @@ export const columns: BasicColumn[] = [ ...@@ -28,7 +28,7 @@ export const columns: BasicColumn[] = [
title: '填报人', title: '填报人',
align: 'left', align: 'left',
dataIndex: 'fillUser', dataIndex: 'fillUser',
width:0, width: "10%",
ifShow: false, ifShow: false,
resizable:true resizable:true
}, },
...@@ -37,6 +37,7 @@ export const columns: BasicColumn[] = [ ...@@ -37,6 +37,7 @@ export const columns: BasicColumn[] = [
align: 'left', align: 'left',
dataIndex: 'respUser', dataIndex: 'respUser',
width: "10%", width: "10%",
ifShow: false,
resizable:true resizable:true
}, },
{ {
...@@ -44,6 +45,7 @@ export const columns: BasicColumn[] = [ ...@@ -44,6 +45,7 @@ export const columns: BasicColumn[] = [
align: 'left', align: 'left',
dataIndex: 'enterTel', dataIndex: 'enterTel',
width: "10%", width: "10%",
ifShow: false,
resizable:true resizable:true
}, },
{ {
...@@ -79,19 +81,39 @@ export const columns: BasicColumn[] = [ ...@@ -79,19 +81,39 @@ export const columns: BasicColumn[] = [
{ {
title: '报告状态', title: '报告状态',
align: 'left', align: 'left',
dataIndex: 'sta', dataIndex: 'bpmStatus',
ifShow: true, ifShow: true,
width: "8%", width: "8%",
resizable:true, resizable:true,
customRender: ({ text }) => { customRender: ({ text }) => {
let color = "red"; let color = "";
if(!text||text===0) { color = "red";} let status = "";
if(text===1) { color = "green"} if (text === null || text === undefined) {
if(text===2) { color = "orange"} color = "red";
if(text===3) { color = "red"} status = "未启动";
if(text===4) { color = "gray"} } else if(text==="0") {
if(text===9) {color = "blue"} color = "yellow";
return render.renderTag(render.renderDict(text, 'fxc_report_sta'), color); status = "已启动";
} else if(text==="2") {
color = "green";
status = "运行中";
} else {
color = "";
status = "完成";
}
return render.renderTag(status, color);
},
},
{
title: '流程节点',
align: 'left',
dataIndex: 'flowtaskName',
ifShow: true,
width: "10%",
resizable:true,
customRender: ({ text }) => {
return !text ? '开始' : text;
}, },
}, },
{ {
......
<template> <template>
<div style="min-height: 400px"> <a-card style="width: 100%" :tab-list="tabList" :active-tab-key="key" @tabChange="onTabChange">
<BasicForm @register="registerForm"></BasicForm> <div style="background-color: #ececec; padding: 20px">
<div style="width: 100%;text-align: center" v-if="!formDisabled"> <a-row :gutter="[16, 16]">
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button> <a-col :span="8" v-for="item in dataList" :key="item.id">
<a-card :bordered="false">
<template #title>
{{ item.code }} - {{ item.nm }}
</template>
<template #extra>
<a href="#" @click.prevent="openReportModal(item)">填报</a>
</template>
<span>年度:{{ item.vyear }} &nbsp;</span>
<span>版本:{{ item.version }} &nbsp;</span>
<span>节点数:{{ item.childNum }}</span><br />
<span>{{ item.xmlfilePath }}</span>
</a-card>
</a-col>
</a-row>
</div> </div>
<!-- 全屏报表填报弹窗 -->
<a-modal
v-model:visible="modalVisible"
:title="modalTitle"
:width="'100%'"
:style="{ top: '0', paddingBottom: '0' }"
:footer="null"
:destroy-on-close="true"
:mask-closable="false"
:keyboard="true"
wrapClassName="full-screen-modal"
@cancel="handleModalClose"
>
<template #closeIcon>
<CloseOutlined />
</template>
<div class="full-screen-content">
<component
:is="currentComponent"
v-if="currentComponent"
:taskId="queryParam.taskId"
:taskName="queryParam.taskName"
:tplId="queryParam.tplId"
:tplName="queryParam.tplName"
:tplCode="queryParam.tplCode"
@close="handleModalClose"
@submit="handleFormSubmit"
/>
</div> </div>
</a-modal>
</a-card>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import {BasicForm, useForm} from '/@/components/Form/index'; import { ref, computed, markRaw } from 'vue';
import {computed, defineComponent} from 'vue'; import { CloseOutlined } from '@ant-design/icons-vue';
import {defHttp} from '/@/utils/http/axios'; import { findUserRightForTpl } from '../api/BaosongTpl.api';
import { propTypes } from '/@/utils/propTypes';
import {getBpmFormSchema} from '../data/BaosongTaskRecord.data'; // 静态导入所有组件
import {saveOrUpdate} from '../api/BaosongTaskRecord.api'; import Tb1 from '../../report/components/Tb1.vue';
import Tb2 from '../../report/components/Tb2.vue';
export default defineComponent({ import Tb3 from '../../report/components/Tb3.vue';
name: "BaosongTaskRecordForm", import Tb4 from '../../report/components/Tb4.vue';
components:{ import Tb5 from '../../report/components/Tb5.vue';
BasicForm import Tb6 from '../../report/components/Tb6.vue';
}, import Tb7 from '../../report/components/Tb7.vue';
props:{ import Tb8 from '../../report/components/Tb8.vue';
formData: propTypes.object.def({}), import Tb9 from '../../report/components/Tb9.vue';
formBpm: propTypes.bool.def(true), import Tb10 from '../../report/components/Tb10.vue';
}, import Tb11 from '../../report/components/Tb11.vue';
setup(props){ import Rr1 from '../../report/components/Rr1.vue';
const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({ import Rr2 from '../../report/components/Rr2.vue';
labelWidth: 150, import Tm1 from '../../report/components/Tm1.vue';
schemas: getBpmFormSchema(props.formData), import Tm2 from '../../report/components/Tm2.vue';
showActionButtonGroup: false, import Tq1 from '../../report/components/Tq1.vue';
baseColProps: {span: 24} import Tq2 from '../../report/components/Tq2.vue';
}); import Tq3 from '../../report/components/Tq3.vue';
import Tq4 from '../../report/components/Tq4.vue';
const formDisabled = computed(()=>{
if(props.formData.disabled === false){
return false; // 组件映射
} const componentMap: Record<string, any> = {
return true; 'T-B-1': markRaw(Tb1),
}); 'T-B-2': markRaw(Tb2),
'T-B-3': markRaw(Tb3),
let formData = {}; 'T-B-4': markRaw(Tb4),
const queryByIdUrl = '/baosong/baosongTaskRecord/queryById'; 'T-B-5': markRaw(Tb5),
async function initFormData(){ 'T-B-6': markRaw(Tb6),
let params = {id: props.formData.dataId}; 'T-B-7': markRaw(Tb7),
const data = await defHttp.get({url: queryByIdUrl, params}); 'T-B-8': markRaw(Tb8),
formData = {...data} 'T-B-9': markRaw(Tb9),
//设置表单的值 'T-B-10': markRaw(Tb10),
await setFieldsValue(formData); 'T-B-11': markRaw(Tb11),
//默认是禁用 'R-R-1': markRaw(Rr1),
await setProps({disabled: formDisabled.value}) 'R-R-2': markRaw(Rr2),
'T-M-1': markRaw(Tm1),
'T-M-2': markRaw(Tm2),
'T-Q-1': markRaw(Tq1),
'T-Q-2': markRaw(Tq2),
'T-Q-3': markRaw(Tq3),
'T-Q-4': markRaw(Tq4),
};
// 类型映射
const typeMap: Record<string, number> = {
tab1: 1,
tab2: 2,
tab3: 3,
tab4: 4,
};
const queryParam = ref({
taskId: 0,
taskName: '',
tplId: '',
tplName: '',
tplCode: '',
});
const key = ref('tab1');
const dataList = ref<any[]>([]);
const dataMap = ref<Record<number, any[]>>({});
const dataAllList = ref<any[]>([]);
// 弹窗相关状态
const modalVisible = ref(false);
const modalTitle = ref('');
const currentComponent = ref<any>(null);
const tabList = computed(() => {
const tabs = [
{ key: 'tab1', tab: '年报', type: 1 },
{ key: 'tab2', tab: '季报', type: 2 },
{ key: 'tab3', tab: '月报', type: 3 },
{ key: 'tab4', tab: '年度报告', type: 4 },
];
return tabs.map(tab => ({
...tab,
disabled: !dataMap.value[tab.type] || dataMap.value[tab.type].length === 0,
}));
});
const onTabChange = async (value: string) => {
key.value = value;
const type = typeMap[value];
if (type) {
dataList.value = dataMap.value[type] || [];
} }
};
async function submitForm() { // 打开报表填报弹窗
let data = getFieldsValue(); const openReportModal = (item: any) => {
let params = Object.assign({}, formData, data); const component = componentMap[item.code];
console.log('表单数据', params) if (!component) {
await saveOrUpdate(params, true) console.warn(`未找到对应组件: ${item.code}`);
return;
} }
initFormData(); queryParam.value.tplName = item.nm || '';
queryParam.value.tplCode = item.code || '';
queryParam.value.tplId = item.id || '';
modalTitle.value = `${item.code} - ${item.nm} 填报`;
currentComponent.value = component;
modalVisible.value = true;
};
// 关闭弹窗
const handleModalClose = () => {
modalVisible.value = false;
currentComponent.value = null;
};
return { // 表单提交成功后的处理
registerForm, const handleFormSubmit = (data?: any) => {
formDisabled, console.log('表单提交成功', data);
submitForm, handleModalClose();
};
// 初始化数据
const iniData = async (taskId: number) => {
queryParam.value.taskId = taskId;
queryParam.value.tplName = '';
queryParam.value.tplCode = '';
queryParam.value.tplId = '';
try {
dataAllList.value = await findUserRightForTpl({ taskId });
console.log('获取数据:', dataAllList.value);
dataMap.value = dataAllList.value.reduce((result, item) => {
const key = item.tp;
if (!result[key]) {
result[key] = [];
} }
result[key].push(item);
return result;
}, {} as Record<number, any[]>);
dataList.value = dataMap.value[1] || [];
} catch (error) {
console.error('初始化数据失败:', error);
} }
}); };
// 初始化
iniData(116);
defineExpose({
iniData,
});
</script> </script>
<style>
/* 全屏弹窗样式 - 使用全局样式因为 antd modal 挂载在 body 上 */
.full-screen-modal {
top: 0 !important;
padding-bottom: 0 !important;
}
.full-screen-modal .ant-modal {
top: 0 !important;
width: 100% !important;
height: 100vh !important;
margin: 0 !important;
padding-bottom: 0 !important;
}
.full-screen-modal .ant-modal-content {
height: 100vh;
display: flex;
flex-direction: column;
border-radius: 0;
}
.full-screen-modal .ant-modal-header {
flex-shrink: 0;
border-radius: 0;
padding: 16px 24px;
}
.full-screen-modal .ant-modal-body {
flex: 1;
overflow-y: auto;
padding: 20px;
}
.full-screen-modal .ant-modal-close {
top: 16px;
right: 16px;
}
.full-screen-content {
height: 100%;
width: 100%;
}
</style>
\ No newline at end of file
...@@ -16,26 +16,45 @@ ...@@ -16,26 +16,45 @@
</a-dropdown> </a-dropdown>
</template> </template>
<template #action="{ record }"> <template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" /> <TableAction v-if="record.bpmStatus === null" :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
<TableAction v-else :actions="getTableAction(record)" />
</template> </template>
</BasicTable> </BasicTable>
<BaosongTaskModal @register="registerModal" @success="handleSuccess" /> <BaosongTaskModal @register="registerModal" @success="handleSuccess" />
<BaosongAllocDrawer ref="refAllocDrawer" @callback="handleSuccess" /> <FlowHistoryDrawer @register="refFlowHistoryDrawer" />
<BaosongTaskDrawer ref="refTaskDrawer" @callback="handleSuccess" />
<task-assignee-drawer @register="registerAssigneeDrawer" @success="handlSendSuccess" @error="handleError" />
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, unref } from 'vue'; import { ref } from 'vue';
import { BasicTable, TableAction } from '/@/components/Table'; import { BasicTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal'; import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage'; import { useListPage } from '/@/hooks/system/useListPage';
import BaosongTaskModal from '../form/BaosongTaskModal.vue'; import BaosongTaskModal from '../form/BaosongTaskModal.vue';
import { columns, searchFormSchema } from '../data/BaosongTask.data'; import { columns, searchFormSchema } from '../data/BaosongTask.data';
import { list, deleteOne, batchDelete, saveOrUpdate } from '../api/BaosongTask.api'; import { list, deleteOne, batchDelete, saveOrUpdate } from '../api/BaosongTask.api';
import BaosongAllocDrawer from '../form/BaosongAllocDrawer.vue'; import { definitionStartByDeployId, getNodesByTableName } from "/@/components/Process/api/definition";
import { useDrawer } from '/@/components/Drawer';
import TaskAssigneeDrawer from '/@/views/common/TaskAssigneeDrawer.vue';
import FlowHistoryDrawer from '/@/views/common/FlowHistoryDrawer.vue';
import BaosongTaskDrawer from '/@/views/baosong/task/components/BaosongTaskDrawer.vue';
const [refFlowHistoryDrawer, { openDrawer }] = useDrawer();
const [registerAssigneeDrawer, { openDrawer:openAssigneeDrawer }] = useDrawer();
const [registerModal, { openModal }] = useModal(); const [registerModal, { openModal }] = useModal();
const refAllocDrawer = ref();
const workflowNodes = ref<Recordable[]>([]);
const currentNodeIndex = ref(0);
const userType = ref('');
const assignee = ref('');
const dataId = ref('');
const deployId = ref('');
const currentNode = ref<Recordable>({});
const formTableName = "baosong_task";
const refTaskDrawer = ref();
const { tableContext } = useListPage({ const { tableContext } = useListPage({
tableProps: { tableProps: {
...@@ -50,7 +69,8 @@ ...@@ -50,7 +69,8 @@
showAdvancedButton: true, showAdvancedButton: true,
}, },
actionColumn: { actionColumn: {
width: 200, align: 'left',
width: 150,
fixed: 'right', fixed: 'right',
}, },
}, },
...@@ -59,31 +79,27 @@ ...@@ -59,31 +79,27 @@
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext; const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
function handleAdd() { function handleAdd() {
openModal(true, { openModal(true, { isUpdate: false, showFooter: true });
isUpdate: false,
showFooter: true,
});
} }
function handleAlloc(record: Recordable) { const handleDefinitionStart = async (data) => {
refAllocDrawer.value.setIniData(record); const formData = { dataId: data.id, dataName: 'id' };
} const startResRaw = await definitionStartByDeployId(currentNode.value.deployId || '', formData);
if (startResRaw?.instanceId) {
data.procInsId = startResRaw.instanceId;
data.bpmStatus = 0;
data.bpmNodeId = currentNode.value.id;
data.deployId = currentNode.value.deployId;
await saveOrUpdate(data, true);
}
};
function handleEdit(record: Recordable) { function handleEdit(record: Recordable) {
openModal(true, { openModal(true, { record, isUpdate: true, showFooter: true });
record,
isUpdate: true,
showFooter: true,
});
} }
function handleDetail(record: Recordable) { function handleDetail(record: Recordable) {
openModal(true, { openModal(true, { record, isUpdate: true, showFooter: false });
record,
isUpdate: true,
showFooter: false,
});
} }
async function handleDelete(record: Recordable) { async function handleDelete(record: Recordable) {
...@@ -99,33 +115,102 @@ function handleAlloc(record: Recordable) { ...@@ -99,33 +115,102 @@ function handleAlloc(record: Recordable) {
await reload(); await reload();
} }
function handleShowHistory(record) {
openDrawer(true, {
procInsId: record.procInsId,
dataId: record.id,
deployId: record.deployId,
});
};
const handlSendSuccess = async () => {
await handleSuccess();
};
const handleError = (error: Error) => {
console.error('任务分配失败:', error);
};
const setNextNodeUser = async () => {
currentNodeIndex.value++;
const nextNode = workflowNodes.value[currentNodeIndex.value];
const attributes = nextNode?.attributes || {};
const userTypes = attributes.userType || [];
if (userTypes.length > 0) {
userType.value = userTypes[0].value || '';
if (userType.value === "role") {
assignee.value = nextNode.candidateGroups?.[0]?.id;
} else {
assignee.value = nextNode.assignee;
}
}
};
const handleDefinitionSend = async (data: Recordable) => {
workflowNodes.value = await getNodesByTableName(formTableName);
currentNode.value = workflowNodes.value[0];
if (!data.procInsId) {
await handleDefinitionStart(data)
}
dataId.value = data.id;
deployId.value = currentNode.value.deployId || '';
await setNextNodeUser();
openAssigneeDrawer(true, {
assignee: assignee.value,
assigneeName: '',
userType: userType.value,
dataId: data.id,
deployId: deployId.value,
});
};
function handleAlloc(record: Recordable) {
refTaskDrawer.value.setIniData(record);
}
function getTableAction(record: Recordable) { function getTableAction(record: Recordable) {
return [ return [
{ {
label: '分配', label: '分配',
//disabled:record.sta>1,
onClick: handleAlloc.bind(null, record), onClick: handleAlloc.bind(null, record),
}, },
{ {
label: '提交', label: '发起任务',
onClick: () => emit('sendWorkFlow', record), ifShow: record.bpmStatus === null,
popConfirm: {
title: '是否确认发起任务',
confirm: () => handleDefinitionSend(record),
},
},
{
label: '发送任务',
ifShow: record.bpmStatus === "0",
popConfirm: {
title: '是否确认发起任务',
confirm: () => handleDefinitionSend(record),
},
}, },
{ {
label: '待办', label: '查看流程',
onClick: () => emit('open-multi-form', record), ifShow: record.bpmStatus !== null,
onClick: () => handleShowHistory(record),
},
{
label: '归档',
ifShow: record.bpmStatus === "3",
onClick: () => handleShowHistory(record),
}, },
]; ];
} }
function getDropDownAction(record: Recordable) { function getDropDownAction(record: Recordable) {
return [ return [
{ { label: '详情', onClick: () => handleDetail(record) },
label: '详情', { label: '编辑', onClick: () => handleEdit(record) },
onClick: () => handleDetail(record),
},
{
label: '编辑',
onClick: () => handleEdit(record),
},
{ {
label: '删除', label: '删除',
popConfirm: { popConfirm: {
...@@ -136,32 +221,23 @@ function handleAlloc(record: Recordable) { ...@@ -136,32 +221,23 @@ function handleAlloc(record: Recordable) {
]; ];
} }
const emit = defineEmits(['sendWorkFlow', 'open-multi-form']); defineExpose({
handleUpdate: async (dataId: string, flowNode: Recordable) => {
const handleUpdate = async (dataId: string, flowNode: Recordable) => { await saveOrUpdate({
const record = { id: dataId,
bpmNodeId: flowNode.id, bpmNodeId: flowNode.id,
deployId: flowNode.deployId, deployId: flowNode.deployId,
bpmStatus: 2, bpmStatus: 2,
id: dataId, }, true);
};
await saveOrUpdate(record, true);
await handleSuccess(); await handleSuccess();
}; },
handleStartUpdate: async (flowData: Recordable) => {
const handleStartUpdate = async (flowData: Recordable) => { await saveOrUpdate({
const record = {
procInsId: flowData.procInsId,
id: flowData.dataId, id: flowData.dataId,
procInsId: flowData.procInsId,
bpmStatus: 0, bpmStatus: 0,
}; }, true);
await saveOrUpdate(record, true);
await handleSuccess(); await handleSuccess();
}; },
defineExpose({
handleUpdate,
handleStartUpdate,
}); });
</script> </script>
\ No newline at end of file
<template>
<div>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined">新增</a-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined" />
删除
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作 <Icon icon="mdi:chevron-down" /></a-button>
</a-dropdown>
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<BaosongTaskModal @register="registerModal" @success="handleSuccess" />
<BaosongAllocDrawer ref="refAllocDrawer" @callback="handleSuccess" />
</div>
</template>
<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();
const props = defineProps({
todoList: { type: Array as () => Recordable[], default: () => [] },
})
const { tableContext } = useListPage({
tableProps: {
title: '任务表',
api: list,
columns,
canResize: false,
formConfig: {
labelWidth: '30%',
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: true,
},
beforeFetch(params) {
params['bpmStatus'] = "2";
params['todoList'] = props.todoList;
return params;
},
actionColumn: {
width: 200,
fixed: 'right',
},
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
function handleAdd() {
openModal(true, {
isUpdate: false,
showFooter: true,
});
}
function handleAlloc(record: Recordable) {
refAllocDrawer.value.setIniData(record);
}
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
function handleDetail(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: false,
});
}
async function handleDelete(record: Recordable) {
await deleteOne({ id: record.id }, handleSuccess);
}
async function batchHandleDelete() {
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
async function handleSuccess() {
selectedRowKeys.value = [];
await reload();
}
function getTableAction(record: Recordable) {
return [
// {
// label: '分配',
// onClick: handleAlloc.bind(null, record),
// },
// {
// label: '提交',
// onClick: () => emit('sendWorkFlow', record),
// },
{
label: '处理',
onClick: () => emit('open-multi-form', record),
},
];
}
function getDropDownAction(record: Recordable) {
return [
{
label: '详情',
onClick: () => handleDetail(record),
},
{
label: '编辑',
onClick: () => handleEdit(record),
},
{
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: () => handleDelete(record),
},
},
];
}
const emit = defineEmits(['sendWorkFlow', 'open-multi-form']);
const handleUpdate = async (dataId: string, flowNode: Recordable) => {
const record = {
bpmNodeId: flowNode.id,
deployId: flowNode.deployId,
bpmStatus: 2,
id: dataId,
};
await saveOrUpdate(record, true);
await handleSuccess();
};
const handleStartUpdate = async (flowData: Recordable) => {
const record = {
procInsId: flowData.procInsId,
id: flowData.dataId,
bpmStatus: 0,
};
await saveOrUpdate(record, true);
await handleSuccess();
};
defineExpose({
handleUpdate,
handleStartUpdate,
});
</script>
\ No newline at end of file
...@@ -16,10 +16,8 @@ enum Api { ...@@ -16,10 +16,8 @@ enum Api {
listForFillData = '/baosong/baosongTask/listForFillData', listForFillData = '/baosong/baosongTask/listForFillData',
importData = '/baosong/baosongTask/importData', importData = '/baosong/baosongTask/importData',
archiveList = '/baosong/baosongTask/archiveList', archiveList = '/baosong/baosongTask/archiveList',
} }
/** /**
* 导出api * 导出api
......
<template>
<div class="app-container">
<vxe-grid ref="xGrid" v-bind="gridOptions" @checkbox-change="onSelectChange" @checkbox-all="onSelectChange">
<!-- 搜索表单插槽 -->
<template #flowNameItem="{ data }">
<vxe-input v-model="data.procDefName" placeholder="请输入流程名称" clearable @keyup.enter="searchEvent"></vxe-input>
</template>
<template #taskNameItem="{ data }">
<vxe-input v-model="data.taskName" placeholder="请输入任务名称" clearable @keyup.enter="searchEvent"></vxe-input>
</template>
<template #startTimeItem="{ data }">
<vxe-input type="date" v-model="data.startTime" placeholder="请选择开始时间" clearable></vxe-input>
</template>
<template #actionItem>
<vxe-button status="primary" icon="vxe-icon-search" @click="searchEvent">搜索</vxe-button>
<vxe-button icon="vxe-icon-refresh" @click="resetEvent">重置</vxe-button>
</template>
<!-- 表格列插槽 -->
<template #procDefVersion_default="{ row }">
<span class="version-tag">v{{ row.procDefVersion }}</span>
</template>
<template #startUser_default="{ row }">
<div class="user-info">
<span class="user-name">{{ row.startUserName }}</span>
<span class="dept-tag">{{ row.startDeptName }}</span>
</div>
</template>
<template #action_default="{ row }">
<vxe-button type="text" icon="vxe-icon-edit" status="primary" @click="handleProcess(row)">处理</vxe-button>
</template>
</vxe-grid>
<div v-if="isShowDrawer">
<a-drawer
destroyOnClose
v-model:open="isShowDrawer"
class="custom-class"
root-class-name="root-class-name"
:root-style="{ color: 'blue' }"
title="待办任务"
placement="right"
width="90%"
style="margin: 0px; padding: 0px"
>
<!-- <template #extra>
<div style="float: right">
<a-tag style="margin-left: 10px">发起人:{{ startUser }}</a-tag>
<a-tag>任务节点:{{ taskName }}</a-tag>
</div>
</template> -->
<TodoIndex v-if="isShowDrawer" ref="refTodoIndex" @callback="handleSuccess" />
</a-drawer>
</div>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, onMounted, nextTick } from 'vue';
import { message } from 'ant-design-vue';
import type { VxeGridProps, VxeGridInstance } from 'vxe-table';
import { todoList, delDeployment } from '/@/components/Process/api/todo';
import XEUtils from 'xe-utils';
import TodoIndex from './components/TodoIndex.vue';
const loading = ref(false);
const isShowDrawer = ref(false);
const refTodoIndex = ref();
const startUser = ref();
const taskName = ref();
interface QueryParams {
pageNum: number;
pageSize: number;
procDefName?: string;
taskName?: string;
startTime?: string;
}
const queryParams = reactive<QueryParams>({
pageNum: 1,
pageSize: 10,
procDefName: undefined,
taskName: undefined,
startTime: undefined,
});
interface TodoItem {
taskId: string;
procDefName: string;
taskName: string;
procDefVersion: number;
startUserName: string;
startDeptName: string;
createTime: string;
procInsId: string;
executionId: string;
deployId: string;
}
const defaultData = reactive({
procDefName: '',
taskName: '',
startTime: '',
});
const selectedRowKeys = ref<string[]>([]);
const selectRecords = ref<TodoItem[]>([]);
const multiple = ref(true);
const xGrid = ref<VxeGridInstance>();
const gridOptions = reactive<VxeGridProps<any>>({
loading: loading.value,
showOverflow: true,
border: true,
rowConfig: {
keyField: 'taskId',
isHover: true,
},
columnConfig: {
resizable: true,
},
pagerConfig: {
enabled: true,
pageSize: 10,
pageSizes: [10, 20, 50, 100],
layouts: ['PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total'],
},
checkboxConfig: {
highlight: true,
range: true,
},
layouts: ['Top', 'Form', 'Toolbar', 'Table', 'Bottom', 'Pager'],
formConfig: {
data: XEUtils.clone(defaultData, true),
items: [
{ field: 'procDefName', title: '流程名称', span: 6, itemRender: {}, slots: { default: 'flowNameItem' } },
{ field: 'taskName', title: '任务名称', span: 6, itemRender: {}, slots: { default: 'taskNameItem' } },
{ field: 'startTime', title: '开始时间', span: 6, itemRender: {}, slots: { default: 'startTimeItem' } },
{ span: 6, align: 'center', itemRender: {}, slots: { default: 'actionItem' } },
],
},
proxyConfig: {
response: {
result: 'result',
total: 'page.total',
},
ajax: {
query: ({ page }) => {
return findPageList(page.currentPage, page.pageSize);
},
},
},
columns: [
{ type: 'checkbox', width: 60, fixed: 'left' },
{ type: 'seq', width: 70, fixed: 'left' },
{ field: 'taskId', title: '任务编号', minWidth: 120, showOverflow: true },
{ field: 'procDefName', title: '流程名称', minWidth: 160, showOverflow: true },
{ field: 'taskName', title: '当前节点', minWidth: 140, showOverflow: true },
{ field: 'taskType', title: '节点类型', minWidth: 140, showOverflow: true },
{ field: 'procDefVersion', title: '流程版本', width: 100, align: 'center', slots: { default: 'procDefVersion_default' } },
{ field: 'startUser', title: '流程发起人', minWidth: 180, align: 'center', slots: { default: 'startUser_default' } },
{ field: 'createTime', title: '接收时间', width: 180, align: 'center' },
{
title: '操作',
width: 120,
fixed: 'right',
align: 'center',
slots: { default: 'action_default' },
},
],
});
const findPageList = async (currentPage: number, pageSize: number) => {
queryParams.pageNum = currentPage;
queryParams.pageSize = pageSize;
if (gridOptions.formConfig?.data) {
queryParams.procDefName = gridOptions.formConfig.data.procDefName;
queryParams.taskName = gridOptions.formConfig.data.taskName;
queryParams.startTime = gridOptions.formConfig.data.startTime;
}
try {
loading.value = true;
const retData = await todoList(queryParams);
return {
page: {
total: retData.total,
},
result: retData.records,
};
} catch (error) {
console.error('查询数据失败:', error);
message.error('查询数据失败');
return {
page: { total: 0 },
result: [],
};
} finally {
loading.value = false;
}
};
const searchEvent = async () => {
queryParams.pageNum = 1;
if (xGrid.value) {
await xGrid.value.commitProxy('query');
}
};
const resetEvent = () => {
if (gridOptions.formConfig) {
gridOptions.formConfig.data = XEUtils.clone(defaultData, true);
}
searchEvent();
};
const onSelectChange = () => {
if (xGrid.value) {
const checkedRecords = xGrid.value.getCheckboxRecords();
selectRecords.value = checkedRecords;
selectedRowKeys.value = checkedRecords.map((item) => item.taskId);
multiple.value = !selectedRowKeys.value.length;
}
};
const handleProcess = async (row) => {
isShowDrawer.value = true;
startUser.value = row.startUserName;
taskName.value = row.taskName;
await nextTick(() => {
if (refTodoIndex.value) {
refTodoIndex.value.iniData(row);
} else {
isShowDrawer.value = false;
}
});
};
const handleSuccess = async () => {
isShowDrawer.value = false;
await searchEvent();
};
</script>
<style scoped>
.app-container {
padding: 16px;
width: 100%;
height: 100%;
}
.user-info {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
flex-wrap: nowrap;
}
.user-name {
font-weight: 500;
white-space: nowrap;
}
.dept-tag {
background: #f0f0f0;
color: #666;
padding: 2px 6px;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
}
.version-tag {
background: #1890ff;
color: white;
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
}
/* Vxe Grid 样式调整 */
:deep(.vxe-form--wrapper) {
background: #fafafa;
padding: 16px;
border-radius: 4px;
border: 1px solid #e8e8e8;
margin-bottom: 16px;
}
:deep(.vxe-form--item-title) {
font-weight: 500;
color: #333;
}
:deep(.vxe-grid--wrapper) {
font-family: inherit;
}
:deep(.vxe-grid--header) {
background-color: #fafafa;
}
:deep(.vxe-grid--body) {
background-color: #fff;
}
:deep(.vxe-cell) {
padding: 8px 4px;
}
:deep(.vxe-toolbar) {
background: transparent;
padding: 8px 0;
margin-bottom: 8px;
}
:deep(.vxe-table--render-wrapper) {
border-radius: 4px;
}
</style>
...@@ -153,7 +153,9 @@ const handleConfirm = async () => { ...@@ -153,7 +153,9 @@ const handleConfirm = async () => {
taskId: myTaskFlow.taskId, taskId: myTaskFlow.taskId,
dataId: dataId.value, dataId: dataId.value,
comment: '', comment: '',
values: { approval: assigneeId.value, approvalType: localUserType.value }, values: {
approval: assigneeId.value,
approvalType: localUserType.value },
}) })
} }
} }
......
...@@ -199,7 +199,10 @@ watch(() => props.externalFormData, (newData) => { ...@@ -199,7 +199,10 @@ watch(() => props.externalFormData, (newData) => {
} }
}, { deep: true }) }, { deep: true })
onMounted(() => { resetFormData() }) onMounted(() => {
showHistoryVisible.value = props.showHistoryFormData
resetFormData()
})
defineExpose({ defineExpose({
resetFormData, resetFormData,
......
...@@ -2,6 +2,7 @@ package org.jeecg.modules.stm.baosong.controller; ...@@ -2,6 +2,7 @@ package org.jeecg.modules.stm.baosong.controller;
import java.util.*; import java.util.*;
import dev.langchain4j.internal.Utils;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
...@@ -15,6 +16,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; ...@@ -15,6 +16,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.base.controller.JeecgController; import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.stm.my.entity.MyTaskFlow;
import org.jeecg.modules.stm.my.service.IMyTaskFlowService;
import org.jeecg.modules.stm.problem.entity.StProblemCheck;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
...@@ -45,6 +49,8 @@ public class BaosongTaskController extends JeecgController<BaosongTask, IBaosong ...@@ -45,6 +49,8 @@ public class BaosongTaskController extends JeecgController<BaosongTask, IBaosong
private IBaosongTaskRecordService baosongTaskRecordService; private IBaosongTaskRecordService baosongTaskRecordService;
@Autowired @Autowired
private IBaosongTaskReviewService baosongTaskReviewService; private IBaosongTaskReviewService baosongTaskReviewService;
@Autowired
private IMyTaskFlowService myTaskFlowService;
/** /**
* 分页列表查询 * 分页列表查询
...@@ -65,6 +71,20 @@ public class BaosongTaskController extends JeecgController<BaosongTask, IBaosong ...@@ -65,6 +71,20 @@ public class BaosongTaskController extends JeecgController<BaosongTask, IBaosong
QueryWrapper<BaosongTask> queryWrapper = QueryGenerator.initQueryWrapper(baosongTask, req.getParameterMap()); QueryWrapper<BaosongTask> queryWrapper = QueryGenerator.initQueryWrapper(baosongTask, req.getParameterMap());
queryWrapper.ne("sta",9); queryWrapper.ne("sta",9);
Page<BaosongTask> page = new Page<BaosongTask>(pageNo, pageSize); Page<BaosongTask> page = new Page<BaosongTask>(pageNo, pageSize);
MyTaskFlow myTaskFlow = new MyTaskFlow();
myTaskFlow.setFormTableName("baosong_task");
if(!Utils.isNullOrEmpty(baosongTask.getBpmStatus())){
String bpmStatus = baosongTask.getBpmStatus();
if(bpmStatus.equals("2")) {
if(Utils.isNullOrEmpty(baosongTask.getTodoList())) {
return Result.OK();
}
queryWrapper.in("proc_ins_id",baosongTask.getTodoList());
}
}
IPage<BaosongTask> pageList = baosongTaskService.page(page, queryWrapper); IPage<BaosongTask> pageList = baosongTaskService.page(page, queryWrapper);
setStaValue (baosongTask,pageList.getRecords()); setStaValue (baosongTask,pageList.getRecords());
return Result.OK(pageList); return Result.OK(pageList);
......
...@@ -101,7 +101,7 @@ public class BaosongTask implements Serializable { ...@@ -101,7 +101,7 @@ public class BaosongTask implements Serializable {
// 当前用户需要处理的工作流 实例ID // 当前用户需要处理的工作流 实例ID
@TableField(exist = false) @TableField(exist = false)
private java.util.List todolist; private java.util.List todoList;
/**流程状态*/ /**流程状态*/
private java.lang.String bpmStatus; private java.lang.String bpmStatus;
/**部署ID*/ /**部署ID*/
...@@ -114,4 +114,7 @@ public class BaosongTask implements Serializable { ...@@ -114,4 +114,7 @@ public class BaosongTask implements Serializable {
/**UID*/ /**UID*/
private java.lang.String uid; private java.lang.String uid;
/**flowtaskName*/
private java.lang.String flowtaskName;
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论