From c6e96cdb8b1cfb51e9a45bf86c38d1353e983127 Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期一, 19 十月 2026 15:19:48 +0800
Subject: [PATCH] 设备模块业务完善及前序页面优化

---
 src/views/CNAS/resourceDemand/device/component/files.vue |  202 +++++++++++++++++++++++++++-----------------------
 1 files changed, 109 insertions(+), 93 deletions(-)

diff --git a/src/views/CNAS/resourceDemand/device/component/files.vue b/src/views/CNAS/resourceDemand/device/component/files.vue
index 4228c5f..ec28e92 100644
--- a/src/views/CNAS/resourceDemand/device/component/files.vue
+++ b/src/views/CNAS/resourceDemand/device/component/files.vue
@@ -15,12 +15,16 @@
       <el-row :gutter="20">
         <el-col :span="6">
           <!-- 鍔犳椂闂存埑閬垮厤娴忚鍣ㄧ紦瀛橀棶棰� -->
-          <el-image :src="`${javaApi}/img/${Mdata.imageUpload}`" fit="fill" :key="'personalPicture' + timeStamp"
+          <el-image v-if="Mdata.imageUpload" :src="`${javaApi}/img/${Mdata.imageUpload}`" fit="fill" :key="'personalPicture' + timeStamp"
             style="width: 200px;height: 300px;border: 1px solid #000;border-radius: 10px;margin-left: 30px;margin-top: 20px;">
             <template #error><div  class="image-slot">
               <lims-icon name="el-icon-picture-outline" style="font-size: 40px;"></lims-icon>
             </div></template>
           </el-image>
+          <div v-else class="image-slot"
+            style="width: 198px;height: 298px;border: 1px solid #000;border-radius: 10px;margin-left: 30px;margin-top: 20px;display: flex;align-items: center;justify-content: center;">
+            <lims-icon name="el-icon-picture-outline" style="font-size: 40px;"></lims-icon>
+          </div>
         </el-col>
         <el-col :span="8">
           <div class="form-item">
@@ -52,10 +56,6 @@
           </div>
 
           <div class="form-item">
-            <label>鍑哄巶鏃ユ湡</label>
-            <p>{{ formaterDateTime(Mdata.acquisitionDate) }}</p>
-          </div>
-          <div class="form-item">
             <label>鏍″噯鏈夋晥鏈�</label>
             <p>{{ formaterDateTime(Mdata.activationDate) }}</p>
           </div>
@@ -65,19 +65,11 @@
           </div>
 
           <div class="form-item">
-            <label>鎶ュ簾鏃堕棿</label>
-            <p>{{ handleData() }}</p>
-          </div>
-          <div class="form-item">
             <label>鍑嗙‘搴﹂噺鍊�</label>
             <el-tooltip class="item" :content="Mdata.technicalIndicators">
               <span class="text-ellipsis">{{ Mdata.technicalIndicators }}</span>
             </el-tooltip>
             <!-- <p>{{ Mdata.technicalIndicators }}</p> -->
-          </div>
-          <div class="form-item">
-            <label>缁翠慨璁板綍</label>
-            <p>{{ handleData() }}</p>
           </div>
           <div class="form-item">
             <label>琚巿鏉冧汉</label>
@@ -136,15 +128,11 @@
           </div>
           <div class="form-item">
             <label>閲囪喘璐圭敤(鍏�)</label>
-            <p>{{ Mdata.unitPrice }}</p>
+            <p>{{ formatPurchasePrice(Mdata.unitPrice) }}</p>
           </div>
           <div class="form-item">
             <label>璁惧璐熻矗浜�</label>
             <p>{{ Mdata.equipmentManagerName }}</p>
-          </div>
-          <div class="form-item">
-            <label>楠屾敹璁板綍</label>
-            <p>{{ handleData() }}</p>
           </div>
           <div class="form-item">
             <label>鏍稿噯璇佷功</label>
