xiaweibo hai 2 meses
pai
achega
23625d56ce

+ 159 - 6
src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage/components/detail.vue

@@ -165,11 +165,61 @@
         </el-button>
       </template>
     </el-dialog>
+
+    <!-- 选择审核人:点击提交时弹出 -->
+    <el-dialog
+      v-model="showApproverDialog"
+      title="选择审核人"
+      width="480px"
+      destroy-on-close
+      @close="resetApproverForm"
+    >
+      <el-form ref="approverFormRef" :model="approverForm" :rules="approverFormRules" label-width="100px">
+        <el-form-item label="部门名称" prop="deptId" required>
+          <el-select
+            v-model="approverForm.deptId"
+            placeholder="选择审核部门名称"
+            clearable
+            filterable
+            style="width: 100%"
+            @change="onApproverDeptChange"
+          >
+            <el-option
+              v-for="item in deptOptions"
+              :key="item.id"
+              :label="item.deptName"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="部门审核人" prop="approverId" required>
+          <el-select
+            v-model="approverForm.approverId"
+            placeholder="选择部门审核人"
+            clearable
+            filterable
+            style="width: 100%"
+            :disabled="!approverForm.deptId"
+          >
+            <el-option
+              v-for="item in approverOptions"
+              :key="item.id"
+              :label="item.realname"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="showApproverDialog = false">取消</el-button>
+        <el-button type="primary" :loading="submitting" @click="handleApproverSave">保存</el-button>
+      </template>
+    </el-dialog>
   </main>
   <footer class="safety-platform-container__footer">
     <el-button @click="router.back()">返回</el-button>
     <template v-if="isCreateMode || isEditMode">
-      <el-button type="primary" :loading="submitting" @click="handleSubmit">
+      <el-button type="primary" :loading="submitting" @click="onPrimaryClick">
         {{ isCreateMode ? '提交' : '保存' }}
       </el-button>
     </template>
@@ -203,8 +253,13 @@
     type PurchaseApplyItem,
     type PpePurchaseApplyDetail,
     type SavePpePurchaseApplyReq,
+    type ApprovalInfoItem,
   } from '@/api/production-safety/personal-protective-equipment-purchase-apply';
   import type { QueryPageRequest } from '@/types/basic-query';
+  import { getAllDepartments } from '@/api/auth/dept';
+  import type { DeptTree } from '@/types/dept/type';
+  import { getUserList } from '@/api/system/user-operate';
+  import type { UserLisItem } from '@/api/system/user-operate';
 
   const router = useRouter();
   const route = useRoute();
@@ -214,6 +269,19 @@
   const showRejectDialog = ref(false);
   const rejectReason = ref('');
 
+  const showApproverDialog = ref(false);
+  const approverFormRef = ref<FormInstance>();
+  const approverForm = reactive<{ deptId: number | null; approverId: number | null }>({
+    deptId: null,
+    approverId: null,
+  });
+  const approverFormRules: FormRules = {
+    deptId: [{ required: true, message: '请选择审核部门名称', trigger: 'change' }],
+    approverId: [{ required: true, message: '请选择部门审核人', trigger: 'change' }],
+  };
+  const deptOptions = ref<{ id: number; deptName: string }[]>([]);
+  const approverOptions = ref<UserLisItem[]>([]);
+
   const operate = computed(() => (route.query.operate as string) || 'inventory-create');
   const currentId = computed(() => Number(route.query.id));
   /** 从列表带入的申请单号/申请人/部门(无主表查询接口时用于展示) */
@@ -341,15 +409,19 @@
     form.itemList.splice(index, 1);
   }
 
+  /** 劳防用品名称下拉:使用 queryPersonalProtectiveEquipmentList,名称用 ppeName */
   async function loadPpeOptions() {
     try {
       const res = await queryPersonalProtectiveEquipmentList({
         pageNumber: 1,
         pageSize: 500,
-        queryParam: {  },
+        queryParam: {},
       } as QueryPageRequest<any>);
       const list = res?.records ?? res?.list ?? [];
-      ppeOptions.value = list as PersonalProtectiveEquipment[];
+      ppeOptions.value = (list as PersonalProtectiveEquipment[]).map((item) => ({
+        ...item,
+        ppeName: item.ppeName ?? (item as any).name ?? '',
+      }));
     } catch (e) {
       console.error('加载劳防用品列表失败:', e);
     }
@@ -371,7 +443,7 @@
     }
   }
 
