Procházet zdrojové kódy

Merge remote-tracking branch 'origin/master'

wwj před 4 měsíci
rodič
revize
8edbca7520

+ 78 - 0
pnpm-lock.yaml

@@ -80,12 +80,18 @@ importers:
       fast-xml-parser:
         specifier: ^4.3.2
         version: 4.3.6
+      file-saver:
+        specifier: ^2.0.5
+        version: 2.0.5
       highlight.js:
         specifier: ^11.9.0
         version: 11.9.0
       jsencrypt:
         specifier: ^3.3.2
         version: 3.3.2
+      jszip:
+        specifier: ^3.10.1
+        version: 3.10.1
       lodash-es:
         specifier: ^4.17.21
         version: 4.17.21
@@ -2650,6 +2656,9 @@ packages:
   core-js@3.37.0:
     resolution: {integrity: sha512-fu5vHevQ8ZG4og+LXug8ulUtVxjOcEYvifJr7L5Bfq9GOztVqsKd9/59hUk2ZSbCrS3BqUr3EpaYGIYzq7g3Ug==}
 
+  core-util-is@1.0.3:
+    resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
+
   cors@2.8.5:
     resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
     engines: {node: '>= 0.10'}
@@ -3303,6 +3312,9 @@ packages:
     resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
     engines: {node: '>=16.0.0'}
 
+  file-saver@2.0.5:
+    resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==}
+
   filelist@1.0.4:
     resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==}
 
@@ -3602,6 +3614,9 @@ packages:
     engines: {node: '>=0.10.0'}
     hasBin: true
 
+  immediate@3.0.6:
+    resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
+
   immer@9.0.21:
     resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==}
 
@@ -3910,6 +3925,9 @@ packages:
     resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
     engines: {'0': node >= 0.2.0}
 
+  jszip@3.10.1:
+    resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
+
   katex@0.16.11:
     resolution: {integrity: sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==}
     hasBin: true
@@ -3946,6 +3964,9 @@ packages:
     resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
     engines: {node: '>= 0.8.0'}
 
+  lie@3.3.0:
+    resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
+
   lilconfig@3.0.0:
     resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==}
     engines: {node: '>=14'}
@@ -4395,6 +4416,9 @@ packages:
     resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
     engines: {node: '>=6'}
 
+  pako@1.0.11:
+    resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
+
   parent-module@1.0.1:
     resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
     engines: {node: '>=6'}
@@ -4610,6 +4634,9 @@ packages:
     resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
     engines: {node: '>=6'}
 
+  process-nextick-args@2.0.1:
+    resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
+
   process@0.11.10:
     resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
     engines: {node: '>= 0.6.0'}
@@ -4654,6 +4681,9 @@ packages:
   react-is@18.3.1:
     resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
 
+  readable-stream@2.3.8:
+    resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
+
   readable-stream@3.6.2:
     resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
     engines: {node: '>= 6'}
@@ -4791,6 +4821,9 @@ packages:
     resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==}
     engines: {node: '>=0.4'}
 
+  safe-buffer@5.1.2:
+    resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+
   safe-buffer@5.2.1:
     resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
 
@@ -4854,6 +4887,9 @@ packages:
     resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
     engines: {node: '>=0.10.0'}
 
+  setimmediate@1.0.5:
+    resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
+
   shebang-command@2.0.0:
     resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
     engines: {node: '>=8'}
@@ -5000,6 +5036,9 @@ packages:
     resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
     engines: {node: '>= 0.4'}
 
+  string_decoder@1.1.1:
+    resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
+
   string_decoder@1.3.0:
     resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
 
@@ -8350,6 +8389,8 @@ snapshots:
 
   core-js@3.37.0: {}
 
+  core-util-is@1.0.3: {}
+
   cors@2.8.5:
     dependencies:
       object-assign: 4.1.1
@@ -9191,6 +9232,8 @@ snapshots:
     dependencies:
       flat-cache: 4.0.1
 
+  file-saver@2.0.5: {}
+
   filelist@1.0.4:
     dependencies:
       minimatch: 5.1.6
@@ -9488,6 +9531,8 @@ snapshots:
 
   image-size@0.5.5: {}
 
+  immediate@3.0.6: {}
+
   immer@9.0.21: {}
 
   immutable@4.3.5: {}
@@ -9743,6 +9788,13 @@ snapshots:
 
   jsonparse@1.3.1: {}
 
+  jszip@3.10.1:
+    dependencies:
+      lie: 3.3.0
+      pako: 1.0.11
+      readable-stream: 2.3.8
+      setimmediate: 1.0.5
+
   katex@0.16.11:
     dependencies:
       commander: 8.3.0
@@ -9774,6 +9826,10 @@ snapshots:
       prelude-ls: 1.2.1
       type-check: 0.4.0
 
+  lie@3.3.0:
+    dependencies:
+      immediate: 3.0.6
+
   lilconfig@3.0.0: {}
 
   lines-and-columns@1.2.4: {}
@@ -10258,6 +10314,8 @@ snapshots:
 
   p-try@2.2.0: {}
 
+  pako@1.0.11: {}
+
   parent-module@1.0.1:
     dependencies:
       callsites: 3.1.0
@@ -10450,6 +10508,8 @@ snapshots:
 
   prismjs@1.29.0: {}
 
+  process-nextick-args@2.0.1: {}
+
   process@0.11.10: {}
 
   progress@2.0.3: {}
@@ -10486,6 +10546,16 @@ snapshots:
 
   react-is@18.3.1: {}
 
+  readable-stream@2.3.8:
+    dependencies:
+      core-util-is: 1.0.3
+      inherits: 2.0.4
+      isarray: 1.0.0
+      process-nextick-args: 2.0.1
+      safe-buffer: 5.1.2
+      string_decoder: 1.1.1
+      util-deprecate: 1.0.2
+
   readable-stream@3.6.2:
     dependencies:
       inherits: 2.0.4
@@ -10636,6 +10706,8 @@ snapshots:
       has-symbols: 1.0.3
       isarray: 2.0.5
 
+  safe-buffer@5.1.2: {}
+
   safe-buffer@5.2.1: {}
 
   safe-json-parse@4.0.0:
@@ -10709,6 +10781,8 @@ snapshots:
       is-plain-object: 2.0.4
       split-string: 3.1.0
 
+  setimmediate@1.0.5: {}
+
   shebang-command@2.0.0:
     dependencies:
       shebang-regex: 3.0.0
@@ -10869,6 +10943,10 @@ snapshots:
       define-properties: 1.2.1
       es-object-atoms: 1.0.0
 
+  string_decoder@1.1.1:
+    dependencies:
+      safe-buffer: 5.1.2
+
   string_decoder@1.3.0:
     dependencies:
       safe-buffer: 5.2.1

+ 1 - 1
src/api/museums/specimeninfo/index.ts

@@ -61,7 +61,7 @@ export const SpecimenInfoApi = {
     return await request.delete({ url: `/museums/specimen-info/delete?id=` + id + '&deletedReason=' + deletedReason})
   },
   //下载导入标本信息模板
-  importSpecimenInfTemplate: async(data: SpecimenInfoVO) => {
+  importSpecimenInfoTemplate: async(data: SpecimenInfoVO) => {
     return await request.download({ url: '/museums/specimen-info/get-specimen-import-template' , data })
   },
 

+ 21 - 22
src/api/museums/specimenoutbound/index.ts

@@ -12,7 +12,7 @@ export interface SpecimenOutboundVO {
   attachments: string // 附件上传
   status: number // 审批状态
   remarks: string // 备注信息
-  processInstanceId: string // 流程实例的编号
+  processInstanceId: string // 一审驳回原因
   operator: string // 出库员
   outgoingTime: Date // 出库时间
   returner: string // 退还人
@@ -20,6 +20,14 @@ export interface SpecimenOutboundVO {
   returnDate: Date // 退还日期
   specimenCondition: string // 标本情况
   sampleStatus: number // 标本状态(已出库、已回库、出库审批中)
+  estimatedReturnTime:Date//预计退还日期
+  approvalTime:Date//一审时间
+  twoApprovalTime:Date//二审时间
+  expectedCollectionTime:Date//预计领取时间
+  rejectionReasons: string//二审驳回原因
+  approveUsers:string//一审批者
+  twoApproveUsers:  string//二审批者
+  startTime: Date//项目开始时间
 
 }
 
@@ -55,17 +63,14 @@ export const SpecimenOutboundApi = {
     return await request.download({ url: `/museums/specimen-outbound/export-excel`, params })
   },
   // 审批通过标本出库回库
-  ApprovalPassSpecimenOutbound: async (data: SpecimenOutboundVO) => {
-    return await request.post({ url: `/museums/specimen-outbound/approve`, data })
-  },
+  // ApprovalPassSpecimenOutbound: async (data: SpecimenOutboundVO) => {
+  //   return await request.post({ url: `/museums/specimen-outbound/approve`, data })
+  // },
   // 审批驳回标本出库回库
  ApprovalSpecimenOutbound: async (data: SpecimenOutboundVO) => {
-    return await request.post({ url: `/museums/specimen-outbound/reject`, data })
+    return await request.post({ url: `/museums/specimen-outbound/approve`, data })
   },
-  // // 确认回标本回库
-  // SpecimenOutboundReturn: async (data: SpecimenOutboundVO) => {
-  //   return await request.post({ url: `/museums/specimen-outbound/update`,data})
-  // },
+
   // 确认回标本出库
   ConfirmSpecimenOutbound :async (id: number) => {
     // 构造请求体
@@ -78,25 +83,19 @@ export const SpecimenOutboundApi = {
       data: reqBody
     });
   },
- // 确认标本回库
- // SpecimenOutboundReturn :async (id: number) => {
- //    // 构造请求体
- //    const reqBody = {
- //      id: id
- //    };
- //    // 发送POST请求,包含请求体
- //    return await request.post({
- //      url: `/museums/specimen-outbound/update`,
- //      data: reqBody
- //    });/museums/specimen-outbound/specimenInfo
- //  }
+
   // 查询标本出库回库信息详情页面
   getSpecimenOutboundDetails: async (id: number) => {
     return await request.get({ url: `/museums/specimen-outbound/specimenInfo?id=` + id })
   },
+
+  // 查询标本出库回库详情页面分页
+  getSpecimenOutboundDetailsPage: async (params: any) => {
+    return await request.get({ url: `/museums/specimen-outbound/specimenInfo`, params })
+  },
+
   // 修改标本出库申请
   alterSpecimenOutbound: async (data: SpecimenOutboundVO) => {
     return await request.put({ url: `/museums/specimen-outbound/recompile`, data })
   },
-
 }