@@ -166,7 +154,7 @@
         <el-table-column prop="quantity" label="浠芥暟" min-width="80" />
         <el-table-column prop="pageCount" label="椤电爜" min-width="80" />
         <el-table-column prop="provider" label="鎻愪緵鑰�" min-width="150" />
-        <el-table-column prop="provideDate" label="褰掓。鏃ユ湡" min-width="170" />
+        <el-table-column prop="provideDate" label="褰掓。鏃ユ湡" min-width="170" :formatter="formatDateCell" />
         <el-table-column prop="comments" label="澶囨敞" min-width="150" />
         <el-table-column fixed="right" label="鎿嶄綔" min-width="180" align="center">
           <template #default="scope">
@@ -185,7 +173,7 @@
       <el-row>
         <el-col :span="7" style="padding-right: 20px;">
           <!-- 鍥剧墖 -->
-          <el-image class="img" style="width:100%;height: 320px;"
+          <el-image v-if="editData.imageUpload" class="img" style="width:100%;height: 320px;"
             :src="javaApi + '/img/' + editData.imageUpload">
             <template #error><div  class="image-error" style="width: calc(100% - 2px);
             height: 318px;
@@ -197,11 +185,15 @@
               <lims-icon name="el-icon-picture-outline" style="font-size:60px;color:var(--lims-text-2);"></lims-icon>
             </div></template>
           </el-image>
+          <div v-else class="image-error"
+            style="width: calc(100% - 2px);height: 320px;border-radius: 16px;display: flex;align-items: center;justify-content: center;border: 1px solid var(--lims-divider);">
+            <lims-icon name="el-icon-picture-outline" style="font-size:60px;color:var(--lims-text-2);"></lims-icon>
+          </div>
           <!-- 鍥剧墖涓婁紶 -->
           <div style="margin-top: 12px;text-align: center;">
             <div v-show="editData.imageName" class="picName">{{ editData.imageName }}</div>
             <el-upload :action="action" :on-success="handleSuccessUpImg2" :show-file-list="false"
-              accept='image/jpg,image/jpeg,image/png' :headers="uploadHeader" :on-change="beforeUpload"
+              accept='image/jpg,image/jpeg,image/png' :headers="uploadHeader" :before-upload="beforeUpload"
               :on-error="onError" ref='upload' class="avatar-uploader">
               <img v-if="editData.imageUpload" :src="javaApi + '/img/' + editData.imageUpload" class="avatar">
               <lims-icon name="el-icon-plus" v-else class="avatar-uploader-icon"></lims-icon>
@@ -276,7 +268,7 @@
               placeholder="璇烽�夋嫨" size="small" style="width:100%;" :collapse-tags="true" separator="," filterable
               clearable></el-cascader>
           </el-form-item>
-          <el-form-item label="璁惧绫诲瀷:">
+          <el-form-item label="璁惧/璁¢噺鍣ㄥ叿:">
             <el-select v-model="editData.largeCategory" placeholder="璇烽�夋嫨" size="small" style="width:100%">
               <el-option v-for="item in equipmentList" :key="item.value" :label="item.label" :value="item.value">
               </el-option>
@@ -319,17 +311,17 @@
         <div class="cycle-row">
           <span class="cycle-title">鏍″噯淇℃伅</span>
           <el-form-item label="鏈�杩戞牎鍑嗘棩鏈�:" class="cycle-item">
-            <el-date-picker style="width:100%" v-model="editData.lastCalibrationDate" format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
+            <el-date-picker style="width:100%" v-model="editData.lastCalibrationDate" @change="calcNextDate(editData)"
+              format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
             </el-date-picker>
           </el-form-item>
           <el-form-item label="涓嬫鏍″噯鏃ユ湡:" class="cycle-item">
-            <el-date-picker style="width:100%" v-model="editData.nextCalibrationDate" format="YYYY-MM-DD"
-              value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
+            <el-date-picker :disabled="true" style="width:100%" v-model="editData.nextCalibrationDate"
+              format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
             </el-date-picker>
           </el-form-item>
           <el-form-item label="鏍″噯鍛ㄦ湡锛堟湀锛�:" prop="calibrationDate" class="cycle-item">
