heshaofeng
9 天以前 36dbf50a73b5b83f42678456facde44165cbcbeb
提交
已添加5个文件
已修改6个文件
1267 ■■■■■ 文件已修改
项目代码/WIDESEA_WMSClient/config/buttons.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/check/recheckOrder.js 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/outbound/allocateoutboundOrder.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/outbound/extend/newAllocateOrderDetail.vue 797 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/stock/stockInfoDetailByMaterielSum.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/router/viewGird.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/stock/stockInfoDetailByMaterielSum.vue 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IStockService/IStockDetailByMaterielService.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoDetailService.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Stock/StockDetailByMateriel.cs 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ÏîÄ¿´úÂë/WIDESEA_WMSClient/config/buttons.js
@@ -208,6 +208,15 @@
    onClick: function () {
    }
},
{
    name: "分拣",
    // icon: 'el-icon-upload2',
    class: '',
    value: 'BatchOrder',
    type: 'primary',
    onClick: function () {
    }
},
]
export default buttons
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/check/recheckOrder.js
@@ -8,8 +8,8 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
import gridBody from './extend/StockSelect.vue'
import http from '@/api/http.js'
import { h,createVNode, render,reactive,ref  } from 'vue';
import { ElDialog , ElForm, ElFormItem, ElInput, ElButton, ElMessage ,ElSelect ,ElOption } from 'element-plus'; // å¼•å…¥ElMessage,解决提示无反应
import { h, createVNode, render, reactive, ref } from 'vue';
import { ElDialog, ElForm, ElFormItem, ElInput, ElButton, ElMessage, ElSelect, ElOption } from 'element-plus'; // å¼•å…¥ElMessage,解决提示无反应
let extension = {
  components: {
    //查询界面扩展组件
@@ -22,36 +22,38 @@
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [ {
          name: '组盘',
          type: 'primary',
          value: '组盘',
          onClick: function () { // ä¿®å¤1:移除无用row参数,加日志调试
            console.log('组盘按钮被点击,开始校验');
            const selectedRows = this.$refs.table.getSelected();
            // æ ¡éªŒ1:是否选中行
            if (selectedRows.length === 0) {
              console.log('校验不通过:未选中任何单据');
              ElMessage.warning('请选择一条单据');
              return;
            }
            // æ ¡éªŒ2:是否选中单行
            if (selectedRows.length > 1) {
              console.log('校验不通过:选中多行单据');
              ElMessage.warning('只能选择一条单据');
              return;
            }
            const targetRow = selectedRows[0];
            this.$emit('openPalletDialog', targetRow.orderNo);
          }
        },], box: [], detail: [] }, //扩展的按钮
  buttons: {
    view: [{
      name: '组盘',
      type: 'primary',
      value: '组盘',
      onClick: function () { // ä¿®å¤1:移除无用row参数,加日志调试
        console.log('组盘按钮被点击,开始校验');
        const selectedRows = this.$refs.table.getSelected();
        // æ ¡éªŒ1:是否选中行
        if (selectedRows.length === 0) {
          console.log('校验不通过:未选中任何单据');
          ElMessage.warning('请选择一条单据');
          return;
        }
        // æ ¡éªŒ2:是否选中单行
        if (selectedRows.length > 1) {
          console.log('校验不通过:选中多行单据');
          ElMessage.warning('只能选择一条单据');
          return;
        }
        const targetRow = selectedRows[0];
        this.$emit('openPalletDialog', targetRow.orderNo);
      }
    },], box: [], detail: []
  }, //扩展的按钮
  methods: {
     //下面这些方法可以保留也可以删除
    //下面这些方法可以保留也可以删除
    onInit() {  //框架初始化配置前,
        this.columns.push({
      this.columns.push({
        field: '操作',
        title: '操作',
        width: 90,
@@ -71,6 +73,19 @@
          this.$refs.gridBody.open(row);
        }
      });
      let EmptyTrayOutboundBtn = this.buttons.find(x => x.value == 'BatchOrder');
      if (EmptyTrayOutboundBtn) {
        EmptyTrayOutboundBtn.onClick = function () {
          let rows = this.$refs.table.getSelected();
          if (rows.length == 0) return this.$error("请选择数据!");
          if (rows.length > 1) return this.$error("请选择一条数据!");
          this.$router.push({
            path: '/outbound/picking',
            query: { orderId: rows[0].id,orderNo:rows[0].orderNo}
          })
        }
      }
    },
    onInited() {
      //框架初始化配置后
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/outbound/allocateoutboundOrder.js
@@ -4,7 +4,7 @@
import { h,createVNode, render,reactive ,ref } from 'vue';
import { ElDialog , ElForm, ElFormItem, ElInput, ElButton, ElMessage ,ElSelect, ElOption} from 'element-plus';
import gridBody from './extend/outOrderDetail.vue'
import gridBody from './extend/newAllocateOrderDetail.vue'
let extension = {
    components: {
      //查询界面扩展组件
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/outbound/extend/newAllocateOrderDetail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,797 @@
<template>
  <div>
    <vol-box
      v-model="showDetialBox"
      :lazy="true"
      width="75%"
      :padding="15"
      title="单据明细信息"
    >
      <div class="box-head">
        <el-alert :closable="false" style="width: 100%">
          <el-row>
            <el-col :span="16">
              <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"
                style="float: right; height: 20px"
                @click="handleOpenPicking"
                >拣选</el-link>
                        <el-link
                type="primary"
                size="small"
                style="float: right; height: 20px; margin-right: 10px"
                  v-if="isBatch === 1"
                @click="handleOpenBatchPicking"
                >分批拣选</el-link>
              <el-link
                type="primary"
                size="small"
                   v-if="isBatch === 0"
                style="float: right; height: 20px; margin-right: 10px"
                @click="outbound"
                >直接出库</el-link
              >
               <el-link
                type="primary"
                size="small"
                 v-if="isBatch === 1"
                style="float: right; height: 20px; margin-right: 10px"
                @click="outboundbatch"
                >分批出库</el-link
              >
              <el-link
                type="primary"
                size="small"
                style="float: right; height: 20px; margin-right: 10px"
                @click="getData"
                >刷新</el-link
              ></el-col
            >
          </el-row>
        </el-alert>
      </div>
      <div class="box-table" style="margin-top: 1%">
        <el-table
          ref="singleTable"
          :data="tableData"
          style="width: 100%; height: 100%"
          highlight-current-row
          @current-change="handleCurrentChange"
          height="500px"
          @row-click="handleRowClick"
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="55"> </el-table-column>
          <el-table-column
            label="序号"
            type="index"
            fixed="left"
            width="55"
            align="center"
          ></el-table-column>
          <el-table-column
            v-for="(item, index) in tableColumns.filter((x) => !x.hidden)"
            :key="index"
            :prop="item.prop"
            :label="item.title"
            :width="item.width"
            align="center"
          >
            <template #default="scoped">
              <div v-if="item.type == 'icon'">
                <el-tooltip
                  class="item"
                  effect="dark"
                  :content="item.title"
                  placement="bottom"
                  ><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>
              </div>
              <div v-else-if="item.type == 'tag'">
                <el-tag size="small">
                  {{ getDictionary(scoped.row, item) }}
                </el-tag>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </vol-box>
    <stock-select ref="child" @parentCall="parentCall"></stock-select>
    <selected-stock
      ref="selectedStock"
      @parentCall="parentCall"
    ></selected-stock>
    <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';
export default {
  components: { VolBox, VolForm, StockSelect, SelectedStock,NoStockOut},
  data() {
    return {
      row: null,
      isBatch :0,
      showDetialBox: false,
      flag: false,
      currentRow: null,
      selection: [],
      tableData: [],
      tableColumns: [
        {
          prop: "id",
          title: "Id",
          type: "int",
          width: 90,
          hidden: true,
        },
        {
          prop: "orderId",
          title: "出库单主键",
          type: "string",
          width: 90,
          hidden: true,
        },
        {
          prop: "materielCode",
          title: "物料编号",
          type: "string",
          width: 150,
        },
        {
          prop: "materielName",
          title: "物料名称",
          type: "string",
          width: 150,
        },
        {
          prop: "batchNo",
          title: "批次号",
          type: "string",
          width: 90,
        },
        {
          prop: "supplyCode",
          title: "供应商编号",
          type: "string",
          width: 150,
        },
        {
          prop: "orderQuantity",
          title: "单据数量",
          type: "string",
          width: 90,
        },
        {
          prop: "lockQuantity",
          title: "锁定数量",
          type: "int",
          width: 90,
        },
        {
          prop: "overOutQuantity",
          title: "已出数量",
          type: "string",
          width: 90,
        },
        {
          prop: "overOutQuantity",
          title: "挪料数量",
          type: "string",
          width: 90,
        },
        {
          prop: "unit",
          title: "单位",
          type: "string",
          width: 90,
        },
        {
          prop: "orderDetailStatus",
          title: "订单明细状态",
          type: "tag",
          width: 90,
          bindKey: "orderDetailStatusEnum",
        },
        {
          prop: "assignStock",
          title: "指定库存",
          type: "icon",
          width: 90,
          hidden:true,
          icon: "el-icon-s-grid",
        },
        {
          prop: "viewDetail",
          title: "出库详细",
          type: "icon",
          width: 90,
          icon: "el-icon-s-operation",
        },
        {
          prop: "creater",
          title: "创建人",
          type: "string",
          width: 90,
        },
        {
          prop: "createDate",
          title: "创建时间",
          type: "datetime",
          width: 160,
        },
        {
          prop: "modifier",
          title: "修改人",
          type: "string",
          width: 100,
        },
        {
          prop: "modifyDate",
          title: "修改时间",
          type: "datetime",
          width: 160,
        },
        {
          prop: "remark",
          title: "备注",
          type: "string",
        },
      ],
      paginations: {
        sort: "id",
        order: "desc",
        Foots: "",
        total: 0,
        // 2020.08.29增加自定义分页条大小
        sizes: [30, 60, 100, 120],
        size: 30, // é»˜è®¤åˆ†é¡µå¤§å°
        Wheres: [],
        page: 1,
        rows: 30,
      },
      searchFormOptions: [
        [
          {
            title: "单据编号",
            field: "allocation_code",
            type: "like",
          },
          {
            title: "单据类型",
            field: "allocation_type",
            type: "select",
            dataKey: "OrderType",
            data: [],
          },
          {
            title: "单据状态",
            field: "allocation_state",
            type: "select",
            dataKey: "OrderState",
            data: [],
          },
        ],
      ],
      searchFormFields: {
        allocation_code: "",
        allocation_type: "",
        allocation_state: "",
      },
      dictionaryList: null,
    };
  },
  methods: {
    open(row) {
      this.row = row;
      this.showDetialBox = true;
      console.log(this.row);
      this.isBatch = row.isBatch;
      this.getDictionaryData();
      this.getData();
    },
    getData() {
      var wheres = [{ name: "orderId", value: this.row.id }];
      var param = {
        page: this.paginations.page,
        rows: this.paginations.rows,
        sort: this.paginations.sort,
        order: this.paginations.order,
        wheres: JSON.stringify(wheres), // æŸ¥è¯¢æ¡ä»¶ï¼Œæ ¼å¼ä¸º[{ name: "字段", value: "xx" }]
      };
      this.http
        .post("api/AllocateOrderDetail/GetPageData", param, "查询中")
        .then((x) => {
          this.tableData = x.rows;
        });
    },
    tableButtonClick(row, column) {
      if (column.prop == "assignStock") {
        this.$refs.child.open(row);
      } else if (column.prop == "NoStockOut") {
        this.$refs.NoStockOut.open(row);
      }else{
          //点击打开出库详情
        this.$refs.selectedStock.open(row);
      }
    },
    lockstocks() {
      if (this.selection.length === 0) {
        return this.$message.error("请选择单据明细");
      }
      var keys = this.selection.map((item) => item.id); // èŽ·å–é€‰ä¸­è¡Œçš„id
      this.http
        .post("api/OutboundOrderDetail/LockOutboundStocks", keys, "数据处理中")
        .then((x) => {
          if (!x.status) return this.$message.error(x.message);
          this.$message.success("操作成功");
          this.showDetialBox = false;
          this.$emit("parentCall", ($vue) => {
            $vue.getData();
          });
        });
    },
    // æ‰“开拣选页面
   handleOpenPicking() {
      this.$router.push({
        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}})
    },
    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');
      document.body.appendChild(mountNode);
      // 2. è¡¨å•数据(默认选中站台3)
      const formData = reactive({
        selectedPlatform: platformOptions[0].value // é»˜è®¤ç»‘定「站台3」的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' }
            ]
          },
          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('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 // å‡ºåº“站台
                };
                // 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'
              }
            }, '确定出库')
          ])
        ])
      });
      // ç»‘定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);
      }
    },
    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'
      }
    }, [
      // å‡ºåº“站台选择项(核心表单项)
      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;
            }
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'
          }
        }, '确定分批出库')
      ])
    ])
  });
  // ç»‘定app上下文,确保El组件正常工作
  vnode.appContext = this.$.appContext;
  render(vnode, mountNode);
},
    setCurrent(row) {
      this.$refs.singleTable.setCurrentRow(row);
    },
    handleCurrentChange(val) {
      this.currentRow = val;
    },
    getButtonEnable(propName, row) {
      if (propName == "assignStock") {
        if (
          row.orderDetailStatus !== 0 &&
          row.orderDetailStatus !== 60 &&
          row.orderDetailStatus !== 70 &&
          row.orderDetailStatus !== 80
        ) {
          return true;
        } else {
          return false;
        }
      }
      return false;
    },
    parentCall(fun) {
      if (typeof fun != "function") {
        return console.log("扩展组件需要传入一个回调方法才能获取父级Vue对象");
      }
      fun(this);
    },
    handleRowClick(row) {
      this.$refs.singleTable.toggleRowSelection(row);
    },
    handleSelectionChange(val) {
      this.selection = val;
    },
    getDictionaryData() {
      if (this.dictionaryList) {
        return;
      }
      var param = [];
      this.tableColumns.forEach((x) => {
        if (x.type == "tag" && x.bindKey != "") {
          param.push(x.bindKey);
        }
      });
      this.http
        .post("api/Sys_Dictionary/GetVueDictionary", param, "查询中")
        .then((x) => {
          if (x.length > 0) {
            this.dictionaryList = x;
          }
        });
    },
    getDictionary(row, column) {
      if (this.dictionaryList) {
        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 {
            return row[column.prop];
          }
        } else {
          return row[column.prop];
        }
      }
    },
  },
};
</script>
<style scoped>
.text-button {
  border: 0px;
}
</style>
<style>
.text-button:hover {
  background-color: #f0f9eb !important;
}
.el-table .warning-row {
  background: oldlace;
}
.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 {
  background: #f0f9eb;
}
.box-table .el-table {
  border: 1px solid #ebeef5;
}
</style>
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js
@@ -386,7 +386,7 @@
      let wheres = [{
        'name': 'orderType',
        'value': ['0','116'],
        'value': '0',
        'displayType': 'text'
      }];
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/stock/stockInfoDetailByMaterielSum.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
        console.log(this)
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/router/viewGird.js
@@ -217,6 +217,11 @@
    path: '/reCheckOrder',
    name: 'Dt_ReCheckOrder',
    component: () => import('@/views/check/ReCheckOrder.vue')
  },
  {
    path: '/stockInfoDetailByMaterielSum',
    name: 'Dt_StockInfoDetailss',
    component: () => import('@/views/stock/stockInfoDetailByMaterielSum.vue')
  }
]
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/stock/stockInfoDetailByMaterielSum.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,222 @@
<template>
  <view-grid ref="grid" :columns="columns" :detail="detail" :editFormFields="editFormFields"
    :editFormOptions="editFormOptions" :searchFormFields="searchFormFields" :searchFormOptions="searchFormOptions"
    :table="table" :extend="extend">
  </view-grid>
