1
heshaofeng
2026-01-07 51197dd4ca2a95dc86f11261d255b6cba8b21263
1
已添加5个文件
已修改8个文件
602 ■■■■■ 文件已修改
项目代码/WIDESEA_WMSClient/src/extension/basic/returnRecord.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/UndoPalletGroup.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/router/viewGird.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/basic/Dt_MesReturnRecord.vue 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/inbound/Dt_AllocateOrder.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/BigGreenService/BigGreenService.cs 117 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_AllocateService/AllocateService.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IRecordService/IMesReturnRecordService.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IRecordService/IRecordService.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_RecordService/MesReturnRecordService.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_RecordService/RecordService.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Record/MesReturnRecordController.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/basic/returnRecord.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: '',
    gridBody: '',
    gridFooter: '',
    //新建、编辑弹出框扩展组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [], box: [], detail: [] }, //扩展的按钮
  methods: {
     //下面这些方法可以保留也可以删除
    onInit() {  //框架初始化配置前,
        //示例:在按钮的最前面添加一个按钮
        //   this.buttons.unshift({  //也可以用push或者splice方法来修改buttons数组
        //     name: '按钮', //按钮名称
        //     icon: 'el-icon-document', //按钮图标vue2版本见iview文档icon,vue3版本见element ui文档icon(注意不是element puls文档)
        //     type: 'primary', //按钮样式vue2版本见iview文档button,vue3版本见element ui文档button
        //     onClick: function () {
        //       this.$Message.success('点击了按钮');
        //     }
        //   });
        //示例:设置修改新建、编辑弹出框字段标签的长度
        // this.boxOptions.labelWidth = 150;
    },
    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/extension/inbound/extend/UndoPalletGroup.vue
@@ -1,11 +1,11 @@
<template>
  <vol-box v-model="show" title="撤销组盘" :width="500" :height="300">
    <template #content>
      <el-form ref="form" :model="form" :rules="rules" label-width="90px">
        <el-form-item label="托盘条码:" prop="code">
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="托盘或条码:" prop="code">
          <el-input
            v-model="form.code"
            placeholder="请扫描/输入托盘条码"
            placeholder="请扫描/输入托盘或条码"
            @keydown.enter.prevent="submit"
            clearable
            @paste="handlePaste"
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/router/viewGird.js
@@ -251,6 +251,10 @@
    path: '/wms-dashboard',
    name: 'wms-dashboard',
    component: () => import('@/views/charts/wms-dashboard.vue')
  }, {
    path: '/Dt_MesReturnRecord',
    name: 'Dt_MesReturnRecord',
    component: () => import('@/views/basic/Dt_MesReturnRecord.vue')
  }
]
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/basic/Dt_MesReturnRecord.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,343 @@
<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/basic/warehouse.js"; // æ³¨æ„ï¼šè‹¥æœ‰ä¸“属的回传记录扩展文件,需替换此路径
import { ref, defineComponent } from "vue";
export default defineComponent({
  setup() {
    // 1. è¡¨æ ¼åŸºç¡€é…ç½®ï¼šé€‚配回传记录实体
    const table = ref({
      key: "id", // å¯¹åº”实体主键Id
      footer: "Foots",
      cnName: "接口回传记录", // æ›¿æ¢åŽŸä»“åº“ä¿¡æ¯
      name: "returnRecord", // è‡ªå®šä¹‰è¡¨åæ ‡è¯†
      url: "/MesReturnRecord/", // å¯¹åº”后端接口路径(需根据实际后端路由调整)
      sortName: "id",
    });
    // 2. ç¼–辑表单字段:对应实体所有字段
    const editFormFields = ref({
      id: "",
      orderId: "",
      orderNo: "",
      returnType: "",
      interfaceType: "",
      requestData: "",
      apiUrl: "",
      responseData: "",
      httpStatusCode: "",
      returnCount: "",
      requestCode: "",
      returnStatus: "",
      lastReturnTime: "",
      successTime: "",
      failureReason: "",
    });
    // 3. ç¼–辑表单配置:区分必填项,适配字段类型
    const editFormOptions = ref([
      [
        {
          title: "单据主表ID",
          required: true,
          field: "orderId",
          type: "int",
        },
        {
          title: "单据编号",
          required: true,
          field: "orderNo",
          type: "string",
        },
        {
          title: "回传类型",
          required: true,
          field: "returnType",
          type: "select", // æžšä¸¾ç±»åž‹ç”¨ä¸‹æ‹‰æ¡†
          data: [
            { label: "整单", value: 1 },
            { label: "分批", value: 2 },
          ],
        },
      ],
      [
        {
          title: "回传接口类型",
          required: true,
          field: "interfaceType",
          type: "select",
          data: [
            { label: "出库", value: 1 },
            { label: "入库", value: 2 },
            { label: "调拨", value: 3 },
          ],
        },
        {
          title: "API地址",
          required: true,
          field: "apiUrl",
          type: "string",
        },
        {
          title: "请求代码",
          required: true,
          field: "requestCode",
          type: "string",
        },
      ],
      [
        {
          title: "回传次数",
          required: true,
          field: "returnCount",
          type: "int",
        },
        {
          title: "回传状态",
          required: true,
          field: "returnStatus",
          type: "select",
          data: [
            { label: "回传成功", value: 1 },
            { label: "回传失败", value: 2 },
          ],
        },
        {
          title: "HTTP状态码",
          field: "httpStatusCode",
          type: "int",
        },
      ],
      [
        {
          title: "回传数据(JSON)",
          required: true,
          field: "requestData",
          type: "textarea", // å¤§æ–‡æœ¬ç”¨æ–‡æœ¬åŸŸ
          rows: 4,
        },
        {
          title: "返回报文(JSON)",
          field: "responseData",
          type: "textarea",
          rows: 4,
        },
      ],
      [
        {
          title: "最后回传时间",
          field: "lastReturnTime",
          type: "datetime",
        },
        {
          title: "回传成功时间",
          field: "successTime",
          type: "datetime",
        },
        {
          title: "失败原因",
          field: "failureReason",
          type: "textarea",
          rows: 3,
        },
      ],
    ]);
    // 4. æœç´¢è¡¨å•字段:配置常用搜索项
    const searchFormFields = ref({
      orderNo: "",
      returnType: "",
      interfaceType: "",
      returnStatus: "",
      requestCode: "",
    });
    // 5. æœç´¢è¡¨å•配置:适配搜索类型
    const searchFormOptions = ref([
      [
        { title: "单据编号", field: "orderNo", type: "like" },
        {
          title: "回传类型",
          field: "returnType",
          type: "select",
          data: [
            { label: "整单", value: 1 },
            { label: "分批", value: 2 },
          ],
        },
        {
          title: "回传接口类型",
          field: "interfaceType",
          type: "select",
          data: [
            { label: "出库", value: 1 },
            { label: "入库", value: 2 },
            { label: "调拨", value: 3 },
          ],
        },
      ],
      [
        {
          title: "回传状态",
          field: "returnStatus",
          type: "select",
          data: [
            { label: "回传成功", value: 1 },
            { label: "回传失败", value: 2 },
          ],
        },
        { title: "请求代码", field: "requestCode", type: "like" },
      ],
    ]);
    // 6. è¡¨æ ¼åˆ—配置:完全匹配C#实体字段
    const columns = ref([
      {
        field: "id",
        title: "主键ID",
        type: "int",
        width: 80,
        hidden: true, // ä¸»é”®é»˜è®¤éšè—
        readonly: true,
        align: "left",
      },
      {
        field: "orderId",
        title: "单据主表ID",
        type: "int",
        width: 100,
        align: "left",
      },
      {
        field: "orderNo",
        title: "单据编号",
        type: "string",
        width: 120,
        align: "left",
      },
      {
        field: "interfaceType",
        title: "接口类型",
        type: "int",
        width: 90,
        align: "left",
        formatter: (row) => {
          const map = { 1: "出库", 2: "入库", 3: "调拨" };
          return map[row.interfaceType] || "-";
        },
      },
      {
        field: "apiUrl",
        title: "API地址",
        type: "string",
        width: 200,
        align: "left",
      },
      {
        field: "returnCount",
        title: "回传次数",
        type: "int",
        width: 80,
        align: "center",
      },
      {
        field: "returnStatus",
        title: "回传状态",
        type: "int",
        width: 90,
        align: "center",
        formatter: (row) => {
          return row.returnStatus === 1
            ? '<span style="color: green;">成功</span>'
            : '<span style="color: red;">失败</span>';
        },
      },
      {
        field: "httpStatusCode",
        title: "HTTP状态码",
        type: "int",
        width: 100,
        align: "center",
      },
      {
        field: "lastReturnTime",
        title: "最后回传时间",
        type: "datetime",
        width: 180,
        align: "left",
      },
      {
        field: "successTime",
        title: "成功时间",
        type: "datetime",
        width: 180,
        align: "left",
      },
      {
        field: "requestCode",
        title: "请求代码",
        type: "string",
        width: 100,
        align: "left",
      },
      {
        field: "failureReason",
        title: "失败原因",
        type: "string",
        width: 200,
        align: "left",
      },
      {
        field: "requestData",
        title: "回传数据",
        type: "string",
        width: 150,
        align: "left",
        hidden: true, // å¤§æ–‡æœ¬é»˜è®¤éšè—ï¼Œå¯é€šè¿‡åˆ—配置显示
      },
      {
        field: "responseData",
        title: "返回报文",
        type: "string",
        width: 150,
        align: "left",
      },
    ]);
    // 7. è¯¦æƒ…配置:适配新实体
    const detail = ref({
      cnName: "接口回传记录详情",
      table: "returnRecord",
      columns: [],
      sortName: "id",
    });
    return {
      table,
      extend,
      editFormFields,
      editFormOptions,
      searchFormFields,
      searchFormOptions,
      columns,
      detail,
    };
  },
});
</script>
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/inbound/Dt_AllocateOrder.vue
@@ -293,7 +293,7 @@
        align: "left",
      },
      {
        field: "modifier",
        field: "operator",
        title: "修改人",
        type: "string",
        width: 100,
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue
@@ -193,7 +193,7 @@
        align: "left",
      },
      {
        field: "modifier",
        field: "operator",
        title: "修改人",
        type: "string",
        width: 100,
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/BigGreenService/BigGreenService.cs
@@ -1,5 +1,6 @@
using IBigBreenService;
using Microsoft.IdentityModel.Tokens;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using SqlSugar;
using System;
using System.Collections.Generic;
@@ -14,6 +15,7 @@
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.Helper;
using WIDESEA_Model.Models;
using WIDESEA_Model.Models.Basic;
namespace BigGreenService
{
@@ -27,8 +29,9 @@
        private readonly IRepository<Dt_Task_Hty> _taskHtyRepository;
        private readonly IRepository<Dt_Task> _taskRepository;
        private readonly IRepository<Dt_StockInfo> _stockInfoRepository;
        private readonly IRepository<Dt_MaterialExpirationDate> _materialExpirationDateRepository;
        public BigGreenService(IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRepository<Dt_OutboundOrder> outBoundOrderRepository, IRepository<Dt_LocationInfo> locationInfoRepository,IRepository<Dt_OutboundOrderDetail> outBoundOrderDetailRepository, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository,IRepository<Dt_Task> taskRepository,IRepository<Dt_Task_Hty> taskHtyRepository, IRepository<Dt_StockInfo> stockInfoRepository)
        public BigGreenService(IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRepository<Dt_OutboundOrder> outBoundOrderRepository, IRepository<Dt_LocationInfo> locationInfoRepository, IRepository<Dt_OutboundOrderDetail> outBoundOrderDetailRepository, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_Task> taskRepository, IRepository<Dt_Task_Hty> taskHtyRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_MaterialExpirationDate> materialExpirationDateRepository)
        {
            _stockInfoDetailRepository = stockInfoDetailRepository;
            _outBoundOrderRepository = outBoundOrderRepository;
@@ -38,6 +41,7 @@
            _taskRepository = taskRepository;
            _taskHtyRepository = taskHtyRepository;
            _stockInfoRepository = stockInfoRepository;
            _materialExpirationDateRepository = materialExpirationDateRepository;
        }
        public WebResponseContent GetBigGreenData()
        {
@@ -50,27 +54,28 @@
                (int)OutOrderStatusEnum.出库中,
                (int)OutOrderStatusEnum.未开始
            };
            var unOutBound =_outBoundOrderRepository.Db.Queryable<Dt_OutboundOrder>().Where(x =>targetStatus.Contains(x.OrderStatus)).Count();
            var unOutBound = _outBoundOrderRepository.Db.Queryable<Dt_OutboundOrder>().Where(x => targetStatus.Contains(x.OrderStatus)).Count();
            //计算库位利用率
            var freeLocation =_locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x=>x.LocationStatus==(int)LocationStatusEnum.Free).Count();
            var inStockLocation =_locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x => x.LocationStatus == (int)LocationStatusEnum.InStock || x.LocationStatus == (int)LocationStatusEnum.Pallet).Count();
            var freeLocation = _locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x => x.LocationStatus == (int)LocationStatusEnum.Free).Count();
            var inStockLocation = _locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x => x.LocationStatus == (int)LocationStatusEnum.InStock || x.LocationStatus == (int)LocationStatusEnum.Pallet).Count();
            int totalLocation = freeLocation + inStockLocation;
            decimal locationUtilizationRate = totalLocation == 0
                ? 0
                : Math.Round((decimal)inStockLocation / totalLocation, 4)*100;
                : Math.Round((decimal)inStockLocation / totalLocation, 4) * 100;
            //计算入库任务和出库任务完成数量
            var inboundCount =_taskHtyRepository.Db.Queryable<Dt_Task_Hty>().Where(x => x.TaskType >= 500 && x.TaskType < 900 && x.CreateDate.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd")).Count();
            var outboundCount =_taskHtyRepository.Db.Queryable<Dt_Task_Hty>().Where(x => x.TaskType >= 100 && x.TaskType < 500 && x.CreateDate.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd")).Count();
            var inboundCount = _taskHtyRepository.Db.Queryable<Dt_Task_Hty>().Where(x => x.TaskType >= 500 && x.TaskType < 900 && x.CreateDate.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd")).Count();
            var outboundCount = _taskHtyRepository.Db.Queryable<Dt_Task_Hty>().Where(x => x.TaskType >= 100 && x.TaskType < 500 && x.CreateDate.ToString("yyyy-MM-dd") == DateTime.Now.ToString("yyyy-MM-dd")).Count();
            //计算有货料箱数量
            var inStockPallet = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletType ==(int) PalletTypeEnum.None && !string.IsNullOrEmpty(x.LocationCode)).Count();
            var inStockPallet = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletType == (int)PalletTypeEnum.None && !string.IsNullOrEmpty(x.LocationCode)).Count();
            //计算空箱数量
            var freeStockPallet = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletType == (int)PalletTypeEnum.Empty && !string.IsNullOrEmpty(x.LocationCode)).Count();
            // 4. èŽ·å–è¿‘7日每日出入库明细(核心修改:调用上面的方法)
            var dailyInOutBoundList = Get7DaysDailyInOutBound();
            var nearExpirationList = GetMaterialsNearExpiration();
            //获取作业统计
            var completeTask = SimpleStatistics();
            //任务