-            <el-input v-model="editData.calibrationDate" size="small"></el-input>
+            <el-input v-model="editData.calibrationDate" size="small" @change="calcNextDate(editData)"></el-input>
           </el-form-item>
         </div>
         <div class="cycle-row">
@@ -504,6 +496,8 @@
 } from '@/api/cnas/resourceDemand/device.js'
 import { selectUserCondition } from "@/api/business/inspectionTask";
 import { selectQualifiedSupplierManagementPage } from '@/api/cnas/externalService/supplierManage/supplierManage'
+import { formatListDate } from './dateFormat'
+import { saveBlobOrShowError } from '@/utils/saveBlob'
 export default {
   props: {
     clickNodeVal: {
@@ -544,7 +538,6 @@
       // },
       fileList: [], // 娣诲姞闄勪欢涓婁紶鏂囦欢鍒楄〃
       timeStamp: '', // 缁欏浘鐗囨坊鍔爇ey锛屽湪姣忔鍔犺浇椤甸潰鐨勬椂鍊欐柊寤烘椂闂存埑
-      equipmentManager: [],
       formLabelWidth: '100px',
       dialogVisible1: false,
       recordNumber: '',
@@ -555,7 +548,7 @@
       num: 1,
       //娣诲姞闄勪欢鏁版嵁鏀堕泦
       addFile: {
-        documentType: '', // 缁存姢绫诲瀷
+        documentType: 0, // 缁存姢绫诲瀷
         provideDate: null, // 褰掓。鏃ユ湡
         name: '', // 妗f鍚嶇О
         number: '', // 搴撳彿/璧勪骇缂栧彿
@@ -577,7 +570,11 @@
       responsiblePersonList: [],
       inspectorList: [],
       options: [],
-      equipmentList: [],
+      // 璁惧绫诲瀷锛氫笌宸︿晶鏍戔�滆澶�/璁¢噺鍣ㄥ叿鈥濆垎绫讳繚鎸佷竴鑷�
+      equipmentList: [
+        { label: '璁惧', value: '璁惧' },
+        { label: '璁¢噺鍣ㄥ叿', value: '璁¢噺鍣ㄥ叿' }
+      ],
       deviceStatusList: [],
       props: { multiple: true, emitPath: false, value: 'id', label: 'name' },
       // 鏀堕泦璁惧妗f鏁版嵁
@@ -612,6 +609,9 @@
     this.obtainQualifiedSupplierList()
   },
   methods: {
+    formatDateCell(row, column, cellValue) {
+      return formatListDate(cellValue)
+    },
     // 鎷夊彇鍚堟牸渚涘簲鍟嗗垪琛紙鏍″噯鏈嶅姟鏈烘瀯涓嬫媺閫夐」锛�
     obtainQualifiedSupplierList() {
       selectQualifiedSupplierManagementPage({ current: 1, size: 999 }).then(res => {
@@ -662,12 +662,14 @@
     },
     //闄勪欢鍜岀浉鍏虫枃妗d簨浠�
     handleAttachmentClick(row) {
-      console.log(row)
-      if (row.fileName) {
-        this.$download.saveAs(row.fileName)
-      } else {
+      if (!row.systemFileName) {
         this.$message.warning('鏈笂浼犳枃浠讹紒')
+        return
       }
+      // 鍥剧墖瀛� /img/锛屽叾浠栨枃妗e瓨 /word/
+      const isImage = /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(row.systemFileName)
+      const url = this.javaApi + (isImage ? '/img/' : '/word/') + row.systemFileName
+      this.$download.saveAs(url, row.fileName || row.systemFileName)
     },
     handleViewClick(row) {
       this.isAddFileUpdate = true
@@ -701,11 +703,23 @@
       })
     },
     saveRecord() {
+      if (!this.addFile.name) {
+        this.$message.warning('璇疯緭鍏ユ。妗堝悕绉�')
+        return
+      }
+      if (this.addFile.documentType !== 0 && this.addFile.documentType !== '0' &&
+        this.addFile.documentType !== 1 && this.addFile.documentType !== '1') {
+        this.$message.warning('璇烽�夋嫨缁存姢绫诲瀷')
+        return
+      }
       //杞崲鏁版嵁
       this.addFile.deviceId = this.clickNodeVal.value
+      // 鏂颁笂浼犳椂 systemFileName 鏄� {name: 鍘熷鏂囦欢鍚�, url: 瀛樺偍鏂囦欢鍚峿锛涚紪杈戞棫璁板綍鏃跺凡鏄瓧绗︿覆
       let obj = this.addFile.systemFileName
-      this.addFile.systemFileName = obj.name
-      this.addFile.fileName = obj.url
+      if (obj && typeof obj === 'object') {
+        this.addFile.systemFileName = obj.url
+        this.addFile.fileName = obj.name
+      }
 
       // 鏇存柊
       if (this.isAddFileUpdate) {
@@ -737,11 +751,17 @@
       }
     },
     handleRemove(file, fileList) {
-      this.deleteFile(this.addFile.systemFileName)
+      const obj = this.addFile.systemFileName
+      const fileName = obj && typeof obj === 'object' ? obj.url : obj
+      if (fileName) this.deleteFile(fileName)
+      this.addFile.systemFileName = ''
+      this.addFile.fileName = ''
     },
     deleteFile(fileName) {
       deleteCNASFile({ fileName }).then(res => {
-        this.$message.success('鍒犻櫎鎴愬姛锛�')
+        if (res.code == 200) {
+          this.$message.success('鍒犻櫎鎴愬姛锛�')
+        }
       })
     },
     handleExceed(files, fileList) {
@@ -784,7 +804,9 @@
         // 灏嗗垎绫诲垪琛ㄧ殑淇℃伅瀛樿捣鏉�
         if (res.code == 200) {
           this.Mdata = res.data;
-          this.Mdata.insProductIds = this.Mdata.insProductIds.split(',')
+          this.Mdata.insProductIds = this.Mdata.insProductIds
+              ? String(this.Mdata.insProductIds).split(',')
+              : []
           this.Mdata.authorizedPerson = this.normalizeAuthorizedPerson(this.Mdata.authorizedPerson)
         }
       });
@@ -802,6 +824,11 @@
     //鎵撳紑淇妗f寮规
     openEditForm() {
       this.editData = JSON.parse(JSON.stringify(this.Mdata))
+      // 璁惧绫诲瀷涓虹┖鏃讹紝榛樿鍙栧乏渚ф爲褰撳墠鎵�鍦ㄥ垎绫�
+      const treeCategory = this.clickNodeVal && this.clickNodeVal.parent ? this.clickNodeVal.parent.label : ''
+      if (!this.editData.largeCategory && (treeCategory === '璁惧' || treeCategory === '璁¢噺鍣ㄥ叿')) {
+        this.editData.largeCategory = treeCategory
+      }
       this.$nextTick(() => {
         this.dialogVisible = true
       })
@@ -832,55 +859,39 @@
     },
     //淇妗f
     submitForm() {
-      let flag = true
-      this.$refs['rules1'].validate((valid) => {
-        if (!valid) {
-          flag = false;
-          return false;
+      // validate() 杩斿洖 Promise锛岀粺涓�绛夊洓涓〃鍗曞叏閮ㄦ牎楠屽畬鍐嶅垽鏂�
+      const formRefs = ['rules1', 'rules2', 'ruleForm', 'cycleForm']
+      Promise.all(formRefs.map(ref => this.$refs[ref].validate().catch(() => false))).then(results => {
+        if (results.some(valid => !valid)) {
+          return
         }
-      });
-      this.$refs['rules2'].validate((valid) => {
-        if (!valid) {
-          flag = false;
-          return false;
-        }
-      });
-      this.$refs['ruleForm'].validate((valid) => {
-        if (!valid) {
-          flag = false;
-          return false;
-        }
-      });
-      this.$refs['cycleForm'].validate((valid) => {
-        if (!valid) {
-          flag = false;
-          return false;
-        }
-      });
-      if (!flag) {
-        return;
-      }
-      delete this.editData.createTime
-      delete this.editData.updateTime
-      delete this.editData.createUser
-      delete this.editData.updateUser
-      delete this.editData.orderBy
-      const formData = this.HaveJson(this.editData)
-      formData.userAllow = this.equipmentManager.toString();
-      formData.insProductIds = Array.isArray(formData.insProductIds) ? formData.insProductIds.join(',') : '';
-      formData.authorizedPerson = Array.isArray(formData.authorizedPerson) && formData.authorizedPerson.length
-        ? JSON.stringify(formData.authorizedPerson)
-        : ''
-      this.upLoad = true;
-      upDeviceParameter(formData).then(res => {
-        this.$message.success('淇敼鎴愬姛')
-        this.upLoad = false
-        this.getList(this.clickNodeVal.value)
-        this.dialogVisible = false
-      }).catch(e => {
-        this.$message.error('淇敼澶辫触')
-        this.dialogVisible = false
-        this.upLoad = false
+        delete this.editData.createTime
+        delete this.editData.updateTime
+        delete this.editData.createUser
+        delete this.editData.updateUser
+        delete this.editData.orderBy
+        const formData = this.HaveJson(this.editData)
+        formData.insProductIds = Array.isArray(formData.insProductIds) ? formData.insProductIds.join(',') : '';
+        formData.authorizedPerson = Array.isArray(formData.authorizedPerson) && formData.authorizedPerson.length
+          ? JSON.stringify(formData.authorizedPerson)
+          : ''
+        this.upLoad = true;
+        upDeviceParameter(formData).then(res => {
+          this.upLoad = false
+          if (res.code == 200) {
+            this.$message.success('淇敼鎴愬姛')
+            this.getList(this.clickNodeVal.value)
+            // 绫诲瀷鍙兘鍙樻洿锛屽埛鏂板乏渚ф爲璁╄澶囧綊鍒版柊鐨勫垎绫讳笅
+            this.$emit('refresh-tree')
+            this.dialogVisible = false
+          } else {
+            this.$message.error(res.message || res.msg || '淇敼澶辫触')
+          }
+        }).catch(e => {
+          // 澶辫触淇濈暀寮圭獥锛岄伩鍏嶅凡缂栬緫鍐呭涓㈠け
+          this.$message.error('淇敼澶辫触')
+          this.upLoad = false
+        })
       })
     },
     // 瀵煎嚭
@@ -888,9 +899,18 @@
       this.outLoading = true
       exportDeviceFile({ deviceId: this.clickNodeVal.value }).then(res => {
         this.outLoading = false
-        const blob = new Blob([res], { type: 'application/octet-stream' });
-        this.$download.saveAs(blob, '璁惧妗f鍗�.doc')
+        saveBlobOrShowError(res, '璁惧妗f鍗�.doc', 'application/msword')
+      }).catch(() => {
+        this.outLoading = false
       })
+    },
+    // 淇寮圭獥鎸変竾鍏冨綍鍏ワ紝妗f璇︽儏鎸夊厓灞曠ず
+    formatPurchasePrice(val) {
+      if (val === null || val === undefined || val === '') {
+        return '-'
+      }
+      const num = Number(val)
+      return isNaN(num) ? val : num * 10000
     },
     handleSuccessUpImg2(response) {
       if (response.code == 200) {
@@ -960,10 +980,6 @@
             a.value = parseInt(a.value)
           }
         })
-      });
-      // 璁惧鍒嗙被
-      this.getDicts("device_type").then((response) => {
-        this.equipmentList = this.dictToValue(response.data);
       });
     },
   },

--
Gitblit v1.9.3