leiqunqing
2026-03-05 891207469b41c23d22805876a4e179d75832572f
完整项目更新
已添加6个文件
已修改31个文件
2560 ■■■■■ 文件已修改
代码管理/WIDESEAWCS_Client/config/buttons.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Client/src/assets/test.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Client/src/components/basic/VolUpload.vue 234 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Client/src/extension/basicinfo/extend/formulaExecuteDetail.vue 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Client/src/extension/basicinfo/extend/taskExecuteDetail.vue 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Client/src/extension/basicinfo/formula.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Client/src/extension/basicinfo/processInfo.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Client/src/extension/basicinfo/scanStation.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Client/src/views/Home.vue 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Client/src/views/basicinfo/formula.vue 420 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Client/src/views/basicinfo/processInfo.vue 439 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Client/src/views/basicinfo/processInfoDetail.vue 334 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.794.21998/CodeChunks.db 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.794.21998/SemanticSymbols.db 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/DesignTimeBuild/.dtbcache.v2 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v17/.futdcache.v2 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v17/.suo 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/BoxingDetailService.cs 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/BoxingService.cs 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/ScanStationService.cs 101 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Common/PLCEnum/W_PLCDBName.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Common/Spire.XLS.dll 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_IBasicInfoService/IBoxingService.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_IBasicInfoService/IScanStationService.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/BasicInfo/Dt_Formula.cs 100 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/BasicInfo/Dt_FormulaDetail.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/BasicInfo/Dt_ProcessInfo.cs 69 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/BasicInfo/Dt_ProcessInfoDetail.cs 67 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/BasicInfo/Dt_ScanStation.cs 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/BasicInfo/BoxingController.cs 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/BasicInfo/BoxingDetailController.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/BasicInfo/ScanStationController.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/obj/Debug/net6.0/WIDESEAWCS_TaskInfoService.AssemblyInfo.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/obj/Debug/net6.0/WIDESEAWCS_TaskInfoService.AssemblyInfoInputs.cache 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Tasks/PLCJob.cs 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目资料/发电机弹性支撑BOM结构及工艺参数.pdf 补丁 | 查看 | 原始文档 | blame | 历史
项目资料/发电机弹性支撑信息化流程卡-注释.pdf 补丁 | 查看 | 原始文档 | blame | 历史
´úÂë¹ÜÀí/WIDESEAWCS_Client/config/buttons.js
@@ -136,6 +136,15 @@
    onClick: function () {
        this.export();
    }
},
{
    name: "导出流程卡",
    icon: 'el-icon-bottom',
    type: 'success',
    plain: true,
    value: 'ExportProcessCard',
    onClick: function () {
    }
}
]
´úÂë¹ÜÀí/WIDESEAWCS_Client/src/assets/test.png
´úÂë¹ÜÀí/WIDESEAWCS_Client/src/components/basic/VolUpload.vue
@@ -40,9 +40,7 @@
            </div>
          </div>
        </div>
        <el-button v-else @click="handleClick"
          >选择{{ img ? '图片' : '文件' }}</el-button
        >
        <el-button v-else @click="handleClick">选择{{ img ? "图片" : "文件" }}</el-button>
        <el-button
          v-if="!autoUpload && !img"
@@ -83,7 +81,7 @@
  </div>
</template>
<script>
let OSS = require('ali-oss');
let OSS = require("ali-oss");
export default {
  components: {},
  props: {
@@ -91,62 +89,62 @@
      //是否显示默认介绍
      //是否多选
      type: Boolean,
      default: false
      default: false,
    },
    fileInfo: {
      //用于接收上传的文件,也可以加以默认值,显示已上传的文件,用户上传后会覆盖默认值
      type: Array,
      default: () => {
        return [];
      } //格式[{name:'1.jpg',path:'127.0.01/1.jpg'}]
      }, //格式[{name:'1.jpg',path:'127.0.01/1.jpg'}]
    },
    downLoad: {
      //是否可以点击文件下载
      type: Boolean,
      default: true
      default: true,
    },
    multiple: {
      //是否多选
      type: Boolean,
      default: false
      default: false,
    },
    maxFile: {
      //最多可选文件数量,必须multiple=true,才会生效
      type: Number,
      default: 5
      default: 5,
    },
    maxSize: {
      //文件限制大小3M
      type: Number,
      default: 50
      default: 50,
    },
    autoUpload: {
      //选择文件后是否自动上传
      type: Boolean,
      default: true
      default: true,
    },
    img: {
      //图片类型  img>excel>fileTypes三种文件类型优先级
      type: Boolean,
      default: false
      default: false,
    },
    excel: {
      //excel文件
      type: Boolean,
      default: false
      default: false,
    },
    fileTypes: {
      //指定上传文件的类型
      type: Array,
      default: () => {
        return [];
      }
      },
    },
    url: {
      //上传的url
      type: String,
      default: ''
      default: "",
    },
    uploadBefore: {
      //返回false会中止执行
@@ -154,7 +152,7 @@
      type: Function,
      default: (files) => {
        return true;
      }
      },
    },
    uploadAfter: {
      //返回false会中止执行
@@ -162,14 +160,14 @@
      type: Function,
      default: (result, files) => {
        return true;
      }
      },
    },
    onChange: {
      //选择文件时  //返回false会中止执行
      type: Function,
      default: (files) => {
        return true;
      }
      },
    },
    // clear: {
    //   //上传完成后是否清空文件列表