@@ -78,7 +83,7 @@
            var bigGreenData = new BigGreenDataDto
            {
                TotalStockQuantity=totalStockQuantity,
                TotalStockQuantity = totalStockQuantity,
                UnOutBoundOrderCount = unOutBound,
                LocationUtilizationRate = locationUtilizationRate,
                DailyInOutBoundList = dailyInOutBoundList,
@@ -87,7 +92,8 @@
                OutboundCount = outboundCount,
                InStockPallet = inStockPallet,
                FreeStockPallet = freeStockPallet,
                CompleteTask = completeTask
                CompleteTask = completeTask,
                NearExpirationList = nearExpirationList
            };
            return WebResponseContent.Instance.OK(data: bigGreenData);
        }
@@ -120,13 +126,12 @@
                })
                .ToList()
                .GroupBy(x => x.Date)
                .ToDictionary(k => k.Key , g => g.Sum(x => (decimal?)x.OverOutQuantity) ?? 0); // è½¬ä¸ºå­—典方便匹配
                .ToDictionary(k => k.Key, g => g.Sum(x => (decimal?)x.OverOutQuantity) ?? 0); // è½¬ä¸ºå­—典方便匹配
            // 3. æŸ¥è¯¢æ¯æ—¥å…¥åº“明细(按日期分组)
            var dailyInboundList = _inboundOrderDetailRepository.Db
                .Queryable<Dt_InboundOrderDetail>()
                .Where(x => x.CreateDate != null // è¿‡æ»¤ç©ºæ—¥æœŸ
                         && x.CreateDate >= startDate
                .Where(x => x.CreateDate >= startDate
                         && x.CreateDate < endDate.AddDays(1))
                .Select(x => new
                {
@@ -134,7 +139,7 @@
                    x.OverInQuantity
                })
                .ToList()
                .GroupBy(x=>x.Date)
                .GroupBy(x => x.Date)
                .ToDictionary(k => k.Key, g => g.Sum(x => (decimal?)x.OverInQuantity) ?? 0); // è½¬ä¸ºå­—典方便匹配
            // 4. åˆå¹¶æ¯æ—¥æ•°æ®ï¼ˆç¡®ä¿7天日期完整,无数据补0)
@@ -143,7 +148,7 @@
                Date = date,
                DailyOutboundQuantity = dailyOutboundList.ContainsKey(date) ? dailyOutboundList[date] : 0,
                DailyInboundQuantity = dailyInboundList.ContainsKey(date) ? dailyInboundList[date] : 0,
            }).ToList();
            return dailyInOutBoundList;