+ 13 - 1
src/router/modules/remaining.ts

@@ -661,7 +661,19 @@ const remainingRouter: AppRouteRecordRaw[] = [
           hidden: true,
           canTo: true,
           title: '查看标本出库详情',
-          activeMenu: '/crm/outbound'
+          activeMenu: '/museums/specimenoutbound/OutboundManagement'
+        }
+      },
+      {
+        path: '/museums/specimenoutbound/OutboundForm/ApproalDetails.vue',
+        component: () => import('@/views/museums/specimenoutbound/OutboundForm/ApproalDetails.vue'),
+        name: 'ApproalDetails',
+        meta: {
+          noCache: true,
+          hidden: true,
+          canTo: true,
+          title: '查看标本出库申请详情',
+          activeMenu: 'outboundmanage/approalprocess'
         }
       },
     ]

+ 1 - 0
src/utils/formatTime.ts

@@ -201,6 +201,7 @@ export function dateFormatter(_row: any, _column: TableColumnCtx<any>, cellValue
   return cellValue ? formatDate(cellValue) : ''
 }
 
+
 /**
  * element plus 的时间 Formatter 实现,使用 YYYY-MM-DD 格式
  *

+ 2 - 2
src/views/Home/echarts-data.ts

@@ -66,7 +66,7 @@ const return1 = returnSpecimen.value.data
  const returnCount = years.map(years => years.returnCount);
 //  console.log('sourcs',sourceList.value);
  const year1 = sourcs.map(sourcs => sourcs.year);
- const other = sourcs.map(sourcs => sourcs.other);
+ const purchase = sourcs.map(sourcs => sourcs.other);
  const gather = sourcs.map(sourcs => sourcs.gather);
  const donate = sourcs.map(sourcs => sourcs.donate);
 //统计本年标本入库数量(按月份)
@@ -394,7 +394,7 @@ export const originOptions: EChartsOption = {
     {
       name: "采购",
       type: "line",
-      data: other,
+      data: purchase,
       symbolSize: 1,
       yAxisIndex: 1,
       symbol: "circle",

+ 1 - 1
src/views/museums/specimeninfo/SpecimenImportForm.vue

@@ -203,7 +203,7 @@ const handleExceed = (): void => {
 }
 /** 下载模板操作 */
 const importTemplate = async () => {
-  const res = await SpecimenInfoApi.importSpecimenInfTemplate()
+  const res = await SpecimenInfoApi.importSpecimenInfoTemplate()
   download.excel(res, '用户导入模版.xls')
 }
 

+ 1 - 1
src/views/museums/specimeninfo/index.vue

@@ -620,7 +620,7 @@ onMounted(() => {
 })
 
 
-/** 查看页面 **/
+/** 查看标本详情页面 **/
 import { useRouter } from 'vue-router';
 import UserImportForm from "@/views/system/user/UserImportForm.vue";
 const router = useRouter();

+ 1 - 1
src/views/museums/specimeninfo/specimenDetails.vue

