啊鑫
2025-07-21 1bcee828a3340d5f5642b3dbcf4cd9733072b7aa
pages/QC/LLJ/Add.vue
@@ -4,9 +4,10 @@
      <view class="sheet-header">
         <h1>来料检验单</h1>
         <view class="inspection-number">检验单号:{{formData.releaseNo}}</view>
         <!-- 造梦者特殊功能 -->
         <view style="text-align: right;" v-if="this.current"><a class="sysLike"
               @click="toSysSubmitFrom(formData.releaseNo)">实验室送检</a></view>
         <!--实验室送检 -->
         <view style="text-align: right;" class="action-buttons">
            <a class="sysLike" v-if="this.current" @click="toSysSubmitFrom(formData.releaseNo)">实验室送检</a>
         </view>
      </view>
      <!-- 基本信息区 -->
@@ -88,26 +89,31 @@
         </select>
      </view>
      <view class="dropdown-row">
         <view class="info-label">备注:</view>
         <input type="text" id="remark" v-model="REMARK" placeholder="请输入备注信息" />
               <view class="info-block" style="margin-top: 10px;">
          <view class="info-label">备注:</view>
          <input type="text" id="lotNo1" v-model="formData.lotNo1"
                             placeholder="请输入备注信息"
                             style="color: red; font-weight: bold;"/>
      </view>
      <!-- 操作按钮区 -->
      <view class="action-buttons" v-if="this.current">
         <button class="secondary-btn" @click="getInspectionItems">获取检验项目</button>
      <view class="info-block" style="margin-top: 10px;">
          <view class="info-label">破坏实验数量:</view>
          <view class="info-value highlight">{{formData.phsy}}</view>
      </view>
      <!-- 检验项目表格 -->
      <view class="inspection-table">
         <table>
            <thead>
               <tr>
                  <th width="15%" style="text-align: center;">检验项目</th>
                  <th width="20%" style="text-align: center;">检验项目</th>
                  <th width="50%" style="text-align: center;">检验描述</th>
                  <th width="20%" style="text-align: center;">记录(点击)</th>
                  <th width="15%" style="text-align: center;">记录(点击)</th>
               </tr>
            </thead>
            <tbody>
@@ -129,17 +135,28 @@
                     <button v-if="item.current" class="record-btn" @click="fillRecord(item,index)">填写</button>
                     <button v-if="!item.current" class="record-btn" @click="fillRecord(item,index)">查看</button>
                  </td>
               </tr>
            </tbody>
         </table>
      </view>
      <!-- 操作按钮区 -->
      <view class="action-buttons">
         <button class="secondary-btn" @click="uploadImages">上传/查看图片</button>
         <button class="secondary-btn" @click="fetchDrawingNumber">调取PLM图纸</button>
         <button class="secondary-btn" @click="addDefectDescription" v-if="this.current">添加不良描述</button>
         <button class="primary-btn" @click="submitInspection" v-if="this.current">检验提交</button>
      <!-- 页面内容区域 -->
      <view class="content-wrapper">
         <!-- 为底部按钮留出空间 -->
      </view>
      <!-- 固定在底部的操作按钮区 -->
      <view class="fixed-action-buttons">
         <button class="action-btn" @click="handleEmergencyRelease" v-if="this.current">紧急放行</button>
         <button class="action-btn" @click="handleWithdraw" v-if="this.current">撤回</button>
         <button class="action-btn" @click="getInspectionItems" v-if="this.current">获取检验项目</button>
         <button class="action-btn" @click="addDestruction" v-if="this.current">破坏实验</button>
         <button class="action-btn" @click="uploadImages">上传/查看图片</button>
         <button class="action-btn" @click="fetchDrawingNumber">调取PLM图纸</button>
         <button class="action-btn" @click="viewAttachmentInfo">查看附件信息</button>
         <button class="action-btn" @click="addDefectDescription" v-if="this.current">添加不良描述</button>
         <button class="action-btn primary" @click="submitInspection" v-if="this.current">检验提交</button>
      </view>
      <view v-if="remarksPopup" class="overlay">
         <view class="popup">
@@ -155,11 +172,27 @@
            <button @click="remarksPopup = !remarksPopup">取消</button>
         </view>
      </view>
      <view v-if="destructionPopup" class="overlay">
         <view class="popup">
            <h3>破坏实验数量</h3>
            <form>
               <view class="form-group">
                  <label class="form-label">破坏实验数量:</label>
                  <input class="form-input" type="text" v-model="PHSY" placeholder="留空表示清除数量" />
               </view>
            </form>
            <div v-if="!isInteger" class="error-message">请输入整数值或留空</div>
            <button class="updateBut" @click="editDestruction">修改</button>
            <button @click="clearDestruction">清除</button>
            <button @click="destructionPopup = !destructionPopup">取消</button>
         </view>
      </view>
      <view class="barcode">
         <u-modal :show="drawingShow" title="图纸明细" @confirm="drawingConfirm" @cancel="drawingCancel"
            showCancelButton>
            <uni-table border stripe emptyText="暂无更多数据" style="margin-left: 5px;margin-right: 5px;height: 500px;">
            showCancelButton :z-index="1000">
            <uni-table border stripe emptyText="暂无更多数据" style="margin-left: 5px;margin-right: 5px;height: 400px;max-height: 60vh;overflow-y: auto;">
               <uni-tr>
                  <uni-th align="center">相关文档</uni-th>
                  <uni-th align="center" width="90">有无关联PDF文件</uni-th>