@@ -159,7 +164,7 @@
                    (int)t.TaskType >= 100 && (int)t.TaskType <= 299 ? "出库" :
                    (int)t.TaskType >= 500 && (int)t.TaskType <= 699 ? "入库" : "其他"
                )
                .Where(g => g.Key == "出库" || g.Key == "入库")
                .Where(g => g.Key == "出库" || g.Key == "入库")
                .Select(g => new SimpleStatisticsDTO
                {
                    TaskType = g.Key,
@@ -233,6 +238,8 @@
            public int FreeStockPallet { get; set; }
            public List<SimpleStatisticsDTO> CompleteTask { get; set; }
            public NearExpirationDTO NearExpirationList { get; set; }
        }
        /// <summary>
@@ -263,6 +270,84 @@
            public int Count { get; set; }
        }
        public class NearExpirationDTO
        {
            public int DaysToExpiration { get; set; }
            public List<Dt_StockInfoDetail> Details { get; set; }
            public string LocationCode { get; set; }
            public string PalletCode { get; set; }
        }
        ///<summary>
        ///获取近30天要过期的物料
        /// </summary>
        public NearExpirationDTO GetMaterialsNearExpiration()
        {
            // åˆå§‹åŒ–返回DTO
            var resultDTO = new NearExpirationDTO
            {
                Details = new List<Dt_StockInfoDetail>(),
                LocationCode = string.Empty,
                PalletCode = string.Empty,
                DaysToExpiration = 0 // åˆå§‹åŒ–天数
            };
            DateTime currentTime = DateTime.Now;
            DateTime thirtyDaysLater = currentTime.AddDays(30);
            // ç­›é€‰30天内过期的库存明细
            var nearExpirationList = _stockInfoDetailRepository.Db.Queryable<Dt_StockInfoDetail>()
                .Where(x => (x.ValidDate.Value - x.CreateDate).TotalDays <= 30)
                .ToList();
            // æ— ç¬¦åˆæ¡ä»¶çš„æ˜Žç»†ï¼Œç›´æŽ¥è¿”回
            if (!nearExpirationList.Any())
            {
                return resultDTO;
            }
            var firstStockId = nearExpirationList.First().StockId;
            var stock = _stockInfoRepository.Db.Queryable<Dt_StockInfo>()
                .First(x => x.Id == firstStockId);
            if (stock == null)
            {
                return resultDTO;
            }
            resultDTO.LocationCode = stock.LocationCode;
            resultDTO.PalletCode = stock.PalletCode;
            int minDaysToExpiration = int.MaxValue;
            foreach (var detail in nearExpirationList)
            {
                TimeSpan totalDaysToExpiration = detail.ValidDate.Value - detail.CreateDate;
                double remainingDays = totalDaysToExpiration.TotalDays;
                int daysToExpiration = (int)Math.Ceiling(Math.Max(0, remainingDays));
                if (daysToExpiration < minDaysToExpiration)
                {
                    minDaysToExpiration = daysToExpiration;
                }
                resultDTO.Details.Add(detail);
            }
            resultDTO.DaysToExpiration = minDaysToExpiration;
            return resultDTO;
        }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_AllocateService/AllocateService.cs
