heshaofeng
5 天以前 18ca3750ce28d407afb518cadecdd29d79876c8b
Merge branch 'master' of http://115.159.85.185:8098/r/ZhongRui/ALDbanyunxiangmu
已修改15个文件
1559 ■■■■■ 文件已修改
项目代码/WIDESEA_WMSClient/src/extension/check/extend/StockSelect.vue 150 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js 340 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue 716 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/stock/stockView.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/outbound/outboundOrder.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/stock/stockView.vue 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs 73 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Common/TaskEnum/TaskTypeEnum.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_StockService/StockViewService.cs 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_DictionaryService.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/check/extend/StockSelect.vue
@@ -38,6 +38,53 @@
          </el-row>
        </el-alert>
      </div>
      <!-- æ–°å¢žç­›é€‰åŒºåŸŸ -->
      <div class="filter-area" style="margin: 10px 0; padding: 10px; background: #f8f9fa; border-radius: 4px;">
        <el-form :model="filterForm" inline @submit.prevent>
          <el-form-item label="物料编号:">
            <el-input
              v-model="filterForm.materielCode"
              placeholder="模糊筛选物料编号"
              clearable
              style="width: 180px"
              @input="filterTable"
            ></el-input>
          </el-form-item>
          <el-form-item label="物料条码:">
            <el-input
              v-model="filterForm.barcode"
              placeholder="模糊筛选物料条码"
              clearable
              style="width: 180px"
              @input="filterTable"
            ></el-input>
          </el-form-item>
          <el-form-item label="托盘编号:">
            <el-input
              v-model="filterForm.palletCode"
              placeholder="模糊筛选托盘编号"
              clearable
              style="width: 180px"
              @input="filterTable"
            ></el-input>
          </el-form-item>
          <el-form-item label="货位编号:">
            <el-input
              v-model="filterForm.locationCode"
              placeholder="模糊筛选货位编号"
              clearable
              style="width: 180px"
              @input="filterTable"
            ></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="filterTable">搜索</el-button>
            <el-button @click="resetFilter">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
      <div class="box-table" style="margin-top: 1%">
        <el-table
          ref="singleTable"
@@ -134,6 +181,7 @@
      row: null,
      showDetialBox: false, 
      tableData: [],
      originalTableData: [], // æ–°å¢žï¼šå­˜å‚¨åŽŸå§‹æ•°æ®ï¼Œç”¨äºŽç­›é€‰
      tableColumns: [
        { prop: "materielCode", title: "物料编号", type: "string", width: 150 },
        { prop: "barcode", title: "物料条码", type: "string", width: 150 },
@@ -145,6 +193,14 @@
      selectionSum: 0,
      selectionClass: "less-style",
      originalQuantity: 0,
      // æ–°å¢žï¼šç­›é€‰è¡¨å•数据
      filterForm: {
        materielCode: "",
        barcode: "",
        palletCode: "",
        locationCode: ""
      },
      // å‡ºåº“弹窗相关数据
      showOutboundDialog: false,
@@ -201,23 +257,22 @@
      this.$refs.outboundFormRef.validate((valid) => {
        if (!valid) return;
     if (this.selection.length <= 0) {
        return this.$message.error("请勾选");
      }
      let url = this.pkcx
        ? "api/Task/GenerateOutboundTask?orderDetailId="
        : "api/Task/GenerateOutboundTask?orderDetailId=";
      this.http
        .post(url + this.row.id+"&station="+this.outboundForm.selectedPlatform, this.selection, "数据处理中")
        .then((x) => {
          if (!x.status) return this.$message.error(x.message);
          this.$message.success("操作成功");
          this.showDetialBox = false;
          this.$emit("parentCall", ($vue) => {
            $vue.getData();
        if (this.selection.length <= 0) {
          return this.$message.error("请勾选");
        }
        let url = this.pkcx
          ? "api/Task/GenerateOutboundTask?orderDetailId="
          : "api/Task/GenerateOutboundTask?orderDetailId=";
        this.http
          .post(url + this.row.id+"&station="+this.outboundForm.selectedPlatform, this.selection, "数据处理中")
          .then((x) => {
            if (!x.status) return this.$message.error(x.message);
            this.$message.success("操作成功");
            this.showDetialBox = false;
            this.$emit("parentCall", ($vue) => {
              $vue.getData();
            });
          });
        });
      });
    },
@@ -233,11 +288,14 @@
        )
        .then((x) => {
          this.tableData = x;
          this.originalTableData = x; // æ–°å¢žï¼šä¿å­˜åŽŸå§‹æ•°æ®
          // åˆ·æ–°åŽæ¸…空之前的选择和计数
          this.clearSelection();
          this.selectionSum = 0;
          this.originalQuantity = 0;
          this.updateSelectionClass();
          // åˆ·æ–°åŽé‡ç½®ç­›é€‰æ¡ä»¶
          this.resetFilter();
        });
    },