@@ -179,48 +177,48 @@
    fileList: {
      //是否显示选择的文件列表
      type: Boolean,
      default: true
      default: true,
    },
    fileClick: {
      //点击文件事件
      type: Function,
      default: (index, file, files) => {
        return true;
      }
      },
    },
    removeBefore: {
      //移除文件事件
      type: Function,
      default: (index, file, files) => {
        return true;
      }
      },
    },
    append: {
      //此属性已废弃,多文件上传,默认追加文件
      type: Boolean,
      default: false
      default: false,
    },
    compress: {
      //开启图片压缩,后面根据需要再完善
      type: Boolean,
      default: true
      default: true,
    },
    compressMinSize: {
      //压缩的最小比例
      type: Number,
      default: 0.1
    }
      default: 0.1,
    },
  },
  data() {
    return {
      errorImg: 'this.src="' + require('@/assets/imgs/error-img.png') + '"',
      errorImg: 'this.src="' + require("@/assets/imgs/error-img.png") + '"',
      changed: false, //手动上传成功后禁止重复上传,必须重新选择
      model: true,
      files: [],
      bigImg: '',
      imgTypes: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp', 'jfif'],
      bigImg: "",
      imgTypes: ["gif", "jpg", "jpeg", "png", "bmp", "webp", "jfif"],
      loadingStatus: false,
      loadText: '上传文件'
      loadText: "上传文件",
    };
  },
  created() {
@@ -235,23 +233,23 @@
      handler(files) {
        this.cloneFile(files);
      },
      deep: true
    }
      deep: true,
    },
  },
  methods: {
    cloneFile(files) {
      this.files = files.map((x) => {
        return {
          name: x.name || this.getFileName(x.path),
          path: x.path
          path: x.path,
        };
      });
    },
    getFileName(path) {
      if (!path) {
        return '未定义文件名';
        return "未定义文件名";
      }
      let _index = path.lastIndexOf('/');
      let _index = path.lastIndexOf("/");
      return path.substring(_index + 1);
    },
    previewImg(index) {
@@ -261,20 +259,20 @@
    },
    getSelector() {
      if (this.autoUpload) {
        return 'auto-selector';
        return "auto-selector";
      }
      return 'submit-selector';
      return "submit-selector";
    },
    getImgSrc(file, index) {
      if (file.hasOwnProperty('path')) {
      if (file.hasOwnProperty("path")) {
        if (this.base.isUrl(file.path)) {
          return file.path;
        }
        //2020.12.27增加base64图片操作
        if (file.path.indexOf('/9j/') != -1) {
          return 'data:image/jpeg;base64,' + file.path;
        if (file.path.indexOf("/9j/") != -1) {
          return "data:image/jpeg;base64," + file.path;
        }
        if (file.path.substr(0, 1) == '/') {
        if (file.path.substr(0, 1) == "/") {
          file.path = file.path.substr(1);
        }
        return this.http.ipAddress + file.path;
@@ -290,23 +288,23 @@
        return;
      }
      if (!file.path) {
        this.$message.error('请先上传文件');
        this.$message.error("请先上传文件");
        return;
      }
      this.base.dowloadFile(
        file.path,
        file.name,
        {
          Authorization: this.$store.getters.getToken()
          Authorization: this.$store.getters.getToken(),
        },
        this.http.ipAddress
      );
    },
    getText() {
      if (this.img) {
        return '只能上传图片,';
        return "只能上传图片,";
      } else if (this.excel) {
        return '只能上传excel文件,';
        return "只能上传excel文件,";
      }
    },
    handleClick() {
@@ -360,9 +358,9 @@
      return this.files;
    },
    convertToFile(dataurl, filename) {
      let arr = dataurl.split(',');
      let arr = dataurl.split(",");
      let mime = arr[0].match(/:(.*?);/)[1];
      let suffix = mime.split('/')[1];
      let suffix = mime.split("/")[1];
      let bstr = atob(arr[1]);
      let n = bstr.length;
      let u8arr = new Uint8Array(n);
@@ -373,7 +371,7 @@
      // ç¬¬ä¸‰ä¸ªå‚数是 è¦æ”¾åˆ°æ–‡ä»¶ä¸­çš„内容的 MIME ç±»åž‹
      return new File([u8arr], `${filename}.${suffix}`, {
        type: mime,
        input: true
        input: true,
      });
    },
    async compressImg(file) {
@@ -389,10 +387,10 @@
            //默认按比例压缩
            let w = this.width;
            let h = this.height;
            let canvas = document.createElement('canvas');
            let ctx = canvas.getContext('2d');
            canvas.setAttribute('width', w);
            canvas.setAttribute('height', h);
            let canvas = document.createElement("canvas");
            let ctx = canvas.getContext("2d");
            canvas.setAttribute("width", w);
            canvas.setAttribute("height", h);
            ctx.drawImage(this, 0, 0, w, h);
            let rate = 0.3;
            if (fileSize > 2) {
@@ -404,14 +402,14 @@
              rate = _this.compressMinSize;
            }
            // rate=1;
            let base64 = canvas.toDataURL('image/jpeg', rate);
            let base64 = canvas.toDataURL("image/jpeg", rate);
            resolve(_this.convertToFile(base64, file.name));
          };
        };
      });
    },
    async uploadOSS() {
      this.http.get('api/alioss/getAccessToken', {}, false).then(async (x) => {
      this.http.get("api/alioss/getAccessToken", {}, false).then(async (x) => {
        if (!x.status) return this.$Message.error(x.message);
        let client = new OSS({
          // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
@@ -422,14 +420,14 @@
          // ä»ŽSTS服务获取的安全令牌(SecurityToken)。
          stsToken: x.data.securityToken,
          // å¡«å†™Bucket名称。
          bucket: x.data.bucket
          bucket: x.data.bucket,
        });
        console.log(this.files);
        for (let index = 0; index < this.files.length; index++) {
          const file = this.files[index];
          if (file.input) {
            let result = await client.put(
              x.data.bucketFolder + '/' + x.data.unique + file.name,
              x.data.bucketFolder + "/" + x.data.unique + file.name,
              file
            );
            file.path = result.url;
@@ -442,7 +440,7 @@
        let _files = this.files.map((file) => {
          return {
            name: file.newName || file.name,
            path: file.path
            path: file.path,
          };
        });
        this.fileInfo.push(..._files);
@@ -454,10 +452,10 @@
    async upload(vail) {
      if (vail && !this.checkFile()) return false;
      if (!this.url) {
        return this.$message.error('没有配置好Url');
        return this.$message.error("没有配置好Url");
      }
      if (!this.files || this.files.length == 0) {
        return this.$message.error('请选择文件');
        return this.$message.error("请选择文件");
      }
      //增加上传时自定义参数,后台使用获取Utilities.HttpContext.Current.Request.Query["字段"]
      let params={};
@@ -469,26 +467,26 @@
        paramText="?1=1";
        for (const key in params) {
          let value=params[key];
          if(typeof(value)=='object'){
            value=JSON.stringify(value)
          if (typeof value == "object") {
            value = JSON.stringify(value);
          }
          paramText+=`&${key}=${value}`
          paramText += `&${key}=${value}`;
        }
      }
      this.loadingStatus = true;
      this.loadText = '上传中..';
      this.loadText = "上传中..";
      if (window.oss && window.oss.ali.use) {
        await this.uploadOSS();
        this.loadingStatus = false;
        this.loadText = '上传文件';
        this.loadText = "上传文件";
        if (!this.uploadAfter({status:true}, this.files)) {
          this.changed = false;
          return;
        } else {
          this.changed = true;
        }
        this.$message.success('上传成功');
        this.$message.success("上传成功");
        return;
      }
@@ -496,32 +494,32 @@
      for (let index = 0; index < this.files.length; index++) {
        let file = this.files[index];
        if (file.input) {
          let name = file.name.split('.');
          let name = file.name.split(".");
          name = name[name.length - 1].toLocaleLowerCase();
          let isImg = this.imgTypes.indexOf(name) != -1;
          if (isImg && (name == 'jpg' || name == 'jpeg')) {
          if (isImg && (name == "jpg" || name == "jpeg")) {
            //>200KB的开启压缩
            if (isImg && file.size / 1024 / 1024 > 0.2) {
              console.log('压缩前' + file.size);
              console.log("压缩前" + file.size);
              file = await this.compressImg(file);
              file.compress = true;
              this.files[index] = file;
              this.files[index].input = true;
              console.log('压缩后' + file.size);
              console.log("压缩后" + file.size);
            }
          }
          forms.append('fileInput', file, file.name);
          forms.append("fileInput", file, file.name);
        }
      }
      // forms.append("fileInput", this.files);
      this.http
        .post(this.url+paramText, forms, this.autoUpload ? '正在上传文件' : '')
        .post(this.url + paramText, forms, this.autoUpload ? "正在上传文件" : "")
        .then(
          (x) => {
            // this.$refs.uploadFile.clearFiles();
            this.loadingStatus = false;
            this.loadText = '上传文件';
            this.loadText = "上传文件";
            if (!this.uploadAfter(x, this.files)) {
              this.changed = false;
              return;
@@ -541,7 +539,7 @@
            let _files = this.files.map((file) => {
              return {
                name: file.name,
                path: file.path || x.data + file.name
                path: file.path || x.data + file.name,
              };
            });
            this.fileInfo.push(..._files);
@@ -549,18 +547,14 @@
            this.files = _files;
          },
          (error) => {
            this.loadText = '上传文件';
            this.loadText = "上传文件";
            this.loadingStatus = false;
          }
        );
    },
    format(file, checkFileType) {
      const format =
        file.name
          .split('.')
          .pop()
          .toLocaleLowerCase() || '';
      let fileIcon = 'el-icon-document';
      const format = file.name.split(".").pop().toLocaleLowerCase() || "";
      let fileIcon = "el-icon-document";
      if (this.fileTypes.length > 0 && checkFileType != undefined) {
        if (this.fileTypes.indexOf(format) != -1) {
          return true;
@@ -570,8 +564,8 @@
      if (
        checkFileType &&
        !(checkFileType instanceof Array) &&
        checkFileType != 'img' &&
        checkFileType != 'excel'
        checkFileType != "img" &&
        checkFileType != "excel"
      ) {
        if (checkFileType.indexOf(format) > -1) {
          return true;
@@ -580,41 +574,39 @@
        }
      }
      if (checkFileType == 'img' || this.imgTypes.indexOf(format) > -1) {
        if (checkFileType == 'img') {
      if (checkFileType == "img" || this.imgTypes.indexOf(format) > -1) {
        if (checkFileType == "img") {
          if (this.imgTypes.indexOf(format) > -1) {
            return true;
          } else {
            return false;
          }
        }
        fileIcon = 'el-icon-picture-outline';
        fileIcon = "el-icon-picture-outline";
      }
      if (
        ['mp4', 'm3u8', 'rmvb', 'avi', 'swf', '3gp', 'mkv', 'flv'].indexOf(
          format
        ) > -1
        ["mp4", "m3u8", "rmvb", "avi", "swf", "3gp", "mkv", "flv"].indexOf(format) > -1
      ) {
        fileIcon = 'el-icon-document';
        fileIcon = "el-icon-document";
      }
      if (['mp3', 'wav', 'wma', 'ogg', 'aac', 'flac'].indexOf(format) > -1) {
        fileIcon = 'el-icon-document';
      if (["mp3", "wav", "wma", "ogg", "aac", "flac"].indexOf(format) > -1) {
        fileIcon = "el-icon-document";
      }
      if (['doc', 'txt', 'docx', 'pages', 'epub', 'pdf'].indexOf(format) > -1) {
        fileIcon = 'el-icon-document';
      if (["doc", "txt", "docx", "pages", "epub", "pdf"].indexOf(format) > -1) {
        fileIcon = "el-icon-document";
      }
      if (
        checkFileType == 'excel' ||
        ['numbers', 'csv', 'xls', 'xlsx'].indexOf(format) > -1
        checkFileType == "excel" ||
        ["numbers", "csv", "xls", "xlsx"].indexOf(format) > -1
      ) {
        if (checkFileType == 'excel') {
          if (['numbers', 'csv', 'xls', 'xlsx'].indexOf(format) > -1) {
        if (checkFileType == "excel") {
          if (["numbers", "csv", "xls", "xlsx"].indexOf(format) > -1) {
            return true;
          } else {
            return false;
          }
        }
        fileIcon = 'el-icon-document';
        fileIcon = "el-icon-document";
      }
      return fileIcon;
    },
@@ -627,11 +619,11 @@
        files.length + (inputFiles || []).length > (this.maxFile || 5)
      ) {
        this.$message.error(
          '最多只能选【' +
          "最多只能选【" +
            (this.maxFile || 5) +
            '】' +
            (this.img ? '张图片' : '个文件') +
            ''
            "】" +
            (this.img ? "张图片" : "个文件") +
            ""
        );
        return false;
      }
@@ -644,15 +636,15 @@
      for (let index = 0; index < inputFiles.length; index++) {
        const file = inputFiles[index];
        if (names.indexOf(file.name) != -1) {
          file.name = '(' + index + ')' + file.name;
          file.name = "(" + index + ")" + file.name;
        }
        names.push(file.name);
        if (this.img && !this.format(file, 'img')) {
          this.$message.error('选择的文件【' + file.name + '】只能是图片格式');
        if (this.img && !this.format(file, "img")) {
          this.$message.error("选择的文件【" + file.name + "】只能是图片格式");
          return false;
        }
        if (this.excel && !this.format(file, 'excel')) {
          this.$message.error('选择的文件【' + file.name + '】只能是excel文件');
        if (this.excel && !this.format(file, "excel")) {
          this.$message.error("选择的文件【" + file.name + "】只能是excel文件");
          return false;
        }
        if (
@@ -661,28 +653,24 @@
          !this.format(file, this.fileTypes)
        ) {
          this.$message.error(
            '选择的文件【' +
            "选择的文件【" +
              file.name +
              '】只能是【' +
              this.fileTypes.join(',') +
              '】格式'
              "】只能是【" +
              this.fileTypes.join(",") +
              "】格式"
          );
          return false;
        }
        if (file.size > (this.maxSize || 50) * 1024 * 1024) {
          this.$message.error(
            '选择的文件【' +
              file.name +
              '】不能超过:' +
              (this.maxSize || 50) +
              'M'
            "选择的文件【" + file.name + "】不能超过:" + (this.maxSize || 50) + "M"
          );
          return false;
        }
      }
      return true;
    }
  }
    },
  },
};
</script>
<style lang="less" scoped>
@@ -741,20 +729,26 @@
  .img-selector {
    position: relative;
    cursor: pointer;
    margin: 0 10px 10px 0;
    // margin: 0 10px 10px 0;
    margin: 0px;
    float: left;
    width: 65px;
    height: 65px;
    width: 365px;
    height: 365px;
    border: 1px solid #c7c7c7;
    overflow: hidden;
    border-radius: 5px;
    box-sizing: content-box;
    background-image: url("~@/assets/test.png");
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
    img {
      margin: 0;
      padding: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
      // background-image: url("@/assets/logo.png");
    }
    .operation {
´úÂë¹ÜÀí/WIDESEAWCS_Client/src/extension/basicinfo/extend/formulaExecuteDetail.vue
´úÂë¹ÜÀí/WIDESEAWCS_Client/src/extension/basicinfo/extend/taskExecuteDetail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,259 @@
<template>
  <div>
    <vol-box
      v-model="showDetialBox"
      :lazy="true"
      width="1200px"
      :padding="15"
      title="任务详情"
    >
      <el-row height="50">
        <el-col :span="24">
          <div class="grid-content right-text">
            <el-link type="primary" @click="switchView">切换视图</el-link>
          </div>
        </el-col>
      </el-row>
      <div :style="{ height: height }">
        <div v-if="viewType == 1">
          <el-row height="50">
            <el-col :span="8">
              <div
                class="grid-content content-text"
                style="font-weight: bold; font-size: 18px"
              >
                <span>任务编号:{{ row.taskNum }}</span>
              </div>
            </el-col>
            <el-col :span="8">
              <div
                class="grid-content content-text"
                style="font-weight: bold; font-size: 18px"
              >
                <span>托盘编号:{{ row.palletCode }}</span>
              </div>
            </el-col>
            <el-col :span="8">
              <div
                class="grid-content content-text"
                style="font-weight: bold; font-size: 18px"
              >
                <span>任务状态:{{ row.taskState }}</span>
              </div>
            </el-col>
          </el-row>
          <div style="height: 100px; margin-top: 3%">
            <el-steps :active="active" align-center finish-status="success">
              <el-step
                v-for="item in steps"
                :key="item.title"
                :title="item.title"
                :description="item.description"
              ></el-step>
            </el-steps>
          </div>
          <el-row height="50" v-show="previousShow || nextShow">
            <el-col :span="8">
              <div v-show="previousShow" class="grid-content content-text">
                <el-button type="danger" @click="previous"
                  >回滚到上一步</el-button
                >
              </div>
            </el-col>
            <el-col :span="8">
              <div v-show="recoveryShow" class="grid-content content-text">
                <el-button type="primary" @click="recovery">任务挂起恢复</el-button>
              </div>
            </el-col>
            <el-col :span="8">
              <div v-show="nextShow" class="grid-content content-text">
                <el-button type="warning" @click="next">跳转到下一步</el-button>
              </div>
            </el-col>
          </el-row>
        </div>
        <div v-else>
          <el-table
            :data="tableData"
            style="width: 100%"
            :row-class-name="tableRowClassName"
          >
            <el-table-column type="index" width="50"> </el-table-column>
            <el-table-column prop="taskNum" label="任务号" width="90">
            </el-table-column>
            <el-table-column prop="taskState" label="任务状态" width="90">
            </el-table-column>
            <el-table-column prop="currentAddress" label="当前位置" width="90">
            </el-table-column>
            <el-table-column prop="nextAddress" label="下一位置" width="90">
            </el-table-column>
            <el-table-column prop="isManual" label="是否人工操作" width="120">
            </el-table-column>
            <el-table-column prop="isNormal" label="是否正常" width="90">
            </el-table-column>
            <el-table-column prop="description" label="描述"> </el-table-column>
            <el-table-column prop="createDate" label="创建时间" width="180">
            </el-table-column>
            <el-table-column prop="remark" label="备注" width="180">
            </el-table-column>
          </el-table>
        </div>
      </div>
    </vol-box>
  </div>
</template>
<script>
import VolBox from "@/components/basic/VolBox.vue";
export default {
  components: { VolBox },
  data() {
    return {
      active: 0,
      showDetialBox: false,
      row: {},
      steps: [],
      viewType: 1,
      height: "200px",
      tableData: [],
      previousShow: false,
      nextShow: false,
      recoveryShow: true,
    };
  },
  methods: {
    open(row) {
      this.row = row;
      this.showDetialBox = true;
      if (this.viewType == 1) {
        this.getSteps();
      } else {
        this.getDetailDatas();
      }
      this.$emit("parentCall", ($vue) => {
        var previousButton = $vue.buttons.find((x) => x.value == "Previous");
        this.previousShow = previousButton != null;
        var nextButton = $vue.buttons.find((x) => x.value == "Next");
        this.nextShow = nextButton != null;
      });
    },
    getSteps() {
      this.http
        .post(
          "/api/TaskExecuteDetail/GetDetailInfo?taskNum=" + this.row.taskNum,
          {},
          true
        )
        .then((x) => {
          if (!x.status) return this.$message.error(x.message);
          this.steps = x.data.list;
          this.active = x.data.active;
        });
    },
    getDetailDatas() {
      this.http
        .post(
          "/api/TaskExecuteDetail/GetDetailDatas?taskNum=" + this.row.taskNum,
          {},
          true
        )
        .then((x) => {
          if (!x.status) return this.$message.error(x.message);
          this.tableData = x.data;
        });
    },
    previous() {
      this.http
        .post(
          "/api/Task/RollbackTaskStatusToLast?taskNum=" + this.row.taskNum,
          {},
          true
        )
        .then((x) => {
          if (!x.status) return this.$message.error(x.message);
          this.$message.success("操作成功");
          this.getSteps();
        });
    },
    recovery(){
      this.http
        .post(
          "/api/Task/TaskStatusRecovery?taskNum=" + this.row.taskNum,
          {},
          true
        )
        .then((x) => {
          if (!x.status) return this.$message.error(x.message);
          this.$message.success("操作成功");
          this.getSteps();
        });
    },
    next() {
      this.http
        .post(
          "/api/Task/UpdateTaskStatusToNext?taskNum=" + this.row.taskNum,
          {},
          true
        )
        .then((x) => {
          if (!x.status) return this.$message.error(x.message);
          this.$message.success("操作成功");
          this.getSteps();
        });
    },
    switchView() {
      this.viewType = this.viewType == 1 ? 2 : 1;
      if (this.viewType == 2) {
        this.height = "600px";
        this.getDetailDatas();
      } else {
        this.height = "200px";
      }
    },
    tableRowClassName({ row, rowIndex }) {
      if (!row.isNormal) {
        return "error-row";
      } else if (row.isManual) {
        return "warning-row";
      }
      return "success-row";
    },
  },
  created() {},
};
</script>
<style scoped>
.el-col {
  border-radius: 4px;
}
.grid-content {
  border-radius: 4px;
  min-height: 36px;
}
.content-text {
  display: flex;
  align-items: center;
  justify-content: center;
}
.right-text {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
</style>
<style>
.el-table .warning-row {
  background: #fcf1e2;
}
.el-table .success-row {
  background: #f0f9eb;
}
.el-table .error-row {
  background: #fde2e2;
}
</style>
´úÂë¹ÜÀí/WIDESEAWCS_Client/src/extension/basicinfo/formula.js
@@ -12,6 +12,7 @@
    buttons: [],//扩展的按钮
    methods: {//事件扩展
        onInit() {
        },
        onInited() {
        }
´úÂë¹ÜÀí/WIDESEAWCS_Client/src/extension/basicinfo/processInfo.js
@@ -14,6 +14,7 @@
    buttons: [],//扩展的按钮
    methods: {//事件扩展
        onInit() {
        },
        onInited() {
        }
´úÂë¹ÜÀí/WIDESEAWCS_Client/src/extension/basicinfo/scanStation.js
@@ -14,6 +14,18 @@
    buttons: [],//扩展的按钮
    methods: {//事件扩展
        onInit() {
    let ExportProcessCardBtn = this.buttons.find(x => x.value == 'ExportProcessCard');
      if (ExportProcessCardBtn) {
        ExportProcessCardBtn.onClick = function () {
          this.http
            .post("api/scanStation/ExportData", null, "数据处理中")
            .then((x) => {
              if (!x.status) return this.$message.error(x.message);
              this.$message.success("操作成功");
              this.refresh();
            });
        }
      }
        },
        onInited() {
        }
´úÂë¹ÜÀí/WIDESEAWCS_Client/src/views/Home.vue
@@ -34,6 +34,14 @@
              v-model="leftPartCodes[index]"
              disabled
            />
            <!-- æ–°å¢žï¼šä¾›æ–¹ä»£ç è¾“入框 -->
            <input
              type="text"
              class="input-box supplier-code-input"
              v-model="leftPartSupplierCodes[index]"
              disabled
              placeholder="供方代码"
            />
            <label class="checkbox-container">
              <input
                type="checkbox"
@@ -57,7 +65,14 @@
      <div class="right-top">
        <div class="form-row input-submit-row">
          <span class="label">录入框:</span>
          <input type="text" class="input-box" v-model="rightTopInput" />
          <!-- å…³é”®ä¿®æ”¹1:添加ref标识 -->
          <input
            ref="inputBoxRef"
            type="text"
            class="input-box"
            v-model="rightTopInput"
            @blur="handleInputBlur"
          />
          <button class="btn save-btn submit-input-btn" @click="saveData">
            <i class="icon icon-submit"></i>提交
          </button>
@@ -76,6 +91,14 @@
            />
            <button class="btn clear-btn" @click="clearFinishedProductCode">
              <i class="icon icon-clear"></i>清除
            </button>
            <!-- æ–°å¢žï¼šåˆ é™¤å½“前托盘按钮 -->
            <button
              class="btn delete-tray-btn"
              @click="deleteCurrentTray"
              :disabled="deleteLoading"
            >
              <i class="icon icon-delete"></i>删除当前托盘
            </button>
          </div>
          <div
@@ -101,7 +124,7 @@
</template>
<script>
import { ref, onMounted, onUnmounted, watch, computed } from "vue";
import { ref, onMounted, onUnmounted, watch, computed, nextTick } from "vue";
import axios from "axios";
export default {
@@ -111,12 +134,19 @@
    const finishedProductId = ref(""); // å·¦ä¾§æˆå“ID(接口返回)
    const rightTopInput = ref(""); // å³ä¾§æ ¸å¿ƒå½•入框
    const leftPartCodes = ref(Array(10).fill("")); // å·¦ä¾§é›¶ä»¶ç¼–号数组
    // æ–°å¢žï¼šå·¦ä¾§ä¾›æ–¹ä»£ç æ•°ç»„
    const leftPartSupplierCodes = ref(Array(10).fill(""));
    const rightPartCodes = ref(Array(10).fill("")); // å³ä¾§é›¶ä»¶ç¼–号数组
    const leftPartChecked = ref(Array(10).fill(false)); // å·¦ä¾§é›¶ä»¶å‹¾é€‰çŠ¶æ€
    const leftPartIds = ref(Array(10).fill("")); // å·¦ä¾§é›¶ä»¶ID(接口返回)
    const finishedProductCode = ref(""); // å³ä¾§æˆå“ç¼–号输入框
    const fillIndex = ref(-1); // å½•入框自动填充索引
    const checkLoading = ref(Array(10).fill(false)); // é›¶ä»¶å‹¾é€‰åŠ è½½é”
    // æ–°å¢žï¼šåˆ é™¤æ‰˜ç›˜åŠ è½½çŠ¶æ€
    const deleteLoading = ref(false);
    // å…³é”®ä¿®æ”¹2:定义录入框ref
    const inputBoxRef = ref(null);
    // ä¿¡å·ç¯ç›¸å…³
    const signalStates = ref([false, false, false, false, false]);
@@ -136,6 +166,17 @@
    const destroyDelayTime = 500; // å½•入框填充延迟500ms
    let autoSubmitDebounceTimer = null;
    let submitLock = ref(false); // æäº¤é”ï¼Œé˜²æ­¢é‡å¤æäº¤
    // å…³é”®ä¿®æ”¹3:封装聚焦方法
    const focusInputBox = () => {
      nextTick(() => {
        if (inputBoxRef.value) {
          inputBoxRef.value.focus();
          // å¯é€‰ï¼šé€‰ä¸­è¾“入框内容,方便直接覆盖输入
          // inputBoxRef.value.select();
        }
      });
    };
    // è®¡ç®—属性 - ç»Ÿè®¡æœ‰æ•ˆå‹¾é€‰/填充数量(过滤空值)
    const checkedCount = computed(() => {
@@ -162,6 +203,8 @@
            for (let i = 0; i < 10; i++) {
              leftPartCodes.value[i] = data.leftPartCodes[i] || "";
              leftPartIds.value[i] = data.leftPartIds?.[i] || "";
              // æ–°å¢žï¼šèµ‹å€¼ä¾›æ–¹ä»£ç 
              leftPartSupplierCodes.value[i] = data.leftPartSupplierCodes?.[i] || "";
            }
          }
          if (Array.isArray(data.leftPartChecked) && data.leftPartChecked.length >= 10) {
@@ -172,6 +215,9 @@
        }
      } catch (error) {
        console.error("获取左侧初始数据失败:", error);
      } finally {
        // æ•°æ®åŠ è½½å®ŒæˆåŽèšç„¦
        focusInputBox();
      }
    };
@@ -214,16 +260,19 @@
      if (!finishedProductId.value) {
        alert("成品ID不存在,无法更新零件扫码状态!");
        leftPartChecked.value[index] = !isChecked;
        focusInputBox(); // æç¤ºåŽèšç„¦
        return;
      }
      if (!partId) {
        alert(`零件${index + 1}数据库ID不存在,无法更新扫码状态!`);
        leftPartChecked.value[index] = !isChecked;
        focusInputBox(); // æç¤ºåŽèšç„¦
        return;
      }
      if (!partCode.trim()) {
        alert(`零件${index + 1}编号为空,无法更新扫码状态!`);
        leftPartChecked.value[index] = !isChecked;
        focusInputBox(); // æç¤ºåŽèšç„¦
        return;
      }
@@ -254,6 +303,7 @@
        checkLoading.value[index] = false;
        if (checkDebounceTimer) clearTimeout(checkDebounceTimer);
        checkDebounceTimer = null;
        focusInputBox(); // æ“ä½œå®ŒæˆåŽèšç„¦
      }
    };
@@ -271,12 +321,10 @@
          fillIndex.value++;
        } else {
          alert("成品编号和零件1-10已全部填充完成,无法继续录入!");
          rightTopInput.value = "";
          destroyDelayTimer = null;
          return;
        }
        rightTopInput.value = "";
        destroyDelayTimer = null;
        focusInputBox(); // å¡«å……完成后聚焦
      }, destroyDelayTime);
    };
@@ -289,9 +337,23 @@
      { immediate: false }
    );
    // å…³é”®ä¿®æ”¹4:失去焦点时重新聚焦
    const handleInputBlur = () => {
      // å»¶è¿Ÿä¸€ç‚¹æ‰§è¡Œï¼Œé¿å…å’Œå…¶ä»–操作冲突
      setTimeout(() => {
        focusInputBox();
      }, 50);
    };
    // å³ä¾§è¾“入框清除方法
    const clearRightPart = (index) => (rightPartCodes.value[index] = "");
    const clearFinishedProductCode = () => (finishedProductCode.value = "");
    const clearRightPart = (index) => {
      rightPartCodes.value[index] = "";
      focusInputBox(); // æ¸…除后聚焦
    };
    const clearFinishedProductCode = () => {
      finishedProductCode.value = "";
      focusInputBox(); // æ¸…除后聚焦
    };
    // æ ¸å¿ƒä¿®æ”¹ï¼šæ¢å¤æˆå“ç¼–号必填校验,未填写直接提示并终止提交
    const saveData = async () => {
@@ -299,6 +361,7 @@
      const productCode = finishedProductCode.value.trim();
      if (!productCode) {
        alert("请先填写成品编号,成品编号为必填项!");
        focusInputBox(); // æç¤ºåŽèšç„¦
        return;
      }
      // 2. æäº¤é”ï¼šé˜²æ­¢é‡å¤ç‚¹å‡»
@@ -328,10 +391,14 @@
          rightPartCodes.value = Array(10).fill("");
          rightTopInput.value = "";
          fillIndex.value = -1;
          const msg = resData.message;
          // æ ¸å¿ƒä¿®æ”¹ï¼šä»…当 msg ä¸æ˜¯ null æ—¶æ‰å¼¹å‡ºæç¤º
          if (msg !== null) {
            alert(msg);
          }
        } else {
          // ä¸šåŠ¡é”™è¯¯ï¼šç›´æŽ¥å±•ç¤ºåŽç«¯è¿”å›žçš„message(如物料错误、无配方)
          const errorMsg = resData.message || "提交失败,未知业务错误";
          alert(`提交失败:${errorMsg}`);
          alert(`${resData.message || "未知错误"}`);
        }
      } catch (error) {
        // 6. å¼‚常捕获:兼容后端未捕获异常(如PLC通讯异常、数组越界、500错误)
@@ -352,6 +419,7 @@
      } finally {
        // 7. é‡Šæ”¾æäº¤é”ï¼šæ— è®ºæˆåŠŸ/失败都要释放
        submitLock.value = false;
        focusInputBox(); // æäº¤å®ŒæˆåŽèšç„¦
      }
    };
@@ -372,6 +440,7 @@
        if (!hasProductCode) {
          console.log("⚠️ æˆå“ç¼–号未填写,跳过自动提交");
          autoSubmitDebounceTimer = null;
          focusInputBox(); // æ ¡éªŒåŽèšç„¦
          return;
        }
@@ -393,6 +462,61 @@
      }, 300); // 300ms防抖,避免输入频繁触发
    };
    // æ–°å¢žï¼šåˆ é™¤å½“前托盘方法
    const deleteCurrentTray = async () => {
      // ç¡®è®¤æ“ä½œï¼Œé˜²æ­¢è¯¯åˆ 
      if (!confirm("确认要删除当前托盘数据吗?此操作不可恢复!")) {
        focusInputBox();
        return;
      }
      // è®¾ç½®åŠ è½½çŠ¶æ€ï¼Œé˜²æ­¢é‡å¤ç‚¹å‡»
      deleteLoading.value = true;
      try {
        console.log("📤 è°ƒç”¨åˆ é™¤å½“前托盘接口:/api/boxing/DeleteCurrentTray");
        // è°ƒç”¨åˆ é™¤æŽ¥å£ï¼ˆæ ¹æ®å®žé™…需求选择GET/POST,这里默认用POST,若后端是GET可改为get)
        const response = await axios.post(
          "/api/boxing/DeleteCurrentTray",
          {}, // è‹¥æ— å‚数传空对象
          { timeout: 8000 }
        );
        const resData = response.data;
        console.log("📥 åˆ é™¤å½“前托盘接口返回:", resData);
        // é€‚配后端返回格式
        const isSuccess = resData.status === true || resData.Status === true;
        if (isSuccess) {
          // åˆ é™¤æˆåŠŸåŽæ¸…ç©ºå³ä¾§è¾“å…¥æ¡†
          finishedProductCode.value = "";
          rightPartCodes.value = Array(10).fill("");
          rightTopInput.value = "";
          fillIndex.value = -1;
          alert(resData.message || "当前托盘删除成功!");
        } else {
          alert(`删除失败:${resData.message || "未知错误"}`);
        }
      } catch (error) {
        // å¼‚常处理
        let errorMsg = "删除托盘请求异常!";
        if (error.code === "ECONNABORTED") {
          errorMsg = "删除请求超时!请稍后重试";
        } else if (error.response) {
          errorMsg = `服务器错误:${error.response.status} - ${error.response.statusText}`;
          console.error("❌ åˆ é™¤æ‰˜ç›˜æœåŠ¡å™¨é”™è¯¯è¯¦æƒ…ï¼š", error.response.data);
        } else if (error.request) {
          errorMsg = "网络异常!未收到后端响应,请检查接口地址和网络";
        } else {
          errorMsg = `请求错误:${error.message}`;
        }
        alert(errorMsg);
        console.error("❌ åˆ é™¤æ‰˜ç›˜æŽ¥å£å¼‚常详情:", error);
      } finally {
        // é‡Šæ”¾åŠ è½½çŠ¶æ€
        deleteLoading.value = false;
        focusInputBox(); // æ“ä½œå®ŒæˆåŽèšç„¦å½•入框
      }
    };
    // ç›‘听自动提交相关数据变化,触发校验
    watch([checkedCount, filledPartCount, finishedProductCode], () => checkAutoSubmit(), {
      deep: true,
@@ -403,8 +527,7 @@
    const detectFillIndex = () => {
      if (!finishedProductCode.value.trim()) {
        fillIndex.value = -1;
        return;
      }
      } else {
      for (let i = 0; i < 10; i++) {
        if (!rightPartCodes.value[i].trim()) {
          fillIndex.value = i;
@@ -412,6 +535,7 @@
        }
      }
      fillIndex.value = 10;
      }
    };
    // ç›‘听成品/零件输入,更新填充索引
@@ -425,6 +549,7 @@
      await fetchLeftInitialData();
      startPolling();
      detectFillIndex();
      focusInputBox(); // é¡µé¢æŒ‚载后立即聚焦
    });
    // ç”Ÿå‘½å‘¨æœŸï¼šå¸è½½æ—¶æ¸…除所有定时器/防抖,防止内存泄漏
@@ -440,16 +565,22 @@
      finishedProduct,
      rightTopInput,
      leftPartCodes,
      // æ–°å¢žï¼šæš´éœ²ä¾›æ–¹ä»£ç æ•°ç»„
      leftPartSupplierCodes,
      rightPartCodes,
      leftPartChecked,
      signalStates,
      signalLabels,
      finishedProductCode,
      checkLoading,
      deleteLoading, // æš´éœ²åˆ é™¤åŠ è½½çŠ¶æ€
      handlePartCheck,
      saveData,
      deleteCurrentTray, // æš´éœ²åˆ é™¤æ‰˜ç›˜æ–¹æ³•
      clearRightPart,
      clearFinishedProductCode,
      inputBoxRef, // æš´éœ²ref
      handleInputBlur, // æš´éœ²æ–¹æ³•
    };
  },
};
@@ -613,6 +744,11 @@
  transition: all 0.2s ease;
  background-color: #ffffff;
}
/* æ–°å¢žï¼šä¾›æ–¹ä»£ç è¾“入框样式(宽度稍窄) */
.supplier-code-input {
  flex: 0 0 150px;
  min-width: 120px;
}
.input-box:focus {
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.12);
@@ -645,6 +781,10 @@
  gap: 8px;
  position: relative;
  overflow: hidden;
}
/* æ–°å¢žï¼šåˆ é™¤æ‰˜ç›˜æŒ‰é’®å®½åº¦é€‚配 */
.delete-tray-btn {
  width: 140px !important;
}
.submit-input-btn {
  width: 110px !important;
@@ -692,6 +832,10 @@
.icon-submit {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M2.01 21L15 13.4 23 21V5H2.01V21zM17 15l-5-5-5 5V7h10v8z'/%3E%3C/svg%3E");
}
/* æ–°å¢žï¼šåˆ é™¤å›¾æ ‡ */
.icon-delete {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z'/%3E%3C/svg%3E");
}
/* æŒ‰é’®ä¸»é¢˜æ ·å¼ */
.clear-btn {
@@ -711,6 +855,16 @@
.save-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(59, 130, 246, 0.15);
}
/* æ–°å¢žï¼šåˆ é™¤æ‰˜ç›˜æŒ‰é’®æ ·å¼ */
.delete-tray-btn {
  background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
  color: #fff;
  padding: 0 12px;
}
.delete-tray-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(245, 158, 11, 0.15);
}
/* ä¿¡å·ç¯æ ·å¼ */
@@ -851,8 +1005,16 @@
  .input-box {
    width: 100%;
  }
  /* é€‚配移动端供方代码输入框 */
  .supplier-code-input {
    flex: 1;
    min-width: 100%;
    margin-top: 6px;
  }
  /* ç§»åŠ¨ç«¯æŒ‰é’®å®½åº¦é€‚é… */
  .btn,
  .submit-input-btn {
  .submit-input-btn,
  .delete-tray-btn {
    width: 100% !important;
    margin-top: 6px;
  }
´úÂë¹ÜÀí/WIDESEAWCS_Client/src/views/basicinfo/formula.vue
@@ -11,14 +11,43 @@
    :extend="extend"
  >
  </view-grid>
  <!-- å³ä¾§å›¾ç‰‡ä¾§è¾¹æ  - å¢žåŠ z-index层级 -->
  <div class="image-sidebar" :class="{ 'sidebar-open': isSidebarOpen }">
    <div class="sidebar-toggle" @click="toggleSidebar">
      <span>{{ isSidebarOpen ? ">" : "<" }}</span>
    </div>
    <div class="sidebar-content">
      <div class="image-container">
        <img :src="logoUrl" alt="参考图片" class="reference-image" />
        <div class="image-description">配方布局参考图</div>
      </div>
    </div>
  </div>
</template>
<script>
import extend from "@/extension/basicinfo/formula.js";
import { ref, defineComponent } from "vue";
import { ref, defineComponent, computed } from "vue";
export default defineComponent({
  setup() {
    const isSidebarOpen = ref(false);
    // å›¾ç‰‡è·¯å¾„
    const logoUrl = computed(() => {
      try {
        return require("@/assets/test.png");
      } catch (e) {
        console.log("使用相对路径加载图片");
        return "/assets/test.png";
      }
    });
    const toggleSidebar = () => {
      isSidebarOpen.value = !isSidebarOpen.value;
    };
    const table = ref({
      key: "id",
      footer: "Foots",
@@ -28,7 +57,7 @@
      sortName: "createDate",
    });
    // ç¼–辑表单字段 - æ–°å¢žpressFastenTorque(压装位紧固扭矩)
    // ç¼–辑表单字段 - å®Œå…¨åŒ¹é…åŽç«¯Dt_Formula实体类
    const editFormFields = ref({
      id: "",
      productCode: "",
@@ -37,173 +66,230 @@
      productWidth: "",
      productHeight: "",
      pressNoTighten: "",
      screwDownsetDistance: "",
      screwTorqueOutput: "",
      pressFastenTorque: "", // ã€æ–°å¢žã€‘压装位紧固扭矩
      pressNoCheckBottomPlate: "",
      screwDownsetDistance: "", // åŽç«¯æ³¨é‡Šä¸ºï¼šä¿åŽ‹åŽ‹åŠ›
      screwTorqueOutput: "", // åŽç«¯æ³¨é‡Šä¸ºï¼šä¸­å¿ƒé«˜åº¦
      dintAutoScrewOn: "",
      pressFastenTorque: "",
      p0P1Width: "",
      p0P2Width: "",
      p0P3Width: "",
      p1P3Height: "",
      p2P3Height: "",
      productImagePath: "",
      pressPressureDiff: "",
      pressTorqueDiff: "",
      detectHeightDiff: "",
      screwPositionDiff: "",
      // ç§»é™¤äº†centerHeight字段(后端无此字段,原前端配置错误映射)
    });
    // ç¼–辑表单配置-新增压装位紧固扭矩,布局适配原有紧凑性
    // ç¼–辑表单配置 - ä¿®æ­£å­—段中文名称和注释,匹配后端实体
    // é‡ç‚¹ï¼šä¸ºæ ¸å¿ƒå­—段补充必填配置(require: true)
    const editFormOptions = ref([
      // ç¬¬ä¸€è¡Œï¼šåŸºç¡€æ ‡è¯†
      [
        {
          title: "成品编号",
          required: true,
          field: "productCode",
          type: "input",
          type: "string",
          width: 200,
          require: true,
        },
        {
          title: "成品名称",
          field: "productName",
          type: "input",
          type: "string",
          width: 200,
          require: true,
          required: true,
        },
        {
          title: "拧紧程序号",
          field: "dintAutoScrewOn",
          type: "input",
          type: "string",
          inputType: "number",
          width: 180,
          placeholder: "请输入整数",
        },
        {
          title: "产品长度",
          field: "productLength",
          type: "input",
          inputType: "number",
          width: 120,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true,
        },
      ],
      [
        {
          title: "产品宽度",
          title: "产品长度", // ä¿®æ­£åŽç«¯æ³¨é‡Š
          field: "productLength",
          type: "string",
          inputType: "number",
          width: 100,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true,
        },
        {
          title: "产品宽度", // ä¿®æ­£åŽç«¯æ³¨é‡Š
          field: "productWidth",
          type: "input",
          type: "string",
          inputType: "number",
          width: 120,
          width: 100,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true,
        },
        {
          title: "产品高度",
          title: "产品高度", // ä¿®æ­£åŽç«¯æ³¨é‡Š
          field: "productHeight",
          type: "input",
          type: "string",
          inputType: "number",
          width: 120,
          width: 100,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true,
        },
      ],
      [
        {
          title: "压装位不拧紧",
          title: "不拧紧",
          field: "pressNoTighten",
          type: "select",
          width: 120,
          align: "center",
          defaultValue: "0",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          required: true, // æ–°å¢žï¼šå¼€å…³ç±»å­—段必填
        },
        {
          title: "不测底板",
          field: "pressNoCheckBottomPlate",
          type: "select",
          width: 120,
          align: "center",
          defaultValue: "0",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          required: true, // æ–°å¢žï¼šå¼€å…³ç±»å­—段必填
        },
        {
          title: "保压压力",
          field: "screwDownsetDistance",
          type: "input",
          inputType: "number",
          width: 150,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
        },
      ],
      [
        {
          title: "中心高度",
          field: "screwTorqueOutput",
          type: "input",
          type: "string",
          inputType: "number",
          width: 120,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true, // æ–°å¢žï¼šå·¥è‰ºå‚æ•°å¿…å¡«
        },
      ],
      [
        {
          title: "中心高度", // ä¿®æ­£å­—段中文名称(后端注释)
          field: "screwTorqueOutput",
          type: "string",
          inputType: "number",
          width: 120,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true, // æ–°å¢žï¼šå·¥è‰ºå‚æ•°å¿…å¡«
        },
        {
          title: "紧固扭矩",
          title: "紧固扭矩", // è¡¥å……完整字段名称
          field: "pressFastenTorque",
          type: "input",
          type: "string",
          inputType: "number",
          width: 150,
          width: 120,
          placeholder: "保留2位小数,默认0.00",
          attrs: { step: 0.01, min: 0 },
          required: true, // æ–°å¢žï¼šå·¥è‰ºå‚æ•°å¿…å¡«
        },
        {
          title: "P0P1宽度",
          field: "p0P1Width",
          type: "input",
          type: "string",
          inputType: "number",
          width: 120,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true, // æ–°å¢žï¼šå°ºå¯¸å‚æ•°å¿…å¡«
        },
      ],
      [
        {
          title: "P0P2宽度",
          field: "p0P2Width",
          type: "input",
          type: "string",
          inputType: "number",
          width: 120,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true, // æ–°å¢žï¼šå°ºå¯¸å‚æ•°å¿…å¡«
        },
      ],
      // ç¬¬å››è¡Œï¼šP系列高度 + äº§å“å›¾ç‰‡è·¯å¾„
      [
        {
          title: "P0P3宽度",
          field: "p0P3Width",
          type: "input",
          type: "string",
          inputType: "number",
          width: 120,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true, // æ–°å¢žï¼šå°ºå¯¸å‚æ•°å¿…å¡«
        },
        {
          title: "P1P3高度",
          field: "p1P3Height",
          type: "input",
          title: "压力差值",
          field: "pressPressureDiff",
          type: "string",
          inputType: "number",
          width: 150,
          width: 120,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true, // æ–°å¢žï¼šå·®å€¼å‚æ•°å¿…å¡«
        },
      ],
      [
        {
          title: "P2P3高度",
          field: "p2P3Height",
          type: "input",
          title: "扭力差值",
          field: "pressTorqueDiff",
          type: "string",
          inputType: "number",
          width: 150,
          width: 120,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true, // æ–°å¢žï¼šå·®å€¼å‚æ•°å¿…å¡«
        },
        {
          title: "产品图片路径",
          field: "productImagePath",
          type: "textarea",
          width: 400,
          rows: 2,
          placeholder: "请输入图片完整路径,支持500字符以内",
          title: "高度差值",
          field: "detectHeightDiff",
          type: "string",
          inputType: "number",
          width: 120,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true, // æ–°å¢žï¼šå·®å€¼å‚æ•°å¿…å¡«
        },
        {
          title: "螺纹差值",
          field: "screwPositionDiff",
          type: "string",
          inputType: "number",
          width: 120,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true, // æ–°å¢žï¼šå·®å€¼å‚æ•°å¿…å¡«
        },
      ],
      [
        {
          title: "垫片高度",
          field: "gasketHeight",
          type: "string",
          inputType: "number",
          width: 120,
          placeholder: "保留2位小数",
          attrs: { step: 0.01, min: 0 },
          required: true,
        },
      ],
    ]);
    // æœç´¢è¡¨å•字段 - æ— éœ€ä¿®æ”¹
    // æœç´¢è¡¨å•字段
    const searchFormFields = ref({
      productCode: "",
      productName: "",
@@ -211,7 +297,7 @@
      createDate: "",
    });
    // æœç´¢è¡¨å•配置 - æ— éœ€ä¿®æ”¹
    // æœç´¢è¡¨å•配置
    const searchFormOptions = ref([
      [
        { title: "成品编号", field: "productCode", type: "like", width: 200 },
@@ -223,14 +309,14 @@
      ],
    ]);
    // è¡¨æ ¼åˆ—配置 - æ–°å¢žåŽ‹è£…ä½ç´§å›ºæ‰­çŸ©åˆ—
    // è¡¨æ ¼åˆ—配置 - ä¿®æ­£å­—段中文名称和注释,匹配后端实体
    const columns = ref([
      {
        field: "id",
        title: "序号",
        title: "id",
        type: "int",
        width: 80,
        hidden: true,
        // hidden: true,
        align: "center",
      },
      {
@@ -250,28 +336,28 @@
      },
      {
        field: "productLength",
        title: "产品长度",
        title: "产品长度", // ä¿®æ­£åŽç«¯æ³¨é‡Š
        type: "decimal",
        width: 90,
        align: "center",
      },
      {
        field: "productWidth",
        title: "产品宽度",
        title: "产品宽度", // ä¿®æ­£åŽç«¯æ³¨é‡Š
        type: "decimal",
        width: 90,
        align: "center",
      },
      {
        field: "productHeight",
        title: "产品高度",
        title: "产品高度", // ä¿®æ­£åŽç«¯æ³¨é‡Š
        type: "decimal",
        width: 90,
        align: "center",
      },
      {
        field: "pressNoTighten",
        title: "压装位不拧紧",
        title: "不拧紧",
        type: "select",
        width: 100,
        align: "center",
@@ -284,24 +370,38 @@
        },
      },
      {
        field: "pressNoCheckBottomPlate",
        title: "不测底板",
        type: "select",
        width: 110,
        align: "center",
        bind: {
          key: "value",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
        },
      },
      {
        field: "screwDownsetDistance",
        title: "保压压力",
        title: "保压压力", // ä¿®æ­£å­—段中文名称
        type: "decimal",
        width: 110,
        align: "center",
      },
      {
        field: "screwTorqueOutput",
        title: "中心高度",
        title: "中心高度", // ä¿®æ­£å­—段中文名称
        type: "decimal",
        width: 90,
        align: "center",
      },
      {
        field: "pressFastenTorque", // ã€æ–°å¢žã€‘表格列
        title: "压装位紧固扭矩",
        field: "pressFastenTorque",
        title: "紧固扭矩", // è¡¥å……完整字段名称
        type: "decimal",
        width: 120,
        width: 90,
        align: "center",
      },
      {
@@ -311,7 +411,6 @@
        width: 100,
        align: "center",
      },
      // P系列宽度
      {
        field: "p0P1Width",
        title: "P0P1宽度",
@@ -333,30 +432,41 @@
        width: 90,
        align: "center",
      },
      // P系列高度
      {
        field: "p1P3Height",
        title: "P1P3高度",
        field: "pressPressureDiff",
        title: "压力差值",
        type: "decimal",
        width: 90,
        width: 100,
        align: "center",
      },
      {
        field: "p2P3Height",
        title: "P2P3高度",
        field: "pressTorqueDiff",
        title: "扭矩差值",
        type: "decimal",
        width: 90,
        width: 100,
        align: "center",
      },
      {
        field: "productImagePath",
        title: "图片路径",
        type: "string",
        width: 200,
        align: "left",
        overflow: "ellipsis",
        field: "detectHeightDiff",
        title: "高度差值",
        type: "decimal",
        width: 100,
        align: "center",
      },
      // å…¬å…±å­—段
      {
        field: "screwPositionDiff",
        title: "螺纹差值",
        type: "decimal",
        width: 100,
        align: "center",
      },
      {
        field: "gasketHeight",
        title: "垫片高度",
        type: "decimal",
        width: 100,
        align: "center",
      },
      {
        field: "creater",
        title: "创建人",
@@ -387,7 +497,7 @@
      },
    ]);
    // é…æ–¹æ˜Žç»†é…ç½® - æ— éœ€ä¿®æ”¹
    // é…æ–¹æ˜Žç»†é…ç½® - åŒæ ·ç»™æ˜Žç»†å­—段添加必填
    const detail = ref({
      cnName: "配方信息详情",
      table: "FormulaDetail",
@@ -399,32 +509,34 @@
          width: 90,
          hidden: true,
          readonly: true,
          require: true,
          required: true,
          align: "center",
        },
        {
          field: "componentCode",
          title: "零件编号",
          type: "string",
          edit: { type: "" },
          edit: { type: "input" },
          width: 120,
          require: true,
          required: true, // æ˜Žç»†æ ¸å¿ƒå­—段必填
          align: "left",
        },
        {
          field: "componentName",
          title: "零件名称",
          type: "string",
          edit: { type: "" },
          edit: { type: "input" },
          width: 150,
          required: true, // æ˜Žç»†æ ¸å¿ƒå­—段必填
          align: "left",
        },
        {
          field: "supplierCode",
          title: "供方代码",
          type: "string",
          edit: { type: "" },
          edit: { type: "input" },
          width: 150,
          required: true, // æ˜Žç»†æ ¸å¿ƒå­—段必填
          align: "left",
        },
        {
@@ -440,6 +552,7 @@
              { key: "1", value: "是" },
            ],
          },
          required: true, // æ˜Žç»†å¼€å…³å­—段必填
        },
      ],
      sortName: "createDate",
@@ -455,7 +568,112 @@
      searchFormOptions,
      columns,
      detail,
      isSidebarOpen,
      logoUrl,
      toggleSidebar,
    };
  },
});
</script>
<style scoped>
/* ä¾§è¾¹æ æ ·å¼ - å¢žåŠ z-index层级 */
.image-sidebar {
  position: fixed;
  top: 0;
  right: -600px;
  width: 600px;
  height: 100vh;
  background: #fff;
  box-shadow: -2px 0 10px rgba(0, 0, 0, 0.1);
  transition: right 0.3s ease;
  z-index: 9999;
  display: flex;
}
.sidebar-open {
  right: 0;
}
.sidebar-toggle {
  position: absolute;
  left: -40px;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 80px;
  background: #409eff;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border-radius: 8px 0 0 8px;
  font-size: 16px;
  font-weight: bold;
  transition: all 0.3s ease;
  box-shadow: -2px 0 5px rgba(0, 0, 0, 0.1);
  z-index: 10000; /* åˆ‡æ¢æŒ‰é’®çš„z-index更高 */
}
.sidebar-toggle:hover {
  background: #66b1ff;
}
.sidebar-toggle span {
  transition: transform 0.3s ease;
}
.sidebar-open .sidebar-toggle span {
  transform: rotate(180deg);
}
.sidebar-content {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
  z-index: 9999; /* å†…容区域也设置高z-index */
}
.image-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
}
.reference-image {
  max-width: 100%;
  max-height: 60vh;
  object-fit: contain;
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 10px;
  background: #f8f9fa;
}
.image-description {
  margin-top: 15px;
  padding: 10px;
  background: #409eff;
  color: white;
  border-radius: 4px;
  font-size: 14px;
  text-align: center;
}
/* å“åº”式设计 */
@media (max-width: 768px) {
  .image-sidebar {
    width: 250px;
    right: -250px;
  }
  .sidebar-toggle {
    left: -30px;
    width: 30px;
    height: 60px;
  }
}
</style>
´úÂë¹ÜÀí/WIDESEAWCS_Client/src/views/basicinfo/processInfo.vue
@@ -19,6 +19,13 @@
export default defineComponent({
  setup() {
    // å·¥å…·å‡½æ•°ï¼šæ ¼å¼åŒ–数字为两位小数
    const formatTwoDecimal = (value) => {
      if (value === "" || value === null || value === undefined) return "";
      const num = parseFloat(value);
      return isNaN(num) ? "" : num.toFixed(2);
    };
    // è¡¨æ ¼åŸºç¡€é…ç½®
    const table = ref({
      key: "id",
@@ -27,45 +34,51 @@
      name: "processInfo",
      url: "/processInfo/",
      sortName: "createDate",
      sortOrder: "desc", // æ–°å¢žï¼šåˆ›å»ºæ—¶é—´é»˜è®¤å€’序,符合常规使用
      sortOrder: "desc", // åˆ›å»ºæ—¶é—´é»˜è®¤å€’序
    });
    // ç¼–辑表单字段 - å®Œå…¨åŒ¹é…åŽç«¯Dt_ProcessInfo实体
    // æ–°å¢žï¼špressPressure(压装位下压压力),补全所有后端字段
    // ç¼–辑表单字段 - ä¸¥æ ¼åŒ¹é…åŽç«¯Dt_ProcessInfo实体
    const editFormFields = ref({
      id: "",
      id: 0, // ä¸»é”®é»˜è®¤å€¼æ”¹ä¸ºæ•°å­—0
      palletCode: "",
      productCode: "",
      productName: "",
      productSn: "", // æµæ°´å·
      pressTightenNg: "", // åŽ‹è£…æ‹§ç´§_拧紧NG
      pressTightenOk: "", // åŽ‹è£…æ‹§ç´§_拧紧OK
      pressTightenUnfinished: "", // åŽ‹è£…æ‹§ç´§_本次加工未完成
      checkUnfinished: "", // æ£€æµ‹_本次检测未完成
      //componentQty: "", // é›¶ä»¶æ•°é‡
      // torsioValue: "", // æ‰­åЛ值
      // torsioValueStandard: "", // æ‰­åŠ›å€¼æ ‡å‡†
      // stiffnessValue: "", // åˆšåº¦å€¼
      // stiffnessValueStandard: "", // åˆšåº¦å€¼æ ‡å‡†
      // testResult: "", // æµ‹è¯•结果
      pressHeight: "", // åŽ‹è£…ä½ä¸‹åŽ‹é«˜åº¦
      screwTorque: "", // åŽ‹è£…ä½æ‹§ç´§æ‰­åŠ›
      screwAngle: "", // åŽ‹è£…ä½æ‹§ç´§è§’åº¦
      pressPressure: "", // ã€æ–°å¢žã€‘压装位下压压力(匹配后端实体)
      height1: "", // æ‹§ç´§ä½æ£€æµ‹é«˜åº¦1
      height2: "", // æ‹§ç´§ä½æ£€æµ‹é«˜åº¦2
      height3: "", // æ‹§ç´§ä½æ£€æµ‹é«˜åº¦3
      productSn: "",
      pressTightenOk: 0, // æ”¹ä¸ºæ•°å­—默认值
      pressTightenUnfinished: 0, // æ”¹ä¸ºæ•°å­—默认值
      productStatus: 0, // æ–°å¢žï¼šäº§å“çŠ¶æ€å­—æ®µ
      screwTorque: "",
      screwAngle: "",
      pressPressure: "",
      productCheckHeight: "",
      threadPositionHeight: "",
      height1: "",
      height2: "",
      height3: "",
    });
    // ç¼–辑表单配置-【取消分类,均匀排布】,保留所有原有校验/默认值/属性
    // äº§å“çŠ¶æ€ä¸‹æ‹‰é€‰é¡¹ï¼ˆåŒ¹é…åŽç«¯æ³¨é‡Šï¼‰
    const productStatusOptions = [
      { key: "0", value: "不合格" },
      { key: "1", value: "合格" },
      { key: "2", value: "人工确认合格" },
    ];
    // å¸ƒå°”型下拉选项(通用)
    const booleanOptions = [
      { key: "0", value: "否" },
      { key: "1", value: "是" },
    ];
    // ç¼–辑表单配置 - ä¿®æ­£å­—段匹配,优化布局和命名
    const editFormOptions = ref([
      // ç¬¬ä¸€è¡Œï¼š5个字段(基础标识+1个状态),宽度协调
      // åŸºç¡€ä¿¡æ¯è¡Œ
      [
        {
          title: "工装板编号",
          field: "palletCode",
          type: "input",
          width: 160,
          width: 180,
          require: true,
          placeholder: "请输入工装板编号",
        },
@@ -73,7 +86,7 @@
          title: "成品编号",
          field: "productCode",
          type: "input",
          width: 160,
          width: 180,
          require: true,
          placeholder: "请输入成品编号",
        },
@@ -81,7 +94,7 @@
          title: "成品名称",
          field: "productName",
          type: "input",
          width: 160,
          width: 180,
          require: true,
          placeholder: "请输入成品名称",
        },
@@ -89,220 +102,172 @@
          title: "流水号",
          field: "productSn",
          type: "input",
          width: 180,
          width: 200,
          require: false,
          placeholder: "请输入产品流水号",
        },
      ],
      // åŠ å·¥çŠ¶æ€è¡Œ - ç§»é™¤ä¸å­˜åœ¨çš„checkUnfinished,新增产品状态
      [
        {
          title: "拧紧NG",
          field: "pressTightenNg",
          type: "select",
          width: 150,
          align: "center",
          defaultValue: "0",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
        },
        {
          title: "拧紧OK",
          title: "压装拧紧_拧紧OK",
          field: "pressTightenOk",
          type: "select",
          width: 150,
          width: 160,
          align: "center",
          defaultValue: "0",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          defaultValue: 0,
          data: booleanOptions,
        },
        {
          title: "拧紧未完成",
          title: "压装拧紧_本次加工未完成",
          field: "pressTightenUnfinished",
          type: "select",
          width: 170,
          width: 180,
          align: "center",
          defaultValue: "0",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          defaultValue: 0,
          data: booleanOptions,
        },
        {
          title: "检测未完成",
          field: "checkUnfinished",
          title: "产品状态",
          field: "productStatus",
          type: "select",
          width: 150,
          align: "center",
          defaultValue: "0",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
        },
        // {
        //   title: "零件数量",
        //   field: "componentQty",
        //   type: "input",
        //   inputType: "number",
        //   width: 140,
        //   require: false,
        //   attrs: { min: 0, step: 1 },
        //   placeholder: "请输入正整数",
        // },
        {
          title: "主键ID",
          field: "id",
          type: "input",
          width: 100,
          hidden: true,
          readonly: true,
        },
      ],
      // // ç¬¬ä¸‰è¡Œï¼š5个字段(扭力/刚度相关+测试结果),小数校验
      // [
      //   {
      //     title: "扭力值",
      //     field: "torsioValue",
      //     type: "input",
      //     inputType: "number",
      //     width: 140,
      //     require: false,
      //     attrs: { step: 0.01, min: 0 },
      //     placeholder: "保留2位小数",
      //   },
      //   {
      //     title: "扭力值标准",
      //     field: "torsioValueStandard",
      //     type: "input",
      //     inputType: "number",
      //     width: 160,
      //     require: false,
      //     attrs: { step: 0.01, min: 0 },
      //     placeholder: "保留2位小数",
      //   },
      //   {
      //     title: "刚度值",
      //     field: "stiffnessValue",
      //     type: "input",
      //     inputType: "number",
      //     width: 140,
      //     require: false,
      //     attrs: { step: 0.01, min: 0 },
      //     placeholder: "保留2位小数",
      //   },
      //   {
      //     title: "刚度值标准",
      //     field: "stiffnessValueStandard",
      //     type: "input",
      //     inputType: "number",
      //     width: 160,
      //     require: false,
      //     attrs: { step: 0.01, min: 0 },
      //     placeholder: "保留2位小数",
      //   },
      //   {
      //     title: "测试结果",
      //     field: "testResult",
      //     type: "input",
      //     inputType: "number",
      //     width: 140,
      //     require: false,
      //     placeholder: "请输入数字结果",
      //   },
      // ],
      // ç¬¬å››è¡Œï¼š4个字段(压装位全参数),小数校验,新增压装压力
      [
        {
          title: "压装高度",
          field: "pressHeight",
          type: "input",
          inputType: "number",
          width: 160,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          align: "center",
          defaultValue: 0,
          data: productStatusOptions,
        },
        {
          title: "压装压力",
          title: "压装位下压压力",
          field: "pressPressure",
          type: "input",
          inputType: "number",
          width: 160,
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
        },
        },
      ],
      // åŽ‹è£…æ£€æµ‹å‚æ•°è¡Œ - ä¼˜åŒ–标题,匹配后端注释
      [
        {
          title: "压装扭力",
          title: "压装位拧紧检测扭力",
          field: "screwTorque",
          type: "input",
          inputType: "number",
          width: 160,
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
        {
          title: "拧紧角度",
          title: "压装位拧紧检测角度",
          field: "screwAngle",
          type: "input",
          inputType: "number",
          width: 160,
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
        {
          title: "产品检测高度",
          field: "productCheckHeight",
          type: "input",
          inputType: "number",
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
        {
          title: "螺纹位置高度",
          field: "threadPositionHeight",
          type: "input",
          inputType: "number",
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
      ],
      // ç¬¬äº”行:3个字段(拧紧位检测高度),小数校验,居中排布
      // æ‹§ç´§ä½æ£€æµ‹é«˜åº¦è¡Œ
      [
        {
          title: "检测高度1",
          title: "拧紧位检测高度1",
          field: "height1",
          type: "input",
          inputType: "number",
          width: 200,
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
        {
          title: "检测高度2",
          title: "拧紧位检测高度2",
          field: "height2",
          type: "input",
          inputType: "number",
          width: 200,
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
        {
          title: "检测高度3",
          title: "拧紧位检测高度3",
          field: "height3",
          type: "input",
          inputType: "number",
          width: 200,
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
      ],
    ]);
    // æœç´¢è¡¨å•字段 - æ ¸å¿ƒæœç´¢é¡¹ï¼ˆæµæ°´å·+基础信息+创建信息)
    // æœç´¢è¡¨å•字段 - åŒ¹é…åŽç«¯å®žä½“,移除无关字段
    const searchFormFields = ref({
      palletCode: "",
      productCode: "",
      productName: "",
      productSn: "", // æµæ°´å·æœç´¢
      creater: "",
      productSn: "",
      productStatus: "", // æ–°å¢žï¼šäº§å“çŠ¶æ€æœç´¢
      createDate: "",
    });
    // æœç´¢è¡¨å•配置 - ä¼˜åŒ–宽度,匹配布局
    // æœç´¢è¡¨å•配置 - ä¼˜åŒ–布局,新增产品状态搜索
    const searchFormOptions = ref([
      [
        { title: "工装板编号", field: "palletCode", type: "like", width: 180 },
@@ -311,12 +276,18 @@
        { title: "流水号", field: "productSn", type: "like", width: 200 },
      ],
      [
        { title: "创建人", field: "creater", type: "like", width: 200 },
        {
          title: "产品状态",
          field: "productStatus",
          type: "select",
          width: 180,
          data: productStatusOptions,
        },
        { title: "创建时间", field: "createDate", type: "datetime", width: 380 },
      ],
    ]);
    // è¡¨æ ¼åˆ—配置 - å®Œå…¨åŒ¹é…åŽç«¯å®žä½“,新增pressPressure列,优化列宽/对齐
    // è¡¨æ ¼åˆ—配置 - ä¿®æ­£å­—段匹配,新增产品状态列,优化标题
    const columns = ref([
      {
        field: "id",
@@ -355,159 +326,107 @@
        align: "left",
        overflow: "ellipsis",
      },
      // 4个状态列 - æ˜¯å¦æ ¼å¼åŒ–显示
      {
        field: "pressTightenNg",
        title: "拧紧NG",
        type: "select",
        width: 120,
        align: "center",
        bind: {
          key: "value",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
        },
      },
      // çŠ¶æ€åˆ— - ç§»é™¤checkUnfinished,新增产品状态
      {
        field: "pressTightenOk",
        title: "拧紧OK",
        type: "select",
        width: 120,
        width: 100,
        align: "center",
        bind: {
          key: "value",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          data: booleanOptions,
        },
      },
      {
        field: "pressTightenUnfinished",
        title: "拧紧未完成",
        type: "select",
        width: 140,
        width: 120,
        align: "center",
        bind: {
          key: "value",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          data: booleanOptions,
        },
      },
      {
        field: "checkUnfinished",
        title: "检测未完成",
        field: "productStatus",
        title: "产品状态",
        type: "select",
        width: 120,
        align: "center",
        bind: {
          key: "value",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          data: productStatusOptions,
        },
      },
      // {
      //   field: "componentQty",
      //   title: "零件数量",
      //   type: "int",
      //   width: 90,
      //   align: "center",
      // },
      // // æ‰­åŠ›/刚度相关 - decimal类型(保留2位小数)
      // {
      //   field: "torsioValue",
      //   title: "扭力值",
      //   type: "decimal",
      //   width: 90,
      //   align: "center",
      // },
      // {
      //   field: "torsioValueStandard",
      //   title: "扭力标准",
      //   type: "decimal",
      //   width: 100,
      //   align: "center",
      // },
      // {
      //   field: "stiffnessValue",
      //   title: "刚度值",
      //   type: "decimal",
      //   width: 90,
      //   align: "center",
      // },
      // {
      //   field: "stiffnessValueStandard",
      //   title: "刚度标准",
      //   type: "decimal",
      //   width: 100,
      //   align: "center",
      // },
      // {
      //   field: "testResult",
      //   title: "测试结果",
      //   type: "int",
      //   width: 90,
      //   align: "center",
      // },
      // åŽ‹è£…ä½æ£€æµ‹å‚æ•° - ã€æ–°å¢žpressPressure列】decimal类型
      // åŽ‹è£…æ£€æµ‹å‚æ•°åˆ— - ä¼˜åŒ–标题,统一格式化
      {
        field: "pressHeight",
        title: "压装高度",
        field: "pressPressure",
        title: "压装位下压压力",
        type: "decimal",
        width: 100,
        width: 120,
        align: "center",
      },
      {
        field: "pressPressure", // ã€æ–°å¢žã€‘压装位下压压力
        title: "压装压力",
        type: "decimal",
        width: 100,
        align: "center",
        columnDescription: "压装位下压压力",
        formatter: (row) => formatTwoDecimal(row.pressPressure),
      },
      {
        field: "screwTorque",
        title: "压装扭力",
        title: "拧紧检测扭力",
        type: "decimal",
        width: 100,
        width: 120,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.screwTorque),
      },
      {
        field: "screwAngle",
        title: "拧紧角度",
        title: "拧紧检测角度",
        type: "decimal",
        width: 100,
        width: 120,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.screwAngle),
      },
      // æ‹§ç´§ä½æ£€æµ‹é«˜åº¦
      // äº§å“æ£€æµ‹é«˜åº¦åˆ—
      {
        field: "productCheckHeight",
        title: "产品检测高度",
        type: "decimal",
        width: 120,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.productCheckHeight),
      },
      {
        field: "threadPositionHeight",
        title: "螺纹位置高度",
        type: "decimal",
        width: 120,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.threadPositionHeight),
      },
      {
        field: "height1",
        title: "检测高度1",
        title: "高度1",
        type: "decimal",
        width: 100,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.height1),
      },
      {
        field: "height2",
        title: "检测高度2",
        title: "高度2",
        type: "decimal",
        width: 100,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.height2),
      },
      {
        field: "height3",
        title: "检测高度3",
        title: "高度3",
        type: "decimal",
        width: 100,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.height3),
      },
      // å…¬å…±å­—段 - åˆ›å»º/修改信息
      // å…¬å…±å­—段
      {
        field: "creater",
        title: "创建人",
@@ -538,7 +457,7 @@
      },
    ]);
    // åŠ å·¥ä¿¡æ¯æ— æ˜Žç»†ï¼Œä¿æŒç©ºé…ç½®
    // åŠ å·¥ä¿¡æ¯æ— æ˜Žç»†
    const detail = ref({
      cnName: "",
      table: "",
´úÂë¹ÜÀí/WIDESEAWCS_Client/src/views/basicinfo/processInfoDetail.vue
@@ -19,7 +19,14 @@
export default defineComponent({
  setup() {
    // è¡¨æ ¼åŸºç¡€é…ç½® - æ–°å¢žé»˜è®¤å€’序、统一规范
    // å·¥å…·å‡½æ•°ï¼šæ ¼å¼åŒ–数字为两位小数
    const formatTwoDecimal = (value) => {
      if (value === "" || value === null || value === undefined) return "";
      const num = parseFloat(value);
      return isNaN(num) ? "" : num.toFixed(2);
    };
    // è¡¨æ ¼åŸºç¡€é…ç½®
    const table = ref({
      key: "id",
      footer: "Foots",
@@ -27,38 +34,51 @@
      name: "processInfoDetail",
      url: "/processInfoDetail/",
      sortName: "createDate",
      sortOrder: "desc", // æ–°å¢žï¼šåˆ›å»ºæ—¶é—´é»˜è®¤å€’序,和主页面保持一致
      sortOrder: "desc", // åˆ›å»ºæ—¶é—´é»˜è®¤å€’序
    });
    // ç¼–辑表单字段 - åŒæ­¥ä¸»é¡µé¢ï¼Œæ–°å¢žpressPressure(压装压力),匹配后端实体
    // ç¼–辑表单字段 - ä¸¥æ ¼åŒ¹é…åŽç«¯Dt_ProcessInfo实体
    const editFormFields = ref({
      id: "",
      id: 0, // ä¸»é”®é»˜è®¤å€¼æ”¹ä¸ºæ•°å­—0
      palletCode: "",
      productCode: "",
      productName: "",
      productSn: "", // æµæ°´å·
      pressTightenNg: "", // åŽ‹è£…æ‹§ç´§_拧紧NG
      pressTightenOk: "", // åŽ‹è£…æ‹§ç´§_拧紧OK
      pressTightenUnfinished: "", // åŽ‹è£…æ‹§ç´§_本次加工未完成
      checkUnfinished: "", // æ£€æµ‹_本次检测未完成
      pressHeight: "", // åŽ‹è£…ä½ä¸‹åŽ‹é«˜åº¦
      screwTorque: "", // åŽ‹è£…ä½æ‹§ç´§æ‰­åŠ›
      screwAngle: "", // åŽ‹è£…ä½æ‹§ç´§è§’åº¦
      pressPressure: "", // ã€æ–°å¢žã€‘压装位下压压力(匹配后端实体)
      height1: "", // æ‹§ç´§ä½æ£€æµ‹é«˜åº¦1
      height2: "", // æ‹§ç´§ä½æ£€æµ‹é«˜åº¦2
      height3: "", // æ‹§ç´§ä½æ£€æµ‹é«˜åº¦3
      productSn: "",
      pressTightenOk: 0, // æ”¹ä¸ºæ•°å­—默认值
      pressTightenUnfinished: 0, // æ”¹ä¸ºæ•°å­—默认值
      productStatus: 0, // æ–°å¢žï¼šäº§å“çŠ¶æ€å­—æ®µ
      screwTorque: "",
      screwAngle: "",
      pressPressure: "",
      productCheckHeight: "",
      threadPositionHeight: "",
      height1: "",
      height2: "",
      height3: "",
    });
    // ç¼–辑表单配置 - å–消冗余分类、均匀排布,新增压装压力项,补全默认值/校验,统一宽度
    // äº§å“çŠ¶æ€ä¸‹æ‹‰é€‰é¡¹ï¼ˆåŒ¹é…åŽç«¯æ³¨é‡Šï¼‰
    const productStatusOptions = [
      { key: "0", value: "不合格" },
      { key: "1", value: "合格" },
      { key: "2", value: "人工确认合格" },
    ];
    // å¸ƒå°”型下拉选项(通用)
    const booleanOptions = [
      { key: "0", value: "否" },
      { key: "1", value: "是" },
    ];
    // ç¼–辑表单配置 - ä¿®æ­£å­—段匹配,优化布局和命名
    const editFormOptions = ref([
      // ç¬¬ä¸€è¡Œï¼šåŸºç¡€æ ‡è¯†ï¼Œå®½åº¦åè°ƒï¼Œå’Œä¸»é¡µé¢å¸ƒå±€ä¸€è‡´
      // åŸºç¡€ä¿¡æ¯è¡Œ
      [
        {
          title: "工装板编号",
          field: "palletCode",
          type: "input",
          width: 160,
          width: 180,
          require: true,
          placeholder: "请输入工装板编号",
        },
@@ -66,7 +86,7 @@
          title: "成品编号",
          field: "productCode",
          type: "input",
          width: 160,
          width: 180,
          require: true,
          placeholder: "请输入成品编号",
        },
@@ -74,7 +94,7 @@
          title: "成品名称",
          field: "productName",
          type: "input",
          width: 160,
          width: 180,
          require: true,
          placeholder: "请输入成品名称",
        },
@@ -82,158 +102,172 @@
          title: "流水号",
          field: "productSn",
          type: "input",
          width: 180,
          width: 200,
          require: false,
          placeholder: "请输入产品流水号",
        },
      ],
      // ç¬¬äºŒè¡Œï¼š4个状态列+主键,补全默认值0(否),统一宽度/对齐,隐藏主键
      // åŠ å·¥çŠ¶æ€è¡Œ - ç§»é™¤ä¸å­˜åœ¨çš„checkUnfinished,新增产品状态
      [
        {
          title: "拧紧NG",
          field: "pressTightenNg",
          type: "select",
          width: 150,
          align: "center",
          defaultValue: "0", // æ–°å¢žé»˜è®¤å€¼ï¼Œå’Œä¸»é¡µé¢ä¸€è‡´
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
        },
        {
          title: "拧紧OK",
          title: "压装拧紧_拧紧OK",
          field: "pressTightenOk",
          type: "select",
          width: 150,
          width: 160,
          align: "center",
          defaultValue: "0", // æ–°å¢žé»˜è®¤å€¼
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          defaultValue: 0,
          data: booleanOptions,
        },
        {
          title: "拧紧未完成",
          title: "压装拧紧_本次加工未完成",
          field: "pressTightenUnfinished",
          type: "select",
          width: 170,
          width: 180,
          align: "center",
          defaultValue: "0",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          defaultValue: 0,
          data: booleanOptions,
        },
        {
          title: "检测未完成",
          field: "checkUnfinished",
          title: "产品状态",
          field: "productStatus",
          type: "select",
          width: 150,
          width: 160,
          align: "center",
          defaultValue: "0", // æ–°å¢žé»˜è®¤å€¼ï¼Œç»Ÿä¸€è§„范
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          defaultValue: 0,
          data: productStatusOptions,
        },
        {
          title: "主键ID",
          field: "id",
          title: "压装位下压压力",
          field: "pressPressure",
          type: "input",
          width: 100,
          hidden: true,
          readonly: true,
          inputType: "number",
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
      ],
      // åŽ‹è£…æ£€æµ‹å‚æ•°è¡Œ - ä¼˜åŒ–标题,匹配后端注释
      [
        {
          title: "压装高度",
          field: "pressHeight",
          type: "input",
          inputType: "number",
          width: 160,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
        },
        {
          title: "压装压力",
          field: "pressPressure", // æ–°å¢žåŽ‹è£…åŽ‹åŠ›é¡¹
          type: "input",
          inputType: "number",
          width: 160,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
        },
        {
          title: "压装扭力",
          title: "压装位拧紧检测扭力",
          field: "screwTorque",
          type: "input",
          inputType: "number",
          width: 160,
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
        {
          title: "拧紧角度",
          title: "压装位拧紧检测角度",
          field: "screwAngle",
          type: "input",
          inputType: "number",
          width: 160,
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
        {
          title: "产品检测高度",
          field: "productCheckHeight",
          type: "input",
          inputType: "number",
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
        {
          title: "螺纹位置高度",
          field: "threadPositionHeight",
          type: "input",
          inputType: "number",
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
      ],
      // ç¬¬äº”行:拧紧位检测高度,小数校验,居中排布,统一宽度
      // æ‹§ç´§ä½æ£€æµ‹é«˜åº¦è¡Œ
      [
        {
          title: "检测高度1",
          title: "拧紧位检测高度1",
          field: "height1",
          type: "input",
          inputType: "number",
          width: 200,
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
        {
          title: "检测高度2",
          title: "拧紧位检测高度2",
          field: "height2",
          type: "input",
          inputType: "number",
          width: 200,
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
        {
          title: "检测高度3",
          title: "拧紧位检测高度3",
          field: "height3",
          type: "input",
          inputType: "number",
          width: 200,
          width: 180,
          require: false,
          attrs: { step: 0.01, min: 0 },
          placeholder: "保留2位小数",
          formatter: formatTwoDecimal,
          onBlur: (e) => {
            e.target.value = formatTwoDecimal(e.target.value);
          },
        },
      ],
    ]);
    // æœç´¢è¡¨å•字段 - ä¿æŒå’Œä¸»é¡µé¢ã€åŽŸæœ‰ä»£ç ä¸€è‡´ï¼Œæ ¸å¿ƒæœç´¢é¡¹æ— è°ƒæ•´
    // æœç´¢è¡¨å•字段 - åŒ¹é…åŽç«¯å®žä½“,移除无关字段
    const searchFormFields = ref({
      palletCode: "",
      productCode: "",
      productName: "",
      productSn: "", // æµæ°´å·æœç´¢
      creater: "",
      productSn: "",
      productStatus: "", // æ–°å¢žï¼šäº§å“çŠ¶æ€æœç´¢
      createDate: "",
    });
    // æœç´¢è¡¨å•配置 - ä¼˜åŒ–宽度匹配布局,和主页面完全一致
    // æœç´¢è¡¨å•配置 - ä¼˜åŒ–布局,新增产品状态搜索
    const searchFormOptions = ref([
      [
        { title: "工装板编号", field: "palletCode", type: "like", width: 180 },
@@ -242,12 +276,18 @@
        { title: "流水号", field: "productSn", type: "like", width: 200 },
      ],
      [
        { title: "创建人", field: "creater", type: "like", width: 200 },
        {
          title: "产品状态",
          field: "productStatus",
          type: "select",
          width: 180,
          data: productStatusOptions,
        },
        { title: "创建时间", field: "createDate", type: "datetime", width: 380 },
      ],
    ]);
    // è¡¨æ ¼åˆ—配置 - ã€æ–°å¢žpressPressure列】,统一列名/宽度/类型,修复首字母大写问题,优化对齐
    // è¡¨æ ¼åˆ—配置 - ä¿®æ­£å­—段匹配,新增产品状态列,优化标题
    const columns = ref([
      {
        field: "id",
@@ -286,115 +326,107 @@
        align: "left",
        overflow: "ellipsis",
      },
      // 4个状态列 - ä¿®å¤åŽŸæœ‰PressTightenNg首字母大写问题,统一规范
      {
        field: "pressTightenNg",
        title: "拧紧NG",
        type: "select",
        width: 120,
        align: "center",
        bind: {
          key: "value",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
        },
      },
      // çŠ¶æ€åˆ— - ç§»é™¤checkUnfinished,新增产品状态
      {
        field: "pressTightenOk",
        title: "拧紧OK",
        type: "select",
        width: 120,
        width: 100,
        align: "center",
        bind: {
          key: "value",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          data: booleanOptions,
        },
      },
      {
        field: "pressTightenUnfinished",
        title: "拧紧未完成",
        type: "select",
        width: 140,
        width: 120,
        align: "center",
        bind: {
          key: "value",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          data: booleanOptions,
        },
      },
      {
        field: "checkUnfinished",
        title: "检测未完成",
        field: "productStatus",
        title: "产品状态",
        type: "select",
        width: 120,
        align: "center",
        bind: {
          key: "value",
          data: [
            { key: "0", value: "否" },
            { key: "1", value: "是" },
          ],
          data: productStatusOptions,
        },
      },
      // åŽ‹è£…æ£€æµ‹å‚æ•°åˆ— - ä¼˜åŒ–标题,统一格式化
      {
        field: "pressHeight",
        title: "压装高度",
        field: "pressPressure",
        title: "压装位下压压力",
        type: "decimal",
        width: 100,
        width: 120,
        align: "center",
      },
      {
        field: "pressPressure", // æ–°å¢žåŽ‹è£…åŽ‹åŠ›åˆ—
        title: "压装压力",
        type: "decimal",
        width: 100,
        align: "center",
        columnDescription: "压装位下压压力",
        formatter: (row) => formatTwoDecimal(row.pressPressure),
      },
      {
        field: "screwTorque",
        title: "压装扭力",
        title: "拧紧检测扭力",
        type: "decimal",
        width: 100,
        width: 120,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.screwTorque),
      },
      {
        field: "screwAngle",
        title: "拧紧角度",
        title: "拧紧检测角度",
        type: "decimal",
        width: 100,
        width: 120,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.screwAngle),
      },
      // æ‹§ç´§ä½æ£€æµ‹é«˜åº¦
      // äº§å“æ£€æµ‹é«˜åº¦åˆ—
      {
        field: "productCheckHeight",
        title: "产品检测高度",
        type: "decimal",
        width: 120,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.productCheckHeight),
      },
      {
        field: "threadPositionHeight",
        title: "螺纹位置高度",
        type: "decimal",
        width: 120,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.threadPositionHeight),
      },
      {
        field: "height1",
        title: "检测高度1",
        title: "高度1",
        type: "decimal",
        width: 100,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.height1),
      },
      {
        field: "height2",
        title: "检测高度2",
        title: "高度2",
        type: "decimal",
        width: 100,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.height2),
      },
      {
        field: "height3",
        title: "检测高度3",
        title: "高度3",
        type: "decimal",
        width: 100,
        align: "center",
        formatter: (row) => formatTwoDecimal(row.height3),
      },
      // å…¬å…±å­—段 - åˆ›å»º/修改信息,和主页面一致
      // å…¬å…±å­—段
      {
        field: "creater",
        title: "创建人",
@@ -425,7 +457,7 @@
      },
    ]);
    // æ— äºŒçº§æ˜Žç»†ï¼Œä¿æŒç©ºé…ç½®ä¸å˜
    // åŠ å·¥ä¿¡æ¯æ— æ˜Žç»†
    const detail = ref({
      cnName: "",
      table: "",
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.794.21998/CodeChunks.db
Binary files differ
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/17.14.794.21998/SemanticSymbols.db
Binary files differ
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/DesignTimeBuild/.dtbcache.v2
Binary files differ
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v17/.futdcache.v2
Binary files differ
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v17/.suo
Binary files differ
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/BoxingDetailService.cs
@@ -11,6 +11,7 @@
using WIDESEAWCS_Core.BaseServices;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_DTO.BasicInfo;
using WIDESEAWCS_IBasicInfoService;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
@@ -22,6 +23,10 @@
        private readonly IBoxingService _boxingService;
        private readonly IFormulaService _formulaService;
        private readonly IFormulaDetailService _formulaDetailService;
        private readonly IProcessInfoDetailService _processInfoDetailService;
        private readonly IScanStationService _scanStationService;
        private readonly IUnitOfWorkManage _unitOfWorkManage;
        public BoxingDetailService(
@@ -29,13 +34,18 @@
            IFormulaService formulaService,
            IBoxingService boxingService,
            IFormulaDetailService formulaDetailService,
            IProcessInfoDetailService processInfoDetailService,
            IScanStationService scanStationService,
            IUnitOfWorkManage unitOfWorkManage
            ) : base(BaseDal)
        {
            _formulaService = formulaService;
            _boxingService = boxingService;
            _formulaDetailService = formulaDetailService;
            _processInfoDetailService = processInfoDetailService;
            _scanStationService = scanStationService;
            _unitOfWorkManage = unitOfWorkManage;
        }
        public IRepository<Dt_BoxingDetail> Repository => BaseDal;
@@ -103,6 +113,7 @@
        /// <returns></returns>
        public string IsComponentCodesEqual(List<string> boxingDetails, List<string> formulaDetails)
        {
            // å¤„理null集合,规避空指针异常
            var boxList = boxingDetails ?? new List<string>();
            var formulaList = formulaDetails ?? new List<string>();
@@ -142,15 +153,17 @@
                        return WebResponseContent.Instance.Error("提交参数不能为空");
                    }
                    string productCode = toolingBoardSubmitDto.FinishedProductCode?.Trim();
                    if (!string.IsNullOrWhiteSpace(productCode))
                    {
                        string proCode = string.Empty;
                        string proOther = string.Empty;
                    if (!string.IsNullOrWhiteSpace(productCode))
                    {
                        var proCodeMatch = System.Text.RegularExpressions.Regex.Match(productCode, @"TX(\d+)(?=\s|\||$)", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                        if (proCodeMatch.Success)
                        {
                            proCode = $"TX{proCodeMatch.Groups[1].Value.Trim()}"; // æ‹¼æŽ¥TX+数字,保持格式统一
                            proCode = $"TX{proCodeMatch.Groups[1].Value.Trim()}";
                        }
                        // æ­£åˆ™2:匹配连续的10位纯数字(全局匹配,取第一个符合的即可)
@@ -165,6 +178,12 @@
                        if (formulaModel == null)
                        {
                            return WebResponseContent.Instance.Error("无成品配方,请核对成品编码");
                        }
                        Dt_ScanStation dt_ScanStation = _scanStationService.Repository.QueryFirst(x => x.StationCode == "001");
                        if (dt_ScanStation.StationEndProduct != proCode)
                        {
                            return WebResponseContent.Instance.Error("成品编号错误");
                        }
                        List<Dt_FormulaDetail> dt_FormulaDetails = _formulaDetailService.Repository.QueryData(x => x.FormulaId == formulaModel.Id && x.IsScanned == 1);
@@ -193,6 +212,11 @@
                        if (!PalletCode.IsNotEmptyOrNull() || PalletCode == "NoRead")
                        {
                            throw new InvalidOperationException("托盘码未扫到,请重试");
                        }
                        Dt_Boxing dt_Boxing = _boxingService.Repository.QueryFirst(x => x.PalletCode == PalletCode);
                        if(dt_Boxing != null)
                        {
                            throw new InvalidOperationException("托盘码重复扫描");
                        }
                        Dt_Boxing existBoxinModel = new Dt_Boxing();
                        existBoxinModel.PalletCode = PalletCode;
@@ -326,9 +350,18 @@
                    //    #endregion
                    //}
                    //uow.Commit();
                    //string msg = existBoxinModel == null ? "组盘信息新增成功!" : "组盘信息修改成功!";
                    string msg = null;
                    List<Dt_ProcessInfoDetail> dt_ProcessInfoDetail = _processInfoDetailService.Repository
                            .QueryData(x => x.ProductSn == proOther && x.ProductCode == proCode).ToList();
                    return WebResponseContent.Instance.OK();
                    // 3. åˆ¤æ–­æŸ¥è¯¢ç»“果,存在则赋值提示信息
                    if (dt_ProcessInfoDetail.Count<=3 && dt_ProcessInfoDetail.Count != 0)
                    {
                        msg = "已有流水号";
                    }
                    // 4. è¿”回响应(存在重复则msg是"已有流水号",不存在则msg为null)
                    return WebResponseContent.Instance.OK(msg);
                }
                catch (Exception ex)
                {
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/BoxingService.cs
@@ -1,20 +1,80 @@
using System;
using Autofac.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEAWCS_Common;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.BaseRepository;
using WIDESEAWCS_Core.BaseServices;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_IBasicInfoService;
using WIDESEAWCS_Model.Models;
namespace WIDESEAWCS_BasicInfoService
{
    public class BoxingService : ServiceBase<Dt_Boxing, IRepository<Dt_Boxing>>, IBoxingService
    {
        public BoxingService(IRepository<Dt_Boxing> BaseDal) : base(BaseDal)
        private readonly IProcessInfoService _processInfoService;
        // ç›´æŽ¥æ³¨å…¥ BoxingDetail çš„仓储,替代注入 BoxingDetailService
        private readonly IRepository<Dt_BoxingDetail> _boxingDetailRepo;
        public BoxingService(
            IRepository<Dt_Boxing> BaseDal,
            IProcessInfoService processInfoService,
            // æ–°å¢žæ³¨å…¥ BoxingDetail ä»“储
            IRepository<Dt_BoxingDetail> boxingDetailRepo
            ) : base(BaseDal)
        {
            _processInfoService = processInfoService;
            _boxingDetailRepo = boxingDetailRepo; // èµ‹å€¼
        }
        public IRepository<Dt_Boxing> Repository => BaseDal;
        //删除当前托盘
        public WebResponseContent DeleteCurrentTray()
        {
            try
            {
                var PalletCode = TcpClientExample.Start("192.168.2.120", 2001);
                if (!PalletCode.IsNotEmptyOrNull() || PalletCode == "NoRead")
                {
                    return WebResponseContent.Instance.Error("托盘码未扫到,请重试");
                }
                Db.Ado.BeginTran();
                // 1. åˆ é™¤ Boxing ä¸»è¡¨æ•°æ®
                Dt_Boxing dt_Boxing = BaseDal.QueryFirst(x => x.PalletCode == PalletCode);
                if (dt_Boxing != null)
                {
                    BaseDal.DeleteData(dt_Boxing);
                    // 2. ç›´æŽ¥é€šè¿‡ä»“储删除 BoxingDetail æ•°æ®ï¼ˆæ ¸å¿ƒä¿®æ”¹ï¼‰
                    Dt_BoxingDetail dt_BoxingDetail = _boxingDetailRepo.QueryFirst(x => x.BoxingId == dt_Boxing.Id);
                    if (dt_BoxingDetail != null)
                    {
                        _boxingDetailRepo.DeleteData(dt_BoxingDetail);
                    }
                }
                // 3. åˆ é™¤ ProcessInfo æ•°æ®
                Dt_ProcessInfo dt_ProcessInfo = _processInfoService.Repository.QueryFirst(x => x.PalletCode == PalletCode);
                if (dt_ProcessInfo != null)
                {
                    _processInfoService.Repository.DeleteData(dt_ProcessInfo);
                }
                Db.Ado.CommitTran();
                return WebResponseContent.Instance.OK("删除成功");
            }
            catch (Exception ex)
            {
                Db.Ado.RollbackTran();
                throw new Exception(ex.Message);
            }
        }
    }
}
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/ScanStationService.cs
@@ -1,5 +1,6 @@
using Autofac.Core;
using OfficeOpenXml;
using OfficeOpenXml.Style;
using Spire.Xls;
using System;
using System.Collections.Generic;
@@ -126,6 +127,9 @@
        /// <exception cref="Exception"></exception>
        public WebResponseContent GetSignalStates()
        {
            try
            {
            OtherDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceName == "主控PLC") as OtherDevice;
            if (device == null) throw new Exception("未找到主控PLC设备信息");
            if (!device.IsConnected) throw new Exception($"主控PLC设备通讯异常");
@@ -155,6 +159,11 @@
            };
            return WebResponseContent.Instance.OK(data: responseData);
        }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
        /// <summary>
        /// èŽ·å–æˆå“ä¿¡æ¯
@@ -176,13 +185,16 @@
                }
                List<Dt_FormulaDetail> dt_FormulaDetails = _formulaDetailService.Repository.QueryData(x => x.FormulaId == dt_Formula.Id);
                // æ–°å¢žleftPartSupplierCodes字段存储供方代码
                var responseData = new
                {
                    finishedProductId = dt_Formula.Id,
                    finishedProduct = dt_Formula.ProductCode,
                    leftPartCodes = new List<string>(),
                    leftPartIds = new List<int>(),
                    leftPartChecked = new List<int>()
                    leftPartChecked = new List<int>(),
                    // å­˜å‚¨æ¯ä¸ªé›¶ä»¶çš„供方代码
                    leftPartSupplierCodes = new List<string>()
                };
                foreach (var detail in dt_FormulaDetails.Take(10))
@@ -190,6 +202,8 @@
                    responseData.leftPartCodes.Add(detail.ComponentCode ?? "");
                    responseData.leftPartIds.Add(detail.Id);
                    responseData.leftPartChecked.Add(detail.IsScanned);
                    // æ·»åŠ ä¾›æ–¹ä»£ç ï¼Œä¸ºç©ºæ—¶è¿”å›žç©ºå­—ç¬¦ä¸²
                    responseData.leftPartSupplierCodes.Add(detail.SupplierCode ?? "");
                }
                int needFillCount = 10 - responseData.leftPartCodes.Count;
@@ -198,6 +212,8 @@
                    responseData.leftPartCodes.Add("");
                    responseData.leftPartIds.Add(0);
                    responseData.leftPartChecked.Add(0);
                    //补足10条数据,空的供方代码返回空字符串
                    responseData.leftPartSupplierCodes.Add("");
                }
                return WebResponseContent.Instance.OK("获取左侧初始数据成功", responseData);
            }
@@ -237,12 +253,18 @@
        /// </summary>
        /// <param name="dt_ProcessInfo"></param>
        /// <returns></returns>
        public WebResponseContent ExportData(Dt_ScanStation dt_ScanStation)
        public WebResponseContent ExportData()
        {
            try
            {
                Dt_ScanStation dt_ScanStation = BaseDal.QueryFirst(x => x.StationCode == "001");
            string fileName = $"{DateTime.Now.ToString("yyyyMMddHHssmm")}.xlsx";
                string fileName = $"{DateTime.Now.ToString("yyyyMMddHHssmm")}" + $"{dt_ScanStation.StationEndProduct}.xlsx";
            string templatePath = $"{AppDomain.CurrentDomain.BaseDirectory}ExprotTemplate\\发电机弹性支撑信息化流程卡.xlsx";//模板路径
            string savePath = $"{AppDomain.CurrentDomain.BaseDirectory}Download\\{fileName}";//保存文件路径
                                                                                                                   // èŽ·å–ç³»ç»Ÿæ¡Œé¢è·¯å¾„
                string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\流程卡";
                //string desktopPath = "C:\\Users\\Administrator\\Desktop";
                string savePath = Path.Combine(desktopPath, fileName);
            using Stream templateStream = new FileStream(templatePath, FileMode.Open);
            using Stream saveStream = new FileStream(savePath, FileMode.Create);
@@ -255,11 +277,14 @@
                dt_FormulaDetails.Add(new Dt_FormulaDetail());
            }
            worksheet.Cells[3, 5].Value = dt_ScanStation.StationEndProduct;//成品编号
            worksheet.Cells[3, 17].Value = dt_ScanStation.LastProductSn.ObjToInt() - dt_ScanStation.FirstProductSn.ObjToInt() + 1;//数量;
            worksheet.Cells[3, 29].Value = dt_ScanStation.FirstProductSn + "-" + dt_ScanStation.LastProductSn;//流水号
            worksheet.Cells[4, 5].Value = DateTime.Now.ToString("yyyy/MM/dd");//组装日期
            worksheet.Cells[4, 17].Value = dt_ScanStation.AssembleUser;//组装人员
            int row = 7;
            for (int j = 0; j < 5; j++)
@@ -283,9 +308,15 @@
            worksheet.Cells[17, 12].Value = "☑ æ˜¯     â–¡ å¦";
            worksheet.Cells[23, 5].Value = "☑ æ˜¯     â–¡ å¦";
                worksheet.Cells[26, 7].Value = formula.ProductHeight;
                worksheet.Cells[26, 13].Value = formula.ScrewTorqueOutput;
                worksheet.Cells[26, 19].Value = formula.ScrewDownsetDistance;
                worksheet.Cells[26, 25].Value = formula.PressFastenTorque;
            List<Dt_ProcessInfoDetail> dt_ProcessInfoDetails = _processInfoDetailService.Repository
                .QueryData(x => x.ProductCode == dt_ScanStation.StationEndProduct
                && x.ProductSn.CompareTo(dt_ScanStation.LastProductSn) >= 0
                    && x.ProductSn.CompareTo(dt_ScanStation.FirstProductSn) >= 0
                && x.ProductSn.CompareTo(dt_ScanStation.LastProductSn) <= 0)
                .OrderBy(x => x.CreateDate)
                .ToList();
@@ -299,7 +330,7 @@
                    var targetRange = worksheet.Cells[row, 1, row, 36];
                    // 1. å¤åˆ¶åˆå¹¶è§„则(原有逻辑保留)
                    this.CopyCellMerge(worksheet, sourceRange, targetRange);
                        CopyCellMerge(worksheet, sourceRange, targetRange);
                    // 2. å¤åˆ¶æ ·å¼ï¼ˆå…¼å®¹æ‰€æœ‰EPPlus版本)
                    targetRange.StyleID = sourceRange.StyleID;
                    // 3. åŒæ­¥è¡Œé«˜
@@ -307,22 +338,31 @@
                }
                worksheet.Cells[row, 1].Value = item.ProductSn;
                worksheet.Cells[row, 7].Value = item.Height2;
                worksheet.Cells[row, 13].Value = item.Height1;
                    worksheet.Cells[row, 7].Value = item.ProductCheckHeight;
                    worksheet.Cells[row, 7].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                    worksheet.Cells[row, 7].Style.Fill.BackgroundColor.SetColor(SixLabors.ImageSharp.Color.Yellow);
                    worksheet.Cells[row, 13].Value = item.ThreadPositionHeight;
                    worksheet.Cells[row, 13].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                    worksheet.Cells[row, 13].Style.Fill.BackgroundColor.SetColor(SixLabors.ImageSharp.Color.Yellow);
                worksheet.Cells[row, 19].Value = item.PressPressure;
                    worksheet.Cells[row, 19].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                    worksheet.Cells[row, 19].Style.Fill.BackgroundColor.SetColor(SixLabors.ImageSharp.Color.Yellow);
                worksheet.Cells[row, 25].Value = item.ScrewTorque;
                if (item.PressTightenUnfinished == 1)
                {
                    worksheet.Cells[row, 31].Value = "压装拧紧异常";
                }
                else if (item.CheckUnfinished == 1)
                {
                    worksheet.Cells[row, 31].Value = "检测异常";
                }
                else
                {
                    worksheet.Cells[row, 31].Value = "正常";
                }
                    worksheet.Cells[row, 25].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                    worksheet.Cells[row, 25].Style.Fill.BackgroundColor.SetColor(SixLabors.ImageSharp.Color.Yellow);
                    worksheet.Cells[row, 31].Value = item.ProductStatus == 0 ? "不合格" : item.ProductStatus == 1 ? "合格" : "人工确认合格";
                    //if (item.PressTightenUnfinished == 1)
                    //{
                    //    worksheet.Cells[row, 31].Value = "压装拧紧异常";
                    //}
                    //else
                    //{
                    //    worksheet.Cells[row, 31].Value = "正常";
                    //}
                row++;
            }
@@ -330,16 +370,27 @@
            package.Save();
            string pdfFileName = $"{DateTime.Now.ToString("yyyyMMddHHssmm")}.pdf";
            string pdfPath = $"{AppDomain.CurrentDomain.BaseDirectory}Download\\{pdfFileName}";
                string pdfFileName = $"{DateTime.Now.ToString("yyyyMMddHHssmm")}" + $"{dt_ScanStation.StationEndProduct}.pdf";
                //string pdfPath = $"{AppDomain.CurrentDomain.BaseDirectory}Download\\{pdfFileName}";
                string pdfPath = Path.Combine(desktopPath, pdfFileName);
            Workbook workbook = new Workbook();
            workbook.LoadFromFile(savePath);
            // è½¬æ¢ç¬¬ä¸€ä¸ªå·¥ä½œè¡¨åˆ°PDF
            workbook.SaveToFile(pdfPath, FileFormat.PDF);
            return WebResponseContent.Instance.OK(data: new { path = pdfPath, fileName = pdfFileName });
                // è®¾ç½®è½¬æ¢é€‰é¡¹ï¼ŒåŒ…含所有工作表
                workbook.ConverterSetting.SheetFitToPage = true;
                // ä¿å­˜æ‰€æœ‰å·¥ä½œè¡¨åˆ°åŒä¸€ä¸ªPDF文件
                workbook.SaveToFile(pdfPath, FileFormat.PDF);
                //// è½¬æ¢ç¬¬ä¸€ä¸ªå·¥ä½œè¡¨åˆ°PDF
                //workbook.SaveToFile(pdfPath, FileFormat.PDF);
                return WebResponseContent.Instance.OK(data: new { path = pdfPath, fileName = pdfFileName });
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Common/PLCEnum/W_PLCDBName.cs
@@ -48,6 +48,10 @@
        /// åŽ‹è£…ä½ä¸æ‹§ç´§
        /// </summary>
        wboolLocation8ScanDone,
        /// <summary>
        /// åŽ‹è£…ä½ä¸æµ‹åº•æ¿
        /// </summary>
        wboolLocation9ScanDone,
        /// <summary>
        /// åŽ‹è£…ä½äº§å“é•¿åº¦
@@ -103,5 +107,26 @@
        /// </summary>
        wrealCheckPalletCode,
        /// <summary>
        /// åŽ‹è£…åŽ‹åŠ›å·®å€¼
        /// </summary>
        wrealPressPressure,
        /// <summary>
        /// åŽ‹è£…æ‰­åŠ›å·®å€¼
        /// </summary>
        wrealTighteningTorque,
        /// <summary>
        /// æ£€æµ‹é«˜åº¦å·®å€¼
        /// </summary>
        wrealProdHeightDiff,
        /// <summary>
        /// èžºçº¹ä½ç½®å·®å€¼
        /// </summary>
        wrealScrewHeight,
        /// <summary>
        /// ç´§å›ºæ‰­çŸ©å·®å€¼
        /// </summary>
        wrealFastenTorque,
    }
}
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Common/Spire.XLS.dll
Binary files differ
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_IBasicInfoService/IBoxingService.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.BaseRepository;
using WIDESEAWCS_Core.BaseServices;
using WIDESEAWCS_Model.Models;
@@ -12,5 +13,7 @@
    public interface IBoxingService : IService<Dt_Boxing>
    {
        public IRepository<Dt_Boxing> Repository { get; }
        public WebResponseContent DeleteCurrentTray();
    }
}
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_IBasicInfoService/IScanStationService.cs
@@ -31,7 +31,7 @@
        public WebResponseContent UpdatePartScannedStatus(UpdatePartScannedStatusRequest updatePartScannedStatusRequest);
        // ä¸‹è½½æµç¨‹å¡
        public WebResponseContent ExportData(Dt_ScanStation dt_ScanStation);
        public WebResponseContent ExportData();
    }
}
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/BasicInfo/Dt_Formula.cs
@@ -1,12 +1,13 @@
using System;
using Magicodes.ExporterAndImporter.Core;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Numeric;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Numeric;
using SqlSugar;
using WIDESEAWCS_Core.DB.Models;
using Magicodes.IE.Core;
namespace WIDESEAWCS_Model.Models
{
    [SugarTable(nameof(Dt_Formula), "配方信息表")]
@@ -15,107 +16,170 @@
        /// <summary>
        /// ä¸»é”®
        /// </summary>
        ///
        [ImporterHeader(IsIgnore = true)]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "主键")]
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "主键")]
        public int Id { get; set; }
        /// <summary>
        /// æˆå“ç¼–号
        /// </summary>
        [SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "成品编号")]
        ///
        [ImporterHeader(Name = "成品编号")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "成品编号")]
        [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "成品编号")]
        public string ProductCode { get; set; }
        /// <summary>
        /// æˆå“åç§°
        /// </summary>
        [ImporterHeader(Name = "成品名称")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "成品名称")]
        [SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "成品名称")]
        public string ProductName { get; set; }
        /// <summary>
        /// åŽ‹è£…ä½äº§å“é•¿åº¦
        /// </summary>
        [ImporterHeader(Name = "产品长度")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "产品长度")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "压装位产品长度")]
        public decimal? ProductLength { get; set; }
        /// <summary>
        /// åŽ‹è£…ä½äº§å“å®½åº¦
        /// </summary>
        [ImporterHeader(Name = "产品宽度")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "产品宽度")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "压装位产品宽度")]
        public decimal? ProductWidth { get; set; }
        /// <summary>
        /// åŽ‹è£…ä½äº§å“é«˜åº¦
        /// </summary>
        [ImporterHeader(Name = "产品高度")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "产品高度")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "压装位产品高度")]
        public decimal? ProductHeight { get; set; }
        /// <summary>
        /// åŽ‹è£…ä½ä¸æ‹§ç´§
        /// </summary>
        [ImporterHeader(Name = "不拧紧")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "不拧紧")]
        [SugarColumn(IsNullable = true, DefaultValue = "0", ColumnDescription = "压装位不拧紧")]
        public int? PressNoTighten { get; set; }
        /// <summary>
        /// åŽ‹è£…ä½æ‹§ç´§ä¸‹é™é«˜åº¦
        /// åŽ‹è£…ä½ä¸æµ‹åº•æ¿
        /// 0-检测 1-不检测
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "压装位拧紧下降高度")]
        [ImporterHeader(Name = "不测底板")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "不测底板")]
        [SugarColumn(IsNullable = true, DefaultValue = "0", ColumnDescription = "压装位不测底板")]
        public int? PressNoCheckBottomPlate { get; set; }
        /// <summary>
        /// ä¿åŽ‹åŽ‹åŠ›
        /// </summary>
        [ImporterHeader(Name = "保压压力")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "保压压力")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "保压压力")]
        public decimal? ScrewDownsetDistance { get; set; }
        /// <summary>
        /// åŽ‹è£…ä½æ‹§ç´§æ‰­åŠ›
        /// ä¸­å¿ƒé«˜åº¦
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "压装位拧紧扭力")]
        [ImporterHeader(Name = "中心高度")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "中心高度")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "中心高度")]
        public decimal? ScrewTorqueOutput { get; set; }
        /// <summary>
        /// åŽ‹è£…ä½è‡ªåŠ¨æ‹§ç´§ç¨‹åºå·
        /// </summary>
        [ImporterHeader(Name = "自动拧紧程序号")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "自动拧紧程序号")]
        [SugarColumn(IsNullable = true, ColumnDescription = "压装位自动拧紧程序号")]
        public int? DintAutoScrewOn { get; set; }
        /// <summary>
        /// åŽ‹è£…ä½ç´§å›ºæ‰­çŸ©
        /// </summary>
        [ImporterHeader(Name = "紧固扭矩")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "紧固扭矩")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "压装位紧固扭矩", DefaultValue = "0.00")]
        public decimal? PressFastenTorque { get; set; }
        /// <summary>
        /// P0P1宽度
        /// </summary>
        [ImporterHeader(Name = "P0P1宽度")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "P0P1宽度")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "P0P1宽度")]
        public decimal? P0P1Width { get; set; }
        /// <summary>
        /// P0P2宽度
        /// </summary>
        [ImporterHeader(Name = "P0P2宽度")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "P0P2宽度")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "P0P2宽度")]
        public decimal? P0P2Width { get; set; }
        /// <summary>
        /// P0P3宽度
        /// </summary>
        [ImporterHeader(Name = "P0P3宽度")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "P0P3宽度")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "P0P3宽度")]
        public decimal? P0P3Width { get; set; }
        /// <summary>
        /// P1P3高度
        /// åž«ç‰‡é«˜åº¦
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "P1P3高度")]
        public decimal? P1P3Height { get; set; }
        [ImporterHeader(Name = "垫片高度")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "垫片高度")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "垫片高度")]
        public decimal? GasketHeight { get; set; }
        /// <summary>
        /// P2P3高度
        /// åŽ‹è£…åŽ‹åŠ›å·®å€¼
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "P2P3高度")]
        public decimal? P2P3Height { get; set; }
        [ImporterHeader(Name = "压力差值")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "压力差值")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "压装压力差值")]
        public decimal? PressPressureDiff { get; set; }
        /// <summary>
        /// äº§å“å›¾ç‰‡è·¯å¾„
        /// åŽ‹è£…æ‰­åŠ›å·®å€¼
        /// </summary>
        [SugarColumn(IsNullable = true, Length = 500, ColumnDescription = "产品图片路径")]
        public string ProductImagePath { get; set; }
        [ImporterHeader(Name = "扭力差值")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "扭力差值")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "压装扭力差值")]
        public decimal? PressTorqueDiff { get; set; }
        /// <summary>
        /// æ£€æµ‹é«˜åº¦å·®å€¼
        /// </summary>
        [ImporterHeader(Name = "高度差值")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "高度差值")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "检测高度差值")]
        public decimal? DetectHeightDiff { get; set; }
        /// <summary>
        /// èžºçº¹ä½ç½®å·®å€¼
        /// </summary>
        [ImporterHeader(Name = "螺纹差值")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "螺纹差值")]
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "螺纹位置差值")]
        public decimal? ScrewPositionDiff { get; set; }
        [SugarColumn(IsIgnore = true)]//不参与数据库映射,测试使用
        [Navigate(NavigateType.OneToMany, nameof(Dt_FormulaDetail.FormulaId), nameof(Id))]
        public List<Dt_FormulaDetail> Details { get; set; }
    }
}
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/BasicInfo/Dt_FormulaDetail.cs
@@ -1,10 +1,12 @@
using SqlSugar;
using Magicodes.ExporterAndImporter.Core;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEAWCS_Core.DB.Models;
using Magicodes.IE.Core;
namespace WIDESEAWCS_Model.Models
{
@@ -14,35 +16,47 @@
        /// <summary>
        /// ä¸»é”®
        /// </summary>
        [ImporterHeader(IsIgnore = true)]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "主键")]
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "主键")]
        public int Id { get; set; }
        /// <summary>
        /// é…æ–¹ä¿¡æ¯ä¸»é”®
        /// </summary>
        [ImporterHeader(Name = "配方信息主键")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "配方信息主键")]
        [SugarColumn(IsNullable = false, ColumnDescription = "配方信息主键")]
        public int FormulaId { get; set; }
        /// <summary>
        /// é›¶ä»¶ç¼–号
        /// </summary>
        [ImporterHeader(Name = "零件编号")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "零件编号")]
        [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "零件编号")]
        public string ComponentCode { get; set; }
        /// <summary>
        /// é›¶ä»¶åç§°
        /// </summary>
        [ImporterHeader(Name = "零件名称")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "零件名称")]
        [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "零件名称")]
        public string ComponentName { get; set; }
        /// <summary>
        /// ä¾›æ–¹ä»£ç 
        /// </summary>
        [ImporterHeader(Name = "供方代码")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "供方代码")]
        [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "供方代码")]
        public string SupplierCode { get; set; }
        /// <summary>
        /// æ˜¯å¦æ‰«ç 
        /// </summary>
        [ImporterHeader(Name = "是否扫码")]
        [ExporterHeader(null, 11f, null, true, true, false, 0, KnownColor.Empty, DisplayName = "是否扫码")]
        [SugarColumn(IsNullable = true, DefaultValue = "0", ColumnDescription = "是否扫码")]
        public int IsScanned { get; set; }
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/BasicInfo/Dt_ProcessInfo.cs
@@ -42,12 +42,6 @@
        public string ProductSn { get; set; }
        /// <summary>
        /// åŽ‹è£…æ‹§ç´§_拧紧NG
        /// </summary>
        [SugarColumn(IsNullable = true, DefaultValue = "0", ColumnDescription = "压装拧紧_拧紧NG")]
        public int? PressTightenNg { get; set; }
        /// <summary>
        /// åŽ‹è£…æ‹§ç´§_拧紧OK
        /// </summary>
        [SugarColumn(IsNullable = true, DefaultValue = "0", ColumnDescription = "压装拧紧_拧紧OK")]