-  function buildSubmitPayload(): SavePpePurchaseApplyReq {
+  function buildSubmitPayload(extra?: { approvalInfoList?: ApprovalInfoItem[]; approvalDescription?: string }): SavePpePurchaseApplyReq {
     const ppePurchaseApplyDetails = form.itemList
       .filter((it) => it.ppeName || it.equipmentName)
       .map((it) => itemToDetail(it));
@@ -382,19 +454,85 @@
       deptName: mainFromQuery.value.deptName,
       saveOrSubmit: isCreateMode.value ? 1 : 0,
       ppePurchaseApplyDetails,
+      ...extra,
     };
   }
 
-  async function handleSubmit() {
+  /** 扁平化部门树为选项列表 */
+  function flattenDeptTree(nodes: DeptTree[], result: { id: number; deptName: string }[] = []): { id: number; deptName: string }[] {
+    if (!nodes?.length) return result;
+    for (const node of nodes) {
+      if (node.id != null && node.deptName) result.push({ id: node.id, deptName: node.deptName });
+      if (node.children?.length) flattenDeptTree(node.children, result);
+    }
+    return result;
+  }
+
+  async function loadDeptOptions() {
+    try {
+      const res = await getAllDepartments();
+      const tree = (Array.isArray(res) ? res : res?.children) ?? [];
+      const list = tree.length && tree[0]?.children ? tree[0].children : tree;
+      deptOptions.value = flattenDeptTree(list as DeptTree[]);
+    } catch (e) {
+      console.error('加载部门列表失败:', e);
+    }
+  }
+
+  async function onApproverDeptChange(deptId: number | null) {
+    approverForm.approverId = null;
+    approverOptions.value = [];
+    if (!deptId) return;
+    try {
+      const res = await getUserList({
+        pageNumber: 1,
+        pageSize: 500,
+        queryParam: { deptId },
+      });
+      approverOptions.value = res?.records ?? [];
+    } catch (e) {
+      console.error('加载部门审核人失败:', e);
+    }
+  }
+
+  function resetApproverForm() {
+    approverForm.deptId = null;
+    approverForm.approverId = null;
+    approverOptions.value = [];
+  }
+
+  /** 点击底部「提交」:先校验表单,再弹出选择审核人 */
+  async function openApproverDialog() {
     const valid = await formRef.value?.validate().catch(() => false);
     if (!valid) return;
     if (!form.itemList.length || form.itemList.every((it) => !it.ppeName && !it.equipmentName)) {
       ElMessage.warning('请至少填写一条劳防用品明细');
       return;
     }
+    showApproverDialog.value = true;
+    if (!deptOptions.value.length) await loadDeptOptions();
+  }
+
+  /** 弹窗内点击「保存」:校验审核人后带审批信息提交 */
+  async function handleApproverSave() {
+    const valid = await approverFormRef.value?.validate().catch(() => false);
+    if (!valid) return;
+    const approvalInfoList: ApprovalInfoItem[] = [
+      { approvalOrder: 1, approverIdList: String(approverForm.approverId) },
+    ];
+    const payload = buildSubmitPayload({
+      approvalInfoList,
+      approvalDescription: '',
+    });
+    await doSubmit(payload);
+    showApproverDialog.value = false;
+    resetApproverForm();
+  }
+
+  /** 实际提交请求(新增/编辑) */
+  async function doSubmit(payload: SavePpePurchaseApplyReq) {
     submitting.value = true;
     try {
-      const payload = buildSubmitPayload();
       if (isCreateMode.value) {
         await savePurchaseApply(payload);
         ElMessage.success('提交成功');
@@ -411,6 +549,21 @@
     }
   }
 
+  /** 底部主按钮:新增时弹出选择审核人,编辑时直接保存 */
+  async function onPrimaryClick() {
+    if (isCreateMode.value) {
+      await openApproverDialog();
+    } else {
+      const valid = await formRef.value?.validate().catch(() => false);
+      if (!valid) return;
+      if (!form.itemList.length || form.itemList.every((it) => !it.ppeName && !it.equipmentName)) {
+        ElMessage.warning('请至少填写一条劳防用品明细');
+        return;
+      }
+      await doSubmit(buildSubmitPayload());
+    }
+  }
+
   async function handleAuditPass() {
     if (!currentId.value) return;
     auditSubmitting.value = true;