@@ -271,9 +329,10 @@
    // æ›´æ–°å·²é€‰æ•°é‡æ ·å¼
    updateSelectionClass() {
      if (!this.row) return;
      if (this.selectionSum === this.row.orderQuantity) {
      // ä¿®å¤ï¼šrow.orderQuantity æ”¹ä¸º row.qty(模板里显示的是row.qty)
      if (this.selectionSum === this.row.qty) {
        this.selectionClass = "equle-style";
      } else if (this.selectionSum < this.row.orderQuantity) {
      } else if (this.selectionSum < this.row.qty) {
        this.selectionClass = "less-style";
      } else {
        this.selectionClass = "more-style";
@@ -298,6 +357,55 @@
    tableButtonClick(row, item) {
      console.log("图标按钮点击:", item.title, row);
    },
    // æ–°å¢žï¼šç­›é€‰è¡¨æ ¼æ•°æ®
    filterTable() {
      if (!this.originalTableData.length) return;
      // è§£æž„筛选条件并转为小写(忽略大小写)
      const { materielCode, barcode, palletCode, locationCode } = this.filterForm;
      const mc = materielCode.toLowerCase().trim();
      const bc = barcode.toLowerCase().trim();
      const pc = palletCode.toLowerCase().trim();
      const lc = locationCode.toLowerCase().trim();
      // æ¨¡ç³Šç­›é€‰é€»è¾‘
      this.tableData = this.originalTableData.filter(item => {
        // æ¯ä¸ªå­—段都做空值处理和小写转换,支持模糊匹配
        const itemMc = (item.materielCode || "").toLowerCase();
        const itemBc = (item.barcode || "").toLowerCase();
        const itemPc = (item.palletCode || "").toLowerCase();
        const itemLc = (item.locationCode || "").toLowerCase();
        return (
          itemMc.includes(mc) &&
          itemBc.includes(bc) &&
          itemPc.includes(pc) &&
          itemLc.includes(lc)
        );
      });
      // ç­›é€‰åŽæ¸…空选择状态
      this.clearSelection();
      this.selectionSum = 0;
      this.updateSelectionClass();
    },
    // æ–°å¢žï¼šé‡ç½®ç­›é€‰æ¡ä»¶
    resetFilter() {
      this.filterForm = {
        materielCode: "",
        barcode: "",
        palletCode: "",
        locationCode: ""
      };
      // æ¢å¤åŽŸå§‹æ•°æ®
      this.tableData = [...this.originalTableData];
      // é‡ç½®é€‰æ‹©çŠ¶æ€
      this.clearSelection();
      this.selectionSum = 0;
      this.updateSelectionClass();
    }
  },
};
</script>
@@ -314,6 +422,12 @@
.more-style {
  color: red;
}
/* ç­›é€‰åŒºåŸŸæ ·å¼ä¼˜åŒ– */
.filter-area :deep(.el-form-item) {
  margin-bottom: 0;
  margin-right: 10px;
}
</style>
<style>
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js
@@ -1,4 +1,3 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
import http from '@/api/http.js'
import { h, createVNode, render, reactive, ref } from 'vue';
@@ -44,159 +43,159 @@
          this.$emit('openPalletDialog', targetRow.inboundOrderNo);
        }
      },
     {
                name: '撤销组盘',
                type: 'primary',
                value: '撤销组盘',
                onClick: function () {
                    console.log('撤销组盘按钮被点击');
                    const mountNode = document.createElement('div');
                    document.body.appendChild(mountNode);
      {
        name: '撤销组盘',
        type: 'primary',
        value: '撤销组盘',
        onClick: function () {
          console.log('撤销组盘按钮被点击');
          const mountNode = document.createElement('div');
          document.body.appendChild(mountNode);
                    // å“åº”式表单数据:托盘号(必填)
                    const formData = reactive({
                        palletCode: '', // æ‰˜ç›˜å·è¾“入框
                        barcode:''
                    });
          // å“åº”式表单数据:托盘号(必填)
          const formData = reactive({
            palletCode: '', // æ‰˜ç›˜å·è¾“入框
            barcode: ''
          });
                    // æäº¤è¡¨å•的统一逻辑
                    const submitForm = async () => {
                        const formRef = vnode.component.refs.cancelPalletForm;
                        try {
                            // æ‰§è¡Œè¡¨å•校验(托盘号必填)
                            await formRef.validate();
                        } catch (err) {
                            ElMessage.warning('请输入有效的托盘号');
                            return;
                        }
          // æäº¤è¡¨å•的统一逻辑
          const submitForm = async () => {
            const formRef = vnode.component.refs.cancelPalletForm;
            try {
              // æ‰§è¡Œè¡¨å•校验(托盘号必填)
              await formRef.validate();
            } catch (err) {
              ElMessage.warning('请输入有效的托盘号');
              return;
            }
                        // å‘起撤销组盘请求
                        try {
                            //console.log('发起撤销组盘请求,托盘号:', formData.palletCode.trim());
                            const response = await http.post('/api/InboundOrder/UndoPalletGroup?palletCode='+formData.palletCode.trim()+'&barcode='+formData.barcode.trim());
            // å‘起撤销组盘请求
            try {
              //console.log('发起撤销组盘请求,托盘号:', formData.palletCode.trim());
              const response = await http.post('/api/InboundOrder/UndoPalletGroup?palletCode=' + formData.palletCode.trim() + '&barcode=' + formData.barcode.trim());
                            const { status, message, data } = response;
                            if (status) {
                                ElMessage.success(response.message);
                                console.log(response.message)
                                this.refresh(); // æˆåŠŸåŽåˆ·æ–°åˆ—è¡¨
                                // å…³é—­å¯¹è¯æ¡†
                                render(null, mountNode);
                                document.body.removeChild(mountNode);
                            } else {
                                console.log('撤销组盘失败,后端提示:', message);
                                ElMessage.error(message || data?.message || '撤销组盘失败');
                                selectPalletCodeInput(); // é€‰ä¸­è¾“入框方便重新输入
                            }
                        } catch (error) {
                            console.error('撤销组盘请求异常:', error);
                            ElMessage.error('网络异常或接口错误,请稍后重试');
                            selectPalletCodeInput();
                        }
                    };
                    // é€‰ä¸­è¾“入框文本(方便重新输入)
                    const selectPalletCodeInput = () => {
                        setTimeout(() => {
                            const inputRef = vnode.component.refs.palletCodeInput;
                            if (inputRef) {
                                const targetInput = inputRef.$el?.querySelector('input') || inputRef;
                                targetInput?.focus();
                                targetInput?.select();
                            }
                        }, 100);
                    };
              const { status, message, data } = response;
              if (status) {
                ElMessage.success(response.message);
                console.log(response.message)
                this.refresh(); // æˆåŠŸåŽåˆ·æ–°åˆ—è¡¨
                // å…³é—­å¯¹è¯æ¡†
                render(null, mountNode);
                document.body.removeChild(mountNode);
              } else {
                console.log('撤销组盘失败,后端提示:', message);
                ElMessage.error(message || data?.message || '撤销组盘失败');
                selectPalletCodeInput(); // é€‰ä¸­è¾“入框方便重新输入
              }
            } catch (error) {
              console.error('撤销组盘请求异常:', error);
              ElMessage.error('网络异常或接口错误,请稍后重试');
              selectPalletCodeInput();
            }
          };
                    // åˆ›å»ºå¯¹è¯æ¡†VNode
                    const vnode = createVNode(ElDialog, {
                        title: '撤销组盘',
                        width: '400px',
                        modelValue: true,
                        appendToBody: true,
                        onOpened: () => {
                            // å¯¹è¯æ¡†æ‰“开后自动聚焦输入框
                            setTimeout(() => {
                                const inputRef = vnode.component.refs.palletCodeInput;
                                inputRef?.focus();
                            }, 100);
                        },
                        'onUpdate:modelValue': (isVisible) => {
                            if (!isVisible) {
                                render(null, mountNode);
                                document.body.removeChild(mountNode);
                            }
                        }
                    }, {
                        default: () => h(ElForm, {
                            model: formData,
                            rules: {
                                palletCode: [
                                    { required: true, message: '请输入托盘号', trigger: ['blur', 'enter'] },
                                    { min: 1, max: 50, message: '托盘号长度不能超过50个字符', trigger: ['blur', 'input'] }
                                ]
                            },
                            ref: 'cancelPalletForm'
                        }, [
                            // æ‰˜ç›˜å·è¾“入项
                            h(ElFormItem, { label: '托盘号', prop: 'palletCode', required: true }, [
                                h(ElInput, {
                                    type: 'text',
                                    modelValue: formData.palletCode,
                                    'onUpdate:modelValue': (val) => {
                                        formData.palletCode = val;
                                    },
                                    ref: 'palletCodeInput',
                                    placeholder: '扫码输入或手动输入托盘号',
                                    maxLength: 50,
                                    // ç›‘听回车事件(扫码枪默认会发送回车)
                                    onKeydown: (e) => {
                                        if (e.key === 'Enter') {
                                            e.preventDefault();
                                            submitForm();
                                        }
                                    }
                                })
                            ]),
                            h(ElFormItem,{label: '条码', prop: 'barcode'},[
                              h(ElInput, {
                                type: 'text',
                                modelValue: formData.barcode,
                                'onUpdate:modelValue': (val) => {
                                    formData.barcode = val;
                                },
                                placeholder: '可选,扫码输入或手动输入条码',
                                maxLength: 50,
                                onKeydown: (e) => {
                                    if (e.key === 'Enter') {
                                        e.preventDefault();
                                        submitForm();
                                    }
                                  }
                              })
                            ]),
                            // åº•部按钮区
                            h('div', { style: { textAlign: 'right', marginTop: '16px' } }, [
                                h(ElButton, {
                                    type: 'text',
                                    onClick: () => {
                                        render(null, mountNode);
                                        document.body.removeChild(mountNode);
                                        ElMessage.info('取消撤销组盘');
                                    }
                                }, '取消'),
                                h(ElButton, {
                                    type: 'primary',
                                    onClick: submitForm.bind(this) // ç»‘定this上下文
                                }, '确认撤销')
                            ])
                        ])
                    });
          // é€‰ä¸­è¾“入框文本(方便重新输入)
          const selectPalletCodeInput = () => {
            setTimeout(() => {
              const inputRef = vnode.component.refs.palletCodeInput;
              if (inputRef) {
                const targetInput = inputRef.$el?.querySelector('input') || inputRef;
                targetInput?.focus();
                targetInput?.select();
              }
            }, 100);
          };
                    vnode.appContext = this.$.appContext;
                    render(vnode, mountNode);
                }
          // åˆ›å»ºå¯¹è¯æ¡†VNode
          const vnode = createVNode(ElDialog, {
            title: '撤销组盘',
            width: '400px',
            modelValue: true,
            appendToBody: true,
            onOpened: () => {
              // å¯¹è¯æ¡†æ‰“开后自动聚焦输入框
              setTimeout(() => {
                const inputRef = vnode.component.refs.palletCodeInput;
                inputRef?.focus();
              }, 100);
            },
            'onUpdate:modelValue': (isVisible) => {
              if (!isVisible) {
                render(null, mountNode);
                document.body.removeChild(mountNode);
              }
            }
          }, {
            default: () => h(ElForm, {
              model: formData,
              rules: {
                palletCode: [
                  { required: true, message: '请输入托盘号', trigger: ['blur', 'enter'] },
                  { min: 1, max: 50, message: '托盘号长度不能超过50个字符', trigger: ['blur', 'input'] }
                ]
              },
              ref: 'cancelPalletForm'
            }, [
              // æ‰˜ç›˜å·è¾“入项
              h(ElFormItem, { label: '托盘号', prop: 'palletCode', required: true }, [
                h(ElInput, {
                  type: 'text',
                  modelValue: formData.palletCode,
                  'onUpdate:modelValue': (val) => {
                    formData.palletCode = val;
                  },
                  ref: 'palletCodeInput',
                  placeholder: '扫码输入或手动输入托盘号',
                  maxLength: 50,
                  // ç›‘听回车事件(扫码枪默认会发送回车)
                  onKeydown: (e) => {
                    if (e.key === 'Enter') {
                      e.preventDefault();
                      submitForm();
                    }
                  }
                })
              ]),
              h(ElFormItem, { label: '条码', prop: 'barcode' }, [
                h(ElInput, {
                  type: 'text',
                  modelValue: formData.barcode,
                  'onUpdate:modelValue': (val) => {
                    formData.barcode = val;
                  },
                  placeholder: '可选,扫码输入或手动输入条码',
                  maxLength: 50,
                  onKeydown: (e) => {
                    if (e.key === 'Enter') {
                      e.preventDefault();
                      submitForm();
                    }
                  }
                })
              ]),
              // åº•部按钮区
              h('div', { style: { textAlign: 'right', marginTop: '16px' } }, [
                h(ElButton, {
                  type: 'text',
                  onClick: () => {
                    render(null, mountNode);
                    document.body.removeChild(mountNode);
                    ElMessage.info('取消撤销组盘');
                  }
                }, '取消'),
                h(ElButton, {
                  type: 'primary',
                  onClick: submitForm.bind(this) // ç»‘定this上下文
                }, '确认撤销')
              ])
            ])
          });
          vnode.appContext = this.$.appContext;
          render(vnode, mountNode);
        }
      },
      {
        name: '分批入库',
        type: 'primary',
@@ -427,30 +426,30 @@
    //下面这些方法可以保留也可以删除
    onInit() {
      this.columns.forEach(column => {
      if (column.field === 'orderStatistics') {
        column.formatter = (row) => {
          // æ ¡éªŒdetails是否存在且有数据
          if (row.details && row.details.length > 0) {
            //按materielCode分组统计orderQuantity总和
            const materielSumMap = row.details.reduce((acc, item) => {
              const materielCode = item.materielCode || '未知物料';
              const quantity = Number(item.orderQuantity) || 0;
              acc[materielCode] = (acc[materielCode] || 0) + quantity;
              return acc;
            }, {});
        if (column.field === 'orderStatistics') {
          column.formatter = (row) => {
            // æ ¡éªŒdetails是否存在且有数据
            if (row.details && row.details.length > 0) {
              //按materielCode分组统计orderQuantity总和
              const materielSumMap = row.details.reduce((acc, item) => {
                const materielCode = item.materielCode || '未知物料';
                const quantity = Number(item.orderQuantity) || 0;
                acc[materielCode] = (acc[materielCode] || 0) + quantity;
                return acc;
              }, {});
            //每个物料项生成独立div,跨行显示
            const displayItems = Object.entries(materielSumMap).map(([code, total]) => {
              return `<div style="line-height: 1.5; white-space: normal;">${code}:${total}个</div>`;
            });
            const displayContent = displayItems.join('');
            return `<div style="color: #F56C6C; white-space: normal; word-break: break-all;">${displayContent}</div>`;
          } else {
            return '<span style="color: #F56C6C">无入库明细</span>';
          }
        };
      }
    });
              //每个物料项生成独立div,跨行显示
              const displayItems = Object.entries(materielSumMap).map(([code, total]) => {
                return `<div style="line-height: 1.5; white-space: normal;">${code}:${total}个</div>`;
              });
              const displayContent = displayItems.join('');
              return `<div style="color: #F56C6C; white-space: normal; word-break: break-all;">${displayContent}</div>`;
            } else {
              return '<span style="color: #F56C6C">无入库明细</span>';
            }
          };
        }
      });
    },
    onInited() {
@@ -473,7 +472,6 @@
      return true;
    },
    searchAfter(result) {
      //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
      return true;
    },
    addBefore(formData) {
@@ -498,4 +496,4 @@
    }
  }
};
export default extension;
export default extension;
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue
@@ -14,39 +14,34 @@
              <span>已选中 {{ selection.length }} é¡¹</span>
            </el-col>
            <el-col :span="8">
          <!--     <el-link
                type="primary"
                size="small"
                style="float: right; height: 20px"
                @click="lockstocks"
                >锁定库存</el-link> -->
              <el-link
                type="primary"
                size="small"
                    v-if="isBatch === 0"
                v-if="isBatch === 0"
                style="float: right; height: 20px"
                @click="handleOpenPicking"
                >拣选</el-link>
                        <el-link
                >拣选</el-link
              >
              <el-link
                type="primary"
                size="small"
                style="float: right; height: 20px; margin-right: 10px"
                  v-if="isBatch === 1"
                v-if="isBatch === 1"
                @click="handleOpenBatchPicking"
                >分批拣选</el-link>
                >分批拣选</el-link
              >
              <el-link
                type="primary"
                size="small"
                   v-if="isBatch === 0"
                v-if="isBatch === 0"
                style="float: right; height: 20px; margin-right: 10px"
                @click="outbound"
                >直接出库</el-link
              >
               <el-link
              <el-link
                type="primary"
                size="small"
                 v-if="isBatch === 1"
                v-if="isBatch === 1"
                style="float: right; height: 20px; margin-right: 10px"
                @click="outboundbatch"
                >分批出库</el-link
