xwt
4 天以前 59dc3bbd1fdedab400b56d67a169bcda97dcf75e
SJ,XJ,RKJ优化修改
已修改6个文件
1006 ■■■■ 文件已修改
manifest.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/RKJ/Add.vue 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/RKJ/List.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/RKJ/detail.vue 281 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/SJ/detail.vue 307 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/XJ/detail.vue 351 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manifest.json
@@ -2,7 +2,7 @@
    "name" : "GS-MES-AP",
    "appid" : "__UNI__F08FAE3",
    "description" : "",
    "versionName" : "1.1.4.6",
    "versionName" : "1.1.4.9",
    "versionCode" : 1,
    "transformPx" : false,
    /* 5+App特有相关 */
pages/QC/RKJ/Add.vue
@@ -41,8 +41,8 @@
                <view class="form-row">
                    <label class="form-label required">送检数量:</label>
                    <input type="number" v-model="formData.quantity" placeholder="请输入送检数量" class="large-quantity-input"
                        @input="onQuantityChange" />
                    <input type="number" v-model="formData.sjqty" placeholder="请输入送检数量" class="large-quantity-input"
                        @input="onSjqtyChange" />
                </view>
            </view>
@@ -79,7 +79,7 @@
        <view class="form-actions">
            <button class="btn-primary"
                v-if="!isShowTable && formData.workShop && formData.lineName && formData.rBillNo && formData.quantity"
                v-if="!isShowTable && formData.workShop && formData.lineName && formData.rBillNo && formData.sjqty"
                @click="getItem">
                <text class="btn-icon">✓</text>
                生成检验单
@@ -130,8 +130,12 @@
                <view class="info-value">{{formData.itemModel}}</view>
            </view>
            <view class="info-block">
                <view class="info-label">工单数量:</view>
                <view class="info-value">{{formData.quantity || formData.planQty}}</view>
            </view>
            <view class="info-block">
                <view class="info-label">送检数量:</view>
                <view class="info-value highlight">{{formData.quantity}}</view>
                <view class="info-value highlight">{{formData.sjqty}}</view>
            </view>
            <view class="info-block" v-if="formData.remarks">
                <view class="info-label">不合格描述:</view>
@@ -474,7 +478,8 @@
                    rbillNo: "",
                    workShop: "", // 工作车间
                    lineName: "", // 线体名称
                    quantity: "", // 送检数量
                    quantity: "", // 工单数量(原送检数量字段)
                    sjqty: "", // 送检数量(新增字段)
                    planQty: "", // 工单计划数量
                    fngDesc: "" // 不良描述
                },