@@ -60,52 +54,13 @@
        public int? PressTightenUnfinished { get; set; }
        /// <summary>
        /// æ£€æµ‹_本次检测未完成
        /// äº§å“çŠ¶æ€
        /// 0 - ä¸åˆæ ¼
        /// 1 - åˆæ ¼
        /// 2 - äººå·¥ç¡®è®¤åˆæ ¼
        /// </summary>
        [SugarColumn(IsNullable = true, DefaultValue = "0", ColumnDescription = "检测_本次检测未完成")]
        public int? CheckUnfinished { get; set; }
        /// <summary>
        /// é›¶ä»¶æ•°é‡
        /// </summary>
        [SugarColumn(IsNullable = true, ColumnDescription = "零件数量")]
        public int? ComponentQty { get; set; }
        /// <summary>
        /// æ‰­åЛ值
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "扭力值")]
        public decimal? TorsioValue { get; set; }
        /// <summary>
        /// æ‰­åŠ›å€¼æ ‡å‡†
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "扭力值标准")]
        public decimal? TorsioValueStandard { get; set; }
        /// <summary>
        /// åˆšåº¦å€¼
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "刚度值")]
        public decimal? StiffnessValue { get; set; }
        /// <summary>
        /// åˆšåº¦å€¼æ ‡å‡†
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "刚度值标准")]
        public decimal? StiffnessValueStandard { get; set; }
        /// <summary>
        /// æµ‹è¯•结果
        /// </summary>
        [SugarColumn(IsNullable = true, ColumnDescription = "测试结果")]
        public int? TestResult { get; set; }
        /// <summary>
        /// åŽ‹è£…ä½ä¸‹åŽ‹æ£€æµ‹é«˜åº¦
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "压装位下压检测高度")]
        public decimal? PressHeight { get; set; }
        [SugarColumn(IsNullable = true, DefaultValue = "0", ColumnDescription = "产品状态")]
        public int? ProductStatus { get; set; }
        /// <summary>
        /// åŽ‹è£…ä½æ‹§ç´§æ£€æµ‹æ‰­åŠ›
