Просмотр исходного кода

Merge branch 'feat/production-safety' of http://14.103.151.10:8888/product-group-fe/sfy-safety-group/sfy-safety into feat/production-safety

sunqijun 1 месяц назад
Родитель
Сommit
57b4940841
15 измененных файлов с 2200 добавлено и 12 удалено
  1. 16 1
      src/router/routers/production-safety-router/risk-identification-and-control.ts
  2. 21 7
      src/router/routers/production-safety-router/safetyAssessment.ts
  3. 45 0
      src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/Item.vue
  4. 1005 0
      src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/components/detail.vue
  5. 85 0
      src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/configs/constant.ts
  6. 68 0
      src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/configs/form.ts
  7. 58 0
      src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/configs/tables.ts
  8. 58 0
      src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/configs/tablesTow.ts
  9. 3 3
      src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage/listAdmin.vue
  10. 524 0
      src/views/production-safety/safetyAssessment/receiptRecordAdministratorReview/components/ReceiptRecordDetail.vue
  11. 107 0
      src/views/production-safety/safetyAssessment/receiptRecordAdministratorReview/configs/form.ts
  12. 30 0
      src/views/production-safety/safetyAssessment/receiptRecordAdministratorReview/configs/status.ts
  13. 127 0
      src/views/production-safety/safetyAssessment/receiptRecordAdministratorReview/configs/tables.ts
  14. 1 1
      src/views/production-safety/safetyAssessment/receiptRecord/receiptRecordAdministratorReview.vue
  15. 52 0
      src/views/production-safety/safetyAssessment/receiptRecordAdministratorReview/receiptRecordItem.vue

+ 16 - 1
src/router/routers/production-safety-router/risk-identification-and-control.ts

@@ -631,7 +631,7 @@ const riskIdentificationAndControlRoutes: RouteComponent[] = [{
       parentId: 90014,
       parentId: 90014,
       name: 'laborProductsPurchaseApplyManageAdmin',
       name: 'laborProductsPurchaseApplyManageAdmin',
       path: 'labor-products-purchase-apply-manage-admin',
       path: 'labor-products-purchase-apply-manage-admin',
-      component: '/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage/listAdmin',
+      component: '/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/listAdmin',
       meta: {
       meta: {
         title: '劳防用品采购申请(管理员)',
         title: '劳防用品采购申请(管理员)',
         icon: 'OverviewIcon',
         icon: 'OverviewIcon',
@@ -639,6 +639,21 @@ const riskIdentificationAndControlRoutes: RouteComponent[] = [{
         hidden: false,
         hidden: false,
         noCache: false,
         noCache: false,
       }
       }
+    },   
+    {
+      id: 93036,
+      parentId: 90014,
+      name: 'laborProductsPurchaseApplyManageAdminItem',
+      path: 'labor-products-purchase-apply-manage-admin-item',
+      component: '/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/Item',
+      meta: {
+        title: '劳防用品采购申请详情(管理员)',
+        activeMenu: '/work-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin',
+        icon: 'OverviewIcon',
+        isRoot: false,
+        hidden: false,
+        noCache: false,
+      }
     },
     },
     //工伤认定申请
     //工伤认定申请
     {
     {

+ 21 - 7
src/router/routers/production-safety-router/safetyAssessment.ts

@@ -56,12 +56,26 @@
           noCache: false,
           noCache: false,
         },
         },
       },
       },