@@ -183,8 +216,99 @@
            </uni-table>
         </u-modal>
      </view>
      <!-- 附件详情弹窗 -->
      <view v-if="showAttachmentDetail" class="overlay">
         <view class="popup attachment-detail-popup">
            <h3 class="attachment-popup-title">附件详情</h3>
            <div class="attachment-popup-divider"></div>
            <div v-if="selectedAttachment" class="attachment-detail-content">
               <div class="attachment-detail-row"><span class="attachment-label">ID:</span><span>{{ Math.trunc(selectedAttachment.id) }}</span></div>
               <div class="attachment-detail-row"><span class="attachment-label">附件名:</span><span>{{ selectedAttachment.fattach }}</span></div>
               <div class="attachment-detail-row"><span class="attachment-label">类型:</span><span>{{ selectedAttachment.ftype }}</span></div>
               <div class="attachment-detail-row"><span class="attachment-label">版本:</span><span>{{ selectedAttachment.fversion }}</span></div>
               <div class="attachment-detail-row"><span class="attachment-label">受控日期:</span><span>{{ selectedAttachment.fdate }}</span></div>
               <div class="attachment-detail-row"><span class="attachment-label">上传人:</span><span>{{ selectedAttachment.createBy }}</span></div>
               <div class="attachment-detail-row"><span class="attachment-label">上传时间:</span><span>{{ selectedAttachment.createDate }}</span></div>
               <div class="attachment-actions-detail">
                  <button class="attachment-action-btn preview-btn"
                     @click="previewFtpFile(selectedAttachment)"
                     v-if="isPreviewable(selectedAttachment.fattach)">
                     🔍 在线预览
                  </button>
                  <button class="attachment-action-btn download-btn"
                     @click="downloadAttachment(selectedAttachment)">
                     📥 下载文件
                  </button>
               </div>
            </div>
            <div v-else class="attachment-detail-empty">暂无附件信息</div>
            <button class="attachment-popup-close" @click="closeAttachmentDetail">返回附件列表</button>
         </view>
      </view>
      <!-- 附件列表弹窗 -->
      <view v-if="showAttachmentPopup" class="overlay">
         <view class="popup" style="width: 60vw; max-width: 500px;">
            <h3>附件列表</h3>
            <div v-if="attachmentsLoading">加载中...</div>
            <div v-else-if="attachments.length === 0">暂无附件</div>
            <ul class="attachment-list" v-else>
               <li v-for="item in attachments" :key="item.id">
                  <div class="attachment-info">
                     <span class="attachment-name" @click="showAttachmentDetailDialog(item)">
                        {{ item.fattach }}
                     </span>
                     <div class="attachment-meta">
                        <span class="attachment-type">{{ item.ftype || '未知类型' }}</span>
                     </div>
                  </div>
                  <div class="attachment-actions">
                     <button class="secondary-btn" @click="showAttachmentDetailDialog(item)">详情</button>
                     <button class="secondary-btn preview-btn" @click="previewFtpFile(item)"
                        v-if="isPreviewable(item.fattach)">预览</button>
                     <button class="secondary-btn" @click="downloadAttachment(item)">下载</button>
                  </div>
               </li>
            </ul>
            <button class="attachment-popup-close" @click="closeAttachmentPopup">关闭</button>
         </view>
      </view>
      <!-- 文件预览弹窗 -->
      <view v-if="showFilePreviewPopup" class="overlay">
         <view class="popup file-preview-popup">
            <h3 class="file-preview-title">{{ previewTitle }}</h3>
            <div class="file-preview-divider"></div>
            <div class="file-preview-content">
               <!-- 文本内容预览 -->
               <pre v-if="previewType === 'text'">{{ previewContent }}</pre>
               <!-- 图片内容预览 -->
               <view v-else-if="previewType === 'image'" class="image-preview-container">
                  <image :src="previewContent" mode="widthFix" style="width: 100%; max-height: 400px;"></image>
               </view>
               <!-- Excel 等 Office 文件提示 -->
               <view v-else-if="previewType === 'excel'" class="unsupported-preview">
                  <view class="unsupported-icon">📊</view>
                  <view class="unsupported-text">Excel 文件暂不支持在线预览</view>
                  <view class="unsupported-hint">请点击下载按钮获取完整文件</view>
               </view>
               <!-- 不支持的文件类型 -->
               <view v-else class="unsupported-preview">
                  <view class="unsupported-icon">📄</view>
                  <view class="unsupported-text">此文件格式暂不支持预览</view>
                  <view class="unsupported-hint">请点击下载按钮获取完整文件</view>
               </view>
            </div>
            <div class="file-preview-actions">
               <button v-if="previewType !== 'text'" class="file-preview-btn download-btn" @click="downloadPreviewFile">📥 下载文件</button>
               <button class="file-preview-btn close-btn" @click="closeFilePreview">关闭</button>
            </div>
         </view>
      </view>
   </view>
</template>
<script>
@@ -207,10 +331,21 @@
               planQty: "",
               mocode: "",
               boardStyle: "",
               itemId: ""
               itemId: "",
               emergencyStatus: false,
               lotNo1: '',
               emergency:'',
               permissionModalVisible: false,
               permissionAccount: '',
               hasEmergencyPermission: false,
               showPopup: false,
               PHSY:'',
               EMERGENCY: '0',
            },
            tableData: [],
            remarksPopup: false,
            meomPopup: false,
            current: true,
            drawing: [],
            drawingShow: false,
