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

问题管理工作流

上级 000b6ae6
......@@ -198,3 +198,9 @@ export function getNodesByTableName(tableName) {
})
}
export function addMyTaskFlow(data) {
return defHttp.post({
url: '//my/myTaskFlow/add',
data: data
})
}
<!-- TaskAssigneeDrawer.vue -->
<template>
<a-drawer
:title="title"
......@@ -14,7 +13,6 @@
<div class="drawer-content">
<div class="assignee-section">
<a-card :title="assigneeTitle" :bordered="false" class="assignee-card">
<a-form layout="vertical" ref="formRef">
<a-form-item label="用户类型" required>
<a-radio-group v-model:value="localUserType" @change="handleUserTypeChange" disabled>
......@@ -27,14 +25,13 @@
</a-radio-group>
</a-form-item>
<!-- 用户选择区域 -->
<!-- 用户选择区域 - 未选择时显示选择器 -->
<a-form-item
v-if="localUserType === 'user' && !userAssigneeId"
label="选择用户"
:required="required"
:validate-status="userValidateStatus"
:help="userValidateHelp"
:key="'user-form-item-' + userAssigneeId"
>
<div class="assignee-selector">
<a-input
......@@ -58,22 +55,31 @@
</a-button>
</div>
</a-form-item>
已经指定用户:
<div v-if="localUserType === 'user' && userAssigneeId" class="assignee-info">
<!-- 已指定用户信息展示 -->
<div v-if="localUserType === 'user' && userAssigneeId" class="assignee-info-wrapper">
<div class="assignee-info-label">已指定用户:</div>
<a-descriptions :column="1" size="small" bordered>
<a-descriptions-item label="ID">{{ userAssigneeId }}</a-descriptions-item>
<a-descriptions-item label="名称">{{ userName }}</a-descriptions-item>
<a-descriptions-item label="用户ID">{{ userAssigneeId }}</a-descriptions-item>
<a-descriptions-item label="用户名称">{{ userName || '--' }}</a-descriptions-item>
</a-descriptions>
<!-- <a-button
type="link"
size="small"
@click="clearAssignee"
class="change-btn"
>
重新选择
</a-button> -->
</div>
<!-- 角色选择区域 -->
<!-- 角色选择区域 - 未选择时显示选择器 -->
<a-form-item
v-if="localUserType === 'role'"
v-if="localUserType === 'role' && !roleAssigneeId"
label="选择角色"
:required="required"
:validate-status="roleValidateStatus"
:help="roleValidateHelp"
:key="'role-form-item-' + roleAssigneeId"
>
<div class="assignee-selector">
<a-input
......@@ -98,11 +104,21 @@
</div>
</a-form-item>
<div v-if="localUserType === 'role' && roleAssigneeId" class="assignee-info">
<!-- 已指定角色信息展示 -->
<div v-if="localUserType === 'role' && roleAssigneeId" class="assignee-info-wrapper">
<div class="assignee-info-label">已指定角色:</div>
<a-descriptions :column="1" size="small" bordered>
<a-descriptions-item label="角色ID">{{ roleAssigneeId }}</a-descriptions-item>
<a-descriptions-item label="角色名称">{{ roleName }}</a-descriptions-item>
<a-descriptions-item label="角色名称">{{ roleName || '--' }}</a-descriptions-item>
</a-descriptions>
<!-- <a-button
type="link"
size="small"
@click="clearAssignee"
class="change-btn"
>
重新选择
</a-button> -->
</div>
</a-form>
......@@ -136,7 +152,7 @@
</template>
<script lang="ts" setup>
import { ref, computed, watch } from 'vue'
import { ref, computed, watch, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { useModal } from '/@/components/Modal'
import {
......@@ -146,8 +162,7 @@ import {
} from '@ant-design/icons-vue'
import UserSelectModal from '/@/components/Form/src/jeecg/components/modal/UserSelectModal.vue'
import RoleSelectModal from '/@/components/Form/src/jeecg/components/modal/RoleSelectModal.vue'
import { complete,getMyTaskFlow} from '/@/components/Process/api/todo';
import { complete, getMyTaskFlow } from '/@/components/Process/api/todo'
const props = defineProps({
// 抽屉基础配置
......@@ -171,7 +186,6 @@ const props = defineProps({
type: Boolean,
default: true
},
formData: {
type: Object,
default: () => ({})
......@@ -199,6 +213,18 @@ const props = defineProps({
required: {
type: Boolean,
default: true
},
beforeFlowNode: {
type: Object,
default: () => ({})
},
currentFlowNode: {
type: Object,
default: () => ({})
},
nextFlowNode: {
type: Object,
default: () => ({})
}
})
......@@ -213,7 +239,6 @@ const emit = defineEmits([
const [registerSelUserModal, { openModal: userOpenModal }] = useModal()
const [registerSelRoleModal, { openModal: roleOpenModal }] = useModal()
// 独立的状态变量
const localUserType = ref<'user' | 'role'>('user')
const userAssigneeId = ref('')
const userName = ref('')
......@@ -222,29 +247,60 @@ const roleName = ref('')
const confirmLoading = ref(false)
// 初始化数据
/**
* 初始化数据 - 修复核心问题
*/
const initData = () => {
console.log('initData called, assignee:', props.assignee, 'userType:', props.userType)
// 清空现有数据
userAssigneeId.value = ''
userName.value = ''
roleAssigneeId.value = ''
roleName.value = ''
if (props.assignee) {
// 根据 userType 决定显示类型
if (props.userType === 'role') {
localUserType.value = 'role'
userAssigneeId.value = ''
userName.value = ''
roleAssigneeId.value = props.assignee
// 如果有 name 属性可以传入,但当前 props 没有,可以后续扩展
} else {
localUserType.value = 'user'
userAssigneeId.value = props.assignee
roleName.value = ''
// 如果有 name 属性可以传入,但当前 props 没有,可以后续扩展
}
} else {
// 没有 assignee 时使用默认类型
localUserType.value = props.userType === 'role' ? 'role' : 'user'
userAssigneeId.value = ''
userName.value = ''
roleAssigneeId.value = ''
roleName.value = ''
}
console.log('initData result:', {
localUserType: localUserType.value,
userAssigneeId: userAssigneeId.value,
roleAssigneeId: roleAssigneeId.value
})
}
/**
* 设置用户信息(供外部调用,用于传入用户名)
*/
const setUserInfo = (userId: string, userNameValue: string) => {
userAssigneeId.value = userId
userName.value = userNameValue
localUserType.value = 'user'
}
/**
* 设置角色信息(供外部调用,用于传入角色名)
*/
const setRoleInfo = (roleId: string, roleNameValue: string) => {
roleAssigneeId.value = roleId
roleName.value = roleNameValue
localUserType.value = 'role'
}
// 表单验证状态
const userValidateStatus = computed(() => {
if (!props.required) return ''
if (localUserType.value !== 'user') return ''
......@@ -265,7 +321,6 @@ const roleValidateHelp = computed(() =>
roleValidateStatus.value === 'error' ? '请选择角色' : ''
)
function handleUserTypeChange() {
clearAssignee()
}
......@@ -282,7 +337,7 @@ function handleSelectRole() {
function onSelectUserOk(options: any[], values: any[]) {
if (!values || values.length === 0) return
userAssigneeId.value = values[0]
userName.value = options[0].label
userName.value = options[0]?.label || ''
localUserType.value = 'user'
}
......@@ -290,7 +345,7 @@ function onSelectUserOk(options: any[], values: any[]) {
function onSelectRoleOk(options: any[], values: any[]) {
if (!values || values.length === 0) return
roleAssigneeId.value = values[0]
roleName.value = options[0].label
roleName.value = options[0]?.label || ''
localUserType.value = 'role'
}
......@@ -355,60 +410,78 @@ function getAssigneeData() {
}
}
watch(() => props.visible, (newVal) => {
if (newVal) {
initData()
} else {
resetDrawer()
}
})
watch(() => props.assignee, () => {
if (props.visible) {
initData()
}
}, { deep: true })
const handleSendTask = async () => {
try {
const submitData = {
instanceId: "",deployId: "",taskId: "",
comment: '',values: {},
approval: '', approvalType: '',
};
submitData.values['approval'] = localUserType.value === 'user' ? userAssigneeId.value : roleAssigneeId.value;
submitData.values['approvalType'] = localUserType.value === 'user' ? 'user' : 'role';
const dataId = props.formData.id || '';
instanceId: "",
deployId: "",
taskId: "",
comment: '',
values: {},
approval: '',
approvalType: '',
}
submitData.values['approval'] = localUserType.value === 'user' ? userAssigneeId.value : roleAssigneeId.value
submitData.values['approvalType'] = localUserType.value === 'user' ? 'user' : 'role'
const dataId = props.formData.id || ''
if (dataId) {
try {
const myTaskFlow = await getMyTaskFlow({ deploymentId: props.deployId, dataId: dataId });
console.log('获取流程任务信息:', myTaskFlow);
const myTaskFlow = await getMyTaskFlow({ deploymentId: props.deployId, dataId: dataId })
console.log('获取流程任务信息88888888888888888:', myTaskFlow)
if (myTaskFlow?.taskId) {
submitData.taskId = myTaskFlow.taskId;
submitData.deployId = myTaskFlow.deployId;
submitData.instanceId = myTaskFlow.instanceId;
submitData.taskId = myTaskFlow.taskId
submitData.deployId = myTaskFlow.deployId
submitData.instanceId = myTaskFlow.procInsId
}
//await complete(submitData);
await complete(submitData)
emit('success', dataId)
message.success('任务发送成功');
message.success('任务发送成功')
} catch (e) {
console.warn('flowTaskInfo 获取 taskId 失败', e);
console.warn('flowTaskInfo 获取 taskId 失败', e)
throw e // 重新抛出错误,让外层 catch 处理
}
} else {
// 没有 dataId 时的处理
emit('success', null)
message.success('操作成功')
}
} catch (error: any) {
message.error(error.message || '发送任务失败');
} finally {
console.error('handleSendTask error:', error)
throw error
}
}
// 监听 visible 变化
watch(() => props.visible, (newVal) => {
if (newVal) {
initData()
} else {
resetDrawer()
}
}, { immediate: true })
// 监听 assignee 变化
watch(() => props.assignee, () => {
if (props.visible) {
initData()
}
})
// 监听 userType 变化
watch(() => props.userType, () => {
if (props.visible && !props.assignee) {
localUserType.value = props.userType === 'role' ? 'role' : 'user'
}
};
})
defineExpose({
resetDrawer,
getAssigneeData,
submit: handleConfirm
submit: handleConfirm,
setUserInfo,
setRoleInfo
})
</script>
......@@ -520,12 +593,26 @@ defineExpose({
}
}
.assignee-info {
.assignee-info-wrapper {
margin-top: 12px;
padding: 12px;
background-color: #fafbfc;
border-radius: 8px;
.assignee-info-label {
margin-bottom: 8px;
font-weight: 500;
color: #1f2f3d;
}
.change-btn {
margin-top: 8px;
padding-left: 0;
}
:deep(.ant-descriptions) {
.ant-descriptions-item-label {
background-color: #fafbfc;
background-color: #f5f5f5;
width: 80px;
}
}
......
......@@ -11,6 +11,8 @@ enum Api {
deleteBatch = '/problem/stProblemCheckArchive/deleteBatch',
importExcel = '/problem/stProblemCheckArchive/importExcel',
exportXls = '/problem/stProblemCheckArchive/exportXls',
}
/**
* 导出api
......
......@@ -3,7 +3,6 @@
<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>
......@@ -168,16 +167,24 @@
}
async function handleFlow(record: Recordable) {
record['deployId'] = props.nextFlowNode.deployId
record['bmpNodeId'] = props.nextFlowNode.id
record['bpmStatus'] = 2
emit("sendWorkFlow",record)
}
async function handleUpdate(dataId) {
let record = {
bmpNodeId: props.nextFlowNode.id,
deployId: props.nextFlowNode.deployId,
bpmStatus: 2,
id:dataId
}
await saveOrUpdate(record,true).then(res => {
handleSuccess(record)
handleSuccess(null);
})
emit("sendWorkFlow",record)
}
defineExpose({
handleUpdate,
})
</script>
......
......@@ -18,6 +18,9 @@
该节点未配置表单
</div>
</a-tab-pane>
<template #tabBarExtraContent>
<a-button type="primary">查看流程图</a-button>
</template>
</a-tabs>
<WorkFlowFormDrawer
v-model:visible="drawerVisible"
......@@ -60,10 +63,12 @@
<script lang="ts" name="problem-stProblemCheck" setup>
import { ref, nextTick, onMounted, defineAsyncComponent, h } from 'vue';
import { getNodesByTableName } from '/@/components/Process/api/definition';
import { definitionStart, definitionStartByDeployId } from "/@/components/Process/api/definition";
import { definitionStart, definitionStartByDeployId,addMyTaskFlow } from "/@/components/Process/api/definition";
import WorkFlowFormDrawer from '/@/views/common/WorkFlowFormDrawer.vue';
import TaskAssigneeDrawer from '/@/views/common/TaskAssigneeDrawer.vue'
const formTableName = "st_problem_check";
const workflowNodes = ref<any[]>([]);
const activeTab = ref(1);
const dataId = ref('');
......@@ -171,12 +176,30 @@
const handleDefinitionStart = async (data) => {
const formData = { dataId:data.id, dataName: 'id' };
const startResRaw = await definitionStartByDeployId(
currentNode.value?.deployId || '',
);
if (startResRaw?.data?.id) {
dataId.value = startResRaw.data.id;
const deployId = currentNode.value.deployId || '';
const startResRaw = await definitionStartByDeployId(deployId, formData);
alert(JSON.stringify(startResRaw))
let myTaskFlow = {}
if (startResRaw?.procInsId) {
myTaskFlow["taskId"] = startResRaw.taskId;
myTaskFlow["deployId"] = startResRaw.deployId;
myTaskFlow["procInsId"] = startResRaw.instanceId;
myTaskFlow["executionId"] = startResRaw.executionId;
myTaskFlow["procDefId"] = startResRaw.procInsId;
myTaskFlow["targetId"] = data.id;
myTaskFlow["taskDefinitionKey"] = currentNode.value.id;
myTaskFlow["formTableName"] = formTableName;
const attributes = currentNode.value?.attributes || {}
const userTypes = attributes.userType || [];
if (userTypes.length > 0) {
userType.value = userTypes[0].value || '';
if(userType.value==="role"){
myTaskFlow["roleid"] = currentNode.value.assignee;
} else {
myTaskFlow["uid"] = currentNode.value.assignee;
}
}
await addMyTaskFlow(myTaskFlow);
}
}
......@@ -207,7 +230,7 @@
procDefId?: string;
formData?: Record<string, any>;
}) => {
console.log('打开多表单抽屉:', params);
if (params.nodeIndex !== undefined) {
currentMultiFormIndex.value = params.nodeIndex;
} else {
......@@ -276,7 +299,6 @@
}
function handlSendSuccess(dataId: any) {
const currentFormComponent = getCurrentFormComponent();
if (currentFormComponent && typeof currentFormComponent.handleUpdate === 'function') {
currentFormComponent.handleUpdate(dataId);
......@@ -298,8 +320,10 @@
onMounted(async () => {
await nextTick();
try {
const nodes = await getNodesByTableName("st_problem_check");
const nodes = await getNodesByTableName(formTableName);
workflowNodes.value = nodes;
console.log('获取到的节点:', workflowNodes.value);
workflowNodes.value.forEach((node, index) => {
console.log(`节点${index + 1}:`, node.name, 'formListUrl:', node.formListUrl);
});
......
......@@ -65,8 +65,8 @@
emit("callback",record)
}
function handleSendNext(record: Recordable) {
emit("sendWorkFlow",record)
async function handleSendNext(record: Recordable) {
emit("sendWorkFlow",record)
}
function handleSuccess() {
......@@ -87,10 +87,14 @@
}
async function handleUpdate(dataId) {
await saveOrUpdate({
//alert(dataId)
let record = {
bmpNodeId: props.nextFlowNode.id,
id:dataId,
},true).then(res => {
deployId: props.nextFlowNode.deployId,
bpmStatus: 2,
id:dataId
}
await saveOrUpdate(record,true).then(res => {
handleSuccess();
})
}
......
......@@ -54,6 +54,7 @@
let data = getFieldsValue();
let params = Object.assign({}, formData, data);
await saveOrUpdate(params, true);
alert(1)
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论