@@ -57,8 +52,8 @@
                style="float: right; height: 20px; margin-right: 10px"
                @click="getData"
                >刷新</el-link
              ></el-col
            >
              >
            </el-col>
          </el-row>
        </el-alert>
      </div>
@@ -96,18 +91,23 @@
                  effect="dark"
                  :content="item.title"
                  placement="bottom"
                  ><el-link
                >
                  <el-link
                    type="primary"
                    :disabled="getButtonEnable(item.prop, scoped.row)"
                    @click="tableButtonClick(scoped.row, item)"
                    ><i :class="item.icon" style="font-size: 22px"></i></el-link
                ></el-tooltip>
                  >
                    <i :class="item.icon" style="font-size: 22px"></i>
                  </el-link>
                </el-tooltip>
              </div>
              <div v-else-if="item.type == 'tag'">
                <el-tag size="small">
                  {{ getDictionary(scoped.row, item) }}
                </el-tag>
              </div>
              <div v-else>
                {{ scoped.row[item.prop] }}
              </div>
            </template>
          </el-table-column>
@@ -122,27 +122,37 @@
    <NoStockOut ref="NoStockOut" @parentCall="parentCall"></NoStockOut>
  </div>
</template>
<script>
import VolBox from "@/components/basic/VolBox.vue";
import VolForm from "@/components/basic/VolForm.vue";
import StockSelect from "./StockSelect.vue";
import SelectedStock from "./SelectedStock.vue";
import NoStockOut from "./NoStockOut.vue";
import { h,createVNode, render,reactive  } from 'vue';
import { ElDialog , ElForm, ElFormItem, ElSelect,ElOption, ElButton, ElInput, ElMessage } from 'element-plus';
import { th } from 'element-plus/es/locale';
import { h, createVNode, render, reactive } from "vue";
import {
  ElDialog,
  ElForm,
  ElFormItem,
  ElSelect,
  ElOption,
  ElButton,
  ElInput,
  ElMessage,
} from "element-plus";
export default {
  components: { VolBox, VolForm, StockSelect, SelectedStock,NoStockOut},
  components: { VolBox, VolForm, StockSelect, SelectedStock, NoStockOut },
  data() {
    return {
      row: null,
      isBatch :0,
      isBatch: 0,
      showDetialBox: false,
      flag: false,
      currentRow: null,
      selection: [],
      tableData: [],
      mainBusinessType: null, // æ–°å¢žï¼šå­˜å‚¨ä¸»å•据的businessType
      tableColumns: [
        {
          prop: "id",
@@ -162,7 +172,7 @@
          prop: "materielCode",
          title: "物料编号",
          type: "string",
          width: 150,
          width: 120,
        },
        {
          prop: "materielName",
@@ -180,7 +190,7 @@
          prop: "supplyCode",
          title: "供应商编号",
          type: "string",
          width: 150,
          width: 90,
        },
        {
          prop: "orderQuantity",
@@ -210,7 +220,7 @@
          prop: "unit",
          title: "单位",
          type: "string",
          width: 90,
          width: 80,
        },
        {
          prop: "orderDetailStatus",
@@ -224,7 +234,7 @@
          title: "指定库存",
          type: "icon",
          width: 90,
          hidden:true,
          hidden: true, // é»˜è®¤éšè—
          icon: "el-icon-s-grid",
        },
        {
@@ -269,9 +279,8 @@
        order: "desc",
        Foots: "",
        total: 0,
        // 2020.08.29增加自定义分页条大小
        sizes: [30, 60, 100, 120],
        size: 30, // é»˜è®¤åˆ†é¡µå¤§å°
        size: 30,
        Wheres: [],
        page: 1,
        rows: 30,
@@ -308,13 +317,24 @@
    };
  },
  methods: {
    toggleAssignStockColumn() {
      const assignStockColumn = this.tableColumns.find(
        (item) => item.prop === "assignStock"
      );
      if (assignStockColumn) {
        // businessType为22时显示,否则隐藏
        assignStockColumn.hidden = this.mainBusinessType !=='22';
      }
    },
    open(row) {
      this.row = row;
      this.showDetialBox = true;
      console.log(this.row);
      console.log("主单据数据:", this.row);
      this.isBatch = row.isBatch;
      this.mainBusinessType = row.businessType;
      this.getDictionaryData();
      this.getData();
      this.toggleAssignStockColumn();
    },
    getData() {
      var wheres = [{ name: "orderId", value: this.row.id }];
@@ -323,12 +343,13 @@
        rows: this.paginations.rows,
        sort: this.paginations.sort,
        order: this.paginations.order,
        wheres: JSON.stringify(wheres), // æŸ¥è¯¢æ¡ä»¶ï¼Œæ ¼å¼ä¸º[{ name: "字段", value: "xx" }]
        wheres: JSON.stringify(wheres),
      };
      this.http
        .post("api/OutboundOrderDetail/GetPageData", param, "查询中")
        .then((x) => {
          this.tableData = x.rows;
          this.toggleAssignStockColumn(); // æ•°æ®åŠ è½½åŽé‡æ–°ç¡®è®¤åˆ—æ˜¾éš
        });
    },
    tableButtonClick(row, column) {
@@ -336,8 +357,7 @@
        this.$refs.child.open(row);
      } else if (column.prop == "NoStockOut") {
        this.$refs.NoStockOut.open(row);
      }else{
          //点击打开出库详情
      } else {
        this.$refs.selectedStock.open(row);
      }
    },
@@ -345,7 +365,7 @@
      if (this.selection.length === 0) {
        return this.$message.error("请选择单据明细");
      }
      var keys = this.selection.map((item) => item.id); // èŽ·å–é€‰ä¸­è¡Œçš„id
      var keys = this.selection.map((item) => item.id);
      this.http
        .post("api/OutboundOrderDetail/LockOutboundStocks", keys, "数据处理中")
        .then((x) => {
@@ -357,341 +377,346 @@
          });
        });
    },
    // æ‰“开拣选页面
   handleOpenPicking() {
    handleOpenPicking() {
      this.$router.push({
        path: '/outbound/picking',
        query: { orderId: this.row.id ,orderNo:this.row.orderNo}
      })
        path: "/outbound/picking",
        query: { orderId: this.row.id, orderNo: this.row.orderNo },
      });
    },
    handleOpenBatchPicking() {
      this.$router.push({
        path: '/outbound/batchpicking',
        query: { orderId: this.row.id ,orderNo:this.row.orderNo}})
      this.$router.push({
        path: "/outbound/batchpicking",
        query: { orderId: this.row.id, orderNo: this.row.orderNo },
      });
    },
    outbound() {
      if (this.selection.length === 0) {
        return this.$message.error("请选择单据明细");
      }
      const platformOptions = [{label:'站台2',value:'2-1'},{label:'站台3',value:'3-1'}];
      const mountNode = document.createElement('div');
      const platformOptions = [
        { label: "站台2", value: "2-1" },
        { label: "站台3", value: "3-1" },
      ];
      const mountNode = document.createElement("div");
      document.body.appendChild(mountNode);
      // 2. è¡¨å•数据(默认选中站台3)
      const formData = reactive({
        selectedPlatform: platformOptions[0].value // é»˜è®¤ç»‘定「站台3」的value
        selectedPlatform: platformOptions[0].value,
      });
      // 3. åŠ¨æ€åˆ›å»ºå¼¹çª—ç»„ä»¶
      const vnode = createVNode(ElDialog, {
        title: '出库操作 - é€‰æ‹©å‡ºåº“站台',
        width: '500px',
        modelValue: true,
        appendToBody: true,
        'onUpdate:modelValue': (isVisible) => {
          if (!isVisible) {
            render(null, mountNode);
            document.body.removeChild(mountNode);
          }
        },
        style: {
          padding: '20px 0',
          borderRadius: '8px'
        }
      }, {
        default: () => h(ElForm, {
          model: formData,
          rules: {
            selectedPlatform: [
              { required: true, message: '请选择出库站台', trigger: 'change' }
            ]
      const vnode = createVNode(
        ElDialog,
        {
          title: "出库操作 - é€‰æ‹©å‡ºåº“站台",
          width: "500px",
          modelValue: true,
          appendToBody: true,
          "onUpdate:modelValue": (isVisible) => {
            if (!isVisible) {
              render(null, mountNode);
              document.body.removeChild(mountNode);
            }
          },
          ref: 'outboundForm',
          labelWidth: '100px',
          style: {
            padding: '0 30px'
          }
        }, [
          // å‡ºåº“站台选择项(核心表单项)
          h(ElFormItem, {
            label: '出库站台',
            prop: 'selectedPlatform',
            style: {
              marginBottom: '24px'
            }
          }, [
            h(ElSelect, {
              placeholder: '请选择出库站台(3-12)',
              modelValue: formData.selectedPlatform,
              'onUpdate:modelValue': (val) => {
                formData.selectedPlatform = val;
            padding: "20px 0",
            borderRadius: "8px",
          },
        },
        {
          default: () =>
            h(
              ElForm,
              {
                model: formData,
                rules: {
                  selectedPlatform: [
                    { required: true, message: "请选择出库站台", trigger: "change" },
                  ],
                },
                ref: "outboundForm",
                labelWidth: "100px",
                style: {
                  padding: "0 30px",
                },
              },
              style: {
                width: '100%',
                height: '40px',
                borderRadius: '4px',
                borderColor: '#dcdfe6'
              }
            }, platformOptions.map(platform =>
              h(ElOption, { label: platform.label, value: platform.value })
            ))
          ]),
          // åº•部按钮区
          h('div', {
            style: {
              textAlign: 'right',
              marginTop: '8px',
              paddingRight: '4px'
            }
          }, [
            h(ElButton, {
              type: 'text',
              onClick: () => {
                render(null, mountNode);
                document.body.removeChild(mountNode);
                ElMessage.info('取消出库操作');
              },
              style: {
                marginRight: '8px',
                color: '#606266'
              }
            }, '取消'),
            h(ElButton, {
              type: 'primary',
              onClick: async () => {
                const formRef = vnode.component.refs.outboundForm;
                try {
                  // è¡¨å•校验
                  await formRef.validate();
                } catch (err) {
                  return;
                }
              [
                h(ElFormItem, {
                  label: "出库站台",
                  prop: "selectedPlatform",
                  style: {
                    marginBottom: "24px",
                  },
                }, [
                  h(ElSelect, {
                    placeholder: "请选择出库站台(3-12)",
                    modelValue: formData.selectedPlatform,
                    "onUpdate:modelValue": (val) => {
                      formData.selectedPlatform = val;
                    },
                    style: {
                      width: "100%",
                      height: "40px",
                      borderRadius: "4px",
                      borderColor: "#dcdfe6",
                    },
                  }, platformOptions.map((platform) =>
                    h(ElOption, { label: platform.label, value: platform.value })
                  )),
                ]),
                h("div", {
                  style: {
                    textAlign: "right",
                    marginTop: "8px",
                    paddingRight: "4px",
                  },
                }, [
                  h(ElButton, {
                    type: "text",
                    onClick: () => {
                      render(null, mountNode);
                      document.body.removeChild(mountNode);
                      ElMessage.info("取消出库操作");
                    },
                    style: {
                      marginRight: "8px",
                      color: "#606266",
                    },
                  }, "取消"),
                  h(ElButton, {
                    type: "primary",
                    onClick: async () => {
                      const formRef = vnode.component.refs.outboundForm;
                      try {
                        await formRef.validate();
                      } catch (err) {
                        return;
                      }
                // 4. æž„造请求参数(选中单据ID + é€‰æ‹©çš„出库站台)
                const keys = this.selection.map((item) => item.id);
                const requestParams = {
                  taskIds: keys,
                  outboundPlatform: formData.selectedPlatform // å‡ºåº“站台
                };
                      const keys = this.selection.map((item) => item.id);
                      const requestParams = {
                        taskIds: keys,
                        outboundPlatform: formData.selectedPlatform,
                      };
                // 5. è°ƒç”¨å‡ºåº“接口
                this.http
                  .post("api/Task/GenerateOutboundTasks", requestParams, "数据处理中")
                  .then((x) => {
                    if (!x.status) return ElMessage.error(x.message);
                    ElMessage.success("操作成功");
                    this.showDetialBox = false; // å…³é—­è¯¦æƒ…框
                    this.$emit("parentCall", ($vue) => {
                      $vue.getData(); // é€šçŸ¥çˆ¶ç»„件刷新
                    });
                    // å…³é—­å¼¹çª—
                    render(null, mountNode);
                    document.body.removeChild(mountNode);
                  })
                  .catch(() => {
                    ElMessage.error('请求失败,请稍后重试');
                  });
              },
              style: {
                borderRadius: '4px',
                padding: '8px 20px'
              }
            }, '确定出库')
          ])
        ])
      });
                      this.http
                        .post(
                          "api/Task/GenerateOutboundTasks",
                          requestParams,
                          "数据处理中"
                        )
                        .then((x) => {
                          if (!x.status) return ElMessage.error(x.message);
                          ElMessage.success("操作成功");
                          this.showDetialBox = false;
                          this.$emit("parentCall", ($vue) => {
                            $vue.getData();
                          });
                          render(null, mountNode);
                          document.body.removeChild(mountNode);
                        })
                        .catch(() => {
                          ElMessage.error("请求失败,请稍后重试");
                        });
                    },
                    style: {
                      borderRadius: "4px",
                      padding: "8px 20px",
                    },
                  }, "确定出库"),
                ]),
              ]),
        }
      );
      // ç»‘定app上下文,确保El组件正常工作
      vnode.appContext = this.$.appContext;
      render(vnode, mountNode);
    },
    outboundbatch() {
  if (this.selection.length === 0) {
    return this.$message.error("请选择单据明细");
  }
    if (this.selection.length>1) {
    return this.$message.error("只能选择一条单据明细进行分批出库");
  }
  const platformOptions = [{label:'站台2',value:'2-1'},{label:'站台3',value:'3-1'}];
  const mountNode = document.createElement('div');
  document.body.appendChild(mountNode);
  // 2. è¡¨å•数据(默认选中站台3,新增小数字段)
  const formData = reactive({
    selectedPlatform: platformOptions[0].value, // é»˜è®¤ç»‘定「站台3」的value
    outboundDecimal: '' // æ–°å¢žï¼šå°æ•°è¾“入框字段
  });
  // 3. åŠ¨æ€åˆ›å»ºå¼¹çª—ç»„ä»¶
  const vnode = createVNode(ElDialog, {
    title: '出库操作 - é€‰æ‹©å‡ºåº“站台',
    width: '500px',
    modelValue: true,
    appendToBody: true,
    'onUpdate:modelValue': (isVisible) => {
      if (!isVisible) {
        render(null, mountNode);
        document.body.removeChild(mountNode);
      if (this.selection.length === 0) {
        return this.$message.error("请选择单据明细");
      }
    },
    style: {
      padding: '20px 0',
      borderRadius: '8px'
    }
  }, {
    default: () => h(ElForm, {
      model: formData,
      rules: {
        selectedPlatform: [
          { required: true, message: '请选择出库站台', trigger: 'change' }
        ],
        // æ–°å¢žï¼šå°æ•°å­—段验证规则(必填 + æœ‰æ•ˆå°æ•°æ ¼å¼ï¼‰
        outboundDecimal: [
          { required: true, message: '请输入小数数值', trigger: 'blur' },
          {
            validator: (rule, value, callback) => {
              // éªŒè¯è§„则:正数、支持小数点后最多2位(可根据需求调整小数位数)
              const decimalReg = /^(([1-9]\d*)|0)(\.\d{1,2})?$/;
              if (value && !decimalReg.test(value)) {
                callback(new Error('请输入有效的小数(正数,最多2位小数)'));
              } else {
                callback();
              }
            },
            trigger: 'blur'
          }
        ]
      },
      ref: 'outboundForm',
      labelWidth: '100px',
      style: {
        padding: '0 30px'
      if (this.selection.length > 1) {
        return this.$message.error("只能选择一条单据明细进行分批出库");
      }
    }, [
      // å‡ºåº“站台选择项(核心表单项)
      h(ElFormItem, {
        label: '出库站台',
        prop: 'selectedPlatform',
        style: {
          marginBottom: '24px'
        }
      }, [
        h(ElSelect, {
          placeholder: '请选择出库站台(3-12)',
          modelValue: formData.selectedPlatform,
          'onUpdate:modelValue': (val) => {
            formData.selectedPlatform = val;
          },
          style: {
            width: '100%',
            height: '40px',
            borderRadius: '4px',
            borderColor: '#dcdfe6'
          }
        }, platformOptions.map(platform =>
          h(ElOption, { label: platform.label, value: platform.value })
        ))
      ]),
      // æ–°å¢žï¼šå°æ•°è¾“入框表单项
      h(ElFormItem, {
        label: '出库数', // å¯æ ¹æ®ä¸šåŠ¡éœ€æ±‚ä¿®æ”¹æ ‡ç­¾åï¼ˆå¦‚â€œå‡ºåº“æ•°é‡â€â€œé‡é‡â€ç­‰ï¼‰
        prop: 'outboundDecimal',
        style: {
          marginBottom: '24px'
        }
      }, [
        h(ElInput, {
          type: 'number', // æ•°å­—类型,原生支持小数输入
          placeholder: '请输入小数数值(最多2位小数)',
          modelValue: formData.outboundDecimal,
          'onUpdate:modelValue': (val) => {
            formData.outboundDecimal = val;
          },
          style: {
            width: '100%',
            height: '40px',
            borderRadius: '4px',
            borderColor: '#dcdfe6'
          },
          step: '0.01', // æ­¥é•¿0.01,点击上下箭头时按0.01增减
          precision: 2, // é™åˆ¶æœ€å¤šè¾“å…¥2位小数(Element Plus属性)
          min: 0.01, // å¯é€‰ï¼šé™åˆ¶æœ€å°å€¼ä¸º0.01,避免输入0或负数
        })
      ]),
      // åº•部按钮区
      h('div', {
        style: {
          textAlign: 'right',
          marginTop: '8px',
          paddingRight: '4px'
        }
      }, [
        h(ElButton, {
          type: 'text',
          onClick: () => {
            render(null, mountNode);
            document.body.removeChild(mountNode);
            ElMessage.info('取消分批出库操作');
          },
          style: {
            marginRight: '8px',
            color: '#606266'
          }
        }, '取消'),
        h(ElButton, {
          type: 'primary',
          onClick: async () => {
            const formRef = vnode.component.refs.outboundForm;
            try {
              // è¡¨å•校验(会同时校验出库站台和小数字段)
              await formRef.validate();
            } catch (err) {
              return;
      const platformOptions = [
        { label: "站台2", value: "2-1" },
        { label: "站台3", value: "3-1" },
      ];
      const mountNode = document.createElement("div");
      document.body.appendChild(mountNode);
      const formData = reactive({
        selectedPlatform: platformOptions[0].value,
        outboundDecimal: "",
      });
      const vnode = createVNode(
        ElDialog,
        {
          title: "出库操作 - é€‰æ‹©å‡ºåº“站台",
          width: "500px",
          modelValue: true,
          appendToBody: true,
          "onUpdate:modelValue": (isVisible) => {
            if (!isVisible) {
              render(null, mountNode);
              document.body.removeChild(mountNode);
            }
console.log(this.selection);
            // 4. æž„造请求参数(新增小数字段)
            const keys = this.selection.map((item) => item.id);
            const requestParams = {
              orderDetailId: keys[0], // åˆ†æ‰¹å‡ºåº“仅支持单条明细
              outboundPlatform: formData.selectedPlatform, // å‡ºåº“站台
              batchQuantity: formData.outboundDecimal // æ–°å¢žï¼šå°æ•°å­—段传给后端
            };
            // 5. è°ƒç”¨å‡ºåº“接口
            this.http
              .post("api/Task/GenerateOutboundBatchTasks", requestParams, "数据处理中")
              .then((x) => {
                if (!x.status) return ElMessage.error(x.message);
                ElMessage.success("操作成功");
                this.showDetialBox = false; // å…³é—­è¯¦æƒ…框
                this.$emit("parentCall", ($vue) => {
                  $vue.getData(); // é€šçŸ¥çˆ¶ç»„件刷新
                });
                // å…³é—­å¼¹çª—
                render(null, mountNode);
                document.body.removeChild(mountNode);
              })
              .catch(() => {
                ElMessage.error('请求失败,请稍后重试');
              });
          },
          style: {
            borderRadius: '4px',
            padding: '8px 20px'
          }
        }, '确定分批出库')
      ])
    ])
  });
            padding: "20px 0",
            borderRadius: "8px",
          },
        },
        {
          default: () =>
            h(
              ElForm,
              {
                model: formData,
                rules: {
                  selectedPlatform: [
                    { required: true, message: "请选择出库站台", trigger: "change" },
                  ],
                  outboundDecimal: [
                    { required: true, message: "请输入小数数值", trigger: "blur" },
                    {
                      validator: (rule, value, callback) => {
                        const decimalReg = /^(([1-9]\d*)|0)(\.\d{1,2})?$/;
                        if (value && !decimalReg.test(value)) {
                          callback(new Error("请输入有效的小数(正数,最多2位小数)"));
                        } else {
                          callback();
                        }
                      },
                      trigger: "blur",
                    },
                  ],
                },
                ref: "outboundForm",
                labelWidth: "100px",
                style: {
                  padding: "0 30px",
                },
              },
              [
                h(ElFormItem, {
                  label: "出库站台",
                  prop: "selectedPlatform",
                  style: {
                    marginBottom: "24px",
                  },
                }, [
                  h(ElSelect, {
                    placeholder: "请选择出库站台(3-12)",
                    modelValue: formData.selectedPlatform,
                    "onUpdate:modelValue": (val) => {
                      formData.selectedPlatform = val;
                    },
                    style: {
                      width: "100%",
                      height: "40px",
                      borderRadius: "4px",
                      borderColor: "#dcdfe6",
                    },
                  }, platformOptions.map((platform) =>
                    h(ElOption, { label: platform.label, value: platform.value })
                  )),
                ]),
                h(ElFormItem, {
                  label: "出库数",
                  prop: "outboundDecimal",
                  style: {
                    marginBottom: "24px",
                  },
                }, [
                  h(ElInput, {
                    type: "number",
                    placeholder: "请输入小数数值(最多2位小数)",
                    modelValue: formData.outboundDecimal,
                    "onUpdate:modelValue": (val) => {
                      formData.outboundDecimal = val;
                    },
                    style: {
                      width: "100%",
                      height: "40px",
                      borderRadius: "4px",
                      borderColor: "#dcdfe6",
                    },
                    step: "0.01",
                    precision: 2,
                    min: 0.01,
                  }),
                ]),
                h("div", {
                  style: {
                    textAlign: "right",
                    marginTop: "8px",
                    paddingRight: "4px",
                  },
                }, [
                  h(ElButton, {
                    type: "text",
                    onClick: () => {
                      render(null, mountNode);
                      document.body.removeChild(mountNode);
                      ElMessage.info("取消分批出库操作");
                    },
                    style: {
                      marginRight: "8px",
                      color: "#606266",
                    },
                  }, "取消"),
                  h(ElButton, {
                    type: "primary",
                    onClick: async () => {
                      const formRef = vnode.component.refs.outboundForm;
                      try {
                        await formRef.validate();
                      } catch (err) {
                        return;
                      }
  // ç»‘定app上下文,确保El组件正常工作
  vnode.appContext = this.$.appContext;
  render(vnode, mountNode);
},
                      const keys = this.selection.map((item) => item.id);
                      const requestParams = {
                        orderDetailId: keys[0],
                        outboundPlatform: formData.selectedPlatform,
                        batchQuantity: formData.outboundDecimal,
                      };
                      this.http
                        .post(
                          "api/Task/GenerateOutboundBatchTasks",
                          requestParams,
                          "数据处理中"
                        )
                        .then((x) => {
                          if (!x.status) return ElMessage.error(x.message);
                          ElMessage.success("操作成功");
                          this.showDetialBox = false;
                          this.$emit("parentCall", ($vue) => {
                            $vue.getData();
                          });
                          render(null, mountNode);
                          document.body.removeChild(mountNode);
                        })
                        .catch(() => {
                          ElMessage.error("请求失败,请稍后重试");
                        });
                    },
                    style: {
                      borderRadius: "4px",
                      padding: "8px 20px",
                    },
                  }, "确定分批出库"),
                ]),
              ]),
        }
      );
      vnode.appContext = this.$.appContext;
      render(vnode, mountNode);
    },
    setCurrent(row) {
      this.$refs.singleTable.setCurrentRow(row);
    },
@@ -748,7 +773,6 @@
        var item = this.dictionaryList.find((x) => x.dicNo == column.bindKey);
        if (item) {
          var dicItem = item.data.find((x) => x.key == row[column.prop]);
          console.log(dicItem);
          if (dicItem) {
            return dicItem.value;
          } else {
@@ -758,10 +782,12 @@
          return row[column.prop];
        }
      }
      return row[column.prop];
    },
  },
};
</script>
<style scoped>
.text-button {
  border: 0px;
@@ -779,12 +805,10 @@
.box-table .el-table tbody tr:hover > td {
  background-color: #d8e0d4 !important;
  /* color: #ffffff; */
}
.box-table .el-table tbody tr.current-row > td {
  background-color: #f0f9eb !important;
  /* color: #ffffff; */
}
.el-table .success-row {
@@ -794,4 +818,4 @@
.box-table .el-table {
  border: 1px solid #ebeef5;
}
</style>
</style>
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js
@@ -381,6 +381,7 @@
      //this.detailOptions.columns.forEach(column=>{ });
    },
    searchBefore(param) {
      //界面查询前,可以给param.wheres添加查询参数
      //返回false,则不会执行查询
      return true;
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/stock/stockView.js
@@ -93,28 +93,42 @@
          column.formatter = (row) => {
            // æ ¡éªŒdetails是否存在且有数据
            if (row.details && row.details.length > 0) {
              // æŒ‰materielCode分组统计stockQuantity总和,并记录单位(取第一个非空单位)
              const materielSumMap = row.details.reduce((acc, item) => {
                const materielCode = item.materielCode || '未知物料';
              // æŒ‰barcode + supplyCode + BatchNo ç»„合维度分组统计stockQuantity总和,并记录单位(取第一个非空单位)
              const groupSumMap = row.details.reduce((acc, item) => {
                // èŽ·å–åˆ†ç»„å…³é”®å­—æ®µï¼Œä¸ºç©ºæ—¶èµ‹äºˆé»˜è®¤å€¼
                const supplyCode = item.supplyCode || '未知供应商编码';
                const batchNo = item.batchNo || '未知批次号';
                const materielCode = item.materielCode || '未知物料'; // ä¿ç•™åŽŸæœ‰ç‰©æ–™ç¼–ç 
                const quantity = Number(item.stockQuantity) || 0;
                const unit = item.unit || ''; // èŽ·å–å•ä½ï¼Œæ— åˆ™ä¸ºç©º
                // ç´¯åŠ æ•°é‡
                acc[materielCode] = {
                  total: (acc[materielCode]?.total || 0) + quantity,
                  unit: acc[materielCode]?.unit || unit // ä¿ç•™ç¬¬ä¸€ä¸ªéžç©ºå•位
                // ç»„合分组键(可根据需要调整显示格式)
                const groupKey = `${supplyCode}|${batchNo}|${materielCode}`;
                // ç´¯åŠ æ•°é‡ï¼Œä¿ç•™ç¬¬ä¸€ä¸ªéžç©ºå•ä½
                acc[groupKey] = {
                  total: (acc[groupKey]?.total || 0) + quantity,
                  unit: acc[groupKey]?.unit || unit,
                  supplyCode,
                  batchNo,
                  materielCode
                };
                return acc;
              }, {});
              // æ¯ä¸ªç‰©æ–™é¡¹ç”Ÿæˆç‹¬ç«‹div,跨行显示(包含单位)
              const displayItems = Object.entries(materielSumMap).map(([code, data]) => {
              // æ¯ä¸ªåˆ†ç»„项生成独立div,跨行显示(包含所有分组维度和单位)
              const displayItems = Object.entries(groupSumMap).map(([_, data]) => {
                // å¤„理单位显示:有单位则加空格显示,无则不显示
                const unitText = data.unit ? ` ${data.unit}` : '';
                return `<div style="line-height: 1.5; white-space: normal;">${code}:${data.total}${unitText}</div>`;
                // ç»„装显示文本(可根据需求调整字段显示顺序和格式)
                return `<div style="line-height: 1.5; white-space: normal; margin-bottom: 4px;">
                  ä¾›åº”商编码:${data.supplyCode} | æ‰¹æ¬¡å·ï¼š${data.batchNo} | ç‰©æ–™ç¼–码:${data.materielCode}:${data.total}${unitText}
        </div>`;
              });
              const displayContent = displayItems.join('');
              return `<div style="color: #F56C6C; white-space: normal; word-break: break-all;">${displayContent}</div>`;
              return `<div style="color: #716cf5ff; white-space: normal; word-break: break-all;">${displayContent}</div>`;
            } else {
              return '<span style="color: #F56C6C">空箱</span>';
            }
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue
@@ -87,15 +87,14 @@
    });
    const searchFormOptions = ref([
      [
        { title: "单据编号", field: "inboundOrderNo", type: "like" },
        { title: "扫描单据编号或条码", field: "inboundOrderNo", type: "like" },
        { title: "上游单据编号", field: "upperOrderNo", type: "like" },
        {
          title: "单据类型",
          field: "orderType",
          title: "业务类型",
          field: "businessType",
          type: "select",
          dataKey: "inOrderType",
          data: [0],
          hidden:true
          dataKey: "documentTypeEmun",
          data: [],
        },
        {
          title: "单据状态",
@@ -184,6 +183,19 @@
        bind: { key: "createType", data: [] },
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 180,
        align: "left"
      },
      {
        field: "returnToMESStatus",
        title: "回传MES状态",
        width: 120,
        bind: { key: "createType", data:[{key:0, value:"未回传"},{key:1, value:"已回传成功"},{key:2, value:"回传失败"}]},
      },
      {
        field: "factoryArea",
        title: "厂区",
        type: "string",
@@ -216,13 +228,6 @@
        title: "修改时间",
        type: "datetime",
        width: 160,
        align: "left",
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 100,
        align: "left",
      },
    ]);
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/outbound/outboundOrder.vue
@@ -124,12 +124,11 @@
        { title: "单据编号", field: "orderNo", type: "like" },
        { title: "上游单据编号", field: "upperOrderNo", type: "like" },
        {
          title: "单据类型",
          field: "orderType",
          title: "业务类型",
          field: "businessType",
          type: "select",
          dataKey: "outOrderType",
          dataKey: "documentTypeEmun",
          data: [],
          hidden:true
        },
        {
          title: "单据状态",
@@ -210,6 +209,19 @@
        bind: { key: "createType", data: [] },
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 180,
        align: "left"
      },
      {
        field: "returnToMESStatus",
        title: "回传MES状态",
        width: 120,
        bind: { key: "createType", data:[{key:0, value:"未回传"},{key:1, value:"已回传成功"},{key:2, value:"回传失败"}]},
      },
      {
        field: "factoryArea",
        title: "厂区",
        type: "string",
@@ -264,13 +276,6 @@
        title: "修改时间",
        type: "datetime",
        width: 160,
        align: "left",
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 100,
        align: "left",
      },
    ]);
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/stock/stockView.vue
@@ -44,7 +44,14 @@
      [
        { title: "物料编号", field: "materielCode",type: "like"},
        { title: "批次号", field: "batchNo",type: "like"},
        { title: "所属仓库", field: "warehouseId",type: "selectList",dataKey: "warehouses",data: [],},
        { title: "所属仓库", field: "locationType",type: "select",dataKey: "locationType",data: [],},
        { title: "所含条码", field: "barcode",type: "like"},
      ],
      [
        { title: "供应商编号", field: "supplyCode",type: "like"},
        { title: "所含单据编号", field: "orderNo",type: "like"},
        { title: "库存创建时间", field: "createDate",type: "datetime"},
      ],
    ]);
    const columns = ref([
@@ -59,6 +66,14 @@
        align: "left",
      },
      {
        field: "locationType",
        title: "所属仓库",
        type: "string",
        width: 150,
        align: "left",
        bind: { key: "locationType", data: [] },
      },
      {
        field: "palletCode",
        title: "托盘编号",
        type: "string",
@@ -70,14 +85,14 @@
        field: "locationCode",
        title: "货位编号",
        type: "string",
        width: 200,
        width: 150,
        align: "left",
      },
      {
        field: "locationName",
        title: "货位名称",
        type: "string",
        width: 150,
        width: 120,
        align: "left",
      },
      
@@ -93,7 +108,7 @@
        field: "orderStatistics",
        title: "所含物料明细",
        type: "string",
        width: 240,
        width: 630,
        align: "left",
      },
      {
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs
@@ -41,6 +41,7 @@
        private readonly IRepository<Dt_StockInfoDetail> _stockInfoDetailRepository;
        private readonly IRepository<Dt_StockInfo> _stockInfoRepository;
        private readonly IRepository<Dt_InboundOrder> _inboundOrderRepository;
        private readonly IRepository<Dt_InboundOrderDetail> _inboundOrderDetailRepository;
        private readonly IRepository<Dt_PickingRecord> _pickingRecoreRepository;
        private readonly IMaterialUnitService _materialUnitService;
        private readonly IOutboundOrderService _outboundOrderService;
@@ -53,7 +54,7 @@
        // å…¨å±€é™æ€é”ï¼šç”¨äºŽä¿æŠ¤ _resourceLocks å­—典中 GetOrAdd æˆ– TryRemove æ—¶çš„竞争
        private static readonly object _globalLocker = new object();
        public InvokeMESService(IHttpClientFactory httpClientFactory, ILogger<InvokeMESService> logger, IRepository<Dt_FeedbackToMes> feedbacktomesRepository, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_InboundOrder> inboundOrderRepository, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IOutStockLockInfoService outStockLockInfoService, IMaterialUnitService materialUnitService, IRepository<Dt_PickingRecord> pickingRecoreRepository, IRepository<Dt_InterfaceLog> interfacelogRepository)
        public InvokeMESService(IHttpClientFactory httpClientFactory, ILogger<InvokeMESService> logger, IRepository<Dt_FeedbackToMes> feedbacktomesRepository, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_InboundOrder> inboundOrderRepository, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IOutStockLockInfoService outStockLockInfoService, IMaterialUnitService materialUnitService, IRepository<Dt_PickingRecord> pickingRecoreRepository, IRepository<Dt_InterfaceLog> interfacelogRepository, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository)
        {
            _httpClientFactory = httpClientFactory;
            _logger = logger;
@@ -67,6 +68,7 @@
            _materialUnitService = materialUnitService;
            _pickingRecoreRepository = pickingRecoreRepository;
            _interfacelogRepository = interfacelogRepository;
            _inboundOrderDetailRepository = inboundOrderDetailRepository;
        }
        /// <summary>
@@ -245,7 +247,7 @@
        public async Task<WebResponseContent> BatchOrderFeedbackToMes(List<string> orderNos, int inout)
        {
            try
            {
            {
                if (inout == 1)
                {
@@ -260,6 +262,15 @@
                            var unreports = stockinfos.Where(x => !feeds.Contains(x.PalletCode)).ToList();
                            if (unreports != null && !unreports.Any())
                            {
                                _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1, Remark = "" })
                                                 .Where(it => it.InboundOrderNo == orderNo).ExecuteCommand();
                                var inboundOrder = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>().First(x => x.InboundOrderNo == orderNo);
                                if (inboundOrder != null)
                                {
                                    _inboundOrderDetailRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 })
                                         .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
                                }
                                return WebResponseContent.Instance.Error("没有需要回传的数据");
                            }
                            foreach (var item in unreports)
@@ -351,6 +362,30 @@
                                            if (result != null && result.code == 200)
                                            {
                                                _feedbacktomesRepository.Db.Insertable(new Dt_FeedbackToMes { OrderNo = orderNo, PalletCode = item.PalletCode, ReportStatus = 1 }).ExecuteCommand();
                                                var feedstockinfos = _stockInfoRepository.Db.Queryable<Dt_StockInfo>("info").Where(info => info.StockStatus == 6)
                                           .Where(it => SqlFunc.Subqueryable<Dt_StockInfoDetail>().Where(s => s.StockId == it.Id && s.OrderNo == orderNo).Any())
                                           .ToList();
                                                var feedstomes = _feedbacktomesRepository.Db.Queryable<Dt_FeedbackToMes>().Where(x => x.OrderNo == orderNo && x.ReportStatus == 1).Select(o => o.PalletCode).ToList();
                                                var feedunreports = feedstockinfos.Where(x => !feedstomes.Contains(x.PalletCode)).ToList();
                                                if (feedunreports != null && !feedunreports.Any())
                                                {
                                                    _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1, Remark = "" })
                                                     .Where(it => it.InboundOrderNo == orderNo).ExecuteCommand();
                                                    var feedinboundOrder = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>().First(x => x.InboundOrderNo == orderNo);
                                                    if (feedinboundOrder != null)
                                                    {
                                                        _inboundOrderDetailRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 })
                                                             .Where(it => it.OrderId == feedinboundOrder.Id).ExecuteCommand();
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 2, Remark = result.message })
                                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                                                _inboundOrderDetailRepository.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 })
                                              .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
                                            }
                                        }
                                    }