@@ -126,6 +81,18 @@
        public decimal? PressPressure { get; set; }
        /// <summary>
        /// äº§å“æ£€æµ‹é«˜åº¦
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "产品检测高度")]
        public decimal? ProductCheckHeight { get; set; }
        /// <summary>
        /// èžºçº¹ä½ç½®é«˜åº¦
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "螺纹位置高度")]
        public decimal? ThreadPositionHeight { get; set; }
        /// <summary>
        /// æ‹§ç´§ä½æ£€æµ‹é«˜åº¦1
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "拧紧位检测高度1")]
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/BasicInfo/Dt_ProcessInfoDetail.cs
@@ -42,12 +42,6 @@
        public string ProductSn { get; set; }
        /// <summary>
        /// åŽ‹è£…æ‹§ç´§_拧紧NG
        /// </summary>
        [SugarColumn(IsNullable = true, DefaultValue = "0", ColumnDescription = "压装拧紧_拧紧NG")]
        public int? PressTightenNg { get; set; }
        /// <summary>
        /// åŽ‹è£…æ‹§ç´§_拧紧OK
        /// </summary>
        [SugarColumn(IsNullable = true, DefaultValue = "0", ColumnDescription = "压装拧紧_拧紧OK")]
@@ -60,52 +54,10 @@
        public int? PressTightenUnfinished { get; set; }
        /// <summary>
        /// æ£€æµ‹_本次检测未完成
        /// äº§å“çŠ¶æ€
        /// </summary>
        [SugarColumn(IsNullable = true, DefaultValue = "0", ColumnDescription = "检测_本次检测未完成")]
        public int? CheckUnfinished { get; set; }
        /// <summary>
        /// é›¶ä»¶æ•°é‡
        /// </summary>
        [SugarColumn(IsNullable = true, ColumnDescription = "零件数量")]
        public int? ComponentQty { get; set; }
        /// <summary>
        /// æ‰­åЛ值
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "扭力值")]
        public decimal? TorsioValue { get; set; }
        /// <summary>
        /// æ‰­åŠ›å€¼æ ‡å‡†
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "扭力值标准")]
        public decimal? TorsioValueStandard { get; set; }
        /// <summary>
        /// åˆšåº¦å€¼
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "刚度值")]
        public decimal? StiffnessValue { get; set; }
        /// <summary>
        /// åˆšåº¦å€¼æ ‡å‡†
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "刚度值标准")]
        public decimal? StiffnessValueStandard { get; set; }
        /// <summary>
        /// æµ‹è¯•结果
        /// </summary>
        [SugarColumn(IsNullable = true, ColumnDescription = "测试结果")]
        public int? TestResult { get; set; }
        /// <summary>
        /// åŽ‹è£…ä½ä¸‹åŽ‹æ£€æµ‹é«˜åº¦
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "压装位下压检测高度")]
        public decimal? PressHeight { get; set; }
        [SugarColumn(IsNullable = true, DefaultValue = "0", ColumnDescription = "产品状态")]
        public int? ProductStatus { get; set; }
        /// <summary>
        /// åŽ‹è£…ä½æ‹§ç´§æ£€æµ‹æ‰­åŠ›