@@ -525,10 +525,12 @@
                {
                    item.OrderStatus = _InboundOrder.OrderStatus;
                    item.OrderType = _InboundOrder.OrderType;
                    item.Modifier = _InboundOrder.Operator;
                }else if (OutboundOrder!=null)
                {
                    item.OrderStatus = OutboundOrder.OrderStatus;
                    item.OrderType = OutboundOrder.OrderType;
                    item.Modifier = OutboundOrder.Operator;
                }
            }
            return new PageGridData<Dt_AllocateOrder>(totalCount, data);
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_IRecordService/IMesReturnRecordService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
using WIDESEA_Model.Models;
namespace WIDESEA_IRecordService
{
    public interface IMesReturnRecordService : IService<Dt_MesReturnRecord>
    {
        IRepository<Dt_MesReturnRecord> Repository { get; }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_IRecordService/IRecordService.cs
@@ -12,5 +12,7 @@
        ILocationStatusChangeRecordService LocationStatusChangeRecordSetvice { get; }
        IStockQuantityChangeRecordService StockQuantityChangeRecordService { get; }
        IMesReturnRecordService MesReturnRecordService { get; }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_RecordService/MesReturnRecordService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
using WIDESEA_IRecordService;
using WIDESEA_Model.Models;
namespace WIDESEA_RecordService
{
    public class MesReturnRecordService : ServiceBase<Dt_MesReturnRecord, IRepository<Dt_MesReturnRecord>>, IMesReturnRecordService
    {
        public MesReturnRecordService(IRepository<Dt_MesReturnRecord> BaseDal) : base(BaseDal)
        {
        }
        public IRepository<Dt_MesReturnRecord> Repository => BaseDal;
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_RecordService/RecordService.cs
@@ -13,6 +13,8 @@
        public IStockQuantityChangeRecordService StockQuantityChangeRecordService { get; }
        public IMesReturnRecordService MesReturnRecordService { get; }
        public RecordService(ILocationStatusChangeRecordService locationStatusChangeRecordSetvice, IStockQuantityChangeRecordService stockQuantityChangeRecordService)
        {
            LocationStatusChangeRecordSetvice = locationStatusChangeRecordSetvice;
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Record/MesReturnRecordController.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Mvc;
using WIDESEA_Core.BaseController;
using WIDESEA_IRecordService;
using WIDESEA_Model.Models;
namespace WIDESEA_WMSServer.Controllers.Record
{
    [Route("api/MesReturnRecord")]
    [ApiController]
    public class MesReturnRecordController : ApiBaseController<IMesReturnRecordService, Dt_MesReturnRecord>
    {
        public MesReturnRecordController(IMesReturnRecordService service) : base(service)
        {
        }
    }
}