|
|
@@ -49,7 +49,7 @@
|
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="最少借用天数" prop="condition.min_days">
|
|
|
- <el-input-number v-model="form.condition.min_days" :min="1" controls-position="right" style="width: 100px" />
|
|
|
+ <el-input-number v-model="form.condition.min_days" :min="0" controls-position="right" style="width: 100px" />
|
|
|
<span style="margin-left: 8px">天</span>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
@@ -236,29 +236,29 @@ watch(visible, (v) => emit('update:visible', v));
|
|
|
|
|
|
|
|
|
|
|
|
-const leaderOptions =reactive([]);
|
|
|
+const leaderOptions = reactive<Array<{ id: number; name: string }>>([]);
|
|
|
firstapi.GetCollegeLeadershipList()
|
|
|
-.then(res=>{
|
|
|
- const deviceLeaderData = res.data;
|
|
|
+.then((res: any) => {
|
|
|
+ const deviceLeaderData = res.data || [];
|
|
|
leaderOptions.splice(0, leaderOptions.length, ...deviceLeaderData);
|
|
|
})
|
|
|
-.catch(error => {
|
|
|
+.catch((error: any) => {
|
|
|
// eslint-disable-next-line no-console
|
|
|
console.error("请求失败:", error);
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
-const resdevicelist=reactive([]);
|
|
|
+const resdevicelist = reactive<Array<{ id: number; name: string }>>([]);
|
|
|
firstapi.GetDeviceClassList()
|
|
|
- .then(result => {
|
|
|
- const deviceData = result.data;
|
|
|
+ .then((result: any) => {
|
|
|
+ const deviceData = result.data || [];
|
|
|
// eslint-disable-next-line no-console
|
|
|
console.log("获取到的data值:", deviceData);
|
|
|
// 清空并填充响应式数组
|
|
|
resdevicelist.splice(0, resdevicelist.length, ...deviceData);
|
|
|
})
|
|
|
- .catch(error => {
|
|
|
+ .catch((error: any) => {
|
|
|
// eslint-disable-next-line no-console
|
|
|
console.error("请求失败:", error);
|
|
|
});
|
|
|
@@ -266,7 +266,7 @@ firstapi.GetDeviceClassList()
|
|
|
const defaultRole = () => ({
|
|
|
name: '',
|
|
|
passType: '',
|
|
|
- leaderId: null,
|
|
|
+ leaderId: null as number | string | null,
|
|
|
});
|
|
|
const defaultStep = () => ({
|
|
|
roles: [defaultRole()],
|
|
|
@@ -321,10 +321,10 @@ const formRef = ref();
|
|
|
function generateStepRules() {
|
|
|
form.steps.forEach((step, stepIdx) => {
|
|
|
step.roles.forEach((role, roleIdx) => {
|
|
|
- rules[`steps.${stepIdx}.roles.${roleIdx}.name`] = [
|
|
|
+ (rules as any)[`steps.${stepIdx}.roles.${roleIdx}.name`] = [
|
|
|
{ required: true, message: '请选择角色', trigger: 'change' },
|
|
|
];
|
|
|
- rules[`steps.${stepIdx}.roles.${roleIdx}.passType`] = [
|
|
|
+ (rules as any)[`steps.${stepIdx}.roles.${roleIdx}.passType`] = [
|
|
|
{ required: true, message: '请选择通过条件', trigger: 'change' },
|
|
|
];
|
|
|
});
|
|
|
@@ -332,7 +332,8 @@ function generateStepRules() {
|
|
|
}
|
|
|
|
|
|
|
|
|
-const editId=ref('');
|
|
|
+// 保存步骤ID,用于编辑时更新
|
|
|
+const stepIds = ref<number[]>([]);
|
|
|
|
|
|
watch(
|
|
|
() => props.editData,
|
|
|
@@ -364,20 +365,29 @@ watch(
|
|
|
const workflowSteps = await firstapi.GetInfo(cloned.id);
|
|
|
console.log("workflowSteps",workflowSteps)
|
|
|
if (workflowSteps && workflowSteps.data) {
|
|
|
- editId.value = workflowSteps.data[0].id;
|
|
|
- form.steps = workflowSteps.data.map((step: any) => ({
|
|
|
+ // 按 step_order 排序
|
|
|
+ const sortedSteps = workflowSteps.data.sort((a: any, b: any) => (a.step_order || 0) - (b.step_order || 0));
|
|
|
+ // 保存步骤ID
|
|
|
+ stepIds.value = sortedSteps.map((step: any) => step.id);
|
|
|
+ form.steps = sortedSteps.map((step: any) => ({
|
|
|
roles: [{
|
|
|
name: step.step_name || '',
|
|
|
passType: String(step.step_type ?? '1'),
|
|
|
- leaderId:step.app_approver_names.join(",")||null,
|
|
|
+ leaderId: step.app_approvers && step.app_approvers.length > 0
|
|
|
+ ? (Array.isArray(step.app_approvers) ? step.app_approvers[0] : step.app_approvers)
|
|
|
+ : (step.app_approver_names && step.app_approver_names.length > 0
|
|
|
+ ? step.app_approver_names[0]
|
|
|
+ : null),
|
|
|
}],
|
|
|
}));
|
|
|
} else {
|
|
|
+ stepIds.value = [];
|
|
|
form.steps = [defaultStep()];
|
|
|
}
|
|
|
|
|
|
generateStepRules();
|
|
|
} else {
|
|
|
+ stepIds.value = [];
|
|
|
form.name = '';
|
|
|
form.scene = '';
|
|
|
form.workflow_type = "0";
|
|
|
@@ -437,39 +447,38 @@ async function onSave() {
|
|
|
|
|
|
const isEditMode = !!props.editData;
|
|
|
|
|
|
- // 组装接口需要的数据
|
|
|
- const payload = {
|
|
|
+ // 组装流程接口需要的数据
|
|
|
+ const workflowPayload = {
|
|
|
name: form.name,
|
|
|
workflow_type: form.workflow_type,
|
|
|
description: form.description,
|
|
|
is_active: typeof form.is_active === 'boolean' ? form.is_active : true,
|
|
|
trigger_conditions: {
|
|
|
- min_days: form.condition?.min_days,
|
|
|
- max_days: form.condition?.max_days,
|
|
|
- equipment_categories: form.condition?.equipment ? [form.condition.equipment] : ['贵重设备'],
|
|
|
- borrow_types: form.condition?.borrow_types?.length ? form.condition.borrow_types : ['0', '1', '2'],
|
|
|
- team_type: form.condition?.team_type?.length ? form.condition.team_type : ['0', '1'],
|
|
|
- user_types: form.condition?.roles?.length ? form.condition.roles:['student', 'teacher'],
|
|
|
- require_approval:true
|
|
|
+ min_days: form.condition?.min_days ?? 0,
|
|
|
+ max_days: form.condition?.max_days ?? null,
|
|
|
+ equipment_categories: form.condition?.equipment ? [form.condition.equipment] : [],
|
|
|
+ borrow_types: form.condition?.borrow_types?.length ? form.condition.borrow_types : [],
|
|
|
+ team_type: form.condition?.team_type?.length ? form.condition.team_type : [],
|
|
|
+ user_types: form.condition?.roles?.length ? form.condition.roles : [],
|
|
|
+ require_approval: true
|
|
|
},
|
|
|
};
|
|
|
|
|
|
- let workflowId = '';
|
|
|
- // eslint-disable-next-line no-console
|
|
|
- // console.log(payload);
|
|
|
+ let workflowId: number | string = '';
|
|
|
+
|
|
|
+ // 1. 先更新或创建流程
|
|
|
if (isEditMode) {
|
|
|
- console.log(editId.value);
|
|
|
- const editRes = await api.UpdateObj(editId.value, payload);
|
|
|
- workflowId = editId.value;
|
|
|
+ workflowId = props.editData.id;
|
|
|
+ const editRes = await api.UpdateObj(Number(workflowId), workflowPayload);
|
|
|
// eslint-disable-next-line no-console
|
|
|
- console.log(editRes);
|
|
|
+ console.log('流程更新结果:', editRes);
|
|
|
if (!editRes || editRes.code !== 2000) {
|
|
|
- ElMessage.error('编辑流程失败');
|
|
|
+ ElMessage.error(editRes?.msg || '编辑流程失败');
|
|
|
return;
|
|
|
}
|
|
|
- }else{
|
|
|
- //创建审批
|
|
|
- const res = await api.AddObj(payload);
|
|
|
+ } else {
|
|
|
+ // 创建新流程
|
|
|
+ const res = await api.AddObj(workflowPayload);
|
|
|
workflowId = res?.data?.id;
|
|
|
if (!workflowId) {
|
|
|
ElMessage.error('新增未能获取流程 ID');
|
|
|
@@ -477,27 +486,36 @@ async function onSave() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+ // 2. 处理步骤:更新现有步骤,创建新步骤
|
|
|
for (let i = 0; i < form.steps.length; i++) {
|
|
|
const step = form.steps[i];
|
|
|
const stepOrder = i + 1;
|
|
|
|
|
|
const roleNames = step.roles.map(role => role.name).filter(Boolean);
|
|
|
const passTypes = step.roles.map(role => role.passType).filter(Boolean);
|
|
|
- const leaderIds = step.roles.map(role => role.leaderId).filter(Boolean);
|
|
|
+ const leaderIds = step.roles
|
|
|
+ .map(role => role.leaderId)
|
|
|
+ .filter((id): id is number | string => Boolean(id))
|
|
|
+ .map((id: number | string) => {
|
|
|
+ // 如果是字符串(逗号分隔),转换为数组
|
|
|
+ if (typeof id === 'string' && id.includes(',')) {
|
|
|
+ return id.split(',').map((n: string) => parseInt(n.trim())).filter((n: number) => !isNaN(n));
|
|
|
+ }
|
|
|
+ return typeof id === 'number' ? [id] : [parseInt(String(id))].filter((n: number) => !isNaN(n));
|
|
|
+ })
|
|
|
+ .flat();
|
|
|
|
|
|
const stepType = passTypes[0] || '1';
|
|
|
|
|
|
const approverRoles = roleNames.map(name => roleNameToId[name]).filter(Boolean);
|
|
|
|
|
|
- const stepPayload = {
|
|
|
- workflow: String(workflowId),
|
|
|
- step_name: `${roleNames.join(',')}审批`,
|
|
|
+ const stepPayload: any = {
|
|
|
+ step_name: roleNames.join(',') || `审批步骤${stepOrder}`,
|
|
|
step_order: stepOrder,
|
|
|
step_type: stepType,
|
|
|
description: `由${roleNames.join(',')}进行审批`,
|
|
|
approvers: [1],
|
|
|
- app_approvers:leaderIds.length > 0 ? leaderIds : [],
|
|
|
+ app_approvers: leaderIds.length > 0 ? leaderIds : [],
|
|
|
approver_roles: approverRoles,
|
|
|
approver_depts: [],
|
|
|
approval_conditions: {
|
|
|
@@ -507,16 +525,54 @@ async function onSave() {
|
|
|
timeout_hours: 24,
|
|
|
timeout_action: "auto_reject",
|
|
|
is_active: true
|
|
|
- };
|
|
|
+ };
|
|
|
|
|
|
- // eslint-disable-next-line no-console
|
|
|
- console.log(`步骤 ${stepOrder} payload`, stepPayload);
|
|
|
+ // eslint-disable-next-line no-console
|
|
|
+ console.log(`步骤 ${stepOrder} payload`, stepPayload);
|
|
|
+
|
|
|
if (isEditMode) {
|
|
|
- await api.UpdateFirstObj(props.editData.id,stepPayload);
|
|
|
- }else{
|
|
|
- await api.AddFirstObj(stepPayload);
|
|
|
+ // 编辑模式:如果该位置有现有步骤ID,则更新;否则创建新步骤
|
|
|
+ const existingStepId = stepIds.value[i];
|
|
|
+ if (existingStepId) {
|
|
|
+ // 更新现有步骤
|
|
|
+ const updateRes = await api.UpdateFirstObj(existingStepId, stepPayload);
|
|
|
+ if (!updateRes || updateRes.code !== 2000) {
|
|
|
+ ElMessage.error(`更新步骤${stepOrder}失败: ${updateRes?.msg || '未知错误'}`);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 创建新步骤(用户新增了步骤)
|
|
|
+ stepPayload.workflow = workflowId;
|
|
|
+ const addRes = await api.AddFirstObj(stepPayload);
|
|
|
+ if (!addRes || addRes.code !== 2000) {
|
|
|
+ ElMessage.error(`创建步骤${stepOrder}失败: ${addRes?.msg || '未知错误'}`);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 新增模式:创建步骤
|
|
|
+ stepPayload.workflow = workflowId;
|
|
|
+ const addRes = await api.AddFirstObj(stepPayload);
|
|
|
+ if (!addRes || addRes.code !== 2000) {
|
|
|
+ ElMessage.error(`创建步骤${stepOrder}失败: ${addRes?.msg || '未知错误'}`);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 如果编辑模式下步骤数量减少了,需要删除多余的步骤
|
|
|
+ if (isEditMode && stepIds.value.length > form.steps.length) {
|
|
|
+ // 删除多余的步骤(从后往前删除)
|
|
|
+ for (let i = form.steps.length; i < stepIds.value.length; i++) {
|
|
|
+ const stepIdToDelete = stepIds.value[i];
|
|
|
+ try {
|
|
|
+ await api.DelFirstObj(stepIdToDelete as any);
|
|
|
+ } catch (error: any) {
|
|
|
+ // eslint-disable-next-line no-console
|
|
|
+ console.warn(`删除步骤失败 (ID: ${stepIdToDelete}):`, error);
|
|
|
+ // 不阻断主流程,继续执行
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
ElMessage.success('保存成功');
|