@@ -284,7 +284,7 @@ const fetchData = async () => {
 
 // // 在组件加载时获取数据
 onMounted(async () => {
-  console.log(1)
+
   await fetchData()
 
 

+ 78 - 54
src/views/museums/specimenoutbound/ApproalProcess.vue

@@ -46,21 +46,21 @@
           class="!w-220px"
         />
       </el-form-item>
-      <el-form-item label="审批状态" prop="status">
-        <el-select
-          v-model="queryParams.status"
-          placeholder="请选择审批状态"
-          clearable
-          class="!w-240px"
-        >
-          <el-option
-                     v-for="dict in getIntDictOptions(DICT_TYPE. MUSEUMS_APPROAL_STATUS)"
-                     :key="dict.value"
-                     :label="dict.label"
-                     :value="dict.value" />
-        </el-select>
-      </el-form-item>
-      <el-form-item>
+<!--      <el-form-item label="审批状态" prop="status">-->
+<!--        <el-select-->
+<!--          v-model="queryParams.status"-->
+<!--          placeholder="请选择审批状态"-->
+<!--          clearable-->
+<!--          class="!w-240px"-->
+<!--        >-->
+<!--          <el-option-->
+<!--                     v-for="dict in getIntDictOptions(DICT_TYPE. MUSEUMS_APPROAL_STATUS)"-->
+<!--                     :key="dict.value"-->
+<!--                     :label="dict.label"-->
+<!--                     :value="dict.value" />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+      <el-form-item  >
         <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
 
@@ -79,12 +79,37 @@
 
   <!-- 列表 -->
   <ContentWrap>
+
     <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
       <el-table-column label="序号" align="center" prop="id" />
-<!--      <el-table-column label="标本ID" align="center" prop="infoId" />-->
-      <el-table-column label="标本编号" align="center" prop="specimenNumber" />
-      <el-table-column label="中文名称" align="center" prop="chineseName" />
-      <el-table-column label="申请人(单位)" align="center" width="120px" prop="applicantName" />
+      <el-table-column label="申请人姓名" align="center" width="120px" prop="applicantName" />
+      <el-table-column label="申请单位" align="center" width="120px" prop="applicationUsage" />
+      <el-table-column label="研究项目名称" align="center" prop="projectName" />
+      <el-table-column label="附件" align="center" prop="attachments" >
+        <template #default="{ row }">
+          <el-image
+            v-if="row.type && row.type.includes('image')"
+            class="h-80px w-80px"
+            lazy
+            :src="row.attachments"
+            :preview-src-list="[row.attachments]"
+            preview-teleported
+            fit="cover"
+          />
+          <el-link
+            v-else-if="row.type && row.type.includes('pdf')"
+            type="primary"
+            :href="row.attachments"
+            :underline="false"
+            target="_blank"
+          >预览</el-link
+          >
+          <el-link v-else type="primary" download :href="row.attachments" :underline="false" target="_blank"
+          >下载</el-link
+          >
+        </template>
+      </el-table-column>
+
       <el-table-column
         label="申请日期"
         align="center"
@@ -92,24 +117,13 @@
         :formatter="dateFormatter"
         width="180px"
       />
-      <el-table-column label="用途" align="center" prop="applicationUsage" />
-      <el-table-column label="附件" align="center" prop="attachments" />
-
       <el-table-column
-        label="出库时间"
+        label="项目开始时间"
         align="center"
-        prop="outgoingTime"
+        prop="startTime"
         :formatter="dateFormatter"
         width="180px"
       />
-      <el-table-column
-        label="退还日期"
-        align="center"
-        prop="returnDate"
-        :formatter="dateFormatter"
-        width="180px"
-      />
-<!--      <el-table-column label="标本情况" align="center" prop="specimenCondition" />-->
       <el-table-column label="审批状态" align="center" prop="sampleStatus" >
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.MUSEUMS_APPROAL_STATUS" :value="scope.row.status"/>
@@ -120,18 +134,11 @@
           <el-button
             link
             type="primary"
-            @click="Approvaldetails(scope.row.id)"
+            @click="ApproalDetails(scope.row.id)"
           >
             查看
           </el-button>
-          <el-button
-            v-if="scope.row.status !== 1 && scope.row.status !== 2 && scope.row.status !== 3 && scope.row.status !== 2  && scope.row.status !== 4"
-            link
-            type="danger"
-            @click="handleApproval(scope.row.id)"
-          >
-            审批
-          </el-button>
+
         </template>
       </el-table-column>
     </el-table>
@@ -142,13 +149,13 @@
       @pagination="getList"
       />
    </ContentWrap>
-  <Approval ref="ApprovalRef" @success="getList" />
+<!--  <Approval ref="ApprovalRef" @success="getList" />-->
   </el-skeleton>
 </template>
 
 
 <script setup lang="ts">
-import Approval from "@/views/museums/specimenoutbound/approval.vue"
+// import Approval from "@/views/museums/specimenoutbound/approval.vue"
 import download from '@/utils/download'
 import { SpecimenOutboundApi, SpecimenOutboundVO } from '@/api/museums/specimenoutbound'
 import {dateFormatter} from "@/utils/formatTime";
@@ -158,6 +165,7 @@ import {DICT_TYPE, getIntDictOptions} from "@/utils/dict";
 defineOptions({ name: 'ApproalProcess' })
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
+
 const loading = ref(true) // 列表的加载中
 const list = ref<SpecimenOutboundVO[]>([]) // 列表的数据
 const total = ref(0) // 列表的总页数
@@ -171,7 +179,7 @@ const queryParams = reactive({
   applicationDate: [],
   applicationUsage: undefined,
   attachments: undefined,
-  status: undefined,
+  status: [],
   remarks: undefined,
   processInstanceId: undefined,
   operator: undefined,
@@ -181,7 +189,9 @@ const queryParams = reactive({
   returnDate: [],
   specimenCondition: undefined,
   createTime: [],
-  sampleStatus: undefined
+  sampleStatus: undefined,
+  estimatedReturnTime: [],
+  startTime:[],
 })
 const queryFormRef = ref() // 搜索的表单
 const exportLoading = ref(false) // 导出的加载中
@@ -215,14 +225,14 @@ const resetQuery = () => {
   handleQuery()
 }
 
-/** 审批按钮操作 */
-
-// 检查用户权限的方法
-const ApprovalRef = ref()
-const handleApproval = ( id?: number) => {
-  ApprovalRef.value.open( id)
-
-}
+// /** 审批按钮操作 */
+//
+// // 检查用户权限的方法
+// const ApprovalRef = ref()
+// const handleApproval = ( id?: number) => {
+//   ApprovalRef.value.open( id)
+//
+// }
 /** 导出按钮操作 */
 const handleExport = async () => {
   try {
@@ -230,7 +240,7 @@ const handleExport = async () => {
     await message.exportConfirm()
     // 发起导出
     exportLoading.value = true
-    const data = await SpecimenOutboundApi.ApprovalSpecimenOutbound(queryParams)
+    const data = await SpecimenOutboundApi.exportSpecimenOutbound(queryParams)
     download.excel(data, '标本出库回库信息.xls')
   } catch {
   } finally {
@@ -238,6 +248,20 @@ const handleExport = async () => {
   }
 }
 
+/** 查看出库入库申请审批详情页面 **/
+import { useRouter } from 'vue-router';
+
+const router = useRouter();
+const ApproalDetails=(dataId: number) => {
+  router.push({
+    name: 'ApproalDetails',
+    query: {
+      dataId: dataId,
+    }
+  })
+}
+
+
 /** 初始化 **/
 onMounted(() => {
   getList()

+ 29 - 23
src/views/museums/specimenoutbound/OutboundApplication.vue

@@ -104,13 +104,12 @@
 
     <!-- 列表 -->
     <ContentWrap>
+
       <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
         <el-table-column label="序号" align="center" prop="id"/>
-        <!--      <el-table-column label="标本ID" align="center" prop="infoId" />-->
-        <el-table-column label="标本编号" align="center" prop="specimenNumber"/>
-        <el-table-column label="中文名称" align="center" prop="chineseName"/>
-        <el-table-column label="申请人(单位)" align="center" width="120px" prop="applicantName"/>
-        <el-table-column label="用途" align="center" prop="applicationUsage"/>
+        <el-table-column label="申请人姓名" align="center" width="120px" prop="applicantName" />
+        <el-table-column label="申请单位" align="center" width="120px" prop="applicationUsage" />
+        <el-table-column label="研究项目名称" align="center" prop="projectName" />
         <el-table-column label="申请附件" align="center" prop="attachments">
           <template #default="{ row }">
             <div v-if="row.attachments">
@@ -146,13 +145,13 @@
         />
 
         <!--      <el-table-column label="审批状态" align="center" prop="status" />-->
-        <el-table-column
-          label="出库时间"
-          align="center"
-          prop="outgoingTime"
-          :formatter="dateFormatter"
-          width="180px"
-        />
+<!--        <el-table-column-->
+<!--          label="出库时间"-->
+<!--          align="center"-->
+<!--          prop="outgoingTime"-->
+<!--          :formatter="dateFormatter"-->
+<!--          width="180px"-->
+<!--        />-->
         <!--      <el-table-column label="申请附件" align="center" prop="url">-->
         <!--          <template #default="{ row }">-->
         <!--            <el-image-->
@@ -186,7 +185,7 @@
           <template #default="scope">
             <!-- 只有当记录未被审批或驳回时,才显示编辑按钮 -->
             <el-button
-              v-if="scope.row.status !== 1 &&  scope.row.status !== 3  && scope.row.status !== 4"
+              v-if="scope.row.status !== 1 &&  scope.row.status !== 3  && scope.row.status !== 4 && scope.row.status !== 5 && scope.row.status !== 6 && scope.row.status !== 2"
               link
               type="primary"
               @click="openForm('update', scope.row.id)"
@@ -197,13 +196,13 @@
 
 
             <el-button
-              v-if="scope.row.status !== 0 && scope.row.status !== 1 && scope.row.status !== 3 && scope.row.status !== 4"
+              v-if="scope.row.status !== 0 && scope.row.status !== 1 && scope.row.status !== 3 && scope.row.status !== 4 && scope.row.status !== 5 "
               link
               type="success"
               @click="handleInitiative(scope.row.id)"
-              v-hasPermi="['museums:specimen-outbound:delete']"
+
             >
-             查看驳回原因
+             修改申请
             </el-button>
             <el-button
               link
@@ -226,8 +225,9 @@
     </ContentWrap>
 
     <!-- 表单弹窗:编辑标本出库申请 -->
+
     <SpecimenOutboundForm ref="formRef" @success="getList"/>
-      <InitiativeProcessInstance ref="initiativeFormRef" @success="getList" />
+    <InitiativeProcessInstance ref="initiativeFormRef" @success="getList" />
   </el-skeleton>
 </template>
 
@@ -238,14 +238,15 @@ import download from '@/utils/download'
 import {SpecimenOutboundApi, SpecimenOutboundVO} from '@/api/museums/specimenoutbound'
 import SpecimenOutboundForm from "@/views/museums/specimenoutbound/SpecimenOutboundForm.vue";
 import InitiativeProcessInstance from '@/views/museums/specimenoutbound/OutboundForm/InitiativeProcessInstance.vue'
-import {ref} from "vue";
-// import type { Action } from 'element-plus'
+import {ref,} from "vue";
+import type { Action } from 'element-plus'
 defineOptions({name: 'OutboundApplication'})
 import {getIntDictOptions, DICT_TYPE} from '@/utils/dict'
 
 const message = useMessage() // 消息弹窗
 const {t} = useI18n() // 国际化
 
+
 const loading = ref(true) // 列表的加载中
 const list = ref<SpecimenOutboundVO[]>([]) // 列表的数据
 const total = ref(0) // 列表的总页数
@@ -307,12 +308,14 @@ const openForm = (type: string, id?: number) => {
   formRef.value.open(type, id)
 }
 
-/** 查看驳回原因*/
-const initiativeFormRef = ref(null)
-const handleInitiative = (id) => {
+/** 查看并修改出库申请*/
 
-  initiativeFormRef.value.open('someType', id)
+ const  initiativeFormRef = ref()
+const handleInitiative = (type: string, id?: number) => {
+  initiativeFormRef.value.open(type, id)
 }
+
+
 // const handleInitiative = async (id) => {
 //   try {
 //     const processInstanceId = await SpecimenOutboundApi.getSpecimenOutboundPage(id); // 假设这是你的 API 请求方法
@@ -361,6 +364,9 @@ const handleExport = async () => {
   }
 }
 
+
+
+
 /** 初始化 **/
 onMounted(() => {
   getList()

+ 235 - 0
src/views/museums/specimenoutbound/OutboundForm/ApproalDetails.vue

@@ -0,0 +1,235 @@
+<template>
+  <el-skeleton :loading="loading" animated>
+   <el-row :gutter="8" justify="space-between">
+     <el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24">
+       <el-card style="margin-bottom: 10px">
+
+         <template #header>
+           <div class="card-header" style="text-align: center">
+             <h1 class="text1">标本出库申请详情</h1>
+           </div>
+         </template>
+       <el-row >
+         <el-col :xl="11" :lg="11" :md="24" :sm="24" :xs="24" >
+         <el-descriptions
+           :column="1"
+           border
+           :size="size"
+           v-if="outboundData"
+         >
+           <el-descriptions-item label="审批状态:"  label-align="right" label-class-name="my-label">{{ outboundData.status }}</el-descriptions-item>
+           <el-descriptions-item label="申请人姓名:"   label-align="right" label-class-name="my-label">{{ outboundData.applicantName }}</el-descriptions-item>
+           <el-descriptions-item label="申请单位:" label-align="right" label-class-name="my-label">{{outboundData.applicationUsage }}</el-descriptions-item>
+           <el-descriptions-item label="电话号码:" label-align="right" label-class-name="my-label">{{ outboundData.phoneNumber}}</el-descriptions-item>
+         </el-descriptions>
+       </el-col>
+         <el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24" >
+           <el-descriptions
+             :column="1"
+             border
+             :size="size"
+             v-if="outboundData"
+           >
+           <el-descriptions-item label="研究项目名称:" label-align="right" label-class-name="my-label">{{ outboundData.projectName}}</el-descriptions-item>
+           <el-descriptions-item label="项目开始时间:" label-align="right" label-class-name="my-label">{{ outboundData.startTime }}</el-descriptions-item>
+           <el-descriptions-item label="项目结束时间:" label-align="right" label-class-name="my-label">{{outboundData.endTime }}</el-descriptions-item>
+           <el-descriptions-item label="出库备注信息:" label-align="right" label-class-name="my-label">{{ outboundData.outboundRemarks}}</el-descriptions-item>
+           </el-descriptions>
+         </el-col>
+         <el-col :xl="3" :lg="3" :md="24" :sm="24" :xs="24" >
+           <el-descriptions
+             v-if="outboundData"
+             direction="vertical"
+             :size="size"
+             border
+
+           >
+             <el-descriptions-item
+               :width="200"
+               label="申请附件"
+               align="center"
+               label-class-name="my-label"
+               class-name="my-content"
+             ><div class="demo-image__preview" v-if="outboundData" >
+               <el-image
+                 style="width: 40px; height:40px;margin-right: 5px"
+                 class="h-200px w-150px"
+                 lazy
+                 :src="outboundData.attachments"
+                 :preview-src-list="outboundData.attachments"
+                 preview-teleported
+                 fit="cover"
+               />
+             </div>
+             </el-descriptions-item>
+           </el-descriptions>
+<!--           <div class="demo-image__preview" v-if="outboundData ">-->
+<!--             <el-image-->
+
+<!--               style=" align-items: center"-->
+<!--               :src="outboundData.attachments"-->
+<!--               :zoom-rate="1.2"-->
+<!--               :max-scale="7"-->
+<!--               :min-scale="0.2"-->
+<!--               :preview-src-list="outboundData.attachments"-->
+<!--               :initial-index="index"-->
+<!--               fit="cover"-->
+<!--             />-->
+<!--           </div>-->
+         </el-col>
+         </el-row>
+<!--         <div style="text-align: right; margin-top: 20px;margin-right: 30px">-->
+
+<!--           <el-button-->
+<!--             v-if="outboundData.status !== 1 && outboundData.status !== 2 && outboundData.status !== 3 && outboundData.status !== 4"-->
+<!--             link-->
+<!--             type="danger"-->
+<!--             plain-->
+<!--             @click="handleApproval(outboundData.id)"-->
+<!--           >-->
+<!--             审批-->
+<!--           </el-button>-->
+<!--         </div>-->
+         </el-card>
+     </el-col>
+
+
+
+
+     <el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24" >
+       <el-card>
+         <template #header>
+           <div class="card-header" style="text-align: center">
+             <h1 class="text1">申请出库标本信息</h1>
+           </div>
+         </template>
+         <el-table v-loading="loading" :data="outboundData.specimenInfoList" :stripe="true" :show-overflow-tooltip="true" >
+<!--           <el-table-column label="标本ID" align="center" prop="id" />-->
+           <el-table-column label="标本编号" align="center" prop="specimenNumber" />
+           <el-table-column label="中文名称" align="center" prop="chineseName" />
+           <el-table-column label="标本类型" align="center" prop="specimenType">
+             <template #default="scope">
+               <dict-tag :type="DICT_TYPE.MUSEUMS_SPECIMEN_TYPE" :value="scope.row.specimenType" />
+             </template>
+           </el-table-column>
+           <el-table-column label="标本数量" align="center" prop="specimenAmount" />
+           <el-table-column label="标本重量" align="center" prop="weight" />
+           <el-table-column label="标本位置" align="center" prop="storageLocation" />
+           <el-table-column label="保存类型" align="center" prop="preservationType">
+             <template #default="scope">
+               <dict-tag :type="DICT_TYPE.MUSEUMS_SPECIMEN_INFO" :value="scope.row.preservationType" />
+             </template>
+           </el-table-column>
+           <el-table-column label="标本图片" align="center" prop="url" >
+             <template #default="{ row }">
+               <div class="demo-image__preview" v-if="queryParams" >
+                 <block  v-for="(image, index) in row.imagePath" :key="index">
+                   <el-image
+                     class="image-class"
+                     lazy
+                     :src="image"
+                     :preview-src-list="row.imagePath"
+                     preview-teleported
+                     fit="cover" />
+                 </block>
+               </div>
+             </template>
+           </el-table-column>
+         </el-table>
+         <!-- 分页 -->
+         <Pagination
+           :total="total"
+           v-model:page="queryParams.pageNo"
+           v-model:limit="queryParams.pageSize"
+           @pagination="getList"
+         />
+         <el-button
+           @click="handleApproval"
+           type="primary"
+           style="float: right; margin-left: 20px;margin-top: 20px;margin-bottom: 20px"
+         > 审批
+         </el-button>
+       </el-card>
+     </el-col>
+
+
+   </el-row>
+
+    <Approval ref="ApprovalRef" @success="getList" />
+  </el-skeleton>
+</template>
+
+
+<script setup lang="ts">
+import {type ComponentSize, ElCol, ElImage} from "element-plus";
+import {SpecimenOutboundApi, SpecimenOutboundVO} from "@/api/museums/specimenoutbound";
+import {formatDate} from "@/utils/formatTime";
+import {reactive, ref} from "vue";
+import {DICT_TYPE} from "@/utils/dict";
+import Approval from "@/views/museums/specimenoutbound/approval.vue"
+
+const size = ref<ComponentSize>('large')
+let outboundData = ref(null); // 初始化响应式数据
+const {query} = useRoute() // 查询参数
+const loading = ref(true) // 列表的加载中
+const list = ref<SpecimenOutboundVO[]>([]) // 列表的数据
+const total = ref(0) // 列表的总页数
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  infoId: undefined,
+  chineseName: undefined,
+  specimenNumber: undefined,
+  attachments: undefined,
+  processInstanceId: undefined,
+  specimenCondition: undefined,
+  imagePath:undefined
+})
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await SpecimenOutboundApi.getSpecimenOutboundDetailsPage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+const fetchData = async () => {
+  try {
+    console.log(query.dataId)
+    let res: any = await SpecimenOutboundApi.getSpecimenOutboundDetails(query.dataId)
+    console.log(res)
+    outboundData.value = res
+    console.log(outboundData.value)
+  }  finally {
+  }
+}
+
+// // 在组件加载时获取数据
+onMounted(async () => {
+  await fetchData()
+  await getList()
+})
+
+/** 审批按钮操作 */
+
+// 检查用户权限的方法
+const ApprovalRef = ref()
+const handleApproval = ( id?: number) => {
+  ApprovalRef.value.open( id)
+
+}
+</script>
+
+<style scoped>
+:deep(.my-label) {
+  background: #FAF8F7 !important;
+  width: 180px;
+}
+:deep(.my-content) {
+  height: 143px;
+}
+</style>

+ 211 - 36
src/views/museums/specimenoutbound/OutboundForm/InitiativeProcessInstance.vue

@@ -1,18 +1,85 @@
 <template>
   <Dialog
     v-model="dialogVisible"
-    title="标本出库申请驳回原因:"
+    title="修改申请"
     width="800"
+    ref="initiativeFormRef"
     v-loading="formLoading">
-    <el-form
-      ref="initiativeFormRef"
-      v-loading="formLoading"
-      v-if="outboundData"
-     >
-<text>{{ outboundData.processInstanceId }}</text>
-    </el-form>
+    <!-- 编辑表单 -->
+<div v-if="formType !== 'view'">
+  <div style="margin-bottom: 20px;color: red;font-size: 20px">
+    申请驳回原因:{{outboundData.processInstanceId}}
+  </div>
+  <div v-if="someType !== 'view'">
+  <el-form
+    ref="initiativeFormRef"
+    :model="outboundData"
+    :rules="formRules"
+    label-width="140px"
+    v-loading="formLoading"
+    v-if="outboundData"
+
+  >
+    <div style="margin-bottom: 20px;margin-left: 70px;font-size: 18px; font-weight: bold">请重新申请</div>
+
+
+    <!--        点击添加的时候扩展一栏,即formData.specimenNumber的长度+1-->
+    <el-button type="primary"
+               style="float: right"
+               @click="removeSpecimenNumber">-</el-button>
+    <el-button type="primary"
+               style="float: right"
+               @click="addSpecimenNumber">+</el-button>
+
+    <el-form-item
+      v-for="(id, index) in outboundData.specimenNumber"
+      :key="index"
+      :label="`标本编号 ${index + 1}`"
+      prop="specimenNumber"
+      label-width="150px"
+    >
+      <el-input v-model="outboundData.specimenNumber[index]" placeholder="请输入标本编号" />
+    </el-form-item>
+    <el-form-item label="申请人或申请单位"  prop="applicantName" label-width="150px">
+      <el-input v-model="outboundData.applicantName" placeholder="请输入申请人或申请单位" label-width="150px"/>
+    </el-form-item>
+    <el-form-item label="申请日期" prop="applicationDate" label-width="150px">
+      <el-date-picker
+        v-model="outboundData.applicationDate"
+        type="date"
+        value-format="x"
+        placeholder="选择申请日期"
+      />
+    </el-form-item>
+    <el-form-item label="申请出库的用途" prop="applicationUsage" label-width="150px">
+      <el-input v-model="outboundData.applicationUsage" placeholder="请输入申请出库的用途" label-width="150px"/>
+    </el-form-item>
+    <el-form-item label="附件上传" prop="attachments" label-width="150px">
+      <UploadImg v-model="outboundData.attachments" />
+    </el-form-item>
+    <el-form-item label="预计领取日期" prop="outgoingTime" label-width="150px">
+      <el-date-picker
+        v-model="outboundData.expectedCollectionTime"
+        type="date"
+        value-format="x"
+        placeholder="选择领取日期"
+      />
+    </el-form-item>
+    <el-form-item label="退还日期" prop="returnDate" label-width="150px">
+      <el-date-picker
+        v-model="outboundData.returnDate"
+        type="date"
+        value-format="x"
+        placeholder="选择退还日期"
+        label-width="150px"
+      />
+    </el-form-item>
+  </el-form>
+  </div>
+</div>
     <template #footer>
-      <el-button @click="close">关闭</el-button>
+      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
     </template>
   </Dialog>
 
@@ -20,56 +87,164 @@
 
 
 <script setup lang="ts">
-import {ref} from "vue";
-import {SpecimenOutboundApi} from '@/api/museums/specimenoutbound'
+import {ref, reactive, onMounted} from "vue";
 
+import {SpecimenOutboundApi, SpecimenOutboundVO} from '@/api/museums/specimenoutbound'
+import {useRoute} from 'vue-router';
+import { useI18n } from 'vue-i18n';
 defineOptions({name: 'InitiativeProcessInstance'})
 const formLoading = ref(false) // 表单的加载中
 const dialogVisible = ref(false) // 弹窗的是否展示
 const formType = ref('')
-const {query} = useRoute() // 查询参数
-let outboundData = ref(null)
+ const {query} = useRoute() // 查询参数
+const someType = ref('')
+// 国际化和消息提示
+const { t } = useI18n();
+const message = useMessage();
+
+
+
+const formRef = ref() // 表单 Ref
+const initiativeFormRef = ref() // 表单 Ref
+const outboundData = ref({
+  id: undefined,
+  infoId: undefined,
+  chineseName: [],
+  specimenNumber: [''],
+  applicantName: undefined,
+  applicationDate: undefined,
+  applicationUsage: undefined,
+  attachments: undefined,
+  status: undefined,
+  remarks: undefined,
+  processInstanceId: undefined,
+  operator: undefined,
+  outgoingTime: undefined,
+  returner: undefined,
+  receiver: undefined,
+  returnDate: undefined,
+  specimenCondition: undefined,
+  sampleStatus: undefined,
+  expectedCollectionTime:undefined,
+
+})
+const formRules = reactive({
+  infoId: [{ required: true, message: '关联到总表中的标本ID不能为空', trigger: 'blur' }],
+  chineseName: [{ required: true, message: '中文名称不能为空', trigger: 'blur' }],
+  specimenNumber: [{ required: true, message: '申请出库的标本编号不能为空', trigger: 'blur' }],
+  applicantName: [{ required: true, message: '申请人或申请单位不能为空', trigger: 'blur' }],
+  applicationUsage: [{ required: true, message: '申请出库的用途不能为空', trigger: 'blur' }],
+  returnDate: [{ required: true, message: '退还日期不能为空', trigger: 'blur' }],
+  expectedCollectionTime: [{ required: true, message: '预计领取日期不能为空', trigger: 'blur' }]
+})
+
+
+/**增减标本编号**/
+const addSpecimenNumber = () => {
+  outboundData.value.specimenNumber.push(''); // 向数组中添加一个新的空字符串
+};
+const removeSpecimenNumber = () => {
+  if (outboundData.value.specimenNumber.length > 1) { // 确保至少保留一个输入框
+    outboundData.value.specimenNumber.pop(); // 从数组中移除最后一个元素
+  }
+};
+
+
 /** 打开弹窗 */
+// let formData= ref(null)
 const open = async (type: string, id?: number) => {
+
   dialogVisible.value = true
   formType.value = type
+  resetForm();
   if (id) {
     formLoading.value = true
     try {
-      const data = await SpecimenOutboundApi.getSpecimenOutboundPage(id)
-      formData.value = data;
-      console.log(data)
+      if (type === 'view' || type === 'someType') {
+        let res = await SpecimenOutboundApi.getSpecimenOutbound(id);
+        // console.log(res)
+        outboundData.value = res
+      }
     } finally {
       formLoading.value = false
     }
   }
 }
-defineExpose({open}) // 提供 open 方法,用于打开弹窗
-/** 关闭弹窗 */
-const close = () => {
-  dialogVisible.value = false;
-};
+  defineExpose({open}) // 提供 open 方法,用于打开弹窗
 
-const formData = ref({
-  infoId: undefined,
-  processInstanceId: undefined,
-})
 
-/**查看驳回信息*/
-const fetchData = async () => {
-  try {
-    console.log(query.dataId)
-    let res: any = await SpecimenOutboundApi.getSpecimenOutboundPage(query.dataId)
-    console.log(res)
-    outboundData.value = res
-    console.log(outboundData.value)
-  }  finally {
+
+
+/** 提交表单 */
+const emit = defineEmits(['success'])
+  const submitForm = async () => {
+    // 校验表单
+    await formRef.value.validate()
+    // 提交请求
+    formLoading.value = true;
+    try {
+      const data = outboundData.value as unknown as SpecimenOutboundVO
+      console.log(data)
+       if  (formType.value === 'someType') {
+          await SpecimenOutboundApi.alterSpecimenOutbound(data);
+          message.success(t('修改出库申请成功'));
+        }
+        dialogVisible.value = false;
+        emit('success')
+      } finally {
+        formLoading.value = false;
+
+      }
+  };
+
+/** 标本搜索选择 */
+
+// 重置表单的方法
+const resetForm = () => {
+  outboundData.value = {
+    id: undefined,
+    infoId: undefined,
+    chineseName: undefined,
+    specimenNumber: undefined,
+    applicantName: undefined,
+    applicationDate: undefined,
+    applicationUsage: undefined,
+    attachments: undefined,
+    status: undefined,
+    remarks: undefined,
+    processInstanceId: undefined,
+    operator: undefined,
+    outgoingTime: undefined,
+    returner: undefined,
+    receiver: undefined,
+    returnDate: undefined,
+    specimenCondition: undefined,
+    sampleStatus: undefined
   }
-}
+    initiativeFormRef.value?.resetFields();
+  }///
+
+
+// const handleClose = (index: number) => {
+//   outboundData.specimenNumber.value.splice(index, 1); // 删除指定索引的标签
+// };
+//
+// const handleInputEnter = () => {
+//   if (specimenNumber.value.trim() !== '') {
+//     outboundData.specimenNumber.value.push(specimenNumber.value); // 添加新的标本编号
+//     specimenNumber.value = ''; // 清空输入框
+//   }
+// };
+
 
 // // 在组件加载时获取数据
 onMounted(async () => {
-  await fetchData()
+
+  console.log(1)
+   // await fetchData()
+  await submitForm()
 
 })
+
+
 </script>

+ 132 - 57
src/views/museums/specimenoutbound/OutboundForm/outboundDetail.vue

@@ -7,74 +7,102 @@
 
             <template #header>
               <div class="card-header" style="text-align: center">
-                <h1 class="text1">标本出库入库申请详情</h1>
+                <h1 class="text1">标本出库入库详情</h1>
               </div>
             </template>
 
 <el-row>
-           <el-col :xl="20" :lg="20" :md="24" :sm="24" :xs="24" >
-              <el-descriptions  v-if="outboundData"
-                                border>
-              <el-descriptions-item label="申请人或申请单位:" label-align="right" >{{
+           <el-col :xl="11" :lg="11" :md="24" :sm="24" :xs="24" >
+              <el-descriptions
+                :column="1"
+                v-if="outboundData"
+                :size="size"
+
+                border>
+              <el-descriptions-item label="申请人姓名:" label-align="right" label-class-name="my-label">{{
                   outboundData.applicantName
                 }}
               </el-descriptions-item>
-              <el-descriptions-item label="申请日期:" label-align="right" >{{
-                  outboundData.applicationDate
-                }}
-              </el-descriptions-item>
-              <el-descriptions-item label="申请出库的用途:" label-align="right" >{{
+              <el-descriptions-item label="申请单位:" label-align="right" label-class-name="my-label">{{
                   outboundData.applicationUsage
                 }}
               </el-descriptions-item>
-              <el-descriptions-item label="审批状态:" label-align="right" v-if="outboundData">{{
-                  statusText
-                }}
-              </el-descriptions-item>
-              <el-descriptions-item label="驳回原因" label-align="right">{{
-                  outboundData.processInstanceId
-                }}
-              </el-descriptions-item>
-              <el-descriptions-item label="审批员:" label-align="right" >{{
-                  outboundData.approveUsers
+              <el-descriptions-item label="电话号码:" label-align="right" label-class-name="my-label">{{
+                  outboundData.phoneNumber
                 }}
               </el-descriptions-item>
-              <el-descriptions-item label="审批时间:" label-align="right" >{{
-                  outboundData.approvalTime
-                }}
-              </el-descriptions-item>
-              <el-descriptions-item label="备注信息:" label-align="right" >{{outboundData.remarks}}
-              </el-descriptions-item>
-
-                <el-descriptions-item label="出库时间:" label-align="right" >{{ outboundData.outgoingTime }}</el-descriptions-item>
-                <el-descriptions-item label="出库员:" label-align="right">{{  outboundData.operator}}
+                <el-descriptions-item label="研究项目名称:" label-align="right" label-class-name="my-label">{{
+                    outboundData.projectName }}</el-descriptions-item>
+                <el-descriptions-item label="项目开始时间:" label-align="right" label-class-name="my-label">{{
+                    outboundData.startTime }}</el-descriptions-item>
+                <el-descriptions-item label="项目结束时间:" label-align="right" label-class-name="my-label">{{
+                    outboundData.endTime
+                  }}
                 </el-descriptions-item>
-
-                <el-descriptions-item label="退还日期" label-align="right" >{{
-                    outboundData.returnDate
+                <el-descriptions-item label="一审时间:" label-align="right" label-class-name="my-label">{{
+                    outboundData.approvalTime
                   }}
                 </el-descriptions-item>
-                <el-descriptions-item label="点收人:" label-align="right" >{{
-                    outboundData.receiver
+                <el-descriptions-item label="一审审批者:" label-align="right"  label-class-name="my-label">{{
+                    outboundData.approveUsers
                   }}
                 </el-descriptions-item>
-
-
-                <el-descriptions-item label="退还人" label-align="right">{{
-                    outboundData.returner
+                <el-descriptions-item label="一审建议" label-align="right"  label-class-name="my-label">{{
+                    outboundData.processInstanceId
                   }}
                 </el-descriptions-item>
-
-
-
             </el-descriptions>
     </el-col>
-
-
-              <el-col :xl="4" :lg="4" :md="24" :sm="24" :xs="24" >
+  <el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24" >
+    <el-descriptions
+      :column="1"
+      v-if="outboundData"
+      :size="size"
+      border>
+      <el-descriptions-item label="二审时间:" label-align="right" label-class-name="my-label">{{
+          outboundData.twoApprovalTime
+        }}
+      </el-descriptions-item>
+      <el-descriptions-item label="二审审批者:" label-align="right"  label-class-name="my-label">{{
+          outboundData.twoApproveUsers
+        }}
+      </el-descriptions-item>
+      <el-descriptions-item label="二审建议" label-align="right"  label-class-name="my-label">{{
+          outboundData.rejectionReasons
+        }}
+      </el-descriptions-item>
+      <el-descriptions-item label="出库时间:" label-align="right" label-class-name="my-label">{{ outboundData.outgoingTime }}</el-descriptions-item>
+      <el-descriptions-item label="出库员:" label-align="right">{{  outboundData.operator}}
+      </el-descriptions-item>
+
+      <el-descriptions-item label="退还日期:" label-align="right" label-class-name="my-label">{{
+          outboundData.returnDate
+        }}
+      </el-descriptions-item>
+      <el-descriptions-item label="退还人:" label-align="right" label-class-name="my-label">{{
+          outboundData.returner
+        }}
+      </el-descriptions-item>
+      <el-descriptions-item label="点收人:" label-align="right" label-class-name="my-label">{{
+          outboundData.receiver
+        }}
+      </el-descriptions-item>
+
+
+
+      <el-descriptions-item label="回库备注信息:" label-align="right" label-class-name="my-label">{{outboundData.remarks}}
+      </el-descriptions-item>
+
+
+    </el-descriptions>
+  </el-col>
+
+              <el-col :xl="3" :lg="3" :md="24" :sm="24" :xs="24" >
                 <el-descriptions
                   v-if="outboundData"
                   direction="vertical"
+                  :column="1"
+                  :size="size"
                   border
                 >
                   <!--              <el-descriptions-item label="标本ID:"    label-align="right" >{{ outboundData.infoId }}</el-descriptions-item>-->
@@ -87,20 +115,46 @@
                     :width="140"
                     label="申请附件"
                     align="center"
-
+                    label-class-name="my-label"
+                    class-name="my-content"
                   ><div class="demo-image__preview" v-if="outboundData" >
-                    <block  v-for="(image, index) in attachments" :key="index">
+
                       <el-image
                         style="width: 40px; height:40px;margin-right: 5px"
                         class="h-80px w-80px"
                         lazy
-                        :src="image"
-                        :preview-src-list="imagePath"
+                        :src="outboundData.attachments"
+                        :preview-src-list="outboundData.attachments"
                         preview-teleported
                         fit="cover"
 
+
                       />
-                    </block>
+
+                  </div>
+
+                  </el-descriptions-item>
+                  <el-descriptions-item
+                    :rowspan="4"
+                    :width="140"
+                    label="回库附件"
+                    align="center"
+                    label-class-name="my-label"
+                    class-name="my-content"
+                  ><div class="demo-image__preview" v-if="outboundData" >
+
+                    <el-image
+                      style="width: 40px; height:40px;margin-right: 5px"
+                      class="h-80px w-80px"
+                      lazy
+                      :src="outboundData.sampleStatus"
+                      :preview-src-list="outboundData.sampleStatus"
+                      preview-teleported
+                      fit="cover"
+
+
+                    />
+
                   </div>
 
                   </el-descriptions-item>
@@ -123,23 +177,35 @@
 
 
                   <el-table v-loading="loading" :data="outboundData.specimenInfoList" :stripe="true" :show-overflow-tooltip="true" >
-                    <el-table-column label="标本ID" align="center" prop="id" />
+                    <el-table-column label="标本编号" align="center" prop="specimenNumber" />
                     <el-table-column label="中文名称" align="center" prop="chineseName" />
-                    <el-table-column label="标本编号" align="center" prop="specimenAmount" />
-                    <el-table-column label="标本类型" align="center" prop="specimenType" />
+                    <el-table-column label="标本类型" align="center" prop="specimenType">
+                      <template #default="scope">
+                        <dict-tag :type="DICT_TYPE.MUSEUMS_SPECIMEN_TYPE" :value="scope.row.specimenType" />
+                      </template>
+                    </el-table-column>
                     <el-table-column label="标本重量(g)" align="center" prop="weight" />
-                    <el-table-column label="标本图片" align="center" prop="imagePath" >
+                    <el-table-column label="保存位置" align="center" prop="storageLocation" />
+                    <el-table-column label="保存类型" align="center" prop="preservationType">
+                      <template #default="scope">
+                        <dict-tag :type="DICT_TYPE.MUSEUMS_SPECIMEN_INFO" :value="scope.row.preservationType" />
+                      </template>
+                    </el-table-column>
+                    <el-table-column label="标本图片" align="center" prop="url" >
                       <template #default="{ row }">
+                        <div class="demo-image__preview" v-if="queryParams" >
+                        <block  v-for="(image, index) in row.imagePath" :key="index">
                         <el-image
-                          v-for="(image, index) in row.imagePath"
-                          :key="index"
                           class="image-class"
                           lazy
                           :src="image"
+                          :preview-src-list="row.imagePath"
+                          preview-teleported
                           fit="cover" />
+                        </block>
+                        </div>
                       </template>
                     </el-table-column>
-                    <el-table-column label="保存位置" align="center" prop="storageLocation" />
                   </el-table>
                   <!-- 分页 -->
                   <Pagination
@@ -155,13 +221,15 @@
   </el-skeleton>
 </template>
 <script setup lang="ts">
-import {ElCol} from "element-plus";
+import {type ComponentSize, ElCol} from "element-plus";
 import {ref, reactive, onMounted, computed} from "vue";
 import {SpecimenOutboundApi, SpecimenOutboundVO} from "@/api/museums/specimenoutbound";
 import { formatDate} from "@/utils/formatTime";
+import {DICT_TYPE} from "@/utils/dict";
 
 
 defineOptions({ name: 'outboundDetail' })
+const size = ref<ComponentSize>('large')
 const {query} = useRoute() // 查询参数
 const loading = ref(true) // 列表的加载中
 const list = ref<SpecimenOutboundVO[]>([]) // 列表的数据
@@ -237,5 +305,12 @@ const statusText = computed(() => {
 </script>
 
 <style scoped>
+:deep(.my-label) {
+  background: #FAF8F7 !important;
+  width: 180px;
+}
+:deep(.my-content) {
+  height:167px;
+}
 
 </style>

+ 3 - 3
src/views/museums/specimenoutbound/OutboundForm/specimenReturnForm.vue

@@ -7,9 +7,9 @@
       :rules="formRules"
       label-width="100px"
     >
-      <el-form-item label="标本ID" prop="infoId">
-        <el-input v-model="formData.infoId" placeholder="请输入标本ID"/>
-      </el-form-item>
+<!--      <el-form-item label="标本ID" prop="infoId">-->
+<!--        <el-input v-model="formData.infoId" placeholder="请输入标本ID"/>-->
+<!--      </el-form-item>-->
       <el-form-item label="退还人" prop="returner">
         <el-input v-model="formData.returner" placeholder="请输入退还人"/>
       </el-form-item>

+ 12 - 8
src/views/museums/specimenoutbound/OutboundManagement.vue

@@ -90,12 +90,12 @@
 
   <!-- 列表 -->
   <ContentWrap>
+
     <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
       <el-table-column label="序号" align="center" prop="id" />
-      <el-table-column label="标本ID" align="center" prop="infoId" />
-      <el-table-column label="中文名称" align="center" prop="chineseName" />
-      <el-table-column label="标本编号" align="center" prop="specimenNumber" />
-      <el-table-column label="申请人(单位)" align="center" width="120px" prop="applicantName" />
+      <el-table-column label="申请人姓名" align="center" width="120px" prop="applicantName" />
+      <el-table-column label="申请单位" align="center" width="120px" prop="applicationUsage" />
+      <el-table-column label="研究项目名称" align="center" prop="projectName" />
       <el-table-column
         label="申请日期"
         align="center"
@@ -103,7 +103,6 @@
         :formatter="dateFormatter"
         width="180px"
       />
-      <el-table-column label="用途" align="center" prop="applicationUsage" />
       <el-table-column label="审批状态" align="center" prop="status"  >
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.MUSEUMS_APPROAL_STATUS" :value="scope.row.status" />
@@ -135,7 +134,7 @@
           查看
           </el-button>
           <el-button
-            v-if=" scope.row.status !== 2 && scope.row.status !== 3  && scope.row.status !== 4"
+            v-if=" scope.row.status !== 0 && scope.row.status !== 1 && scope.row.status !== 2 && scope.row.status !== 3 && scope.row.status !== 4 && scope.row.status !== 6  "
             link
             type="primary"
             @click="handleOutbound(scope.row.id)"
@@ -143,7 +142,7 @@
             出库
           </el-button>
           <el-button
-            v-if="scope.row.status !== 2 && scope.row.status !== 4"
+            v-if="scope.row.status !== 0 && scope.row.status !== 1 && scope.row.status !== 2 && scope.row.status !== 4 && scope.row.status !== 5 && scope.row.status !== 6"
             link
             type="success"
             @click=" openForm(scope.row.id)"
@@ -178,6 +177,8 @@ import specimenReturnForm from '@/views/museums/specimenoutbound/OutboundForm/sp
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
 
+
+
 const loading = ref(true) // 列表的加载中
 const list = ref<SpecimenOutboundVO[]>([]) // 列表的数据
 const total = ref(0) // 列表的总页数
@@ -191,7 +192,7 @@ const queryParams = reactive({
   applicationDate: [],
   applicationUsage: undefined,
   attachments: undefined,
-  status: undefined,
+  status: [],
   remarks: undefined,
   processInstanceId: undefined,
   operator: undefined,
@@ -210,6 +211,7 @@ const exportLoading = ref(false) // 导出的加载中
 const getList = async () => {
   loading.value = true
   try {
+
     const data = await SpecimenOutboundApi.getSpecimenOutboundPage(queryParams)
     list.value = data.list
     total.value = data.total
@@ -282,6 +284,8 @@ const openForm = (type: string, id?: number) => {
   formRef.value.open(type, id)
 }
 
+
+;
 /** 初始化 **/
 onMounted(() => {
   getList()

+ 195 - 77
src/views/museums/specimenoutbound/SpecimenOutboundForm.vue

@@ -7,19 +7,39 @@
       label-width="140px"
       v-loading="formLoading"
     >
-      <el-form-item label="标本ID" prop="infoId">
-        <el-input v-model="formData.infoId" placeholder="请输入标本ID" />
-      </el-form-item>
-      <el-form-item label="中文名称" prop="chineseName">
-        <el-input v-model="formData.chineseName" placeholder="请输入中文名称" />
+<!--      <div>-->
+<!--        <div style="margin-bottom: 20px;color: red;font-size: 20px">-->
+<!--          申请驳回原因:{{formData.processInstanceId}}-->
+<!--        </div>-->
+<!--            <div style="margin-bottom: 20px;margin-left: 70px;font-size: 18px; font-weight: bold">请重新申请</div>-->
+<!--            </div>-->
+
+      <!--        点击添加的时候扩展一栏,即formData.specimenNumber的长度+1-->
+      <el-button type="primary"
+                 style="float: right ;margin-left: 5px; padding: 5px 10px; font-size: 12px;"
+                 @click="removeSpecimenNumber">-</el-button>
+      <el-button type="primary"
+                 style="float: right; padding: 5px 10px; font-size: 12px;"
+                 @click="addSpecimenNumber">+</el-button>
+      <el-form-item label="标本编号"  prop="number" label-width="150px">
+        <el-input v-model="formData.number[0]" placeholder="请输入标本编号" label-width="150px"/>
       </el-form-item>
-      <el-form-item label="标本编号" prop="specimenNumber">
-        <el-input v-model="formData.specimenNumber" placeholder="请输入标本编号" />
+        <el-form-item
+          v-for="(item, index) in formData.number.slice(1)"
+          :key="index + 1"
+          :label="`标本编号 ${index + 2}`"
+          prop="number"
+          label-width="150px"
+        >
+          <el-input v-model="formData.number[index + 1]" placeholder="请输入标本编号" />
+        </el-form-item>
+      <el-form-item label="申请人姓名"  prop="applicantName" label-width="150px">
+        <el-input v-model="formData.applicantName" placeholder="请输入申请人姓名" label-width="150px"/>
       </el-form-item>
-      <el-form-item label="申请人或申请单位"  prop="applicantName">
-        <el-input v-model="formData.applicantName" placeholder="请输入申请人或申请单位" />
+      <el-form-item label="申请单位"  prop="applicantName" label-width="150px">
+        <el-input v-model="formData.applicationUsage" placeholder="请输入申请人姓名" label-width="150px"/>
       </el-form-item>
-      <el-form-item label="申请日期" prop="applicationDate">
+      <el-form-item label="申请日期" prop="applicationDate" label-width="150px">
         <el-date-picker
           v-model="formData.applicationDate"
           type="date"
@@ -27,56 +47,51 @@
           placeholder="选择申请日期"
         />
       </el-form-item>
-      <el-form-item label="申请出库的用途" prop="applicationUsage">
-        <el-input v-model="formData.applicationUsage" placeholder="请输入申请出库的用途" />
+      <el-form-item label="研究项目名称" prop="projectName" label-width="150px">
+        <el-input v-model="formData.projectName" placeholder="请输入申请出库的用途" label-width="150px"/>
+      </el-form-item>
+      <el-form-item label="电话号码" prop="phoneNumber" label-width="150px">
+        <el-input v-model="formData.phoneNumber" placeholder="电话号码" label-width="150px"/>
       </el-form-item>
-      <el-form-item label="附件上传" prop="attachments">
-          <UploadImg v-model="formData.attachments" />
+      <el-form-item label="附件上传" prop="attachments" label-width="150px">
+        <el-upload
+          ref="uploadRef"
+          v-model:file-list="fileList"
+          :action="importUrl + '?another=' + 1"
+          :auto-upload="false"
+          :data="data"
+          :disabled="formLoading"
+          :limit="1"
+          :on-change="handleFileChange"
+          :on-error="submitFormError"
+          :on-exceed="handleExceed"
+          :on-success="submitFormSuccess"
+          drag
+          :headers="uploadHeaders"
+        >
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text"> 将文件拖到此处,或 <em>点击上传</em></div>
+        </el-upload>
       </el-form-item>
-<!--      <el-form-item label="审批状态" prop="status">-->
-<!--        <el-select v-model="formData.status" placeholder="请选择审批状态">-->
-<!--          <el-option label="请选择字典生成" value="" />-->
-<!--        </el-select>-->
-<!--      </el-form-item>-->
-<!--      <el-form-item label="备注信息" prop="remarks">-->
-<!--        <el-input v-model="formData.remarks" placeholder="请输入备注信息" />-->
-<!--      </el-form-item>-->
-<!--      <el-form-item label="流程实例的编号" prop="processInstanceId">-->
-<!--        <el-input v-model="formData.processInstanceId" placeholder="请输入流程实例的编号" />-->
-<!--      </el-form-item>-->
-<!--      <el-form-item label="出库员" prop="operator">-->
-<!--        <el-input v-model="formData.operator" placeholder="请输入出库员" />-->
-<!--      </el-form-item>-->
-<!--      <el-form-item label="出库时间" prop="outgoingTime">-->
-<!--        <el-date-picker-->
-<!--          v-model="formData.outgoingTime"-->
-<!--          type="date"-->
-<!--          value-format="x"-->
-<!--          placeholder="选择出库时间"-->
-<!--        />-->
-<!--      </el-form-item>-->
-<!--      <el-form-item label="退还人" prop="returner">-->
-<!--        <el-input v-model="formData.returner" placeholder="请输入退还人" />-->
-<!--      </el-form-item>-->
-<!--      <el-form-item label="点收人" prop="receiver">-->
-<!--        <el-input v-model="formData.receiver" placeholder="请输入点收人" />-->
-<!--      </el-form-item>-->
-      <el-form-item label="退还日期" prop="returnDate">
+
+      <el-form-item label="预计领取日期" prop="outgoingTime" label-width="150px">
         <el-date-picker
-          v-model="formData.returnDate"
+          v-model="formData.expectedCollectionTime"
+          type="date"
+          value-format="x"
+          placeholder="选择领取日期"
+        />
+      </el-form-item>
+
+      <el-form-item label="预计退还日期" prop="returnDate" label-width="150px">
+        <el-date-picker
+          v-model="formData.estimatedReturnTime"
           type="date"
           value-format="x"
           placeholder="选择退还日期"
         />
       </el-form-item>
-<!--      <el-form-item label="标本情况" prop="specimenCondition">-->
-<!--        <el-input v-model="formData.specimenCondition" placeholder="请输入标本情况" />-->
-<!--      </el-form-item>-->
-<!--      <el-form-item label="标本状态(已出库、已回库、出库审批中)" prop="sampleStatus">-->
-<!--        <el-select v-model="formData.sampleStatus" placeholder="请选择标本状态(已出库、已回库、出库审批中)">-->
-<!--          <el-option label="请选择字典生成" value="" />-->
-<!--        </el-select>-->
-<!--      </el-form-item>-->
+
     </el-form>
     <template #footer>
       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
@@ -87,14 +102,17 @@
 </template>
 <script setup lang="ts">
 import { SpecimenOutboundApi, SpecimenOutboundVO } from '@/api/museums/specimenoutbound'
-import { UploadFilled } from '@element-plus/icons-vue'
-import {ref} from "vue";
+//import { UploadFilled } from '@element-plus/icons-vue'
+import {ref, reactive, defineEmits} from "vue";
 /** 标本出库回库信息 表单 */
 defineOptions({ name: 'SpecimenOutboundForm' })
-
+const importUrl =
+  import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + 'museums:specimen-outbound:create'
 const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
-
+const fileList = ref([]) // 文件列表
+const data = ref({ path: '' })
+const uploadRef = ref()
 const dialogVisible = ref(false) // 弹窗的是否展示
 const dialogTitle = ref('') // 弹窗的标题
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
@@ -102,8 +120,8 @@ const formType = ref('') // 表单的类型:create - 新增;update - 修改
 const formData = ref({
   id: undefined,
   infoId: undefined,
-  chineseName: undefined,
-  specimenNumber: undefined,
+  chineseName: [],// 确保初始值为数组
+  number: [''],// 确保初始值为数组
   applicantName: undefined,
   applicationDate: undefined,
   applicationUsage: undefined,
@@ -117,21 +135,33 @@ const formData = ref({
   receiver: undefined,
   returnDate: undefined,
   specimenCondition: undefined,
-  sampleStatus: undefined
+  sampleStatus: undefined,
+  estimatedReturnTime: undefined,
+  expectedCollectionTime:undefined
 })
+
+
 const formRules = reactive({
-  infoId: [{ required: true, message: '关联到总表中的标本ID不能为空', trigger: 'blur' }],
   chineseName: [{ required: true, message: '中文名称不能为空', trigger: 'blur' }],
-  specimenNumber: [{ required: true, message: '申请出库的标本编号不能为空', trigger: 'blur' }],
+  number: [{ required: true, message: '申请出库的标本编号不能为空', trigger: 'blur' }],
   applicantName: [{ required: true, message: '申请人或申请单位不能为空', trigger: 'blur' }],
   applicationUsage: [{ required: true, message: '申请出库的用途不能为空', trigger: 'blur' }],
   operator: [{ required: true, message: '出库员不能为空', trigger: 'blur' }],
   returner: [{ required: true, message: '退还人不能为空', trigger: 'blur' }],
   receiver: [{ required: true, message: '点收人不能为空', trigger: 'blur' }],
-  returnDate: [{ required: true, message: '退还日期不能为空', trigger: 'blur' }]
+  estimatedReturnTime: [{ required: true, message: '预计退还日期不能为空', trigger: 'blur' }],
+  expectedCollectionTime: [{ required: true, message: '预计领取日期不能为空', trigger: 'blur' }]
 })
 const formRef = ref() // 表单 Ref
-
+/**增减标本编号**/
+const addSpecimenNumber = () => {
+  formData.value.number.push(''); // 向数组中添加一个新的空字符串
+};
+const removeSpecimenNumber = () => {
+  if (formData.value.number.length > 0) { // 确保至少保留一个输入框
+    formData.value.number.pop(); // 从数组中移除最后一个元素
+  }
+};
 /** 打开弹窗 */
 const open = async (type: string, id?: number) => {
   dialogVisible.value = true
@@ -150,37 +180,123 @@ const open = async (type: string, id?: number) => {
 }
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 
+
+
+// /** 标本搜索选择 */
+// const props = reactive({
+//   value: 'value',
+//   label: 'label',
+//   children: 'children',
+//   multiple: true
+// });
+//
+// const options = ref([]);
+//
+// const fetchOptions = async () => {
+//   try {
+//     const response = await SpecimenOutboundApi.createSpecimenOutbound();
+//     options.value = processOptions(response.data);
+//   } catch (error) {
+//     console.error('获取选项数据失败:', error);
+//   }
+// };
+//
+// const processOptions = (data) => {
+//   // 将后端数据格式化为 el-cascader 需要的格式
+//   return data.map(item => ({
+//     value: item.id, // 假设后端返回的ID字段是id
+//     label: item.name, // 假设后端返回的名称字段是name
+//     children: item.children ? processOptions(item.children) : undefined
+//   }));
+// };
+//
+//
+// const handleCascaderChange = (value, formData) => {
+//   formData.value.chineseName = value;
+// };
+
+
+
+
+/** 上传错误提示 */
+const submitFormError = (): void => {
+  message.error('上传失败,请您重新上传!')
+  formLoading.value = false
+}
+/** 处理上传的文件发生变化 */
+const handleFileChange = (file) => {
+  data.value.path = file.name
+}
+const uploadHeaders = ref() // 上传 Header 头
+
+/** 文件数超出提示 */
+const handleExceed = (): void => {
+  message.error('最多只能上传一个文件!')
+}
+
 /** 提交表单 */
 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+// const submitForm = async () => {
+//   // 校验表单
+//   await formRef.value.validate()
+//   // 提交请求
+//   formLoading.value = true
+//   try {
+//     const data = formData.value as unknown as SpecimenOutboundVO
+//     if (formType.value === 'create') {
+//       await SpecimenOutboundApi.createSpecimenOutbound(data)
+//       message.success(t('新增标本出库申请成功'))
+//     } else {
+//       await SpecimenOutboundApi.alterSpecimenOutbound(data)
+//       message.success(t('标本出库申请修改成功'))
+//     }
+//     dialogVisible.value = false
+//     // 发送操作成功的事件
+//     emit('success')
+//   } finally {
+//     formLoading.value = false
+//   }
+// }
+//
+
 const submitForm = async () => {
   // 校验表单
-  await formRef.value.validate()
+
+  await formRef.value.validate();
+
+  // // 将数组字段转换为字符串
+  // if (formData.value.chineseName.length) {
+  //   formData.value.chineseName = formData.value.chineseName.join(',');
+  // }
+  // if (formData.value.specimenNumber.length) {
+  //   formData.value.specimenNumber = formData.value.specimenNumber.join(',');
+  // }
+
   // 提交请求
-  formLoading.value = true
+  formLoading.value = true;
   try {
-    const data = formData.value as unknown as SpecimenOutboundVO
+    const data = formData.value as unknown as SpecimenOutboundVO;
     if (formType.value === 'create') {
-      await SpecimenOutboundApi.createSpecimenOutbound(data)
-      message.success(t('新增标本出库申请成功'))
+      await SpecimenOutboundApi.createSpecimenOutbound(data);
+      message.success(t('新增标本出库申请成功'));
     } else {
-      await SpecimenOutboundApi.alterSpecimenOutbound(data)
-      message.success(t('标本出库申请修改成功'))
+      await SpecimenOutboundApi.alterSpecimenOutbound(data);
+      message.success(t('标本出库申请修改成功'));
     }
-    dialogVisible.value = false
+    dialogVisible.value = false;
     // 发送操作成功的事件
-    emit('success')
+    emit('success');
   } finally {
-    formLoading.value = false
+    formLoading.value = false;
   }
-}
-//
+};
 /** 重置表单 */
 const resetForm = () => {
   formData.value = {
     id: undefined,
     infoId: undefined,
-    chineseName: undefined,
-    specimenNumber: undefined,
+    chineseName: [],// 确保初始值为数组
+    number: [],// 确保初始值为数组
     applicantName: undefined,
     applicationDate: undefined,
     applicationUsage: undefined,
@@ -198,4 +314,6 @@ const resetForm = () => {
   }
   formRef.value?.resetFields()
 }
+
+
 </script>

+ 21 - 32
src/views/museums/specimenoutbound/approval.vue

@@ -13,17 +13,24 @@
           <el-radio :label="2">驳回</el-radio>
         </el-radio-group>
       </el-form-item>
+
+        <el-form-item  v-if="approvalStatus === 1">
+          <el-input
+            v-model="formData.processInstanceId"
+            style="width:800px; height: 200px"
+            placeholder="请输入审批建议"
+            type="textarea"
+          />
+        </el-form-item>
       <el-form-item  v-if="approvalStatus === 2">
         <el-input
-          v-model="formData.remarks"
+          v-model="formData.chkRemarks"
           style="width:800px ;height: 200px"
           placeholder="请输入驳回原因"
           type="textarea"
-          autosize
         />
       </el-form-item>
     </el-form>
-
     <div>
         <el-button :disabled="formLoading" type="primary" @click="submitApproval">确定</el-button>
         <el-button type="danger" @click="dialogVisible = false">取消</el-button>
@@ -46,38 +53,21 @@ const dialogVisible = ref(false) // 弹窗的是否展示
 
 const chkRemarks = ref('')
 const message = useMessage() // 消息弹窗
-// const processInstanceId = ref([]) // 文件列表
 
-// const updateSupport = ref(0) // 是否更新已经存在的标本数据
 const formData = ref({
   id: undefined,
   processInstanceId:undefined,
-  remarks : undefined
+  chkRemarks : undefined
 })
 /** 打开弹窗 */
 const open = async (id?: number) => {
   dialogVisible.value = true
-  // formLoading.value = true
   approvalStatus.value = 0
-
-  // updateSupport.value = 0
-  // processInstanceId.value = []
   chkRemarks.value = '';
   formData.value.id = id
   resetForm()
   console.log(id)
-  // if (id) {
-  //   // console.log(id,formData)
-  //   formData.value.id = id
-  //   console.log(formData.value)
-  //   formLoading.value = true
-  //   // try {
-  //   //   // formData.value = await SpecimenOutboundApi.ApprovalSpecimenOutbound(id)
-  //   // }
-  //   finally {
-  //     formLoading.value = false
-  //   }
-  // }
+
 }
 defineExpose({ open })// 提供 open 方法,用于打开弹窗
 
@@ -86,21 +76,20 @@ defineExpose({ open })// 提供 open 方法,用于打开弹窗
 /** 提交审批 */
 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
 const submitApproval = async () => {
-
-  // const id= formData.value as unknown as SpecimenOutboundVO
-  if (approvalStatus.value === 2 && !chkRemarks.value.trim()) {
-    // await SpecimenOutboundApi.ApprovalSpecimenOutbound(formData.value.id)
+  // 检查是否有驳回原因
+  if ((approvalStatus.value === 2 || approvalStatus.value === 6)  && !formData.value.chkRemarks.trim()) {
     message.error(t('请输入驳回原因'))
     return// 阻止表单提交
   }
-  // formLoading.value = true;
   try {
     formLoading.value = true;
-    if (approvalStatus.value === 1) {
-      await SpecimenOutboundApi.ApprovalPassSpecimenOutbound(formData.value)
-    } else {
-      await SpecimenOutboundApi.ApprovalSpecimenOutbound(formData.value);
-    }
+    const data = {
+      ...formData.value,
+     status: approvalStatus.value, // 确保传入审批状态
+      approvalRemarks:  (approvalStatus.value === 2 || approvalStatus.value === 6)? chkRemarks.value : '' // 如果是驳回,则传入驳回原因
+    };
+
+      await SpecimenOutboundApi.ApprovalSpecimenOutbound(data)
     message.success(t('common.updateSuccess'));
     dialogVisible.value = false
     // 发送操作成功的事件