@@ -640,12 +675,21 @@
            var mesResult = await FeedbackOutbound(feedModel);
            if (mesResult == null || mesResult.code != 200)
            {
                var messages = mesResult?.message??"";
                await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
                   .SetColumns(x => new Dt_OutboundOrder
                   {
                       ReturnToMESStatus = 2,
                       Remark = messages,
                   })
                   .Where(x => x.OrderNo == orderNo)
                   .ExecuteCommandAsync();
                // æ›´æ–°æ˜Žç»†ä¸ºå›žä¼ å¤±è´¥ï¼ˆReturnToMESStatus=2)
                await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
                    .SetColumns(it => new Dt_OutboundOrderDetail
                    {
                        ReturnToMESStatus = 2,
                        ReturnToMESStatus = 2,
                        documentsNO = documentNo,
                    })
                    .Where(x => detailIds.Contains(x.Id))
@@ -653,10 +697,7 @@
                return (flowControl: false, value: WebResponseContent.Instance.Error($"回传MES失败"));
            }
            foreach (var record in pickingRecords.Where(x => detailIds.Contains(x.OrderDetailId)).ToList())
            {
                record.ReturnToMESStatus = 1;
            }
            var updates = pickingRecords.Where(x => detailIds.Contains(x.OrderDetailId)).ToList();
            updates.ForEach(x =>
            {
@@ -686,7 +727,7 @@
                await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
                    .SetColumns(x => new Dt_OutboundOrder
                    {
                        ReturnToMESStatus = 1,
                        ReturnToMESStatus = 1,Remark="",
                        OrderStatus = newStatus
                    })
                    .Where(x => x.OrderNo == orderNo)
@@ -717,6 +758,7 @@
                        .SetColumns(it => new Dt_OutboundOrder
                        {
                            ReturnToMESStatus = 1,
                            Remark = "",
                            OrderStatus = OutOrderStatusEnum.出库完成.ObjToInt(),
                        })
                        .Where(x => x.OrderNo == orderNo)
@@ -724,7 +766,7 @@
                }
            }
            return (flowControl: true, value: null);
            return (flowControl: true, value: WebResponseContent.Instance.OK($"回传MES成功,单据号:{orderNo}"));
        }
        private async Task<WebResponseContent> HandleOutboundOrderToMESCompletion(Dt_OutboundOrder outboundOrder, string orderNo)