</template>
<script>
import extend from "@/extension/stock/stockInfoDetailByMaterielSum.js";
import { ref, defineComponent } from "vue";
export default defineComponent({
  setup() {
    const table = ref({
      key: "id",
      footer: "Foots",
      cnName: "库存信息明细",
      name: "stockInfoDetail",
      url: "/StockInfoDetail/",
      sortName: "id",
    });
    const editFormFields = ref({
      deviceCode: "",
      deviceName: "",
      deviceType: "",
      deviceStatus: "",
      deviceIp: "",
      devicePort: "",
      devicePlcType: "",
      deviceRemark: "",
    });
    const editFormOptions = ref([
      [
        {
          title: "物料编号",
          required: true,
          field: "materielCode",
          type: "string",
        },
        {
          title: "单据编号",
          required: true,
          field: "materielName",
          type: "string",
        },
        {
          title: "批次号",
          required: true,
          field: "orderNo",
          type: "string",
        },
        {
          title: "序列号",
          required: true,
          field: "serialNumber",
          type: "string",
        },
      ],
    ]);
    const searchFormFields = ref({
      materielCode: "",
      materielName: "",
      orderNo: "",
    });
    const searchFormOptions = ref([
      [
        { title: "物料编号", field: "materielCode" ,type:'like'},
        { title: "物料名称", field: "materielName" ,type:'like'},
        { title: "单据编号", field: "orderNo" ,type:'like'},
        { title: "托盘号", field: "palletCode" ,type:'like'},
      ],
    ]);
    const columns = ref([
      {
        field: "id",
        title: "Id",
        type: "int",
        width: 90,
        hidden: true,
        readonly: true,
        require: true,
        align: "left",
      },
      {
        field: "stockId",
        title: "库存信息主键",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "materielCode",
        title: "物料编号",
        type: "string",
        width: 150,
        align: "left",
      },
      {
        field: "materielName",
        title: "物料名称",
        type: "string",
        width: 150,
        align: "left",
      },
      {
        field: "orderNo",
        title: "单据编号",
        type: "decimal",
        width: 90,
        align: "left",
      },
      {
        field: "batchNo",
        title: "批次号",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "serialNumber",
        title: "序列号",
        type: "int",
        width: 120,
        align: "left",
      },
      {
        field: "supplyCode",
        title: "供应商编号",
        type: "string",
        width: 120,
        align: "left",
      },
      {
        field: "warehouseCode",
        title: "仓库号",
        type: "string",
        width: 120,
        align: "left",
      },
      {
        field: "barcode",
        title: "条码",
        type: "string",
        width: 120,
        align: "left",
      },
      {
        field: "stockQuantity",
        title: "库存数量",
        type: "string",
        width: 200,
        align: "left",
      },
      {
        field: "outboundQuantity",
        title: "出库数量",
        type: "string",
        width: 180,
        align: "left",
      },
      {
        field: "status",
        title: "库存明细状态",
        type: "string",
        width: 120,
        align: "left",
        bind: { key: "stockStatusEmun", data: [] },
      },
      {
        field: "creater",
        title: "创建人",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "createDate",
        title: "创建时间",
        type: "datetime",
        width: 160,
        align: "left",
      },
      {
        field: "modifier",
        title: "修改人",
        type: "string",
        width: 100,
        align: "left",
      },
      {
        field: "modifyDate",
        title: "修改时间",
        type: "datetime",
        width: 160,
        align: "left",
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 100,
        align: "left",
      },
    ]);
    const detail = ref({
      cnName: "#detailCnName",
      table: "",
      columns: [],
      sortName: "",
    });
    return {
      table,
      extend,
      editFormFields,
      editFormOptions,
      searchFormFields,
      searchFormOptions,
      columns,
      detail,
    };
  },
});
</script>
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_IStockService/IStockDetailByMaterielService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
using WIDESEA_DTO.Stock;
using WIDESEA_Model.Models;
namespace WIDESEA_IStockService
{
    public interface IStockDetailByMaterielService : IService<StockDetailByMateriel>
    {
        IRepository<StockDetailByMateriel> Repository { get; }
        PageGridData<StockDetailByMateriel> GetPageData2(PageDataOptions options);
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoDetailService.cs
@@ -14,5 +14,7 @@
        bool ExistBarcodes(List<string> barcodes);
        PageGridData<StockInfoDetailWithPalletDto> GetPageData2(PageDataOptions options);
        PageGridData<StockDetailDtO> GetPageDataByMateriel(PageDataOptions options);
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_Model/Models/Stock/StockDetailByMateriel.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WIDESEA_Model.Models
{
    public class StockDetailByMateriel
    {
        public int Id { get; set; }
        public int StockId { get; set; }
        public string MaterielCode { get; set; }
        public string MaterielName { get; set; }
        public string OrderNo { get; set; }
        public string BatchNo { get; set; }
        public string ProductionDate { get; set; }
        public string EffectiveDate { get; set; }
        public string SerialNumber { get; set; }
        public decimal StockQuantity { get; set; }
        public decimal OutboundQuantity { get; set; }
        public int Status { get; set; }
        public string Unit { get; set; }
        public string InboundOrderRowNo { get; set; }
        public string? SupplyCode { get; set; }
        public string FactoryArea { get; set; }
        public string? WarehouseCode { get; set; }
        public string? Barcode { get; set; }
        public string? BusinessType { get; set; }
        public decimal BarcodeQty { get; set; }
        public string BarcodeUnit { get; set; }
        public DateTime? ValidDate { get; set; }
        public string Remark { get; set; }
    }
}