@@ -126,6 +78,18 @@
        public decimal? PressPressure { get; set; }
        /// <summary>
        /// äº§å“æ£€æµ‹é«˜åº¦
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "产品检测高度")]
        public decimal? ProductCheckHeight { get; set; }
        /// <summary>
        /// èžºçº¹ä½ç½®é«˜åº¦
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "螺纹位置高度")]
        public decimal? ThreadPositionHeight { get; set; }
        /// <summary>
        /// æ‹§ç´§ä½æ£€æµ‹é«˜åº¦1
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "拧紧位检测高度1")]
@@ -142,6 +106,5 @@
        /// </summary>
        [SugarColumn(IsNullable = true, DecimalDigits = 2, ColumnDescription = "拧紧位检测高度3")]
        public decimal? Height3 { get; set; }
    }
}
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/BasicInfo/Dt_ScanStation.cs
@@ -59,62 +59,5 @@
        [SugarColumn(IsNullable = true, DefaultValue = "0", ColumnDescription = "是否扫码")]
        public int IsScanned { get; set; }
        ///// <summary>
        ///// é›¶ä»¶æ•°é‡
        ///// </summary>
        //[SugarColumn(IsNullable = true, ColumnDescription = "零件数量")]
        //public int StationComponentQty { get; set; }
        ///// <summary>
        ///// é›¶ä»¶1
        ///// </summary>
        //[SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "零件1")]
        //public string StationComponent1 { get; set; }
        ///// <summary>
        ///// é›¶ä»¶2
        ///// </summary>
        //[SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "零件2")]
        //public string StationComponent2 { get; set; }
        ///// <summary>
        ///// é›¶ä»¶3
        ///// </summary>
        //[SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "零件3")]
        //public string StationComponent3 { get; set; }
        ///// <summary>
        ///// é›¶ä»¶4
        ///// </summary>
        //[SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "零件4")]
        //public string StationComponent4 { get; set; }
        ///// <summary>
        ///// é›¶ä»¶5
        ///// </summary>
        //[SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "零件5")]
        //public string StationComponent5 { get; set; }
        ///// <summary>
        ///// é›¶ä»¶6
        ///// </summary>
        //[SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "零件6")]
        //public string StationComponent6 { get; set; }
        ///// <summary>
        ///// é›¶ä»¶7
        ///// </summary>
        //[SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "零件7")]
        //public string StationComponent7 { get; set; }
        ///// <summary>
        ///// é›¶ä»¶8
        ///// </summary>
        //[SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "零件8")]
        //public string StationComponent8 { get; set; }
        ///// <summary>
        ///// é›¶ä»¶9
        ///// </summary>
        //[SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "零件9")]
        //public string StationComponent9 { get; set; }
        ///// <summary>
        ///// é›¶ä»¶10
        ///// </summary>
        //[SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "零件10")]
        //public string StationComponent10 { get; set; }
    }
}
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/BasicInfo/BoxingController.cs
@@ -1,6 +1,13 @@
using Microsoft.AspNetCore.Mvc;
using Autofac.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using WIDESEAWCS_BasicInfoService;
using WIDESEAWCS_Common;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.BaseController;
using WIDESEAWCS_Core.BaseRepository;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_IBasicInfoService;
using WIDESEAWCS_Model.Models;
namespace WIDESEAWCS_Server.Controllers.BoxingInfo
@@ -12,10 +19,18 @@
    [ApiController]
    public class BoxingController : ApiBaseController<IBoxingService, Dt_Boxing>
    {
        public BoxingController(IBoxingService service) : base(service)
        {
        }
        //删除当前托盘
        [HttpPost, Route("DeleteCurrentTray"), AllowAnonymous]
        public WebResponseContent DeleteCurrentTray()
        {
            return Service.DeleteCurrentTray();
        }
    }
}
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/BasicInfo/BoxingDetailController.cs
@@ -13,7 +13,7 @@
    /// </summary>
    [Route("api/boxingDetail")]
    [ApiController]
    public class BoxingDetailController : ApiBaseController<IBoxingDetailService, Dt_Boxing>
    public class BoxingDetailController : ApiBaseController<IBoxingDetailService, Dt_BoxingDetail>
    {
        public BoxingDetailController(IBoxingDetailService service) : base(service)
        {
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/BasicInfo/ScanStationController.cs
@@ -83,9 +83,9 @@
        /// <param name="dt_ProcessInfo"></param>
        /// <returns></returns>
        [HttpPost, Route("ExportData"), AllowAnonymous]
        public WebResponseContent ExportData([FromBody] Dt_ScanStation dt_ScanStation)
        public WebResponseContent ExportData()
        {
            return Service.ExportData(dt_ScanStation);
            return Service.ExportData();
        }
    }
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/obj/Debug/net6.0/WIDESEAWCS_TaskInfoService.AssemblyInfo.cs
@@ -14,7 +14,7 @@
[assembly: System.Reflection.AssemblyCompanyAttribute("WIDESEAWCS_TaskInfoService")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+15b3879cd259108e7ebb755fe02c190f28f1e20c")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+8aa5f0e094e6ff51aa7c47d5b4e8331a16eb09ff")]
[assembly: System.Reflection.AssemblyProductAttribute("WIDESEAWCS_TaskInfoService")]
[assembly: System.Reflection.AssemblyTitleAttribute("WIDESEAWCS_TaskInfoService")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/obj/Debug/net6.0/WIDESEAWCS_TaskInfoService.AssemblyInfoInputs.cache
@@ -1 +1 @@
2fcc0eeacc37ee31f32434a719cbb8cb3eedf35ecc022754a7ce9ac39f254105
c97e13df12cbbd7b4f052106b0c5e3e54606d4e7d7c3571cbd36adfdc2f442d8
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_Tasks/PLCJob.cs
@@ -27,7 +27,6 @@
        private readonly IProcessInfoDetailService _processDetailInfoService;
        private readonly IUnitOfWorkManage _unitOfWorkManage;
        private readonly IScanStationService _scanStationService;
        //private readonly string PalletCode = "PL107";
        public PLCJob(IBoxingService boxingService,
            IBoxingDetailService boxingDetailService,
@@ -300,13 +299,23 @@
                    {
                        device.SetValue(W_PLCDBName.wboolLocation8ScanDone,true);
                    }
                    else
                    {
                        device.SetValue(W_PLCDBName.wboolLocation8ScanDone, false);
                    }
                    device.SetValue(W_PLCDBName.wrealProductLength, dt_Formula.ProductLength);
                    device.SetValue(W_PLCDBName.wrealProductWidth, dt_Formula.ProductWidth);
                    device.SetValue(W_PLCDBName.wrealProductHeight, dt_Formula.ProductHeight);
                    device.SetValue(W_PLCDBName.wrealProductHeight, dt_Formula.ProductHeight + dt_Formula.GasketHeight);
                    device.SetValue(W_PLCDBName.wrealScrewDownsetDistance, dt_Formula.ScrewDownsetDistance);
                    //中心高度
                    device.SetValue(W_PLCDBName.wrealScrewTorque, dt_Formula.ScrewTorqueOutput);
                    device.SetValue(W_PLCDBName.wrealScrewTorque, dt_Formula.ScrewTorqueOutput + dt_Formula.GasketHeight);
                    device.SetValue(W_PLCDBName.wrealAutoScrewProgramNo, dt_Formula.DintAutoScrewOn);
                    device.SetValue(W_PLCDBName.wrealPressPressure, dt_Formula.PressPressureDiff);
                    device.SetValue(W_PLCDBName.wrealTighteningTorque, dt_Formula.PressTorqueDiff);
                    device.SetValue(W_PLCDBName.wrealFastenTorque, dt_Formula.PressFastenTorque);
                    //压装扫码完成
                    device.SetValue(W_PLCDBName.wboolLocation2ScanDone, true);
@@ -354,11 +363,9 @@
                    //接收数据
                    decimal PressHeight = (decimal)device.GetValue<R_PLCDBName, float>(R_PLCDBName.rrealDetectPressHeight);
                    decimal ScrewTorque = (decimal)device.GetValue<R_PLCDBName, float>(R_PLCDBName.rrealDetectScrewTorque);
                    decimal ScrewAngle = (decimal)device.GetValue<R_PLCDBName, float>(R_PLCDBName.rrealDetectScrewAngle);
                    decimal PressPressure = (decimal)device.GetValue<R_PLCDBName, float>(R_PLCDBName.rrealDetectPressForce);
                    bool PressTightenNg = device.GetValue<R_PLCDBName, bool>(R_PLCDBName.rrealPressScrewByScrewNG);
                    bool PressTightenOk = device.GetValue<R_PLCDBName, bool>(R_PLCDBName.rrealPressScrewByScrewOK);
                    bool PressTightenUnfinished = device.GetValue<R_PLCDBName, bool>(R_PLCDBName.rrealPressScrewByProcessUnfinished);
@@ -371,14 +378,22 @@
                        ProductCode = dt_Formula.ProductCode,
                        ProductName = dt_Formula.ProductName,
                        ProductSn = dt_Boxing.BoxingNo,
                        PressTightenNg = PressTightenNg?1:0,
                        ProductStatus = 1,
                        PressTightenOk = PressTightenOk?1:0,
                        PressTightenUnfinished = PressTightenUnfinished?1:0,
                        PressHeight = PressHeight,
                        ScrewTorque = ScrewTorque,
                        ScrewAngle = ScrewAngle,
                        PressPressure = PressPressure,
                    };
                    if (
                        PressPressure > dt_Formula.ScrewDownsetDistance + dt_Formula.PressPressureDiff || PressPressure < dt_Formula.ScrewDownsetDistance - dt_Formula.PressPressureDiff ||
                        ScrewTorque > dt_Formula.PressFastenTorque + dt_Formula.PressTorqueDiff || ScrewTorque < dt_Formula.PressFastenTorque - dt_Formula.PressTorqueDiff
                        )
                    {
                        dt_ProcessInfo.ProductStatus = 0;
                    }
                    _processInfoService.Repository.AddData(dt_ProcessInfo);
                    // åŽ‹è£…ä¿¡æ¯ä¸Šä¼ å®Œæˆ
@@ -427,14 +442,27 @@
                        return;
                    }
                    Dt_Formula dt_Formula = _formulaService.Repository.QueryFirst(x => x.ProductCode == dt_Boxing.ProductCode);
                    if(dt_Formula.PressNoCheckBottomPlate == 1)
                    {
                        device.SetValue(W_PLCDBName.wboolLocation9ScanDone, true);
                    }
                    else
                    {
                        device.SetValue(W_PLCDBName.wboolLocation9ScanDone, false);
                    }
                    //写入PLC
                    device.SetValue(W_PLCDBName.wrealCheckPalletCode, dt_Boxing.Id % 100);
                    device.SetValue(W_PLCDBName.wrealP0P1Width, dt_Formula.P0P1Width);
                    device.SetValue(W_PLCDBName.wrealP0P2Width, dt_Formula.P0P2Width);
                    device.SetValue(W_PLCDBName.wrealP0P3Width, dt_Formula.P0P3Width);
                    device.SetValue(W_PLCDBName.wrealP0P3Width, dt_Formula.P0P3Width);
                    device.SetValue(W_PLCDBName.wrealP1P3Height, dt_Formula.P1P3Height);
                    device.SetValue(W_PLCDBName.wrealP2P3Height, dt_Formula.P2P3Height);
                    device.SetValue(W_PLCDBName.wrealP1P3Height, dt_Formula.ScrewTorqueOutput + dt_Formula.GasketHeight);
                    device.SetValue(W_PLCDBName.wrealP2P3Height, dt_Formula.ProductHeight + dt_Formula.GasketHeight);
                    device.SetValue(W_PLCDBName.wrealProdHeightDiff, dt_Formula.DetectHeightDiff);
                    device.SetValue(W_PLCDBName.wrealScrewHeight, dt_Formula.ScrewPositionDiff);
                    //检测扫码完成
                    device.SetValue(W_PLCDBName.wboolLocation3ScanDone, true);