@@ -846,7 +888,7 @@
                            .ExecuteCommandAsync();
                        await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
                            .SetColumns(x => x.ReturnToMESStatus == 1)
                            .SetColumns(it => new Dt_OutboundOrder { ReturnToMESStatus = 1, Remark = "" })
                            .Where(x => x.OrderNo == orderNo)
                            .ExecuteCommandAsync();
@@ -861,6 +903,17 @@
                    {
                        var errorMsg = $"OrderNo: {orderNo} å›žä¼ MES失败,错误码:{result.code},错误信息:{result.message ?? "无"}";
                        _logger.LogError(errorMsg);
                        await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
                          .SetColumns(x => x.ReturnToMESStatus ==2)
                          .Where(x => x.OrderId == outboundOrder.Id)
                          .ExecuteCommandAsync();
                        await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
                            .SetColumns(it => new Dt_OutboundOrder { ReturnToMESStatus = 2, Remark = result.message })
                            .Where(x => x.OrderNo == orderNo)
                            .ExecuteCommandAsync();
                        return WebResponseContent.Instance.Error(errorMsg);
                    }
                }
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_Common/TaskEnum/TaskTypeEnum.cs
@@ -97,7 +97,7 @@
        /// <summary>
        /// é‡‡è´­å…¥åº“
        /// </summary>
        [Description("采购入库")]
        [Description("入库")]
        Inbound = 510,
        /// <summary>
        /// ç›˜ç‚¹å…¥åº“
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs
@@ -3,7 +3,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SqlSugar;
using SqlSugar.Extensions;
using WIDESEA_Common.AllocateEnum;
using WIDESEA_Common.OrderEnum;
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
using MailKit.Search;
using Microsoft.Extensions.Logging;
using SqlSugar;
using WIDESEA_BasicService;
using WIDESEA_Common.CommonEnum;
@@ -934,7 +935,7 @@
            return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Success((pickingRecord, lockInfo, orderDetail));
        }
        /// <summary>
        /// æ£€æŸ¥é”å®šä¿¡æ¯å¯¹åº”的条码是否已经回库
