helongyang
2025-07-19 63d187526792e6e29bfec07d0e3f0dce07df31b3
成品报废单新增优化
已修改9个文件
已添加2个文件
771 ■■■■■ 文件已修改
代码管理/WMS/WIDESEA_WMSClient/src/extension/outbound/erpProScrapSheet.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/AddErpProScrapSheet.vue 444 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/ScrapSheet.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/basic/palletCodeInfo.vue 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/ErpProScrapSheetModel.cs 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IOutboundService/IErpProScrapSheetService.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IStockService/IProStockInfoService.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/ErpProScrapSheetService.cs 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockService/ProStockInfoService.cs 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/ErpProScrapSheetController.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/ProStockInfoController.cs 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/outbound/erpProScrapSheet.js
@@ -1,10 +1,11 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
import gridBody from './extend/ScrapSheet.vue'
import gridHeader from './extend/AddErpProScrapSheet.vue'
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: '',
    gridHeader: gridHeader,
    gridBody: gridBody,
    gridFooter: '',
    //新建、编辑弹出框扩展组件
@@ -17,6 +18,13 @@
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {
      let addBtn = this.buttons.find(x => x.value == 'Add');
      if (addBtn) {
        addBtn.onClick = function () {
          this.$refs.gridHeader.open();
        }
      };
        this.columns.push({
            field: '操作',
            title: '操作',
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/AddErpProScrapSheet.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,444 @@
<template>
  <div>
    <vol-box
      v-model="showDetialBox"
      :lazy="true"
      width="1300px"
      height="700px"
      :padding="20"
      title="添加成品超期报废明细"
    >
      <div style="max-height: 700px; overflow-y: auto;">
        <el-form ref="form" :model="form" label-width="130px">
          <!-- ä»“库选择 -->
          <el-form-item required label="所属仓库:">
            <el-select
              v-model="form.warehouseId"
              filterable
              placeholder="请选择仓库"
              @change="handleWarehouseChange"
              style="width: 100%;"
            >
              <el-option
                v-for="item in warehouses"
                :key="item.key"
                :label="item.value"
                :value="item.key"
              >
                <span style="float: left">{{ item.value }}</span>
                <span style="float: right; color: #8492a6; font-size: 13px">{{ item.key }}</span>
              </el-option>
            </el-select>
          </el-form-item>
          <!-- å•据编号(只读) -->
          <el-form-item required label="单据编号:">
            <el-input
              v-model="form.proScrapSheetOrderNo"
              placeholder="系统将自动生成"
              readonly
              style="width: 100%;"
            ></el-input>
          </el-form-item>
          <!-- æ˜Žç»†åˆ—表 -->
          <el-form-item label="报废明细:">
            <div v-for="(detail, index) in detailList" :key="index" class="detail-item">
              <div class="detail-header">
                <span>明细 {{ index + 1 }}</span>
                <el-button
                  type="text"
                  size="mini"
                  color="#f56c6c"
                  @click="removeDetail(index)"
                  :disabled="detailList.length <= 1"
                >
                  åˆ é™¤
                </el-button>
              </div>
              <el-row :gutter="20" class="detail-row">
                <el-col :span="6">
                  <el-form-item
                    required
                    :prop="'detailList.' + index + '.scrapProCode'"
                    :rules="{ required: true, message: '请选择产品编码', trigger: 'blur' }"
                  >
                    <el-select
                      v-model="detail.scrapProCode"
                      filterable
                      placeholder="产品编码"
                      @change="handleProCodeChange(detail, index)"
                      clearable
                      style="width: 100%;"
                    >
                      <el-option
                        v-for="(code, index) in proCodeOptions"
                        :key="index"
                        :label="code"
                        :value="code"
                      ></el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="5">
                  <el-form-item
                    required
                    :prop="'detailList.' + index + '.scrapProVersion'"
                    :rules="{ required: true, message: '请选择版本', trigger: 'blur' }"
                  >
                    <el-select
                      v-model="detail.scrapProVersion"
                      filterable
                      placeholder="版本"
                      clearable
                      style="width: 100%;"
                    >
                      <el-option
                        v-for="item in detail.versionOptions"
                        :key="item"
                        :label="item"
                        :value="item"
                      ></el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="5">
                  <el-form-item
                    required
                    :prop="'detailList.' + index + '.scrapProLotNo'"
                    :rules="{ required: true, message: '请选择批次号', trigger: 'blur' }"
                  >
                    <el-select
                      v-model="detail.scrapProLotNo"
                      filterable
                      placeholder="批次号"
                      clearable
                      style="width: 100%;"
                    >
                      <el-option
                        v-for="item in detail.lotNoOptions"
                        :key="item"
                        :label="item"
                        :value="item"
                      ></el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="4">
                  <el-form-item
                    required
                    :prop="'detailList.' + index + '.scrapPcsQty'"
                    :rules="{
                      required: true,
                      message: '请输入PCS数量',
                      trigger: 'blur',
                      validator: validateNumber // è‡ªå®šä¹‰æ•°å­—校验
                    }"
                  >
                    <el-input
                      v-model="detail.scrapPcsQty"
                      placeholder="PCS数量"
                      style="width: 100%;"
                      @blur="formatNumber(detail, 'scrapPcsQty')"
                    ></el-input>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="20" class="detail-row">
                <el-col :span="24">
                  <el-form-item label="备注:">
                    <el-input
                      v-model="detail.remark"
                      placeholder="请输入备注信息"
                      type="textarea"
                      rows="2"
                      style="width: 100%;"
                    ></el-input>
                  </el-form-item>
                </el-col>
              </el-row>
            </div>
            <!-- æ·»åŠ æ˜Žç»†æŒ‰é’® -->
            <el-button
              type="dashed"
              size="small"
              class="add-detail-btn"
              @click="addDetail"
              :disabled="detailList.length >= 10"
              style="width: 100%; margin-top: 15px;"
            >
              <i class="el-icon-plus"></i> æ·»åŠ æ˜Žç»†
            </el-button>
          </el-form-item>
        </el-form>
      </div>
      <!-- åº•部按钮 -->
      <template #footer>
        <el-button type="primary" size="mini" @click="submitForm" style="padding: 8px 20px;">确认提交</el-button>
        <el-button type="danger" size="mini" @click="close" style="padding: 8px 20px; margin-left: 10px;">关闭</el-button>
      </template>
    </vol-box>
  </div>
</template>
<script>
import VolBox from "@/components/basic/VolBox.vue";
export default {
  components: { VolBox },
  data() {
    const validateNumber = (rule, value, callback) => {
      if (!value) {
        return callback(new Error('请输入数量'));
      }
      const numberRegex = /^\d+(\.\d+)?$/;
      if (!numberRegex.test(value)) {
        return callback(new Error('请输入有效的数字'));
      }
      if (parseFloat(value) <= 0) {
        return callback(new Error('数量必须大于0'));
      }
      callback();
    };
    return {
      showDetialBox: false,
      warehouses: [],
      proCodeOptions: [],
      form: {
        warehouseId: "",
        proScrapSheetOrderNo: ""
      },
      detailList: [
        {
          scrapProCode: "",
          scrapProVersion: "",
          scrapProLotNo: "",
          scrapPcsQty: "",
          remark: "",
          versionOptions: [],
          lotNoOptions: []
        }
      ],
      validateNumber
    };
  },
  methods: {
    // æ‰“开弹窗
    open() {
      this.initForm();
      this.showDetialBox = true;
    },
    // åˆå§‹åŒ–表单
    initForm() {
      this.form = {
        warehouseId: "",
        proScrapSheetOrderNo: ""
      };
      this.detailList = [this.createEmptyDetail()];
      // åŠ è½½ä»“åº“åˆ—è¡¨
      if (this.warehouses.length === 0) {
        this.getWarehouseList();
      }
    },
    // åˆ›å»ºç©ºæ˜Žç»†
    createEmptyDetail() {
      return {
        scrapProCode: "",
        scrapProVersion: "",
        scrapProLotNo: "",
        scrapPcsQty: "",
        remark: "",
        versionOptions: [],
        lotNoOptions: []
      };
    },
    // èŽ·å–ä»“åº“åˆ—è¡¨
    getWarehouseList() {
      this.http
        .post("api/Warehouse/GetWarehouseDicByUser", null, "加载仓库数据中")
        .then((res) => {
          if (!res.status) return this.$message.error(res.message);
          this.warehouses = res.data || [];
          // è‹¥åªæœ‰ä¸€ä¸ªä»“库,自动选中
          if (this.warehouses.length === 1) {
            this.form.warehouseId = this.warehouses[0].key;
            this.handleWarehouseChange(this.warehouses[0].key);
          }
        });
    },
    // ä»“库变更事件
    handleWarehouseChange(warehouseId) {
      if (!warehouseId) return;
      // æ ¹æ®ä»“库ID加载产品编码列表
      this.http
        .post(`api/ProStockInfo/GetProCodeByWarehouse?warehouseId=${this.form.warehouseId}`,null, "加载产品数据中")
        .then((res) => {
          if (res.status) {
            this.proCodeOptions = [...new Set(res.data)];
          } else {
            this.$message.error(res.message);
          }
        });
    },
    // äº§å“ç¼–码变更事件
    handleProCodeChange(detail, index) {
      if (!detail.scrapProCode) {
        detail.versionOptions = [];
        detail.lotNoOptions = [];
        return;
      }
      // æ ¹æ®äº§å“ç¼–码加载版本列表
      this.http
      .post(
        `api/ProStockInfo/GetProVersionByCode?scrapProCode=${detail.scrapProCode}&warehouseId=${this.form.warehouseId}`,null, "加载版本数据中")
        .then((res) => {
          if (res.status) {
            detail.versionOptions = [...new Set(res.data)];
          }
        });
      // æ ¹æ®äº§å“ç¼–码加载批次号列表
      this.http
        .post(`api/ProStockInfo/GetProLotNoByCode?scrapProCode=${detail.scrapProCode}&warehouseId=${this.form.warehouseId}`,null, "加载批次数据中")
        .then((res) => {
          if (res.status) {
            detail.lotNoOptions = [...new Set(res.data)];
          }
        });
    },
    formatNumber(detail, field) {
      if (!detail[field]) return;
      let value = detail[field].replace(/[^0-9.]/g, '');
      const decimalIndex = value.indexOf('.');
      if (decimalIndex !== -1) {
        value = value.substring(0, decimalIndex + 1) + value.substring(decimalIndex + 1).replace(/\./g, '');
      }
      const parts = value.split('.');
      if (parts.length > 1 && parts[1].length > 2) {
        parts[1] = parts[1].substring(0, 2);
        value = parts.join('.');
      }
      detail[field] = value;
    },
    // æ·»åŠ æ˜Žç»†
    addDetail() {
      this.detailList.push(this.createEmptyDetail());
    },
    // åˆ é™¤æ˜Žç»†
    removeDetail(index) {
      this.detailList.splice(index, 1);
    },
    // æäº¤è¡¨å•
    submitForm() {
  if (!this.form.warehouseId) {
    return this.$message.error("请选择所属仓库");
  }
  const invalidDetail = this.detailList.find(item =>
    !item.scrapProCode || !item.scrapProVersion || !item.scrapProLotNo || !item.scrapPcsQty  || isNaN(parseFloat(item.scrapPcsQty))|| parseFloat(item.scrapPcsQty) <= 0
  );
  if (invalidDetail) {
    return this.$message.error("请为所有明细输入有效的数量值(大于0的数字)");
  }
  const submitData = {
    warehouseId: this.form.warehouseId,
    details: this.detailList.map(item => ({
      scrapProCode: item.scrapProCode,
      scrapProVersion: item.scrapProVersion,
      scrapProLotNo: item.scrapProLotNo,
      scrapPcsQty: parseFloat(item.scrapPcsQty),
      remark: item.remark
    }))
  };
  this.http
    .post("api/ErpProScrapSheet/Save", submitData, "提交中")
    .then((res) => {
          if (!res.status) return this.$message.error(res.message);
          this.$message.success("操作成功");
          this.close();
          this.$emit("parentCall", ($vue) => {
            $vue.refresh();
          });
        });
    },
    // å…³é—­å¼¹çª—
    close() {
      this.showDetialBox = false;
    }
  },
  created() {
    // åˆå§‹åŒ–时预加载仓库数据
    if (this.warehouses.length === 0) {
      this.getWarehouseList();
    }
  }
};
</script>
<style scoped>
.detail-item {
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  padding: 15px;
  margin-bottom: 20px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px dashed #e4e7ed;
  font-weight: 500;
}
.detail-row {
  margin-bottom: 15px;
}
.add-detail-btn {
  height: 40px;
  line-height: 38px;
}
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
::-webkit-scrollbar-thumb {
  background-color: #ddd;
  border-radius: 4px;
}
::-webkit-scrollbar-track {
  background-color: #f5f5f5;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/ScrapSheet.vue
@@ -236,20 +236,26 @@
            prop: "overScrapSETQty",
            title: "已报废SET数",
            type: "int",
            width: 180,
            width: 120,
          },
          {
            prop: "overScrapPcsQty",
            title: "已报废PCS数",
            type: "string",
            width: 180,
            width: 120,
          },
          {
            prop: "scrapProDetailStatus",
            title: "订单明细状态",
            type: "string",
            width: 180,
        }
          },
          {
            prop: "remark",
            title: "备注",
            type: "string",
            width: 180,
          }
        ],
      };
    },
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/basic/palletCodeInfo.vue
@@ -29,20 +29,7 @@
    const editFormFields = ref({});
    const editFormOptions = ref([
      [
        {
          title: "仓库",
          field: "warehouseId",
          type: "select",
          dataKey: "warehouses",
          data: [],
          required: true,
        },
        {
          title: "数量",
          field: "count",
          type: "int",
          required: true,
        },
      ],
    ]);
    const searchFormFields = ref({
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/ErpProScrapSheetModel.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_Core.Attributes;
namespace WIDESEA_DTO.Outbound
{
    /// <summary>
    /// æˆå“æŠ¥åºŸå•新增
    /// </summary>
    [ModelValidate]
    public class ErpProScrapSheetModel
    {
        // <summary>
        /// ä»“库Id
        /// </summary>
        [PropertyValidate("仓库Id", NotNullAndEmpty = true)]
        public int WarehouseId { get; set; }
        /// <summary>
        /// å•据编号
        /// </summary>
        [PropertyValidate("单据编号", NotNullAndEmpty = true)]
        public string ProScrapSheetOrderNo { get; set; }
        /// <summary>
        /// æŠ¥åºŸæ˜Žç»†
        /// </summary>
        [PropertyValidate("报废明细", NotNullAndEmpty = true)]
        public List<ErpProScrapSheetDetailDTO> Details { get; set; }
    }
    [ModelValidate]
    public class ErpProScrapSheetDetailDTO
    {
        /// <summary>
        /// äº§å“ç¼–码
        /// </summary>
        [PropertyValidate("产品编码", NotNullAndEmpty = true)]
        public string ScrapProCode { get; set; }
        /// <summary>
        /// æŠ¥åºŸç‰ˆæœ¬
        /// </summary>
        [PropertyValidate("报废版本", NotNullAndEmpty = true)]
        public string ScrapProVersion { get; set; }
        /// <summary>
        /// æ‰¹æ¬¡å·
        /// </summary>
        [PropertyValidate("批次号", NotNullAndEmpty = true)]
        public string ScrapProLotNo { get; set; }
        /// <summary>
        /// æŠ¥åºŸSET数量
        /// </summary>
        [PropertyValidate("报废SET数量", NotNullAndEmpty = true)]
        public int ScrapSETQty { get; set; }
        /// <summary>
        /// æŠ¥åºŸPCS数
        /// </summary>
        [PropertyValidate("报废PCS数", NotNullAndEmpty = true)]
        public int ScrapPcsQty { get; set; }
        /// <summary>
        /// å¤‡æ³¨
        /// </summary>
        [PropertyValidate("备注", NotNullAndEmpty = false)]
        public string Remark { get; set; }
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_IOutboundService/IErpProScrapSheetService.cs
@@ -8,11 +8,13 @@
using WIDESEA_Core;
using WIDESEA_IOutboundRepository;
using WIDESEA_Model.Models;
using WIDESEA_DTO.Outbound;
namespace WIDESEA_IOutboundService
{
    public interface IErpProScrapSheetService : IService<Dt_ErpProScrapSheet>
    {
        IErpProScrapSheetRepository Repository { get; }
        public WebResponseContent Save(ErpProScrapSheetModel addProScrapSheet);
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_IStockService/IProStockInfoService.cs
@@ -43,5 +43,23 @@
        /// èŽ·å–æˆå“æŠ¥åºŸçš„åº“å­˜
        /// </summary>
        List<Dt_ProStockInfo> GetOutboundStocks(List<Dt_ProStockInfo> stockInfos, Dt_ErpProScrapSheetDetail outOrderDetail, float needQuantity, out float residueQuantity);
        /// <summary>
        /// æŠ¥åºŸå•库存产品编号查询
        /// </summary>
        /// <param name="warehouseId"></param>
        /// <returns></returns>
        public WebResponseContent GetProCodeByWarehouse(int warehouseId);
        /// <summary>
        /// æŠ¥åºŸå•库存版本查询
        /// </summary>
        /// <param name="scrapProCode"></param>
        /// <returns></returns>
        public WebResponseContent GetProVersionByCode(string scrapProCode,int warehouseId);
        /// <summary>
        /// æŠ¥åºŸå•库存批次号查询
        /// </summary>
        /// <param name="scrapProCode"></param>
        /// <returns></returns>
        public WebResponseContent GetProLotNoByCode(string scrapProCode, int warehouseId);
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/ErpProScrapSheetService.cs
@@ -1,4 +1,5 @@
using System;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -9,7 +10,12 @@
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
using WIDESEA_Core.CodeConfigEnum;
using WIDESEA_Core.DB;
using WIDESEA_Core.Helper;
using WIDESEA_Core.Seed;
using WIDESEA_DTO.Outbound;
using WIDESEA_IBasicService;
using WIDESEA_IOutboundRepository;
using WIDESEA_IOutboundService;
using WIDESEA_Model.Models;
@@ -19,11 +25,14 @@
    public partial class ErpProScrapSheetService : ServiceBase<Dt_ErpProScrapSheet, IErpProScrapSheetRepository>, IErpProScrapSheetService
    {
        private readonly IUnitOfWorkManage _unitOfWorkManage;
        private readonly IWarehouseService _warehouseService;
        public IErpProScrapSheetRepository Repository => BaseDal;
        public ErpProScrapSheetService(IErpProScrapSheetRepository BaseDal, IUnitOfWorkManage unitOfWorkManage) : base(BaseDal)
        public ErpProScrapSheetService(IErpProScrapSheetRepository BaseDal, IUnitOfWorkManage unitOfWorkManage,IWarehouseService warehouseService) : base(BaseDal)
        {
            _unitOfWorkManage = unitOfWorkManage;
            _warehouseService = warehouseService;
        }
        public override WebResponseContent AddData(SaveModel saveModel)
        {
@@ -60,5 +69,104 @@
            }
            return base.AddData(saveModel);
        }
        public WebResponseContent Save(ErpProScrapSheetModel addProScrapSheet) {
            try
            {
                List<Dt_ErpProScrapSheetDetail> erpProScrapSheetDetails = new List<Dt_ErpProScrapSheetDetail>();
                if (addProScrapSheet.Details != null)
                {
                    foreach (var model in addProScrapSheet.Details)
                    {
                        Dt_ErpProScrapSheetDetail erpProScrapSheetDetail = new Dt_ErpProScrapSheetDetail()
                        {
                            ScrapProCode = model.ScrapProCode,
                            ScrapProVersion = model.ScrapProVersion,
                            ScrapProLotNo = model.ScrapProLotNo,
                            ScrapPcsQty = model.ScrapPcsQty,
                            ScrapSETQty = 0,
                        };
                        erpProScrapSheetDetails.Add(erpProScrapSheetDetail);
                    }
                }
                Dt_ErpProScrapSheet erpProScrapSheet = new Dt_ErpProScrapSheet()
                {
                    WarehouseId = addProScrapSheet.WarehouseId,
                    ProScrapSheetOrderNo = CreateCodeByRule(nameof(RuleCodeEnum.ProScrapSheetRule)),
                    ProScrapStatus = ProScrapSheetStatusEnum.TOChecked.ObjToInt(),
                    Details = erpProScrapSheetDetails
                };
                _unitOfWorkManage.BeginTran();
                Db.InsertNav(erpProScrapSheet).Include(x => x.Details).ExecuteCommand();
                _unitOfWorkManage.CommitTran();
                return WebResponseContent.Instance.OK();
            }
            catch(Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
        static object lock_code = new object();
        public string CreateCodeByRule(string ruleCode)
        {
            lock (lock_code)
            {
                string code = string.Empty;
                DateTime dateTime = DateTime.Now;
                DateTime now = DateTime.Now;
                try
                {
                    if (string.IsNullOrEmpty(ruleCode))
                        throw new ArgumentNullException(nameof(ruleCode));
                    SqlSugarClient sugarClient = new SqlSugarClient(new ConnectionConfig
                    {
                        IsAutoCloseConnection = true,
                        DbType = DbType.SqlServer,
                        ConnectionString = DBContext.ConnectionString
                    });
                    Dt_CodeRuleConfig codeRuleConfig = sugarClient.Queryable<Dt_CodeRuleConfig>().Where(x => x.RuleCode == ruleCode).First();
                    if (codeRuleConfig == null)
                        throw new ArgumentNullException(nameof(codeRuleConfig));
                    if (codeRuleConfig.ModifyDate != null)
                    {
                        dateTime = Convert.ToDateTime(codeRuleConfig.ModifyDate);
                    }
                    else
                    {
                        dateTime = Convert.ToDateTime(codeRuleConfig.CreateDate);
                    }
                    if (now.Year == dateTime.Year && now.Month == dateTime.Month && now.Day == dateTime.Day)
                    {
                        now = dateTime;
                        codeRuleConfig.CurrentVal = Convert.ToInt32(codeRuleConfig.CurrentVal) + 1;
                    }
                    else
                    {
                        codeRuleConfig.CurrentVal = 1;
                    }
                    codeRuleConfig.ModifyDate = DateTime.Now;
                    code = codeRuleConfig.Format;
                    code = code.Replace($"[{CodeFormatTypeEnum.YYYY}]", now.Year.ToString().PadLeft(4, '0'));
                    code = code.Replace($"[{CodeFormatTypeEnum.MM}]", now.Month.ToString().PadLeft(2, '0'));
                    code = code.Replace($"[{CodeFormatTypeEnum.DD}]", now.Day.ToString().PadLeft(2, '0'));
                    code = code.Replace($"[{CodeFormatTypeEnum.ST}]", codeRuleConfig.StartStr?.ToString() ?? "");
                    code = code.Replace($"[{CodeFormatTypeEnum.NUM}]", codeRuleConfig.CurrentVal.ToString().PadLeft(codeRuleConfig.Length, '0'));
                    Dictionary<string, object> keyValuePairs = new Dictionary<string, object>() { { nameof(codeRuleConfig.CurrentVal), codeRuleConfig.CurrentVal }, { nameof(codeRuleConfig.Id), codeRuleConfig.Id }, { nameof(codeRuleConfig.ModifyDate), DateTime.Now } };
                    sugarClient.Updateable(keyValuePairs).AS(MainDb.CodeRuleConfig).WhereColumns(nameof(codeRuleConfig.Id)).ExecuteCommand();
                    sugarClient.Updateable(codeRuleConfig);
                }
                catch (Exception ex)
                {
                }
                return code;
            }
        }
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_StockService/ProStockInfoService.cs
@@ -362,5 +362,52 @@
        //    }
        //    return (deleteStockDetails, updateStockDetails);
        //}
        public WebResponseContent GetProCodeByWarehouse(int warehouseId)
        {
            try
            {
                List<Dt_ProStockInfo> proStockInfo = BaseDal.QueryData(x => x.WarehouseId == warehouseId);
                List<int> proStockId = proStockInfo.Select(x => x.Id).ToList();
                List<Dt_ProStockInfoDetail> proStockInfoDetails = BaseDal.Db.Queryable<Dt_ProStockInfoDetail>().Where(x => proStockId.Contains(x.OutDetailId)).ToList();
                List<string> proCode = proStockInfoDetails.Select(x => x.ProductCode).ToList();
                return WebResponseContent.Instance.OK(data: proCode);
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
        public WebResponseContent GetProVersionByCode(string scrapProCode, int warehouseId)
        {
            try
            {
                List<Dt_ProStockInfo> proStockInfo = BaseDal.QueryData(x => x.WarehouseId == warehouseId);
                List<int> proStockId = proStockInfo.Select(x => x.Id).ToList();
                List<Dt_ProStockInfoDetail> proStockInfoDetails = BaseDal.Db.Queryable<Dt_ProStockInfoDetail>().Where(x => scrapProCode.Contains(x.ProductCode) && proStockId.Contains(x.OutDetailId)).ToList();
                List<string> productVersion = proStockInfoDetails.Select(x => x.ProductVersion).ToList();
                return WebResponseContent.Instance.OK(data: productVersion);
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
        public WebResponseContent GetProLotNoByCode(string scrapProCode, int warehouseId)
        {
            try
            {
                List<Dt_ProStockInfo> proStockInfo = BaseDal.QueryData(x => x.WarehouseId == warehouseId);
                List<int> proStockId = proStockInfo.Select(x => x.Id).ToList();
                List<Dt_ProStockInfoDetail> proStockInfoDetails = BaseDal.Db.Queryable<Dt_ProStockInfoDetail>().Where(x => scrapProCode.Contains(x.ProductCode) && proStockId.Contains(x.OutDetailId)).ToList();
                List<string> lotNumber = proStockInfoDetails.Select(x => x.LotNumber).ToList();
                return WebResponseContent.Instance.OK(data: lotNumber);
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/ErpProScrapSheetController.cs
@@ -4,6 +4,7 @@
using WIDESEA_Core;
using WIDESEA_IOutboundService;
using WIDESEA_Model.Models;
using WIDESEA_DTO.Outbound;
namespace WIDESEA_WMSServer.Controllers.Outbound
{
@@ -17,5 +18,10 @@
        public ErpProScrapSheetController(IErpProScrapSheetService service) : base(service)
        {
        }
        [HttpGet,HttpPost,Route("Save"),AllowAnonymous]
        public WebResponseContent Save([FromBody] ErpProScrapSheetModel addProScrapSheet)
        {
            return Service.Save(addProScrapSheet);
        }
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/ProStockInfoController.cs
@@ -1,4 +1,6 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using WIDESEA_Core;
using WIDESEA_Core.BaseController;
using WIDESEA_IStockService;
using WIDESEA_Model.Models;
@@ -15,5 +17,37 @@
        public ProStockInfoController(IProStockInfoService service) : base(service)
        {
        }
        /// <summary>
        /// æŠ¥åºŸå•库存产品编号查询
        /// </summary>
        /// <param name="warehouseId"></param>
        /// <returns></returns>
        [HttpPost,HttpGet,Route("GetProCodeByWarehouse"),AllowAnonymous]
        public WebResponseContent GetProCodeByWarehouse(int warehouseId)
        {
            return Service.GetProCodeByWarehouse(warehouseId);
        }
        /// <summary>
        /// æŠ¥åºŸå•库存版本查询
        /// </summary>
        /// <param name="warehouseId"></param>
        /// <returns></returns>
        [HttpPost, HttpGet, Route("GetProVersionByCode"), AllowAnonymous]
        public WebResponseContent GetProVersionByCode(string scrapProCode,int warehouseId)
        {
            return Service.GetProVersionByCode(scrapProCode,warehouseId);
        }
        /// <summary>
        /// æŠ¥åºŸå•库存版本查询
        /// </summary>
        /// <param name="warehouseId"></param>
        /// <returns></returns>
        [HttpPost, HttpGet, Route("GetProLotNoByCode"), AllowAnonymous]
        public WebResponseContent GetProLotNoByCode(string scrapProCode, int warehouseId)
        {
            return Service.GetProLotNoByCode(scrapProCode, warehouseId);
        }
    }
}