111
啊鑫
5 天以前 2b0e70bb88ced210dbc693a4d2ded2d658b1da02
111
已添加1个文件
已修改5个文件
4186 ■■■■■ 文件已修改
pages/QC/Laboratory/ImageItem.vue 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/Laboratory/Laboratory.vue 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/OQC/Add.vue 576 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/OQC/ImageItem.vue 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/OQC/ScanCode.vue 1605 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/OQC/detail.vue 1623 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/Laboratory/ImageItem.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,238 @@
<template>
  <!-- #ifdef APP -->
  <scroll-view class="page-scroll-view">
    <!-- #endif -->
    <view>
      <view class="uni-common-mt">
        <view class="uni-list list-pd" style="padding: 15px;">
          <view class="uni-flex" style="margin-bottom: 10px;">
            <view class="uni-list-cell-left">点击可预览选好的图片</view>
            <view style="margin-left: auto;">
              <view class="click-t">共有{{ qsImage.length }}张图片</view>
            </view>
          </view>
          <view class="uni-flex" style="flex-wrap: wrap;">
            <view v-for="(image,index) in qsImage" :key="index" class="uni-uploader__input-box"
                  style="position: relative; border: 0;">
              <image :data-src="image.img" :src="image.img"
                     @tap="previewImage(index)"></image>
              <image class="image-remove" src="/static/plus.png" @click="removeImage(index,image.id)"></image>
            </view>
            <image class="uni-uploader__input-box" src="/static/plus.png" @tap="chooseImage"></image>
          </view>
        </view>
      </view>
      <view class="plus-button">
        <button class="upImg" type="primary" @click="save">上传图片</button>
      </view>
    </view>
    <!-- #ifdef APP -->
  </scroll-view>
  <!-- #endif -->
</template>
<script>
import {pathToBase64} from '../../../js_sdk/mmmm-image-tools/index'
var sourceTypeArray = [
  ['camera'],
  ['album'],
  ['camera', 'album']
]
var sizeTypeArray = [
  ['compressed'],
  ['original'],
  ['compressed', 'original']
]
export default {
  data() {
    return {
      title: 'choose/previewImage',
      sourceTypeIndex: 2,
      sourceType: ['拍照', '相册', '拍照或相册'],
      sizeTypeIndex: 2,
      sizeType: ['压缩', '原图', '压缩或原图'],
      countIndex: 8,
      count: [1, 2, 3, 4, 5, 6, 7, 8, 9],
      isCrop: false,
      cropPercent: 80,
      cropWidth: 100,
      cropHeight: 100,
      cropResize: false,
      qsImage: [],
      fid: 0,
      qsType: 5,
      orderNo: "",
    }
  },
  onLoad(options) {
    //options中包含了url附带的参数
    let params = options;
    if (params["id"]) {
      this.fid = params["id"];
      this.orderNo = params["orderNo"];
      //getQaItemXj02
      this.init();
    }
  },
  onUnload() {
    this.qsImage = [];
    this.sourceTypeIndex = 2
    this.sourceType = ['拍照', '相册', '拍照或相册']
    this.sizeTypeIndex = 2
    this.sizeType = ['压缩', '原图', '压缩或原图']
    this.countIndex = 8
  },
  methods: {
    removeImage(index, id) {
      this.qsImage.splice(index, 1);
      if (id) {
        this.$post({
          url: "/Base/removeImage",
          data: {
            id: id
          }
        }).then(res => {
        });
      }
    },
    chooseImage() {
      if (this.qsImage.length >= 9) {
        uni.showToast({
          position: "bottom",
          title: "已经有9张图片了,请删除部分图片之后重新选择"
        });
        return;
      }
      uni.chooseImage({
        sourceType: sourceTypeArray[this.sourceTypeIndex],
        sizeType: sizeTypeArray[this.sizeTypeIndex],
        crop: this.isCrop ? {
          "quality": this.cropPercent,
          "width": this.cropWidth,
          "height": this.cropHeight,
          "resize": this.cropResize
        } : null,
        count: this.qsImage.length + this.count[this.countIndex] > 9 ? 9 - this.qsImage.length : this.count[this.countIndex],
        success: (res) => {
          let url = res.tempFilePaths[0];
          pathToBase64(url)
              .then(base64 => {
                // æ‰¾åˆ°æœ€åŽä¸€ä¸ªæ–œæ çš„位置
                let lastSlashIndex = url.lastIndexOf("/");
                // æå–文件名
                let fileName = url.substring(lastSlashIndex + 1);
                let entity = {};
                entity.img = base64;
                entity.Picturename = fileName;
                entity.fid = this.fid;
                entity.qsType = this.qsType;
                entity.orderNo = this.orderNo;
                entity.base64Date = base64.split(',')[1];
                this.qsImage.push(entity);
              })
              .catch(error => {
                console.error(error)
              })
        },
        fail: (err) => {
          console.log("err: ", JSON.stringify(err));
        }
      });
    },
    previewImage(index) {
      // uni.previewImage({
      //   current: index, // è®¾ç½®å½“前显示图片的链接
      //   urls: this.qsImage.map(s=>s.img), // éœ€è¦é¢„览的图片链接列表
      //   loop: false, // æ˜¯å¦å¼€å¯å›¾ç‰‡è½®æ’­ï¼Œé»˜è®¤ä¸º false
      //   indicator: 'default',// å›¾ç‰‡æŒ‡ç¤ºå™¨ç±»åž‹ï¼Œå¯é€‰å€¼ä¸º "default"、"number"、"pointer",默认为 "default"
      // });
    },
    init() {
      this.$post({
        url: "/Base/getByFid",
        data: {
          id: this.fid,
          qsType: this.qsType
        }
      }).then(res => {
        let tableData = res.data.tbBillList;
        this.qsImage = tableData;
        this.qsImage.forEach(s => {
          s.img = 'data:image/png;base64,' + s.base64Date;
        });
      });
    },
    save() {
      this.$post({
        url: "/Base/saveImage",
        data: {
          entity: this.qsImage
        }
      }).then(res => {
        this.init();
        this.$showMessage("保存成功");
      });
    }
  }
}
</script>
<style>
.click-t {
  color: darkgray;
}
.list-pd {
  margin-top: 25px;
}
.uni-uploader__input-box {
  margin: 5px;
  border: 1px solid #D9D9D9;
}
.image-remove {
  transform: rotate(45deg);
  width: 25px;
  height: 25px;
  position: absolute;
  top: 0;
  right: 0;
  border-radius: 13px;
  background-color: #FF0000;
}
.uni-common-mt {
  background-color: #ffffff;
  /* çº¢è‰²èƒŒæ™¯ */
}
.plus-button {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
  background-color: #ffffff; /* èƒŒæ™¯é¢œè‰² */
  /* padding: 10px; */
  box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1); /* æ·»åŠ åº•éƒ¨é˜´å½±æ•ˆæžœ */
  z-index: 999; /* ç¡®ä¿æŒ‰é’®ä½äºŽé¡¶å±‚ */
}
.uni-flex {
  max-height: calc(100vh - 240px); /* å±å¹•高度减去上传按钮高度 */
  overflow-y: auto; /* å½“内容超出高度时出现垂直滚动条 */
}
.upImg {
  background-color: #3498db;
  color: white;
}
</style>
pages/QC/Laboratory/Laboratory.vue
@@ -4,12 +4,12 @@
    <view class="page-header">
      <view class="header-title">实验室检测详情</view>
    </view>
    <!-- åŠ è½½çŠ¶æ€ -->
    <view v-if="loading" class="loading-container">
      <uni-load-more status="loading" />
      <uni-load-more status="loading"/>
    </view>
    <!-- æ•°æ®å±•示 -->
    <view v-else-if="data" class="content">
      <view class="card">
@@ -21,7 +21,7 @@
            </view>
          </view>
        </view>
        <view class="card-body">
          <view class="info-group">
            <view class="info-row">
@@ -34,7 +34,7 @@
                <text class="info-value">{{ data.createUser }}</text>
              </view>
            </view>
            <view class="info-row">
              <view class="info-item">
                <label class="info-label">生产线编码:</label>
@@ -45,21 +45,21 @@
                <text class="info-value">{{ data.itemNo }}</text>
              </view>
            </view>
            <view class="info-row full-width">
              <view class="info-item">
                <label class="info-label">物料名称:</label>
                <text class="info-value">{{ data.itemName }}</text>
              </view>
            </view>
            <view class="info-row full-width">
              <view class="info-item">
                <label class="info-label">物料规格:</label>
                <text class="info-value">{{ data.itemModel }}</text>
              </view>
            </view>
            <view class="info-row">
              <view class="info-item">
                <label class="info-label">生产车间编码:</label>
@@ -70,14 +70,14 @@
                <text class="info-value">{{ data.departmentId }}</text>
              </view>
            </view>
            <view class="info-row full-width">
              <view class="info-item">
                <label class="info-label">销售订单号:</label>
                <text class="info-value">{{ data.saleOrderNoc }}</text>
              </view>
            </view>
            <view class="info-row">
              <view class="info-item">
                <label class="info-label">检验时间:</label>
@@ -88,36 +88,43 @@
                <text class="info-value">{{ data.inspectionUser }}</text>
              </view>
            </view>
            <view class="info-row">
              <view class="info-item status-item">
                <label class="info-label">检验结果:</label>
                <view class="result-container">
                  <!-- æ˜¾ç¤ºå½“前检验结果 -->
                  <text v-if="data.inspectionResult" class="status-badge" :class="data.inspectionResult === '合格' ? 'success' : 'danger'">
                  <text v-if="data.inspectionResult" :class="data.inspectionResult === '合格' ? 'success' : 'danger'"
                        class="status-badge">
                    {{ data.inspectionResult }}
                  </text>
                  <text v-else class="status-badge pending">
                    å¾…检验
                  </text>
                  <!-- å½•å…¥/重新录入按钮 -->
                  <button v-if="!showResultInput" class="input-btn" @click="showResultInput = true">
                    {{ data.inspectionResult ? '重新录入' : '录入结果' }}
                  </button>
                  <!-- æ£€éªŒç»“果选择按钮 -->
                  <view v-if="showResultInput" class="result-input-container">
                    <button class="result-btn qualified" @click="updateInspectionResult('合格')" :disabled="updating">
                    <button :disabled="updating" class="result-btn qualified" @click="updateInspectionResult('合格')">
                      åˆæ ¼
                    </button>
                    <button class="result-btn unqualified" @click="updateInspectionResult('不合格')" :disabled="updating">
                    <button :disabled="updating" class="result-btn unqualified"
                            @click="updateInspectionResult('不合格')">
                      ä¸åˆæ ¼
                    </button>
                    <button class="result-btn cancel" @click="showResultInput = false" :disabled="updating">
                    <button :disabled="updating" class="result-btn cancel" @click="showResultInput = false">
                      å–消
                    </button>
                  </view>
                  <!-- å›¾ç‰‡ä¸Šä¼ æŒ‰é’® -->
                  <button class="upload-btn" @click="uploadImage">
                    ðŸ“· ä¸Šä¼ å›¾ç‰‡
                  </button>
                </view>
              </view>
            </view>
@@ -125,7 +132,7 @@
        </view>
      </view>
    </view>
    <!-- ç©ºçŠ¶æ€ -->
    <view v-else class="empty-state">
      <view class="empty-icon">📋</view>
@@ -145,24 +152,24 @@
      updating: false
    }
  },
  onLoad(options) {
    this.itemId = options.id;
    if (this.itemId) {
      this.loadData();
    }
  },
  methods: {
    loadData() {
      this.loading = true;
      const requestData = {
        pageIndex: 1,
        limit: 1,
        id: this.itemId
      };
      this.$post({
        url: "/MesLaboratory/GetPage",
        data: requestData
@@ -180,16 +187,16 @@
        this.loading = false;
      });
    },
    updateInspectionResult(result) {
      this.updating = true;
      const requestData = {
        id: this.itemId,
        inspectionResult: result,
        inspectionBy: this.$loginInfo.account
      };
      this.$post({
        url: "/MesLaboratory/UpdateInspectionResult",
        data: requestData
@@ -207,6 +214,16 @@
        this.$showMessage('录入失败,请重试');
      }).finally(() => {
        this.updating = false;
      });
    },
    uploadImage() {
      // å¤„理billNo,去掉"-"后面的部分
      const orderNo = this.data.billNo.split('-')[0];
      // è·³è½¬åˆ°å›¾ç‰‡ä¸Šä¼ é¡µé¢
      uni.navigateTo({
        url: `ImageItem?id=${this.itemId}&orderNo=${orderNo}`
      });
    }
  }