@@ -486,7 +514,14 @@
                    decimal Height1 = (decimal)device.GetValue<R_PLCDBName, float>(R_PLCDBName.rrealDetectHeight1);//113
                    decimal Height2 = (decimal)device.GetValue<R_PLCDBName, float>(R_PLCDBName.rrealDetectHeight2);//92
                    decimal Height3 = (decimal)device.GetValue<R_PLCDBName, float>(R_PLCDBName.rrealDetectHeight3);//11
                    bool CheckUnfinished = device.GetValue<R_PLCDBName, bool>(R_PLCDBName.rrealDetectByInspectUnfinished);
                    if(dt_Formula.PressNoCheckBottomPlate == 1)
                    {
                        Height3 = 0;
                    }
                    //bool CheckUnfinished = device.GetValue<R_PLCDBName, bool>(R_PLCDBName.rrealDetectByInspectUnfinished);
                    Dt_ProcessInfo dt_ProcessInfo = _processInfoService.Repository.QueryFirst(x => x.PalletCode == dt_Boxing.PalletCode);
                    int id = 0;
@@ -498,7 +533,6 @@
                            ProductCode = dt_Formula.ProductCode,
                            ProductName = dt_Formula.ProductName,
                            ProductSn = dt_Boxing.BoxingNo,
                            CheckUnfinished = CheckUnfinished?1:0,
                        };
                        id = _processInfoService.Repository.AddData(dt_ProcessInfo);
                    }