@@ -220,18 +355,38 @@
            REMARK: '',
            checkState: false,
            writeStatu: true,
            fileName:''
            fileName:'',
            originalRemarks: '',
            hasEmergencyPermission: false,
            destructionPopup: false,
            PHSY: '',
            isInteger: true,
            attachments: [],
            showAttachmentPopup: false,
            attachmentsLoading: false,
            selectedAttachment: null,
            showAttachmentDetail: false,
            showFilePreviewPopup: false,
            previewContent: '',
            previewTitle: '',
            previewItemNo: '',
            previewType: '', // 'text', 'image', 'excel', 'unsupported'
         }
      },
      onLoad(options) {
         //options中包含了url附带的参数
         let params = options;
         if (params["id"]) {
            this.formData.id = params["id"];
            this.formData.releaseNo = params["releaseNo"];
            this.formData.lotNo = params["lotNo"];
            this.msgId = params["msgId"];
            this.emergency = params["emergency"]
            this.meom = params["meom"]
            if (params["current"] === 'A') {
               this.current = true;
@@ -254,6 +409,11 @@
            });
         }
          if (this.$loginInfo.account === 'PL017') {this.hasEmergencyPermission = true;}
          // 测试附件服务器连接
      },
      methods: {
@@ -279,7 +439,8 @@
               data: {
                  itemNo: this.formData.itemId,
                  quantity: this.formData.fcovertQty,
                  releaseNo: this.formData.releaseNo
                  releaseNo: this.formData.releaseNo,
                  PHSY: this.formData.PHSY
               }
            }).then(res => {
               if (res.status == 0) {
@@ -306,6 +467,7 @@
               }
            });
         },
         fillRecord(item, index) {
            // 填写记录的逻辑
            uni.navigateTo({
@@ -374,7 +536,8 @@
                              staffNo: 'HMCS',
                              // staffNo: this.$loginInfo.account,
                              iqcStatus: this.PSTYPE,
                              department: this.DEPARTMENT
                              department: this.DEPARTMENT,
                              EMERGENCY: this.formData.emergencyStatus ? "1" : "0" // 确保紧急放行状态正确传递
                           };
                        }
                        else{
@@ -391,14 +554,16 @@
                              // staffNo: 'HMCS',
                              staffNo: this.$loginInfo.account,
                              iqcStatus: this.PSTYPE,
                              department: this.DEPARTMENT
                              department: this.DEPARTMENT,
                              EMERGENCY: this.formData.emergencyStatus ? "1" : "0" // 确保紧急放行状态正确传递
                           };
                        }
                        console.log(this.QcIssueResultDetailes)
                        console.log("提交的紧急放行状态:", this.formData.emergencyStatus ? "1" : "0");
                        console.log("完整的提交数据:", this.QcIssueResultDetailes);
                        const url = `http://192.168.1.22:10054/api/QcIssueResult/GetProcessNo`;
                        // 发送 POST 请求
                        const url = this.$store.state.serverInfo.serverAPI+`/QcIssueResult/GetProcessNo`;
                        if (this.PSTYPE === '特采/让步使用') {// 发送 POST 请求
                        uni.request({
                           url: url, // 请求地址
                           method: 'POST', // 请求方法
@@ -415,7 +580,10 @@
                              // 如果有页面跳转,需要用定时器延迟
                              setTimeout(() => {
                                 uni.navigateTo({
                                 // 设置一个标记,告诉List页面需要刷新
                                 getApp().globalData = getApp().globalData || {};
                                 getApp().globalData.needRefreshList = true;
                                 uni.redirectTo({
                                    url: 'List'
                                 });
                              }, 2000); // 保持与 duration 相同的时长
@@ -430,7 +598,7 @@
                              });
                           }
                        });
                     }
                        uni.showToast({
                           title: res.message.toString(),
                           icon: 'success',
@@ -469,11 +637,11 @@
                     })
                     // 如果有页面跳转,需要用定时器延迟
                     setTimeout(() => {
                        uni.navigateTo({
                           url: 'List'
                        });
                        // 设置一个标记,告诉List页面需要刷新
                        getApp().globalData = getApp().globalData || {};
                        getApp().globalData.needRefreshList = true;
                        uni.navigateBack();
                     }, 2000); // 保持与 duration 相同的时长
                  } else {
                     uni.showModal({
                        title: "提示",
@@ -508,8 +676,16 @@
            }).then(res => {
               let data = res.data.tbBillList[0];
               if (data) {
                  this.formData = data;
                  this.formData = {
                     ...data,
                     emergencyStatus: data.emergency === 1 || data.emergency === "1" || data.emergency === true
                  };
                  // 确保PHSY字段被正确设置
                  this.formData.PHSY = data.PHSY;
                  console.log("加载的紧急放行状态:", this.formData.emergencyStatus);
                  this.$post({
                     url: "/LLJ/getJYItem",
                     data: {
@@ -520,9 +696,9 @@
                     let tableData = res1.data.tbBillList
                     //当已检验个数都不为空时按照检测结构排序
                     tableData.sort((a, b) => {
                        if (a.result === '未完成' && b.result === '合格') {
                        if (a.result === '合格' && b.result === '未完成') {
                           return -1;
                        } else if (a.result === '合格' && b.result === '未完成') {
                        } else if (a.result === '未完成' && b.result === '合格') {
                           return 1;
                        } else {
                           return 0;
@@ -562,58 +738,25 @@
            });
         },
         editRemarks() {
            if (this.remarks) {
               //saveRemarksGid
               this.$post({
                  url: "/LLJ/saveRemarksGid",
                  data: {
                     gid: this.formData.id,
                     remarks: this.remarks,
                     releaseNo: this.formData.releaseNo,
                  }
               }).then(res => {
                  if (res.data.tbBillList > 0) {
                     this.formData.remarks = this.remarks;
                     this.remarksPopup = !this.remarksPopup;
                     this.$showMessage("保存成功");
                     setTimeout(() => {
                        let pages = getCurrentPages();
                        let beforePage = pages[pages.length - 2];
                        uni.navigateBack({
                           delta: 1, //返回的页面数,如果为1表示返回上一页
                           success: (event) => {
                              beforePage.$vm.reload()
                           }
                        });
                     }, 2000);
                  }
               })
            } else {
               this.$post({
                  url: "/LLJ/saveRemarksGid",
                  data: {
                     gid: this.formData.id,
                     remarks: '',
                     releaseNo: this.formData.releaseNo,
                  }
               }).then(res => {
                  if (res.data.tbBillList > 0) {
                     this.formData.remarks = this.remarks;
                     this.remarksPopup = !this.remarksPopup;
                     this.$showMessage("保存成功");
                     setTimeout(() => {
                        let pages = getCurrentPages();
                        let beforePage = pages[pages.length - 2];
                        uni.navigateBack({
                           delta: 1, //返回的页面数,如果为1表示返回上一页
                           success: (event) => {
                              beforePage.$vm.reload()
                           }
                        });
                     }, 2000);
                  }
               })
            }
            // 保存不良描述
            this.$post({
               url: "/LLJ/saveRemarksGid",
               data: {
                  gid: this.formData.id,
                  remarks: this.remarks || '',
                  releaseNo: this.formData.releaseNo
                  // 不再包含PHSY字段
               }
            }).then(res => {
               if (res.data.tbBillList > 0) {
                  this.formData.remarks = this.remarks;
                  this.remarksPopup = !this.remarksPopup;
                  this.$showMessage("保存成功");
                  setTimeout(() => {
                     this.init();
                  }, 2000);
               }
            })
         },
         drawingConfirm() {
@@ -632,22 +775,24 @@
            const item = this.formData.itemNo;
            console.log(this.formData.itemNo)
            // console.log(item)
            const url = "http://192.168.1.22:10054/api/PLM/RetrieveDrawings?ItemNo=" + item
            const url = this.$store.state.serverInfo.serverAPI +"/PLM/RetrieveDrawings?ItemNo=" + item
            // const item = '5.06.04.4002';
            // const url = "http://192.168.0.100:10054/api/PLM/RetrieveDrawings?ItemNo=" + item
            let _this = this;
            uni.request({
               url: url,
               method: 'POST',
               success: (response) => {
                  console.log(response)
                  if (response.data.data == '返回结果为空') {
                     this.drawing = null
                     _this.drawing = null
                  } else {
                     this.drawing = response.data.data
                     _this.drawing = response.data.data
                     // 遍历数据,判断文件后缀并添加字段
                     this.drawing.forEach((file) => {
                     _this.drawing.forEach((file) => {
                        // 获取文件名的后缀
                        const fileExtension = file.fName.split('.').pop()
                           .toLowerCase();
@@ -680,7 +825,7 @@
            if (item.fRelevantObject.length > 2) {
               // 生成请求URL(简化编码逻辑)
               const encodedName = encodeURIComponent(item.fName); 
               const url = `http://192.168.1.22:10054/api/PLM/OpenDrawingsGet?fileId=${item.fRelevantObject}&fName=${encodedName}`;
               const url = this.$store.state.serverInfo.serverAPI+`/PLM/OpenDrawingsGet?fileId=${item.fRelevantObject}&fName=${encodedName}`;
               console.log('请求URL:', url);
               
               const now = new Date();
@@ -984,7 +1129,734 @@
            //       title: '无对应PDF文件,打开失败',
            //       icon: 'none'
            //    });            // }
         }
         },
         // 处理紧急放行
         handleEmergencyRelease() {
                     if (this.formData.emergencyStatus) {
                         uni.showModal({
                             title: "提示",
                             content: '该单已紧急放行,请勿重复操作',
                             showCancel: false
                         });
                         return;
                     }
                     uni.showModal({
                         title: '确认',
                         content: '确定要执行紧急放行吗?',
                         success: (res) => {
                             if (res.confirm) {
                                 // 调用新的后端接口
                                 this.$post({
                                     url: "/LLJ/EmergencyRelease",
                                     data: {
                                         id: this.formData.id
                                     }
                                 }).then(res => {
                                     if (res.data && res.status === 0) {
                                         const result = res.data.tbBillList[0];
                                         const message = res.data.tbBillList[1];
                                 const lotNo1 = res.data.tbBillList[2] || "";
                                         if (result === "0") {
                                             this.formData.emergencyStatus = true;
                                    this.originalLotNo1 = lotNo1;
                                    this.formData.lotNo1 = lotNo1;
                                    // 更新紧急放行状态,确保提交时能正确传递
                                    this.formData.EMERGENCY = "1";
                                             uni.showToast({
                                                 title: message || '紧急放行成功',
                                                 icon: 'success',
                                                 duration: 2000
                                             });
                                             this.init();
                                         } else {
                                             uni.showModal({
                                                 title: "提示",
                                                 content: message || '操作失败',
                                                 showCancel: false
                                             });
                                         }
                                     }
                                 }).catch(error => {
                                     uni.showModal({
                                         title: "错误",
                                         content: '网络错误,请检查网络连接',
                                         showCancel: false
                                     });
                                 });
                             }
                         }
                     });
                 },
                 // 处理撤回
                 handleWithdraw() {
                     uni.showModal({
                         title: '确认',
                         content: '确定要撤回紧急放行吗?',
                         success: (res) => {
                             if (res.confirm) {
                                 // 调用新的后端接口
                                 this.$post({
                                     url: "/LLJ/WithdrawEmergencyRelease",
                                     data: {
                                         id: this.formData.id
                                     }
                                 }).then(res => {
                                     if (res.data && res.status === 0) {
                                         const result = res.data.tbBillList[0];
                                         const message = res.data.tbBillList[1];
                                         if (result === "0") {
                                             this.formData.emergencyStatus = false;
                                    // 更新紧急放行状态,确保提交时能正确传递
                                    this.formData.EMERGENCY = "0";
                                             uni.showToast({
                                                 title: message || '撤回成功',
                                                 icon: 'success',
                                                 duration: 2000
                                             });
                                             this.init();
                                         } else {
                                             uni.showModal({
                                                 title: "提示",
                                                 content: message || '操作失败',
                                                 showCancel: false
                                             });
                                         }
                                     }
                                 }).catch(error => {
                                     uni.showModal({
                                         title: "错误",
                                         content: '网络错误,请检查网络连接',
                                         showCancel: false
                                     });
                                 });
                             }
                         }
                     });
                 },
               editRemarks() {
                  // 保存不良描述
                  this.$post({
                     url: "/LLJ/saveRemarksGid",
                     data: {
                        gid: this.formData.id,
                        remarks: this.remarks || '',
                        releaseNo: this.formData.releaseNo
                        // 不再包含PHSY字段
                     }
                  }).then(res => {
                     if (res.data.tbBillList > 0) {
                        this.formData.remarks = this.remarks;
                        this.remarksPopup = !this.remarksPopup;
                        this.$showMessage("保存成功");
                        setTimeout(() => {
                           this.init();
                        }, 2000);
                     }
                  })
               },
         addDestruction() {
            // 添加破坏实验的逻辑
            this.destructionPopup = !this.destructionPopup;
            this.PHSY = this.formData.PHSY || '';
            this.isInteger = true;
         },
         editDestruction() {
            // 验证输入是否为整数
            if(this.PHSY === '') {
               this.isInteger = true;
               // 如果为空,传递空字符串,后端会处理为null
            } else {
               const isInteger = /^-?\d+$/.test(this.PHSY);
               this.isInteger = isInteger;
               if (!isInteger) {
                  return;
               }
            }
            // 保存破坏实验数量
            this.$post({
               url: "/LLJ/saveRemarksGid",
               data: {
                  gid: this.formData.id,
                  releaseNo: this.formData.releaseNo,
                  PHSY: this.PHSY // 可以是空字符串或有效整数
                  // 不再包含remarks字段
               }
            }).then(res => {
               if (res.data.tbBillList > 0) {
                  // 如果输入为空,设置为null以便不显示
                  this.formData.PHSY = this.PHSY === '' ? null : this.PHSY;
                  this.destructionPopup = false;
                  this.$showMessage("保存成功");
                  setTimeout(() => {
                     this.init();
                  }, 2000);
               }
            })
         },
         clearDestruction() {
            // 清除破坏实验数量
            this.PHSY = '';
            this.$post({
               url: "/LLJ/saveRemarksGid",
               data: {
                  gid: this.formData.id,
                  releaseNo: this.formData.releaseNo,
                  PHSY: '' // 空字符串,后端会处理为null
               }
            }).then(res => {
               if (res.data.tbBillList > 0) {
                  this.formData.PHSY = null; // 确保前端也为null,不显示
                  this.destructionPopup = false;
                  this.$showMessage("清除成功");
                  setTimeout(() => {
                     this.init();
                  }, 2000);
               }
            })
         },
         viewAttachmentInfo() {
            this.showAttachmentPopup = true; // 先弹窗
            this.attachmentsLoading = true;
            this.attachments = [];
            this.$post({
               url: "/LLJ/getAttachments",
               data: { releaseNo: this.formData.releaseNo }
            }).then(res => {
               this.attachmentsLoading = false;
               if (res.status === 0) {
                  this.attachments = res.data.tbBillList;
                  // 为每个附件设置默认可用状态
                  this.attachments.forEach((item, index) => {
                     this.$set(item, 'ftpAvailable', true); // 默认认为文件可用
                     this.$set(item, 'checking', false);
                  });
               } else if (res.status === 1 && res.message === "该检验单未上传附件信息!") {
                  uni.showToast({ title: res.message, icon: "none" });
               } else {
                  uni.showToast({ title: "获取附件失败", icon: "none" });
               }
            });
         },
         closeAttachmentPopup() {
            this.showAttachmentPopup = false;
         },
         getAttachmentUrl(item) {
            // 去除所有空白字符(包括中英文空格、制表符等)
            let fileName = item.fattach.replace(/[\s\u3000\r\n]+/g, '').trim();
            // 统一使用FTP下载接口,包含FTP服务器地址
            return this.$store.state.serverInfo.serverAPI + "/LLJ/DownloadFtpFile?itemNo=" + encodeURIComponent(item.itemNo) + "&fileName=" + encodeURIComponent(fileName) + "&ftpServer=" + encodeURIComponent(this.$store.state.serverInfo.ftpServer);
         },
         showAttachmentDetailDialog(item) {
            console.log('查看详情', item);
            this.selectedAttachment = item;
            this.showAttachmentPopup = false;
            this.showAttachmentDetail = true;
            console.log('showAttachmentDetail:', this.showAttachmentDetail);
         },
         closeAttachmentDetail() {
            this.showAttachmentDetail = false;
            this.selectedAttachment = null;
            this.showAttachmentPopup = true;
         },
         isPreviewable(filename) {
            if (!filename) return false;
            const ext = filename.trim().split('.').pop().toLowerCase();
            // 支持在线预览的文件类型
            return [
               'pdf',           // PDF文件
               'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp',  // 图片文件
               'txt', 'log', 'md',  // 文本文件
               'doc', 'docx',   // Word文档
               'xls', 'xlsx',   // Excel表格
               'ppt', 'pptx',   // PowerPoint演示文稿
               'csv'            // CSV文件
            ].includes(ext);
         },
         // 处理附件下载错误
         handleAttachmentError(item) {
            uni.showModal({
               title: '下载失败',
               content: `无法下载附件:${item.fattach}\n请检查网络连接或联系管理员`,
               showCancel: false
            });
         },
         // 预览FTP文件
         previewFtpFile(item) {
            const fileName = item.fattach.replace(/[\s\u3000\r\n]+/g, '').trim();
            const fileExt = fileName.split('.').pop().toLowerCase();
            // 检查文件类型是否支持预览
            if (!this.isPreviewable(fileName)) {
               uni.showModal({
                  title: '不支持预览',
                  content: '该文件类型不支持在线预览,请下载后查看',
                  showCancel: false
               });
               return;
            }
            const previewUrl = this.$store.state.serverInfo.serverAPI + "/LLJ/PreviewFtpFile?itemNo=" + encodeURIComponent(item.itemNo) + "&fileName=" + encodeURIComponent(fileName) + "&ftpServer=" + encodeURIComponent(this.$store.state.serverInfo.ftpServer);
            // 根据文件类型进行不同的预览处理
            if (['pdf'].includes(fileExt)) {
               this.previewPdfFile(previewUrl, fileName);
            } else if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(fileExt)) {
               this.previewImageFile(previewUrl, fileName);
            } else if (['txt'].includes(fileExt)) {
               this.previewTextFile(previewUrl, fileName);
            } else if (['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'].includes(fileExt)) {
               this.previewOfficeFile(previewUrl, fileName);
            } else {
               // 尝试通用预览
               this.previewGenericFile(previewUrl, fileName);
            }
         },
         // 预览PDF文件
         previewPdfFile(url, fileName) {
            // 先下载PDF文件,转为base64后预览
            uni.request({
               url: url,
               method: 'GET',
               responseType: 'arraybuffer',
               success: (res) => {
                  if (res.statusCode === 200) {
                     const base64Data = uni.arrayBufferToBase64(res.data);
                     // 存储到全局变量
                     getApp().globalData.tempPDF = base64Data;
                     uni.navigateTo({
                        url: `/pages/fileView/pdfView`
                     });
                  } else {
                     this.handlePreviewError(res.statusCode, fileName);
                  }
               },
               fail: (error) => {
                  this.handlePreviewError(0, fileName, error.errMsg);
               }
            });
         },
         // 预览图片文件
         previewImageFile(url, fileName) {
            // #ifdef APP-PLUS
            // APP环境:先下载到本地再预览,避免网络图片加载问题
            uni.showLoading({ title: '加载图片...' });
            uni.downloadFile({
               url: url,
               success: (res) => {
                  uni.hideLoading();
                  if (res.statusCode === 200) {
                     // 使用本地临时路径
                     uni.navigateTo({
                        url: `/pages/fileView/imageView?url=${encodeURIComponent(res.tempFilePath)}`
                     });
                  } else {
                     this.handlePreviewError(res.statusCode, fileName);
                  }
               },
               fail: (error) => {
                  uni.hideLoading();
                  this.handlePreviewError(0, fileName, error.errMsg);
               }
            });
            // #endif
            // #ifdef H5 || MP
            // H5和小程序:直接使用网络URL
            uni.navigateTo({
               url: `/pages/fileView/imageView?url=${encodeURIComponent(url)}`
            });
            // #endif
         },
         // 预览文本文件
         previewTextFile(url, fileName) {
            // 文本文件直接显示在弹窗中
            uni.showLoading({ title: '加载文件内容...' });
            uni.request({
               url: url,
               method: 'GET',
               success: (res) => {
                  uni.hideLoading();
                  if (res.statusCode === 200) {
                     const fileType = this.getFileType(fileName);
                     if (fileType === 'text') {
                        // 文本文件:显示内容
                        this.showFilePreview(res.data, fileName);
                     } else if (fileType === 'image') {
                        // 图片文件:显示图片URL
                        this.showFilePreview(url, fileName);
                     } else {
                        // 其他文件类型:显示提示信息
                        this.showFilePreview('', fileName);
                     }
                  } else {
                     this.handlePreviewError(res.statusCode, fileName);
                  }
               },
               fail: (error) => {
                  uni.hideLoading();
                  this.handlePreviewError(0, fileName, error.errMsg);
               }
            });
         },
         // 检测文件类型
         getFileType(fileName) {
            const fileExt = fileName.split('.').pop().toLowerCase();
            if (['txt', 'log', 'md', 'csv', 'json', 'xml'].includes(fileExt)) {
               return 'text';
            } else if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(fileExt)) {
               return 'image';
            } else if (['xls', 'xlsx', 'doc', 'docx', 'ppt', 'pptx'].includes(fileExt)) {
               return 'excel';
            } else {
               return 'unsupported';
            }
         },
         // 显示文件预览弹窗
         showFilePreview(content, fileName) {
            this.previewContent = content;
            this.previewTitle = fileName;
            this.previewItemNo = this.selectedAttachment?.itemNo || '';
            this.previewType = this.getFileType(fileName);
            this.showFilePreviewPopup = true;
         },
         // 关闭文件预览弹窗
         closeFilePreview() {
            this.showFilePreviewPopup = false;
            this.previewContent = '';
            this.previewTitle = '';
            this.previewItemNo = '';
            this.previewType = '';
         },
         // 下载预览文件
         downloadPreviewFile() {
            const item = { fattach: this.previewTitle, itemNo: this.previewItemNo };
            this.downloadAttachment(item);
            this.closeFilePreview();
         },
         // 预览Office文件
         previewOfficeFile(url, fileName) {
            // 先检查Excel文件,使用专门的Excel预览页面
            const fileExt = fileName.split('.').pop().toLowerCase();
            if (['xls', 'xlsx'].includes(fileExt)) {
               // Excel文件预览
               uni.request({
                  url: url,
                  method: 'GET',
                  responseType: 'arraybuffer',
                  success: (res) => {
                     if (res.statusCode === 200) {
                        const base64Data = uni.arrayBufferToBase64(res.data);
                        // 存储 Base64 数据到本地存储
                        uni.setStorageSync('excelBase64Data', base64Data);
                        uni.navigateTo({
                           url: `/pages/fileView/excelView`
                        });
                     } else {
                        this.handlePreviewError(res.statusCode, fileName);
                     }
                  },
                  fail: (error) => {
                     this.handlePreviewError(0, fileName, error.errMsg);
                  }
               });
            } else if (['doc', 'docx'].includes(fileExt)) {
               // Word文件,尝试使用Word预览页面或者微软在线预览
               try {
                  const officePreviewUrl = `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}`;
                  // 如果有webView页面,使用webView预览
                  this.previewGenericFile(officePreviewUrl, fileName);
               } catch (error) {
                  this.handlePreviewError(0, fileName, '不支持此Office文件类型的预览');
               }
            } else {
               // 其他Office文件,使用微软在线预览服务
               const officePreviewUrl = `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}`;
               this.previewGenericFile(officePreviewUrl, fileName);
            }
         },
         // 通用文件预览
         previewGenericFile(url, fileName) {
            // 由于没有通用的webView页面,显示提示并提供下载
            uni.showModal({
               title: '文件预览',
               content: `文件 "${fileName}" 需要下载后查看,是否立即下载?`,
               showCancel: true,
               confirmText: '下载',
               cancelText: '取消',
               success: (res) => {
                  if (res.confirm) {
                     const item = { fattach: fileName, itemNo: this.selectedAttachment.itemNo };
                     this.downloadAttachment(item);
                  }
               }
            });
         },
         // 处理预览错误
         handlePreviewError(statusCode, fileName, errorMsg = '') {
            let message = '';
            if (statusCode === 404) {
               message = `文件 ${fileName} 在FTP服务器上不存在`;
            } else if (statusCode === 0) {
               message = `预览失败:${errorMsg}`;
            } else {
               message = `预览失败,状态码:${statusCode}`;
            }
            uni.showModal({
               title: '预览失败',
               content: message,
               showCancel: true,
               confirmText: '下载',
               cancelText: '取消',
               success: (res) => {
                  if (res.confirm) {
                     // 用户选择下载文件
                     const item = { fattach: fileName, itemNo: this.selectedAttachment.itemNo };
                     this.downloadAttachment(item);
                  }
               }
            });
         },
         downloadAttachment(item) {
            // 去除所有空格、全角空格、回车、换行
            const fileName = item.fattach.replace(/[\s\u3000\r\n]+/g, '').trim();
            // 使用配置的服务器地址和FTP服务器地址
            const url = this.$store.state.serverInfo.serverAPI + "/LLJ/DownloadFtpFile?itemNo=" + encodeURIComponent(item.itemNo) + "&fileName=" + encodeURIComponent(fileName) + "&ftpServer=" + encodeURIComponent(this.$store.state.serverInfo.ftpServer);
            // 检查运行环境
            // #ifdef H5
            // H5环境:使用浏览器下载
            this.downloadFileInBrowser(url, fileName);
            // #endif
            // #ifdef APP-PLUS
            // APP环境:使用uni.downloadFile
            this.downloadFileInApp(url, fileName);
            // #endif
            // #ifdef MP
            // 小程序环境:使用uni.downloadFile
            this.downloadFileInApp(url, fileName);
            // #endif
         },
         // 在浏览器中下载文件
         downloadFileInBrowser(url, fileName) {
            uni.showLoading({ title: '正在准备下载...' });
            // 方法1:创建隐藏的a标签下载
            try {
               const link = document.createElement('a');
               link.href = url;
               link.download = fileName;
               link.style.display = 'none';
               document.body.appendChild(link);
               link.click();
               document.body.removeChild(link);
               uni.hideLoading();
               uni.showToast({
                  title: '下载已开始',
                  icon: 'success',
                  duration: 2000
               });
            } catch (error) {
               console.log('a标签下载失败,尝试window.open方式:', error);
               // 方法2:使用window.open
               try {
                  window.open(url, '_blank');
                  uni.hideLoading();
                  uni.showToast({
                     title: '下载已开始',
                     icon: 'success',
                     duration: 2000
                  });
               } catch (error2) {
                  console.log('window.open下载失败,尝试fetch方式:', error2);
                  // 方法3:使用fetch下载
                  this.downloadFileWithFetch(url, fileName);
               }
            }
         },
         // 使用fetch下载文件
         downloadFileWithFetch(url, fileName) {
            fetch(url)
               .then(response => {
                  if (!response.ok) {
                     throw new Error(`HTTP error! status: ${response.status}`);
                  }
                  return response.blob();
               })
               .then(blob => {
                  // 创建blob URL
                  const blobUrl = window.URL.createObjectURL(blob);
                  // 创建下载链接
                  const link = document.createElement('a');
                  link.href = blobUrl;
                  link.download = fileName;
                  link.style.display = 'none';
                  document.body.appendChild(link);
                  link.click();
                  document.body.removeChild(link);
                  // 释放blob URL
                  window.URL.revokeObjectURL(blobUrl);
                  uni.hideLoading();
                  uni.showToast({
                     title: '下载成功',
                     icon: 'success',
                     duration: 2000
                  });
               })
               .catch(error => {
                  console.error('Fetch下载失败:', error);
                  uni.hideLoading();
                  if (error.message.includes('404')) {
                     uni.showModal({
                        title: '文件不存在',
                        content: `该附件在FTP服务器上不存在`,
                        showCancel: false
                     });
                  } else {
                     uni.showModal({
                        title: '下载失败',
                        content: `下载失败: ${error.message}`,
                        showCancel: false
                     });
                  }
               });
         },
         // 在APP中下载文件
         downloadFileInApp(url, fileName) {
            // #ifdef APP-PLUS
            uni.showLoading({ title: '从FTP服务器下载中...' });
            // Android 获取存储路径
            const saveDir = plus.os.name === 'Android' ? plus.io.convertLocalFileSystemURL('_downloads/') : plus.io.convertLocalFileSystemURL('_documents/');
            const filePath = `${saveDir}${fileName}`;
            const downloadTask = uni.downloadFile({
               url: url,
               filePath: filePath, // 指定保存路径
               success: (res) => {
                  uni.hideLoading();
                  if (res.statusCode === 200) {
                     const fileInfo = {
                        name: fileName,
                        path: res.filePath || filePath,
                        tempPath: res.tempFilePath
                     };
                     uni.showModal({
                        title: '下载成功',
                        content: `文件已保存到:${fileInfo.path}`,
                        showCancel: true,
                        confirmText: '打开文件',
                        cancelText: '确定',
                        success: (modalRes) => {
                           if (modalRes.confirm) {
                              // 用户选择打开文件
                              this.openFileInApp(fileInfo);
                           }
                        }
                     });
                  } else if (res.statusCode === 404) {
                     uni.showModal({
                        title: '文件不存在',
                        content: `该附件在FTP服务器上不存在`,
                        showCancel: false
                     });
                  } else {
                     uni.showModal({
                        title: '下载失败',
                        content: `状态码:${res.statusCode}`,
                        showCancel: false
                     });
                  }
               },
               fail: (error) => {
                  uni.hideLoading();
                  console.error('下载失败:', error);
                  uni.showModal({
                     title: '下载失败',
                     content: `网络错误:${error.errMsg}`,
                     showCancel: false
                  });
               }
            });
            // 监听下载进度
            downloadTask.onProgressUpdate((res) => {
               const progress = Math.round(res.progress);
               uni.showLoading({
                  title: `下载中 ${progress}%`,
                  mask: true
               });
            });
            // #endif
            // #ifdef MP
            // 小程序环境的简化实现
            uni.showLoading({ title: '下载中...' });
            uni.downloadFile({
               url: url,
               success: (res) => {
                  uni.hideLoading();
                  if (res.statusCode === 200) {
                     uni.showToast({ title: '下载完成', icon: 'success' });
                  }
               },
               fail: (error) => {
                  uni.hideLoading();
                  uni.showModal({ title: '下载失败', content: error.errMsg, showCancel: false });
               }
            });
            // #endif
         },
         // APP中打开文件
         openFileInApp(fileInfo) {
            // #ifdef APP-PLUS
            if (typeof plus !== 'undefined') {
               const filePath = fileInfo.path || fileInfo.tempPath;
               // 尝试打开文件
               plus.runtime.openFile(filePath, {}, (error) => {
                  console.error('打开文件失败:', error);
                  uni.showModal({
                     title: '无法打开',
                     content: '系统中没有找到能打开此文件的应用程序',
                     showCancel: false
                  });
               });
            }
            // #endif
         },
      }
   }
</script>
@@ -995,9 +1867,11 @@
      font-family: 'Microsoft YaHei', 'Segoe UI', sans-serif;
      max-width: 1000px;
      margin: 0 auto;
      padding: 20px;
      padding: 20px 20px 160px 20px; /* 底部增加padding为固定按钮留空间 */
      background-color: #fff;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
      min-height: 100vh;
      position: relative;
   }
   /* 头部样式 */
@@ -1078,12 +1952,9 @@
   }
   .sysLike {
      color: #3498db;
      color: #1890ff;
      text-decoration: none;
      margin-left: 15px;
      padding: 3px 8px;
      border-radius: 3px;
      font-size: 12px;
      cursor: pointer;
   }
   .doc-link:hover {
@@ -1121,16 +1992,87 @@
      background-color: #f1f5f9;
   }
   /* 按钮样式 */
   .action-buttons {
   /* 固定底部按钮样式 */
   .fixed-action-buttons {
      position: fixed;
      bottom: 0;
      left: 0;
      right: 0;
      background-color: #fff;
      box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
      padding: 10px 15px 20px 15px;
      z-index: 100;
      display: flex;
      justify-content: flex-end;
      gap: 10px;
      margin-top: 20px;
      flex-direction: column;
      gap: 8px;
      max-height: 150px;
      overflow-y: auto;
   }
   .primary-btn,
   .action-btn {
      background-color: #ecf0f1;
      color: #34495e;
      padding: 12px 15px;
      border: none;
      border-radius: 6px;
      cursor: pointer;
      font-size: 14px;
      font-weight: 500;
      transition: all 0.3s ease;
      text-align: center;
      min-height: 44px;
      display: flex;
      align-items: center;
      justify-content: center;
   }
   .action-btn:hover {
      background-color: #d5dbdb;
      transform: translateY(-1px);
   }
   .action-btn.primary {
      background-color: #3498db;
      color: #fff;
   }
   .action-btn.primary:hover {
      background-color: #2980b9;
   }
   /* 内容包装器,为底部按钮留出空间 */
   .content-wrapper {
      height: 20px; /* 额外的空白区域 */
   }
   /* 原有按钮样式保持兼容 */
   .action-buttons {
      display: flex;
      gap: 10px;
      margin: 15px 0;
      justify-content: flex-end;
   }
   .secondary-btn {
      background-color: #ecf0f1;
      color: #7f8c8d;
      padding: 8px 15px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
   }
   .secondary-btn:hover {
      background-color: #d5dbdb;
   }
   .secondary-btn:disabled {
      background-color: #d9d9d9;
      cursor: not-allowed;
      opacity: 0.7;
   }
   .primary-btn {
      padding: 10px 20px;
      border: none;
      border-radius: 4px;
@@ -1139,22 +2081,8 @@
      transition: all 0.3s;
   }
   .primary-btn {
      background-color: #3498db;
      color: white;
   }
   .primary-btn:hover {
      background-color: #2980b9;
   }
   .secondary-btn {
      background-color: #ecf0f1;
      color: #7f8c8d;
   }
   .secondary-btn:hover {
      background-color: #d5dbdb;
   }
   .record-btn {
@@ -1226,59 +2154,334 @@
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 10;
      z-index: 1000; /* 提高层级,确保在固定按钮上方 */
   }
   .popup {
      background-color: #fff;
      padding: 20px;
      border: 1px solid #ccc;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
      width: 68vw;
      /* 设置宽度为视口宽度的80% */
      height: 25vh;
      /* 设置高度为视口高度的80% */
   /* 弹窗整体美化 */
   .popup, .attachment-detail-popup {
      background: #fff;
      border-radius: 16px;
      box-shadow: 0 8px 32px rgba(60,60,60,0.18);
      padding: 28px 28px 18px 28px;
      border: none;
      position: relative;
      min-width: 260px;
      z-index: 1001; /* 确保弹窗内容在最上层 */
      max-height: 80vh; /* 限制最大高度,避免被底部按钮遮挡 */
      overflow-y: auto; /* 内容过多时可滚动 */
   }
   .form-group {
   .attachment-popup-title {
      font-size: 22px;
      font-weight: 700;
      color: #222;
      margin-bottom: 8px;
      letter-spacing: 1px;
      text-align: center;
   }
   .attachment-popup-divider {
      height: 1px;
      background: linear-gradient(90deg,#e0e7ef 0%,#f5f7fa 100%);
      margin-bottom: 18px;
   }
   .attachment-detail-content {
      margin-bottom: 18px;
   }
   .attachment-detail-row {
      display: flex;
      align-items: center;
      border-bottom: 1px solid #c9c9c9;
      margin-bottom: 8px;
      font-size: 15px;
   }
   .updateBut {
      background-color: #3498db;
   .attachment-label {
      min-width: 80px;
      color: #1976d2;
      font-weight: 500;
      margin-right: 8px;
   }
   .attachment-preview-area {
      margin: 18px 0 8px 0;
      border-radius: 10px;
      background: #f8fafc;
      padding: 10px;
      box-shadow: 0 2px 8px rgba(60,60,60,0.06);
   }
   .attachment-download-area {
      margin: 18px 0 8px 0;
      text-align: center;
   }
   .attachment-download-link {
      display: inline-block;
      padding: 7px 18px;
      background: linear-gradient(90deg,#4f8cff 0%,#1976d2 100%);
      color: #fff;
      border-radius: 6px;
      font-weight: 500;
      text-decoration: none;
      transition: background 0.2s;
      box-shadow: 0 2px 8px rgba(60,60,60,0.08);
   }
   .attachment-download-link:hover {
      background: linear-gradient(90deg,#1976d2 0%,#4f8cff 100%);
   }
   .attachment-detail-empty {
      color: #888;
      text-align: center;
      margin: 30px 0;
      font-size: 16px;
   }
   .attachment-popup-close {
      margin-top: 18px;
      width: 100%;
      background: linear-gradient(90deg,#e0e0e0 0%,#f5f7fa 100%);
      color: #444;
      border-radius: 8px;
      font-size: 16px;
      padding: 10px 0;
      border: none;
      font-weight: 600;
      letter-spacing: 1px;
      transition: background 0.2s, color 0.2s;
      box-shadow: 0 2px 8px rgba(60,60,60,0.06);
   }
   .attachment-popup-close:hover {
      background: linear-gradient(90deg,#bdbdbd 0%,#e0e0e0 100%);
      color: #1976d2;
   }
   /* 附件详情页面的操作按钮 */
   .attachment-actions-detail {
      margin: 20px 0;
      display: flex;
      gap: 12px;
      justify-content: center;
      flex-wrap: wrap;
   }
   .attachment-action-btn {
      padding: 10px 20px;
      border: none;
      border-radius: 8px;
      font-size: 14px;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.3s ease;
      display: flex;
      align-items: center;
      justify-content: center;
      min-width: 120px;
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
   }
   .attachment-action-btn.preview-btn {
      background: linear-gradient(135deg, #4CAF50, #45a049);
      color: white;
   }
   /* 响应式设计 */
   @media (max-width: 500px) {
      .info-row,
      .info-block {
         flex-direction: column;
         align-items: flex-start;
      }
      .doc-links {
         margin-left: 0;
         margin-top: 10px;
      }
      .action-buttons {
         flex-direction: column;
      }
      .inspection-table table {
         display: block;
         overflow-x: auto;
      }
      .click-wd {
         color: #056cba;
         font-size: 1.25rem;
         text-decoration: underline;
      }
   .attachment-action-btn.preview-btn:hover {
      background: linear-gradient(135deg, #45a049, #3d8b40);
      transform: translateY(-1px);
      box-shadow: 0 4px 8px rgba(0,0,0,0.15);
   }
   .attachment-action-btn.download-btn {
      background: linear-gradient(135deg, #2196F3, #1976D2);
      color: white;
   }
   .attachment-action-btn.download-btn:hover {
      background: linear-gradient(135deg, #1976D2, #1565C0);
      transform: translateY(-1px);
      box-shadow: 0 4px 8px rgba(0,0,0,0.15);
   }
   /* 文件预览弹窗样式 */
   .file-preview-popup {
      width: 80vw;
      max-width: 600px;
      max-height: 70vh;
      display: flex;
      flex-direction: column;
   }
   /* APP环境适配 */
   /* #ifdef APP-PLUS */
   .file-preview-popup {
      width: 85vw;
      max-height: 75vh;
   }
   .file-preview-content {
      max-height: 350px;
   }
   /* #endif */
   .file-preview-title {
      font-size: 18px;
      font-weight: 700;
      color: #222;
      margin-bottom: 8px;
      text-align: center;
      word-break: break-all;
   }
   .file-preview-divider {
      height: 1px;
      background: linear-gradient(90deg,#e0e7ef 0%,#f5f7fa 100%);
      margin-bottom: 16px;
   }
   .file-preview-content {
      flex: 1;
      max-height: 400px;
      overflow-y: auto;
      background: #f8fafc;
      border-radius: 8px;
      padding: 16px;
      margin-bottom: 16px;
      border: 1px solid #e2e8f0;
   }
   .file-preview-content pre {
      font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
      font-size: 12px;
      line-height: 1.5;
      color: #2d3748;
      white-space: pre-wrap;
      word-wrap: break-word;
      margin: 0;
   }
   /* 图片预览样式 */
   .image-preview-container {
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 200px;
   }
   /* 不支持文件类型的提示样式 */
   .unsupported-preview {
      text-align: center;
      padding: 40px 20px;
      color: #666;
   }
   .unsupported-icon {
      font-size: 48px;
      margin-bottom: 16px;
   }
   .unsupported-text {
      font-size: 16px;
      font-weight: 600;
      color: #333;
      margin-bottom: 8px;
   }
   .unsupported-hint {
      font-size: 14px;
      color: #999;
      line-height: 1.4;
   }
   .file-preview-actions {
      display: flex;
      gap: 12px;
      justify-content: center;
   }
   .file-preview-btn {
      padding: 8px 20px;
      border: none;
      border-radius: 6px;
      font-size: 14px;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.3s ease;
      display: flex;
      align-items: center;
      justify-content: center;
      min-width: 120px;
   }
   .file-preview-btn.download-btn {
      background: linear-gradient(135deg, #2196F3, #1976D2);
      color: white;
   }
   .file-preview-btn.download-btn:hover {
      background: linear-gradient(135deg, #1976D2, #1565C0);
      transform: translateY(-1px);
   }
   .file-preview-btn.close-btn {
      background: linear-gradient(135deg, #e0e0e0, #bdbdbd);
      color: #444;
   }
   .file-preview-btn.close-btn:hover {
      background: linear-gradient(135deg, #bdbdbd, #9e9e9e);
      transform: translateY(-1px);
   }
   /* 列表弹窗美化(保留原有) */
   .attachment-list {
      padding: 0;
      margin: 0;
      list-style: none;
      max-height: 300px;
      overflow-y: auto;
   }
   .attachment-list li {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 12px 0;
      border-bottom: 1px solid #f0f0f0;
   }
   .attachment-info {
      flex: 1;
      margin-right: 10px;
   }
   .attachment-name {
      color: #3498db;
      cursor: pointer;
      font-weight: 500;
      transition: color 0.2s;
      display: block;
      margin-bottom: 4px;
   }
   .attachment-name:hover {
      color: #217dbb;
      text-decoration: underline;
   }
   .attachment-meta {
      font-size: 12px;
   }
   .attachment-type {
      color: #7f8c8d;
      font-style: italic;
   }
   .attachment-actions {
      display: flex;
      gap: 8px;
      flex-shrink: 0;
   }
   .attachment-list .secondary-btn {
      padding: 4px 10px;
      font-size: 13px;
      border-radius: 3px;
      background: #f5f7fa;
      color: #333;
      border: 1px solid #dbe2ea;
      transition: background 0.2s, color 0.2s;
   }
   .attachment-list .secondary-btn:hover {
      background: #e6f0fa;
      color: #1976d2;
   }
   .preview-btn {
      background: #e8f5e8 !important;
      color: #2e7d2e !important;
      border-color: #a5d6a5 !important;
   }
   .preview-btn:hover {
      background: #d4eecc !important;
      color: #1e5f1e !important;
   }
   .attachment-popup-close {
      margin-top: 18px;
      width: 100%;
      background: #e0e0e0;
      color: #444;
      border-radius: 4px;
      font-size: 15px;
      padding: 8px 0;
      border: none;
      transition: background 0.2s;
   }
   .attachment-popup-close:hover {
      background: #bdbdbd;
   }
</style>