111
啊鑫
5 天以前 2b0e70bb88ced210dbc693a4d2ded2d658b1da02
111
已添加1个文件
已修改5个文件
834 ■■■■ 文件已修改
pages/QC/Laboratory/ImageItem.vue 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/Laboratory/Laboratory.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/OQC/Add.vue 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/OQC/ImageItem.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/OQC/ScanCode.vue 269 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/QC/OQC/detail.vue 193 ●●●● 补丁 | 查看 | 原始文档 | 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
@@ -94,7 +94,8 @@
                <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">
@@ -108,16 +109,22 @@
                  
                  <!-- æ£€éªŒç»“果选择按钮 -->
                  <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>
@@ -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}`
      });
    }
  }
@@ -416,6 +433,26 @@
  }
}
.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
@@ -5,39 +5,39 @@
            <form :modelValue="formData">
                <view class="form-group">
                    <label class="form-label">检验单号:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.releaseNo" />
          <input v-model="formData.releaseNo" class="form-input" disabled="true" type="text"/>
                </view>
                <view class="form-group">
                    <label class="form-label">物料编码:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.itemNo" />
          <input v-model="formData.itemNo" class="form-input" disabled="true" type="text"/>
                </view>
                <view class="form-group">
                    <label class="form-label">物料名称:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.itemName" />
          <input v-model="formData.itemName" class="form-input" disabled="true" type="text"/>
                </view>
                <view class="form-group">
                    <label class="form-label">物料规格:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.itemModel" />
          <input v-model="formData.itemModel" class="form-input" disabled="true" type="text"/>
                </view>
                <view class="form-group">
                    <label class="form-label">订单编号:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.saleOrderNo" />
          <input v-model="formData.saleOrderNo" class="form-input" disabled="true" type="text"/>
                </view>
                <view class="form-group">
                    <label class="form-label">送检数量:</label>
                    <input class="form-input" disabled="true" type="number" v-model="formData.planQty" />
          <input v-model="formData.planQty" class="form-input" disabled="true" type="number"/>
                </view>
                <view class="form-group">
                    <label class="form-label">创建时间:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.createDate" />
          <input v-model="formData.createDate" class="form-input" disabled="true" type="text"/>
                </view>
                <view class="form-group">
                    <label class="form-label">创建人:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.createUser" />
          <input v-model="formData.createUser" class="form-input" disabled="true" type="text"/>
                </view>
                <view class="form-group">
                    <label class="form-label">不良描述:</label>
                    <input class="form-input" disabled="true" type="text" v-model="formData.remeke" />
          <input v-model="formData.remeke" class="form-input" disabled="true" type="text"/>
                </view>
            </form>
        </view>
@@ -50,27 +50,30 @@
                <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 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-indicator"
                        :class="{ 'status-pass': item.fcheckResu === '合格', 'status-fail': item.fcheckResu === '不合格', 'status-pending': item.fcheckResu === '未检验' }">
          <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="status-badge"
                                :class="{ 'badge-pass': item.fcheckResu === '合格', 'badge-fail': item.fcheckResu === '不合格', 'badge-pending': item.fcheckResu === '未检验' }">
                                <text class="status-icon">{{ item.fcheckResu === '合格' ? '✓' : item.fcheckResu === '不合格' ? '✗' : '○' }}</text>
              <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 class="item-description" v-if="item.fcheckItemDesc">
            <view v-if="item.fcheckItemDesc" class="item-description">
                            <text class="description-text">{{ item.fcheckItemDesc }}</text>
                        </view>
                        
@@ -78,16 +81,16 @@
                            <view class="progress-info">
                                <text class="progress-label">检验进度:</text>
                                <view class="progress-bar">
                                    <view class="progress-fill"
                  <view :class="{ 'progress-complete': item.fenterQty >= item.checkQyt, 'progress-incomplete': item.fenterQty < item.checkQyt }"
                                        :style="{ width: (item.fenterQty / item.checkQyt * 100) + '%' }"
                                        :class="{ 'progress-complete': item.fenterQty >= item.checkQyt, 'progress-incomplete': item.fenterQty < item.checkQyt }">
                        class="progress-fill">
                                    </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 }">
              <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>
@@ -114,7 +117,7 @@
        
        <!-- ä¸åˆæ ¼æè¿°å¼¹å‡ºå±‚ -->
        <view v-if="remarksPopup" class="overlay active">
          <view class="popup" :class="{ 'popup-scale': isPopupAnimated }" @animationend="isPopupAnimated = false">
      <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>
@@ -122,7 +125,7 @@
            <form>
              <view class="form-group">
                <label class="form-label">不合格描述:</label>
                <input class="form-input" type="text" v-model="remarks" />
            <input v-model="remarks" class="form-input" type="text"/>
              </view>
              <view class="button-group popup-buttons">
                <button :class="['action-btn', 'btn-danger']" @click="editRemarks">
@@ -195,7 +198,7 @@
            uploadImages() {
                // ä¸Šä¼ /查看图片的逻辑
                uni.navigateTo({
                    url: 'ImageItem?id=' + this.formData.releaseNo
        url: 'ImageItem?id=' + this.formData.id
                });
            },
            addDefectDescription() {
@@ -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%);
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'],
@@ -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,6 +225,7 @@
  max-height: calc(100vh - 240px); /* å±å¹•高度减去上传按钮高度 */
  overflow-y: auto; /* å½“内容超出高度时出现垂直滚动条 */
}
.upImg{
 
      background-color: #3498db;
pages/QC/OQC/ScanCode.vue
@@ -7,30 +7,30 @@
                    <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="输入后离开或按回车" />
              <input v-model="formData.ItemBarcode" class="form-input scan-input" placeholder="输入后离开或按回车"
                     type="text"
                     @confirm="addItemBarCode"/>
                            <view class="scan-button" @tap="startScan">
                                <uni-icons type="scan" size="24" color="#007bff"></uni-icons>
                <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 class="form-input" disabled="true" type="text" v-model="formData.itemName" />
            <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 class="form-input" disabled="true" type="text" v-model="formData.itemNo" />
            <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 class="form-input" disabled="true" type="text" v-model="formData.taskNo" />
            <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 class="form-input" disabled="true" type="text" v-model="quantity" />
            <input v-model="quantity" class="form-input" disabled="true" type="text"/>
                    </view>
                </view>
            </form>
@@ -46,7 +46,7 @@
            </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-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>
@@ -54,7 +54,7 @@
                            <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-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">
@@ -70,38 +70,25 @@
                                <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>
                <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="cell-content"> </view>
                <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 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="action-buttons-container button-group">
            <view class="plus-button" :class="{ 'submitting': isSubmitting }" @tap="handleSubmit">
      <view :class="{ 'submitting': isSubmitting }" class="plus-button" @tap="handleSubmit">
                <text>{{ isSubmitting ? '提交中...' : '生成OQC检验单' }}</text>
            </view>
        </view>
@@ -370,8 +357,8 @@
    .form-container {
      .form-grid {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 24rpx 16rpx;
    grid-template-columns: 1fr;
    gap: 24rpx;
      }
    
      .form-group {
@@ -474,10 +461,12 @@
        border-radius: 8rpx;
        overflow: hidden;
        border: 1rpx solid #dee2e6;
    display: flex;
      }
    
      .table-scroll {
        width: calc(100% - 80rpx); /* å‡åŽ»å›ºå®šåˆ—å®½åº¦ */
    flex: 1;
    overflow-x: auto;
        white-space: nowrap;
      }
    
@@ -492,7 +481,9 @@
            font-size: 26rpx;
            color: #495057;
            font-weight: 600;
            padding: 20rpx 12rpx;
        padding: 0 8rpx;
        height: 68rpx;
        line-height: 68rpx;
            background: transparent !important;
            border-right: 1rpx solid #dee2e6;
            white-space: nowrap;
@@ -516,11 +507,13 @@
          }
    
          .uni-td {
            padding: 16rpx 12rpx;
        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;
@@ -529,10 +522,13 @@
            .cell-content {
              font-size: 24rpx;
              color: #495057;
              line-height: 1.4;
          line-height: 68rpx;
              max-width: 100%;
              overflow: hidden;
              text-overflow: ellipsis;
          display: flex;
          align-items: center;
          height: 68rpx;
    
              &.quantity {
                font-weight: 600;
@@ -550,24 +546,26 @@
              font-size: 24rpx;
              color: #6c757d;
              font-weight: 500;
          line-height: 68rpx;
          display: flex;
          align-items: center;
          height: 68rpx;
            }
          }
        }
      }
    
      /* å³å›ºå®šæ‚¬æµ®åˆ é™¤åˆ— */
      .fixed-delete-column {
        position: absolute;
        top: 0;
        right: 0;
        width: 80rpx;
    flex-shrink: 0;
    width: 100rpx;
        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;
      height: 68rpx;
          background: linear-gradient(135deg, #f8f9fa, #e9ecef);
          display: flex;
          align-items: center;
@@ -583,7 +581,7 @@
    
        .fixed-content {
          .fixed-delete-item {
            height: 48rpx;
        height: 68rpx;
            display: flex;
            align-items: center;
            justify-content: center;
@@ -643,7 +641,9 @@
        max-width: 600rpx;
        height: 96rpx;
        background: linear-gradient(135deg, #007bff, #0056b3);
        border-radius: 48rpx;
    border-radius: 12rpx;
    border: 2rpx solid #007bff;
    cursor: pointer;
        display: flex;
        justify-content: center;
        align-items: center;
@@ -652,9 +652,21 @@
        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;
    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: "";
@@ -683,6 +695,15 @@
          &::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);
        }
      }
    }
@@ -742,4 +763,166 @@
      }
    }
/* æ‰‹æœºç«¯å“åº”式优化 */
@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
@@ -13,19 +13,19 @@
                    <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" />
              <input v-model="formData.fcheckItem" class="form-input" disabled="true" type="text"/>
                        </view>
                        <view class="form-group">
                            <label class="form-label">规格要求:</label>
                            <input class="form-input" disabled="true" type="text" v-model="formData.fspecRequ" />
              <input v-model="formData.fspecRequ" class="form-input" disabled="true" type="text"/>
                        </view>
                        <view class="form-group">
                            <label class="form-label">检验方法:</label>
                            <input class="form-input" disabled="true" type="text" v-model="formData.inspectionMethod" />
              <input v-model="formData.inspectionMethod" class="form-input" disabled="true" type="text"/>
                        </view>
                        <view class="form-group">
                            <label class="form-label">检验工具:</label>
                            <input class="form-input" disabled="true" type="text" v-model="formData.fcheckTool" />
              <input v-model="formData.fcheckTool" class="form-input" disabled="true" type="text"/>
                        </view>
                    </view>
                </view>
@@ -41,21 +41,21 @@
                            <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" />
                  <input v-model="formData.checkQyt" class="form-input" disabled="true" type="text"/>
                                </view>
                                <view class="form-group">
                                    <label class="form-label">检验标准编码:</label>
                                    <input class="form-input" disabled="true" type="text"
                                        v-model="formData.sampleSizeNo" />
                  <input v-model="formData.sampleSizeNo" class="form-input" disabled="true"
                         type="text"/>
                                </view>
                                <view class="form-group">
                                    <label class="form-label">检验水平:</label>
                                    <input class="form-input" disabled="true" type="text"
                                        v-model="formData.fcheckLevel" />
                  <input v-model="formData.fcheckLevel" class="form-input" disabled="true"
                         type="text"/>
                                </view>
                                <view class="form-group">
                                    <label class="form-label">接收水平:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.facLevel" />
                  <input v-model="formData.facLevel" class="form-input" disabled="true" type="text"/>
                                </view>
                            </view>
                        </view>
@@ -70,16 +70,16 @@
                            <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" />
                  <input v-model="formData.fdownAllow" class="form-input" disabled="true"
                         type="text"/>
                                </view>
                                <view class="form-group">
                                    <label class="form-label">标准值:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.fstand" />
                  <input v-model="formData.fstand" class="form-input" disabled="true" type="text"/>
                                </view>
                                <view class="form-group">
                                    <label class="form-label">上限:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.fupAllow" />
                  <input v-model="formData.fupAllow" class="form-input" disabled="true" type="text"/>
                                </view>
                            </view>
                        </view>
@@ -94,19 +94,19 @@
                            <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" />
                  <input v-model="formData.facQty" class="form-input" disabled="true" type="text"/>
                                </view>
                                <view class="form-group">
                                    <label class="form-label">RE数:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.freQty" />
                  <input v-model="formData.freQty" class="form-input" disabled="true" type="text"/>
                                </view>
                                <view class="form-group">
                                    <label class="form-label">不合格数:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.fngQty" />
                  <input v-model="formData.fngQty" class="form-input" disabled="true" type="text"/>
                                </view>
                                <view class="form-group">
                                    <label class="form-label">预览结果:</label>
                                    <input class="form-input" disabled="true" type="text" v-model="formData.fcheckResu" />
                  <input v-model="formData.fcheckResu" class="form-input" disabled="true" type="text"/>
                                </view>
                            </view>
                        </view>
@@ -130,7 +130,7 @@
                    <view class="form-grid">
                        <view class="form-group">
                            <label class="form-label">检测结果:</label>
                            <input class="form-input" type="number" v-model="fcheckResuK" />
              <input v-model="fcheckResuK" class="form-input" type="number"/>
                        </view>
                        <!-- æç¤ºè¯ä½œä¸ºæ£€æµ‹ç»“果的提示 -->
@@ -144,8 +144,8 @@
                    </view>
                </view>
                <button :class="['action-btn', 'btn-primary', { 'btn-loading': isLoading }]"
                    v-if="tableData.length < formData.checkQyt" @click="submit" :disabled="isLoading">
        <button v-if="tableData.length < formData.checkQyt"
                :class="['action-btn', 'btn-primary', { 'btn-loading': isLoading }]" :disabled="isLoading" @click="submit">
                    {{ isLoading ? '保存中...' : '保存' }}
                </button>
            </view>
@@ -160,34 +160,34 @@
            <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-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="table-row"
                        :class="{ 'hover-effect': isHoveringRow === index }" @mouseenter="isHoveringRow = index"
          <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 class="form-input" disabled="true" type="text" v-model="item.fstand" />
              <input v-model="item.fstand" class="form-input" disabled="true" type="text"/>
                        </uni-td>
                        <uni-td align="center">
                            <span class="result-badge"
                                :class="{ 'pass': item.fcheckResu === 'OK', 'fail': item.fcheckResu === 'NG' }">
                            <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">
                <button v-if="isNumber"
                        :class="['action-btn', 'btn-sm', 'btn-warn', { 'btn-disabled': isLoading }]" :disabled="isLoading" @click="toDetail(item)">
                                    {{ isLoading ? '处理中...' : '修改' }}
                                </button>
                                <button :class="['action-btn', 'btn-sm', 'btn-warn', { 'btn-disabled': isLoading }]"
                                    v-if="!isNumber" @click="numberEdit(item)" :disabled="isLoading">
                <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>
@@ -200,8 +200,8 @@
        <!-- æ“ä½œæŒ‰é’® -->
        <view class="action-buttons">
            <view class="button-group">
                <button :class="['action-btn', 'btn-warn', { 'btn-disabled': isLoading }]" @click="saveRemarks"
                    :disabled="isLoading">
        <button :class="['action-btn', 'btn-warn', { 'btn-disabled': isLoading }]" :disabled="isLoading"
                @click="saveRemarks">
                    {{ isLoading ? '处理中...' : '添加不合格描述' }}
                </button>
            </view>
@@ -209,7 +209,7 @@
        <!-- ä¿®æ”¹æ£€éªŒç»“果弹出层 -->
        <view v-if="showPopup" class="overlay active">
            <view class="popup" :class="{ 'popup-scale': isPopupAnimated }" @animationend="isPopupAnimated = false">
      <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>
@@ -217,11 +217,11 @@
                <form :modelValue="editData">
                    <view class="form-group">
                        <label class="form-label">检验结果:</label>
                        <input class="form-input" type="text" v-model="editData.fcheckResu" />
            <input v-model="editData.fcheckResu" class="form-input" type="text"/>
                    </view>
                    <view class="button-group">
                        <button :class="['action-btn', 'btn-warn', { 'btn-loading': isEditLoading }]" @click="eidt"
                            :disabled="isEditLoading">
            <button :class="['action-btn', 'btn-warn', { 'btn-loading': isEditLoading }]" :disabled="isEditLoading"
                    @click="eidt">
                            {{ isEditLoading ? '修改中...' : '修改' }}
                        </button>
                        <button @click="showPopup = !showPopup">
@@ -234,7 +234,7 @@
        <!-- ä¿®æ”¹ä¸åˆæ ¼æè¿°å¼¹å‡ºå±‚ -->
        <view v-if="remarksPopup" class="overlay active">
            <view class="popup" :class="{ 'popup-scale': isPopupAnimated }" @animationend="isPopupAnimated = false">
      <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>
@@ -242,11 +242,11 @@
                <form>
                    <view class="form-group">
                        <label class="form-label">不合格描述:</label>
                        <input class="form-input" type="text" v-model="remarks" />
            <input v-model="remarks" class="form-input" type="text"/>
                    </view>
                    <view class="button-group">
                        <button :class="['action-btn', 'btn-warn', { 'btn-loading': isRemarksLoading }]"
                            @click="editRemarks" :disabled="isRemarksLoading">
                    :disabled="isRemarksLoading" @click="editRemarks">
                            {{ isRemarksLoading ? '保存中...' : '修改' }}
                        </button>
                        <button @click="remarksPopup = !remarksPopup">
@@ -825,4 +825,111 @@
        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>