@@ -506,10 +540,23 @@
                    {
                        id = dt_ProcessInfo.Id;
                    }
                    decimal? ThreadPositionHeight = Height1 - Height3 - dt_Formula.GasketHeight;
                    decimal? ProductCheckHeight = Height2 - Height3 - dt_Formula.GasketHeight;
                    dt_ProcessInfo.Id = id;
                    dt_ProcessInfo.Height1 = Height1 = Height1 - Height3;
                    dt_ProcessInfo.Height2 = Height2 = Height2 - Height3;
                    dt_ProcessInfo.ThreadPositionHeight = ThreadPositionHeight;
                    dt_ProcessInfo.ProductCheckHeight = ProductCheckHeight;
                    dt_ProcessInfo.Height1 = Height1;
                    dt_ProcessInfo.Height2 = Height2;
                    dt_ProcessInfo.Height3 = Height3;
                    if(
                        ProductCheckHeight > dt_Formula.ProductHeight + dt_Formula.DetectHeightDiff || ProductCheckHeight < dt_Formula.ProductHeight - dt_Formula.DetectHeightDiff ||
                        ThreadPositionHeight > dt_Formula.ScrewTorqueOutput + dt_Formula.ScrewPositionDiff || ThreadPositionHeight < dt_Formula.ScrewTorqueOutput - dt_Formula.ScrewPositionDiff
                        )
                    {
                        dt_ProcessInfo.ProductStatus = 0;
                    }
                    _processInfoService.Repository.UpdateData(dt_ProcessInfo);
                    //检测信息上传完成