@@ -1172,7 +1173,7 @@
        #endregion
        #region å›žåº“操作私有方法
        /// <summary>
        /// æ£€æŸ¥æ•´ä¸ªæ‰˜ç›˜æ˜¯å¦å·²ç»å›žåº“
        /// </summary>
@@ -1250,7 +1251,7 @@
        }
        private async Task<WebResponseContent> HandleNoReturnItems(string orderNo, string palletCode, Dt_Task originalTask, int stockInfoId)
        {
        {
            try
            {
                var locationtype = 0;
@@ -1537,7 +1538,7 @@
        }
        private async Task HandlePalletStockGoodsReturn(List<Dt_StockInfoDetail> palletStockGoods)
        {
@@ -1894,7 +1895,7 @@
                _logger.LogError($"UpdateOrderStatusForReturn失败 - OrderNo: {orderNo}, Error: {ex.Message}");
            }
        }
        #endregion
        #region ç©ºæ‰˜ç›˜
@@ -2143,7 +2144,7 @@
            return result;
        }
        private async Task<string> GenerateNewBarcode()
        {
@@ -2557,10 +2558,20 @@
                if (result1 != null && result1.code == 200)
                {
                    var orderIds = inboundOrderDetails.Select(x => x.Id).Distinct().ToList();
                    _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1 })
                    .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                    if (inboundOrder.OrderStatus == InOrderStatusEnum.入库完成.ObjToInt())
                    {
                        _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1, Remark = "" })
                        .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                    }
                    _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 })
                    .Where(it => orderIds.Contains(it.Id)).ExecuteCommand();
                }
                else
                {
                    _inboundOrderRepository.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 2, Remark = result1.message })
                    .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                    _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 })
                   .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
                }
                //出库回传MES