@@ -706,8 +711,8 @@
                    data: {
                        from: this.formData,
                        userNo: this.$loginInfo.account,
                        quantity: this.formData.quantity,
                        //moidNum: this.formData.moidNum
                        quantity: this.formData.quantity, // 工单数量
                        sjqty: this.formData.sjqty, // 送检数量
                        items: this.tableData
                    }
                }).then(res => {
@@ -826,39 +831,40 @@
                this.formData.billNo = data.daa001; // 工单号作为billNo
                this.formData.rbillNo = "无源单"; // 送检批次号(使用默认值)
                this.formData.itemModel = data.daa004 || ""; // 产品规格
                this.formData.planQty = data.daa008 || ""; // 工单数量
                this.formData.planQty = data.daa008 || ""; // 工单数量(仅显示)
                this.formData.quantity = data.daa008 || ""; // 工单数量(保存到数据库)
                // 不清空送检数量,保持用户已输入的值
                this.tableData = [];
            },
            // 送检数量变化事件
            onQuantityChange(event) {
            onSjqtyChange(event) {
                // 如果输入为空,不进行验证
                if (!this.formData.quantity || this.formData.quantity === "") {
                if (!this.formData.sjqty || this.formData.sjqty === "") {
                    return;
                }
                const quantity = parseFloat(this.formData.quantity);
                const sjqty = parseFloat(this.formData.sjqty);
                // 检查是否为有效数字
                if (isNaN(quantity)) {
                if (isNaN(sjqty)) {
                    this.$showMessage("请输入有效的数字");
                    this.formData.quantity = "";
                    this.formData.sjqty = "";
                    return;
                }
                // 只有在输入完成且数量大于0时才进行验证
                if (quantity <= 0) {
                if (sjqty <= 0) {
                    this.$showMessage("送检数量必须大于0");
                    this.formData.quantity = "";
                    this.formData.sjqty = "";
                    return;
                }
                // 只有在已选择工单且有工单数量时才进行数量比较
                if (this.formData.planQty) {
                    const planQty = parseFloat(this.formData.planQty);
                    if (!isNaN(planQty) && quantity > planQty) {
                if (this.formData.quantity || this.formData.planQty) {
                    const planQty = parseFloat(this.formData.quantity || this.formData.planQty);
                    if (!isNaN(planQty) && sjqty > planQty) {
                        this.$showMessage("送检数量不能大于工单数量");
                        this.formData.quantity = "";
                        this.formData.sjqty = "";
                        return;
                    }
                }
@@ -888,7 +894,8 @@
                        this.formData.itemNo = data.itemNo;
                        this.formData.itemId = data.itemId;
                        this.formData.lineNo = data.lineNo;
                        this.formData.quantity = data.quantity;
                        this.formData.quantity = data.quantity; // 工单数量
                        this.formData.sjqty = data.sjqty; // 送检数量
                        this.formData.fcheckResu = data.fcheckResu;
                        this.formData.fcheckBy = data.fcheckBy;
                        this.formData.fcheckDate = data.fcheckDate;
@@ -1089,8 +1096,8 @@
                });
            },
            getTable() {
                // 确保quantity有值
                if (!this.formData.quantity || parseFloat(this.formData.quantity) <= 0) {
                // 确保sjqty有值
                if (!this.formData.sjqty || parseFloat(this.formData.sjqty) <= 0) {
                    this.$showMessage("请先输入有效的送检数量");
                    return;
                }
@@ -1099,7 +1106,7 @@
                    url: "/RKJ/setJYItem",
                    data: {
                        itemNo: this.formData.itemNo,
                        quantity: this.formData.quantity
                        quantity: this.formData.sjqty
                    }
                }).then(res => {
pages/QC/RKJ/List.vue
@@ -67,17 +67,21 @@
  
            <view class="info-row">
              <view class="info-item">
                <text class="info-label">送检数量</text>
                <text class="info-content highlight">{{item.quantity}}</text>
                <text class="info-label">工单数量</text>
                <text class="info-content">{{item.quantity}}</text>
              </view>
              <view class="info-item">
                <text class="info-label">创建人</text>
                <text class="info-content">{{item.createBy}}</text>
                <text class="info-label">送检数量</text>
                <text class="info-content highlight">{{item.sjqty}}</text>
              </view>
            </view>
  
            <view class="info-row">
              <view class="info-item">
                <text class="info-label">创建人</text>
                <text class="info-content">{{item.createBy}}</text>
              </view>
              <view class="info-item">
                <text class="info-label">送检批次</text>
                <text class="info-content">{{item.rbillNo}}</text>
              </view>
pages/QC/RKJ/detail.vue
@@ -107,7 +107,7 @@
              v-model="formData.fcheckResu"
              type="text"
              class="result-input"
              placeholder="没有最大值和最小值时填写0(未通过检验)或1(通过检验)"
              placeholder="无上下限时填写OK(合格)或NG(不合格)"
              placeholder-class="placeholder" />
            <button v-if="(tableData.length < formData.levelNum)"
              style="margin: 0px;background-color: #3498db;color:#ffffff ;" class="btn primary-btn"
@@ -139,17 +139,24 @@
      </button>
    </view>
    <!-- 图片预览 -->
    <view v-if="isShowImg" class="section">
    <!-- 图片预览 - 支持多图片 -->
    <view v-if="imageList && imageList.length > 0" class="section">
      <view class="section-header">
        <view class="section-title">相关图片</view>
        <view class="section-actions">
          <button class="delete-image-btn" @click="deleteImage">删除图片</button>
        </view>
        <view class="section-title">相关图片 ({{ imageList.length }}张)</view>
      </view>
      <view class="section-body">
        <view class="image-preview" @click="previewImage">
          <image :src="base64Image" mode="aspectFit" class="preview-image"/>
        <view class="image-list">
          <view v-for="(img, index) in imageList" :key="img.id" class="image-item">
            <view class="image-preview" @click="previewMultiImage(index)">
              <image :src="'data:image/jpeg;base64,' + img.base64Data" mode="aspectFill" class="preview-image"/>
            </view>
            <view class="image-actions">
              <button class="delete-image-btn" @click="deleteSingleImage(img)">
                <text class="delete-icon">🗑️</text>
                <text>删除</text>
              </button>
            </view>
          </view>
        </view>
      </view>
    </view>
@@ -174,7 +181,7 @@
              </view>
            </view>
            <view class="td">
              <view class="result-badge" :class="item.fcheckResu === '1' ? 'OK' : 'NG'">
              <view class="result-badge" :class="(item.fcheckResu === 'OK' || item.fcheckResu === '1' || item.fcheckResu == 1) ? 'OK' : 'NG'">
                {{ item.fcheckResu }}
              </view>
            </view>
@@ -400,6 +407,7 @@
      tableData: [],
      isShowImg: false,
      base64Image: "",
      imageList: [],  // 多图片列表
      remarks: "",
      remarksPopup: false,
      fcheckResu: null,
@@ -433,7 +441,7 @@
    
    // 判断是否已上传图片
    hasImage() {
      return this.formData.imageData && this.formData.imageData.length > 0;
      return this.imageList && this.imageList.length > 0;
    },
    
    // 判断是否已填写不良描述
@@ -448,7 +456,8 @@
    },
    editResult(fcheckResu) {
      if (fcheckResu == '1') {
      // 1 或 OK 都表示合格
      if (fcheckResu == '1' || fcheckResu == 'OK' || fcheckResu == 1) {
        return "改为不合格";
      } else {
        return "改为合格";
@@ -477,22 +486,27 @@
      } else {
        if (!this.formData.fcheckResu) {
          this.formData.fcheckResu = 1
          this.formData.fcheckResu = 'OK';  // 默认合格
        }
        if (this.formData.fcheckResu == 0 || this.formData.fcheckResu == 1) {
          this.formData.isPass = this.formData.fcheckResu
        // 统一使用 OK/NG
        const upperValue = String(this.formData.fcheckResu).toUpperCase();
        if (upperValue === 'OK' || upperValue === 'NG') {
          this.formData.fcheckResu = upperValue;  // 统一转为大写
          if (upperValue === 'NG') {
            fstand = "×";
          }
        } else {
          this.$showMessage("无标准值时,检验结果只能为0或1!");
          this.$showMessage("无上下限时,检验结果只能为OK或NG!");
          return;
        }
        count = count - this.tableData.length;
      }
      // 验证不合格检验项目必须上传图片并填写不良描述
      if (fstand === "×" || this.formData.fcheckResu == 0) {
      if (fstand === "×" || this.formData.fcheckResu === 'NG') {
        // 检查是否已上传图片
        if (!this.formData.imageData || this.formData.imageData.length === 0) {
        if (!this.imageList || this.imageList.length === 0) {
          this.$showMessage("检验项目不合格,必须上传图片!");
          return;
        }
@@ -534,12 +548,26 @@
        this.tableData = res.data.tbBillList.itemXj02s;
        // 处理图片显示状态
        if (this.formData.imageData && this.formData.imageData.length > 0) {
        // 处理多图片列表
        if (this.formData.imageList && this.formData.imageList.length > 0) {
          this.imageList = this.formData.imageList;
          this.isShowImg = true;
          if (this.imageList.length > 0) {
            this.base64Image = 'data:image/jpeg;base64,' + this.imageList[0].base64Data;
          }
        } else if (this.formData.imageData && this.formData.imageData.length > 0) {
          // 向后兼容:如果没有imageList但有imageData
          this.imageList = [{
            id: 0,
            base64Data: this.formData.imageData,
            fileName: '',
            createDate: null,
            createBy: ''
          }];
          this.isShowImg = true;
          this.base64Image = 'data:image/jpeg;base64,' + this.formData.imageData;
        } else {
          // 如果没有图片数据,隐藏图片显示区域
          this.imageList = [];
          this.isShowImg = false;
          this.base64Image = '';
        }
@@ -586,23 +614,26 @@
      } else {
        if (!this.editData.fcheckResu) {
          this.editData.fcheckResu = 1
          this.editData.fcheckResu = 'OK';  // 默认合格
        }
        if (this.editData.fcheckResu == 0 || this.editData.fcheckResu == 1) {
          if (this.editData.fcheckResu == 0) {
        // 统一使用 OK/NG
        const upperValue = String(this.editData.fcheckResu).toUpperCase();
        if (upperValue === 'OK' || upperValue === 'NG') {
          this.editData.fcheckResu = upperValue;  // 统一转为大写
          if (upperValue === 'NG') {
            fstand = "×";
          }
        } else {
          this.$showMessage("无标准值时,检验结果只能为0或1!");
          this.$showMessage("无上下限时,检验结果只能为OK或NG!");
          return;
        }
      }
      // 验证不合格检验项目必须上传图片并填写不良描述
      if (fstand === "×" || this.editData.fcheckResu == 0) {
      if (fstand === "×" || this.editData.fcheckResu === 'NG') {
        // 检查是否已上传图片
        if (!this.formData.imageData || this.formData.imageData.length === 0) {
        if (!this.imageList || this.imageList.length === 0) {
          this.$showMessage("检验项目不合格,必须上传图片!");
          return;
        }
@@ -642,17 +673,18 @@
    numberEdit(item) {
      let fstand = "√";
      let fcheckResu = 1;
      let fcheckResu = 'OK';  // 合格用OK
      if (item.fcheckResu == '1') {
      // 判断当前是否为合格状态(OK 或 1 都表示合格)
      if (item.fcheckResu == '1' || item.fcheckResu == 'OK' || item.fcheckResu == 1) {
        fstand = "×";
        fcheckResu = 0;
        fcheckResu = 'NG';  // 不合格用NG
      }
      // 验证不合格检验项目必须上传图片并填写不良描述
      if (fstand === "×" || fcheckResu == 0) {
      if (fstand === "×" || fcheckResu == 'NG') {
        // 检查是否已上传图片
        if (!this.formData.imageData || this.formData.imageData.length === 0) {
        if (!this.imageList || this.imageList.length === 0) {
          this.$showMessage("检验项目不合格,必须上传图片!");
          return;
        }
@@ -983,20 +1015,34 @@
      });
    },
    
    // 根据选择的来源选择图片
    // 根据选择的来源选择图片(支持多选)
    chooseImageWithSource(sourceType) {
      // 计算还可以上传多少张图片
      const currentCount = this.imageList ? this.imageList.length : 0;
      const maxCount = 9;
      const remainCount = maxCount - currentCount;
      if (remainCount <= 0) {
        uni.showToast({
          title: '最多只能上传' + maxCount + '张图片',
          icon: 'none'
        });
        return;
      }
      uni.chooseImage({
        count: 1, // 最多选择1张图片
        sizeType: ['compressed', 'original'], // 提供压缩和原图选项
        sourceType: sourceType, // 根据用户选择设置来源
        count: sourceType.includes('camera') ? 1 : remainCount, // 拍照只能一张,相册可多选
        sizeType: ['compressed', 'original'],
        sourceType: sourceType,
        success: (res) => {
          const tempFilePath = res.tempFilePaths[0];
          const tempFilePaths = res.tempFilePaths;
          
          // 如果是拍照,显示预览确认
          if (sourceType.includes('camera')) {
            this.showImagePreview(tempFilePath);
            this.showImagePreview(tempFilePaths[0]);
          } else {
            this.uploadImageToServer(tempFilePath);
            // 多图片批量上传
            this.uploadMultipleImages(tempFilePaths);
          }
        },
        fail: (error) => {
@@ -1007,6 +1053,77 @@
          }
          uni.showToast({
            title: errorMessage,
            icon: 'none'
          });
        }
      });
    },
    // 批量上传图片
    uploadMultipleImages(tempFilePaths) {
      if (!tempFilePaths || tempFilePaths.length === 0) {
        return;
      }
      uni.showLoading({
        title: '上传中... (0/' + tempFilePaths.length + ')'
      });
      const uploadUrl = this.$store.state.serverInfo.serverAPI + "/RKJ/UploadImageToPicture";
      let successCount = 0;
      let failCount = 0;
      const total = tempFilePaths.length;
      const uploadPromises = tempFilePaths.map((filePath, index) => {
        return new Promise((resolve) => {
          uni.uploadFile({
            url: uploadUrl,
            filePath: filePath,
            name: 'file',
            formData: {
              id: this.id,
              gid: this.gid,
              billNo: this.billNo,
              createBy: this.$loginInfo.account
            },
            success: (uploadRes) => {
              try {
                const result = JSON.parse(uploadRes.data);
                if (result.status === 0) {
                  successCount++;
                } else {
                  failCount++;
                }
              } catch (error) {
                failCount++;
              }
              uni.showLoading({
                title: '上传中... (' + (successCount + failCount) + '/' + total + ')'
              });
              resolve();
            },
            fail: () => {
              failCount++;
              uni.showLoading({
                title: '上传中... (' + (successCount + failCount) + '/' + total + ')'
              });
              resolve();
            }
          });
        });
      });
      Promise.all(uploadPromises).then(() => {
        uni.hideLoading();
        if (successCount > 0) {
          uni.showToast({
            title: '成功上传' + successCount + '张图片',
            icon: 'success'
          });
          this.refreshResult();
        } else {
          uni.showToast({
            title: '图片上传失败',
            icon: 'none'
          });
        }
@@ -1114,17 +1231,45 @@
      });
    },
    
    // 预览多图片
    previewMultiImage(index) {
      const urls = this.imageList.map(img => 'data:image/jpeg;base64,' + img.base64Data);
      uni.previewImage({
        urls: urls,
        current: index
      });
    },
    // 删除单张图片
    deleteSingleImage(img) {
      uni.showModal({
        title: '确认删除',
        content: '确定要删除这张图片吗?',
        confirmText: '删除',
        cancelText: '取消',
        confirmColor: '#e74c3c',
        success: (res) => {
          if (res.confirm) {
            this.deleteImageFromServer(img.id);
          }
        }
      });
    },
    // 从服务器删除图片
    deleteImageFromServer() {
    deleteImageFromServer(imageId = null) {
      uni.showLoading({
        title: '删除中...'
      });
      
      const data = { id: this.id };
      if (imageId !== null && imageId !== undefined && imageId !== 0) {
        data.imageId = imageId;
      }
      this.$post({
        url: "/RKJ/DeleteImageFromPicture",
        data: {
          id: this.id // 当前检验项目ID
        }
        data: data
      }).then(res => {
        uni.hideLoading();
        if (res.status === 0) {
@@ -1223,6 +1368,56 @@
  }
}
/* 多图片列表样式 */
.image-list {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
.image-item {
  width: 150px;
  display: flex;
  flex-direction: column;
  align-items: center;
  .image-preview {
    width: 150px;
    height: 150px;
    border: 1px solid $border-color;
    border-radius: 8px;
    overflow: hidden;
    cursor: pointer;
    .preview-image {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  }
  .image-actions {
    margin-top: 8px;
    .delete-image-btn {
      display: flex;
      align-items: center;
      gap: 4px;
      padding: 6px 12px;
      background-color: $danger-color;
      color: #fff;
      border: none;
      border-radius: 4px;
      font-size: 12px;
      cursor: pointer;
      .delete-icon {
        font-size: 14px;
      }
    }
  }
}
.info-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
pages/QC/SJ/detail.vue
@@ -134,7 +134,7 @@
                v-model="formData.fcheckResu"
                type="text"
                class="result-input"
                placeholder="没有最大值和最小值时填写0(未通过检验)或1(通过检验)"
                placeholder="无上下限时填写OK(合格)或NG(不合格)"
                placeholder-class="placeholder" />
              <button v-if="!isAllCompleted"
                style="margin: 0px;background-color: #3498db;color:#ffffff ;" class="btn primary-btn"
@@ -203,17 +203,24 @@
        </view>
      </view>
 
      <!-- 图片预览 -->
      <view v-if="isShowImg" class="section">
      <!-- 图片预览 - 支持多图片 -->
      <view v-if="imageList && imageList.length > 0" class="section">
        <view class="section-header">
          <view class="section-title">相关图片</view>
          <view class="section-actions">
            <button class="delete-image-btn" @click="deleteImage">删除图片</button>
          </view>
          <view class="section-title">相关图片 ({{ imageList.length }}张)</view>
        </view>
        <view class="section-body">
          <view class="image-preview" @click="previewImage">
            <image :src="base64Image" mode="aspectFit" class="preview-image"/>
          <view class="image-list">
            <view v-for="(img, index) in imageList" :key="img.id" class="image-item">
              <view class="image-preview" @click="previewMultiImage(index)">
                <image :src="'data:image/jpeg;base64,' + img.base64Data" mode="aspectFill" class="preview-image"/>
              </view>
              <view class="image-actions">
                <button class="delete-image-btn" @click="deleteSingleImage(img)">
                  <text class="delete-icon">🗑️</text>
                  <text>删除</text>
                </button>
              </view>
            </view>
          </view>
        </view>
      </view>
@@ -437,6 +444,7 @@
      tableData: [],
      base64Image: "",
      isShowImg: false,
      imageList: [],  // 多图片列表
      remarks: "",
      remarksPopup: false,
      // ===== 新增LLJ样式相关数据 =====
@@ -560,13 +568,13 @@
               this.formData.fcheckResu > this.formData.maxValue;
      }
      
      // 如果没有最大值和最小值,检查是否为0(不合格)
      return this.formData.fcheckResu == 0;
      // 如果没有上下限,检查是否为NG(不合格)或兼容旧的06
      return this.formData.fcheckResu == 0 || this.formData.fcheckResu === 'NG';
    },
    
    // 判断是否已上传图片
    hasImage() {
      return this.formData.imageData && this.formData.imageData.length > 0;
      return this.imageList && this.imageList.length > 0;
    },
    
    // 判断是否已填写不良描述
@@ -592,9 +600,9 @@
        return 'NG';
      } else {
        // 如果没有fstand,根据fcheckResu的值判断
        if (fcheckResu === '1' || fcheckResu === 1) {
        if (fcheckResu === '1' || fcheckResu === 1 || fcheckResu === 'OK') {
          return 'OK';
        } else if (fcheckResu === '0' || fcheckResu === 0) {
        } else if (fcheckResu === '0' || fcheckResu === 0 || fcheckResu === 'NG') {
          return 'NG';
        } else {
          // 对于有上下限的数值检验,根据fcheckResu是否在范围内判断
@@ -632,9 +640,9 @@
        return '不合格';
      } else {
        // 如果没有fstand,根据fcheckResu的值判断
        if (fcheckResu === '1' || fcheckResu === 1) {
        if (fcheckResu === '1' || fcheckResu === 1 || fcheckResu === 'OK') {
          return '合格';
        } else if (fcheckResu === '0' || fcheckResu === 0) {
        } else if (fcheckResu === '0' || fcheckResu === 0 || fcheckResu === 'NG') {
          return '不合格';
        } else {
          // 对于有上下限的数值检验,根据fcheckResu是否在范围内判断
@@ -692,8 +700,31 @@
        urls: [this.base64Image],
      });
    },
    // 多图片预览
    previewMultiImage(index) {
      const urls = this.imageList.map(img => 'data:image/jpeg;base64,' + img.base64Data);
      uni.previewImage({
        urls: urls,
        current: index
      });
    },
    // 删除单张图片
    deleteSingleImage(img) {
      uni.showModal({
        title: '确认删除',
        content: '确定要删除这张图片吗?',
        success: (res) => {
          if (res.confirm) {
            this.deleteImageFromServer(img.id);
          }
        }
      });
    },
    editResult(fcheckResu) {
      if (fcheckResu == '1') {
      // 1 或 OK 都表示合格
      if (fcheckResu == '1' || fcheckResu == 'OK' || fcheckResu == 1) {
        return "改为不合格";
      } else {
        return "改为合格";
@@ -749,9 +780,9 @@
      }
 
      // 验证不合格检验项目必须上传图片并填写不良描述
      if (fstand === "×" || this.formData.fcheckResu == 0) {
      if (fstand === "×" || this.formData.fcheckResu === 'NG') {
        // 检查是否已上传图片
        if (!this.formData.imageData || this.formData.imageData.length === 0) {
        if (!this.imageList || this.imageList.length === 0) {
          this.$showMessage("检验项目不合格,必须上传图片!");
          return;
        }
@@ -798,13 +829,31 @@
        console.log("获取到的 formData:", this.formData);
        console.log("itemNo 值:", this.formData.itemNo);
        
        if (this.formData.imageData) {
        // 处理多图片列表
        if (this.formData.imageList && this.formData.imageList.length > 0) {
          this.imageList = this.formData.imageList;
          this.isShowImg = true;
          // 保持向后兼容
          if (this.imageList.length > 0) {
            this.base64Image = 'data:image/jpeg;base64,' + this.imageList[0].base64Data;
          }
        } else if (this.formData.imageData) {
          // 向后兼容:如果只有单张图片数据
          this.imageList = [{
            id: 0,
            base64Data: this.formData.imageData,
            fileName: '',
            createDate: null,
            createBy: ''
          }];
          this.isShowImg = true;
          this.base64Image = 'data:image/jpeg;base64,' + this.formData.imageData;
        } else {
          this.imageList = [];
          this.isShowImg = false;
          this.base64Image = '';
        }
        if (this.formData.maxValue && this.formData.minValue && this.formData.standardValue) {
          this.isNumber = true;
        }
@@ -871,7 +920,7 @@
      }
 
      // 验证不合格检验项目必须上传图片并填写不良描述
      if (fstand === "×" || this.editData.fcheckResu == 0) {
      if (fstand === "×" || this.editData.fcheckResu === 'NG') {
        // 检查是否已上传图片
        if (!this.formData.imageData || this.formData.imageData.length === 0) {
          this.$showMessage("检验项目不合格,必须上传图片!");
@@ -918,17 +967,18 @@
    numberEdit(item) {
 
      let fstand = "√";
      let fcheckResu = 1;
      let fcheckResu = 'OK';  // 合格用OK
 
      if (item.fcheckResu == '1') {
      // 判断当前是否为合格状态(OK 或 1 都表示合格)
      if (item.fcheckResu == '1' || item.fcheckResu == 'OK' || item.fcheckResu == 1) {
        fstand = "×";
        fcheckResu = 0;
        fcheckResu = 'NG';  // 不合格用NG
      }
      // 验证不合格检验项目必须上传图片并填写不良描述
      if (fstand === "×" || fcheckResu == 0) {
      if (fstand === "×" || fcheckResu == 'NG') {
        // 检查是否已上传图片
        if (!this.formData.imageData || this.formData.imageData.length === 0) {
        if (!this.imageList || this.imageList.length === 0) {
          this.$showMessage("检验项目不合格,必须上传图片!");
          return;
        }
@@ -1246,26 +1296,89 @@
      });
    },
    // 选择图片来源
    // 选择图片来源 - 支持多选
    chooseImageWithSource(source) {
      uni.chooseImage({
        count: 1,
        count: 9,  // 支持最多选择9张图片
        sizeType: ['compressed'],
        sourceType: [source],
        success: (res) => {
          const tempFilePath = res.tempFilePaths[0];
          const tempFilePaths = res.tempFilePaths;
          if (source === 'camera') {
            // 拍照后显示预览确认
            this.showImagePreview(tempFilePath);
            // 拍照后直接上传(单张)
            this.uploadImageToServer(tempFilePaths[0]);
          } else {
            // 相册选择直接上传
            this.uploadImageToServer(tempFilePath);
            // 相册选择,批量上传
            this.uploadMultipleImages(tempFilePaths);
          }
        },
        fail: (err) => {
          console.error('选择图片失败:', err);
          this.$showMessage('选择图片失败');
        }
      });
    },
    // 批量上传图片
    uploadMultipleImages(tempFilePaths) {
      if (!tempFilePaths || tempFilePaths.length === 0) {
        return;
      }
      uni.showLoading({
        title: `上传中(0/${tempFilePaths.length})...`
      });
      let successCount = 0;
      let failCount = 0;
      const total = tempFilePaths.length;
      // 使用 Promise.all 并行上传
      const uploadPromises = tempFilePaths.map((filePath, index) => {
        return new Promise((resolve) => {
          uni.uploadFile({
            url: this.$store.state.serverInfo.serverAPI + '/SJ/UploadImageToPicture',
            filePath: filePath,
            name: 'file',
            formData: {
              id: this.id.toString(),
              gid: this.gid.toString(),
              billNo: this.billNo,
              createBy: this.$loginInfo.account
            },
            success: (res) => {
              try {
                const result = JSON.parse(res.data);
                if (result.status === 0) {
                  successCount++;
                } else {
                  failCount++;
                }
              } catch (e) {
                failCount++;
              }
              uni.showLoading({
                title: `上传中(${successCount + failCount}/${total})...`
              });
              resolve();
            },
            fail: (err) => {
              failCount++;
              console.error('上传失败:', err);
              resolve();
            }
          });
        });
      });
      Promise.all(uploadPromises).then(() => {
        uni.hideLoading();
        if (failCount === 0) {
          this.$showMessage(`${successCount}张图片上传成功`);
        } else {
          this.$showMessage(`上传完成:成功${successCount}张,失败${failCount}张`);
        }
        this.refreshResult();
      });
    },
@@ -1340,17 +1453,24 @@
      });
    },
    // 从服务器删除图片
    deleteImageFromServer() {
    // 从服务器删除图片 - 支持删除单张或所有图片
    deleteImageFromServer(imageId = null) {
      uni.showLoading({
        title: '删除中...'
      });
      const data = {
        id: this.id
      };
      // 如果传入了 imageId,则删除单张图片
      if (imageId !== null && imageId !== undefined && imageId !== 0) {
        data.imageId = imageId;
      }
      this.$post({
        url: '/SJ/DeleteImageFromPicture',
        data: {
          id: this.id
        }
        data: data
      }).then(res => {
        uni.hideLoading();
        if (res.status === 0) {
@@ -2424,6 +2544,117 @@
  transform: translateY(-1px);
}
/* 多图片列表样式 */
.image-list {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 10px 0;
}
.image-item {
  position: relative;
  width: calc(33.33% - 8px);
  min-width: 100px;
  max-width: 150px;
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 2px 12px rgba(0,0,0,0.08);
  transition: all 0.3s ease;
}
.image-item:hover {
  box-shadow: 0 4px 20px rgba(0,0,0,0.12);
  transform: translateY(-2px);
}
.image-item .image-preview {
  width: 100%;
  height: 100px;
  overflow: hidden;
  cursor: pointer;
  position: relative;
}
.image-item .preview-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.image-actions {
  padding: 8px 6px;
  text-align: center;
  background: linear-gradient(to bottom, #fafafa, #f5f5f5);
}
.image-actions .delete-image-btn {
  width: 100%;
  padding: 8px 12px;
  font-size: 13px;
  border-radius: 20px;
  background: linear-gradient(135deg, #ff6b6b 0%, #ee5a5a 100%);
  border: none;
  color: white;
  font-weight: 500;
  box-shadow: 0 2px 8px rgba(238, 90, 90, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  transition: all 0.2s ease;
}
.image-actions .delete-image-btn:active {
  transform: scale(0.95);
  box-shadow: 0 1px 4px rgba(238, 90, 90, 0.3);
}
.delete-icon {
  font-size: 14px;
  margin-right: 2px;
}
/* 移动端优化 */
@media (max-width: 480px) {
  .image-list {
    gap: 10px;
  }
  .image-item {
    width: calc(50% - 5px);
    min-width: 0;
    max-width: none;
    border-radius: 10px;
  }
  .image-item .image-preview {
    height: 90px;
  }
  .image-actions {
    padding: 6px 5px;
  }
  .image-actions .delete-image-btn {
    padding: 6px 10px;
    font-size: 12px;
    border-radius: 16px;
  }
}
@media (min-width: 768px) {
  .image-item {
    width: calc(25% - 9px);
    max-width: 160px;
  }
  .image-item .image-preview {
    height: 120px;
  }
}
/* 上传图片按钮样式 */
.tablet-upload-btn {
  background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
pages/QC/XJ/detail.vue
@@ -101,7 +101,7 @@
              v-model="formData.fcheckResu"
              type="text"
              class="result-input"
              placeholder="没有最大值和最小值时填写0(未通过检验)或1(通过检验)"
              placeholder="无上下限时填写OK(合格)或NG(不合格)"
              placeholder-class="placeholder" />
            <button v-if="(tableData.length < formData.levelNum)"
              style="margin: 0px;background-color: #3498db;color:#ffffff ;" class="btn primary-btn"
@@ -111,17 +111,24 @@
      </view>
    </view>
    <!-- 图片预览 -->
    <view v-if="isShowImg" class="section">
    <!-- 图片预览 - 支持多图片 -->
    <view v-if="imageList && imageList.length > 0" class="section">
      <view class="section-header">
        <view class="section-title">相关图片</view>
        <view class="section-actions">
          <button class="delete-image-btn" @click="deleteImage">删除图片</button>
        </view>
        <view class="section-title">相关图片 ({{ imageList.length }}张)</view>
      </view>
      <view class="section-body">
        <view class="image-preview" @click="previewImage">
          <image :src="base64Image" mode="aspectFit" class="preview-image"/>
        <view class="image-list">
          <view v-for="(img, index) in imageList" :key="img.id" class="image-item">
            <view class="image-preview" @click="previewMultiImage(index)">
              <image :src="'data:image/jpeg;base64,' + img.base64Data" mode="aspectFill" class="preview-image"/>
            </view>
            <view class="image-actions">
              <button class="delete-image-btn" @click="deleteSingleImage(img)">
                <text class="delete-icon">🗑️</text>
                <text>删除</text>
              </button>
            </view>
          </view>
        </view>
      </view>
    </view>
@@ -137,7 +144,7 @@
      <view v-for="(item, index) in tableData" :key="index" class="table-row">
        <view class="td">{{ index + 1 }}</view>
        <view class="td">
          <view :class="['result-badge', item.fstand === '√' ? 'OK' : 'NG']">
          <view class="result-badge" :class="(item.fcheckResu === 'OK' || item.fcheckResu === '1' || item.fcheckResu == 1) ? 'OK' : 'NG'">
            {{ item.fcheckResu }}
          </view>
        </view>
@@ -391,6 +398,7 @@
      tableData: [],
      isShowImg: false,
      base64Image:"",
      imageList: [],  // 多图片列表
      remarks: "",
      remarksPopup: false,
      
@@ -430,7 +438,7 @@
    
    // 判断是否已上传图片
    hasImage() {
      return this.formData.imageData && this.formData.imageData.length > 0;
      return this.imageList && this.imageList.length > 0;
    },
    
    // 判断是否已填写不良描述
@@ -444,8 +452,31 @@
        urls: [this.base64Image],
      });
    },
    // 多图片预览
    previewMultiImage(index) {
      const urls = this.imageList.map(img => 'data:image/jpeg;base64,' + img.base64Data);
      uni.previewImage({
        urls: urls,
        current: index
      });
    },
    // 删除单张图片
    deleteSingleImage(img) {
      uni.showModal({
        title: '确认删除',
        content: '确定要删除这张图片吗?',
        success: (res) => {
          if (res.confirm) {
            this.deleteImageFromServer(img.id);
          }
        }
      });
    },
    editResult(fcheckResu) {
      if (fcheckResu == '1') {
      // 1 或 OK 都表示合格
      if (fcheckResu == '1' || fcheckResu == 'OK' || fcheckResu == 1) {
        return "改为不合格";
      } else {
        return "改为合格";
@@ -472,24 +503,28 @@
        }
        count = 1;
      } else {
        if (!this.formData.fcheckResu) {
          this.formData.fcheckResu = 1
          this.formData.fcheckResu = 'OK';  // 默认合格
        }
        if (this.formData.fcheckResu == 0 || this.formData.fcheckResu == 1) {
          this.formData.isPass = this.formData.fcheckResu
        // 统一使用 OK/NG
        const upperValue = String(this.formData.fcheckResu).toUpperCase();
        if (upperValue === 'OK' || upperValue === 'NG') {
          this.formData.fcheckResu = upperValue;  // 统一转为大写
          if (upperValue === 'NG') {
            fstand = "×";
          }
        } else {
          this.$showMessage("无标准值时,检验结果只能为0或1!");
          this.$showMessage("无上下限时,检验结果只能为OK或NG!");
          return;
        }
        count = count - this.tableData.length;
      }
      // 验证不合格检验项目必须上传图片并填写不良描述
      if (fstand === "×" || this.formData.fcheckResu == 0) {
      if (fstand === "×" || this.formData.fcheckResu === 'NG') {
        // 检查是否已上传图片
        if (!this.formData.imageData || this.formData.imageData.length === 0) {
        if (!this.imageList || this.imageList.length === 0) {
          this.$showMessage("检验项目不合格,必须上传图片!");
          return;
        }
@@ -531,12 +566,27 @@
        this.tableData = res.data.tbBillList.itemXj02s;
        // 处理图片显示状态
        if (this.formData.imageData && this.formData.imageData.length > 0) {
        // 处理多图片列表
        if (this.formData.imageList && this.formData.imageList.length > 0) {
          this.imageList = this.formData.imageList;
          this.isShowImg = true;
          // 保持向后兼容
          if (this.imageList.length > 0) {
            this.base64Image = 'data:image/jpeg;base64,' + this.imageList[0].base64Data;
          }
        } else if (this.formData.imageData && this.formData.imageData.length > 0) {
          // 向后兼容:如果只有单张图片数据
          this.imageList = [{
            id: 0,
            base64Data: this.formData.imageData,
            fileName: '',
            createDate: null,
            createBy: ''
          }];
          this.isShowImg = true;
          this.base64Image = 'data:image/jpeg;base64,' + this.formData.imageData;
        } else {
          // 如果没有图片数据,隐藏图片显示区域
          this.imageList = [];
          this.isShowImg = false;
          this.base64Image = '';
        }
@@ -578,25 +628,27 @@
          fstand = "×";
        }
      } else {
        if (!this.editData.fcheckResu) {
          this.editData.fcheckResu = 1
          this.editData.fcheckResu = 'OK';  // 默认合格
        }
        if (this.editData.fcheckResu == 0 || this.editData.fcheckResu == 1) {
          if (this.editData.fcheckResu == 0) {
        // 统一使用 OK/NG
        const upperValue = String(this.editData.fcheckResu).toUpperCase();
        if (upperValue === 'OK' || upperValue === 'NG') {
          this.editData.fcheckResu = upperValue;  // 统一转为大写
          if (upperValue === 'NG') {
            fstand = "×";
          }
        } else {
          this.$showMessage("无标准值时,检验结果只能为0或1!");
          this.$showMessage("无上下限时,检验结果只能为OK或NG!");
          return;
        }
      }
      // 验证不合格检验项目必须上传图片并填写不良描述
      if (fstand === "×" || this.editData.fcheckResu == 0) {
      if (fstand === "×" || this.editData.fcheckResu === 'NG') {
        // 检查是否已上传图片
        if (!this.formData.imageData || this.formData.imageData.length === 0) {
        if (!this.imageList || this.imageList.length === 0) {
          this.$showMessage("检验项目不合格,必须上传图片!");
          return;
        }
@@ -629,17 +681,18 @@
    numberEdit(item) {
      let fstand = "√";
      let fcheckResu = 1;
      let fcheckResu = 'OK';  // 合格用OK
      if (item.fcheckResu == '1') {
      // 判断当前是否为合格状态(OK 或 1 都表示合格)
      if (item.fcheckResu == '1' || item.fcheckResu == 'OK' || item.fcheckResu == 1) {
        fstand = "×";
        fcheckResu = 0;
        fcheckResu = 'NG';  // 不合格用NG
      }
      // 验证不合格检验项目必须上传图片并填写不良描述
      if (fstand === "×" || fcheckResu == 0) {
      if (fstand === "×" || fcheckResu == 'NG') {
        // 检查是否已上传图片
        if (!this.formData.imageData || this.formData.imageData.length === 0) {
        if (!this.imageList || this.imageList.length === 0) {
          this.$showMessage("检验项目不合格,必须上传图片!");
          return;
        }
@@ -942,20 +995,21 @@
      });
    },
    
    // 根据选择的来源选择图片
    // 根据选择的来源选择图片 - 支持多选
    chooseImageWithSource(sourceType) {
      uni.chooseImage({
        count: 1, // 最多选择1张图片
        sizeType: ['compressed', 'original'], // 提供压缩和原图选项
        count: 9, // 最多选择9张图片
        sizeType: ['compressed'], // 压缩图片
        sourceType: sourceType, // 根据用户选择设置来源
        success: (res) => {
          const tempFilePath = res.tempFilePaths[0];
          const tempFilePaths = res.tempFilePaths;
          
          // 如果是拍照,显示预览确认
          // 如果是拍照,直接上传(单张)
          if (sourceType.includes('camera')) {
            this.showImagePreview(tempFilePath);
            this.uploadImageToServer(tempFilePaths[0]);
          } else {
            this.uploadImageToServer(tempFilePath);
            // 相册选择,批量上传
            this.uploadMultipleImages(tempFilePaths);
          }
        },
        fail: (error) => {
@@ -969,6 +1023,69 @@
            icon: 'none'
          });
        }
      });
    },
    // 批量上传图片
    uploadMultipleImages(tempFilePaths) {
      if (!tempFilePaths || tempFilePaths.length === 0) {
        return;
      }
      uni.showLoading({
        title: `上传中(0/${tempFilePaths.length})...`
      });
      let successCount = 0;
      let failCount = 0;
      const total = tempFilePaths.length;
      // 使用 Promise.all 并行上传
      const uploadPromises = tempFilePaths.map((filePath, index) => {
        return new Promise((resolve) => {
          uni.uploadFile({
            url: this.$store.state.serverInfo.serverAPI + '/XJ/UploadImageToPicture',
            filePath: filePath,
            name: 'file',
            formData: {
              id: this.id.toString(),
              gid: this.gid.toString(),
              billNo: this.billNo,
              createBy: this.$loginInfo.account
            },
            success: (res) => {
              try {
                const result = JSON.parse(res.data);
                if (result.status === 0) {
                  successCount++;
                } else {
                  failCount++;
                }
              } catch (e) {
                failCount++;
              }
              uni.showLoading({
                title: `上传中(${successCount + failCount}/${total})...`
              });
              resolve();
            },
            fail: (err) => {
              failCount++;
              console.error('上传失败:', err);
              resolve();
            }
          });
        });
      });
      Promise.all(uploadPromises).then(() => {
        uni.hideLoading();
        if (failCount === 0) {
          this.$showMessage(`${successCount}张图片上传成功`);
        } else {
          this.$showMessage(`上传完成:成功${successCount}张,失败${failCount}张`);
        }
        this.refreshResult();
      });
    },
    
@@ -1073,39 +1190,36 @@
      });
    },
    
    // 从服务器删除图片
    deleteImageFromServer() {
    // 从服务器删除图片 - 支持删除单张或所有图片
    deleteImageFromServer(imageId = null) {
      uni.showLoading({
        title: '删除中...'
      });
      
      this.$post({
        url: "/XJ/DeleteImageFromPicture",
        data: {
          id: this.id // 当前检验项目ID
      const data = {
        id: this.id
      };
      // 如果传入了 imageId,则删除单张图片
      if (imageId !== null && imageId !== undefined && imageId !== 0) {
        data.imageId = imageId;
        }
      this.$post({
        url: '/XJ/DeleteImageFromPicture',
        data: data
      }).then(res => {
        uni.hideLoading();
        if (res.status === 0) {
          uni.showToast({
            title: '图片删除成功',
            icon: 'success'
          });
          // 刷新页面数据
          this.refreshResult();
          this.$showMessage('图片删除成功');
          this.refreshResult(); // 刷新页面数据
        } else {
          uni.showToast({
            title: res.message || '图片删除失败',
            icon: 'none'
          });
          this.$showMessage(res.message || '删除失败');
        }
      }).catch(error => {
      }).catch(err => {
        uni.hideLoading();
        console.error('删除图片失败:', error);
        uni.showToast({
          title: '图片删除失败',
          icon: 'none'
        });
        console.error('删除图片失败:', err);
        this.$showMessage('删除失败,请重试');
      });
    }
  },
@@ -2126,4 +2240,115 @@
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
/* 多图片列表样式 */
.image-list {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 10px 0;
}
.image-item {
  position: relative;
  width: calc(33.33% - 8px);
  min-width: 100px;
  max-width: 150px;
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 2px 12px rgba(0,0,0,0.08);
  transition: all 0.3s ease;
}
.image-item:hover {
  box-shadow: 0 4px 20px rgba(0,0,0,0.12);
  transform: translateY(-2px);
}
.image-item .image-preview {
  width: 100%;
  height: 100px;
  overflow: hidden;
  cursor: pointer;
  position: relative;
}
.image-item .preview-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.image-actions {
  padding: 8px 6px;
  text-align: center;
  background: linear-gradient(to bottom, #fafafa, #f5f5f5);
}
.image-actions .delete-image-btn {
  width: 100%;
  padding: 8px 12px;
  font-size: 13px;
  border-radius: 20px;
  background: linear-gradient(135deg, #ff6b6b 0%, #ee5a5a 100%);
  border: none;
  color: white;
  font-weight: 500;
  box-shadow: 0 2px 8px rgba(238, 90, 90, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  transition: all 0.2s ease;
}
.image-actions .delete-image-btn:active {
  transform: scale(0.95);
  box-shadow: 0 1px 4px rgba(238, 90, 90, 0.3);
}
.delete-icon {
  font-size: 14px;
  margin-right: 2px;
}
/* 移动端优化 */
@media (max-width: 480px) {
  .image-list {
    gap: 10px;
  }
  .image-item {
    width: calc(50% - 5px);
    min-width: 0;
    max-width: none;
    border-radius: 10px;
  }
  .image-item .image-preview {
    height: 90px;
  }
  .image-actions {
    padding: 6px 5px;
  }
  .image-actions .delete-image-btn {
    padding: 6px 10px;
    font-size: 12px;
    border-radius: 16px;
  }
}
@media (min-width: 768px) {
  .image-item {
    width: calc(25% - 9px);
    max-width: 160px;
  }
  .image-item .image-preview {
    height: 120px;
  }
}
</style>