@@ -551,16 +598,22 @@
                            throw new InvalidOperationException("托盘为空");
                        }
                        Dt_Boxing dt_Boxing = _boxingService.Repository.QueryFirst(x => x.PalletCode == PalletCode);
                        WriteInfo("下线扫码组盘数据",$"{PalletCode}_boxingService查询{dt_Boxing}");
                        if (dt_Boxing != null)
                        {
                            WriteInfo("下线扫码组盘数据", $"{PalletCode}_boxingService删除{dt_Boxing}");
                            _boxingService.Repository.DeleteData(dt_Boxing);
                            List<Dt_BoxingDetail> dt_BoxingDetails = _boxingDetailService.Repository.QueryData(x => x.BoxingId == dt_Boxing.Id);
                            if (dt_BoxingDetails != null)
                            {
                                WriteInfo("下线扫码组盘数据", $"{PalletCode}_boxingService删除{dt_BoxingDetails}");
                                _boxingDetailService.Repository.DeleteData(dt_BoxingDetails);
                            }
                        }
                        Dt_ProcessInfo dt_ProcessInfo = _processInfoService.Repository.QueryFirst(x => x.PalletCode == PalletCode);
                        WriteInfo("下线扫码组盘数据", $"{PalletCode}_processInfoService查询{dt_ProcessInfo}");
                        if (dt_ProcessInfo != null)
                        {
                            Dt_ProcessInfoDetail dt_ProcessInfoDetail = new Dt_ProcessInfoDetail()
@@ -569,14 +622,14 @@
                                ProductCode = dt_ProcessInfo.ProductCode?.ToString() ?? "",
                                ProductName = dt_ProcessInfo.ProductName?.ToString() ?? "",
                                ProductSn = dt_ProcessInfo.ProductSn,
                                PressTightenNg = dt_ProcessInfo.PressTightenNg,
                                PressTightenOk = dt_ProcessInfo.PressTightenOk,
                                PressTightenUnfinished = dt_ProcessInfo.PressTightenUnfinished,
                                CheckUnfinished = dt_ProcessInfo.CheckUnfinished,
                                PressHeight = dt_ProcessInfo.PressHeight,
                                ProductStatus = dt_ProcessInfo.ProductStatus,
                                ScrewTorque = dt_ProcessInfo.ScrewTorque,
                                ScrewAngle = dt_ProcessInfo.ScrewAngle,
                                PressPressure = dt_ProcessInfo.PressPressure,
                                ThreadPositionHeight = dt_ProcessInfo.ThreadPositionHeight,
                                ProductCheckHeight = dt_ProcessInfo.ProductCheckHeight,
                                Height1 = dt_ProcessInfo.Height1,
                                Height2 = dt_ProcessInfo.Height2,
                                Height3 = dt_ProcessInfo.Height3,
@@ -584,7 +637,9 @@
                                CreateDate = DateTime.Now
                            };
                            _processDetailInfoService.Repository.AddData(dt_ProcessInfoDetail);
                            WriteInfo("下线扫码组盘数据", $"{PalletCode}_processInfoService删除{dt_ProcessInfo}");
                            _processInfoService.DeleteData(dt_ProcessInfo);
                        }
                        uow.Commit();
                        //下线扫码完成
ÏîÄ¿×ÊÁÏ/·¢µç»úµ¯ÐÔÖ§³ÅBOM½á¹¹¼°¹¤ÒÕ²ÎÊý.pdf
Binary files differ
ÏîÄ¿×ÊÁÏ/·¢µç»úµ¯ÐÔÖ§³ÅÐÅÏ¢»¯Á÷³Ì¿¨-×¢ÊÍ.pdf
Binary files differ