+      {
+        id: 9002101,
+        parentId: 90021,
+        name: 'ReceiptRecordItem',
+        path: 'receipt-record-item',
+        component: '/production-safety/safetyAssessment/receiptRecord/receiptRecordItem',
+        meta: {
+          title: '物品领取记录详情',
+          icon: 'OverviewIcon',
+          isRoot: false,
+          hidden: true,
+          noCache: false,
+        },
+      },
       {
       {
         id: 9002102,
         id: 9002102,
         parentId: 90021,
         parentId: 90021,
         name: 'ReceiptRecordAdministratorReview',
         name: 'ReceiptRecordAdministratorReview',
         path: 'receipt-record-administrator-review',
         path: 'receipt-record-administrator-review',
-        component: '/production-safety/safetyAssessment/receiptRecord/receiptRecordAdministratorReview',
+        component: '/production-safety/safetyAssessment/receiptRecordAdministratorReview/receiptRecordAdministratorReview',
         meta: {
         meta: {
           title: '物品领取审核列表',
           title: '物品领取审核列表',
           icon: 'OverviewIcon',
           icon: 'OverviewIcon',
@@ -71,13 +85,13 @@
         },
         },
       },
       },
       {
       {
-        id: 9002101,
-        parentId: 90021,
-        name: 'ReceiptRecordItem',
-        path: 'receipt-record-item',
-        component: '/production-safety/safetyAssessment/receiptRecord/receiptRecordItem',
+        id: 9002103,
+        parentId: 9002102,
+        name: 'ReceiptRecordAdministratorReviewDetails',
+        path: 'receipt-record-administrator-review-details',
+        component: '/production-safety/safetyAssessment/receiptRecordAdministratorReview/receiptRecordItem',
         meta: {
         meta: {
-          title: '物品领取记录详情',
+          title: '物品领取审核详情',
           icon: 'OverviewIcon',
           icon: 'OverviewIcon',
           isRoot: false,
           isRoot: false,
           hidden: true,
           hidden: true,

+ 45 - 0
src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/Item.vue

@@ -0,0 +1,45 @@
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <BreadcrumbBack />
+      <span class="breadcrumb-title">{{ headerTitle }}</span>
+    </header>
+    <Detail />
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { computed } from 'vue';
+  import { useRoute } from 'vue-router';
+  import BreadcrumbBack from '@/components/BreadcrumbBack.vue';
+  import Detail from './components/detail.vue';
+
+  const route = useRoute();
+  const operate = (route.query.operate as string) || 'inventory-create';
+
+  const headerTitle = computed(() => {
+    switch (operate) {
+      case 'inventory-create':
+        return '新增劳防用品采购申请';
+      case 'inventory-edit':
+        return '编辑劳防用品采购申请';
+      case 'inventory-view':
+        return '查看劳防用品采购申请';
+      case 'audit':
+        return '审核劳防用品采购申请';
+      default:
+        return '劳防用品采购申请详情';
+    }
+  });
+</script>
+
+<style scoped lang="scss">
+  @use '@/styles/page-details-layout.scss' as *;
+  @use '@/styles/page-main-layout.scss' as *;
+
+  .safety-platform-container__header {
+    flex-direction: row !important;
+    justify-content: flex-start !important;
+    gap: 8px !important;
+  }
+</style>

Разница между файлами не показана из-за своего большого размера
+ 1005 - 0
src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/components/detail.vue


+ 85 - 0
src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/configs/constant.ts

@@ -0,0 +1,85 @@
+export enum EMERGENCY_PLAN_STATUS {
+  UNAPPROVED = 0,
+  APPROVAL_IN_PROGRESS,
+  RETURNED,
+  PUBLISHED,
+}
+
+export const EMERGENCY_PLAN_STATUS_MAP = {
+  [EMERGENCY_PLAN_STATUS.UNAPPROVED]: '未审批',
+  [EMERGENCY_PLAN_STATUS.APPROVAL_IN_PROGRESS]: '预案审批中',
+  [EMERGENCY_PLAN_STATUS.RETURNED]: '预案已退回',
+  [EMERGENCY_PLAN_STATUS.PUBLISHED]: '已公示',
+};
+
+export const EMERGENCY_PLAN_STATUS_OPTIONS = [
+  {
+    label: EMERGENCY_PLAN_STATUS_MAP[EMERGENCY_PLAN_STATUS.UNAPPROVED],
+    value: EMERGENCY_PLAN_STATUS.UNAPPROVED,
+  },
+  {
+    label: EMERGENCY_PLAN_STATUS_MAP[EMERGENCY_PLAN_STATUS.APPROVAL_IN_PROGRESS],
+    value: EMERGENCY_PLAN_STATUS.APPROVAL_IN_PROGRESS,
+  },
+  {
+    label: EMERGENCY_PLAN_STATUS_MAP[EMERGENCY_PLAN_STATUS.RETURNED],
+    value: EMERGENCY_PLAN_STATUS.RETURNED,
+  },
+  {
+    label: EMERGENCY_PLAN_STATUS_MAP[EMERGENCY_PLAN_STATUS.PUBLISHED],
+    value: EMERGENCY_PLAN_STATUS.PUBLISHED,
+  },
+];
+
+export enum APPROVAL_TYPE {
+  COUNTER_SIGN = 0,
+  ORDINARY_SIGN,
+}
+
+export const APPROVAL_TYPE_MAP = {
+  [APPROVAL_TYPE.COUNTER_SIGN]: '会签',
+  [APPROVAL_TYPE.ORDINARY_SIGN]: '或签',
+};
+
+export enum APPROVER_TYPE{
+  FIX = 0,
+  CUSTOM,
+}
+
+export const APPROVER_TYPE_MAP = {
+  [APPROVER_TYPE.FIX]: '固定',
+  [APPROVER_TYPE.CUSTOM]: '自选',
+};
+
+export enum APPROVAL_STATUS {
+  PENDING = 1,
+  APPROVED,
+  REJECTED,
+  OHTER,
+}
+
+export const APPROVAL_STATUS_MAP = {
+  [APPROVAL_STATUS.PENDING]: '待审批',
+  [APPROVAL_STATUS.APPROVED]: '已审批',
+  [APPROVAL_STATUS.REJECTED]: '退回',
+  [APPROVAL_STATUS.OHTER]: '他人已审批',
+};
+
+export const APPROVAL_STATUS_OPTIONS = [
+  {
+    label: APPROVAL_STATUS_MAP[APPROVAL_STATUS.PENDING],
+    value: APPROVAL_STATUS.PENDING,
+  },
+  {
+    label: APPROVAL_STATUS_MAP[APPROVAL_STATUS.APPROVED],
+    value: APPROVAL_STATUS.APPROVED,
+  },
+  {
+    label: APPROVAL_STATUS_MAP[APPROVAL_STATUS.REJECTED],
+    value: APPROVAL_STATUS.REJECTED,
+  },
+  {
+    label: APPROVAL_STATUS_MAP[APPROVAL_STATUS.OHTER],
+    value: APPROVAL_STATUS.OHTER,
+  },
+];

+ 68 - 0
src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/configs/form.ts

@@ -0,0 +1,68 @@
+import { FormConfig } from '@/types/basic-form';
+
+export const INVENTORY_FORM_CONFIG: FormConfig[] = [
+  {
+    prop: 'itemName',
+    label: '物品名称:',
+    component: 'ElInput',
+    componentProps: {
+      placeholder: '请输入物品名称',
+    },
+  },
+  {
+    prop: 'warehouseDate',
+    label: '入库日期:',
+    component: 'ElDatePicker',
+    componentProps: {
+      type: 'date',
+      placeholder: '请选择入库日期',
+      valueFormat: 'YYYY-MM-DD',
+    },
+  },
+  {
+    prop: 'itemQuantity',
+    label: '物品数量:',
+    component: 'ElInputNumber',
+    componentProps: {
+      min: 1,
+      max: 99999,
+      precision: 0, // 不允许小数点,只能输入整数
+      placeholder: '请输入物品数量',
+    },
+  },
+  {
+    label: '备注:',
+    prop: 'remarks',
+    component: 'ElInput',
+    componentProps: {
+      type: 'textarea',
+      rows: 5,
+      placeholder: '请输入备注',
+    },
+  },
+  {
+    prop: 'status',
+    label: '状态:',
+    slot: 'status',
+  },
+];
+
+export const INVENTORY_FORM_DATA = {
+  status: 'ENABLE',
+  itemName: '',
+  warehouseDate: '',
+  itemQuantity: 1, // 最小值为1
+  remarks: '',
+};
+
+export const INVENTORY_FORM_RULES = {
+  status: [{ required: true, message: '请选择状态', trigger: 'change' }],
+  itemName: [{ required: true, message: '请输入物品名称', trigger: 'blur' }],
+  warehouseDate: [{ required: true, message: '请选择入库日期', trigger: 'change' }],
+  itemQuantity: [
+    { required: true, message: '请输入物品数量', trigger: 'blur' },
+    { type: 'number', min: 1, message: '物品数量不能小于1', trigger: 'blur' },
+    { type: 'number', max: 99999, message: '物品数量不能大于99999', trigger: 'blur' },
+  ],
+  status: [{ required: true, message: '请选择状态', trigger: 'change' }],
+};

+ 58 - 0
src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/configs/tables.ts

@@ -0,0 +1,58 @@
+import type { TableColumnProps } from '@/types/basic-table';
+
+const TABLE_OPTIONS = {
+  emptyText: '暂无数据',
+  loading: true,
+  maxHeight: 'calc(70vh - 150px)',
+};
+
+/** 劳防用品采购申请列表列:申请单号、申请人、申请人部门、状态、当前流程节点、操作(后端字段:applyCode, applicantName, deptName, statusName, nodeDescription) */
+const PURCHASE_APPLY_TABLE_COLUMNS: TableColumnProps[] = [
+  {
+    label: '编号',
+    type: 'index',
+    align: 'center',
+    width: '80px',
+  },
+  {
+    label: '申请单号',
+    prop: 'applyCodeDesc',
+    align: 'left',
+    minWidth: '140px',
+  },
+  {
+    label: '申请人',
+    prop: 'applicantName',
+    align: 'left',
+    minWidth: '100px',
+  },
+  {
+    label: '申请部门',
+    prop: 'deptName',
+    align: 'left',
+    minWidth: '140px',
+  },
+  {
+    label: '状态',
+    prop: 'status',
+    slot: 'status',
+    align: 'center',
+    minWidth: '100px',
+  },
+  {
+    label: '当前流程节点',
+    prop: 'ppeDescription',
+    align: 'left',
+    minWidth: '140px',
+  },
+  {
+    label: '操作',
+    prop: 'action',
+    slot: 'action',
+    fixed: 'right',
+    width: '220px',
+    align: 'left',
+  },
+];
+
+export { TABLE_OPTIONS, PURCHASE_APPLY_TABLE_COLUMNS };

+ 58 - 0
src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage-admin/configs/tablesTow.ts

@@ -0,0 +1,58 @@
+import type { TableColumnProps } from '@/types/basic-table';
+
+const TABLE_OPTIONS = {
+  emptyText: '暂无数据',
+  loading: true,
+  maxHeight: 'calc(70vh - 150px)',
+};
+
+/** 劳防用品采购申请列表列:申请单号、申请人、申请人部门、状态、当前流程节点、操作(后端字段:applyCode, applicantName, deptName, statusName, nodeDescription) */
+const PURCHASE_APPLY_TABLE_COLUMNS: TableColumnProps[] = [
+  {
+    label: '编号',
+    type: 'index',
+    align: 'center',
+    width: '80px',
+  },
+  {
+    label: '申请单号',
+    prop: 'applyCode',
+    align: 'left',
+    minWidth: '140px',
+  },
+  {
+    label: '申请人',
+    prop: 'applicantName',
+    align: 'left',
+    minWidth: '100px',
+  },
+  {
+    label: '申请部门',
+    prop: 'deptName',
+    align: 'left',
+    minWidth: '140px',
+  },
+  {
+    label: '状态',
+    prop: 'status',
+    slot: 'status',
+    align: 'center',
+    minWidth: '100px',
+  },
+  {
+    label: '当前流程节点',
+    prop: 'nodeDescription',
+    align: 'left',
+    minWidth: '140px',
+  },
+  {
+    label: '操作',
+    prop: 'action',
+    slot: 'action',
+    fixed: 'right',
+    width: '220px',
+    align: 'left',
+  },
+];
+
+export { TABLE_OPTIONS, PURCHASE_APPLY_TABLE_COLUMNS };

+ 3 - 3
src/views/production-safety/risk-identification-and-control/labor-products-purchase-apply-manage/listAdmin.vue

@@ -1,7 +1,7 @@
 <template>
 <template>
   <div class="safety-platform-container">
   <div class="safety-platform-container">
     <header class="safety-platform-container__header">
     <header class="safety-platform-container__header">
-      <div class="breadcrumb-title">劳防用品采购申请</div>
+      <div class="breadcrumb-title">劳防用品采购申请(管理员)</div>
     </header>
     </header>
     <main class="safety-platform-container__main">
     <main class="safety-platform-container__main">
       <div class="search-table-container">
       <div class="search-table-container">
@@ -234,7 +234,7 @@
 
 
   const handleView = (id: number, row?: PpePurchaseApply) => {
   const handleView = (id: number, row?: PpePurchaseApply) => {
     router.push({
     router.push({
-      name: 'laborProductsPurchaseApplyManageItem',
+      name: 'laborProductsPurchaseApplyManageAdminItem',
       query: {
       query: {
         id: String(id),
         id: String(id),
         operate: 'inventory-view',
         operate: 'inventory-view',
@@ -252,7 +252,7 @@
 
 
   const handleAudit = (id: number, row?: PpePurchaseApply) => {
   const handleAudit = (id: number, row?: PpePurchaseApply) => {
     router.push({
     router.push({
-      name: 'laborProductsPurchaseApplyManageItem',
+      name: 'laborProductsPurchaseApplyManageAdminItem',
       query: {
       query: {
         id: String(id),
         id: String(id),
         operate: 'audit',
         operate: 'audit',

+ 524 - 0
src/views/production-safety/safetyAssessment/receiptRecordAdministratorReview/components/ReceiptRecordDetail.vue

@@ -0,0 +1,524 @@
+<template>
+  <el-alert v-if="currentStatus === -1" :title="ruleFormData.returnReason" type="warning" />
+  <main class="safety-platform-container__main">
+    <BasicForm
+      ref="basicFormRef"
+      :formData="ruleFormData"
+      :formRules="isViewMode || isAuditMode ? undefined : formRules"
+      :formConfig="computedFormConfig"
+    >
+      <template #itemId>
+        <el-select
+          v-model="ruleFormData.itemId"
+          placeholder="请选择奖品名称"
+          filterable
+          clearable
+          :disabled="isViewMode || isAuditMode"
+        >
+          <el-option v-for="item in inventoryList" :key="item.id" :label="item.stuffName" :value="item.id" />
+        </el-select>
+      </template>
+      <template #department>
+        <el-cascader
+          ref="cascaderRef"
+          v-model="ruleFormData.deptId"
+          :options="deptTree"
+          :props="cascaderDeptProp"
+          :show-all-levels="false"
+          placeholder="请选择部门"
+          filterable
+          :disabled="isViewMode || isAuditMode"
+          @change="handleDeptChange"
+        />
+      </template>
+      <template #recipient>
+        <el-select
+          v-model="ruleFormData.recipientUserId"
+          placeholder="请选择领取人"
+          filterable
+          clearable
+          :disabled="isViewMode || isAuditMode"
+          @change="handleRecipientChange"
+        >
+          <el-option v-for="user in recipientUserList" :key="user.id" :label="user.realname" :value="user.id" />
+        </el-select>
+      </template>
+      <template #approvalTemplateId>
+        <el-select
+          v-model="ruleFormData.approvalTemplateId"
+          placeholder="请选择审批流程"
+          filterable
+          clearable
+          :disabled="isViewMode || isAuditMode"
+        >
+          <el-option v-for="item in approvalList" :key="item.id" :label="item.templateName" :value="item.id" />
+        </el-select>
+      </template>
+    </BasicForm>
+  </main>
+  <footer class="safety-platform-container__footer">
+    <el-button @click="router.back()">返回</el-button>
+    <template v-if="isAuditMode">
+      <el-button type="primary" @click="handleAuditPass">同意</el-button>
+      <el-button type="danger" @click="handleAuditReject">拒绝</el-button>
+    </template>
+    <el-button v-else-if="!isViewMode" type="primary" @click="handleSubmit">
+      {{ isCreateMode ? '提交' : '保存' }}
+    </el-button>
+  </footer>
+  <BasicDialog v-if="!isViewMode && !isAuditMode" ref="basicDialogRef" title="提交审批" @refresh="closeApprovalDialog">
+    <template #form>
+      <div class="form">
+        <el-form ref="approvalFormRef" :model="approvalForm">
+          <!-- <el-form-item label="审批描述:" label-position="top">
+            <el-input v-model="approvalForm.description" placeholder="请输入审批描述" type="textarea" />
+          </el-form-item> -->
+          <div class="form-item">
+            <span>审批流程:</span>
+            <template v-for="item in approvalNodeList" :key="item.id">
+              <el-form-item
+                :label="`第${item.approvalOrder}步:${item.nodeDescription}(${APPROVAL_TYPE_MAP[item.approvalType]})`"
+                label-position="top"
+                :prop="item.approverType !== APPROVER_TYPE.FIX ? `approvers.${item.id}` : ''"
+                :rules="{ required: true, message: '请选择审批人员', trigger: 'change' }"
+              >
+                <el-input
+                  v-if="item.approverType === APPROVER_TYPE.FIX"
+                  :model-value="item.approverInfoList.map((info) => info.approverName).join(',')"
+                  disabled
+                />
+                <el-select
+                  v-else
+                  v-model="approvalForm.approvers[item.id]"
+                  placeholder="请选择审批人员"
+                  value-key="id"
+                  filterable
+                  remote
+                  collapse-tags
+                  collapse-tags-tooltip
+                  :max-collapse-tags="2"
+                  :remote-method="remoteMethod"
+                  :loading="loading"
+                  multiple
+                >
+                  <el-option
+                    v-for="option in userOptions"
+                    :key="option.id"
+                    :label="`${option.realname}(${option.username})${option.deptName}`"
+                    :value="option.id"
+                  />
+                </el-select>
+              </el-form-item>
+            </template>
+          </div>
+        </el-form>
+      </div>
+    </template>
+    <template #footer>
+      <el-button type="primary" @click="handleSubmitApproval">提交</el-button>
+      <el-button @click="basicDialogRef?.closeDialog()">取消</el-button>
+    </template>
+  </BasicDialog>
+</template>
+
+<script setup lang="ts">
+  import { computed, onMounted, ref, reactive } from 'vue';
+  import { useRoute, useRouter } from 'vue-router';
+  import { ElMessage, ElAlert } from 'element-plus';
+  import BasicForm from '@/components/BasicForm.vue';
+  import BasicDialog from '@/components/BasicDialog.vue';
+  import { useFormConfigHook } from '@/hooks/useFormConfigHook';
+  import { RECEIPT_RECORD_FORM_CONFIG, RECEIPT_RECORD_FORM_DATA, RECEIPT_RECORD_FORM_RULES } from '../configs/form';
+  import {
+    saveClaimItemsLog,
+    updateClaimItemsLog,
+    queryClaimItemsLogDetail,
+    querInventoryManageList,
+    updateClaimItemsLogAgree,
+    updateClaimItemsLogReject,
+    submitReceiptRecordApprovalProcess,
+  } from '@/api/receiptRecord';
+  import type { InventoryItem } from '@/api/inventory';
+  import { getAllDepartments } from '@/api/auth/dept';
+  import type { DeptTree } from '@/types/dept/type';
+  import { queryAvailableUserList } from '@/api/production-safety/responsibility-implementation';
+  import type { UserLisItem } from '@/api/system/user-operate';
+  import { getAllApproval } from '@/api/approval/approval';
+  import type { ApprovalInstanceType } from '@/views/system/approval/types';
+  import { useEmergencySuppliesHook } from '@/views/emergency/emergency-supplies/src/hook';
+  import type { ApprovalNodeInstanceType } from '@/views/system/approval/types';
+  import { getApprovalNodeInstanceList } from '@/api/approval/approval';
+  import { APPROVAL_TYPE_MAP, APPROVER_TYPE } from '@/views/emergency/emergency-plan/src/constant';
+
+  const router = useRouter();
+  const route = useRoute();
+
+  const operate = computed(() => (route.query.operate as string) || 'receiptRecord-create');
+  const currentId = computed(() => Number(route.query.id));
+
+  const isCreateMode = computed(() => operate.value === 'receiptRecord-create');
+  const isEditMode = computed(() => operate.value === 'receiptRecord-edit');
+  const isViewMode = computed(() => operate.value === 'receiptRecord-view');
+  const isAuditMode = computed(() => operate.value === 'receiptRecord-audit');
+
+  // 当前记录ID(用于提交审批)
+  const receiptRecordId = ref<number>();
+
+  // 部门树(复用添加应急预案的制定部门数据源)
+  const cascaderRef = ref();
+  const deptTree = ref<DeptTree[]>([]);
+  const cascaderDeptProp = {
+    checkStrictly: true,
+    expandTrigger: 'hover' as const,
+    value: 'id',
+    label: 'deptName',
+    emitPath: false,
+  };
+  const getDeptTreeData = async () => {
+    try {
+      const res = await getAllDepartments();
+      deptTree.value = res?.[0]?.children ?? [];
+    } catch (e) {
+      console.error('获取部门树失败:', e);
+    }
+  };
+  const handleDeptChange = () => {
+    const nodes = cascaderRef.value?.getCheckedNodes();
+    ruleFormData.department = nodes?.[0]?.label ?? '';
+    // 部门变化时,重新获取该部门的用户列表
+    if (ruleFormData.deptId) {
+      getRecipientUserList(ruleFormData.department);
+    } else {
+      recipientUserList.value = [];
+      ruleFormData.recipientUserId = null;
+    }
+  };
+  const findDeptIdByName = (nodes: DeptTree[] | undefined, name: string): number | undefined => {
+    if (!nodes?.length) return undefined;
+    for (const n of nodes) {
+      if (n.deptName === name) return n.id ?? undefined;
+      const found = findDeptIdByName(n.children, name);
+      if (found != null) return found;
+    }
+    return undefined;
+  };
+
+  // 领取人用户列表
+  const recipientUserList = ref<UserLisItem[]>([]);
+  const getRecipientUserList = async (deptId: number) => {
+    try {
+      const res = await queryAvailableUserList({
+        pageNumber: 1,
+        pageSize: 9999,
+        queryParam: {
+          deptId,
+        },
+      });
+      if (res && res.records) {
+        recipientUserList.value = res.records;
+      } else {
+        recipientUserList.value = [];
+      }
+    } catch (e) {
+      console.error('获取用户列表失败:', e);
+      recipientUserList.value = [];
+    }
+  };
+
+  const handleRecipientChange = () => {
+    const selectedUser = recipientUserList.value.find((user) => user.id === ruleFormData.recipientUserId);
+    ruleFormData.recipient = selectedUser?.realname ?? '';
+  };
+
+  // 审批流程列表(复用应急预案的审批模板)
+  const approvalList = ref<ApprovalInstanceType[]>([]);
+  const getApprovalList = async () => {
+    try {
+      const res = await getAllApproval();
+      approvalList.value = Array.isArray(res) ? res : [];
+    } catch (e) {
+      console.error('获取审批流程列表失败:', e);
+      approvalList.value = [];
+    }
+  };
+
+  const { ruleFormData, formRules, ruleFormConfig, cloneRuleFormData } = useFormConfigHook(
+    RECEIPT_RECORD_FORM_CONFIG,
+    RECEIPT_RECORD_FORM_DATA,
+    RECEIPT_RECORD_FORM_RULES,
+  );
+
+  // 提交审批弹窗相关
+  const basicDialogRef = ref<InstanceType<typeof BasicDialog>>();
+  const approvalFormRef = ref();
+  const approvalForm = reactive({
+    description: '',
+    approvers: {} as Record<number, any[]>,
+  });
+
+  const approvalNodeList = ref<ApprovalNodeInstanceType[]>([]);
+
+  const { userOptions, loading, remoteMethod } = useEmergencySuppliesHook();
+
+  const getApprovalNode = async (id: number) => {
+    const res = await getApprovalNodeInstanceList(id);
+    approvalNodeList.value = res.approvalNodeInfoList || [];
+  };
+
+  const resetApprovalForm = () => {
+    approvalFormRef.value?.resetFields();
+    approvalForm.description = '';
+  };
+
+  const closeApprovalDialog = () => {
+    resetApprovalForm();
+    basicDialogRef.value?.closeDialog();
+  };
+
+  // 奖品库存列表
+  const inventoryList = ref<InventoryItem[]>([]);
+
+  // 当前记录状态(用于控制“审核不通过原因”字段显示)
+  const currentStatus = ref<number | undefined>();
+
+  // 查看 / 审核模式下,所有字段设为只读
+  const viewFormConfig = ref(
+    RECEIPT_RECORD_FORM_CONFIG.map((item) => ({
+      ...item,
+      componentProps: {
+        ...item.componentProps,
+        disabled: true,
+      },
+    })),
+  );
+
+  const computedFormConfig = computed(() => {
+    // 新增时不展示“审核不通过原因”字段
+    if (isCreateMode.value) {
+      return ruleFormConfig.value.filter((item) => item.prop !== 'returnReason');
+    }
+
+    // 查看模式:仅在“审核不通过”时展示“审核不通过原因”字段
+    if (isViewMode.value) {
+      if (currentStatus.value === -1) {
+        return viewFormConfig.value;
+      }
+      return viewFormConfig.value.filter((item) => item.prop !== 'returnReason');
+    }
+
+    // 编辑模式:仅在“审核不通过”时展示“审核不通过原因”字段
+    if (isEditMode.value) {
+      if (currentStatus.value === -1) {
+        return ruleFormConfig.value;
+      }
+      return ruleFormConfig.value.filter((item) => item.prop !== 'returnReason');
+    }
+
+    // 审核模式:不展示“审核不通过原因”字段
+    if (isAuditMode.value) {
+      return viewFormConfig.value.filter((item) => item.prop !== 'returnReason');
+    }
+
+    return ruleFormConfig.value;
+  });
+
+  const basicFormRef = ref<InstanceType<typeof BasicForm>>();
+
+  // 获取奖品库存列表
+  const getInventoryList = async () => {
+    try {
+      const res = await querInventoryManageList();
+      if (res) {
+        if (Array.isArray(res)) {
+          inventoryList.value = res;
+        } else if (res && typeof res === 'object' && 'data' in res && Array.isArray(res.data)) {
+          inventoryList.value = res.data;
+        } else {
+          inventoryList.value = res as InventoryItem[];
+        }
+      }
+    } catch (e) {
+      console.error('获取奖品库存列表失败:', e);
+    }
+  };
+
+  const handleValidate = async () => {
+    if (!basicFormRef.value) return;
+    const res = await basicFormRef.value.validateForm();
+    return res;
+  };
+  const ReceiptRecordData = ref({});
+  const getDetail = async () => {
+    if (!currentId.value) return;
+    try {
+      const res = await queryClaimItemsLogDetail(currentId.value);
+      if (res) {
+        ReceiptRecordData.value = res;
+        currentStatus.value = res.status;
+        ruleFormData.itemId = res.stuffName;
+        ruleFormData.outboundDate = res.outStoreTime ? res.outStoreTime.split('T')[0] : '';
+        ruleFormData.outboundQuantity = res.claimQty;
+        ruleFormData.receiptNumber = res.orderNumber;
+        ruleFormData.department = res.deptName ?? '';
+        ruleFormData.deptId = findDeptIdByName(deptTree.value, res.deptName ?? '') ?? null;
+        ruleFormData.recipient = res.userName ?? '';
+        ruleFormData.pimId = res.pimId;
+
+        // 如果部门ID存在,先获取该部门的用户列表,然后根据用户名查找用户ID
+        if (ruleFormData.deptId) {
+          await getRecipientUserList(ruleFormData.deptId);
+          const foundUser = recipientUserList.value.find((user) => user.realname === res.userName);
+          ruleFormData.recipientUserId = foundUser?.id ?? null;
+        } else {
+          ruleFormData.recipientUserId = null;
+        }
+        // 后端如返回审批模板ID,则回显(字段为 templateId)
+        ruleFormData.approvalTemplateId = res.templateId ?? null;
+        // 审核不通过原因(只读展示,后端字段为 rejectReson),仅在审核不通过时展示内容
+        ruleFormData.returnReason = res.status === -1 ? res.rejectReson ?? '' : '';
+      }
+      cloneRuleFormData();
+    } catch (e) {
+      console.error('获取奖品领取记录详情失败:', e);
+      ElMessage.error(e?.message || e?.data || '获取详情失败');
+    }
+  };
+
+  const handleSubmit = async () => {
+    const res = await handleValidate();
+    if (!res) return;
+
+    // 与应急预案保持一致的“添加/修改”提示文案
+    const message = isCreateMode.value ? '添加' : '修改';
+
+    try {
+      const selectedInventory = inventoryList.value.find((item) => {
+        return item.id === ruleFormData.itemId || item.id === ReceiptRecordData.value.pimId;
+      });
+      if (!selectedInventory) {
+        ElMessage.error('请选择有效的奖品名称');
+        return;
+      }
+
+      // const selectedUser = recipientUserList.value.find((user) => user.id === ruleFormData.recipientUserId);
+      // console.log(selectedUser,'selectedUser')
+      // if (!selectedUser) {
+      //   ElMessage.error('请选择有效的领取人');
+      //   return;
+      // }
+
+      const basePayload = {
+        stuffName: selectedInventory.stuffName,
+        pimId: selectedInventory.id,
+        outStoreTime: ruleFormData.outboundDate ? new Date(ruleFormData.outboundDate).toISOString() : '',
+        claimQty: ruleFormData.outboundQuantity,
+        orderNumber: ruleFormData.receiptNumber,
+        // deptName: ruleFormData.department,
+        // deptId: ruleFormData.deptId ?? undefined,
+        // userName: selectedUser.realname,
+        // userId: selectedUser.id, // 领取人用户ID
+        remark: '',
+        // 审批流程ID在与后端交互时字段名为 templateId
+        templateId: ruleFormData.approvalTemplateId ?? undefined,
+      };
+
+      if (isCreateMode.value) {
+        const createRes = await saveClaimItemsLog(basePayload);
+        // 兼容多种返回结构,优先使用数字ID
+        receiptRecordId.value =
+          typeof createRes === 'number'
+            ? createRes
+            : createRes && typeof createRes === 'object' && 'id' in createRes
+            ? (createRes as any).id
+            : undefined;
+      } else if (isEditMode.value && currentId.value) {
+        await updateClaimItemsLog({
+          id: currentId.value,
+          ...basePayload,
+        });
+        receiptRecordId.value = currentId.value;
+      }
+      ElMessage.success(`${message}成功`);
+      if (ruleFormData.approvalTemplateId) {
+        await getApprovalNode(ruleFormData.approvalTemplateId);
+        basicDialogRef.value?.openDialog();
+      }
+    } catch (e) {
+      console.error('保存奖品领取记录失败:', e);
+      ElMessage.error(e?.message || e?.data || '保存失败,请重试');
+    }
+  };
+
+  const handleSubmitApproval = () => {
+    approvalFormRef.value?.validate(async (valid: boolean) => {
+      if (!valid) return;
+      if (!receiptRecordId.value) {
+        ElMessage.error('缺少奖品领取记录ID,无法提交审批');
+        return;
+      }
+
+      const approvalData = {
+        planId: receiptRecordId.value,
+        approvalDescription: approvalForm.description,
+        approvalInfoList: approvalNodeList.value.map((node) => {
+          let approverIdList: number[] = [];
+          if (node.approverType === APPROVER_TYPE.FIX) {
+            approverIdList = node.approverInfoList.map((info) => info.approverId);
+          } else if (approvalForm.approvers[node.id]) {
+            approverIdList = approvalForm.approvers[node.id];
+          }
+          return {
+            approvalOrder: node.approvalOrder,
+            approverIdList,
+          };
+        }),
+      };
+
+      try {
+        await submitReceiptRecordApprovalProcess(approvalData);
+        ElMessage.success('提交成功');
+        closeApprovalDialog();
+        router.back();
+      } catch (e) {
+        console.error('提交审批失败:', e);
+        ElMessage.error(e?.message || e?.data || '提交审批失败,请重试');
+      }
+    });
+  };
+
+  const handleAuditPass = async () => {
+    if (!currentId.value) return;
+    try {
+      await updateClaimItemsLogAgree(currentId.value);
+      ElMessage.success('审核通过');
+      router.back();
+    } catch (e) {
+      console.error('审核失败:', e);
+      ElMessage.error(e?.message || e?.data || '审核失败,请重试');
+    }
+  };
+
+  const handleAuditReject = async () => {
+    if (!currentId.value) return;
+    try {
+      await updateClaimItemsLogReject(currentId.value);
+      ElMessage.success('已审核不通过');
+      router.back();
+    } catch (e) {
+      console.error('审核失败:', e);
+      ElMessage.error(e?.message || e?.data || '审核失败,请重试');
+    }
+  };
+
+  onMounted(async () => {
+    cloneRuleFormData();
+    await Promise.all([getDeptTreeData(), getInventoryList(), getApprovalList()]);
+    if (isEditMode.value || isViewMode.value || isAuditMode.value) {
+      await getDetail();
+    }
+  });
+</script>
+
+<style scoped lang="scss">
+  @use '@/styles/page-details-layout.scss' as *;
+</style>

+ 107 - 0
src/views/production-safety/safetyAssessment/receiptRecordAdministratorReview/configs/form.ts

@@ -0,0 +1,107 @@
+import { FormConfig } from '@/types/basic-form';
+
+export const RECEIPT_RECORD_FORM_CONFIG: FormConfig[] = [
+  {
+    prop: 'itemId',
+    label: '奖品名称:',
+    component: 'ElSelect',
+    slot: 'itemId', // 使用自定义插槽
+    componentProps: {
+      placeholder: '请选择奖品名称',
+      filterable: true,
+    },
+  },
+  {
+    prop: 'outboundDate',
+    label: '出库日期:',
+    component: 'ElDatePicker',
+    componentProps: {
+      type: 'date',
+      placeholder: '请选择出库日期',
+      valueFormat: 'YYYY-MM-DD',
+    },
+  },
+  {
+    prop: 'outboundQuantity',
+    label: '取出数量:',
+    component: 'ElInputNumber',
+    componentProps: {
+      min: 1,
+      max: 99999,
+      precision: 0, // 不允许小数点,只能输入整数
+      placeholder: '请输入取出数量',
+    },
+  },
+  {
+    prop: 'receiptNumber',
+    label: '主动信息报告单号:',
+    component: 'ElInput',
+    componentProps: {
+      placeholder: '请输入主动信息报告单号',
+    },
+  },
+  // {
+  //   prop: 'department',
+  //   label: '部门:',
+  //   slot: 'department', // 复用添加应急预案的制定部门下拉(el-cascader)
+  //   componentProps: {
+  //     placeholder: '请选择部门',
+  //   },
+  // },
+  // {
+  //   prop: 'recipient',
+  //   label: '领取人:',
+  //   slot: 'recipient', // 使用用户列表接口(queryAvailableUserList + el-select)
+  //   componentProps: {
+  //     placeholder: '请选择领取人',
+  //   },
+  // },
+  {
+    prop: 'approvalTemplateId',
+    label: '审批流程:',
+    slot: 'approvalTemplateId', // 复用应急预案的审批流程下拉
+    componentProps: {
+      placeholder: '请选择审批流程',
+    },
+  },
+  //   {
+  //     prop: 'returnReason',
+  //     label: '审核不通过原因:',
+  //     component: 'ElInput',
+  //     componentProps: {
+  //       type: 'textarea',
+  //       rows: 2,
+  //       placeholder: '暂无审核不通过原因',
+  //       disabled: true,
+  //     },
+  //   },
+];
+
+export const RECEIPT_RECORD_FORM_DATA = {
+  itemId: undefined as number | undefined | string, // 奖品库存ID(用于下拉框选中)
+  outboundDate: '',
+  status: null as number | null, // 物品领取记录状态
+  outboundQuantity: 1, // 最小值为1
+  receiptNumber: '',
+  deptId: null as number | null, // 部门ID(部门级联,与应急预案制定部门同源)
+  department: '', // 部门名称,提交给接口的 deptName
+  recipientUserId: null as number | null, // 领取人用户ID(通过queryAvailableUserList接口获取)
+  recipient: '', // 领取人姓名,提交给接口的 userName
+  pimId: 0, // 奖品库存ID(用于提交时使用,兼容旧数据)
+  approvalTemplateId: null as number | null, // 审批流程模板ID(与应急预案保持一致)
+  returnReason: '', // 审核不通过原因(只读展示)
+};
+
+export const RECEIPT_RECORD_FORM_RULES = {
+  itemId: [{ required: true, message: '请选择奖品名称', trigger: 'change' }],
+  outboundDate: [{ required: true, message: '请选择出库日期', trigger: 'change' }],
+  outboundQuantity: [
+    { required: true, message: '请输入取出数量', trigger: 'blur' },
+    { type: 'number', min: 1, message: '取出数量不能小于1', trigger: 'blur' },
+    { type: 'number', max: 99999, message: '取出数量不能大于99999', trigger: 'blur' },
+  ],
+  receiptNumber: [{ required: true, message: '请输入主动信息报告单号', trigger: 'blur' }],
+  department: [{ required: true, message: '请选择部门', trigger: 'change' }],
+  recipient: [{ required: true, message: '请选择领取人', trigger: 'change' }],
+  approvalTemplateId: [{ required: true, message: '请选择审批流程', trigger: 'change' }],
+};

+ 30 - 0
src/views/production-safety/safetyAssessment/receiptRecordAdministratorReview/configs/status.ts

@@ -0,0 +1,30 @@
+// 物品领取记录状态配置
+// 0 待审核, 1 审核通过, -1 审核不通过, 2 已领取
+export const RECEIPT_RECORD_STATUS_OPTIONS = [
+  { label: '待审核', value: 0 },
+  { label: '审核通过', value: 1 },
+  { label: '审核不通过', value: -1 },
+  { label: '已领取', value: 2 },
+];
+
+export const RECEIPT_RECORD_STATUS_LABEL: Record<string, string> = {
+  '0': '待审核',
+  '1': '审核通过',
+  '-1': '审核不通过',
+  '2': '已领取',
+};
+
+// 管理员审核页状态选项(含已领取)
+export const ADMIN_RECEIPT_RECORD_STATUS_OPTIONS = [
+  { label: '待审核', value: 0 },
+  { label: '审核通过', value: 1 },
+  { label: '审核不通过', value: -1 },
+  { label: '已领取', value: 2 },
+];
+
+export const ADMIN_RECEIPT_RECORD_STATUS_LABEL: Record<string, string> = {
+  '0': '待审核',
+  '1': '审核通过',
+  '-1': '审核不通过',
+  '2': '已领取',
+};

+ 127 - 0
src/views/production-safety/safetyAssessment/receiptRecordAdministratorReview/configs/tables.ts

@@ -0,0 +1,127 @@
+import type { TableColumnProps } from '@/types/basic-table';
+
+// 基础表格样式配置
+export const TABLE_OPTIONS = {
+  emptyText: '暂无数据',
+  loading: true,
+  maxHeight: 'calc(70vh - 150px)',
+};
+
+export const RECEIPT_RECORD_TABLE_COLUMNS: TableColumnProps[] = [
+  {
+    label: '奖品名称',
+    prop: 'itemName',
+    align: 'left',
+    minWidth: '120px',
+  },
+  {
+    label: '出库日期',
+    prop: 'outboundDate',
+    align: 'left',
+    minWidth: '120px',
+  },
+  {
+    label: '取出数量',
+    prop: 'outboundQuantity',
+    align: 'center',
+    minWidth: '120px',
+  },
+  {
+    label: '结余数量',
+    prop: 'remainingQuantity',
+    align: 'center',
+    minWidth: '120px',
+  },
+  {
+    label: '单号',
+    prop: 'receiptNumber',
+    align: 'left',
+    minWidth: '120px',
+  },
+  {
+    label: '部门',
+    prop: 'department',
+    align: 'left',
+    minWidth: '120px',
+  },
+  {
+    label: '领取人',
+    prop: 'recipient',
+    align: 'left',
+    minWidth: '120px',
+  },
+  {
+    label: '状态',
+    prop: 'status',
+    slot: 'status',
+    align: 'center',
+    minWidth: '100px',
+  },
+  {
+    label: '操作',
+    prop: 'action',
+    slot: 'action',
+    fixed: 'right',
+    width: '250px',
+    align: 'left',
+  },
+];
+export const ADMIN_RECEIPT_RECORD_TABLE_COLUMNS: TableColumnProps[] = [
+  {
+    label: '奖品名称',
+    prop: 'itemName',
+    align: 'left',
+    minWidth: '120px',
+  },
+  {
+    label: '出库日期',
+    prop: 'outboundDate',
+    align: 'left',
+    minWidth: '120px',
+  },
+  {
+    label: '取出数量',
+    prop: 'outboundQuantity',
+    align: 'center',
+    minWidth: '120px',
+  },
+  {
+    label: '结余数量',
+    prop: 'remainingQuantity',
+    align: 'center',
+    minWidth: '120px',
+  },
+  {
+    label: '单号',
+    prop: 'receiptNumber',
+    align: 'left',
+    minWidth: '120px',
+  },
+  {
+    label: '部门',
+    prop: 'department',
+    align: 'left',
+    minWidth: '120px',
+  },
+  {
+    label: '领取人',
+    prop: 'recipient',
+    align: 'left',
+    minWidth: '120px',
+  },
+  {
+    label: '状态',
+    prop: 'status',
+    slot: 'status',
+    align: 'center',
+    minWidth: '100px',
+  },
+  {
+    label: '操作',
+    prop: 'action',
+    slot: 'action',
+    fixed: 'right',
+    width: '180px',
+    align: 'left',
+  },
+];

+ 1 - 1
src/views/production-safety/safetyAssessment/receiptRecord/receiptRecordAdministratorReview.vue

@@ -283,7 +283,7 @@
 
 
   const handleView = (id: number) => {
   const handleView = (id: number) => {
     router.push({
     router.push({
-      name: 'ReceiptRecordItem',
+      name: 'ReceiptRecordAdministratorReviewDetails',
       query: {
       query: {
         id,
         id,
         operate: 'receiptRecord-view',
         operate: 'receiptRecord-view',

+ 52 - 0
src/views/production-safety/safetyAssessment/receiptRecordAdministratorReview/receiptRecordItem.vue

@@ -0,0 +1,52 @@
+<!--
+ * @Author: liuJie
+ * @Date: 2026-02-26 13:57:24
+ * @LastEditors: liuJie
+ * @LastEditTime: 2026-02-27 15:27:23
+ * @Describe: file describe
+-->
+<template>
+  <div class="safety-platform-container">
+    <header class="safety-platform-container__header">
+      <BreadcrumbBack />
+      <span class="breadcrumb-title">{{ headerTitle }}</span>
+    </header>
+    <ReceiptRecordDetail />
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { computed } from 'vue';
+  import { useRoute } from 'vue-router';
+  import BreadcrumbBack from '@/components/BreadcrumbBack.vue';
+  import ReceiptRecordDetail from './components/ReceiptRecordDetail.vue';
+
+  const route = useRoute();
+  const operate = route.query.operate as string;
+
+  const headerTitle = computed(() => {
+    switch (operate) {
+      case 'receiptRecord-create':
+        return '新增奖品领取记录';
+      case 'receiptRecord-edit':
+        return '编辑奖品领取记录';
+      case 'receiptRecord-view':
+        return '查看奖品领取记录';
+      case 'receiptRecord-audit':
+        return '审核奖品领取记录';
+      default:
+        return '未知操作';
+    }
+  });
+</script>
+
+<style scoped lang="scss">
+  @use '@/styles/page-details-layout.scss' as *;
+  @use '@/styles/page-main-layout.scss' as *;
+
+  .safety-platform-container__header {
+    flex-direction: row !important;
+    justify-content: flex-start !important;
+    gap: 8px !important;
+  }
+</style>