@@ -2632,12 +2643,30 @@
                    await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
                        .SetColumns(x => x.ReturnToMESStatus == 1)
                        .SetColumns(it => new Dt_OutboundOrder { ReturnToMESStatus = 1, Remark = "" })
                        .Where(x => x.Id == outboundOrder.Id)
                        .ExecuteCommandAsync();
                    await _interfaceLog.Db.Updateable<Dt_InterfaceLog>()
                        .SetColumns(x => x.ReturnToMESStatus == 1)
                        .Where(x => x.DocumentNo == documentNo)
                        .ExecuteCommandAsync();
                }
                else
                {
                    var uporderIds = outboundOrderDetails.Select(x => x.Id).Distinct().ToList();
                    await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
                      .SetColumns(x => x.ReturnToMESStatus == 2)
                       .Where(x => uporderIds.Contains(x.Id))
                      .ExecuteCommandAsync();
                    await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
                        .SetColumns(it => new Dt_OutboundOrder { ReturnToMESStatus = 2, Remark = result.message })
                         .Where(x => x.Id == outboundOrder.Id)
                        .ExecuteCommandAsync();
                    await _interfaceLog.Db.Updateable<Dt_InterfaceLog>()
                        .SetColumns(x => x.ReturnToMESStatus == 2)
                        .Where(x => x.DocumentNo == documentNo)
                        .ExecuteCommandAsync();
                }