@@ -273,7 +290,7 @@
.info-row {
  display: flex;
  gap: 20px;
  &.full-width {
    flex-direction: column;
  }
@@ -284,7 +301,7 @@
  align-items: center;
  flex: 1;
  min-width: 0;
  &.status-item {
    align-items: center;
    gap: 10px;
@@ -312,19 +329,19 @@
  font-size: 14px;
  border-radius: 20px;
  font-weight: 500;
  &.success {
    background-color: #e6f7ed;
    color: #36b37e;
    border: 1px solid #d1fae5;
  }
  &.danger {
    background-color: #ffefef;
    color: #ff4d4f;
    border: 1px solid #fee2e2;
  }
  &.pending {
    background-color: #f5f5f5;
    color: #999;
@@ -348,12 +365,12 @@
  color: #409EFF;
  cursor: pointer;
  transition: all 0.2s;
  &:hover {
    background-color: #409EFF;
    color: #fff;
  }
  &:active {
    transform: scale(0.95);
  }
@@ -372,50 +389,70 @@
  border: 1px solid;
  cursor: pointer;
  transition: all 0.2s;
  &:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
  &.qualified {
    background-color: #e6f7ed;
    color: #36b37e;
    border-color: #36b37e;
    &:hover:not(:disabled) {
      background-color: #36b37e;
      color: #fff;
    }
  }
  &.unqualified {
    background-color: #ffefef;
    color: #ff4d4f;
    border-color: #ff4d4f;
    &:hover:not(:disabled) {
      background-color: #ff4d4f;
      color: #fff;
    }
  }
  &.cancel {
    background-color: #f5f5f5;
    color: #666;
    border-color: #ccc;
    &:hover:not(:disabled) {
      background-color: #ccc;
      color: #fff;
    }
  }
  &:active:not(:disabled) {
    transform: scale(0.95);
  }
}
.upload-btn {
  padding: 8px 16px;
  font-size: 14px;
  border-radius: 6px;
  border: 1px solid #67C23A;
  background-color: #fff;
  color: #67C23A;
  cursor: pointer;
  transition: all 0.2s;
  &:hover {
    background-color: #67C23A;
    color: #fff;
  }
  &:active {
    transform: scale(0.95);
  }
}
.empty-state {
  display: flex;
  flex-direction: column;
pages/QC/OQC/Add.vue
@@ -1,284 +1,287 @@
<template>
    <view class="page-container">
        <!-- è¡¨å•容器 -->
        <view class="form-card">
            <form :modelValue="formData">
                <view class="form-group">
                    <label class="form-label">检验单号:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.releaseNo" />
                </view>
                <view class="form-group">
                    <label class="form-label">物料编码:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.itemNo" />
                </view>
                <view class="form-group">
                    <label class="form-label">物料名称:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.itemName" />
                </view>
                <view class="form-group">
                    <label class="form-label">物料规格:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.itemModel" />
                </view>
                <view class="form-group">
                    <label class="form-label">订单编号:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.saleOrderNo" />
                </view>
                <view class="form-group">
                    <label class="form-label">送检数量:</label>
                    <input class="form-input" disabled="true" type="number" v-model="formData.planQty" />
                </view>
                <view class="form-group">
                    <label class="form-label">创建时间:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.createDate" />
                </view>
                <view class="form-group">
                    <label class="form-label">创建人:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.createUser" />
                </view>
                <view class="form-group">
                    <label class="form-label">不良描述:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.remeke" />
                </view>
            </form>
        </view>
  <view class="page-container">
    <!-- è¡¨å•容器 -->
    <view class="form-card">
      <form :modelValue="formData">
        <view class="form-group">
          <label class="form-label">检验单号:</label>
          <input v-model="formData.releaseNo" class="form-input" disabled="true" type="text"/>
        </view>
        <view class="form-group">
          <label class="form-label">物料编码:</label>
          <input v-model="formData.itemNo" class="form-input" disabled="true" type="text"/>
        </view>
        <view class="form-group">
          <label class="form-label">物料名称:</label>
          <input v-model="formData.itemName" class="form-input" disabled="true" type="text"/>
        </view>
        <view class="form-group">
          <label class="form-label">物料规格:</label>
          <input v-model="formData.itemModel" class="form-input" disabled="true" type="text"/>
        </view>
        <view class="form-group">
          <label class="form-label">订单编号:</label>
          <input v-model="formData.saleOrderNo" class="form-input" disabled="true" type="text"/>
        </view>
        <view class="form-group">
          <label class="form-label">送检数量:</label>
          <input v-model="formData.planQty" class="form-input" disabled="true" type="number"/>
        </view>
        <view class="form-group">
          <label class="form-label">创建时间:</label>
          <input v-model="formData.createDate" class="form-input" disabled="true" type="text"/>
        </view>
        <view class="form-group">
          <label class="form-label">创建人:</label>
          <input v-model="formData.createUser" class="form-input" disabled="true" type="text"/>
        </view>
        <view class="form-group">
          <label class="form-label">不良描述:</label>
          <input v-model="formData.remeke" class="form-input" disabled="true" type="text"/>
        </view>
      </form>
    </view>
        <!-- æ£€éªŒé¡¹ç›®å¡ç‰‡ -->
        <view class="inspection-card">
            <view class="card-header">
                <view class="header-icon">🔍</view>
                <text class="header-title">检验项目</text>
                <view class="header-badge">{{ tableData.length }}</view>
            </view>
            <view class="inspection-list" v-if="tableData.length > 0">
                <view v-for="(item, index) in tableData" :key="index" class="inspection-item"
                    :class="{ 'item-completed': item.fcheckResu === '合格', 'item-failed': item.fcheckResu === '不合格' }">
                    <!-- å·¦ä¾§çŠ¶æ€æŒ‡ç¤ºå™¨ -->
                    <view class="status-indicator"
                        :class="{ 'status-pass': item.fcheckResu === '合格', 'status-fail': item.fcheckResu === '不合格', 'status-pending': item.fcheckResu === '未检验' }">
                    </view>
                    <!-- ä¸»è¦å†…容区域 -->
                    <view class="item-content">
                        <view class="item-header">
                            <view class="item-title">{{ item.fcheckItem }}</view>
                            <view class="status-badge"
                                :class="{ 'badge-pass': item.fcheckResu === '合格', 'badge-fail': item.fcheckResu === '不合格', 'badge-pending': item.fcheckResu === '未检验' }">
                                <text class="status-icon">{{ item.fcheckResu === '合格' ? '✓' : item.fcheckResu === '不合格' ? '✗' : '○' }}</text>
                                <text class="status-text">{{ item.fcheckResu }}</text>
                            </view>
                        </view>
                        <view class="item-description" v-if="item.fcheckItemDesc">
                            <text class="description-text">{{ item.fcheckItemDesc }}</text>
                        </view>
                        <view class="item-footer">
                            <view class="progress-info">
                                <text class="progress-label">检验进度:</text>
                                <view class="progress-bar">
                                    <view class="progress-fill"
                                        :style="{ width: (item.fenterQty / item.checkQyt * 100) + '%' }"
                                        :class="{ 'progress-complete': item.fenterQty >= item.checkQyt, 'progress-incomplete': item.fenterQty < item.checkQyt }">
                                    </view>
                                </view>
                                <text class="progress-text">{{ item.fenterQty }}/{{ item.checkQyt }}</text>
                            </view>
                            <view class="action-button" @click="toDetail(item)"
                                :class="{ 'btn-complete': item.fenterQty >= item.checkQyt, 'btn-incomplete': item.fenterQty < item.checkQyt }">
                                <text class="btn-text">{{ item.fenterQty >= item.checkQyt ? '查看详情' : '开始检验' }}</text>
                                <text class="btn-icon">→</text>
                            </view>
                        </view>
                    </view>
                </view>
            </view>
            <!-- ç©ºçŠ¶æ€ -->
            <view v-else class="empty-state">
                <view class="empty-icon">📋</view>
                <text class="empty-text">暂无检验项目</text>
                <text class="empty-desc">请先生成检验项目</text>
            </view>
        </view>
    <!-- æ£€éªŒé¡¹ç›®å¡ç‰‡ -->
    <view class="inspection-card">
      <view class="card-header">
        <view class="header-icon">🔍</view>
        <text class="header-title">检验项目</text>
        <view class="header-badge">{{ tableData.length }}</view>
      </view>
        <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
        <view class="action-buttons">
            <button class="btn btn-primary" @click="submitInspection">提交</button>
            <button class="secondary-btn" @click="uploadImages">上传/查看图片</button>
            <button class="btn btn-secondary" @click="addDefectDescription">添加不合格描述</button>
        </view>
        <!-- ä¸åˆæ ¼æè¿°å¼¹å‡ºå±‚ -->
        <view v-if="remarksPopup" class="overlay active">
          <view class="popup" :class="{ 'popup-scale': isPopupAnimated }" @animationend="isPopupAnimated = false">
            <view class="popup-header">
              <h3 class="popup-title">修改不合格描述</h3>
              <view class="close-btn" @click="remarksPopup = !remarksPopup">×</view>
            </view>
            <form>
              <view class="form-group">
                <label class="form-label">不合格描述:</label>
                <input class="form-input" type="text" v-model="remarks" />
              </view>
              <view class="button-group popup-buttons">
                <button :class="['action-btn', 'btn-danger']" @click="editRemarks">
                  ä¿®æ”¹
                </button>
                <button :class="['action-btn', 'btn-light']" @click="remarksPopup = !remarksPopup">
                  å–消
                </button>
              </view>
            </form>
          </view>
        </view>
    </view>
      <view v-if="tableData.length > 0" class="inspection-list">
        <view v-for="(item, index) in tableData" :key="index" :class="{ 'item-completed': item.fcheckResu === '合格', 'item-failed': item.fcheckResu === '不合格' }"
              class="inspection-item">
          <!-- å·¦ä¾§çŠ¶æ€æŒ‡ç¤ºå™¨ -->
          <view :class="{ 'status-pass': item.fcheckResu === '合格', 'status-fail': item.fcheckResu === '不合格', 'status-pending': item.fcheckResu === '未检验' }"
                class="status-indicator">
          </view>
          <!-- ä¸»è¦å†…容区域 -->
          <view class="item-content">
            <view class="item-header">
              <view class="item-title">{{ item.fcheckItem }}</view>
              <view :class="{ 'badge-pass': item.fcheckResu === '合格', 'badge-fail': item.fcheckResu === '不合格', 'badge-pending': item.fcheckResu === '未检验' }"
                    class="status-badge">
                <text class="status-icon">{{
                    item.fcheckResu === '合格' ? '✓' : item.fcheckResu === '不合格' ? '✗' : '○'
                  }}
                </text>
                <text class="status-text">{{ item.fcheckResu }}</text>
              </view>
            </view>
            <view v-if="item.fcheckItemDesc" class="item-description">
              <text class="description-text">{{ item.fcheckItemDesc }}</text>
            </view>
            <view class="item-footer">
              <view class="progress-info">
                <text class="progress-label">检验进度:</text>
                <view class="progress-bar">
                  <view :class="{ 'progress-complete': item.fenterQty >= item.checkQyt, 'progress-incomplete': item.fenterQty < item.checkQyt }"
                        :style="{ width: (item.fenterQty / item.checkQyt * 100) + '%' }"
                        class="progress-fill">
                  </view>
                </view>
                <text class="progress-text">{{ item.fenterQty }}/{{ item.checkQyt }}</text>
              </view>
              <view :class="{ 'btn-complete': item.fenterQty >= item.checkQyt, 'btn-incomplete': item.fenterQty < item.checkQyt }" class="action-button"
                    @click="toDetail(item)">
                <text class="btn-text">{{ item.fenterQty >= item.checkQyt ? '查看详情' : '开始检验' }}</text>
                <text class="btn-icon">→</text>
              </view>
            </view>
          </view>
        </view>
      </view>
      <!-- ç©ºçŠ¶æ€ -->
      <view v-else class="empty-state">
        <view class="empty-icon">📋</view>
        <text class="empty-text">暂无检验项目</text>
        <text class="empty-desc">请先生成检验项目</text>
      </view>
    </view>
    <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
    <view class="action-buttons">
      <button class="btn btn-primary" @click="submitInspection">提交</button>
      <button class="secondary-btn" @click="uploadImages">上传/查看图片</button>
      <button class="btn btn-secondary" @click="addDefectDescription">添加不合格描述</button>
    </view>
    <!-- ä¸åˆæ ¼æè¿°å¼¹å‡ºå±‚ -->
    <view v-if="remarksPopup" class="overlay active">
      <view :class="{ 'popup-scale': isPopupAnimated }" class="popup" @animationend="isPopupAnimated = false">
        <view class="popup-header">
          <h3 class="popup-title">修改不合格描述</h3>
          <view class="close-btn" @click="remarksPopup = !remarksPopup">×</view>
        </view>
        <form>
          <view class="form-group">
            <label class="form-label">不合格描述:</label>
            <input v-model="remarks" class="form-input" type="text"/>
          </view>
          <view class="button-group popup-buttons">
            <button :class="['action-btn', 'btn-danger']" @click="editRemarks">
              ä¿®æ”¹
            </button>
            <button :class="['action-btn', 'btn-light']" @click="remarksPopup = !remarksPopup">
              å–消
            </button>
          </view>
        </form>
      </view>
    </view>
  </view>
</template>
<script>
    export default {
        data() {
            return {
                formData: {},
                tableData: [],
                remarks: "",
                remarksPopup: false,
                isPopupAnimated: false,
            }
        },
        onLoad(options) {
            //options中包含了url附带的参数
            let params = options;
export default {
  data() {
    return {
      formData: {},
      tableData: [],
      remarks: "",
      remarksPopup: false,
      isPopupAnimated: false,
    }
  },
  onLoad(options) {
    //options中包含了url附带的参数
    let params = options;
            if (params["id"]) {
                this.formData.id = params["id"];
                this.init();
            }
        },
        methods: {
            init() {
                let userName = this.$loginInfo.account;
                this.$post({
                    url: "/MesOqcItemsDetect02/getPage",
                    data: {
                        id: this.formData.id,
                        createUser: userName,
                        pageIndex: 1,
                        limit: 1,
                    }
                }).then(res => {
                    let data = res.data[0];
                    if (data) {
                        this.formData = data;
                        this.getDetail5();
                    }
                });
            },
    if (params["id"]) {
      this.formData.id = params["id"];
      this.init();
    }
  },
  methods: {
    init() {
      let userName = this.$loginInfo.account;
      this.$post({
        url: "/MesOqcItemsDetect02/getPage",
        data: {
          id: this.formData.id,
          createUser: userName,
          pageIndex: 1,
          limit: 1,
        }
      }).then(res => {
        let data = res.data[0];
        if (data) {
          this.formData = data;
          this.getDetail5();
        }
      });
    },
            getDetail5() {
                let userName = this.$loginInfo.account;
                this.$post({
                    url: "/MesOqcItemsDetect02/GetDetail5",
                    data: {
                        id: this.formData.id,
                        createUser: userName,
                        releaseNo: this.formData.releaseNo,
                    }
                }).then(res => {
                    let data = res.data;
                    this.tableData = data;
                });
            },
            uploadImages() {
                // ä¸Šä¼ /查看图片的逻辑
                uni.navigateTo({
                    url: 'ImageItem?id=' + this.formData.releaseNo
                });
            },
            addDefectDescription() {
                // ç¡®ä¿è¡¨å•数据存在
                if (!this.formData) return;
    getDetail5() {
      let userName = this.$loginInfo.account;
      this.$post({
        url: "/MesOqcItemsDetect02/GetDetail5",
        data: {
          id: this.formData.id,
          createUser: userName,
          releaseNo: this.formData.releaseNo,
        }
      }).then(res => {
        let data = res.data;
        this.tableData = data;
      });
    },
    uploadImages() {
      // ä¸Šä¼ /查看图片的逻辑
      uni.navigateTo({
        url: 'ImageItem?id=' + this.formData.id
      });
    },
    addDefectDescription() {
      // ç¡®ä¿è¡¨å•数据存在
      if (!this.formData) return;
                this.remarksPopup = !this.remarksPopup;
                this.remarks = this.formData.remeke || '';
                this.isPopupAnimated = true;
            },
            toDetail(item) {
      this.remarksPopup = !this.remarksPopup;
      this.remarks = this.formData.remeke || '';
      this.isPopupAnimated = true;
    },
    toDetail(item) {
                uni.navigateTo({
                    url: 'detail?mainId=' + item.id + '&releaseNo=' + this.formData
                        .releaseNo
                });
      uni.navigateTo({
        url: 'detail?mainId=' + item.id + '&releaseNo=' + this.formData
            .releaseNo
      });
            },
            submitInspection() {
                // æ£€éªŒæäº¤çš„逻辑
                this.$post({
                    url: "/MesOqcItemsDetect02/IqcQaSubmit",
                    data: {
                        userNo: this.$loginInfo.account,
                        releaseNo: this.formData.releaseNo
                    }
                }).then(res => {
                    if (res.status == 0) {
    },
    submitInspection() {
      // æ£€éªŒæäº¤çš„逻辑
      this.$post({
        url: "/MesOqcItemsDetect02/IqcQaSubmit",
        data: {
          userNo: this.$loginInfo.account,
          releaseNo: this.formData.releaseNo
        }
      }).then(res => {
        if (res.status == 0) {
                        uni.showToast({
                            title: res.message.toString(),
                            icon: 'success',
                            duration: 2000
                        })
                        // å¦‚果有页面跳转,需要用定时器延迟
                        setTimeout(() => {
                            uni.navigateTo({
                                url: 'List'
                            });
                        }, 2000); // ä¿æŒä¸Ž duration ç›¸åŒçš„æ—¶é•¿
          uni.showToast({
            title: res.message.toString(),
            icon: 'success',
            duration: 2000
          })
          // å¦‚果有页面跳转,需要用定时器延迟
          setTimeout(() => {
            uni.navigateTo({
              url: 'List'
            });
          }, 2000); // ä¿æŒä¸Ž duration ç›¸åŒçš„æ—¶é•¿
                    } else {
                        uni.showModal({
                            title: "提示",
                            content: res.message.toString(),
                            confirmText: "确定",
                            showCancel: false,
                            success: (res) => {
        } else {
          uni.showModal({
            title: "提示",
            content: res.message.toString(),
            confirmText: "确定",
            showCancel: false,
            success: (res) => {
                            }
                        })
                    }
                })
            },
            editRemarks() {
              if (this.remarks && this.formData.id) {
                this.$post({
                  url: "/MesOqcItemsDetect02/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 = false;
                    this.$showMessage("保存成功");
                    this.init();
                  } else {
                    this.$showMessage("保存失败");
                  }
                }).catch(() => {
                  this.$showMessage("保存失败,请重试");
                });
              } else if (!this.formData.id) {
                this.$showMessage("请先生成检验单");
              } else {
                this.$showMessage("请输入不合格描述");
              }
            },
        }
    }
            }
          })
        }
      })
    },
    editRemarks() {
      if (this.remarks && this.formData.id) {
        this.$post({
          url: "/MesOqcItemsDetect02/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 = false;
            this.$showMessage("保存成功");
            this.init();
          } else {
            this.$showMessage("保存失败");
          }
        }).catch(() => {
          this.$showMessage("保存失败,请重试");
        });
      } else if (!this.formData.id) {
        this.$showMessage("请先生成检验单");
      } else {
        this.$showMessage("请输入不合格描述");
      }
    },
  }
}
</script>
<style scoped>
@@ -342,13 +345,13 @@
/* æ“ä½œæŒ‰é’®åŒºåŸŸ */
.action-buttons {
  display: flex;
  justify-content: space-between;
  gap: 15px;
  flex-direction: column;
  gap: 12px;
  padding: 15px 0;
}
.btn {
  flex: 1;
.btn, .secondary-btn {
  width: 100%;
  height: 45px;
  border-radius: 8px;
  border: none;
@@ -386,6 +389,19 @@
  background-color: #6D6D70;
}
/* å¤§å±å¹•时保持横向排列 */
@media (min-width: 768px) {
  .action-buttons {
    flex-direction: row;
    gap: 15px;
  }
  .btn, .secondary-btn {
    flex: 1;
    width: auto;
  }
}
/* æ£€éªŒé¡¹ç›®å¡ç‰‡ */
.inspection-card {
  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
@@ -414,7 +430,7 @@
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(45deg, rgba(255,255,255,0.1) 0%, transparent 100%);
  background: linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, transparent 100%);
  pointer-events: none;
}
@@ -699,41 +715,41 @@
    margin: 0 -8px 24px -8px;
    border-radius: 12px;
  }
  .card-header {
    padding: 16px 20px;
  }
  .header-title {
    font-size: 16px;
  }
  .inspection-list {
    padding: 16px 20px;
  }
  .item-content {
    padding: 16px 20px;
  }
  .item-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  .item-footer {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  .progress-info {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  .action-button {
    justify-content: center;
  }
pages/QC/OQC/ImageItem.vue
@@ -14,16 +14,16 @@
          <view class="uni-flex" style="flex-wrap: wrap;">
            <view v-for="(image,index) in qsImage" :key="index" class="uni-uploader__input-box"
                  style="position: relative; border: 0;">
              <image :src="image.img" :data-src="image.img"
              <image :data-src="image.img" :src="image.img"
                     @tap="previewImage(index)"></image>
              <image src="/static/plus.png" class="image-remove" @click="removeImage(index,image.id)"></image>
              <image class="image-remove" src="/static/plus.png" @click="removeImage(index,image.id)"></image>
            </view>
            <image class="uni-uploader__input-box" @tap="chooseImage" src="/static/plus.png"></image>
            <image class="uni-uploader__input-box" src="/static/plus.png" @tap="chooseImage"></image>
          </view>
        </view>
      </view>
      <view class="plus-button">
        <button type="primary" class="upImg" @click="save">上传图片</button>
        <button class="upImg" type="primary" @click="save">上传图片</button>
      </view>
    </view>
    <!-- #ifdef APP -->
@@ -33,7 +33,7 @@
<script>
import {pathToBase64, base64ToPath} from '../../../js_sdk/mmmm-image-tools/index'
import {pathToBase64} from '../../../js_sdk/mmmm-image-tools/index'
var sourceTypeArray = [
  ['camera'],
@@ -62,7 +62,7 @@
      cropResize: false,
      qsImage: [],
      fid: 0,
      qsType : 5,
      qsType: 5,
    }
  },
  onLoad(options) {
@@ -152,9 +152,9 @@
    },
    init() {
      this.$post({
        url: "/Base/getLljAllImgByFid",
        url: "/Base/getByOqcFid",
        data: {
          id: this.fid,
          fid: this.fid,
          qsType: this.qsType
        }
      }).then(res => {
@@ -225,10 +225,11 @@
  max-height: calc(100vh - 240px); /* å±å¹•高度减去上传按钮高度 */
  overflow-y: auto; /* å½“内容超出高度时出现垂直滚动条 */
}
.upImg{
      background-color: #3498db;
      color: white;
.upImg {
  background-color: #3498db;
  color: white;
}
</style>
pages/QC/OQC/ScanCode.vue
@@ -1,745 +1,928 @@
<template>
    <view class="container">
        <!-- è¡¨å•区域 -->
        <view class="form-container card">
            <form :modelValue="formData">
                <view class="form-grid">
                    <view class="form-group col-2">
                        <label class="form-label">物料条码:</label>
                        <view class="input-with-scan">
                            <input class="form-input scan-input" type="text" v-model="formData.ItemBarcode"
                                @confirm="addItemBarCode"
                                placeholder="输入后离开或按回车" />
                            <view class="scan-button" @tap="startScan">
                                <uni-icons type="scan" size="24" color="#007bff"></uni-icons>
                                <text class="scan-text">扫码</text>
                            </view>
                        </view>
                    </view>
                    <view class="form-group col-2">
                        <label class="form-label">产品名称:</label>
                        <input class="form-input" disabled="true" type="text" v-model="formData.itemName" />
                    </view>
                    <view class="form-group col-2">
                        <label class="form-label">产品编码:</label>
                        <input class="form-input" disabled="true" type="text" v-model="formData.itemNo" />
                    </view>
                    <view class="form-group col-2">
                        <label class="form-label">订单编号:</label>
                        <input class="form-input" disabled="true" type="text" v-model="formData.taskNo" />
                    </view>
                    <view class="form-group col-2">
                        <label class="form-label">已扫数量:</label>
                        <input class="form-input" disabled="true" type="text" v-model="quantity" />
                    </view>
                </view>
            </form>
        </view>
  <view class="container">
    <!-- è¡¨å•区域 -->
    <view class="form-container card">
      <form :modelValue="formData">
        <view class="form-grid">
          <view class="form-group col-2">
            <label class="form-label">物料条码:</label>
            <view class="input-with-scan">
              <input v-model="formData.ItemBarcode" class="form-input scan-input" placeholder="输入后离开或按回车"
                     type="text"
                     @confirm="addItemBarCode"/>
              <view class="scan-button" @tap="startScan">
                <uni-icons color="#007bff" size="24" type="scan"></uni-icons>
                <text class="scan-text">扫码</text>
              </view>
            </view>
          </view>
          <view class="form-group col-2">
            <label class="form-label">产品名称:</label>
            <input v-model="formData.itemName" class="form-input" disabled="true" type="text"/>
          </view>
          <view class="form-group col-2">
            <label class="form-label">产品编码:</label>
            <input v-model="formData.itemNo" class="form-input" disabled="true" type="text"/>
          </view>
          <view class="form-group col-2">
            <label class="form-label">订单编号:</label>
            <input v-model="formData.taskNo" class="form-input" disabled="true" type="text"/>
          </view>
          <view class="form-group col-2">
            <label class="form-label">已扫数量:</label>
            <input v-model="quantity" class="form-input" disabled="true" type="text"/>
          </view>
        </view>
      </form>
    </view>
        <!-- å¾…检条码表格区域 -->
        <view class="table-container card">
            <view class="table-header">
                <text class="section-title">待检条码列表</text>
                <view class="table-tip">
                    <text class="tip-text">👈 å·¦å³æ»‘动查看更多信息</text>
                </view>
            </view>
            <view class="table-wrapper">
                <scroll-view class="table-scroll" scroll-x="true" show-scrollbar="true">
                    <uni-table ref="table" border emptyText="暂无更多数据" class="custom-table">
                        <uni-tr class="table-header-row">
                            <uni-th align="center" class="th" width="80">序号</uni-th>
                            <uni-th align="center" class="th" width="160">物料条码</uni-th>
                            <uni-th align="center" class="th" width="140">订单编号</uni-th>
                            <uni-th align="center" class="th" width="140">产品编码</uni-th>
                            <uni-th align="center" class="th" width="160">产品名称</uni-th>
                            <uni-th align="center" class="th" width="100">条码数量</uni-th>
                            <uni-th align="center" class="th" width="80"> </uni-th>
                        </uni-tr>
                        <uni-tr v-for="(item, index) in tableData" :key="index" class="table-row">
                            <uni-td align="center" width="80">
                                <view class="description-text">{{ index + 1 }}</view>
                            </uni-td>
                            <uni-td align="center" width="160">
                                <view class="cell-content">{{ item.itemBarcode }}</view>
                            </uni-td>
                            <uni-td align="center" width="140">
                                <view class="cell-content">{{ item.taskNo || '-' }}</view>
                            </uni-td>
                            <uni-td align="center" width="140">
                                <view class="cell-content">{{ item.itemNo }}</view>
                            </uni-td>
                            <uni-td align="center" width="160">
                                <view class="cell-content" :title="item.itemName">{{ item.itemName }}</view>
                            </uni-td>
                            <uni-td align="center" width="100">
                                <view class="cell-content quantity">{{ item.quantity }}</view>
                            </uni-td>
                            <uni-td align="center" width="80">
                                <view class="cell-content"> </view>
                            </uni-td>
                        </uni-tr>
                    </uni-table>
                </scroll-view>
                <!-- å³å›ºå®šæ‚¬æµ®åˆ é™¤æŒ‰é’®åˆ— -->
                <view class="fixed-delete-column">
                    <view class="fixed-header">
                        <text class="fixed-header-text">操作</text>
                    </view>
                    <view class="fixed-content">
                        <view v-for="(item, index) in tableData" :key="index" class="fixed-delete-item"
                            :class="{ 'even': index % 2 === 1 }">
                            <view @click="deleteItem(index)" class="delete-icon">
                                <uni-icons type="trash" size="24"></uni-icons>
                            </view>
                        </view>
                    </view>
                </view>
            </view>
        </view>
    <!-- å¾…检条码表格区域 -->
    <view class="table-container card">
      <view class="table-header">
        <text class="section-title">待检条码列表</text>
        <view class="table-tip">
          <text class="tip-text">👈 å·¦å³æ»‘动查看更多信息</text>
        </view>
      </view>
      <view class="table-wrapper">
        <scroll-view class="table-scroll" scroll-x="true" show-scrollbar="true">
          <uni-table ref="table" border class="custom-table" emptyText="暂无更多数据">
            <uni-tr class="table-header-row">
              <uni-th align="center" class="th" width="80">序号</uni-th>
              <uni-th align="center" class="th" width="160">物料条码</uni-th>
              <uni-th align="center" class="th" width="140">订单编号</uni-th>
              <uni-th align="center" class="th" width="140">产品编码</uni-th>
              <uni-th align="center" class="th" width="160">产品名称</uni-th>
              <uni-th align="center" class="th" width="100">条码数量</uni-th>
              <uni-th align="center" class="th" width="80">删除</uni-th>
            </uni-tr>
            <uni-tr v-for="(item, index) in tableData" :key="index" class="table-row">
              <uni-td align="center" width="80">
                <view class="description-text">{{ index + 1 }}</view>
              </uni-td>
              <uni-td align="center" width="160">
                <view class="cell-content">{{ item.itemBarcode }}</view>
              </uni-td>
              <uni-td align="center" width="140">
                <view class="cell-content">{{ item.taskNo || '-' }}</view>
              </uni-td>
              <uni-td align="center" width="140">
                <view class="cell-content">{{ item.itemNo }}</view>
              </uni-td>
              <uni-td align="center" width="160">
                <view :title="item.itemName" class="cell-content">{{ item.itemName }}</view>
              </uni-td>
              <uni-td align="center" width="100">
                <view class="cell-content quantity">{{ item.quantity }}</view>
              </uni-td>
              <uni-td align="center" width="80">
                <view class="delete-icon" @click="deleteItem(index)">
                  <uni-icons size="24" type="trash"></uni-icons>
                </view>
              </uni-td>
            </uni-tr>
          </uni-table>
        </scroll-view>
      </view>
    </view>
        <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
        <view class="action-buttons-container button-group">
            <view class="plus-button" :class="{ 'submitting': isSubmitting }" @tap="handleSubmit">
                <text>{{ isSubmitting ? '提交中...' : '生成OQC检验单' }}</text>
            </view>
        </view>
    </view>
    <!-- æ“ä½œæŒ‰é’®åŒºåŸŸ -->
    <view class="action-buttons-container button-group">
      <view :class="{ 'submitting': isSubmitting }" class="plus-button" @tap="handleSubmit">
        <text>{{ isSubmitting ? '提交中...' : '生成OQC检验单' }}</text>
      </view>
    </view>
  </view>
</template>
<script>
    export default {
        data() {
            return {
                formData: {},
                tableData: [],
                quantity: 0,
                isSubmitting: false, // é˜²æ­¢é‡å¤æäº¤
                isProcessing: false, // é˜²æ­¢é‡å¤å¤„理条码
            }
        },
        methods: {
            // å¯åŠ¨æ‰«ç åŠŸèƒ½
            startScan() {
                // æ£€æŸ¥æ˜¯å¦æ­£åœ¨å¤„理条码,防止重复扫码
                if (this.isProcessing) {
                    this.$showMessage("正在处理条码,请稍候");
                    return;
                }
export default {
  data() {
    return {
      formData: {},
      tableData: [],
      quantity: 0,
      isSubmitting: false, // é˜²æ­¢é‡å¤æäº¤
      isProcessing: false, // é˜²æ­¢é‡å¤å¤„理条码
    }
  },
  methods: {
    // å¯åŠ¨æ‰«ç åŠŸèƒ½
    startScan() {
      // æ£€æŸ¥æ˜¯å¦æ­£åœ¨å¤„理条码,防止重复扫码
      if (this.isProcessing) {
        this.$showMessage("正在处理条码,请稍候");
        return;
      }
                uni.scanCode({
                    scanType: ['barCode', 'qrCode'], // æ”¯æŒæ¡ç å’ŒäºŒç»´ç 
                    success: (res) => {
                        console.log('扫码成功:', res);
                        // å°†æ‰«ç ç»“果设置到输入框
                        this.formData.ItemBarcode = res.result;
                        // è‡ªåŠ¨å¤„ç†æ‰«ç ç»“æžœ
                        this.addItemBarCode();
                    },
                    fail: (err) => {
                        console.log('扫码失败:', err);
                        if (err.errMsg && err.errMsg.indexOf('cancel') === -1) {
                            this.$showMessage("扫码失败,请重试");
                        }
                    }
                });
            },
      uni.scanCode({
        scanType: ['barCode', 'qrCode'], // æ”¯æŒæ¡ç å’ŒäºŒç»´ç 
        success: (res) => {
          console.log('扫码成功:', res);
          // å°†æ‰«ç ç»“果设置到输入框
          this.formData.ItemBarcode = res.result;
          // è‡ªåŠ¨å¤„ç†æ‰«ç ç»“æžœ
          this.addItemBarCode();
        },
        fail: (err) => {
          console.log('扫码失败:', err);
          if (err.errMsg && err.errMsg.indexOf('cancel') === -1) {
            this.$showMessage("扫码失败,请重试");
          }
        }
      });
    },
            addItemBarCode() {
                // é˜²æ­¢é‡å¤å¤„理
                if (this.isProcessing) {
                    return;
                }
    addItemBarCode() {
      // é˜²æ­¢é‡å¤å¤„理
      if (this.isProcessing) {
        return;
      }
                // æ ¡éªŒç‰©æ–™æ¡ç æ˜¯å¦ä¸ºç©º
                if (!this.formData.ItemBarcode || this.formData.ItemBarcode.trim() === '') {
                    this.$showMessage("请输入物料条码");
                    return;
                }
      // æ ¡éªŒç‰©æ–™æ¡ç æ˜¯å¦ä¸ºç©º
      if (!this.formData.ItemBarcode || this.formData.ItemBarcode.trim() === '') {
        this.$showMessage("请输入物料条码");
        return;
      }
                // æ£€æŸ¥ç‰©æ–™æ¡ç æ˜¯å¦å·²å­˜åœ¨äºŽ tableData ä¸­
                const isDuplicate = this.tableData.some(item => item.itemBarcode === this.formData.ItemBarcode);
                if (isDuplicate) {
                    this.$showMessage("该物料条码已存在,请检查!");
                    return;
                }
      // æ£€æŸ¥ç‰©æ–™æ¡ç æ˜¯å¦å·²å­˜åœ¨äºŽ tableData ä¸­
      const isDuplicate = this.tableData.some(item => item.itemBarcode === this.formData.ItemBarcode);
      if (isDuplicate) {
        this.$showMessage("该物料条码已存在,请检查!");
        return;
      }
                // è®¾ç½®å¤„理状态
                this.isProcessing = true;
      // è®¾ç½®å¤„理状态
      this.isProcessing = true;
                // å¦‚果通过了上述校验,发送请求并更新数据
                this.$post({
                    url: "/MesOqcItemsDetect02/GetItemBarCode",
                    data: {
                        ItemCode: this.formData.ItemBarcode
                    }
                }).then(res => {
                    let fr = res.data.tbBillList;
      // å¦‚果通过了上述校验,发送请求并更新数据
      this.$post({
        url: "/MesOqcItemsDetect02/GetItemBarCode",
        data: {
          ItemCode: this.formData.ItemBarcode
        }
      }).then(res => {
        let fr = res.data.tbBillList;
                    // æ•°æ®å®Œæ•´æ€§æ ¡éªŒ
                    if (!fr) {
                        this.$showMessage("获取条码信息失败,请重试");
                        return;
                    }
        // æ•°æ®å®Œæ•´æ€§æ ¡éªŒ
        if (!fr) {
          this.$showMessage("获取条码信息失败,请重试");
          return;
        }
                    if (!fr.itemId || !fr.itemName || !fr.itemNo) {
                        this.$showMessage("条码信息不完整,请检查条码");
                        return;
                    }
        if (!fr.itemId || !fr.itemName || !fr.itemNo) {
          this.$showMessage("条码信息不完整,请检查条码");
          return;
        }
                    if (fr.quantity <= 0) {
                        this.$showMessage("条码数量为0,请确认");
                        return;
                    }
        if (fr.quantity <= 0) {
          this.$showMessage("条码数量为0,请确认");
          return;
        }
                    //需要验证
                    //扫的码的itemId必须是和tableData中的itemId相同  å¿…须的条件
                    //扫的码的TaskNo也必须是和tableData中的TaskNo相同
                    //TaskNo为空的只能和TaskNo为空的一起扫
                    // å¦‚æžœtableData中已有数据,需要验证itemId和TaskNo的一致性
                    if (this.tableData.length > 0) {
                        const firstItem = this.tableData[0];
                        // éªŒè¯itemId是否相同(必须条件)
                        if (fr.itemId !== firstItem.itemId) {
                            this.$showMessage("物料编码不一致,请扫描相同物料的条码");
                            return;
                        }
                        // éªŒè¯TaskNo是否相同
                        if (fr.taskNo !== firstItem.taskNo) {
                            this.$showMessage("订单编号不一致,请扫描相同订单的条码");
                            return;
                        }
                        // éªŒè¯ç©ºTaskNo的情况:TaskNo为空的只能和TaskNo为空的一起扫
                        if ((fr.taskNo === '' || fr.taskNo === null || fr.taskNo === undefined) &&
                            (firstItem.taskNo !== '' && firstItem.taskNo !== null && firstItem.taskNo !== undefined)) {
                            this.$showMessage("订单编号不匹配,空订单编号只能与空订单编号一起扫描");
                            return;
                        }
                        if ((fr.taskNo !== '' && fr.taskNo !== null && fr.taskNo !== undefined) &&
                            (firstItem.taskNo === '' || firstItem.taskNo === null || firstItem.taskNo === undefined)) {
                            this.$showMessage("订单编号不匹配,有订单编号的条码只能与有订单编号的条码一起扫描");
                            return;
                        }
                    }
        //需要验证
        //扫的码的itemId必须是和tableData中的itemId相同  å¿…须的条件
        //扫的码的TaskNo也必须是和tableData中的TaskNo相同
        //TaskNo为空的只能和TaskNo为空的一起扫
                    this.formData = fr;
                    this.tableData.push(fr); // å°†æ–°æ•°æ®æ·»åŠ åˆ°è¡¨æ ¼
                    this.quantity = this.tableData.reduce(function(accumulator, current) {
                        return accumulator + current["quantity"];
                    }, 0);
                    // æ¸…空输入框
                    this.formData.ItemBarcode = '';
                }).catch(error => {
                    this.$showMessage("获取条码信息失败,请重试");
                }).finally(() => {
                    // é‡ç½®å¤„理状态
                    this.isProcessing = false;
                });
            },
        // å¦‚æžœtableData中已有数据,需要验证itemId和TaskNo的一致性
        if (this.tableData.length > 0) {
          const firstItem = this.tableData[0];
            // åˆ é™¤æ“ä½œï¼šåˆ é™¤ tableData ä¸­æŒ‡å®šç´¢å¼•的数据
            deleteItem(index) {
                this.tableData.splice(index, 1); // åˆ é™¤è¯¥è¡Œæ•°æ®
                this.quantity = this.tableData.reduce(function(accumulator, current) {
                    return accumulator + current["quantity"];
                }, 0); // æ›´æ–°æ¡ç æ•°é‡
          // éªŒè¯itemId是否相同(必须条件)
          if (fr.itemId !== firstItem.itemId) {
            this.$showMessage("物料编码不一致,请扫描相同物料的条码");
            return;
          }
                if (this.tableData.length <= 0) {
                    this.formData = {};
                }
            },
          // éªŒè¯TaskNo是否相同
          if (fr.taskNo !== firstItem.taskNo) {
            this.$showMessage("订单编号不一致,请扫描相同订单的条码");
            return;
          }
            handleSubmit() {
                console.log("handleSubmit方法被调用,isSubmitting:", this.isSubmitting);
                console.log("tableData长度:", this.tableData.length);
                console.log("quantity:", this.quantity);
                this.submit();
            },
          // éªŒè¯ç©ºTaskNo的情况:TaskNo为空的只能和TaskNo为空的一起扫
          if ((fr.taskNo === '' || fr.taskNo === null || fr.taskNo === undefined) &&
              (firstItem.taskNo !== '' && firstItem.taskNo !== null && firstItem.taskNo !== undefined)) {
            this.$showMessage("订单编号不匹配,空订单编号只能与空订单编号一起扫描");
            return;
          }
            submit() {
                console.log("submit方法被调用");
                // é˜²æ­¢é‡å¤æäº¤
                if (this.isSubmitting) {
                    this.$showMessage("正在提交中,请勿重复操作");
                    return;
                }
          if ((fr.taskNo !== '' && fr.taskNo !== null && fr.taskNo !== undefined) &&
              (firstItem.taskNo === '' || firstItem.taskNo === null || firstItem.taskNo === undefined)) {
            this.$showMessage("订单编号不匹配,有订单编号的条码只能与有订单编号的条码一起扫描");
            return;
          }
        }
                // æ ¡éªŒç”¨æˆ·ç™»å½•状态
                if (!this.$loginInfo.account) {
                    this.$showMessage("用户未登录,请重新登录");
                    return;
                }
        this.formData = fr;
        this.tableData.push(fr); // å°†æ–°æ•°æ®æ·»åŠ åˆ°è¡¨æ ¼
        this.quantity = this.tableData.reduce(function (accumulator, current) {
          return accumulator + current["quantity"];
        }, 0);
                // æ ¡éªŒæ¡ç æ•°é‡æ˜¯å¦æœ‰æ•ˆ
                if (this.quantity <= 0) {
                    this.$showMessage("条码数量必须大于0");
                    return;
                }
        // æ¸…空输入框
        this.formData.ItemBarcode = '';
      }).catch(error => {
        this.$showMessage("获取条码信息失败,请重试");
      }).finally(() => {
        // é‡ç½®å¤„理状态
        this.isProcessing = false;
      });
    },
                // æ ¡éªŒæ˜¯å¦æœ‰æ•°æ®
                if (this.tableData.length === 0) {
                    this.$showMessage("请扫描条码");
                    return;
                }
    // åˆ é™¤æ“ä½œï¼šåˆ é™¤ tableData ä¸­æŒ‡å®šç´¢å¼•的数据
    deleteItem(index) {
      this.tableData.splice(index, 1); // åˆ é™¤è¯¥è¡Œæ•°æ®
      this.quantity = this.tableData.reduce(function (accumulator, current) {
        return accumulator + current["quantity"];
      }, 0); // æ›´æ–°æ¡ç æ•°é‡
                let userName = this.$loginInfo.account;
                this.isSubmitting = true; // è®¾ç½®æäº¤çŠ¶æ€
      if (this.tableData.length <= 0) {
        this.formData = {};
      }
    },
                // å‘送请求
                this.$post({
                    url: "/MesOqcItemsDetect02/ItemBarCodeSubmit",
                    data: {
                        itemBarCodeData: this.tableData,
                        CreateUser: userName
                    }
                }).then(response => {
                    if(response.status == 0){
                        // è¯·æ±‚成功后显示选择框
                        uni.showModal({
                            title: "操作成功",
                            content: "已经成功生成检验单",
                            showCancel: true,
                            cancelText: "继续扫码",
                            confirmText: "跳转到检验单",
                            success: (res) => {
                                if (res.confirm) {
                                    // ç”¨æˆ·ç‚¹å‡»äº†"跳转到检验单"
                                    uni.navigateTo({
                                        url: '/pages/QC/OQC/Add?id=' + response.data
                                    });
                                } else if (res.cancel) {
                                    // ç”¨æˆ·ç‚¹å‡»äº†"继续扫码"
                                    this.clearData();
                                }
                            }
                        });
                    }else{
                        this.$showMessage(response.message);
                    }
                }).catch(error => {
                    // è¯·æ±‚失败时的处理
                    this.$showMessage("请求失败,请稍后重试");
                }).finally(() => {
                    // æ— è®ºæˆåŠŸè¿˜æ˜¯å¤±è´¥éƒ½é‡ç½®æäº¤çŠ¶æ€
                    this.isSubmitting = false;
                });
            },
    handleSubmit() {
      console.log("handleSubmit方法被调用,isSubmitting:", this.isSubmitting);
      console.log("tableData长度:", this.tableData.length);
      console.log("quantity:", this.quantity);
      this.submit();
    },
            // æ¸…空表格和表单数据
            clearData() {
                this.tableData = [];
                this.formData = {};
                this.quantity = 0;
                this.isSubmitting = false;
                this.isProcessing = false;
            }
    submit() {
      console.log("submit方法被调用");
        }
    }
      // é˜²æ­¢é‡å¤æäº¤
      if (this.isSubmitting) {
        this.$showMessage("正在提交中,请勿重复操作");
        return;
      }
      // æ ¡éªŒç”¨æˆ·ç™»å½•状态
      if (!this.$loginInfo.account) {
        this.$showMessage("用户未登录,请重新登录");
        return;
      }
      // æ ¡éªŒæ¡ç æ•°é‡æ˜¯å¦æœ‰æ•ˆ
      if (this.quantity <= 0) {
        this.$showMessage("条码数量必须大于0");
        return;
      }
      // æ ¡éªŒæ˜¯å¦æœ‰æ•°æ®
      if (this.tableData.length === 0) {
        this.$showMessage("请扫描条码");
        return;
      }
      let userName = this.$loginInfo.account;
      this.isSubmitting = true; // è®¾ç½®æäº¤çŠ¶æ€
      // å‘送请求
      this.$post({
        url: "/MesOqcItemsDetect02/ItemBarCodeSubmit",
        data: {
          itemBarCodeData: this.tableData,
          CreateUser: userName
        }
      }).then(response => {
        if (response.status == 0) {
          // è¯·æ±‚成功后显示选择框
          uni.showModal({
            title: "操作成功",
            content: "已经成功生成检验单",
            showCancel: true,
            cancelText: "继续扫码",
            confirmText: "跳转到检验单",
            success: (res) => {
              if (res.confirm) {
                // ç”¨æˆ·ç‚¹å‡»äº†"跳转到检验单"
                uni.navigateTo({
                  url: '/pages/QC/OQC/Add?id=' + response.data
                });
              } else if (res.cancel) {
                // ç”¨æˆ·ç‚¹å‡»äº†"继续扫码"
                this.clearData();
              }
            }
          });
        } else {
          this.$showMessage(response.message);
        }
      }).catch(error => {
        // è¯·æ±‚失败时的处理
        this.$showMessage("请求失败,请稍后重试");
      }).finally(() => {
        // æ— è®ºæˆåŠŸè¿˜æ˜¯å¤±è´¥éƒ½é‡ç½®æäº¤çŠ¶æ€
        this.isSubmitting = false;
      });
    },
    // æ¸…空表格和表单数据
    clearData() {
      this.tableData = [];
      this.formData = {};
      this.quantity = 0;
      this.isSubmitting = false;
      this.isProcessing = false;
    }
  }
}
</script>
<style>
    .container {
      padding: 24rpx;
      background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
      min-height: 100vh;
      display: flex;
      flex-direction: column;
    }
    /* å¡ç‰‡é€šç”¨æ ·å¼ */
    .card {
      background: #ffffff;
      border-radius: 12rpx;
      box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
      margin-bottom: 24rpx;
      padding: 32rpx;
      border: 1rpx solid #e9ecef;
    }
    /* è¡¨å•区域 */
    .form-container {
      .form-grid {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 24rpx 16rpx;
      }
      .form-group {
        display: flex;
        flex-direction: column;
        gap: 16rpx;
        .form-label {
          font-size: 28rpx;
          color: #495057;
          font-weight: 600;
          padding-left: 4rpx;
          position: relative;
          &::after {
            content: "";
            position: absolute;
            left: 0;
            bottom: -4rpx;
            width: 24rpx;
            height: 3rpx;
            background: #007bff;
            border-radius: 2rpx;
          }
        }
        .form-input {
          height: 92rpx;
          padding: 0 24rpx;
          border: 2rpx solid #dee2e6;
          border-radius: 8rpx;
          font-size: 28rpx;
          color: #212529;
          background: #ffffff;
          transition: all 0.3s ease;
          &[disabled] {
            background: #f8f9fa;
            color: #6c757d;
            border-color: #e9ecef;
          }
          &:focus {
            border-color: #007bff;
            box-shadow: 0 0 0 4rpx rgba(0, 123, 255, 0.1);
            outline: none;
          }
          &::placeholder {
            color: #adb5bd;
          }
        }
      }
    }
    /* è¡¨æ ¼ä¼˜åŒ– */
    .table-container {
      .table-header {
        margin-bottom: 24rpx;
        padding-bottom: 16rpx;
        border-bottom: 2rpx solid #e9ecef;
        display: flex;
        justify-content: space-between;
        align-items: center;
        .section-title {
          font-size: 32rpx;
          color: #212529;
          font-weight: 700;
          position: relative;
          padding-left: 24rpx;
          &::before {
            content: "";
            position: absolute;
            left: 0;
            top: 50%;
            transform: translateY(-50%);
            width: 4rpx;
            height: 28rpx;
            background: linear-gradient(135deg, #007bff, #0056b3);
            border-radius: 2rpx;
          }
        }
        .table-tip {
          .tip-text {
            font-size: 22rpx;
            color: #6c757d;
            background: #f8f9fa;
            padding: 8rpx 16rpx;
            border-radius: 16rpx;
            border: 1rpx solid #e9ecef;
          }
        }
      }
      .table-wrapper {
        position: relative;
        border-radius: 8rpx;
        overflow: hidden;
        border: 1rpx solid #dee2e6;
      }
      .table-scroll {
        width: calc(100% - 80rpx); /* å‡åŽ»å›ºå®šåˆ—å®½åº¦ */
        white-space: nowrap;
      }
      .custom-table {
        border: none;
        min-width: 780rpx;
        .table-header-row {
          background: linear-gradient(135deg, #f8f9fa, #e9ecef);
          .th {
            font-size: 26rpx;
            color: #495057;
            font-weight: 600;
            padding: 20rpx 12rpx;
            background: transparent !important;
            border-right: 1rpx solid #dee2e6;
            white-space: nowrap;
            min-width: 80rpx;
            &:last-child {
              border-right: none;
            }
          }
        }
        .table-row {
          transition: background-color 0.2s ease;
          &:nth-child(even) {
            background: #f8f9fa;
          }
          &:hover {
            background: #e3f2fd;
          }
          .uni-td {
            padding: 16rpx 12rpx;
            border-color: #dee2e6 !important;
            border-right: 1rpx solid #dee2e6;
            white-space: nowrap;
            min-width: 80rpx;
            &:last-child {
              border-right: none;
            }
            .cell-content {
              font-size: 24rpx;
              color: #495057;
              line-height: 1.4;
              max-width: 100%;
              overflow: hidden;
              text-overflow: ellipsis;
              &.quantity {
                font-weight: 600;
                color: #007bff;
                background: linear-gradient(135deg, #e3f2fd, #bbdefb);
                padding: 8rpx 16rpx;
                border-radius: 12rpx;
                display: inline-block;
                min-width: 60rpx;
                text-align: center;
              }
            }
            .description-text {
              font-size: 24rpx;
              color: #6c757d;
              font-weight: 500;
            }
          }
        }
      }
      /* å³å›ºå®šæ‚¬æµ®åˆ é™¤åˆ— */
      .fixed-delete-column {
        position: absolute;
        top: 0;
        right: 0;
        width: 80rpx;
        background: #ffffff;
        border-left: 1rpx solid #dee2e6;
        box-shadow: -4rpx 0 8rpx rgba(0, 0, 0, 0.05);
        z-index: 10;
        .fixed-header {
          height: 60rpx;
          background: linear-gradient(135deg, #f8f9fa, #e9ecef);
          display: flex;
          align-items: center;
          justify-content: center;
          border-bottom: 1rpx solid #dee2e6;
          .fixed-header-text {
            font-size: 26rpx;
            color: #495057;
            font-weight: 600;
          }
        }
        .fixed-content {
          .fixed-delete-item {
            height: 48rpx;
            display: flex;
            align-items: center;
            justify-content: center;
            border-bottom: 1rpx solid #dee2e6;
            transition: background-color 0.2s ease;
            &.even {
              background: #f8f9fa;
            }
            &:hover {
              background: #e3f2fd;
            }
            &:last-child {
              border-bottom: none;
            }
          }
        }
      }
    }
    /* åˆ é™¤å›¾æ ‡ä¼˜åŒ– */
    .delete-icon {
      cursor: pointer;
      color: #dc3545;
      transition: all 0.3s ease;
      padding: 12rpx;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      min-width: 48rpx;
      min-height: 48rpx;
      &:hover {
        color: #c82333;
        background: rgba(220, 53, 69, 0.1);
        transform: scale(1.1);
      }
      &:active {
        transform: scale(0.95);
        background: rgba(220, 53, 69, 0.2);
      }
    }
    /* æŒ‰é’®ä¼˜åŒ– */
    .action-buttons-container {
      display: flex;
      justify-content: center;
      margin-top: 48rpx;
      padding: 0 24rpx;
      .plus-button {
        width: 100%;
        max-width: 600rpx;
        height: 96rpx;
        background: linear-gradient(135deg, #007bff, #0056b3);
        border-radius: 48rpx;
        display: flex;
        justify-content: center;
        align-items: center;
        color: #ffffff;
        font-size: 32rpx;
        font-weight: 600;
        box-shadow: 0 8rpx 24rpx rgba(0, 123, 255, 0.3);
        transition: all 0.3s ease;
        border: none;
        position: relative;
        overflow: hidden;
        &::before {
          content: "";
          position: absolute;
          top: 0;
          left: -100%;
          width: 100%;
          height: 100%;
          background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
          transition: left 0.5s ease;
        }
        &:active {
          transform: scale(0.98);
          box-shadow: 0 4rpx 12rpx rgba(0, 123, 255, 0.4);
          &::before {
            left: 100%;
          }
        }
        &.submitting {
          background: linear-gradient(135deg, #6c757d, #5a6268);
          cursor: not-allowed;
          &::before {
            display: none;
          }
        }
      }
    }
    /* æ•°é‡æ˜¾ç¤ºä¼˜åŒ– */
    .form-group {
      &:nth-child(5) .form-input {
        font-weight: 600;
        color: #007bff;
        background: linear-gradient(135deg, #e3f2fd, #bbdefb);
        border: 2rpx solid #007bff;
        text-align: center;
      }
    }
.container {
  padding: 24rpx;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
    /* æ‰«ç è¾“入框样式 */
    .input-with-scan {
      display: flex;
      align-items: center;
      gap: 16rpx;
      .scan-input {
        flex: 1;
      }
      .scan-button {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: 16rpx 20rpx;
        background: linear-gradient(135deg, #e3f2fd, #bbdefb);
        border: 2rpx solid #007bff;
        border-radius: 8rpx;
        min-width: 120rpx;
        height: 92rpx;
        cursor: pointer;
        transition: all 0.3s ease;
        &:hover {
          background: linear-gradient(135deg, #bbdefb, #90caf9);
          transform: translateY(-2rpx);
          box-shadow: 0 4rpx 12rpx rgba(0, 123, 255, 0.2);
        }
        &:active {
          transform: translateY(0);
          box-shadow: 0 2rpx 6rpx rgba(0, 123, 255, 0.3);
        }
        .scan-text {
          font-size: 22rpx;
          color: #007bff;
          font-weight: 600;
          margin-top: 4rpx;
        }
      }
    }
/* å¡ç‰‡é€šç”¨æ ·å¼ */
.card {
  background: #ffffff;
  border-radius: 12rpx;
  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
  margin-bottom: 24rpx;
  padding: 32rpx;
  border: 1rpx solid #e9ecef;
}
/* è¡¨å•区域 */
.form-container {
  .form-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 24rpx;
  }
  .form-group {
    display: flex;
    flex-direction: column;
    gap: 16rpx;
    .form-label {
      font-size: 28rpx;
      color: #495057;
      font-weight: 600;
      padding-left: 4rpx;
      position: relative;
      &::after {
        content: "";
        position: absolute;
        left: 0;
        bottom: -4rpx;
        width: 24rpx;
        height: 3rpx;
        background: #007bff;
        border-radius: 2rpx;
      }
    }
    .form-input {
      height: 92rpx;
      padding: 0 24rpx;
      border: 2rpx solid #dee2e6;
      border-radius: 8rpx;
      font-size: 28rpx;
      color: #212529;
      background: #ffffff;
      transition: all 0.3s ease;
      &[disabled] {
        background: #f8f9fa;
        color: #6c757d;
        border-color: #e9ecef;
      }
      &:focus {
        border-color: #007bff;
        box-shadow: 0 0 0 4rpx rgba(0, 123, 255, 0.1);
        outline: none;
      }
      &::placeholder {
        color: #adb5bd;
      }
    }
  }
}
/* è¡¨æ ¼ä¼˜åŒ– */
.table-container {
  .table-header {
    margin-bottom: 24rpx;
    padding-bottom: 16rpx;
    border-bottom: 2rpx solid #e9ecef;
    display: flex;
    justify-content: space-between;
    align-items: center;
    .section-title {
      font-size: 32rpx;
      color: #212529;
      font-weight: 700;
      position: relative;
      padding-left: 24rpx;
      &::before {
        content: "";
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
        width: 4rpx;
        height: 28rpx;
        background: linear-gradient(135deg, #007bff, #0056b3);
        border-radius: 2rpx;
      }
    }
    .table-tip {
      .tip-text {
        font-size: 22rpx;
        color: #6c757d;
        background: #f8f9fa;
        padding: 8rpx 16rpx;
        border-radius: 16rpx;
        border: 1rpx solid #e9ecef;
      }
    }
  }
  .table-wrapper {
    position: relative;
    border-radius: 8rpx;
    overflow: hidden;
    border: 1rpx solid #dee2e6;
    display: flex;
  }
  .table-scroll {
    flex: 1;
    overflow-x: auto;
    white-space: nowrap;
  }
  .custom-table {
    border: none;
    min-width: 780rpx;
    .table-header-row {
      background: linear-gradient(135deg, #f8f9fa, #e9ecef);
      .th {
        font-size: 26rpx;
        color: #495057;
        font-weight: 600;
        padding: 0 8rpx;
        height: 68rpx;
        line-height: 68rpx;
        background: transparent !important;
        border-right: 1rpx solid #dee2e6;
        white-space: nowrap;
        min-width: 80rpx;
        &:last-child {
          border-right: none;
        }
      }
    }
    .table-row {
      transition: background-color 0.2s ease;
      &:nth-child(even) {
        background: #f8f9fa;
      }
      &:hover {
        background: #e3f2fd;
      }
      .uni-td {
        padding: 0 8rpx;
        height: 68rpx;
        border-color: #dee2e6 !important;
        border-right: 1rpx solid #dee2e6;
        white-space: nowrap;
        min-width: 80rpx;
        vertical-align: middle;
        &:last-child {
          border-right: none;
        }
        .cell-content {
          font-size: 24rpx;
          color: #495057;
          line-height: 68rpx;
          max-width: 100%;
          overflow: hidden;
          text-overflow: ellipsis;
          display: flex;
          align-items: center;
          height: 68rpx;
          &.quantity {
            font-weight: 600;
            color: #007bff;
            background: linear-gradient(135deg, #e3f2fd, #bbdefb);
            padding: 8rpx 16rpx;
            border-radius: 12rpx;
            display: inline-block;
            min-width: 60rpx;
            text-align: center;
          }
        }
        .description-text {
          font-size: 24rpx;
          color: #6c757d;
          font-weight: 500;
          line-height: 68rpx;
          display: flex;
          align-items: center;
          height: 68rpx;
        }
      }
    }
  }
  /* å³å›ºå®šæ‚¬æµ®åˆ é™¤åˆ— */
  .fixed-delete-column {
    flex-shrink: 0;
    width: 100rpx;
    background: #ffffff;
    border-left: 1rpx solid #dee2e6;
    box-shadow: -4rpx 0 8rpx rgba(0, 0, 0, 0.05);
    .fixed-header {
      height: 68rpx;
      background: linear-gradient(135deg, #f8f9fa, #e9ecef);
      display: flex;
      align-items: center;
      justify-content: center;
      border-bottom: 1rpx solid #dee2e6;
      .fixed-header-text {
        font-size: 26rpx;
        color: #495057;
        font-weight: 600;
      }
    }
    .fixed-content {
      .fixed-delete-item {
        height: 68rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        border-bottom: 1rpx solid #dee2e6;
        transition: background-color 0.2s ease;
        &.even {
          background: #f8f9fa;
        }
        &:hover {
          background: #e3f2fd;
        }
        &:last-child {
          border-bottom: none;
        }
      }
    }
  }
}
/* åˆ é™¤å›¾æ ‡ä¼˜åŒ– */
.delete-icon {
  cursor: pointer;
  color: #dc3545;
  transition: all 0.3s ease;
  padding: 12rpx;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 48rpx;
  min-height: 48rpx;
  &:hover {
    color: #c82333;
    background: rgba(220, 53, 69, 0.1);
    transform: scale(1.1);
  }
  &:active {
    transform: scale(0.95);
    background: rgba(220, 53, 69, 0.2);
  }
}
/* æŒ‰é’®ä¼˜åŒ– */
.action-buttons-container {
  display: flex;
  justify-content: center;
  margin-top: 48rpx;
  padding: 0 24rpx;
  .plus-button {
    width: 100%;
    max-width: 600rpx;
    height: 96rpx;
    background: linear-gradient(135deg, #007bff, #0056b3);
    border-radius: 12rpx;
    border: 2rpx solid #007bff;
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #ffffff;
    font-size: 32rpx;
    font-weight: 600;
    box-shadow: 0 8rpx 24rpx rgba(0, 123, 255, 0.3);
    transition: all 0.3s ease;
    position: relative;
    overflow: hidden;
    text-align: center;
    /* ç¡®ä¿æŒ‰é’®å¯ç‚¹å‡» */
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: none;
    user-select: none;
    text {
      color: #ffffff;
      font-size: 32rpx;
      font-weight: 600;
      line-height: 1;
    }
    &::before {
      content: "";
      position: absolute;
      top: 0;
      left: -100%;
      width: 100%;
      height: 100%;
      background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
      transition: left 0.5s ease;
    }
    &:active {
      transform: scale(0.98);
      box-shadow: 0 4rpx 12rpx rgba(0, 123, 255, 0.4);
      &::before {
        left: 100%;
      }
    }
    &.submitting {
      background: linear-gradient(135deg, #6c757d, #5a6268);
      cursor: not-allowed;
      &::before {
        display: none;
      }
    }
    /* æ‚¬åœæ•ˆæžœ */
    &:hover:not(.submitting) {
      background: linear-gradient(135deg, #0056b3, #004085);
      border-color: #0056b3;
      box-shadow: 0 12rpx 32rpx rgba(0, 123, 255, 0.4);
      transform: translateY(-2rpx);
    }
  }
}
/* æ•°é‡æ˜¾ç¤ºä¼˜åŒ– */
.form-group {
  &:nth-child(5) .form-input {
    font-weight: 600;
    color: #007bff;
    background: linear-gradient(135deg, #e3f2fd, #bbdefb);
    border: 2rpx solid #007bff;
    text-align: center;
  }
}
/* æ‰«ç è¾“入框样式 */
.input-with-scan {
  display: flex;
  align-items: center;
  gap: 16rpx;
  .scan-input {
    flex: 1;
  }
  .scan-button {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 16rpx 20rpx;
    background: linear-gradient(135deg, #e3f2fd, #bbdefb);
    border: 2rpx solid #007bff;
    border-radius: 8rpx;
    min-width: 120rpx;
    height: 92rpx;
    cursor: pointer;
    transition: all 0.3s ease;
    &:hover {
      background: linear-gradient(135deg, #bbdefb, #90caf9);
      transform: translateY(-2rpx);
      box-shadow: 0 4rpx 12rpx rgba(0, 123, 255, 0.2);
    }
    &:active {
      transform: translateY(0);
      box-shadow: 0 2rpx 6rpx rgba(0, 123, 255, 0.3);
    }
    .scan-text {
      font-size: 22rpx;
      color: #007bff;
      font-weight: 600;
      margin-top: 4rpx;
    }
  }
}
/* æ‰‹æœºç«¯å“åº”式优化 */
@media (max-width: 768px) {
  .container {
    padding: 16rpx;
  }
  .card {
    padding: 24rpx;
    margin-bottom: 16rpx;
  }
  .form-container .form-grid {
    grid-template-columns: 1fr;
    gap: 20rpx;
  }
  .form-group .form-label {
    font-size: 26rpx;
  }
  .form-group .form-input {
    height: 84rpx;
    font-size: 26rpx;
    padding: 0 20rpx;
  }
  .scan-button {
    min-width: 100rpx !important;
    height: 84rpx !important;
    padding: 12rpx 16rpx !important;
    .scan-text {
      font-size: 20rpx !important;
    }
  }
  .table-scroll {
    flex: 1;
  }
  .fixed-delete-column {
    width: 80rpx;
    flex-shrink: 0;
    .fixed-header {
      height: 60rpx;
      .fixed-header-text {
        font-size: 22rpx;
      }
    }
    .fixed-content .fixed-delete-item {
      height: 60rpx;
    }
  }
  .custom-table {
    .th {
      font-size: 22rpx;
      padding: 0 6rpx;
      height: 60rpx;
      line-height: 60rpx;
    }
    .uni-td {
      padding: 0 6rpx;
      height: 60rpx;
      .cell-content {
        font-size: 22rpx;
        line-height: 60rpx;
        height: 60rpx;
      }
      .description-text {
        line-height: 60rpx;
        height: 60rpx;
      }
    }
  }
  .delete-icon {
    padding: 8rpx;
    min-width: 40rpx;
    min-height: 40rpx;
  }
  .plus-button {
    height: 88rpx;
    font-size: 30rpx;
    border-radius: 8rpx;
    text {
      font-size: 30rpx;
      color: #ffffff;
    }
    &.submitting text {
      color: #ffffff;
    }
  }
}
/* å¼ºåˆ¶æŒ‰é’®æ ·å¼ - è§£å†³æ‰‹æœºç«¯æ˜¾ç¤ºé—®é¢˜ */
.plus-button {
  background: #007bff !important;
  background: linear-gradient(135deg, #007bff, #0056b3) !important;
  border: 2rpx solid #007bff !important;
  border-radius: 12rpx !important;
  color: #ffffff !important;
  font-size: 32rpx !important;
  font-weight: 600 !important;
  box-shadow: 0 8rpx 24rpx rgba(0, 123, 255, 0.3) !important;
  width: 100% !important;
  max-width: 600rpx !important;
  height: 96rpx !important;
  display: flex !important;
  justify-content: center !important;
  align-items: center !important;
  text-align: center !important;
}
.plus-button text {
  color: #ffffff !important;
  font-size: 32rpx !important;
  font-weight: 600 !important;
}
.plus-button.submitting {
  background: #6c757d !important;
  background: linear-gradient(135deg, #6c757d, #5a6268) !important;
  border-color: #6c757d !important;
}
.plus-button.submitting text {
  color: #ffffff !important;
}
/* æ‰‹æœºç«¯æŒ‰é’®å¼ºåˆ¶æ ·å¼ */
@media (max-width: 768px) {
  .plus-button {
    background: #007bff !important;
    background: linear-gradient(135deg, #007bff, #0056b3) !important;
    border: 2rpx solid #007bff !important;
    border-radius: 8rpx !important;
    height: 88rpx !important;
    font-size: 30rpx !important;
  }
  .plus-button text {
    color: #ffffff !important;
    font-size: 30rpx !important;
    font-weight: 600 !important;
  }
  .plus-button.submitting text {
    color: #ffffff !important;
    font-size: 30rpx !important;
  }
}
</style>
pages/QC/OQC/detail.vue
@@ -1,828 +1,935 @@
<template>
    <view class="page-container">
        <!-- æ£€éªŒé¡¹ç›®è¡¨å•卡片 -->
        <view class="form-card">
            <view class="form-title">
                <view class="title-icon">📋</view>
                <span>检验项目详情</span>
            </view>
            <view class="form-container">
                <!-- åŸºæœ¬ä¿¡æ¯æ¨¡å— -->
                <view class="form-section">
                    <view class="section-title">基本信息</view>
                    <view class="form-grid">
                        <view class="form-group">
                            <label class="form-label">项目名称:</label>
                            <input class="form-input" disabled="true" type="text" v-model="formData.fcheckItem" />
                        </view>
                        <view class="form-group">
                            <label class="form-label">规格要求:</label>
                            <input class="form-input" disabled="true" type="text" v-model="formData.fspecRequ" />
                        </view>
                        <view class="form-group">
                            <label class="form-label">检验方法:</label>
                            <input class="form-input" disabled="true" type="text" v-model="formData.inspectionMethod" />
                        </view>
                        <view class="form-group">
                            <label class="form-label">检验工具:</label>
                            <input class="form-input" disabled="true" type="text" v-model="formData.fcheckTool" />
                        </view>
                    </view>
                </view>
  <view class="page-container">
    <!-- æ£€éªŒé¡¹ç›®è¡¨å•卡片 -->
    <view class="form-card">
      <view class="form-title">
        <view class="title-icon">📋</view>
        <span>检验项目详情</span>
      </view>
      <view class="form-container">
        <!-- åŸºæœ¬ä¿¡æ¯æ¨¡å— -->
        <view class="form-section">
          <view class="section-title">基本信息</view>
          <view class="form-grid">
            <view class="form-group">
              <label class="form-label">项目名称:</label>
              <input v-model="formData.fcheckItem" class="form-input" disabled="true" type="text"/>
            </view>
            <view class="form-group">
              <label class="form-label">规格要求:</label>
              <input v-model="formData.fspecRequ" class="form-input" disabled="true" type="text"/>
            </view>
            <view class="form-group">
              <label class="form-label">检验方法:</label>
              <input v-model="formData.inspectionMethod" class="form-input" disabled="true" type="text"/>
            </view>
            <view class="form-group">
              <label class="form-label">检验工具:</label>
              <input v-model="formData.fcheckTool" class="form-input" disabled="true" type="text"/>
            </view>
          </view>
        </view>
                <!-- ä¸‰ä¸ªæ¨¡å—并列容器 -->
                <view class="three-modules-container">
                    <!-- æ£€éªŒå‚数模块 -->
                    <view class="module-item">
                        <view class="module-header">
                            <text class="module-title">检验参数</text>
                        </view>
                        <view class="module-content">
                            <view class="form-grid">
                                <view class="form-group">
                                    <label class="form-label">检验数:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.checkQyt" />
                                </view>
                                <view class="form-group">
                                    <label class="form-label">检验标准编码:</label>
                                    <input class="form-input" disabled="true" type="text"
                                        v-model="formData.sampleSizeNo" />
                                </view>
                                <view class="form-group">
                                    <label class="form-label">检验水平:</label>
                                    <input class="form-input" disabled="true" type="text"
                                        v-model="formData.fcheckLevel" />
                                </view>
                                <view class="form-group">
                                    <label class="form-label">接收水平:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.facLevel" />
                                </view>
                            </view>
                        </view>
                    </view>
        <!-- ä¸‰ä¸ªæ¨¡å—并列容器 -->
        <view class="three-modules-container">
          <!-- æ£€éªŒå‚数模块 -->
          <view class="module-item">
            <view class="module-header">
              <text class="module-title">检验参数</text>
            </view>
            <view class="module-content">
              <view class="form-grid">
                <view class="form-group">
                  <label class="form-label">检验数:</label>
                  <input v-model="formData.checkQyt" class="form-input" disabled="true" type="text"/>
                </view>
                <view class="form-group">
                  <label class="form-label">检验标准编码:</label>
                  <input v-model="formData.sampleSizeNo" class="form-input" disabled="true"
                         type="text"/>
                </view>
                <view class="form-group">
                  <label class="form-label">检验水平:</label>
                  <input v-model="formData.fcheckLevel" class="form-input" disabled="true"
                         type="text"/>
                </view>
                <view class="form-group">
                  <label class="form-label">接收水平:</label>
                  <input v-model="formData.facLevel" class="form-input" disabled="true" type="text"/>
                </view>
              </view>
            </view>
          </view>
                    <!-- æ•°å€¼æ ‡å‡†æ¨¡å— -->
                    <view class="module-item">
                        <view class="module-header">
                            <text class="module-title">数值标准</text>
                        </view>
                        <view class="module-content">
                            <view class="form-grid">
                                <view class="form-group">
                                    <label class="form-label">下限:</label>
                                    <input class="form-input" disabled="true" type="text"
                                        v-model="formData.fdownAllow" />
                                </view>
                                <view class="form-group">
                                    <label class="form-label">标准值:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.fstand" />
                                </view>
                                <view class="form-group">
                                    <label class="form-label">上限:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.fupAllow" />
                                </view>
                            </view>
                        </view>
                    </view>
          <!-- æ•°å€¼æ ‡å‡†æ¨¡å— -->
          <view class="module-item">
            <view class="module-header">
              <text class="module-title">数值标准</text>
            </view>
            <view class="module-content">
              <view class="form-grid">
                <view class="form-group">
                  <label class="form-label">下限:</label>
                  <input v-model="formData.fdownAllow" class="form-input" disabled="true"
                         type="text"/>
                </view>
                <view class="form-group">
                  <label class="form-label">标准值:</label>
                  <input v-model="formData.fstand" class="form-input" disabled="true" type="text"/>
                </view>
                <view class="form-group">
                  <label class="form-label">上限:</label>
                  <input v-model="formData.fupAllow" class="form-input" disabled="true" type="text"/>
                </view>
              </view>
            </view>
          </view>
                    <!-- åˆ¤å®šæ ‡å‡†æ¨¡å— -->
                    <view class="module-item">
                        <view class="module-header">
                            <text class="module-title">判定标准</text>
                        </view>
                        <view class="module-content">
                            <view class="form-grid">
                                <view class="form-group">
                                    <label class="form-label">AC数:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.facQty" />
                                </view>
                                <view class="form-group">
                                    <label class="form-label">RE数:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.freQty" />
                                </view>
                                <view class="form-group">
                                    <label class="form-label">不合格数:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.fngQty" />
                                </view>
                                <view class="form-group">
                                    <label class="form-label">预览结果:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.fcheckResu" />
                                </view>
                            </view>
                        </view>
                    </view>
                </view>
          <!-- åˆ¤å®šæ ‡å‡†æ¨¡å— -->
          <view class="module-item">
            <view class="module-header">
              <text class="module-title">判定标准</text>
            </view>
            <view class="module-content">
              <view class="form-grid">
                <view class="form-group">
                  <label class="form-label">AC数:</label>
                  <input v-model="formData.facQty" class="form-input" disabled="true" type="text"/>
                </view>
                <view class="form-group">
                  <label class="form-label">RE数:</label>
                  <input v-model="formData.freQty" class="form-input" disabled="true" type="text"/>
                </view>
                <view class="form-group">
                  <label class="form-label">不合格数:</label>
                  <input v-model="formData.fngQty" class="form-input" disabled="true" type="text"/>
                </view>
                <view class="form-group">
                  <label class="form-label">预览结果:</label>
                  <input v-model="formData.fcheckResu" class="form-input" disabled="true" type="text"/>
                </view>
              </view>
            </view>
          </view>
        </view>
                <!-- å¤‡æ³¨ä¿¡æ¯æ¨¡å— -->
                <!-- <view class="form-section">
                    <view class="section-title">备注信息</view>
                    <view class="form-grid">
                        <view class="form-group">
                            <label class="form-label">不合格描述:</label>
                            <input class="form-input" disabled="true" type="text" v-model="formData.remarks" />
                        </view>
                    </view>
                </view> -->
        <!-- å¤‡æ³¨ä¿¡æ¯æ¨¡å— -->
        <!-- <view class="form-section">
          <view class="section-title">备注信息</view>
          <view class="form-grid">
            <view class="form-group">
              <label class="form-label">不合格描述:</label>
              <input class="form-input" disabled="true" type="text" v-model="formData.remarks" />
            </view>
          </view>
        </view> -->
                <!-- æ£€æµ‹ç»“果区域 -->
                <view class="form-section">
                    <view class="section-title">检测结果</view>
                    <view class="form-grid">
                        <view class="form-group">
                            <label class="form-label">检测结果:</label>
                            <input class="form-input" type="number" v-model="fcheckResuK" />
                        </view>
        <!-- æ£€æµ‹ç»“果区域 -->
        <view class="form-section">
          <view class="section-title">检测结果</view>
          <view class="form-grid">
            <view class="form-group">
              <label class="form-label">检测结果:</label>
              <input v-model="fcheckResuK" class="form-input" type="number"/>
            </view>
                        <!-- æç¤ºè¯ä½œä¸ºæ£€æµ‹ç»“果的提示 -->
                        <view class="form-group tip-group">
                            <view class="tip-box">
                                <view class="tip-icon">⚠️</view>
                                <view class="tip-text">没有最大值和最小值时填写<span class="highlight">0(未通过检验)</span>或<span
                                        class="highlight">1(通过检验)</span></view>
                            </view>
                        </view>
                    </view>
                </view>
            <!-- æç¤ºè¯ä½œä¸ºæ£€æµ‹ç»“果的提示 -->
            <view class="form-group tip-group">
              <view class="tip-box">
                <view class="tip-icon">⚠️</view>
                <view class="tip-text">没有最大值和最小值时填写<span class="highlight">0(未通过检验)</span>或<span
                    class="highlight">1(通过检验)</span></view>
              </view>
            </view>
          </view>
        </view>
                <button :class="['action-btn', 'btn-primary', { 'btn-loading': isLoading }]"
                    v-if="tableData.length < formData.checkQyt" @click="submit" :disabled="isLoading">
                    {{ isLoading ? '保存中...' : '保存' }}
                </button>
            </view>
        </view>
        <button v-if="tableData.length < formData.checkQyt"
                :class="['action-btn', 'btn-primary', { 'btn-loading': isLoading }]" :disabled="isLoading" @click="submit">
          {{ isLoading ? '保存中...' : '保存' }}
        </button>
      </view>
    </view>
        <!-- æ£€éªŒç»“果表格卡片 -->
        <view class="table-card">
            <view class="table-title">
                <view class="title-icon">📊</view>
                <span>检验结果列表</span>
            </view>
            <view class="list-container">
                <uni-table ref="table" border emptyText="暂无更多数据">
                    <uni-tr>
                        <uni-th width="80" align="center" class="th">编号</uni-th>
                        <uni-th width="120" align="center" class="th">判定标识</uni-th>
                        <uni-th width="100" align="center" class="th">检验结果</uni-th>
                        <uni-th width="120" align="center" class="th">操作</uni-th>
                    </uni-tr>
                    <uni-tr v-for="(item, index) in tableData" :key="index" class="table-row"
                        :class="{ 'hover-effect': isHoveringRow === index }" @mouseenter="isHoveringRow = index"
                        @mouseleave="isHoveringRow = -1">
                        <uni-td align="center">
                            {{ index + 1 }}
                        </uni-td>
                        <uni-td align="center">
                            <input class="form-input" disabled="true" type="text" v-model="item.fstand" />
                        </uni-td>
                        <uni-td align="center">
                            <span class="result-badge"
                                :class="{ 'pass': item.fcheckResu === 'OK', 'fail': item.fcheckResu === 'NG' }">
    <!-- æ£€éªŒç»“果表格卡片 -->
    <view class="table-card">
      <view class="table-title">
        <view class="title-icon">📊</view>
        <span>检验结果列表</span>
      </view>
      <view class="list-container">
        <uni-table ref="table" border emptyText="暂无更多数据">
          <uni-tr>
            <uni-th align="center" class="th" width="80">编号</uni-th>
            <uni-th align="center" class="th" width="120">判定标识</uni-th>
            <uni-th align="center" class="th" width="100">检验结果</uni-th>
            <uni-th align="center" class="th" width="120">操作</uni-th>
          </uni-tr>
          <uni-tr v-for="(item, index) in tableData" :key="index" :class="{ 'hover-effect': isHoveringRow === index }"
                  class="table-row" @mouseenter="isHoveringRow = index"
                  @mouseleave="isHoveringRow = -1">
            <uni-td align="center">
              {{ index + 1 }}
            </uni-td>
            <uni-td align="center">
              <input v-model="item.fstand" class="form-input" disabled="true" type="text"/>
            </uni-td>
            <uni-td align="center">
                            <span :class="{ 'pass': item.fcheckResu === 'OK', 'fail': item.fcheckResu === 'NG' }"
                    class="result-badge">
                                {{ item.fcheckResu || '未检验' }}
                            </span>
                        </uni-td>
                        <uni-td align="center">
                            <view class="action-group">
                                <button :class="['action-btn', 'btn-sm', 'btn-warn', { 'btn-disabled': isLoading }]"
                                    v-if="isNumber" @click="toDetail(item)" :disabled="isLoading">
                                    {{ isLoading ? '处理中...' : '修改' }}
                                </button>
                                <button :class="['action-btn', 'btn-sm', 'btn-warn', { 'btn-disabled': isLoading }]"
                                    v-if="!isNumber" @click="numberEdit(item)" :disabled="isLoading">
                                    {{ isLoading ? '处理中...' : editResult(item.fcheckResu) }}
                                </button>
                            </view>
                        </uni-td>
                    </uni-tr>
                </uni-table>
            </view>
        </view>
            </uni-td>
            <uni-td align="center">
              <view class="action-group">
                <button v-if="isNumber"
                        :class="['action-btn', 'btn-sm', 'btn-warn', { 'btn-disabled': isLoading }]" :disabled="isLoading" @click="toDetail(item)">
                  {{ isLoading ? '处理中...' : '修改' }}
                </button>
                <button v-if="!isNumber"
                        :class="['action-btn', 'btn-sm', 'btn-warn', { 'btn-disabled': isLoading }]" :disabled="isLoading" @click="numberEdit(item)">
                  {{ isLoading ? '处理中...' : editResult(item.fcheckResu) }}
                </button>
              </view>
            </uni-td>
          </uni-tr>
        </uni-table>
      </view>
    </view>
        <!-- æ“ä½œæŒ‰é’® -->
        <view class="action-buttons">
            <view class="button-group">
                <button :class="['action-btn', 'btn-warn', { 'btn-disabled': isLoading }]" @click="saveRemarks"
                    :disabled="isLoading">
                    {{ isLoading ? '处理中...' : '添加不合格描述' }}
                </button>
            </view>
        </view>
    <!-- æ“ä½œæŒ‰é’® -->
    <view class="action-buttons">
      <view class="button-group">
        <button :class="['action-btn', 'btn-warn', { 'btn-disabled': isLoading }]" :disabled="isLoading"
                @click="saveRemarks">
          {{ isLoading ? '处理中...' : '添加不合格描述' }}
        </button>
      </view>
    </view>
        <!-- ä¿®æ”¹æ£€éªŒç»“果弹出层 -->
        <view v-if="showPopup" class="overlay active">
            <view class="popup" :class="{ 'popup-scale': isPopupAnimated }" @animationend="isPopupAnimated = false">
                <view class="popup-header">
                    <h3 class="popup-title">修改检验结果</h3>
                    <view class="close-btn" @click="showPopup = !showPopup">×</view>
                </view>
                <form :modelValue="editData">
                    <view class="form-group">
                        <label class="form-label">检验结果:</label>
                        <input class="form-input" type="text" v-model="editData.fcheckResu" />
                    </view>
                    <view class="button-group">
                        <button :class="['action-btn', 'btn-warn', { 'btn-loading': isEditLoading }]" @click="eidt"
                            :disabled="isEditLoading">
                            {{ isEditLoading ? '修改中...' : '修改' }}
                        </button>
                        <button @click="showPopup = !showPopup">
                            å–消
                        </button>
                    </view>
                </form>
            </view>
        </view>
    <!-- ä¿®æ”¹æ£€éªŒç»“果弹出层 -->
    <view v-if="showPopup" class="overlay active">
      <view :class="{ 'popup-scale': isPopupAnimated }" class="popup" @animationend="isPopupAnimated = false">
        <view class="popup-header">
          <h3 class="popup-title">修改检验结果</h3>
          <view class="close-btn" @click="showPopup = !showPopup">×</view>
        </view>
        <form :modelValue="editData">
          <view class="form-group">
            <label class="form-label">检验结果:</label>
            <input v-model="editData.fcheckResu" class="form-input" type="text"/>
          </view>
          <view class="button-group">
            <button :class="['action-btn', 'btn-warn', { 'btn-loading': isEditLoading }]" :disabled="isEditLoading"
                    @click="eidt">
              {{ isEditLoading ? '修改中...' : '修改' }}
            </button>
            <button @click="showPopup = !showPopup">
              å–消
            </button>
          </view>
        </form>
      </view>
    </view>
        <!-- ä¿®æ”¹ä¸åˆæ ¼æè¿°å¼¹å‡ºå±‚ -->
        <view v-if="remarksPopup" class="overlay active">
            <view class="popup" :class="{ 'popup-scale': isPopupAnimated }" @animationend="isPopupAnimated = false">
                <view class="popup-header">
                    <h3 class="popup-title">修改不合格描述</h3>
                    <view class="close-btn" @click="remarksPopup = !remarksPopup">×</view>
                </view>
                <form>
                    <view class="form-group">
                        <label class="form-label">不合格描述:</label>
                        <input class="form-input" type="text" v-model="remarks" />
                    </view>
                    <view class="button-group">
                        <button :class="['action-btn', 'btn-warn', { 'btn-loading': isRemarksLoading }]"
                            @click="editRemarks" :disabled="isRemarksLoading">
                            {{ isRemarksLoading ? '保存中...' : '修改' }}
                        </button>
                        <button @click="remarksPopup = !remarksPopup">
                            å–消
                        </button>
                    </view>
                </form>
            </view>
        </view>
    </view>
    <!-- ä¿®æ”¹ä¸åˆæ ¼æè¿°å¼¹å‡ºå±‚ -->
    <view v-if="remarksPopup" class="overlay active">
      <view :class="{ 'popup-scale': isPopupAnimated }" class="popup" @animationend="isPopupAnimated = false">
        <view class="popup-header">
          <h3 class="popup-title">修改不合格描述</h3>
          <view class="close-btn" @click="remarksPopup = !remarksPopup">×</view>
        </view>
        <form>
          <view class="form-group">
            <label class="form-label">不合格描述:</label>
            <input v-model="remarks" class="form-input" type="text"/>
          </view>
          <view class="button-group">
            <button :class="['action-btn', 'btn-warn', { 'btn-loading': isRemarksLoading }]"
                    :disabled="isRemarksLoading" @click="editRemarks">
              {{ isRemarksLoading ? '保存中...' : '修改' }}
            </button>
            <button @click="remarksPopup = !remarksPopup">
              å–消
            </button>
          </view>
        </form>
      </view>
    </view>
  </view>
</template>
<script>
    export default {
        data() {
            return {
                formData: {},
                releaseNo: "",
                isNumber: false,
                checkItem: "",
                id: 0,
                gid: 0,
                billNo: "",
                showPopup: false,
                editData: {},
                tableData: [],
                remarks: "",
                remarksPopup: false,
                fcheckResuK: "",
                isLoading: false,
                isEditLoading: false,
                isRemarksLoading: false,
                isHoveringRow: -1,
                isPopupAnimated: false
            };
        },
        methods: {
            editResult(fcheckResu) {
                if (fcheckResu == "OK") {
                    return "改为不合格";
                } else {
                    return "改为合格";
                }
            },
            submit() {
                this.isLoading = true;
                let count = this.formData.checkQyt;
                let fstand = "√";
                if (Number(this.formData.fupAllow) && Number(this.formData.fdownAllow)) {
                    if (!this.fcheckResuK) {
                        this.$showMessage("请输入检验值");
                        this.isLoading = false;
                        return;
                    }
                    if (
                        Number(this.fcheckResuK) >= Number(this.formData.fdownAllow) &&
                        Number(this.fcheckResuK) <= Number(this.formData.fupAllow)
                    ) {
                        fstand = "√";
                    } else {
                        fstand = "×";
                    }
                    count = 1;
                } else {
                    if (!this.fcheckResuK) {
                        this.formData.fcheckResu = 1;
                    }
                    if (this.fcheckResuK == 0 || this.fcheckResuK == 1) {
                        this.formData.isPass = this.fcheckResuK;
                    } else {
                        this.$showMessage("无标准值时,检验结果只能为0或1!");
                        this.isLoading = false;
                        return;
                    }
                    count = count - this.tableData.length;
                }
                this.formData.updater = this.$loginInfo.account;
                this.$post({
                    url: "/LLJ/SetQSItemDetail",
                    data: {
                        mainId: this.formData.id,
                        releaseNo: this.formData.releaseNo,
                        fstand: fstand,
                        fcheckResu: this.fcheckResuK,
                        LastupdateBy: this.$loginInfo.account,
                        count: count
                    }
                }).then((res) => {
                    this.formData.fcheckResu = null;
                    this.$showMessage("保存成功");
                    this.refreshResult();
                    this.isLoading = false;
                }).catch(() => {
                    this.$showMessage("保存失败,请重试");
                    this.isLoading = false;
                });
            },
            refreshResult() {
                this.isLoading = true;
                this.$post({
                    url: "/MesOqcItemsDetect02/getXjDetail02ById",
                    data: {
                        id: this.id
                    }
                }).then((res) => {
                    this.formData = res.data.tbBillList.itemXj01;
                    this.tableData = res.data.tbBillList.itemXj02s;
                    if (this.formData.fupAllow && this.formData.fdownAllow && this.formData.fstand) {
                        this.isNumber = true;
                    } else {
                        this.isNumber = false;
                    }
                    this.isLoading = false;
                }).catch(() => {
                    this.$showMessage("获取数据失败");
                    this.isLoading = false;
                });
            },
            toDetail(item) {
                this.showPopup = true;
                this.editData = {
                    ...item
                };
            },
            eidt() {
                this.isEditLoading = true;
                if (!this.editData.fcheckResu) {
                    this.$showMessage("请输入检验结果");
                    this.isEditLoading = false;
                    return;
                }
                if (this.formData.fcheckResu == this.editData.fcheckResu) {
                    this.$showMessage("修改成功");
                    this.showPopup = false;
                    this.isEditLoading = false;
                    return;
                }
                let fstand = "√";
                if (this.formData.fupAllow && this.formData.fdownAllow) {
                    if (!this.editData.fcheckResu) {
                        this.$showMessage("请输入检验值");
                        this.isEditLoading = false;
                        return;
                    }
                    if (
                        Number(this.editData.fcheckResu) >= Number(this.formData.fdownAllow) &&
                        Number(this.editData.fcheckResu) <= Number(this.formData.fupAllow)
                    ) {
                        this.editData.isPass = 1;
                        fstand = "√";
                    } else {
                        this.editData.isPass = 0;
                        fstand = "×";
                    }
                } else {
                    if (!this.editData.fcheckResu) {
                        this.editData.fcheckResu = 1;
                    }
                    if (this.editData.fcheckResu == 0 || this.editData.fcheckResu == 1) {
                        if (this.editData.fcheckResu == 0) {
                            fstand = "×";
                        }
                    } else {
                        this.$showMessage("无标准值时,检验结果只能为0或1!");
                        this.isEditLoading = false;
                        return;
                    }
                }
                this.editData.updater = this.$loginInfo.account;
                this.$post({
                    url: "/MesOqcItemsDetect02/UpdateQSItemDetail",
                    data: {
                        id: this.editData.id,
                        mainId: this.formData.id,
                        releaseNo: this.formData.releaseNo,
                        fstand: fstand,
                        fcheckResu: this.editData.fcheckResu,
                        lastupdateBy: this.$loginInfo.account
                    }
                }).then((res) => {
                    this.showPopup = false;
                    this.$showMessage("修改成功");
                    this.refreshResult();
                    this.isEditLoading = false;
                }).catch(() => {
                    this.$showMessage("修改失败,请重试");
                    this.isEditLoading = false;
                });
            },
            numberEdit(item) {
                this.isLoading = true;
                let fstand = "√";
                let fcheckResu = "OK";
                if (item.fcheckResu == "OK") {
                    fstand = "×";
                    fcheckResu = "NG";
                }
                this.$post({
                    url: "/MesOqcItemsDetect02/UpdateQSItemDetail",
                    data: {
                        id: item.id,
                        mainId: this.formData.id,
                        releaseNo: this.formData.releaseNo,
                        fstand: fstand,
                        fcheckResu: fcheckResu,
                        lastupdateBy: this.$loginInfo.account
                    }
                }).then((res) => {
                    this.$showMessage("修改成功");
                    this.refreshResult();
                    this.isLoading = false;
                }).catch(() => {
                    this.$showMessage("修改失败,请重试");
                    this.isLoading = false;
                });
            },
            saveRemarks() {
                this.remarksPopup = true;
                this.remarks = this.formData.remarks || "";
            },
            editRemarks() {
                this.isRemarksLoading = true;
                if (this.remarks) {
                    this.$post({
                        url: "/MesOqcItemsDetect02/saveRemarksPid",
                        data: {
                            pid: this.formData.id,
                            remarks: this.remarks
                        }
                    }).then((res) => {
                        if (res.data.tbBillList > 0) {
                            this.formData.remarks = this.remarks;
                            this.remarksPopup = false;
                            this.$showMessage("保存成功");
                        } else {
                            this.$showMessage("保存失败");
                        }
                        this.isRemarksLoading = false;
                    }).catch(() => {
                        this.$showMessage("保存失败,请重试");
                        this.isRemarksLoading = false;
                    });
                } else {
                    this.$showMessage("请输入不合格描述");
                    this.isRemarksLoading = false;
                }
            }
        },
        onLoad(options) {
            let params = options;
            this.id = params["mainId"];
            this.releaseNo = params["releaseNo"];
            this.refreshResult();
        }
    };
export default {
  data() {
    return {
      formData: {},
      releaseNo: "",
      isNumber: false,
      checkItem: "",
      id: 0,
      gid: 0,
      billNo: "",
      showPopup: false,
      editData: {},
      tableData: [],
      remarks: "",
      remarksPopup: false,
      fcheckResuK: "",
      isLoading: false,
      isEditLoading: false,
      isRemarksLoading: false,
      isHoveringRow: -1,
      isPopupAnimated: false
    };
  },
  methods: {
    editResult(fcheckResu) {
      if (fcheckResu == "OK") {
        return "改为不合格";
      } else {
        return "改为合格";
      }
    },
    submit() {
      this.isLoading = true;
      let count = this.formData.checkQyt;
      let fstand = "√";
      if (Number(this.formData.fupAllow) && Number(this.formData.fdownAllow)) {
        if (!this.fcheckResuK) {
          this.$showMessage("请输入检验值");
          this.isLoading = false;
          return;
        }
        if (
            Number(this.fcheckResuK) >= Number(this.formData.fdownAllow) &&
            Number(this.fcheckResuK) <= Number(this.formData.fupAllow)
        ) {
          fstand = "√";
        } else {
          fstand = "×";
        }
        count = 1;
      } else {
        if (!this.fcheckResuK) {
          this.formData.fcheckResu = 1;
        }
        if (this.fcheckResuK == 0 || this.fcheckResuK == 1) {
          this.formData.isPass = this.fcheckResuK;
        } else {
          this.$showMessage("无标准值时,检验结果只能为0或1!");
          this.isLoading = false;
          return;
        }
        count = count - this.tableData.length;
      }
      this.formData.updater = this.$loginInfo.account;
      this.$post({
        url: "/LLJ/SetQSItemDetail",
        data: {
          mainId: this.formData.id,
          releaseNo: this.formData.releaseNo,
          fstand: fstand,
          fcheckResu: this.fcheckResuK,
          LastupdateBy: this.$loginInfo.account,
          count: count
        }
      }).then((res) => {
        this.formData.fcheckResu = null;
        this.$showMessage("保存成功");
        this.refreshResult();
        this.isLoading = false;
      }).catch(() => {
        this.$showMessage("保存失败,请重试");
        this.isLoading = false;
      });
    },
    refreshResult() {
      this.isLoading = true;
      this.$post({
        url: "/MesOqcItemsDetect02/getXjDetail02ById",
        data: {
          id: this.id
        }
      }).then((res) => {
        this.formData = res.data.tbBillList.itemXj01;
        this.tableData = res.data.tbBillList.itemXj02s;
        if (this.formData.fupAllow && this.formData.fdownAllow && this.formData.fstand) {
          this.isNumber = true;
        } else {
          this.isNumber = false;
        }
        this.isLoading = false;
      }).catch(() => {
        this.$showMessage("获取数据失败");
        this.isLoading = false;
      });
    },
    toDetail(item) {
      this.showPopup = true;
      this.editData = {
        ...item
      };
    },
    eidt() {
      this.isEditLoading = true;
      if (!this.editData.fcheckResu) {
        this.$showMessage("请输入检验结果");
        this.isEditLoading = false;
        return;
      }
      if (this.formData.fcheckResu == this.editData.fcheckResu) {
        this.$showMessage("修改成功");
        this.showPopup = false;
        this.isEditLoading = false;
        return;
      }
      let fstand = "√";
      if (this.formData.fupAllow && this.formData.fdownAllow) {
        if (!this.editData.fcheckResu) {
          this.$showMessage("请输入检验值");
          this.isEditLoading = false;
          return;
        }
        if (
            Number(this.editData.fcheckResu) >= Number(this.formData.fdownAllow) &&
            Number(this.editData.fcheckResu) <= Number(this.formData.fupAllow)
        ) {
          this.editData.isPass = 1;
          fstand = "√";
        } else {
          this.editData.isPass = 0;
          fstand = "×";
        }
      } else {
        if (!this.editData.fcheckResu) {
          this.editData.fcheckResu = 1;
        }
        if (this.editData.fcheckResu == 0 || this.editData.fcheckResu == 1) {
          if (this.editData.fcheckResu == 0) {
            fstand = "×";
          }
        } else {
          this.$showMessage("无标准值时,检验结果只能为0或1!");
          this.isEditLoading = false;
          return;
        }
      }
      this.editData.updater = this.$loginInfo.account;
      this.$post({
        url: "/MesOqcItemsDetect02/UpdateQSItemDetail",
        data: {
          id: this.editData.id,
          mainId: this.formData.id,
          releaseNo: this.formData.releaseNo,
          fstand: fstand,
          fcheckResu: this.editData.fcheckResu,
          lastupdateBy: this.$loginInfo.account
        }
      }).then((res) => {
        this.showPopup = false;
        this.$showMessage("修改成功");
        this.refreshResult();
        this.isEditLoading = false;
      }).catch(() => {
        this.$showMessage("修改失败,请重试");
        this.isEditLoading = false;
      });
    },
    numberEdit(item) {
      this.isLoading = true;
      let fstand = "√";
      let fcheckResu = "OK";
      if (item.fcheckResu == "OK") {
        fstand = "×";
        fcheckResu = "NG";
      }
      this.$post({
        url: "/MesOqcItemsDetect02/UpdateQSItemDetail",
        data: {
          id: item.id,
          mainId: this.formData.id,
          releaseNo: this.formData.releaseNo,
          fstand: fstand,
          fcheckResu: fcheckResu,
          lastupdateBy: this.$loginInfo.account
        }
      }).then((res) => {
        this.$showMessage("修改成功");
        this.refreshResult();
        this.isLoading = false;
      }).catch(() => {
        this.$showMessage("修改失败,请重试");
        this.isLoading = false;
      });
    },
    saveRemarks() {
      this.remarksPopup = true;
      this.remarks = this.formData.remarks || "";
    },
    editRemarks() {
      this.isRemarksLoading = true;
      if (this.remarks) {
        this.$post({
          url: "/MesOqcItemsDetect02/saveRemarksPid",
          data: {
            pid: this.formData.id,
            remarks: this.remarks
          }
        }).then((res) => {
          if (res.data.tbBillList > 0) {
            this.formData.remarks = this.remarks;
            this.remarksPopup = false;
            this.$showMessage("保存成功");
          } else {
            this.$showMessage("保存失败");
          }
          this.isRemarksLoading = false;
        }).catch(() => {
          this.$showMessage("保存失败,请重试");
          this.isRemarksLoading = false;
        });
      } else {
        this.$showMessage("请输入不合格描述");
        this.isRemarksLoading = false;
      }
    }
  },
  onLoad(options) {
    let params = options;
    this.id = params["mainId"];
    this.releaseNo = params["releaseNo"];
    this.refreshResult();
  }
};
</script>
<style>
    /* é¡µé¢å®¹å™¨ */
    .page-container {
        padding: 20px;
        background-color: #f5f5f5;
        min-height: 100vh;
    }
/* é¡µé¢å®¹å™¨ */
.page-container {
  padding: 20px;
  background-color: #f5f5f5;
  min-height: 100vh;
}
    /* è¡¨å•卡片 */
    .form-card {
        background-color: #fff;
        border-radius: 12px;
        padding: 20px;
        margin-bottom: 20px;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    }
/* è¡¨å•卡片 */
.form-card {
  background-color: #fff;
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
    /* è¡¨å•标题 */
    .form-title {
        display: flex;
        align-items: center;
        font-size: 18px;
        color: #333;
        margin-bottom: 15px;
    }
/* è¡¨å•标题 */
.form-title {
  display: flex;
  align-items: center;
  font-size: 18px;
  color: #333;
  margin-bottom: 15px;
}
    .title-icon {
        font-size: 22px;
        margin-right: 10px;
    }
.title-icon {
  font-size: 22px;
  margin-right: 10px;
}
    /* è¡¨å•容器 */
    .form-container {
        padding-top: 10px;
    }
/* è¡¨å•容器 */
.form-container {
  padding-top: 10px;
}
    /* è¡¨å•模块标题 */
    .form-section {
        margin-bottom: 20px;
    }
/* è¡¨å•模块标题 */
.form-section {
  margin-bottom: 20px;
}
    .section-title {
        font-size: 16px;
        font-weight: 600;
        color: #333;
        margin-bottom: 10px;
    }
.section-title {
  font-size: 16px;
  font-weight: 600;
  color: #333;
  margin-bottom: 10px;
}
    /* è¡¨æ ¼å¸ƒå±€ */
    .form-grid {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 15px;
    }
/* è¡¨æ ¼å¸ƒå±€ */
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 15px;
}
    /* è¡¨å•项 */
    .form-group {
        display: flex;
        align-items: center;
    }
/* è¡¨å•项 */
.form-group {
  display: flex;
  align-items: center;
}
    .form-label {
        width: 130px;
        color: #333;
        font-size: 14px;
        font-weight: 500;
    }
.form-label {
  width: 130px;
  color: #333;
  font-size: 14px;
  font-weight: 500;
}
    .form-input {
        flex: 1;
        height: 40px;
        padding: 0 10px;
        border: 1px solid #e0e0e0;
        border-radius: 8px;
        background-color: #f8f8f8;
        color: #666;
        font-size: 14px;
    }
.form-input {
  flex: 1;
  height: 40px;
  padding: 0 10px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  background-color: #f8f8f8;
  color: #666;
  font-size: 14px;
}
    .form-input:disabled {
        background-color: #e9e9e9;
    }
.form-input:disabled {
  background-color: #e9e9e9;
}
    .form-input:focus {
        border-color: #007AFF;
        outline: none;
    }
.form-input:focus {
  border-color: #007AFF;
  outline: none;
}
    /* æ£€éªŒç»“果区域 */
    .tip-group {
        margin-top: 15px;
    }
/* æ£€éªŒç»“果区域 */
.tip-group {
  margin-top: 15px;
}
    .tip-box {
        display: flex;
        align-items: center;
        background-color: #fff5d1;
        padding: 10px;
        border-radius: 8px;
        border: 1px solid #f0e0a7;
    }
.tip-box {
  display: flex;
  align-items: center;
  background-color: #fff5d1;
  padding: 10px;
  border-radius: 8px;
  border: 1px solid #f0e0a7;
}
    .tip-icon {
        font-size: 20px;
        color: #f39c12;
        margin-right: 10px;
    }
.tip-icon {
  font-size: 20px;
  color: #f39c12;
  margin-right: 10px;
}
    .tip-text {
        font-size: 14px;
        color: #333;
    }
.tip-text {
  font-size: 14px;
  color: #333;
}
    .highlight {
        color: #007AFF;
        font-weight: 600;
    }
.highlight {
  color: #007AFF;
  font-weight: 600;
}
    /* æŒ‰é’®æ ·å¼ */
    .action-btn {
        width: 100%;
        padding: 12px;
        border-radius: 8px;
        border: none;
        color: #fff;
        font-size: 16px;
        font-weight: 500;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        transition: background-color 0.3s ease;
    }
/* æŒ‰é’®æ ·å¼ */
.action-btn {
  width: 100%;
  padding: 12px;
  border-radius: 8px;
  border: none;
  color: #fff;
  font-size: 16px;
  font-weight: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color 0.3s ease;
}
    .btn-primary {
        background-color: #007AFF;
    }
.btn-primary {
  background-color: #007AFF;
}
    .btn-primary:hover {
        background-color: #0056CC;
    }
.btn-primary:hover {
  background-color: #0056CC;
}
    .btn-warn {
        background-color: #f1b344;
    }
.btn-warn {
  background-color: #f1b344;
}
    .btn-warn:hover {
        background-color: #e6a135;
    }
.btn-warn:hover {
  background-color: #e6a135;
}
    .btn-disabled {
        background-color: #c0c0c0;
        cursor: not-allowed;
    }
.btn-disabled {
  background-color: #c0c0c0;
  cursor: not-allowed;
}
    /* å¼¹å‡ºå±‚样式 */
    .overlay {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 1000;
        opacity: 0;
        transition: opacity 0.3s ease;
    }
/* å¼¹å‡ºå±‚样式 */
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
  opacity: 0;
  transition: opacity 0.3s ease;
}
    .overlay.active {
        opacity: 1;
    }
.overlay.active {
  opacity: 1;
}
    .popup {
        background-color: #fff;
        border-radius: 12px;
        width: 90%;
        max-width: 500px;
        padding: 20px;
        transform: scale(0.8);
        transition: transform 0.3s ease;
    }
.popup {
  background-color: #fff;
  border-radius: 12px;
  width: 90%;
  max-width: 500px;
  padding: 20px;
  transform: scale(0.8);
  transition: transform 0.3s ease;
}
    .popup-scale {
        transform: scale(1);
    }
.popup-scale {
  transform: scale(1);
}
    .popup-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
.popup-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
    .popup-title {
        font-size: 16px;
        font-weight: 600;
        color: #333;
    }
.popup-title {
  font-size: 16px;
  font-weight: 600;
  color: #333;
}
    .close-btn {
        font-size: 20px;
        color: #333;
        cursor: pointer;
    }
.close-btn {
  font-size: 20px;
  color: #333;
  cursor: pointer;
}
    /* æ“ä½œæŒ‰é’®ç»„ */
    .button-group {
        display: flex;
        justify-content: space-between;
        margin-top: 20px;
    }
/* æ“ä½œæŒ‰é’®ç»„ */
.button-group {
  display: flex;
  justify-content: space-between;
  margin-top: 20px;
}
    .button-group button {
        width: 48%;
        padding: 10px;
        border-radius: 8px;
        border: none;
        font-size: 14px;
        font-weight: 500;
        cursor: pointer;
    }
.button-group button {
  width: 48%;
  padding: 10px;
  border-radius: 8px;
  border: none;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
}
    /* æ£€éªŒç»“果表格卡片 */
    .table-card {
        background-color: #fff;
        border-radius: 12px;
        padding: 20px;
        margin-bottom: 20px;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    }
/* æ£€éªŒç»“果表格卡片 */
.table-card {
  background-color: #fff;
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
    /* è¡¨æ ¼æ ‡é¢˜ */
    .table-title {
        display: flex;
        align-items: center;
        font-size: 16px;
        color: #333;
        font-weight: 600;
        margin-bottom: 15px;
    }
/* è¡¨æ ¼æ ‡é¢˜ */
.table-title {
  display: flex;
  align-items: center;
  font-size: 16px;
  color: #333;
  font-weight: 600;
  margin-bottom: 15px;
}
    .title-icon {
        font-size: 22px;
        margin-right: 10px;
    }
.title-icon {
  font-size: 22px;
  margin-right: 10px;
}
    /* è¡¨æ ¼æ ·å¼ */
    .uni-table {
        width: 100%;
        border-collapse: collapse;
    }
/* è¡¨æ ¼æ ·å¼ */
.uni-table {
  width: 100%;
  border-collapse: collapse;
}
    .uni-th,
    .uni-td {
        padding: 12px;
        text-align: center;
    }
.uni-th,
.uni-td {
  padding: 12px;
  text-align: center;
}
    .uni-th {
        background-color: #f5f5f5;
        font-size: 14px;
        color: #666;
        font-weight: 500;
    }
.uni-th {
  background-color: #f5f5f5;
  font-size: 14px;
  color: #666;
  font-weight: 500;
}
    .table-row {
        background-color: #fff;
        border-bottom: 1px solid #e0e0e0;
    }
.table-row {
  background-color: #fff;
  border-bottom: 1px solid #e0e0e0;
}
    .table-row:hover {
        background-color: #f9f9f9;
    }
.table-row:hover {
  background-color: #f9f9f9;
}
    .result-badge {
        padding: 5px 12px;
        font-size: 12px;
        border-radius: 10px;
        color: #fff;
        display: inline-block;
    }
.result-badge {
  padding: 5px 12px;
  font-size: 12px;
  border-radius: 10px;
  color: #fff;
  display: inline-block;
}
    .pass {
        background-color: #28a745;
    }
.pass {
  background-color: #28a745;
}
    .fail {
        background-color: #dc3545;
    }
.fail {
  background-color: #dc3545;
}
    .pending {
        background-color: #f1b344;
    }
.pending {
  background-color: #f1b344;
}
    .action-group {
        display: flex;
        gap: 10px;
    }
.action-group {
  display: flex;
  gap: 10px;
}
    .action-btn.btn-sm {
        width: auto;
        padding: 6px 12px;
        font-size: 12px;
    }
.action-btn.btn-sm {
  width: auto;
  padding: 6px 12px;
  font-size: 12px;
}
    /* æç¤ºä¿¡æ¯ */
    .hover-effect:hover {
        background-color: #f9f9f9;
    }
/* æç¤ºä¿¡æ¯ */
.hover-effect:hover {
  background-color: #f9f9f9;
}
    .btn-sm {
        font-size: 14px;
    }
.btn-sm {
  font-size: 14px;
}
    .btn-loading {
        background-color: #c0c0c0;
        cursor: not-allowed;
    }
.btn-loading {
  background-color: #c0c0c0;
  cursor: not-allowed;
}
/* ä¸‰ä¸ªæ¨¡å—并列容器样式 */
.three-modules-container {
  display: flex;
  flex-direction: column;
  gap: 15px;
  margin-bottom: 20px;
}
/* æ¨¡å—项样式 */
.module-item {
  background-color: #f8f9fa;
  border-radius: 8px;
  padding: 15px;
  border: 1px solid #e0e0e0;
}
.module-header {
  border-bottom: 1px solid #d0d0d0;
  padding-bottom: 8px;
  margin-bottom: 12px;
}
.module-title {
  font-size: 15px;
  font-weight: 600;
  color: #333;
}
/* æ‰‹æœºå±å¹•优化 */
@media (max-width: 768px) {
  .page-container {
    padding: 10px;
  }
  .form-card, .table-card {
    padding: 15px;
    border-radius: 8px;
  }
  .form-grid {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .form-group {
    flex-direction: column;
    align-items: flex-start;
  }
  .form-label {
    width: auto;
    margin-bottom: 5px;
    font-size: 13px;
  }
  .form-input {
    width: 100%;
    height: 36px;
    font-size: 13px;
  }
  .three-modules-container {
    gap: 12px;
  }
  .module-item {
    padding: 12px;
  }
  .module-title {
    font-size: 14px;
  }
  .tip-box {
    padding: 8px;
  }
  .tip-text {
    font-size: 13px;
  }
}
/* è¶…小屏幕优化 */
@media (max-width: 480px) {
  .page-container {
    padding: 8px;
  }
  .form-card, .table-card {
    padding: 12px;
  }
  .form-input {
    height: 34px;
    font-size: 12px;
  }
  .form-label {
    font-size: 12px;
  }
  .action-btn {
    padding: 10px;
    font-size: 14px;
  }
}
</style>