@@ -2654,8 +2683,8 @@
        {
            try
            {
                Dt_InboundOrderDetail inboundOrderDetail = _stockInfoDetailService.Db.Queryable<Dt_InboundOrderDetail>().Where(x=>x.Barcode == barcode&& x.OrderDetailStatus !=OrderDetailStatusEnum.Over.ObjToInt()).First();
                if(inboundOrderDetail == null)
                Dt_InboundOrderDetail inboundOrderDetail = _stockInfoDetailService.Db.Queryable<Dt_InboundOrderDetail>().Where(x => x.Barcode == barcode && x.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt()).First();
                if (inboundOrderDetail == null)
                {
                    return WebResponseContent.Instance.Error($"未找到该条码{barcode}的入库明细或者明细状态已入智仓完成");
                }
@@ -2668,7 +2697,7 @@
                return WebResponseContent.Instance.OK("查询采购单成功", data: resultData);
            }
            catch(Exception ex)
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error(ex.Message);
            }
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_StockService/StockViewService.cs
@@ -31,6 +31,7 @@
            try
            {
                ISugarQueryable<Dt_StockInfo> sugarQueryable1 = _dbBase.Queryable<Dt_StockInfo>().Includes(x => x.Details);
                ISugarQueryable<Dt_LocationInfo> sugarQueryable = _dbBase.Queryable<Dt_LocationInfo>();
                if (!string.IsNullOrEmpty(options.Wheres))
                {
                    try
@@ -56,12 +57,33 @@
                                                .Where(x => x.Details.Any(v => v.BatchNo.Contains(param.Value.ToString())));
                                        }
                                        break;
                                    case var name when name == nameof(Dt_StockInfo.LocationCode).FirstLetterToLower():
                                    case var name when name == nameof(Dt_StockInfoDetail.SupplyCode).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.LocationCode == param.Value.ToString());
                                                .Where(x => x.Details.Any(v => v.SupplyCode.Contains(param.Value.ToString())));
                                        }
                                        break;
                                    case var name when name == nameof(Dt_StockInfoDetail.Barcode).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.Details.Any(v => v.Barcode.Contains(param.Value.ToString())));
                                        }
                                        break;
                                    case var name when name == nameof(Dt_StockInfoDetail.OrderNo).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.Details.Any(v => v.OrderNo.Contains(param.Value.ToString())));
                                        }
                                        break;
                                    case var name when name == nameof(Dt_LocationInfo.LocationStatus).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable = sugarQueryable
                                                .Where(x => x.LocationStatus == param.Value.ObjToInt());
                                        }
                                        break;
                                    case var name when name == nameof(Dt_StockInfo.CreateDate).FirstLetterToLower():
@@ -87,7 +109,7 @@
                    }
                }
                EntityProperties.ValidatePageOptions(options, ref sugarQueryable1);
                ISugarQueryable<Dt_LocationInfo> sugarQueryable = _dbBase.Queryable<Dt_LocationInfo>();
                ISugarQueryable<StockViewDTO> list = sugarQueryable1.InnerJoin(sugarQueryable, (b, a) => a.LocationCode == b.LocationCode).Select((b, a) => new StockViewDTO
                {
                    LocationCode = b.LocationCode,
@@ -100,7 +122,7 @@
                    Layer = a.Layer,
                    LocationName = a.LocationName,
                    LocationStatus = a.LocationStatus,
                    LocationType = a.LocationType,
                    LocationType = b.LocationType,
                    Modifier = b.Modifier,
                    ModifyDate = b.ModifyDate,
                    PalletCode = b.PalletCode,
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_DictionaryService.cs
@@ -270,6 +270,31 @@
                            result = new VueDictionaryDTO { DicNo = key, Config = "", Data = data };
                        }
                        break;
                    case "documentTypeEmun":
                        {
                            List<object> data = new List<object>();
                            Type type = typeof(DocumentType);
                            List<int> enums = Enum.GetValues(typeof(DocumentType)).Cast<int>().ToList();
                            int index = 0;
                            foreach (var item in enums)
                            {
                                FieldInfo? fieldInfo = typeof(DocumentType).GetField(((DocumentType)item).ToString());
                                DescriptionAttribute? description = fieldInfo.GetCustomAttribute<DescriptionAttribute>();
                                if (description != null)
                                {
                                    data.Add(new { key = item.ToString(), value = description.Description });
                                }
                                else
                                {
                                    data.Add(new { key = item.ToString(), value = item.ToString() });
                                }
                                index++;
                            }
                            result = new VueDictionaryDTO { DicNo = key, Config = "", Data = data };
                        }
                        break;
                }
                return result;
            }
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -130,17 +130,18 @@
            _task_HtyService = task_HtyService;
        }
        public async Task TaskStatusChange(string taskNum,TaskStatusEnum taskStatusEnum)
        public async Task TaskStatusChange(string taskNum, TaskStatusEnum taskStatusEnum)
        {
            if (int.TryParse(taskNum, out var newTaskNum))
            {
                await Db.Updateable<Dt_Task>().SetColumns(it => new Dt_Task {
                        TaskStatus = taskStatusEnum.ObjToInt()
                    })
                await Db.Updateable<Dt_Task>().SetColumns(it => new Dt_Task
                {
                    TaskStatus = taskStatusEnum.ObjToInt()
                })
                    .Where(it => it.TaskNum == newTaskNum)
                    .ExecuteCommandAsync();
            }
        }
        /// <summary>
@@ -450,10 +451,17 @@
                            var feedbackresult = await _invokeMESService.FeedbackInbound(feedmodel);
                            if (feedbackresult != null && feedbackresult.code == 200)
                            {
                                _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1 })
                                _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1, Remark = "" })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                                _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 })
                                .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
                            }
                            else
                            {
                                _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 2, Remark = feedbackresult.message })
                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
                                _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 })
                               .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
                            }
                        }
                    }
@@ -586,7 +594,7 @@
            _logger.LogInformation($"TaskService InPickTaskCompleted: {task.TaskNum}");
            try
            {
            {
                // æŸ¥åº“å­˜
                Dt_StockInfo stockInfo = await _stockRepository.Db.Queryable<Dt_StockInfo>()
                    .Includes(x => x.Details)
@@ -624,7 +632,7 @@
                // æ›´æ–°å‡ºåº“锁定记录状态为回库完成
                foreach (var lockInfo in returnLocks)
                {
                    lockInfo.Status = (int)OutLockStockStatusEnum.已回库;
                    lockInfo.Status = (int)OutLockStockStatusEnum.已回库;
                }
                if (returnLocks.Any())
@@ -685,7 +693,7 @@
                );
                await RecalculateOrderStatus(task.OrderNo);
                _logger.LogInformation($"托盘回库完成处理成功 - ä»»åŠ¡å·: {task.TaskNum}, æ‰˜ç›˜: {task.PalletCode}, è®¢å•: {task.OrderNo}");
                _ = Task.Run(async () =>
                {
@@ -964,7 +972,7 @@
                    await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
                        .SetColumns(x => new Dt_OutboundOrder
                        {
                            OrderStatus = newStatus,
                            OrderStatus = newStatus,
                        })
                        .Where(x => x.OrderNo == orderNo)
                        .ExecuteCommandAsync();
@@ -1119,7 +1127,7 @@
                                await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
                                      .SetColumns(x => new Dt_OutboundOrder
                                      {
                                          ReturnToMESStatus = 1,
                                          ReturnToMESStatus = 1,
                                      }).Where(x => x.OrderNo == orderNo).ExecuteCommandAsync();
                            }
                        }
@@ -1204,8 +1212,20 @@
                                    .ExecuteCommandAsync();
                                await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
                                    .SetColumns(x => x.ReturnToMESStatus == 1)
                                    .SetColumns(it => new Dt_OutboundOrder { ReturnToMESStatus = 2, Remark = "" })
                                    .Where(x => x.OrderNo == orderNo)
                                    .ExecuteCommandAsync();
                            }
                            else
                            {
                                await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
                                 .SetColumns(x => x.ReturnToMESStatus == 2)
                                 .Where(x => x.OrderId == outboundOrder.Id)
                                 .ExecuteCommandAsync();
                                await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
                                    .SetColumns(it => new Dt_OutboundOrder { ReturnToMESStatus = 2, Remark = result.message })
                                     .Where(x => x.OrderNo == orderNo)
                                    .ExecuteCommandAsync();
                            }
                        }
@@ -1260,7 +1280,7 @@
                var stockresult = _stockService.StockInfoService.Repository.DeleteAndMoveIntoHty(stockInfo, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
                if (!stockresult)
                {
                {
                    _stockRepository.Db.Deleteable(stockInfo).ExecuteCommand();
                }
                _stockService.StockInfoService.DeleteData(stockInfo);