自动化立体仓库 - WMS系统
43个文件已添加
12个文件已修改
6310 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/MonthlySettleController.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OrderDetlPakinLogController.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OrderDetlPakoutLogController.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OrderPakinLogController.java 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OrderPakoutLogController.java 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OrderTimeChangeLogController.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/MonthlySettle.java 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/MonthlySettleDetail.java 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/OrderDetlPakinLog.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/OrderDetlPakoutLog.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/OrderPakin.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/OrderPakinLog.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/OrderPakout.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/OrderPakoutLog.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/OrderTimeChangeLog.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/param/DateRangeParam.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/param/MonthlySettleQueryParam.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/result/MaterialInOutRawDTO.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/result/MaterialInOutStatDTO.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/result/MonthlySettleResultVO.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/result/MonthlySettleStatisticsVO.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/result/PreviousSettleEndingQtyDTO.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/result/StockQtyDTO.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/ManLocDetlMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/MonthlySettleDetailMapper.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/MonthlySettleMapper.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/OrderTimeChangeLogMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/ManLocDetlService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/MonthlySettleService.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/OrderDetlPakinLogService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/OrderDetlPakoutLogService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/OrderPakinLogService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/OrderPakoutLogService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/OrderTimeChangeLogService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/ManLocDetlServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MonthlySettleServiceImpl.java 593 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OrderDetlPakinLogServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OrderDetlPakoutLogServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OrderPakinLogServiceImpl.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OrderPakoutLogServiceImpl.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/OrderTimeChangeLogServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/OrderPakinMoveHistoryHandler.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/task/handler/OrderPakoutMoveHistoryHandler.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ManLocDetlMapper.xml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/MonthlySettleDetailMapper.xml 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/MonthlySettleMapper.xml 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/sql/man_order_time_change_log.sql 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/sql/monthly_settle.sql 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/sql/出入库历史表创建.sql 1385 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/monthlySettle/monthlySettle.js 620 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/orderPakinLog/order.js 354 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/orderPakoutLog/order.js 354 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/monthlySettle/monthlySettle.html 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/orderPakinLog/order.html 261 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/orderPakoutLog/order.html 261 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/MonthlySettleController.java
New file
@@ -0,0 +1,135 @@
package com.zy.asrs.controller;
import com.baomidou.mybatisplus.plugins.Page;
import com.core.annotations.ManagerAuth;
import com.core.common.R;
import com.zy.asrs.entity.MonthlySettle;
import com.zy.asrs.entity.param.DateRangeParam;
import com.zy.asrs.entity.param.MonthlySettleQueryParam;
import com.zy.asrs.service.MonthlySettleService;
import com.zy.common.web.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.text.SimpleDateFormat;
import java.util.Date;
@RestController
public class MonthlySettleController extends BaseController {
    @Autowired
    private MonthlySettleService monthlySettleService;
    /**
     * èŽ·å–æœˆç»“ä¿¡æ¯
     */
    @RequestMapping(value = "/monthlySettle/{id}/auth")
    @ManagerAuth
    public R get(@PathVariable("id") Long id) {
        return R.ok(monthlySettleService.selectById(id));
    }
    /**
     * åˆ†é¡µæŸ¥è¯¢æœˆç»“列表
     */
    @RequestMapping(value = "/monthlySettle/list/auth")
    @ManagerAuth
    public R list(MonthlySettleQueryParam param) {
        Page<MonthlySettle> page = new Page<>(param.getCurr(), param.getLimit());
        java.util.Map<String, Object> condition = new java.util.HashMap<>();
        if (param.getSettleNo() != null && !param.getSettleNo().trim().isEmpty()) {
            condition.put("settleNo", param.getSettleNo());
        }
        if (param.getStatus() != null) {
            condition.put("status", param.getStatus());
        }
        if (param.getStartDate() != null && !param.getStartDate().trim().isEmpty()
                && param.getEndDate() != null && !param.getEndDate().trim().isEmpty()) {
            condition.put("startDate", param.getStartDate());
            condition.put("endDate", param.getEndDate());
        }
        page.setCondition(condition);
        return R.ok(monthlySettleService.getPage(page));
    }
    /**
     * èŽ·å–æœ€è¿‘çš„æœˆç»“è®°å½•
     */
    @RequestMapping(value = "/monthlySettle/latest/auth")
    @ManagerAuth
    public R getLatest() {
        MonthlySettle latest = monthlySettleService.getLatestSettle();
        return R.ok(latest);
    }
    /**
     * èŽ·å–ä¸‹ä¸€ä¸ªæœˆç»“çš„èµ·å§‹æ—¥æœŸ
     */
    @RequestMapping(value = "/monthlySettle/nextStartDate/auth")
    @ManagerAuth
    public R getNextStartDate() {
        Date nextStartDate = monthlySettleService.getNextStartDate();
        if (nextStartDate != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return R.ok(sdf.format(nextStartDate));
        }
        return R.ok(null);
    }
    /**
     * èŽ·å–æœ€æ™šæœˆç»“è®°å½•çš„ç»“æŸæ—¥æœŸ
     */
    @RequestMapping(value = "/monthlySettle/latestEndDate/auth")
    @ManagerAuth
    public R getLatestEndDate() {
        Date latestEndDate = monthlySettleService.getLatestEndDate();
        if (latestEndDate != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return R.ok(sdf.format(latestEndDate));
        }
        return R.ok(null);
    }
    /**
     * æ£€æŸ¥æœˆç»“时间范围内是否有未完成的订单
     */
    @RequestMapping(value = "/monthlySettle/checkUnfinished/auth")
    @ManagerAuth
    public R checkUnfinished(DateRangeParam param) {
        boolean hasUnfinished = monthlySettleService.hasUnfinishedOrders(param.getStartDate(), param.getEndDate());
        if (hasUnfinished) {
            return R.error("月结时间范围内存在未完成的订单,无法进行月结");
        }
        return R.ok();
    }
    /**
     * å‘起月结
     */
    @RequestMapping(value = "/monthlySettle/start/auth")
    @ManagerAuth
    public R startSettle(DateRangeParam param) {
        return R.ok(monthlySettleService.startSettle(param.getStartDate(), param.getEndDate(), getUserId()));
    }
    /**
     * èŽ·å–æœˆç»“ç»Ÿè®¡ä¿¡æ¯
     */
    @RequestMapping(value = "/monthlySettle/statistics/{id}/auth")
    @ManagerAuth
    public R getStatistics(@PathVariable("id") Long id) {
        return R.ok(monthlySettleService.getSettleStatistics(id));
    }
    /**
     * åˆ é™¤æœˆç»“记录
     */
    @RequestMapping(value = "/monthlySettle/{id}/auth", method = RequestMethod.DELETE)
    @ManagerAuth
    public R delete(@PathVariable("id") Long id) {
        monthlySettleService.deleteSettle(id);
        return R.ok("删除成功");
    }
}
src/main/java/com/zy/asrs/controller/OrderDetlPakinLogController.java
New file
@@ -0,0 +1,64 @@
package com.zy.asrs.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.core.annotations.ManagerAuth;
import com.core.common.Cools;
import com.core.common.DateUtils;
import com.core.common.R;
import com.zy.asrs.entity.OrderDetlPakinLog;
import com.zy.asrs.service.OrderDetlPakinLogService;
import com.zy.common.web.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("order/pakinLog")
public class OrderDetlPakinLogController extends BaseController {
    @Autowired
    private OrderDetlPakinLogService orderDetlService;
    @RequestMapping(value = "/orderDetl/list/auth")
    @ManagerAuth
    public R list(@RequestParam(defaultValue = "1") Integer curr,
                  @RequestParam(defaultValue = "10") Integer limit,
                  @RequestParam(required = false) String orderByField,
                  @RequestParam(required = false) String orderByType,
                  @RequestParam Map<String, Object> param) {
        EntityWrapper<OrderDetlPakinLog> wrapper = new EntityWrapper<>();
        excludeTrash(param);
        convert(param, wrapper);
        if (!Cools.isEmpty(orderByField)) {
            wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));
        } else {
            wrapper.orderBy("create_time", false);
        }
        Page<OrderDetlPakinLog> orderDetlPage = orderDetlService.selectPage(new Page<>(curr, limit), wrapper);
        return R.ok(orderDetlPage);
    }
    private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            String val = String.valueOf(entry.getValue());
            if (Cools.isEmpty(val) || "null".equals(val)) {
                continue;
            }
            if (val.contains(RANGE_TIME_LINK)) {
                String[] dates = val.split(RANGE_TIME_LINK);
                wrapper.ge(key, DateUtils.convert(dates[0]));
                wrapper.le(key, DateUtils.convert(dates[1]));
            } else if ("order_id".equals(key) || "orderId".equals(key)) {
                // order_id使用精确匹配
                wrapper.eq(key, val);
            } else {
                wrapper.like(key, val);
            }
        }
    }
}
src/main/java/com/zy/asrs/controller/OrderDetlPakoutLogController.java
New file
@@ -0,0 +1,64 @@
package com.zy.asrs.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.core.annotations.ManagerAuth;
import com.core.common.Cools;
import com.core.common.DateUtils;
import com.core.common.R;
import com.zy.asrs.entity.OrderDetlPakoutLog;
import com.zy.asrs.service.OrderDetlPakoutLogService;
import com.zy.common.web.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("order/pakoutLog")
public class OrderDetlPakoutLogController extends BaseController {
    @Autowired
    private OrderDetlPakoutLogService orderDetlService;
    @RequestMapping(value = "/orderDetl/list/auth")
    @ManagerAuth
    public R list(@RequestParam(defaultValue = "1") Integer curr,
                  @RequestParam(defaultValue = "10") Integer limit,
                  @RequestParam(required = false) String orderByField,
                  @RequestParam(required = false) String orderByType,
                  @RequestParam Map<String, Object> param) {
        EntityWrapper<OrderDetlPakoutLog> wrapper = new EntityWrapper<>();
        excludeTrash(param);
        convert(param, wrapper);
        if (!Cools.isEmpty(orderByField)) {
            wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));
        } else {
            wrapper.orderBy("create_time", false);
        }
        Page<OrderDetlPakoutLog> orderDetlPage = orderDetlService.selectPage(new Page<>(curr, limit), wrapper);
        return R.ok(orderDetlPage);
    }
    private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            String val = String.valueOf(entry.getValue());
            if (Cools.isEmpty(val) || "null".equals(val)) {
                continue;
            }
            if (val.contains(RANGE_TIME_LINK)) {
                String[] dates = val.split(RANGE_TIME_LINK);
                wrapper.ge(key, DateUtils.convert(dates[0]));
                wrapper.le(key, DateUtils.convert(dates[1]));
            } else if ("order_id".equals(key) || "orderId".equals(key)) {
                // order_id使用精确匹配
                wrapper.eq(key, val);
            } else {
                wrapper.like(key, val);
            }
        }
    }
}
src/main/java/com/zy/asrs/controller/OrderPakinLogController.java
New file
@@ -0,0 +1,222 @@
package com.zy.asrs.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.core.annotations.ManagerAuth;
import com.core.common.*;
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.result.WrkTraceVo;
import com.zy.asrs.service.*;
import com.zy.common.web.BaseController;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@RestController
@RequestMapping("order/pakinLog")
public class OrderPakinLogController extends BaseController {
    @Autowired
    private OrderPakinLogService orderService;
    @Autowired
    private OrderDetlPakinLogService orderDetlService;
    @Autowired
    private WrkDetlService wrkDetlService;
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private WrkMastLogService wrkMastLogService;
    @Autowired
    private OrderTimeChangeLogService orderTimeChangeLogService;
    @RequestMapping(value = "/order/head/page/auth")
    @ManagerAuth
    public R head(@RequestParam(defaultValue = "1") Integer curr,
                  @RequestParam(defaultValue = "10") Integer limit,
                  @RequestParam(required = false) String orderByField,
                  @RequestParam(required = false) String orderByType,
                  @RequestParam Map<String, Object> param) {
        EntityWrapper<OrderPakinLog> wrapper = new EntityWrapper<>();
        excludeTrash(param);
        convert(param, wrapper);
        if (!Cools.isEmpty(orderByField)) {
            wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));
        } else {
            wrapper.orderBy("create_time", false);
        }
        Page<OrderPakinLog> page = orderService.selectPage(new Page<>(curr, limit), wrapper);
        // æ‰¹é‡æŸ¥è¯¢å“ªäº›è®¢å•有变更记录
        if (page.getRecords() != null && !page.getRecords().isEmpty()) {
            java.util.List<Long> orderIds = new java.util.ArrayList<>();
            for (OrderPakinLog order : page.getRecords()) {
                orderIds.add(order.getId());
            }
            if (!orderIds.isEmpty()) {
                EntityWrapper<OrderTimeChangeLog> logWrapper = new EntityWrapper<>();
                logWrapper.in("order_id", orderIds);
                logWrapper.eq("order_type", 1); // 1:入库
                java.util.List<OrderTimeChangeLog> changeLogs = orderTimeChangeLogService.selectList(logWrapper);
                java.util.Set<Long> orderIdsWithLog = new java.util.HashSet<>();
                if (changeLogs != null) {
                    for (OrderTimeChangeLog log : changeLogs) {
                        orderIdsWithLog.add(log.getOrderId());
                    }
                }
                // è®¾ç½®æ˜¯å¦æœ‰å˜æ›´è®°å½•标识
                for (OrderPakinLog order : page.getRecords()) {
                    order.setHasChangeLog(orderIdsWithLog.contains(order.getId()));
                }
            }
        }
        return R.ok(page);
    }
    @RequestMapping(value = "/order/detl/all/auth")
    @ManagerAuth
    public R head(@RequestParam Long orderId) {
        return R.ok().add(orderDetlService.selectList(new EntityWrapper<OrderDetlPakinLog>().eq("order_id", orderId)));
    }
    @PostMapping(value = "/order/wrk/trace/auth")
    @ManagerAuth
    public R orderWrkTrace(@RequestParam("orderId") Long orderId) {
        OrderPakinLog order = orderService.selectById(orderId);
        if (null == order) {
            return R.error("单据不存在");
        }
        // æ•°é‡ç»Ÿè®¡
        List<OrderDetlPakinLog> orderDetls = orderDetlService.selectList(new EntityWrapper<OrderDetlPakinLog>().eq("order_id", orderId));
        double totalQty = 0;
        double wrkQty = 0;
        double lackQty = 0;
        double endQty = 0;
        for (OrderDetlPakinLog orderDetl : orderDetls) {
            totalQty = totalQty + orderDetl.getAnfme();
            wrkQty = wrkQty + (orderDetl.getWorkQty() != null ? orderDetl.getWorkQty() : 0);
            endQty = endQty + (orderDetl.getQty() != null ? orderDetl.getQty() : 0);
        }
        // ä»»åŠ¡è¿½æº¯
        List<WrkTraceVo> wrkTraceVos = new ArrayList<>();
        List<WrkDetl> wrkDetls = wrkDetlService.selectAndLogByOrderNoGroupByMatnrOfSum(order.getOrderNo());
        for (WrkDetl wrkDetl : wrkDetls) {
            WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", wrkDetl.getWrkNo()).eq("io_time", wrkDetl.getIoTime()));
            if (wrkMast == null) {
                WrkMastLog wrkMastLog = wrkMastLogService.selectOne(new EntityWrapper<WrkMastLog>().eq("wrk_no", wrkDetl.getWrkNo()).eq("io_time", wrkDetl.getIoTime()));
                if (wrkMastLog != null && wrkMastLog.getIoType() == 103) {
                    wrkMastLog = wrkMastLogService.selectOne(new EntityWrapper<WrkMastLog>().eq("wrk_no", wrkDetl.getWrkNo()).eq("io_time", wrkDetl.getIoTime()).eq("io_type", 53));
                }
                if (wrkMastLog != null) {
                    wrkMast = new WrkMast();
                    BeanUtils.copyProperties(wrkMastLog, wrkMast);
                } else {
                    continue;
                }
            }
            boolean exist = false;
            for (WrkTraceVo vo : wrkTraceVos) {
                if (vo.getWrkNo().equals(wrkMast.getWrkNo()) && vo.getIoTimeStr().equals(DateUtils.convert(wrkMast.getIoTime()))) {
                    vo.getWrkDetls().add(wrkDetl);
                    exist = true;
                }
            }
            if (!exist) {
                WrkTraceVo vo = new WrkTraceVo(wrkMast.getWrkNo(), DateUtils.convert(wrkMast.getIoTime()), wrkMast, wrkDetl);
                wrkTraceVos.add(vo);
            }
        }
        if (!Cools.isEmpty(wrkTraceVos) && wrkTraceVos.size() > 1) {
            wrkTraceVos.sort((o1, o2) -> (int) (o2.getWrkMast().getIoTime().getTime() - o1.getWrkMast().getIoTime().getTime()));
        }
        return R.ok().add(Cools
                .add("list", wrkTraceVos)
                .add("orderNo", order.getOrderNo())
                .add("totalQty", totalQty)
                .add("wrkQty", wrkQty)
                .add("lackQty", lackQty)
                .add("endQty", endQty)
        );
    }
    @RequestMapping(value = "/order/{id}/auth")
    @ManagerAuth
    public R get(@PathVariable("id") String id) {
        return R.ok(orderService.selectById(String.valueOf(id)));
    }
    @RequestMapping(value = "/order/list/auth")
    @ManagerAuth
    public R list(@RequestParam(defaultValue = "1") Integer curr,
                  @RequestParam(defaultValue = "10") Integer limit,
                  @RequestParam(required = false) String orderByField,
                  @RequestParam(required = false) String orderByType,
                  @RequestParam Map<String, Object> param) {
        EntityWrapper<OrderPakinLog> wrapper = new EntityWrapper<>();
        excludeTrash(param);
        convert(param, wrapper);
        if (!Cools.isEmpty(orderByField)) {
            wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));
        }
        return R.ok(orderService.selectPage(new Page<>(curr, limit), wrapper));
    }
    @PostMapping(value = "/order/update/orderTime/auth")
    @ManagerAuth(memo = "修改历史单据业务时间")
    public R updateOrderTime(@RequestParam Long id, @RequestParam String orderTime, @RequestParam(required = false) String memo) {
        if (Cools.isEmpty(id) || Cools.isEmpty(orderTime)) {
            return R.error("参数不能为空");
        }
        OrderPakinLog order = orderService.selectById(id);
        if (order == null) {
            return R.error("单据不存在");
        }
        // æ£€æŸ¥æ˜¯å¦å·²ç»‘定月结单据,如果已绑定则禁止修改
        if (order.getMonthlySettleId() != null && order.getMonthlySettleId() > 0) {
            return R.error("该单据已绑定月结单据,不能修改业务时间");
        }
        // èŽ·å–åŽŸä¸šåŠ¡æ—¶é—´ï¼ˆåœ¨ä¿®æ”¹å‰èŽ·å–ï¼‰
        String oldOrderTime = order.getOrderTime();
        // æ£€æŸ¥æ–°æ—§æ—¶é—´æ˜¯å¦ç›¸åŒ
        if (oldOrderTime != null && oldOrderTime.equals(orderTime)) {
            return R.error("新业务时间与原业务时间相同,无需修改");
        }
        // æ›´æ–°ä¸šåŠ¡æ—¶é—´
        order.setOrderTime(orderTime);
        order.setUpdateBy(getUserId());
        order.setUpdateTime(new Date());
        if (!orderService.updateById(order)) {
            throw new CoolException("修改业务时间失败");
        }
        // ä¿å­˜å˜æ›´è®°å½•(只有时间不同时才保存)
        if (oldOrderTime != null && !oldOrderTime.equals(orderTime)) {
            OrderTimeChangeLog changeLog = new OrderTimeChangeLog();
            changeLog.setOrderId(order.getId());
            changeLog.setOrderNo(order.getOrderNo());
            changeLog.setOrderType(1); // 1:入库
            changeLog.setOldOrderTime(oldOrderTime);
            changeLog.setNewOrderTime(orderTime);
            changeLog.setMemo(memo);
            changeLog.setCreateBy(getUserId());
            changeLog.setCreateTime(new Date());
            orderTimeChangeLogService.insert(changeLog);
        }
        return R.ok("修改成功");
    }
    private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String val = String.valueOf(entry.getValue());
            if (val.contains(RANGE_TIME_LINK)) {
                String[] dates = val.split(RANGE_TIME_LINK);
                wrapper.ge(entry.getKey(), DateUtils.convert(dates[0]));
                wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
            } else {
                wrapper.like(entry.getKey(), val);
            }
        }
    }
}
src/main/java/com/zy/asrs/controller/OrderPakoutLogController.java
New file
@@ -0,0 +1,227 @@
package com.zy.asrs.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.core.annotations.ManagerAuth;
import com.core.common.*;
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.entity.result.WrkTraceVo;
import com.zy.asrs.service.*;
import com.zy.common.web.BaseController;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@RestController
@RequestMapping("order/pakoutLog")
public class OrderPakoutLogController extends BaseController {
    @Autowired
    private OrderPakoutLogService orderService;
    @Autowired
    private OrderDetlPakoutLogService orderDetlService;
    @Autowired
    private WrkDetlService wrkDetlService;
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private WrkMastLogService wrkMastLogService;
    @Autowired
    private OrderTimeChangeLogService orderTimeChangeLogService;
    @RequestMapping(value = "/order/head/page/auth")
    @ManagerAuth
    public R head(@RequestParam(defaultValue = "1") Integer curr,
                  @RequestParam(defaultValue = "10") Integer limit,
                  @RequestParam(required = false) String orderByField,
                  @RequestParam(required = false) String orderByType,
                  @RequestParam Map<String, Object> param) {
        EntityWrapper<OrderPakoutLog> wrapper = new EntityWrapper<>();
        excludeTrash(param);
        convert(param, wrapper);
        if (!Cools.isEmpty(orderByField)) {
            wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));
        } else {
            wrapper.orderBy("create_time", false);
        }
        Page<OrderPakoutLog> page = orderService.selectPage(new Page<>(curr, limit), wrapper);
        // æ‰¹é‡æŸ¥è¯¢å“ªäº›è®¢å•有变更记录
        if (page.getRecords() != null && !page.getRecords().isEmpty()) {
            java.util.List<Long> orderIds = new java.util.ArrayList<>();
            for (OrderPakoutLog order : page.getRecords()) {
                orderIds.add(order.getId());
            }
            if (!orderIds.isEmpty()) {
                EntityWrapper<OrderTimeChangeLog> logWrapper = new EntityWrapper<>();
                logWrapper.in("order_id", orderIds);
                logWrapper.eq("order_type", 2); // 2:出库
                java.util.List<OrderTimeChangeLog> changeLogs = orderTimeChangeLogService.selectList(logWrapper);
                java.util.Set<Long> orderIdsWithLog = new java.util.HashSet<>();
                if (changeLogs != null) {
                    for (OrderTimeChangeLog log : changeLogs) {
                        orderIdsWithLog.add(log.getOrderId());
                    }
                }
                // è®¾ç½®æ˜¯å¦æœ‰å˜æ›´è®°å½•标识
                for (OrderPakoutLog order : page.getRecords()) {
                    order.setHasChangeLog(orderIdsWithLog.contains(order.getId()));
                }
            }
        }
        return R.ok(page);
    }
    @RequestMapping(value = "/order/detl/all/auth")
    @ManagerAuth
    public R head(@RequestParam Long orderId) {
        return R.ok().add(orderDetlService.selectList(new EntityWrapper<OrderDetlPakoutLog>().eq("order_id", orderId)));
    }
    @PostMapping(value = "/order/wrk/trace/auth")
    @ManagerAuth
    public R orderWrkTrace(@RequestParam("orderId") Long orderId) {
        OrderPakoutLog order = orderService.selectById(orderId);
        if (null == order) {
            return R.error("单据不存在");
        }
        // æ•°é‡ç»Ÿè®¡
        List<OrderDetlPakoutLog> orderDetls = orderDetlService.selectList(new EntityWrapper<OrderDetlPakoutLog>().eq("order_id", orderId));
        double totalQty = 0;
        double wrkQty = 0;
        double lackQty = 0;
        double endQty = 0;
        for (OrderDetlPakoutLog orderDetl : orderDetls) {
            totalQty = totalQty + orderDetl.getAnfme();
            wrkQty = wrkQty + (orderDetl.getWorkQty() != null ? orderDetl.getWorkQty() : 0);
            endQty = endQty + (orderDetl.getQty() != null ? orderDetl.getQty() : 0);
        }
        // ä»»åŠ¡è¿½æº¯
        List<WrkTraceVo> wrkTraceVos = new ArrayList<>();
        List<WrkDetl> wrkDetls = wrkDetlService.selectAndLogByOrderNoGroupByMatnrOfSum(order.getOrderNo());
        for (WrkDetl wrkDetl : wrkDetls) {
            WrkMast wrkMast = wrkMastService.selectOne(
                    new EntityWrapper<WrkMast>().eq("wrk_no", wrkDetl.getWrkNo()).eq("io_time", wrkDetl.getIoTime()));
            if (wrkMast == null) {
                WrkMastLog wrkMastLog = wrkMastLogService.selectOne(new EntityWrapper<WrkMastLog>()
                        .eq("wrk_no", wrkDetl.getWrkNo()).eq("io_time", wrkDetl.getIoTime()));
                if (wrkMastLog != null && wrkMastLog.getIoType() == 103) {
                    wrkMastLog = wrkMastLogService.selectOne(new EntityWrapper<WrkMastLog>()
                            .eq("wrk_no", wrkDetl.getWrkNo()).eq("io_time", wrkDetl.getIoTime()).eq("io_type", 53));
                }
                if (wrkMastLog != null) {
                    wrkMast = new WrkMast();
                    BeanUtils.copyProperties(wrkMastLog, wrkMast);
                } else {
                    continue;
                }
            }
            boolean exist = false;
            for (WrkTraceVo vo : wrkTraceVos) {
                if (vo.getWrkNo().equals(wrkMast.getWrkNo())
                        && vo.getIoTimeStr().equals(DateUtils.convert(wrkMast.getIoTime()))) {
                    vo.getWrkDetls().add(wrkDetl);
                    exist = true;
                }
            }
            if (!exist) {
                WrkTraceVo vo = new WrkTraceVo(wrkMast.getWrkNo(), DateUtils.convert(wrkMast.getIoTime()), wrkMast,
                        wrkDetl);
                wrkTraceVos.add(vo);
            }
        }
        if (!Cools.isEmpty(wrkTraceVos) && wrkTraceVos.size() > 1) {
            wrkTraceVos.sort(
                    (o1, o2) -> (int) (o2.getWrkMast().getIoTime().getTime() - o1.getWrkMast().getIoTime().getTime()));
        }
        return R.ok().add(Cools
                .add("list", wrkTraceVos)
                .add("orderNo", order.getOrderNo())
                .add("totalQty", totalQty)
                .add("wrkQty", wrkQty)
                .add("lackQty", lackQty)
                .add("endQty", endQty));
    }
    @RequestMapping(value = "/order/{id}/auth")
    @ManagerAuth
    public R get(@PathVariable("id") String id) {
        return R.ok(orderService.selectById(String.valueOf(id)));
    }
    @RequestMapping(value = "/order/list/auth")
    @ManagerAuth
    public R list(@RequestParam(defaultValue = "1") Integer curr,
            @RequestParam(defaultValue = "10") Integer limit,
            @RequestParam(required = false) String orderByField,
            @RequestParam(required = false) String orderByType,
            @RequestParam Map<String, Object> param) {
        EntityWrapper<OrderPakoutLog> wrapper = new EntityWrapper<>();
        excludeTrash(param);
        convert(param, wrapper);
        if (!Cools.isEmpty(orderByField)) {
            wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));
        }
        return R.ok(orderService.selectPage(new Page<>(curr, limit), wrapper));
    }
    @PostMapping(value = "/order/update/orderTime/auth")
    @ManagerAuth(memo = "修改历史单据业务时间")
    public R updateOrderTime(@RequestParam Long id, @RequestParam String orderTime, @RequestParam(required = false) String memo) {
        if (Cools.isEmpty(id) || Cools.isEmpty(orderTime)) {
            return R.error("参数不能为空");
        }
        OrderPakoutLog order = orderService.selectById(id);
        if (order == null) {
            return R.error("单据不存在");
        }
        // æ£€æŸ¥æ˜¯å¦å·²ç»‘定月结单据,如果已绑定则禁止修改
        if (order.getMonthlySettleId() != null && order.getMonthlySettleId() > 0) {
            return R.error("该单据已绑定月结单据,不能修改业务时间");
        }
        // èŽ·å–åŽŸä¸šåŠ¡æ—¶é—´ï¼ˆåœ¨ä¿®æ”¹å‰èŽ·å–ï¼‰
        String oldOrderTime = order.getOrderTime();
        // æ£€æŸ¥æ–°æ—§æ—¶é—´æ˜¯å¦ç›¸åŒ
        if (oldOrderTime != null && oldOrderTime.equals(orderTime)) {
            return R.error("新业务时间与原业务时间相同,无需修改");
        }
        // æ›´æ–°ä¸šåŠ¡æ—¶é—´
        order.setOrderTime(orderTime);
        order.setUpdateBy(getUserId());
        order.setUpdateTime(new Date());
        if (!orderService.updateById(order)) {
            throw new CoolException("修改业务时间失败");
        }
        // ä¿å­˜å˜æ›´è®°å½•(只有时间不同时才保存)
        if (oldOrderTime != null && !oldOrderTime.equals(orderTime)) {
            OrderTimeChangeLog changeLog = new OrderTimeChangeLog();
            changeLog.setOrderId(order.getId());
            changeLog.setOrderNo(order.getOrderNo());
            changeLog.setOrderType(2); // 2:出库
            changeLog.setOldOrderTime(oldOrderTime);
            changeLog.setNewOrderTime(orderTime);
            changeLog.setMemo(memo);
            changeLog.setCreateBy(getUserId());
            changeLog.setCreateTime(new Date());
            orderTimeChangeLogService.insert(changeLog);
        }
        return R.ok("修改成功");
    }
    private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String val = String.valueOf(entry.getValue());
            if (val.contains(RANGE_TIME_LINK)) {
                String[] dates = val.split(RANGE_TIME_LINK);
                wrapper.ge(entry.getKey(), DateUtils.convert(dates[0]));
                wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
            } else {
                wrapper.like(entry.getKey(), val);
            }
        }
    }
}
src/main/java/com/zy/asrs/controller/OrderTimeChangeLogController.java
New file
@@ -0,0 +1,77 @@
package com.zy.asrs.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.core.annotations.ManagerAuth;
import com.core.common.Cools;
import com.core.common.R;
import com.zy.asrs.entity.OrderTimeChangeLog;
import com.zy.asrs.service.OrderTimeChangeLogService;
import com.zy.common.web.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("orderTimeChangeLog")
public class OrderTimeChangeLogController extends BaseController {
    @Autowired
    private OrderTimeChangeLogService orderTimeChangeLogService;
    /**
     * åˆ†é¡µæŸ¥è¯¢å˜æ›´è®°å½•
     */
    @PostMapping(value = "/page/auth")
    @ManagerAuth(memo = "查询业务时间变更记录")
    public R page(@RequestParam(defaultValue = "1") Integer curr,
                  @RequestParam(defaultValue = "10") Integer limit,
                  @RequestParam(required = false) String orderByField,
                  @RequestParam(required = false) String orderByType,
                  @RequestParam Map<String, Object> param) {
        EntityWrapper<OrderTimeChangeLog> wrapper = new EntityWrapper<>();
        convert(param, wrapper);
        if (!Cools.isEmpty(orderByField)) {
            wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));
        } else {
            wrapper.orderBy("create_time", false);
        }
        return R.ok(orderTimeChangeLogService.selectPage(new Page<>(curr, limit), wrapper));
    }
    /**
     * æ ¹æ®è®¢å•ID查询变更记录
     */
    @PostMapping(value = "/list/byOrderId/auth")
    @ManagerAuth(memo = "根据订单ID查询变更记录")
    public R listByOrderId(@RequestParam Long orderId) {
        EntityWrapper<OrderTimeChangeLog> wrapper = new EntityWrapper<>();
        wrapper.eq("order_id", orderId);
        wrapper.orderBy("create_time", false);
        java.util.List<OrderTimeChangeLog> list = orderTimeChangeLogService.selectList(wrapper);
        // è®¾ç½®åˆ›å»ºäººåç§°
        if (list != null) {
            for (OrderTimeChangeLog log : list) {
                log.setCreateByName(log.getCreateByName());
            }
        }
        return R.ok(list);
    }
    private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            String val = String.valueOf(entry.getValue());
            if (Cools.isEmpty(val) || "null".equals(val)) {
                continue;
            }
            if ("order_id".equals(key) || "orderId".equals(key)) {
                wrapper.eq(key, val);
            } else {
                wrapper.like(key, val);
            }
        }
    }
}
src/main/java/com/zy/asrs/entity/MonthlySettle.java
New file
@@ -0,0 +1,188 @@
package com.zy.asrs.entity;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import com.core.common.Cools;
import com.core.common.SpringUtils;
import com.zy.system.entity.User;
import com.zy.system.service.UserService;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
@Data
@TableName("man_monthly_settle")
public class MonthlySettle implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ID
     */
    @ApiModelProperty(value = "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * æœˆç»“编号
     */
    @ApiModelProperty(value = "月结编号")
    @TableField("settle_no")
    private String settleNo;
    /**
     * èµ·å§‹æ—¥æœŸ
     */
    @ApiModelProperty(value = "起始日期")
    @TableField("start_date")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date startDate;
    /**
     * ç»“束日期
     */
    @ApiModelProperty(value = "结束日期")
    @TableField("end_date")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date endDate;
    /**
     * çŠ¶æ€ 0:待月结 1:已月结
     */
    @ApiModelProperty(value = "状态 0:待月结 1:已月结")
    private Integer status;
    /**
     * æ€»å…¥åº“数量
     */
    @ApiModelProperty(value = "总入库数量")
    @TableField("total_in_qty")
    private BigDecimal totalInQty;
    /**
     * æ€»å‡ºåº“数量
     */
    @ApiModelProperty(value = "总出库数量")
    @TableField("total_out_qty")
    private BigDecimal totalOutQty;
    /**
     * ç‰©æ–™ç§ç±»æ•°
     */
    @ApiModelProperty(value = "物料种类数")
    @TableField("total_materials")
    private Integer totalMaterials;
    /**
     * å¤‡æ³¨
     */
    @ApiModelProperty(value = "备注")
    private String memo;
    /**
     * åˆ›å»ºäººå‘˜
     */
    @ApiModelProperty(value = "创建人员")
    @TableField("create_by")
    private Long createBy;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @ApiModelProperty(value = "创建时间")
    @TableField("create_time")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * ä¿®æ”¹äººå‘˜
     */
    @ApiModelProperty(value = "修改人员")
    @TableField("update_by")
    private Long updateBy;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    @ApiModelProperty(value = "修改时间")
    @TableField("update_time")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    /**
     * åˆ é™¤æ ‡è®° 0:未删除 1:已删除
     */
    @ApiModelProperty(value = "删除标记 0:未删除 1:已删除")
    @TableField("is_deleted")
    private Integer isDeleted;
    public String getStatus$() {
        if (null == this.status) {
            return null;
        }
        switch (this.status) {
            case 0:
                return "待月结";
            case 1:
                return "已月结";
            default:
                return String.valueOf(this.status);
        }
    }
    public String getStartDate$() {
        if (Cools.isEmpty(this.startDate)) {
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd").format(this.startDate);
    }
    public String getEndDate$() {
        if (Cools.isEmpty(this.endDate)) {
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd").format(this.endDate);
    }
    public String getCreateBy$() {
        UserService service = SpringUtils.getBean(UserService.class);
        User user = service.selectById(this.createBy);
        if (!Cools.isEmpty(user)) {
            return String.valueOf(user.getUsername());
        }
        return null;
    }
    public String getCreateTime$() {
        if (Cools.isEmpty(this.createTime)) {
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdateBy$() {
        UserService service = SpringUtils.getBean(UserService.class);
        User user = service.selectById(this.updateBy);
        if (!Cools.isEmpty(user)) {
            return String.valueOf(user.getUsername());
        }
        return null;
    }
    public String getUpdateTime$() {
        if (Cools.isEmpty(this.updateTime)) {
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
}
src/main/java/com/zy/asrs/entity/MonthlySettleDetail.java
New file
@@ -0,0 +1,151 @@
package com.zy.asrs.entity;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@Data
@TableName("man_monthly_settle_detail")
public class MonthlySettleDetail implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ID
     */
    @ApiModelProperty(value = "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * æœˆç»“主表ID
     */
    @ApiModelProperty(value = "月结主表ID")
    @TableField("settle_id")
    private Long settleId;
    /**
     * æœˆç»“编号
     */
    @ApiModelProperty(value = "月结编号")
    @TableField("settle_no")
    private String settleNo;
    // ========== åŸºæœ¬ä¿¡æ¯ ==========
    /**
     * ç‰©æ–™ç¼–码
     */
    @ApiModelProperty(value = "物料编码")
    private String matnr;
    /**
     * æ‰¹æ¬¡ï¼ˆè®¢å•明细批次)
     */
    @ApiModelProperty(value = "批次")
    private String batch;
    /**
     * ç‰©æ–™åç§°ï¼ˆæœˆç»“时从订单明细表获取)
     */
    @ApiModelProperty(value = "物料名称")
    private String maktx;
    /**
     * å“ç‰Œï¼ˆæœˆç»“时从订单明细表获取)
     */
    @ApiModelProperty(value = "品牌")
    private String brand;
    // ========== æ•°é‡ä¿¡æ¯ ==========
    /**
     * æœŸåˆåº“存(上期结余)
     */
    @ApiModelProperty(value = "期初库存(上期结余)")
    @TableField("beginning_qty")
    private BigDecimal beginningQty;
    /**
     * æœ¬æœŸå…¥åº“数量
     */
    @ApiModelProperty(value = "本期入库数量")
    @TableField("in_qty")
    private BigDecimal inQty;
    /**
     * æœ¬æœŸå‡ºåº“数量
     */
    @ApiModelProperty(value = "本期出库数量")
    @TableField("out_qty")
    private BigDecimal outQty;
    /**
     * æœŸæœ«åº“存(期初+入库-出库)
     */
    @ApiModelProperty(value = "期末库存(期初+入库-出库)")
    @TableField("ending_qty")
    private BigDecimal endingQty;
    /**
     * å·®å¼‚数量(期末库存-期初库存)
     * æœŸæœ«å¤§äºŽæœŸåˆæ—¶ä¸ºæ­£æ•°ï¼Œè¡¨ç¤ºåº“存增加
     */
    @ApiModelProperty(value = "差异数量(期末库存-期初库存)")
    @TableField("diff_qty")
    private BigDecimal diffQty;
    // ========== å…³è”字段(通过关联查询获取,不存储在明细表中)==========
    /**
     * è§„格(优先从出入库订单明细表获取,如果为空则从物料表获取)
     */
    @ApiModelProperty(value = "规格")
    @TableField(exist = false)
    private String specs;
    /**
     * åž‹å·ï¼ˆä¼˜å…ˆä»Žå‡ºå…¥åº“订单明细表获取,如果为空则从物料表获取)
     */
    @ApiModelProperty(value = "型号")
    @TableField(exist = false)
    private String model;
    /**
     * é¢œè‰²ï¼ˆä¼˜å…ˆä»Žå‡ºå…¥åº“订单明细表获取,如果为空则从物料表获取)
     */
    @ApiModelProperty(value = "颜色")
    @TableField(exist = false)
    private String color;
    /**
     * å•位(从物料表获取)
     */
    @ApiModelProperty(value = "单位")
    @TableField(exist = false)
    private String unit;
    // ========== æ—¶é—´ä¿¡æ¯ ==========
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @ApiModelProperty(value = "创建时间")
    @TableField("create_time")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * åˆ é™¤æ ‡è®° 0:未删除 1:已删除
     */
    @ApiModelProperty(value = "删除标记 0:未删除 1:已删除")
    @TableField("is_deleted")
    private Integer isDeleted;
}
src/main/java/com/zy/asrs/entity/OrderDetlPakinLog.java
@@ -23,7 +23,7 @@
import java.util.Objects;
@Data
@TableName("man_order_detl_pakin_log")
@TableName("man_order_detl_log_pakin")
public class OrderDetlPakinLog implements Serializable {
    private static final long serialVersionUID = 1L;
@@ -32,7 +32,7 @@
     * ID
     */
    @ApiModelProperty(value = "ID")
    @TableId(value = "id", type = IdType.AUTO)
    @TableId(value = "id", type = IdType.INPUT)
    private Long id;
    /**
src/main/java/com/zy/asrs/entity/OrderDetlPakoutLog.java
@@ -22,7 +22,7 @@
import java.util.Date;
@Data
@TableName("man_order_detl_pakout_log")
@TableName("man_order_detl_log_pakout")
public class OrderDetlPakoutLog implements Serializable {
    private static final long serialVersionUID = 1L;
@@ -31,7 +31,7 @@
     * ID
     */
    @ApiModelProperty(value = "ID")
    @TableId(value = "id", type = IdType.AUTO)
    @TableId(value = "id", type = IdType.INPUT)
    private Long id;
    /**
src/main/java/com/zy/asrs/entity/OrderPakin.java
@@ -276,6 +276,20 @@
    @TableField("pakin_pakout_status")
    private Integer pakinPakoutStatus;
    /**
     * æœˆç»“ID
     */
    @ApiModelProperty(value = "月结ID")
    @TableField("monthly_settle_id")
    private Long monthlySettleId;
    /**
     * æœˆç»“编号
     */
    @ApiModelProperty(value = "月结编号")
    @TableField("monthly_settle_no")
    private String monthlySettleNo;
    public OrderPakin() {
    }
src/main/java/com/zy/asrs/entity/OrderPakinLog.java
@@ -20,7 +20,7 @@
import java.util.Date;
@Data
@TableName("man_order_pakin_log")
@TableName("man_order_log_pakin")
public class OrderPakinLog implements Serializable {
    private static final long serialVersionUID = 1L;
@@ -29,7 +29,7 @@
     * ID
     */
    @ApiModelProperty(value = "ID")
    @TableId(value = "id", type = IdType.AUTO)
    @TableId(value = "id", type = IdType.INPUT)
    private Long id;
    /**
@@ -276,6 +276,27 @@
    @TableField("pakin_pakout_status")
    private Integer pakinPakoutStatus;
    /**
     * æœˆç»“ID
     */
    @ApiModelProperty(value = "月结ID")
    @TableField("monthly_settle_id")
    private Long monthlySettleId;
    /**
     * æœˆç»“编号
     */
    @ApiModelProperty(value = "月结编号")
    @TableField("monthly_settle_no")
    private String monthlySettleNo;
    /**
     * æ˜¯å¦æœ‰ä¸šåŠ¡æ—¶é—´å˜æ›´è®°å½•ï¼ˆä¸´æ—¶å­—æ®µï¼Œä¸æ˜ å°„åˆ°æ•°æ®åº“ï¼‰
     */
    @ApiModelProperty(value = "是否有业务时间变更记录")
    @TableField(exist = false)
    private Boolean hasChangeLog;
    public OrderPakinLog() {
    }
src/main/java/com/zy/asrs/entity/OrderPakout.java
@@ -276,6 +276,20 @@
    @TableField("pakin_pakout_status")
    private Integer pakinPakoutStatus;
    /**
     * æœˆç»“ID
     */
    @ApiModelProperty(value = "月结ID")
    @TableField("monthly_settle_id")
    private Long monthlySettleId;
    /**
     * æœˆç»“编号
     */
    @ApiModelProperty(value = "月结编号")
    @TableField("monthly_settle_no")
    private String monthlySettleNo;
    public OrderPakout() {
    }
src/main/java/com/zy/asrs/entity/OrderPakoutLog.java
@@ -20,7 +20,7 @@
import java.util.Date;
@Data
@TableName("man_order_pakout_log")
@TableName("man_order_log_pakout")
public class OrderPakoutLog implements Serializable {
    private static final long serialVersionUID = 1L;
@@ -29,7 +29,7 @@
     * ID
     */
    @ApiModelProperty(value = "ID")
    @TableId(value = "id", type = IdType.AUTO)
    @TableId(value = "id", type = IdType.INPUT)
    private Long id;
    /**
@@ -276,6 +276,27 @@
    @TableField("pakin_pakout_status")
    private Integer pakinPakoutStatus;
    /**
     * æœˆç»“ID
     */
    @ApiModelProperty(value = "月结ID")
    @TableField("monthly_settle_id")
    private Long monthlySettleId;
    /**
     * æœˆç»“编号
     */
    @ApiModelProperty(value = "月结编号")
    @TableField("monthly_settle_no")
    private String monthlySettleNo;
    /**
     * æ˜¯å¦æœ‰ä¸šåŠ¡æ—¶é—´å˜æ›´è®°å½•ï¼ˆä¸´æ—¶å­—æ®µï¼Œä¸æ˜ å°„åˆ°æ•°æ®åº“ï¼‰
     */
    @ApiModelProperty(value = "是否有业务时间变更记录")
    @TableField(exist = false)
    private Boolean hasChangeLog;
    public OrderPakoutLog() {
    }
src/main/java/com/zy/asrs/entity/OrderTimeChangeLog.java
New file
@@ -0,0 +1,117 @@
package com.zy.asrs.entity;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import com.core.common.Cools;
import com.core.common.SpringUtils;
import com.zy.system.entity.User;
import com.zy.system.service.UserService;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
@Data
@TableName("man_order_time_change_log")
public class OrderTimeChangeLog implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ID
     */
    @ApiModelProperty(value = "ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * è®¢å•ID
     */
    @ApiModelProperty(value = "订单ID")
    @TableField("order_id")
    private Long orderId;
    /**
     * å•据编号
     */
    @ApiModelProperty(value = "单据编号")
    @TableField("order_no")
    private String orderNo;
    /**
     * è®¢å•类型 1:入库 2:出库
     */
    @ApiModelProperty(value = "订单类型 1:入库 2:出库")
    @TableField("order_type")
    private Integer orderType;
    /**
     * åŽŸä¸šåŠ¡æ—¶é—´
     */
    @ApiModelProperty(value = "原业务时间")
    @TableField("old_order_time")
    private String oldOrderTime;
    /**
     * æ–°ä¸šåŠ¡æ—¶é—´
     */
    @ApiModelProperty(value = "新业务时间")
    @TableField("new_order_time")
    private String newOrderTime;
    /**
     * å¤‡æ³¨
     */
    @ApiModelProperty(value = "备注")
    private String memo;
    /**
     * åˆ›å»ºäºº
     */
    @ApiModelProperty(value = "创建人")
    @TableField("create_by")
    private Long createBy;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @ApiModelProperty(value = "创建时间")
    @TableField("create_time")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * åˆ›å»ºäººåç§°
     */
    @ApiModelProperty(value = "创建人名称")
    @TableField(exist = false)
    private String createByName;
    public String getCreateByName() {
        if (createByName != null) {
            return createByName;
        }
        UserService service = SpringUtils.getBean(UserService.class);
        User user = service.selectById(this.createBy);
        if (!Cools.isEmpty(user)) {
            return user.getUsername();
        }
        if (this.createBy != null && this.createBy == 9527) {
            return "super";
        }
        return null;
    }
    public String getCreateTime$() {
        if (Cools.isEmpty(this.createTime)) {
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
}
src/main/java/com/zy/asrs/entity/param/DateRangeParam.java
New file
@@ -0,0 +1,29 @@
package com.zy.asrs.entity.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * æ—¥æœŸèŒƒå›´å‚æ•°
 */
@Data
public class DateRangeParam {
    /**
     * èµ·å§‹æ—¥æœŸ
     */
    @ApiModelProperty(value = "起始日期", required = true)
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date startDate;
    /**
     * ç»“束日期(可以接受 yyyy-MM-dd æˆ– yyyy-MM-dd HH:mm:ss æ ¼å¼ï¼‰
     */
    @ApiModelProperty(value = "结束日期", required = true)
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date endDate;
}
src/main/java/com/zy/asrs/entity/param/MonthlySettleQueryParam.java
New file
@@ -0,0 +1,48 @@
package com.zy.asrs.entity.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * æœˆç»“查询参数
 */
@Data
public class MonthlySettleQueryParam {
    /**
     * å½“前页
     */
    @ApiModelProperty(value = "当前页")
    private Integer curr = 1;
    /**
     * æ¯é¡µæ•°é‡
     */
    @ApiModelProperty(value = "每页数量")
    private Integer limit = 10;
    /**
     * æœˆç»“编号
     */
    @ApiModelProperty(value = "月结编号")
    private String settleNo;
    /**
     * çŠ¶æ€
     */
    @ApiModelProperty(value = "状态")
    private Integer status;
    /**
     * èµ·å§‹æ—¥æœŸ
     */
    @ApiModelProperty(value = "起始日期")
    private String startDate;
    /**
     * ç»“束日期
     */
    @ApiModelProperty(value = "结束日期")
    private String endDate;
}
src/main/java/com/zy/asrs/entity/result/MaterialInOutRawDTO.java
New file
@@ -0,0 +1,43 @@
package com.zy.asrs.entity.result;
import lombok.Data;
import java.math.BigDecimal;
/**
 * ç‰©æ–™å‡ºå…¥åº“原始数据(未分类)
 */
@Data
public class MaterialInOutRawDTO {
    /**
     * ç‰©æ–™ç¼–码
     */
    private String matnr;
    /**
     * ç‰©æ–™åç§°
     */
    private String maktx;
    /**
     * æ‰¹æ¬¡
     */
    private String batch;
    /**
     * å“ç‰Œ
     */
    private String brand;
    /**
     * æ•°é‡ï¼ˆéƒ½æ˜¯æ­£æ•°ï¼‰
     */
    private BigDecimal qty;
    /**
     * å…¥å‡ºåº“类型(0:未知,1:入库,2:出库)
     */
    private Integer pakinPakoutStatus;
}
src/main/java/com/zy/asrs/entity/result/MaterialInOutStatDTO.java
New file
@@ -0,0 +1,43 @@
package com.zy.asrs.entity.result;
import lombok.Data;
import java.math.BigDecimal;
/**
 * ç‰©æ–™å‡ºå…¥åº“统计
 */
@Data
public class MaterialInOutStatDTO {
    /**
     * ç‰©æ–™ç¼–码
     */
    private String matnr;
    /**
     * ç‰©æ–™åç§°
     */
    private String maktx;
    /**
     * æ‰¹æ¬¡
     */
    private String batch;
    /**
     * å“ç‰Œ
     */
    private String brand;
    /**
     * å…¥åº“数量
     */
    private BigDecimal inQty;
    /**
     * å‡ºåº“数量
     */
    private BigDecimal outQty;
}
src/main/java/com/zy/asrs/entity/result/MonthlySettleResultVO.java
New file
@@ -0,0 +1,44 @@
package com.zy.asrs.entity.result;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
 * æœˆç»“结果
 */
@Data
public class MonthlySettleResultVO {
    /**
     * æœˆç»“ID
     */
    @ApiModelProperty(value = "月结ID")
    private Long settleId;
    /**
     * æœˆç»“编号
     */
    @ApiModelProperty(value = "月结编号")
    private String settleNo;
    /**
     * æ€»å…¥åº“数量
     */
    @ApiModelProperty(value = "总入库数量")
    private BigDecimal totalInQty;
    /**
     * æ€»å‡ºåº“数量
     */
    @ApiModelProperty(value = "总出库数量")
    private BigDecimal totalOutQty;
    /**
     * ç‰©æ–™ç§ç±»æ•°
     */
    @ApiModelProperty(value = "物料种类数")
    private Integer totalMaterials;
}
src/main/java/com/zy/asrs/entity/result/MonthlySettleStatisticsVO.java
New file
@@ -0,0 +1,28 @@
package com.zy.asrs.entity.result;
import com.zy.asrs.entity.MonthlySettle;
import com.zy.asrs.entity.MonthlySettleDetail;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * æœˆç»“统计信息
 */
@Data
public class MonthlySettleStatisticsVO {
    /**
     * æœˆç»“主记录
     */
    @ApiModelProperty(value = "月结主记录")
    private MonthlySettle settle;
    /**
     * æœˆç»“明细列表
     */
    @ApiModelProperty(value = "月结明细列表")
    private List<MonthlySettleDetail> details;
}
src/main/java/com/zy/asrs/entity/result/PreviousSettleEndingQtyDTO.java
New file
@@ -0,0 +1,38 @@
package com.zy.asrs.entity.result;
import lombok.Data;
import java.math.BigDecimal;
/**
 * ä¸ŠæœŸæœˆç»“期末库存
 */
@Data
public class PreviousSettleEndingQtyDTO {
    /**
     * ç‰©æ–™ç¼–码
     */
    private String matnr;
    /**
     * æ‰¹æ¬¡
     */
    private String batch;
    /**
     * å“ç‰Œ
     */
    private String brand;
    /**
     * ç‰©æ–™åç§°
     */
    private String maktx;
    /**
     * æœŸæœ«åº“å­˜
     */
    private BigDecimal endingQty;
}
src/main/java/com/zy/asrs/entity/result/StockQtyDTO.java
New file
@@ -0,0 +1,28 @@
package com.zy.asrs.entity.result;
import lombok.Data;
import java.math.BigDecimal;
/**
 * åº“存数量DTO(用于批量查询)
 */
@Data
public class StockQtyDTO {
    /**
     * ç‰©æ–™ç¼–码
     */
    private String matnr;
    /**
     * æ‰¹æ¬¡
     */
    private String batch;
    /**
     * åº“存数量
     */
    private BigDecimal stockQty;
}
src/main/java/com/zy/asrs/mapper/ManLocDetlMapper.java
@@ -57,6 +57,12 @@
    Double queryStockAnfme(String matnr, String batch);
    /**
     * æ‰¹é‡æŸ¥è¯¢åº“存数量
     * @param matnrBatchList ç‰©æ–™ç¼–码和批次的组合列表,格式:matnr_batch
     */
    List<com.zy.asrs.entity.result.StockQtyDTO> queryStockAnfmeBatch(@Param("matnrBatchList") List<String> matnrBatchList);
    List<StockVo> queryStockTotal();
src/main/java/com/zy/asrs/mapper/MonthlySettleDetailMapper.java
New file
@@ -0,0 +1,20 @@
package com.zy.asrs.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.zy.asrs.entity.MonthlySettleDetail;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface MonthlySettleDetailMapper extends BaseMapper<MonthlySettleDetail> {
    /**
     * æŸ¥è¯¢æœˆç»“明细(关联物料表)
     */
    List<MonthlySettleDetail> selectDetailWithMat(@Param("settleId") Long settleId);
}
src/main/java/com/zy/asrs/mapper/MonthlySettleMapper.java
New file
@@ -0,0 +1,69 @@
package com.zy.asrs.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.zy.asrs.entity.MonthlySettle;
import com.zy.asrs.entity.result.MaterialInOutRawDTO;
import com.zy.asrs.entity.result.PreviousSettleEndingQtyDTO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface MonthlySettleMapper extends BaseMapper<MonthlySettle> {
    /**
     * èŽ·å–æœ€è¿‘çš„æœˆç»“è®°å½•
     */
    MonthlySettle selectLatestSettle();
    /**
     * ç»Ÿè®¡æœˆç»“时间范围内未完成的入库订单数量
     */
    int countUnfinishedOrdersInRangePakin(@Param("startDate") String startDate, @Param("endDate") String endDate);
    /**
     * ç»Ÿè®¡æœˆç»“时间范围内未完成的出库订单数量
     */
    int countUnfinishedOrdersInRangePakout(@Param("startDate") String startDate, @Param("endDate") String endDate);
    /**
     * ç»Ÿè®¡æœˆç»“时间范围内的物料出入库数量(从入库表查询)
     */
    List<MaterialInOutRawDTO> statisticsMaterialInOutFromPakin(@Param("startDate") String startDate, @Param("endDate") String endDate);
    /**
     * ç»Ÿè®¡æœˆç»“时间范围内的物料出入库数量(从出库表查询)
     */
    List<MaterialInOutRawDTO> statisticsMaterialInOutFromPakout(@Param("startDate") String startDate, @Param("endDate") String endDate);
    /**
     * èŽ·å–ä¸Šä¸€ä¸ªæœˆç»“çš„ç‰©æ–™æœŸæœ«åº“å­˜
     */
    List<PreviousSettleEndingQtyDTO> getPreviousSettleEndingQty(@Param("previousSettleId") Long previousSettleId);
    /**
     * æ›´æ–°å…¥åº“订单的月结信息
     */
    int updateOrderSettleInfo(@Param("settleId") Long settleId, @Param("settleNo") String settleNo,
                              @Param("startDate") String startDate, @Param("endDate") String endDate);
    /**
     * æ›´æ–°å‡ºåº“订单的月结信息
     */
    int updateOrderSettleInfoPakout(@Param("settleId") Long settleId, @Param("settleNo") String settleNo,
                                    @Param("startDate") String startDate, @Param("endDate") String endDate);
    /**
     * æ¸…除入库订单的月结信息
     */
    int clearOrderSettleInfo(@Param("settleId") Long settleId);
    /**
     * æ¸…除出库订单的月结信息
     */
    int clearOrderSettleInfoPakout(@Param("settleId") Long settleId);
}
src/main/java/com/zy/asrs/mapper/OrderTimeChangeLogMapper.java
New file
@@ -0,0 +1,12 @@
package com.zy.asrs.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.zy.asrs.entity.OrderTimeChangeLog;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface OrderTimeChangeLogMapper extends BaseMapper<OrderTimeChangeLog> {
}
src/main/java/com/zy/asrs/service/ManLocDetlService.java
@@ -47,6 +47,12 @@
    Double queryStockAnfme(String matnr, String batch);
    /**
     * æ‰¹é‡æŸ¥è¯¢åº“存数量
     * @param matnrBatchList ç‰©æ–™ç¼–码和批次的组合列表,格式:matnr_batch
     */
    List<com.zy.asrs.entity.result.StockQtyDTO> queryStockAnfmeBatch(List<String> matnrBatchList);
    List<StockVo> queryStockTotal();
src/main/java/com/zy/asrs/service/MonthlySettleService.java
New file
@@ -0,0 +1,61 @@
package com.zy.asrs.service;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.IService;
import com.zy.asrs.entity.MonthlySettle;
import com.zy.asrs.entity.result.MonthlySettleResultVO;
import com.zy.asrs.entity.result.MonthlySettleStatisticsVO;
import java.util.Date;
public interface MonthlySettleService extends IService<MonthlySettle> {
    /**
     * èŽ·å–æœ€è¿‘çš„æœˆç»“è®°å½•
     */
    MonthlySettle getLatestSettle();
    /**
     * èŽ·å–ä¸‹ä¸€ä¸ªæœˆç»“çš„èµ·å§‹æ—¥æœŸ
     */
    Date getNextStartDate();
    /**
     * èŽ·å–æœ€æ™šæœˆç»“è®°å½•çš„ç»“æŸæ—¥æœŸ
     */
    Date getLatestEndDate();
    /**
     * æ£€æŸ¥æœˆç»“时间范围内是否有未完成的订单
     */
    boolean hasUnfinishedOrders(Date startDate, Date endDate);
    /**
     * å‘起月结
     */
    MonthlySettleResultVO startSettle(Date startDate, Date endDate, Long userId);
    /**
     * èŽ·å–æœˆç»“ç»Ÿè®¡ä¿¡æ¯
     */
    MonthlySettleStatisticsVO getSettleStatistics(Long settleId);
    /**
     * åˆ†é¡µæŸ¥è¯¢æœˆç»“列表
     */
    Page<MonthlySettle> getPage(Page<MonthlySettle> page);
    /**
     * åˆ é™¤æœˆç»“记录
     */
    void deleteSettle(Long settleId);
    /**
     * æ£€æŸ¥æŒ‡å®šæ—¥æœŸæ˜¯å¦åœ¨ä»»ä½•已月结的区间内
     * @param orderTime è®¢å•业务时间(字符串格式:yyyy-MM-dd HH:mm:ss)
     * @return å¦‚果日期在任何已月结区间内,返回true;否则返回false
     */
    boolean isOrderTimeInSettledRange(String orderTime);
}
src/main/java/com/zy/asrs/service/OrderDetlPakinLogService.java
New file
@@ -0,0 +1,9 @@
package com.zy.asrs.service;
import com.baomidou.mybatisplus.service.IService;
import com.zy.asrs.entity.OrderDetlPakinLog;
public interface OrderDetlPakinLogService extends IService<OrderDetlPakinLog> {
}
src/main/java/com/zy/asrs/service/OrderDetlPakoutLogService.java
New file
@@ -0,0 +1,9 @@
package com.zy.asrs.service;
import com.baomidou.mybatisplus.service.IService;
import com.zy.asrs.entity.OrderDetlPakoutLog;
public interface OrderDetlPakoutLogService extends IService<OrderDetlPakoutLog> {
}
src/main/java/com/zy/asrs/service/OrderPakinLogService.java
New file
@@ -0,0 +1,16 @@
package com.zy.asrs.service;
import com.baomidou.mybatisplus.service.IService;
import com.zy.asrs.entity.OrderDetlPakinLog;
import com.zy.asrs.entity.OrderPakinLog;
import java.util.List;
public interface OrderPakinLogService extends IService<OrderPakinLog> {
    OrderPakinLog selectByNo(String orderNo);
    List<OrderDetlPakinLog> selectDetlsByOrderId(Long orderId);
}
src/main/java/com/zy/asrs/service/OrderPakoutLogService.java
New file
@@ -0,0 +1,16 @@
package com.zy.asrs.service;
import com.baomidou.mybatisplus.service.IService;
import com.zy.asrs.entity.OrderDetlPakoutLog;
import com.zy.asrs.entity.OrderPakoutLog;
import java.util.List;
public interface OrderPakoutLogService extends IService<OrderPakoutLog> {
    OrderPakoutLog selectByNo(String orderNo);
    List<OrderDetlPakoutLog> selectDetlsByOrderId(Long orderId);
}
src/main/java/com/zy/asrs/service/OrderTimeChangeLogService.java
New file
@@ -0,0 +1,8 @@
package com.zy.asrs.service;
import com.baomidou.mybatisplus.service.IService;
import com.zy.asrs.entity.OrderTimeChangeLog;
public interface OrderTimeChangeLogService extends IService<OrderTimeChangeLog> {
}
src/main/java/com/zy/asrs/service/impl/ManLocDetlServiceImpl.java
@@ -105,6 +105,14 @@
    }
    @Override
    public List<com.zy.asrs.entity.result.StockQtyDTO> queryStockAnfmeBatch(List<String> matnrBatchList) {
        if (matnrBatchList == null || matnrBatchList.isEmpty()) {
            return new java.util.ArrayList<>();
        }
        return this.baseMapper.queryStockAnfmeBatch(matnrBatchList);
    }
    @Override
    public List<StockVo> queryStockTotal() {
        return this.baseMapper.queryStockTotal();
    }
src/main/java/com/zy/asrs/service/impl/MonthlySettleServiceImpl.java
New file
@@ -0,0 +1,593 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.core.common.Cools;
import com.core.common.SnowflakeIdWorker;
import com.core.exception.CoolException;
import com.zy.asrs.entity.MonthlySettle;
import com.zy.asrs.entity.MonthlySettleDetail;
import com.zy.asrs.entity.result.MaterialInOutRawDTO;
import com.zy.asrs.entity.result.MaterialInOutStatDTO;
import com.zy.asrs.entity.result.MonthlySettleResultVO;
import com.zy.asrs.entity.result.MonthlySettleStatisticsVO;
import com.zy.asrs.entity.result.PreviousSettleEndingQtyDTO;
import com.zy.asrs.mapper.MonthlySettleDetailMapper;
import com.zy.asrs.mapper.MonthlySettleMapper;
import com.zy.asrs.service.ManLocDetlService;
import com.zy.asrs.service.MonthlySettleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Service("monthlySettleService")
public class MonthlySettleServiceImpl extends ServiceImpl<MonthlySettleMapper, MonthlySettle> implements MonthlySettleService {
    @Autowired
    private MonthlySettleDetailMapper monthlySettleDetailMapper;
    @Autowired
    private ManLocDetlService manLocDetlService;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Override
    public MonthlySettle getLatestSettle() {
        return this.baseMapper.selectLatestSettle();
    }
    @Override
    public Date getNextStartDate() {
        MonthlySettle latestSettle = getLatestSettle();
        if (latestSettle == null) {
            // å¦‚果没有月结记录,返回null,由前端选择起始日期
            return null;
        }
        // è¿”回最晚月结记录结束日期的下一天(起始日期应该是结束日期+1天的00:00:00)
        Calendar cal = Calendar.getInstance();
        cal.setTime(latestSettle.getEndDate());
        // å…ˆè®¾ç½®ä¸ºå½“天的00:00:00,然后加1天,确保返回的是下一天的00:00:00
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.add(Calendar.DAY_OF_MONTH, 1);
        return cal.getTime();
    }
    @Override
    public Date getLatestEndDate() {
        MonthlySettle latestSettle = getLatestSettle();
        if (latestSettle == null) {
            return null;
        }
        // è¿”回最晚月结记录的结束日期(格式化为当天的00:00:00,用于显示)
        Calendar cal = Calendar.getInstance();
        cal.setTime(latestSettle.getEndDate());
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }
    @Override
    public boolean hasUnfinishedOrders(Date startDate, Date endDate) {
        // ç»“束日期+23:59:59
        Calendar cal = Calendar.getInstance();
        cal.setTime(endDate);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        endDate = cal.getTime();
        // æ³¨æ„ï¼šorder_time æ˜¯ varchar ç±»åž‹ï¼Œéœ€è¦æ ¼å¼åŒ–为完整的日期时间字符串进行比较
        SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // èµ·å§‹æ—¥æœŸè®¾ç½®ä¸ºå½“天的 00:00:00
        Calendar startCal = Calendar.getInstance();
        startCal.setTime(startDate);
        startCal.set(Calendar.HOUR_OF_DAY, 0);
        startCal.set(Calendar.MINUTE, 0);
        startCal.set(Calendar.SECOND, 0);
        startCal.set(Calendar.MILLISECOND, 0);
        String startDateStr = dateTimeFormat.format(startCal.getTime());
        String endDateStr = dateTimeFormat.format(endDate);
        // åˆ†ä¸¤æ¬¡æŸ¥è¯¢ï¼šå…¥åº“和出库
        int pakinCount = this.baseMapper.countUnfinishedOrdersInRangePakin(startDateStr, endDateStr);
        int pakoutCount = this.baseMapper.countUnfinishedOrdersInRangePakout(startDateStr, endDateStr);
        return (pakinCount + pakoutCount) > 0;
    }
    @Override
    @Transactional
    public MonthlySettleResultVO startSettle(Date startDate, Date endDate, Long userId) {
        // ç»“束日期+23:59:59
        Calendar cal = Calendar.getInstance();
        cal.setTime(endDate);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        endDate = cal.getTime();
        // æ£€æŸ¥èµ·å§‹æ—¥æœŸå¿…须大于最晚月结记录的结束日期
        MonthlySettle latestSettle = getLatestSettle();
        if (latestSettle != null) {
            Calendar startCal = Calendar.getInstance();
            startCal.setTime(startDate);
            startCal.set(Calendar.HOUR_OF_DAY, 0);
            startCal.set(Calendar.MINUTE, 0);
            startCal.set(Calendar.SECOND, 0);
            startCal.set(Calendar.MILLISECOND, 0);
            Calendar latestEndCal = Calendar.getInstance();
            latestEndCal.setTime(latestSettle.getEndDate());
            latestEndCal.set(Calendar.HOUR_OF_DAY, 0);
            latestEndCal.set(Calendar.MINUTE, 0);
            latestEndCal.set(Calendar.SECOND, 0);
            latestEndCal.set(Calendar.MILLISECOND, 0);
            // èµ·å§‹æ—¥æœŸå¿…须大于最晚结束日期,不能等于或小于
            if (!startCal.getTime().after(latestEndCal.getTime())) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                throw new CoolException("起始日期必须大于最晚月结记录的结束日期:" + sdf.format(latestSettle.getEndDate()));
            }
        }
        // æ£€æŸ¥æ˜¯å¦æœ‰æœªå®Œæˆçš„订单
        if (hasUnfinishedOrders(startDate, endDate)) {
            throw new CoolException("月结时间范围内存在未完成的订单,无法进行月结");
        }
        // ç»Ÿè®¡ç‰©æ–™å‡ºå…¥åº“数量(分别查询两个表,在Java代码中合并)
        // æ³¨æ„ï¼šorder_time æ˜¯ varchar ç±»åž‹ï¼Œéœ€è¦æ ¼å¼åŒ–为完整的日期时间字符串进行比较
        SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // èµ·å§‹æ—¥æœŸè®¾ç½®ä¸ºå½“天的 00:00:00
        Calendar startCal = Calendar.getInstance();
        startCal.setTime(startDate);
        startCal.set(Calendar.HOUR_OF_DAY, 0);
        startCal.set(Calendar.MINUTE, 0);
        startCal.set(Calendar.SECOND, 0);
        startCal.set(Calendar.MILLISECOND, 0);
        String startDateStr = dateTimeFormat.format(startCal.getTime());
        String endDateStr = dateTimeFormat.format(endDate);
        // åˆ†åˆ«æŸ¥è¯¢å…¥åº“表和出库表
        List<MaterialInOutRawDTO> pakinDataList = this.baseMapper.statisticsMaterialInOutFromPakin(startDateStr, endDateStr);
        List<MaterialInOutRawDTO> pakoutDataList = this.baseMapper.statisticsMaterialInOutFromPakout(startDateStr, endDateStr);
        // åˆå¹¶ä¸¤ä¸ªè¡¨çš„æ•°æ®
        List<MaterialInOutRawDTO> rawDataList = new java.util.ArrayList<>();
        if (pakinDataList != null && !pakinDataList.isEmpty()) {
            rawDataList.addAll(pakinDataList);
        }
        if (pakoutDataList != null && !pakoutDataList.isEmpty()) {
            rawDataList.addAll(pakoutDataList);
        }
        // æ£€æŸ¥æ˜¯å¦æœ‰å‡ºå…¥åº“历史订单
        if (rawDataList == null || rawDataList.isEmpty()) {
            throw new CoolException("月结时间范围内没有出入库历史订单,无法进行月结");
        }
        // åœ¨Java代码中处理分类统计逻辑
        // 1. å¤„理NULL值(batch、brand、maktx)
        // 2. æ ¹æ®ç‰©æ–™ç¼–码、批次、品牌分组
        // 3. æ ¹æ® pakin_pakout_status åŒºåˆ†å…¥åº“和出库
        Map<String, MaterialInOutStatDTO> materialStatsMap = new HashMap<>();
        Map<String, String> maktxMap = new HashMap<>(); // å­˜å‚¨ç‰©æ–™åç§°ï¼ˆå–第一个非空值)
        for (MaterialInOutRawDTO raw : rawDataList) {
            // å¤„理NULL值
            String matnr = raw.getMatnr();
            String batch = raw.getBatch() != null ? raw.getBatch() : "";
            String brand = raw.getBrand() != null ? raw.getBrand() : "";
            String maktx = raw.getMaktx() != null ? raw.getMaktx() : "";
            String key = matnr + "_" + batch + "_" + brand;
            // ä¿å­˜ç‰©æ–™åç§°ï¼ˆå–第一个非空值)
            if (maktx != null && !maktx.isEmpty() && !maktxMap.containsKey(key)) {
                maktxMap.put(key, maktx);
            }
            MaterialInOutStatDTO stat = materialStatsMap.get(key);
            if (stat == null) {
                stat = new MaterialInOutStatDTO();
                stat.setMatnr(matnr);
                stat.setMaktx(maktxMap.getOrDefault(key, ""));
                stat.setBatch(batch);
                stat.setBrand(brand);
                stat.setInQty(BigDecimal.ZERO);
                stat.setOutQty(BigDecimal.ZERO);
                materialStatsMap.put(key, stat);
            }
            // æ ¹æ® pakin_pakout_status åˆ†ç±»ç»Ÿè®¡
            // 1 = å…¥åº“,2 = å‡ºåº“,0 = æœªçŸ¥ï¼ˆå·²åœ¨SQL中过滤)
            BigDecimal qty = raw.getQty() != null ? raw.getQty() : BigDecimal.ZERO;
            Integer status = raw.getPakinPakoutStatus();
            if (status != null && qty.compareTo(BigDecimal.ZERO) > 0) {
                if (status == 1) {
                    // å…¥åº“
                    stat.setInQty(stat.getInQty().add(qty));
                } else if (status == 2) {
                    // å‡ºåº“
                    stat.setOutQty(stat.getOutQty().add(qty));
                }
            }
        }
        // è½¬æ¢ä¸ºList
        List<MaterialInOutStatDTO> materialStats = new java.util.ArrayList<>(materialStatsMap.values());
        // èŽ·å–ä¸Šä¸€ä¸ªæœˆç»“è®°å½•ï¼ˆç”¨äºŽè®¡ç®—æœŸåˆåº“å­˜å’Œæ‰¿æŽ¥ä¸Šä¸€æœŸçš„ç‰©æ–™ï¼‰
        MonthlySettle   previousSettle = getLatestSettle();
        Map<String, BigDecimal> previousEndingQtyMap = new HashMap<>();
        Map<String, PreviousSettleEndingQtyDTO> previousDetailMap = new HashMap<>(); // å­˜å‚¨ä¸Šä¸€æœŸçš„完整明细信息
        if (previousSettle != null) {
            List<PreviousSettleEndingQtyDTO> previousDetails = this.baseMapper.getPreviousSettleEndingQty(previousSettle.getId());
            for (PreviousSettleEndingQtyDTO detail : previousDetails) {
                String key = detail.getMatnr() + "_" +
                            (detail.getBatch() != null ? detail.getBatch() : "") + "_" +
                            (detail.getBrand() != null ? detail.getBrand() : "");
                BigDecimal endingQty = detail.getEndingQty() != null ? detail.getEndingQty() : BigDecimal.ZERO;
                previousEndingQtyMap.put(key, endingQty);
                previousDetailMap.put(key, detail); // ä¿å­˜å®Œæ•´ä¿¡æ¯ï¼Œç”¨äºŽåŽç»­åˆ›å»ºæ˜Žç»†
            }
        }
        // ç”Ÿæˆæœˆç»“编号
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String settleNo = "MS" + sdf.format(new Date()) + String.format("%04d", snowflakeIdWorker.nextId() % 10000);
        // åˆ›å»ºæœˆç»“主记录
        MonthlySettle monthlySettle = new MonthlySettle();
        monthlySettle.setSettleNo(settleNo);
        monthlySettle.setStartDate(startDate);
        monthlySettle.setEndDate(endDate);
        monthlySettle.setStatus(1); // å·²æœˆç»“
        monthlySettle.setIsDeleted(0); // æœªåˆ é™¤
        monthlySettle.setCreateBy(userId);
        monthlySettle.setCreateTime(new Date());
        this.insert(monthlySettle);
        BigDecimal totalInQty = BigDecimal.ZERO;
        BigDecimal totalOutQty = BigDecimal.ZERO;
        int materialCount = 0;
        // åˆ›å»º Map å­˜å‚¨æœ¬æœŸæœ‰å‡ºå…¥åº“的物料(用于判断是否需要从上一期继承)
        Map<String, MaterialInOutStatDTO> currentMaterialMap = new HashMap<>();
        for (MaterialInOutStatDTO stat : materialStats) {
            String matnr = stat.getMatnr();
            String batch = stat.getBatch() != null ? stat.getBatch() : "";
            String brand = stat.getBrand() != null ? stat.getBrand() : "";
            String key = matnr + "_" + batch + "_" + brand;
            currentMaterialMap.put(key, stat);
        }
        // æ”¶é›†æ‰€æœ‰æ˜Žç»†è®°å½•,用于批量插入
        List<MonthlySettleDetail> detailList = new java.util.ArrayList<>();
        // 1. å¤„理本期有出入库的物料
        for (MaterialInOutStatDTO stat : materialStats) {
            // 1. æå–基础信息
            String matnr = stat.getMatnr();
            String batch = stat.getBatch() != null ? stat.getBatch() : "";
            String brand = stat.getBrand() != null ? stat.getBrand() : "";
            String maktx = stat.getMaktx();
            // 2. æå–数量信息
            BigDecimal inQty = stat.getInQty() != null ? stat.getInQty() : BigDecimal.ZERO;
            BigDecimal outQty = stat.getOutQty() != null ? stat.getOutQty() : BigDecimal.ZERO;
            // 3. è®¡ç®—库存相关数量
            BigDecimal beginningQty = getBeginningQty(matnr, batch, brand, previousEndingQtyMap);
            BigDecimal endingQty = calculateEndingQty(beginningQty, inQty, outQty);
            // å·®å¼‚数量 = æœŸæœ«åº“å­˜ - æœŸåˆåº“存(期末大于期初时为正数)
            BigDecimal diffQty = calculateDiffQty(beginningQty, endingQty);
            // 4. åˆ›å»ºæ˜Žç»†è®°å½•(暂不插入)
            MonthlySettleDetail detail = buildMonthlySettleDetail(
                monthlySettle.getId(), settleNo, matnr, batch, maktx, brand,
                beginningQty, inQty, outQty, endingQty, diffQty
            );
            detail.setIsDeleted(0); // æœªåˆ é™¤
            detailList.add(detail);
            // 5. ç´¯è®¡ç»Ÿè®¡
            totalInQty = totalInQty.add(inQty);
            totalOutQty = totalOutQty.add(outQty);
            materialCount++;
        }
        // 2. å¤„理上一期存在但本期没有出入库的物料(需要承接显示)
        if (previousSettle != null && !previousDetailMap.isEmpty()) {
            for (Map.Entry<String, PreviousSettleEndingQtyDTO> entry : previousDetailMap.entrySet()) {
                String key = entry.getKey();
                // å¦‚果本期没有出入库,但上一期有期末库存(且不为0),则需要创建一条记录
                if (!currentMaterialMap.containsKey(key)) {
                    PreviousSettleEndingQtyDTO previousDetail = entry.getValue();
                    BigDecimal previousEndingQty = previousDetail.getEndingQty() != null ? previousDetail.getEndingQty() : BigDecimal.ZERO;
                    // å¦‚果上一期的期末库存不为0,或者即使为0也要显示(用于对比)
                    // è¿™é‡Œæˆ‘们总是创建记录,即使上一期期末库存为0,因为用户要求"如果上一期存在过,本期库存归零也要显示一条为0的记录"
                    String matnr = previousDetail.getMatnr();
                    String batch = previousDetail.getBatch() != null ? previousDetail.getBatch() : "";
                    String brand = previousDetail.getBrand() != null ? previousDetail.getBrand() : "";
                    String maktx = previousDetail.getMaktx() != null ? previousDetail.getMaktx() : "";
                    // æœ¬æœŸæ²¡æœ‰å‡ºå…¥åº“,所以入库和出库数量都为0
                    BigDecimal inQty = BigDecimal.ZERO;
                    BigDecimal outQty = BigDecimal.ZERO;
                    // æœŸåˆåº“å­˜ = ä¸Šä¸€æœŸçš„æœŸæœ«åº“å­˜
                    BigDecimal beginningQty = previousEndingQty;
                    // æœŸæœ«åº“å­˜ = æœŸåˆ + å…¥åº“ - å‡ºåº“ = æœŸåˆï¼ˆå› ä¸ºæœ¬æœŸæ²¡æœ‰å‡ºå…¥åº“)
                    BigDecimal endingQty = beginningQty;
                    // å·®å¼‚数量 = æœŸåˆåº“å­˜ - æœŸæœ«åº“存(期初大于期末时为正数)
                    BigDecimal diffQty = calculateDiffQty(beginningQty, endingQty);
                    // åˆ›å»ºæ˜Žç»†è®°å½•(暂不插入)
                    MonthlySettleDetail detail = buildMonthlySettleDetail(
                        monthlySettle.getId(), settleNo, matnr, batch, maktx, brand,
                        beginningQty, inQty, outQty, endingQty, diffQty
                    );
                    detail.setIsDeleted(0); // æœªåˆ é™¤
                    detailList.add(detail);
                    // ç´¯è®¡ç»Ÿè®¡ï¼ˆè™½ç„¶å…¥åº“和出库为0,但也要计入物料种类数)
                    materialCount++;
                }
            }
        }
        // åˆ†æ‰¹æ’入,每批1000条,避免一次性插入过多数据
        if (!detailList.isEmpty()) {
            int batchSize = 1000;
            for (int i = 0; i < detailList.size(); i += batchSize) {
                int end = Math.min(i + batchSize, detailList.size());
                List<MonthlySettleDetail> batch = detailList.subList(i, end);
                for (MonthlySettleDetail detail : batch) {
                    if (monthlySettleDetailMapper.insert(detail) <= 0) {
                        throw new CoolException("插入月结明细失败");
                    }
                }
            }
        }
        // æ›´æ–°æœˆç»“主记录
        monthlySettle.setTotalInQty(totalInQty);
        monthlySettle.setTotalOutQty(totalOutQty);
        monthlySettle.setTotalMaterials(materialCount);
        monthlySettle.setStatus(1); // å·²æœˆç»“
        monthlySettle.setUpdateBy(userId);
        monthlySettle.setUpdateTime(new Date());
        this.updateById(monthlySettle);
        // æ›´æ–°è®¢å•的月结信息(入库和出库都要更新)
        this.baseMapper.updateOrderSettleInfo(monthlySettle.getId(), settleNo, startDateStr, endDateStr);
        this.baseMapper.updateOrderSettleInfoPakout(monthlySettle.getId(), settleNo, startDateStr, endDateStr);
        MonthlySettleResultVO result = new MonthlySettleResultVO();
        result.setSettleId(monthlySettle.getId());
        result.setSettleNo(settleNo);
        result.setTotalInQty(totalInQty);
        result.setTotalOutQty(totalOutQty);
        result.setTotalMaterials(materialCount);
        return result;
    }
    @Override
    public MonthlySettleStatisticsVO getSettleStatistics(Long settleId) {
        MonthlySettle settle = this.selectById(settleId);
        if (settle == null || (settle.getIsDeleted() != null && settle.getIsDeleted() == 1)) {
            throw new CoolException("月结记录不存在");
        }
        // å…³è”物料表查询明细
        List<MonthlySettleDetail> details = monthlySettleDetailMapper.selectDetailWithMat(settleId);
        MonthlySettleStatisticsVO result = new MonthlySettleStatisticsVO();
        result.setSettle(settle);
        result.setDetails(details);
        return result;
    }
    @Override
    public Page<MonthlySettle> getPage(Page<MonthlySettle> page) {
        Map<String, Object> condition = page.getCondition();
        EntityWrapper<MonthlySettle> wrapper = new EntityWrapper<>();
        wrapper.eq("is_deleted", 0);
        if (condition != null) {
            if (condition.get("settleNo") != null) {
                wrapper.like("settle_no", condition.get("settleNo").toString());
            }
            if (condition.get("status") != null) {
                wrapper.eq("status", condition.get("status"));
            }
            if (condition.get("startDate") != null && condition.get("endDate") != null) {
                wrapper.ge("start_date", condition.get("startDate"));
                wrapper.le("end_date", condition.get("endDate"));
            }
        }
        wrapper.orderBy("create_time", false);
        List<MonthlySettle> list = this.selectList(wrapper);
        EntityWrapper<MonthlySettle> countWrapper = new EntityWrapper<>();
        countWrapper.eq("is_deleted", 0);
        if (condition != null) {
            if (condition.get("settleNo") != null) {
                countWrapper.like("settle_no", condition.get("settleNo").toString());
            }
            if (condition.get("status") != null) {
                countWrapper.eq("status", condition.get("status"));
            }
            if (condition.get("startDate") != null && condition.get("endDate") != null) {
                countWrapper.ge("start_date", condition.get("startDate"));
                countWrapper.le("end_date", condition.get("endDate"));
            }
        }
        page.setRecords(list);
        page.setTotal(this.selectCount(countWrapper));
        return page;
    }
    /**
     * èŽ·å–æœŸåˆåº“å­˜ï¼ˆä¸ŠæœŸç»“ä½™ï¼‰
     */
    private BigDecimal getBeginningQty(String matnr, String batch, String brand, Map<String, BigDecimal> previousEndingQtyMap) {
        String key = matnr + "_" + batch + "_" + brand;
        return previousEndingQtyMap.getOrDefault(key, BigDecimal.ZERO);
    }
    /**
     * è®¡ç®—期末库存(期初+入库-出库)
     */
    private BigDecimal calculateEndingQty(BigDecimal beginningQty, BigDecimal inQty, BigDecimal outQty) {
        return beginningQty.add(inQty).subtract(outQty);
    }
    /**
     * èŽ·å–å½“å‰å®žé™…åº“å­˜æ•°é‡ï¼ˆå·²åºŸå¼ƒï¼Œæ”¹ç”¨æ‰¹é‡æŸ¥è¯¢ï¼‰
     * @deprecated ä½¿ç”¨æ‰¹é‡æŸ¥è¯¢æ–¹æ³•替代,避免N+1查询问题
     */
    @Deprecated
    private BigDecimal getCurrentStockQty(String matnr, String batch) {
        Double stockQty = manLocDetlService.queryStockAnfme(matnr, batch);
        return stockQty != null ? BigDecimal.valueOf(stockQty) : BigDecimal.ZERO;
    }
    /**
     * è®¡ç®—差异数量(期末库存-期初库存)
     * æœŸæœ«å¤§äºŽæœŸåˆæ—¶ä¸ºæ­£æ•°ï¼Œè¡¨ç¤ºåº“存增加
     */
    private BigDecimal calculateDiffQty(BigDecimal beginningQty, BigDecimal endingQty) {
        return endingQty.subtract(beginningQty);
    }
    /**
     * æž„建月结明细对象
     */
    private MonthlySettleDetail buildMonthlySettleDetail(
            Long settleId, String settleNo, String matnr, String batch, String maktx, String brand,
            BigDecimal beginningQty, BigDecimal inQty, BigDecimal outQty, BigDecimal endingQty,
            BigDecimal diffQty) {
        MonthlySettleDetail detail = new MonthlySettleDetail();
        // åŸºæœ¬ä¿¡æ¯
        detail.setSettleId(settleId);
        detail.setSettleNo(settleNo);
        detail.setMatnr(matnr);
        detail.setBatch(batch);
        detail.setMaktx(maktx);
        detail.setBrand(brand);
        // æ•°é‡ä¿¡æ¯
        detail.setBeginningQty(beginningQty);
        detail.setInQty(inQty);
        detail.setOutQty(outQty);
        detail.setEndingQty(endingQty);
        // stock_qty å­—段已废弃,实际库存等于期末库存,不再单独存储
        // detail.setStockQty(endingQty);
        detail.setDiffQty(diffQty);
        // æ—¶é—´ä¿¡æ¯
        detail.setCreateTime(new Date());
        return detail;
    }
    @Override
    @Transactional
    public void deleteSettle(Long settleId) {
        MonthlySettle settle = this.selectById(settleId);
        if (settle == null || (settle.getIsDeleted() != null && settle.getIsDeleted() == 1)) {
            throw new CoolException("月结记录不存在");
        }
        // æ¸…除出入库订单的月结信息
        this.baseMapper.clearOrderSettleInfo(settleId);
        this.baseMapper.clearOrderSettleInfoPakout(settleId);
        // é€»è¾‘删除月结明细
        EntityWrapper<MonthlySettleDetail> detailWrapper = new EntityWrapper<>();
        detailWrapper.eq("settle_id", settleId);
        detailWrapper.eq("is_deleted", 0);
        List<MonthlySettleDetail> details = monthlySettleDetailMapper.selectList(detailWrapper);
        if (details != null && !details.isEmpty()) {
            for (MonthlySettleDetail detail : details) {
                detail.setIsDeleted(1);
                monthlySettleDetailMapper.updateById(detail);
            }
        }
        // é€»è¾‘删除月结主记录
        settle.setIsDeleted(1);
        settle.setUpdateTime(new Date());
        this.updateById(settle);
    }
    @Override
    public boolean isOrderTimeInSettledRange(String orderTime) {
        if (Cools.isEmpty(orderTime)) {
            return false;
        }
        try {
            // è§£æžè®¢å•业务时间
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date orderDate = sdf.parse(orderTime);
            // æŸ¥è¯¢æ‰€æœ‰å·²æœˆç»“的记录(status=1且未删除)
            EntityWrapper<MonthlySettle> wrapper = new EntityWrapper<>();
            wrapper.eq("status", 1);
            wrapper.eq("is_deleted", 0);
            List<MonthlySettle> settledList = this.selectList(wrapper);
            if (settledList == null || settledList.isEmpty()) {
                return false;
            }
            // æ£€æŸ¥è®¢å•时间是否在任何已月结的区间内
            for (MonthlySettle settle : settledList) {
                Date startDate = settle.getStartDate();
                Date endDate = settle.getEndDate();
                // ç¡®ä¿startDate是当天的00:00:00
                Calendar startCal = Calendar.getInstance();
                startCal.setTime(startDate);
                startCal.set(Calendar.HOUR_OF_DAY, 0);
                startCal.set(Calendar.MINUTE, 0);
                startCal.set(Calendar.SECOND, 0);
                startCal.set(Calendar.MILLISECOND, 0);
                // ç¡®ä¿endDate是当天的23:59:59.999
                Calendar endCal = Calendar.getInstance();
                endCal.setTime(endDate);
                endCal.set(Calendar.HOUR_OF_DAY, 23);
                endCal.set(Calendar.MINUTE, 59);
                endCal.set(Calendar.SECOND, 59);
                endCal.set(Calendar.MILLISECOND, 999);
                // åˆ¤æ–­è®¢å•时间是否在区间内:[startDate的00:00:00, endDate的23:59:59.999]
                if (!orderDate.before(startCal.getTime()) && !orderDate.after(endCal.getTime())) {
                    return true;
                }
            }
            return false;
        } catch (Exception e) {
            log.error("检查订单时间是否在已月结区间内失败", e);
            return false;
        }
    }
}
src/main/java/com/zy/asrs/service/impl/OrderDetlPakinLogServiceImpl.java
New file
@@ -0,0 +1,13 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zy.asrs.entity.OrderDetlPakinLog;
import com.zy.asrs.mapper.OrderDetlPakinLogMapper;
import com.zy.asrs.service.OrderDetlPakinLogService;
import org.springframework.stereotype.Service;
@Service("orderDetlPakinLogService")
public class OrderDetlPakinLogServiceImpl extends ServiceImpl<OrderDetlPakinLogMapper, OrderDetlPakinLog> implements OrderDetlPakinLogService {
}
src/main/java/com/zy/asrs/service/impl/OrderDetlPakoutLogServiceImpl.java
New file
@@ -0,0 +1,13 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zy.asrs.entity.OrderDetlPakoutLog;
import com.zy.asrs.mapper.OrderDetlPakoutLogMapper;
import com.zy.asrs.service.OrderDetlPakoutLogService;
import org.springframework.stereotype.Service;
@Service("orderDetlPakoutLogService")
public class OrderDetlPakoutLogServiceImpl extends ServiceImpl<OrderDetlPakoutLogMapper, OrderDetlPakoutLog> implements OrderDetlPakoutLogService {
}
src/main/java/com/zy/asrs/service/impl/OrderPakinLogServiceImpl.java
New file
@@ -0,0 +1,37 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.core.common.Cools;
import com.zy.asrs.entity.OrderDetlPakinLog;
import com.zy.asrs.entity.OrderPakinLog;
import com.zy.asrs.mapper.OrderDetlPakinLogMapper;
import com.zy.asrs.mapper.OrderPakinLogMapper;
import com.zy.asrs.service.OrderPakinLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("orderPakinLogService")
public class OrderPakinLogServiceImpl extends ServiceImpl<OrderPakinLogMapper, OrderPakinLog> implements OrderPakinLogService {
    @Autowired
    private OrderDetlPakinLogMapper orderDetlPakinLogMapper;
    @Override
    public OrderPakinLog selectByNo(String orderNo) {
        List<OrderPakinLog> orderList = this.selectList(new EntityWrapper<OrderPakinLog>().eq("order_no", orderNo));
        if (Cools.isEmpty(orderList)) {
            return null;
        }
        return orderList.get(0);
    }
    @Override
    public List<OrderDetlPakinLog> selectDetlsByOrderId(Long orderId) {
        return orderDetlPakinLogMapper.selectList(new EntityWrapper<OrderDetlPakinLog>().eq("order_id", orderId));
    }
}
src/main/java/com/zy/asrs/service/impl/OrderPakoutLogServiceImpl.java
New file
@@ -0,0 +1,37 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.core.common.Cools;
import com.zy.asrs.entity.OrderDetlPakoutLog;
import com.zy.asrs.entity.OrderPakoutLog;
import com.zy.asrs.mapper.OrderDetlPakoutLogMapper;
import com.zy.asrs.mapper.OrderPakoutLogMapper;
import com.zy.asrs.service.OrderPakoutLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("orderPakoutLogService")
public class OrderPakoutLogServiceImpl extends ServiceImpl<OrderPakoutLogMapper, OrderPakoutLog> implements OrderPakoutLogService {
    @Autowired
    private OrderDetlPakoutLogMapper orderDetlPakoutLogMapper;
    @Override
    public OrderPakoutLog selectByNo(String orderNo) {
        List<OrderPakoutLog> orderList = this.selectList(new EntityWrapper<OrderPakoutLog>().eq("order_no", orderNo));
        if (Cools.isEmpty(orderList)) {
            return null;
        }
        return orderList.get(0);
    }
    @Override
    public List<OrderDetlPakoutLog> selectDetlsByOrderId(Long orderId) {
        return orderDetlPakoutLogMapper.selectList(new EntityWrapper<OrderDetlPakoutLog>().eq("order_id", orderId));
    }
}
src/main/java/com/zy/asrs/service/impl/OrderTimeChangeLogServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zy.asrs.entity.OrderTimeChangeLog;
import com.zy.asrs.mapper.OrderTimeChangeLogMapper;
import com.zy.asrs.service.OrderTimeChangeLogService;
import org.springframework.stereotype.Service;
@Service
public class OrderTimeChangeLogServiceImpl extends ServiceImpl<OrderTimeChangeLogMapper, OrderTimeChangeLog> implements OrderTimeChangeLogService {
}
src/main/java/com/zy/asrs/task/handler/OrderPakinMoveHistoryHandler.java
@@ -57,7 +57,6 @@
                orderDetl.setUpdateTime(now);
                OrderDetlPakinLog orderDetlLog = new OrderDetlPakinLog();
                Synchro.Copy(orderDetl, orderDetlLog);
                orderDetlLog.setId(null);
                orderDetlPakinLogMapper.insert(orderDetlLog);
                orderDetlPakinService.deleteById(orderDetl.getId());
            }
@@ -67,7 +66,6 @@
            order.setUpdateTime(now);
            OrderPakinLog orderPakinLog = new OrderPakinLog();
            Synchro.Copy(order, orderPakinLog);
            orderPakinLog.setId(null);
            orderPakinLogMapper.insert(orderPakinLog);
            orderPakinService.deleteById(order.getId());
        }
src/main/java/com/zy/asrs/task/handler/OrderPakoutMoveHistoryHandler.java
@@ -58,7 +58,6 @@
                orderDetl.setUpdateTime(now);
                OrderDetlPakoutLog orderDetlLog = new OrderDetlPakoutLog();
                Synchro.Copy(orderDetl, orderDetlLog);
                orderDetlLog.setId(null);
                orderDetlPakoutLogMapper.insert(orderDetlLog);
                orderDetlPakoutService.deleteById(orderDetl.getId());
            }
@@ -68,7 +67,6 @@
            order.setUpdateTime(now);
            OrderPakoutLog orderPakinLog = new OrderPakoutLog();
            Synchro.Copy(order, orderPakinLog);
            orderPakinLog.setId(null);
            orderPakoutLogMapper.insert(orderPakinLog);
            orderPakoutService.deleteById(order.getId());
        }
src/main/resources/mapper/ManLocDetlMapper.xml
@@ -313,4 +313,22 @@
        where node_id = #{nodeId} ;
    </update>
    <!-- æ‰¹é‡æŸ¥è¯¢åº“存数量 -->
    <select id="queryStockAnfmeBatch" resultType="com.zy.asrs.entity.result.StockQtyDTO">
        SELECT
            matnr,
            ISNULL(batch, '') as batch,
            SUM(anfme) as stockQty
        FROM man_loc_detl
        WHERE 1=1
        <if test="matnrBatchList != null and matnrBatchList.size > 0">
            AND (
            <foreach collection="matnrBatchList" item="item" separator=" OR ">
                (matnr + '_' + ISNULL(batch, '') = #{item})
            </foreach>
            )
        </if>
        GROUP BY matnr, ISNULL(batch, '')
    </select>
</mapper>
src/main/resources/mapper/MonthlySettleDetailMapper.xml
New file
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zy.asrs.mapper.MonthlySettleDetailMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.zy.asrs.entity.MonthlySettleDetail">
        <id column="id" property="id" />
        <result column="settle_id" property="settleId" />
        <result column="settle_no" property="settleNo" />
        <result column="matnr" property="matnr" />
        <result column="batch" property="batch" />
        <result column="maktx" property="maktx" />
        <result column="brand" property="brand" />
        <result column="beginning_qty" property="beginningQty" />
        <result column="in_qty" property="inQty" />
        <result column="out_qty" property="outQty" />
        <result column="ending_qty" property="endingQty" />
        <result column="diff_qty" property="diffQty" />
        <result column="create_time" property="createTime" />
        <result column="is_deleted" property="isDeleted" />
    </resultMap>
    <!-- å…³è”物料表的查询映射结果(获取其他物料信息) -->
    <resultMap id="DetailWithMatResultMap" type="com.zy.asrs.entity.MonthlySettleDetail" extends="BaseResultMap">
        <result column="specs" property="specs" />
        <result column="model" property="model" />
        <result column="color" property="color" />
        <result column="unit" property="unit" />
    </resultMap>
    <!-- æŸ¥è¯¢æœˆç»“明细(从明细表查询,关联物料表获取补充信息) -->
    <select id="selectDetailWithMat" resultMap="DetailWithMatResultMap">
        SELECT
            d.id,
            d.settle_id,
            d.settle_no,
            d.matnr,
            d.batch,
            d.maktx,
            d.brand,
            d.beginning_qty,
            d.in_qty,
            d.out_qty,
            d.ending_qty,
            d.diff_qty,
            d.create_time,
            m.specs,
            m.model,
            m.color,
            m.unit
        FROM man_monthly_settle_detail d
        LEFT JOIN man_mat m ON d.matnr = m.matnr
        WHERE d.settle_id = #{settleId}
        AND d.is_deleted = 0
        ORDER BY d.matnr, d.batch
    </select>
</mapper>
src/main/resources/mapper/MonthlySettleMapper.xml
New file
@@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zy.asrs.mapper.MonthlySettleMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.zy.asrs.entity.MonthlySettle">
        <id column="id" property="id" />
    <result column="settle_no" property="settleNo" />
    <result column="start_date" property="startDate" />
        <result column="end_date" property="endDate" />
        <result column="status" property="status" />
        <result column="total_in_qty" property="totalInQty" />
        <result column="total_out_qty" property="totalOutQty" />
        <result column="total_materials" property="totalMaterials" />
        <result column="memo" property="memo" />
        <result column="create_by" property="createBy" />
        <result column="create_time" property="createTime" />
        <result column="update_by" property="updateBy" />
        <result column="update_time" property="updateTime" />
        <result column="is_deleted" property="isDeleted" />
    </resultMap>
    <!-- èŽ·å–æœ€è¿‘çš„æœˆç»“è®°å½• -->
    <select id="selectLatestSettle" resultMap="BaseResultMap">
        SELECT TOP 1 * FROM man_monthly_settle
        WHERE is_deleted = 0
        ORDER BY end_date DESC
    </select>
    <!-- ç»Ÿè®¡æœˆç»“时间范围内未完成的入库订单数量 -->
    <select id="countUnfinishedOrdersInRangePakin" resultType="int">
        SELECT COUNT(1) FROM man_order_log_pakin molpi
        WHERE molpi.status = 1
        AND molpi.order_time >= #{startDate}
        AND molpi.order_time &lt;= #{endDate}
        AND (molpi.settle IS NULL OR molpi.settle != 6)
        AND (molpi.monthly_settle_id IS NULL OR molpi.monthly_settle_id = 0)
        AND EXISTS (
            SELECT 1 FROM man_order_detl_log_pakin modlpi
            WHERE modlpi.order_id = molpi.id
            AND (modlpi.anfme > modlpi.qty OR modlpi.qty IS NULL)
        )
    </select>
    <!-- ç»Ÿè®¡æœˆç»“时间范围内未完成的出库订单数量 -->
    <select id="countUnfinishedOrdersInRangePakout" resultType="int">
        SELECT COUNT(1) FROM man_order_log_pakout molpo
        WHERE molpo.status = 1
        AND molpo.order_time >= #{startDate}
        AND molpo.order_time &lt;= #{endDate}
        AND (molpo.settle IS NULL OR molpo.settle != 6)
        AND (molpo.monthly_settle_id IS NULL OR molpo.monthly_settle_id = 0)
        AND EXISTS (
            SELECT 1 FROM man_order_detl_log_pakout modlpo
            WHERE modlpo.order_id = molpo.id
            AND (modlpo.anfme > modlpo.qty OR modlpo.qty IS NULL)
        )
    </select>
    <!-- ç»Ÿè®¡æœˆç»“时间范围内的物料出入库数量(从入库表查询) -->
    <select id="statisticsMaterialInOutFromPakin" resultType="com.zy.asrs.entity.result.MaterialInOutRawDTO">
        SELECT
            modlpi.matnr,
            modlpi.maktx,
            modlpi.batch,
            modlpi.brand,
            SUM(modlpi.qty) as qty,
            COALESCE(modlpi.pakin_pakout_status, molpi.pakin_pakout_status) as pakinPakoutStatus
        FROM man_order_log_pakin molpi
        INNER JOIN man_order_detl_log_pakin modlpi ON molpi.id = modlpi.order_id
        WHERE molpi.status = 1
        AND molpi.order_time >= #{startDate}
        AND molpi.order_time &lt;= #{endDate}
        AND molpi.settle = 6
        AND (molpi.monthly_settle_id IS NULL OR molpi.monthly_settle_id = 0)
        AND COALESCE(modlpi.pakin_pakout_status, molpi.pakin_pakout_status) IN (1, 2)
        GROUP BY modlpi.matnr, modlpi.maktx, modlpi.batch, modlpi.brand, COALESCE(modlpi.pakin_pakout_status, molpi.pakin_pakout_status)
    </select>
    <!-- ç»Ÿè®¡æœˆç»“时间范围内的物料出入库数量(从出库表查询) -->
    <select id="statisticsMaterialInOutFromPakout" resultType="com.zy.asrs.entity.result.MaterialInOutRawDTO">
        SELECT
            modlpo.matnr,
            modlpo.maktx,
            modlpo.batch,
            modlpo.brand,
            SUM(modlpo.qty) as qty,
            COALESCE(modlpo.pakin_pakout_status, molpo.pakin_pakout_status) as pakinPakoutStatus
        FROM man_order_log_pakout molpo
        INNER JOIN man_order_detl_log_pakout modlpo ON molpo.id = modlpo.order_id
        WHERE molpo.status = 1
        AND molpo.order_time >= #{startDate}
        AND molpo.order_time &lt;= #{endDate}
        AND molpo.settle = 6
        AND (molpo.monthly_settle_id IS NULL OR molpo.monthly_settle_id = 0)
        AND COALESCE(modlpo.pakin_pakout_status, molpo.pakin_pakout_status) IN (1, 2)
        GROUP BY modlpo.matnr, modlpo.maktx, modlpo.batch, modlpo.brand, COALESCE(modlpo.pakin_pakout_status, molpo.pakin_pakout_status)
    </select>
    <!-- èŽ·å–ä¸Šä¸€ä¸ªæœˆç»“çš„ç‰©æ–™æœŸæœ«åº“å­˜ -->
    <select id="getPreviousSettleEndingQty" resultType="com.zy.asrs.entity.result.PreviousSettleEndingQtyDTO">
        SELECT
            matnr,
            ISNULL(batch, '') as batch,
            ISNULL(brand, '') as brand,
            ISNULL(maktx, '') as maktx,
            ending_qty as endingQty
        FROM man_monthly_settle_detail
        WHERE settle_id = #{previousSettleId}
        AND is_deleted = 0
    </select>
    <!-- æ›´æ–°å…¥åº“订单的月结信息 -->
    <update id="updateOrderSettleInfo">
        UPDATE man_order_log_pakin
        SET monthly_settle_id = #{settleId},
            monthly_settle_no = #{settleNo}
        WHERE status = 1
        AND order_time >= #{startDate}
        AND order_time &lt;= #{endDate}
        AND settle = 6
        AND (monthly_settle_id IS NULL OR monthly_settle_id = 0)
    </update>
    <!-- æ›´æ–°å‡ºåº“订单的月结信息 -->
    <update id="updateOrderSettleInfoPakout">
        UPDATE man_order_log_pakout
        SET monthly_settle_id = #{settleId},
            monthly_settle_no = #{settleNo}
        WHERE status = 1
        AND order_time >= #{startDate}
        AND order_time &lt;= #{endDate}
        AND settle = 6
        AND (monthly_settle_id IS NULL OR monthly_settle_id = 0)
    </update>
    <!-- æ¸…除入库订单的月结信息 -->
    <update id="clearOrderSettleInfo">
        UPDATE man_order_log_pakin
        SET monthly_settle_id = NULL,
            monthly_settle_no = NULL
        WHERE monthly_settle_id = #{settleId}
    </update>
    <!-- æ¸…除出库订单的月结信息 -->
    <update id="clearOrderSettleInfoPakout">
        UPDATE man_order_log_pakout
        SET monthly_settle_id = NULL,
            monthly_settle_no = NULL
        WHERE monthly_settle_id = #{settleId}
    </update>
</mapper>
src/main/resources/sql/man_order_time_change_log.sql
New file
@@ -0,0 +1,29 @@
-- ä¸šåŠ¡æ—¶é—´å˜æ›´è®°å½•è¡¨
CREATE TABLE [man_order_time_change_log] (
  [id] bigint NOT NULL IDENTITY(1,1),
  [order_id] bigint NOT NULL,
  [order_no] varchar(255) NOT NULL,
  [order_type] int NOT NULL,
  [old_order_time] varchar(255) NOT NULL,
  [new_order_time] varchar(255) NOT NULL,
  [memo] varchar(500) DEFAULT NULL,
  [create_by] bigint DEFAULT NULL,
  [create_time] datetime DEFAULT NULL,
  PRIMARY KEY ([id])
);
CREATE INDEX [idx_order_id] ON [man_order_time_change_log] ([order_id]);
CREATE INDEX [idx_order_no] ON [man_order_time_change_log] ([order_no]);
CREATE INDEX [idx_create_time] ON [man_order_time_change_log] ([create_time]);
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'业务时间变更记录表', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_time_change_log';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'ID', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_time_change_log', @level2type = N'COLUMN', @level2name = N'id';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'订单ID', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_time_change_log', @level2type = N'COLUMN', @level2name = N'order_id';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'单据编号', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_time_change_log', @level2type = N'COLUMN', @level2name = N'order_no';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'订单类型 1:入库 2:出库', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_time_change_log', @level2type = N'COLUMN', @level2name = N'order_type';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'原业务时间', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_time_change_log', @level2type = N'COLUMN', @level2name = N'old_order_time';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'新业务时间', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_time_change_log', @level2type = N'COLUMN', @level2name = N'new_order_time';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'备注', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_time_change_log', @level2type = N'COLUMN', @level2name = N'memo';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'创建人', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_time_change_log', @level2type = N'COLUMN', @level2name = N'create_by';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'创建时间', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_time_change_log', @level2type = N'COLUMN', @level2name = N'create_time';
src/main/resources/sql/monthly_settle.sql
New file
@@ -0,0 +1,108 @@
CREATE TABLE [man_monthly_settle] (
  [id] bigint NOT NULL IDENTITY(1,1),
  [settle_no] varchar(255) NOT NULL,
  [start_date] datetime NOT NULL,
  [end_date] datetime NOT NULL,
  [status] int NOT NULL DEFAULT 0,
  [total_in_qty] decimal(24,9) DEFAULT 0.00,
  [total_out_qty] decimal(24,9) DEFAULT 0.00,
  [total_materials] int DEFAULT 0,
  [memo] varchar(255) DEFAULT NULL,
  [create_by] bigint DEFAULT NULL,
  [create_time] datetime DEFAULT NULL,
  [update_by] bigint DEFAULT NULL,
  [update_time] datetime DEFAULT NULL,
  [is_deleted] int NOT NULL DEFAULT 0,
  PRIMARY KEY ([id]),
  CONSTRAINT [uk_settle_no] UNIQUE ([settle_no])
);
CREATE INDEX [idx_start_date] ON [man_monthly_settle] ([start_date]);
CREATE INDEX [idx_end_date] ON [man_monthly_settle] ([end_date]);
CREATE INDEX [idx_status] ON [man_monthly_settle] ([status]);
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结主表', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'ID', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'id';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结编号', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'settle_no';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'起始日期', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'start_date';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'结束日期', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'end_date';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'状态 0:待月结 1:已月结', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'status';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'总入库数量', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'total_in_qty';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'总出库数量', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'total_out_qty';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'物料种类数', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'total_materials';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'备注', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'memo';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'创建人员', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'create_by';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'创建时间', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'create_time';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'修改人员', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'update_by';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'修改时间', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'update_time';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'删除标记 0:未删除 1:已删除', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle', @level2type = N'COLUMN', @level2name = N'is_deleted';
CREATE TABLE [man_monthly_settle_detail] (
  [id] bigint NOT NULL IDENTITY(1,1),
  [settle_id] bigint NOT NULL,
  [settle_no] varchar(255) NOT NULL,
  [matnr] varchar(255) NOT NULL,
  [batch] varchar(255) DEFAULT NULL,
  [maktx] varchar(255) DEFAULT NULL,
  [brand] varchar(255) DEFAULT NULL,
  [beginning_qty] decimal(24,9) NOT NULL,
  [in_qty] decimal(24,9) NOT NULL,
  [out_qty] decimal(24,9) NOT NULL,
  [ending_qty] decimal(24,9) NOT NULL,
  [stock_qty] decimal(24,9) NOT NULL,
  [diff_qty] decimal(24,9) NOT NULL,
  [create_time] datetime DEFAULT NULL,
  [is_deleted] int NOT NULL DEFAULT 0,
  PRIMARY KEY ([id])
);
CREATE INDEX [idx_settle_id] ON [man_monthly_settle_detail] ([settle_id]);
CREATE INDEX [idx_settle_no] ON [man_monthly_settle_detail] ([settle_no]);
CREATE INDEX [idx_matnr] ON [man_monthly_settle_detail] ([matnr]);
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结明细表', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'ID', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'id';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结主表ID', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'settle_id';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结编号', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'settle_no';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'物料编码', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'matnr';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'批次(订单明细批次)', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'batch';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'物料名称(月结时从订单明细表获取)', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'maktx';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'品牌(月结时从订单明细表获取)', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'brand';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'期初库存(上期结余)', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'beginning_qty';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'本期入库数量', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'in_qty';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'本期出库数量', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'out_qty';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'期末库存(期初+入库-出库)', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'ending_qty';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'当前实际库存数量', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'stock_qty';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'差异数量(期末库存-期初库存)', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'diff_qty';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'创建时间', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'create_time';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'删除标记 0:未删除 1:已删除', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_monthly_settle_detail', @level2type = N'COLUMN', @level2name = N'is_deleted';
ALTER TABLE [man_order_log_pakin] ADD [monthly_settle_id] bigint DEFAULT NULL;
ALTER TABLE [man_order_log_pakin] ADD [monthly_settle_no] varchar(255) DEFAULT NULL;
CREATE INDEX [idx_monthly_settle_id] ON [man_order_log_pakin] ([monthly_settle_id]);
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结ID', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_log_pakin', @level2type = N'COLUMN', @level2name = N'monthly_settle_id';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结编号', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_log_pakin', @level2type = N'COLUMN', @level2name = N'monthly_settle_no';
ALTER TABLE [man_order_log_pakout] ADD [monthly_settle_id] bigint DEFAULT NULL;
ALTER TABLE [man_order_log_pakout] ADD [monthly_settle_no] varchar(255) DEFAULT NULL;
CREATE INDEX [idx_monthly_settle_id] ON [man_order_log_pakout] ([monthly_settle_id]);
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结ID', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_log_pakout', @level2type = N'COLUMN', @level2name = N'monthly_settle_id';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结编号', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_log_pakout', @level2type = N'COLUMN', @level2name = N'monthly_settle_no';
-- ä¸º man_order_pakin è¡¨æ·»åŠ æœˆç»“å‚æ•°å­—æ®µ
ALTER TABLE [man_order_pakin] ADD [monthly_settle_id] bigint DEFAULT NULL;
ALTER TABLE [man_order_pakin] ADD [monthly_settle_no] varchar(255) DEFAULT NULL;
CREATE INDEX [idx_monthly_settle_id] ON [man_order_pakin] ([monthly_settle_id]);
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结ID', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_pakin', @level2type = N'COLUMN', @level2name = N'monthly_settle_id';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结编号', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_pakin', @level2type = N'COLUMN', @level2name = N'monthly_settle_no';
-- ä¸º man_order_pakout è¡¨æ·»åŠ æœˆç»“å‚æ•°å­—æ®µ
ALTER TABLE [man_order_pakout] ADD [monthly_settle_id] bigint DEFAULT NULL;
ALTER TABLE [man_order_pakout] ADD [monthly_settle_no] varchar(255) DEFAULT NULL;
CREATE INDEX [idx_monthly_settle_id] ON [man_order_pakout] ([monthly_settle_id]);
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结ID', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_pakout', @level2type = N'COLUMN', @level2name = N'monthly_settle_id';
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'月结编号', @level0type = N'SCHEMA', @level0name = N'dbo', @level1type = N'TABLE', @level1name = N'man_order_pakout', @level2type = N'COLUMN', @level2name = N'monthly_settle_no';
src/main/resources/sql/³öÈë¿âÀúÊ·±í´´½¨.sql
New file
@@ -0,0 +1,1385 @@
CREATE TABLE [dbo].[man_order_log_pakout] (
[id] bigint  NOT NULL,
[uuid] varchar(255) COLLATE Chinese_PRC_CI_AS  NOT NULL,
[order_no] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[order_time] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[doc_type] bigint  NULL,
[item_id] bigint  NULL,
[item_name] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[allot_item_id] bigint  NULL,
[def_number] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[number] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[cstmr] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[cstmr_name] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[tel] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[oper_memb] varchar(50) COLLATE Chinese_PRC_CI_AS  NULL,
[total_fee] decimal(24,9)  NULL,
[discount] decimal(24,9)  NULL,
[discount_fee] decimal(24,9)  NULL,
[other_fee] decimal(24,9)  NULL,
[act_fee] decimal(24,9)  NULL,
[pay_type] int  NULL,
[salesman] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[account_day] int  NULL,
[post_fee_type] int  NULL,
[post_fee] decimal(24,9)  NULL,
[pay_time] datetime  NULL,
[send_time] datetime  NULL,
[ship_name] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[ship_code] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[settle] bigint  NULL,
[status] int  NULL,
[create_by] bigint  NULL,
[create_time] datetime  NULL,
[update_by] bigint  NULL,
[update_time] datetime  NULL,
[memo] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[move_status] int  NULL,
[pakin_pakout_status] int DEFAULT ((2)) NULL,
[monthly_settle_id] bigint DEFAULT NULL NULL,
[monthly_settle_no] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT NULL NULL
)
ON [PRIMARY]
GO
ALTER TABLE [dbo].[man_order_log_pakout] SET (LOCK_ESCALATION = TABLE)
GO
CREATE NONCLUSTERED INDEX [idx_monthly_settle_id]
ON [dbo].[man_order_log_pakout] (
[monthly_settle_id] ASC
)
GO
EXEC sp_addextendedproperty
'MS_Description', N'ID',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'编号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'uuid'
GO
EXEC sp_addextendedproperty
'MS_Description', N'订单编号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'order_no'
GO
EXEC sp_addextendedproperty
'MS_Description', N'单据日期',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'order_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'单据类型[man_doc_type]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'doc_type'
GO
EXEC sp_addextendedproperty
'MS_Description', N'项目编号[man_item]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'item_id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'调拨项目编号[man_item]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'allot_item_id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'初始票据号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'def_number'
GO
EXEC sp_addextendedproperty
'MS_Description', N'票据号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'number'
GO
EXEC sp_addextendedproperty
'MS_Description', N'客户编号[man_cstmr]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'cstmr'
GO
EXEC sp_addextendedproperty
'MS_Description', N'客户',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'cstmr_name'
GO
EXEC sp_addextendedproperty
'MS_Description', N'联系方式',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'tel'
GO
EXEC sp_addextendedproperty
'MS_Description', N'操作人员',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'oper_memb'
GO
EXEC sp_addextendedproperty
'MS_Description', N'合计金额',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'total_fee'
GO
EXEC sp_addextendedproperty
'MS_Description', N'优惠率',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'discount'
GO
EXEC sp_addextendedproperty
'MS_Description', N'优惠金额',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'discount_fee'
GO
EXEC sp_addextendedproperty
'MS_Description', N'销售或采购费用合计',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'other_fee'
GO
EXEC sp_addextendedproperty
'MS_Description', N'实付金额',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'act_fee'
GO
EXEC sp_addextendedproperty
'MS_Description', N'付款类型{1:现金,2:è®°è´¦}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'pay_type'
GO
EXEC sp_addextendedproperty
'MS_Description', N'业务员',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'salesman'
GO
EXEC sp_addextendedproperty
'MS_Description', N'结算天数',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'account_day'
GO
EXEC sp_addextendedproperty
'MS_Description', N'邮费支付类型{1:在线支付,2:货到付款}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'post_fee_type'
GO
EXEC sp_addextendedproperty
'MS_Description', N'邮费',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'post_fee'
GO
EXEC sp_addextendedproperty
'MS_Description', N'付款时间',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'pay_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'发货时间',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'send_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'物流名称',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'ship_name'
GO
EXEC sp_addextendedproperty
'MS_Description', N'物流单号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'ship_code'
GO
EXEC sp_addextendedproperty
'MS_Description', N'订单状态[man_order_settle]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'settle'
GO
EXEC sp_addextendedproperty
'MS_Description', N'状态{1:正常,0:禁用}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'status'
GO
EXEC sp_addextendedproperty
'MS_Description', N'添加人员[sys_user]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'create_by'
GO
EXEC sp_addextendedproperty
'MS_Description', N'添加时间',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'create_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'修改人员[sys_user]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'update_by'
GO
EXEC sp_addextendedproperty
'MS_Description', N'修改时间',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'update_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'备注',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'memo'
GO
EXEC sp_addextendedproperty
'MS_Description', N'入出库类型(0:未知,1:入库,2:出库)',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'pakin_pakout_status'
GO
EXEC sp_addextendedproperty
'MS_Description', N'月结ID',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'monthly_settle_id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'月结编号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakout',
'COLUMN', N'monthly_settle_no'
CREATE TABLE [dbo].[man_order_log_pakin] (
[id] bigint  NOT NULL,
[uuid] varchar(255) COLLATE Chinese_PRC_CI_AS  NOT NULL,
[order_no] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[order_time] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[doc_type] bigint  NULL,
[item_id] bigint  NULL,
[item_name] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[allot_item_id] bigint  NULL,
[def_number] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[number] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[cstmr] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[cstmr_name] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[tel] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[oper_memb] varchar(50) COLLATE Chinese_PRC_CI_AS  NULL,
[total_fee] decimal(24,9)  NULL,
[discount] decimal(24,9)  NULL,
[discount_fee] decimal(24,9)  NULL,
[other_fee] decimal(24,9)  NULL,
[act_fee] decimal(24,9)  NULL,
[pay_type] int  NULL,
[salesman] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[account_day] int  NULL,
[post_fee_type] int  NULL,
[post_fee] decimal(24,9)  NULL,
[pay_time] datetime  NULL,
[send_time] datetime  NULL,
[ship_name] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[ship_code] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[settle] bigint  NULL,
[status] int  NULL,
[create_by] bigint  NULL,
[create_time] datetime  NULL,
[update_by] bigint  NULL,
[update_time] datetime  NULL,
[memo] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[move_status] int  NULL,
[pakin_pakout_status] int DEFAULT ((1)) NULL,
[monthly_settle_id] bigint DEFAULT NULL NULL,
[monthly_settle_no] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT NULL NULL
)
ON [PRIMARY]
GO
ALTER TABLE [dbo].[man_order_log_pakin] SET (LOCK_ESCALATION = TABLE)
GO
CREATE NONCLUSTERED INDEX [idx_monthly_settle_id]
ON [dbo].[man_order_log_pakin] (
[monthly_settle_id] ASC
)
GO
EXEC sp_addextendedproperty
'MS_Description', N'ID',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'编号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'uuid'
GO
EXEC sp_addextendedproperty
'MS_Description', N'订单编号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'order_no'
GO
EXEC sp_addextendedproperty
'MS_Description', N'单据日期',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'order_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'单据类型[man_doc_type]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'doc_type'
GO
EXEC sp_addextendedproperty
'MS_Description', N'项目编号[man_item]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'item_id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'调拨项目编号[man_item]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'allot_item_id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'初始票据号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'def_number'
GO
EXEC sp_addextendedproperty
'MS_Description', N'票据号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'number'
GO
EXEC sp_addextendedproperty
'MS_Description', N'客户编号[man_cstmr]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'cstmr'
GO
EXEC sp_addextendedproperty
'MS_Description', N'客户',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'cstmr_name'
GO
EXEC sp_addextendedproperty
'MS_Description', N'联系方式',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'tel'
GO
EXEC sp_addextendedproperty
'MS_Description', N'操作人员',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'oper_memb'
GO
EXEC sp_addextendedproperty
'MS_Description', N'合计金额',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'total_fee'
GO
EXEC sp_addextendedproperty
'MS_Description', N'优惠率',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'discount'
GO
EXEC sp_addextendedproperty
'MS_Description', N'优惠金额',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'discount_fee'
GO
EXEC sp_addextendedproperty
'MS_Description', N'销售或采购费用合计',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'other_fee'
GO
EXEC sp_addextendedproperty
'MS_Description', N'实付金额',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'act_fee'
GO
EXEC sp_addextendedproperty
'MS_Description', N'付款类型{1:现金,2:è®°è´¦}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'pay_type'
GO
EXEC sp_addextendedproperty
'MS_Description', N'业务员',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'salesman'
GO
EXEC sp_addextendedproperty
'MS_Description', N'结算天数',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'account_day'
GO
EXEC sp_addextendedproperty
'MS_Description', N'邮费支付类型{1:在线支付,2:货到付款}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'post_fee_type'
GO
EXEC sp_addextendedproperty
'MS_Description', N'邮费',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'post_fee'
GO
EXEC sp_addextendedproperty
'MS_Description', N'付款时间',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'pay_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'发货时间',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'send_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'物流名称',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'ship_name'
GO
EXEC sp_addextendedproperty
'MS_Description', N'物流单号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'ship_code'
GO
EXEC sp_addextendedproperty
'MS_Description', N'订单状态[man_order_settle]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'settle'
GO
EXEC sp_addextendedproperty
'MS_Description', N'状态{1:正常,0:禁用}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'status'
GO
EXEC sp_addextendedproperty
'MS_Description', N'添加人员[sys_user]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'create_by'
GO
EXEC sp_addextendedproperty
'MS_Description', N'添加时间',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'create_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'修改人员[sys_user]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'update_by'
GO
EXEC sp_addextendedproperty
'MS_Description', N'修改时间',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'update_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'备注',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'memo'
GO
EXEC sp_addextendedproperty
'MS_Description', N'入出库类型(0:未知,1:入库,2:出库)',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'pakin_pakout_status'
GO
EXEC sp_addextendedproperty
'MS_Description', N'月结ID',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'monthly_settle_id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'月结编号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_log_pakin',
'COLUMN', N'monthly_settle_no'
CREATE TABLE [dbo].[man_order_detl_log_pakin] (
[id] bigint  NOT NULL,
[order_id] bigint  NOT NULL,
[order_no] varchar(255) COLLATE Chinese_PRC_CI_AS  NOT NULL,
[anfme] decimal(24,9) DEFAULT ((1)) NOT NULL,
[qty] decimal(24,9) DEFAULT ((0)) NOT NULL,
[matnr] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[maktx] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[batch] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[specs] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[model] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[color] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[brand] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[unit] varchar(50) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[price] decimal(24,9) DEFAULT ((1)) NOT NULL,
[sku] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[units] decimal(24,9) DEFAULT ((1)) NOT NULL,
[barcode] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[origin] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[manu] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[manu_date] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[item_num] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[safe_qty] decimal(24,9) DEFAULT ((999999)) NOT NULL,
[weight] decimal(24,9) DEFAULT ((9999)) NOT NULL,
[man_length] decimal(24,9) DEFAULT ((9999)) NOT NULL,
[volume] decimal(24,9) DEFAULT ((9999)) NOT NULL,
[three_code] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[supp] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[supp_code] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[be_batch] int DEFAULT ((0)) NOT NULL,
[dead_time] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[dead_warn] int DEFAULT ((9999)) NOT NULL,
[source] int DEFAULT ((0)) NOT NULL,
[inspect] int DEFAULT ((0)) NOT NULL,
[danger] int DEFAULT ((0)) NOT NULL,
[status] int DEFAULT ((1)) NOT NULL,
[create_by] bigint  NULL,
[create_time] datetime  NULL,
[update_by] bigint  NULL,
[update_time] datetime  NULL,
[memo] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NULL,
[work_qty] decimal(24,9) DEFAULT ((0)) NULL,
[qr_code] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[start_date] datetime  NULL,
[end_date] datetime  NULL,
[pakin_pakout_status] int DEFAULT ((1)) NOT NULL,
[line_number] bigint DEFAULT ((1)) NOT NULL,
[standby1] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NULL,
[standby2] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NULL,
[standby3] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NULL,
[box_type1] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT ('1') NULL,
[box_type2] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT ('1') NULL,
[box_type3] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT ('1') NULL
)
ON [PRIMARY]
GO
ALTER TABLE [dbo].[man_order_detl_log_pakin] SET (LOCK_ESCALATION = TABLE)
GO
EXEC sp_addextendedproperty
'MS_Description', N'ID',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'订单内码[man_order]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'order_id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'单据编号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'order_no'
GO
EXEC sp_addextendedproperty
'MS_Description', N'数量',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'anfme'
GO
EXEC sp_addextendedproperty
'MS_Description', N'商品编码',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'matnr'
GO
EXEC sp_addextendedproperty
'MS_Description', N'商品名称',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'maktx'
GO
EXEC sp_addextendedproperty
'MS_Description', N'批号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'batch'
GO
EXEC sp_addextendedproperty
'MS_Description', N'规格',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'specs'
GO
EXEC sp_addextendedproperty
'MS_Description', N'型号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'model'
GO
EXEC sp_addextendedproperty
'MS_Description', N'颜色',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'color'
GO
EXEC sp_addextendedproperty
'MS_Description', N'品牌',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'brand'
GO
EXEC sp_addextendedproperty
'MS_Description', N'单位',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'unit'
GO
EXEC sp_addextendedproperty
'MS_Description', N'单价',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'price'
GO
EXEC sp_addextendedproperty
'MS_Description', N'sku',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'sku'
GO
EXEC sp_addextendedproperty
'MS_Description', N'单位量',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'units'
GO
EXEC sp_addextendedproperty
'MS_Description', N'条码',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'barcode'
GO
EXEC sp_addextendedproperty
'MS_Description', N'产地',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'origin'
GO
EXEC sp_addextendedproperty
'MS_Description', N'厂家',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'manu'
GO
EXEC sp_addextendedproperty
'MS_Description', N'生产日期',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'manu_date'
GO
EXEC sp_addextendedproperty
'MS_Description', N'品项数',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'item_num'
GO
EXEC sp_addextendedproperty
'MS_Description', N'安全库存量',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'safe_qty'
GO
EXEC sp_addextendedproperty
'MS_Description', N'重量',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'weight'
GO
EXEC sp_addextendedproperty
'MS_Description', N'长度',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'man_length'
GO
EXEC sp_addextendedproperty
'MS_Description', N'体积',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'volume'
GO
EXEC sp_addextendedproperty
'MS_Description', N'三方编码',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'three_code'
GO
EXEC sp_addextendedproperty
'MS_Description', N'供应商',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'supp'
GO
EXEC sp_addextendedproperty
'MS_Description', N'供应商编码',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'supp_code'
GO
EXEC sp_addextendedproperty
'MS_Description', N'是否批次{1:是,0:否}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'be_batch'
GO
EXEC sp_addextendedproperty
'MS_Description', N'保质期',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'dead_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'预警天数',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'dead_warn'
GO
EXEC sp_addextendedproperty
'MS_Description', N'制购{1:制造,2:采购,3:外协}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'source'
GO
EXEC sp_addextendedproperty
'MS_Description', N'要求检验{1:是,0:否}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'inspect'
GO
EXEC sp_addextendedproperty
'MS_Description', N'危险品{1:是,0:否}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'danger'
GO
EXEC sp_addextendedproperty
'MS_Description', N'状态{1:正常,0:禁用}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'status'
GO
EXEC sp_addextendedproperty
'MS_Description', N'添加人员[sys_user]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'create_by'
GO
EXEC sp_addextendedproperty
'MS_Description', N'添加时间',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'create_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'修改人员[sys_user]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'update_by'
GO
EXEC sp_addextendedproperty
'MS_Description', N'修改时间',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'update_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'备注',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'memo'
GO
EXEC sp_addextendedproperty
'MS_Description', N'条形码',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'qr_code'
GO
EXEC sp_addextendedproperty
'MS_Description', N'收卷开始日期',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'start_date'
GO
EXEC sp_addextendedproperty
'MS_Description', N'收卷结束日期',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'end_date'
GO
EXEC sp_addextendedproperty
'MS_Description', N'入出库类型(0:未知,1:入库,2:出库)',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'pakin_pakout_status'
GO
EXEC sp_addextendedproperty
'MS_Description', N'行号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakin',
'COLUMN', N'line_number'
CREATE TABLE [dbo].[man_order_detl_log_pakout] (
[id] bigint  NOT NULL,
[order_id] bigint  NOT NULL,
[order_no] varchar(255) COLLATE Chinese_PRC_CI_AS  NOT NULL,
[anfme] decimal(24,9) DEFAULT ((1)) NOT NULL,
[qty] decimal(24,9) DEFAULT ((0)) NOT NULL,
[matnr] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[maktx] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[batch] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[specs] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[model] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[color] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[brand] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[unit] varchar(50) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[price] decimal(24,9) DEFAULT ((1)) NOT NULL,
[sku] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[units] decimal(24,9) DEFAULT ((1)) NOT NULL,
[barcode] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[origin] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[manu] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[manu_date] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[item_num] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[safe_qty] decimal(24,9) DEFAULT ((999999)) NOT NULL,
[weight] decimal(24,9) DEFAULT ((9999)) NOT NULL,
[man_length] decimal(24,9) DEFAULT ((9999)) NOT NULL,
[volume] decimal(24,9) DEFAULT ((9999)) NOT NULL,
[three_code] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[supp] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[supp_code] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NOT NULL,
[be_batch] int DEFAULT ((0)) NOT NULL,
[dead_time] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[dead_warn] int DEFAULT ((9999)) NOT NULL,
[source] int DEFAULT ((0)) NOT NULL,
[inspect] int DEFAULT ((0)) NOT NULL,
[danger] int DEFAULT ((0)) NOT NULL,
[status] int DEFAULT ((1)) NOT NULL,
[create_by] bigint  NULL,
[create_time] datetime  NULL,
[update_by] bigint  NULL,
[update_time] datetime  NULL,
[memo] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NULL,
[work_qty] decimal(24,9) DEFAULT ((0)) NULL,
[qr_code] varchar(255) COLLATE Chinese_PRC_CI_AS  NULL,
[start_date] datetime  NULL,
[end_date] datetime  NULL,
[pakin_pakout_status] int DEFAULT ((2)) NOT NULL,
[line_number] bigint DEFAULT ((1)) NOT NULL,
[standby1] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NULL,
[standby2] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NULL,
[standby3] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT '' NULL,
[box_type1] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT ('1') NULL,
[box_type2] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT ('1') NULL,
[box_type3] varchar(255) COLLATE Chinese_PRC_CI_AS DEFAULT ('1') NULL
)
ON [PRIMARY]
GO
ALTER TABLE [dbo].[man_order_detl_log_pakout] SET (LOCK_ESCALATION = TABLE)
GO
EXEC sp_addextendedproperty
'MS_Description', N'ID',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'订单内码[man_order]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'order_id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'单据编号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'order_no'
GO
EXEC sp_addextendedproperty
'MS_Description', N'数量',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'anfme'
GO
EXEC sp_addextendedproperty
'MS_Description', N'商品编码',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'matnr'
GO
EXEC sp_addextendedproperty
'MS_Description', N'商品名称',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'maktx'
GO
EXEC sp_addextendedproperty
'MS_Description', N'批号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'batch'
GO
EXEC sp_addextendedproperty
'MS_Description', N'规格',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'specs'
GO
EXEC sp_addextendedproperty
'MS_Description', N'型号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'model'
GO
EXEC sp_addextendedproperty
'MS_Description', N'颜色',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'color'
GO
EXEC sp_addextendedproperty
'MS_Description', N'品牌',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'brand'
GO
EXEC sp_addextendedproperty
'MS_Description', N'单位',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'unit'
GO
EXEC sp_addextendedproperty
'MS_Description', N'单价',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'price'
GO
EXEC sp_addextendedproperty
'MS_Description', N'sku',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'sku'
GO
EXEC sp_addextendedproperty
'MS_Description', N'单位量',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'units'
GO
EXEC sp_addextendedproperty
'MS_Description', N'条码',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'barcode'
GO
EXEC sp_addextendedproperty
'MS_Description', N'产地',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'origin'
GO
EXEC sp_addextendedproperty
'MS_Description', N'厂家',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'manu'
GO
EXEC sp_addextendedproperty
'MS_Description', N'生产日期',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'manu_date'
GO
EXEC sp_addextendedproperty
'MS_Description', N'品项数',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'item_num'
GO
EXEC sp_addextendedproperty
'MS_Description', N'安全库存量',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'safe_qty'
GO
EXEC sp_addextendedproperty
'MS_Description', N'重量',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'weight'
GO
EXEC sp_addextendedproperty
'MS_Description', N'长度',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'man_length'
GO
EXEC sp_addextendedproperty
'MS_Description', N'体积',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'volume'
GO
EXEC sp_addextendedproperty
'MS_Description', N'三方编码',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'three_code'
GO
EXEC sp_addextendedproperty
'MS_Description', N'供应商',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'supp'
GO
EXEC sp_addextendedproperty
'MS_Description', N'供应商编码',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'supp_code'
GO
EXEC sp_addextendedproperty
'MS_Description', N'是否批次{1:是,0:否}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'be_batch'
GO
EXEC sp_addextendedproperty
'MS_Description', N'保质期',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'dead_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'预警天数',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'dead_warn'
GO
EXEC sp_addextendedproperty
'MS_Description', N'制购{1:制造,2:采购,3:外协}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'source'
GO
EXEC sp_addextendedproperty
'MS_Description', N'要求检验{1:是,0:否}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'inspect'
GO
EXEC sp_addextendedproperty
'MS_Description', N'危险品{1:是,0:否}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'danger'
GO
EXEC sp_addextendedproperty
'MS_Description', N'状态{1:正常,0:禁用}',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'status'
GO
EXEC sp_addextendedproperty
'MS_Description', N'添加人员[sys_user]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'create_by'
GO
EXEC sp_addextendedproperty
'MS_Description', N'添加时间',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'create_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'修改人员[sys_user]',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'update_by'
GO
EXEC sp_addextendedproperty
'MS_Description', N'修改时间',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'update_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'备注',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'memo'
GO
EXEC sp_addextendedproperty
'MS_Description', N'条形码',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'qr_code'
GO
EXEC sp_addextendedproperty
'MS_Description', N'收卷开始日期',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'start_date'
GO
EXEC sp_addextendedproperty
'MS_Description', N'收卷结束日期',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'end_date'
GO
EXEC sp_addextendedproperty
'MS_Description', N'入出库类型(0:未知,1:入库,2:出库)',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'pakin_pakout_status'
GO
EXEC sp_addextendedproperty
'MS_Description', N'行号',
'SCHEMA', N'dbo',
'TABLE', N'man_order_detl_log_pakout',
'COLUMN', N'line_number'
src/main/webapp/static/js/monthlySettle/monthlySettle.js
New file
@@ -0,0 +1,620 @@
var pageCurr;
layui.config({
    base: baseUrl + "/static/layui/lay/modules/"
}).use(['layer', 'form', 'table', 'util', 'admin', 'laydate', 'laytpl'], function () {
    var $ = layui.jquery;
    var layer = layui.layer;
    var form = layui.form;
    var table = layui.table;
    var util = layui.util;
    var admin = layui.admin;
    var layDate = layui.laydate;
    var laytpl = layui.laytpl;
    // æ¸²æŸ“表格
    tableIns = table.render({
        elem: '#monthlySettle',
        url: baseUrl + '/monthlySettle/list/auth',
        headers: {token: localStorage.getItem('token')},
        method: 'POST',
        page: true,
        cellMinWidth: 100,
        where: {},
        cols: [[
            {type: 'numbers'},
            {field: 'settleNo', title: '月结编号', width: 180},
            {field: 'startDate$', align: 'center', title: '起始日期', width: 120},
            {field: 'endDate$', align: 'center', title: '结束日期', width: 120},
            {field: 'totalInQty', align: 'center', title: '总入库数量', width: 120},
            {field: 'totalOutQty', align: 'center', title: '总出库数量', width: 120},
            {field: 'totalMaterials', align: 'center', title: '物料种类数', width: 120},
            {field: 'createTime$', title: '创建时间', minWidth: 180, width: 180},
            {align: 'center', title: '操作', toolbar: '#operate', width: 180}
        ]],
        request: {
            pageName: 'curr',
            pageSize: 'limit'
        },
        parseData: function (res) {
            return {
                'code': res.code,
                'msg': res.msg,
                'count': res.data.total,
                'data': res.data.records
            }
        },
        response: {
            statusCode: 200
        },
        done: function (res, curr, count) {
            if (res.code === 403) {
                top.location.href = baseUrl + "/";
            }
            pageCurr = curr;
        }
    });
    // æœç´¢
    form.on('submit(search)', function (data) {
        pageCurr = 1;
        tableReload(false);
    });
    // é‡ç½®
    form.on('submit(reset)', function (data) {
        pageCurr = 1;
        clearFormVal($('#search-box'));
        // æ‰‹åŠ¨æ¸…ç©ºæ—¥æœŸèŒƒå›´é€‰æ‹©å™¨
        $('input[name="date_range"]').val('');
        // æ˜¾å¼æ¸…空表格配置中的 where å‚æ•°
        if (tableIns && tableIns.config) {
            tableIns.config.where = {};
        }
        // ä½¿ç”¨ setTimeout ç¡®ä¿è¡¨å•值被完全清空后再重新加载表格
        setTimeout(function() {
            tableReload(false);
        }, 0);
    });
    // æ—¥æœŸèŒƒå›´é€‰æ‹©å™¨
    layDate.render({
        elem: '.layui-laydate-range',
        type: 'date',
        range: true
    });
    // å‘起月结
    $('#startSettleBtn').click(function () {
        showStartSettleDialog();
    });
    // æ˜¾ç¤ºå‘起月结弹窗
    function showStartSettleDialog() {
        admin.open({
            type: 1,
            title: '发起月结',
            content: $('#startSettleDialog').html(),
            area: '500px',
            success: function (layero, dIndex) {
                var startDateIns = null;
                var endDateIns = null;
                // åˆå§‹åŒ–结束日期选择器(先初始化,后续再设置min)
                // ä½¿ç”¨ setTimeout ç¡®ä¿ DOM å·²å®Œå…¨æ¸²æŸ“
                setTimeout(function() {
                    var $endDate = layero.find('#endDate');
                    if ($endDate.length > 0) {
                        endDateIns = layDate.render({
                            elem: $endDate[0],
                            type: 'date',
                            done: function(value, date, endDate){
                                var startDate = layero.find('#startDate').val();
                                if (startDate && value < startDate) {
                                    layer.msg('结束日期不能早于起始日期', {icon: 2});
                                    layero.find('#endDate').val('');
                                    checkUnfinishedOrders(startDate, '');
                                    return;
                                }
                                checkUnfinishedOrders(startDate, value);
                            }
                        });
                    }
                }, 50);
                // èŽ·å–ä¸‹ä¸€ä¸ªæœˆç»“çš„èµ·å§‹æ—¥æœŸï¼ˆæœ€æ™šæœˆç»“è®°å½•ç»“æŸæ—¥æœŸçš„ä¸‹ä¸€å¤©ï¼‰
                $.ajax({
                    url: baseUrl + '/monthlySettle/nextStartDate/auth',
                    headers: {'token': localStorage.getItem('token')},
                    method: 'POST',
                    success: function (res) {
                        if (res.code === 200) {
                            // æ•°æ®åœ¨ msg å­—段中
                            var nextStartDate = res.msg;
                            // ç¡®ä¿ nextStartDate æ˜¯å­—符串格式
                            if (nextStartDate != null && nextStartDate !== '') {
                                // è½¬æ¢ä¸ºå­—符串,处理可能的数字或其他类型
                                nextStartDate = String(nextStartDate).trim();
                                if (nextStartDate !== '' && nextStartDate !== 'null') {
                                    // ä½¿ç”¨ setTimeout ç¡®ä¿ DOM å·²å®Œå…¨æ¸²æŸ“
                                    setTimeout(function() {
                                        // ä½¿ç”¨ layero.find æŸ¥æ‰¾å¼¹çª—内的元素
                                        var $startDate = layero.find('#startDate');
                                        if ($startDate.length > 0) {
                                            $startDate.val(nextStartDate);
                                            $startDate.attr('readonly', true);
                                            $startDate.css('background-color', '#f5f5f5');
                                            $startDate.css('cursor', 'not-allowed');
                                            console.log('已设置起始日期:', $startDate.val());
                                        } else {
                                            console.error('未找到 #startDate å…ƒç´ ');
                                        }
                                    }, 50);
                                    // èŽ·å–æœ€æ™šç»“æŸæ—¥æœŸç”¨äºŽæç¤º
                                    $.ajax({
                                        url: baseUrl + '/monthlySettle/latestEndDate/auth',
                                        headers: {'token': localStorage.getItem('token')},
                                        method: 'POST',
                                        success: function (latestRes) {
                                            var latestEndDate = (latestRes.code === 200 && latestRes.msg) ? String(latestRes.msg) : '';
                                            var tipMsg = latestEndDate
                                                ? '提示:最晚月结记录结束日期为 ' + latestEndDate + ',本次月结起始日期已自动设置为 ' + nextStartDate + ',不可修改'
                                                : '提示:本次月结起始日期已自动设置为 ' + nextStartDate + ',不可修改';
                                            layero.find('#settleTip').html(tipMsg);
                                        },
                                        error: function() {
                                            layero.find('#settleTip').html('提示:本次月结起始日期已自动设置为 ' + nextStartDate + ',不可修改');
                                        }
                                    });
                                    // é‡æ–°æ¸²æŸ“结束日期选择器,设置最小日期为起始日期
                                    setTimeout(function() {
                                        endDateIns = layDate.render({
                                            elem: layero.find('#endDate')[0],
                                            type: 'date',
                                            min: nextStartDate,
                                            done: function(value, date, endDate){
                                                var startDate = layero.find('#startDate').val();
                                                if (startDate && value < startDate) {
                                                    layer.msg('结束日期不能早于起始日期', {icon: 2});
                                                    layero.find('#endDate').val('');
                                                    checkUnfinishedOrders(startDate, '');
                                                    return;
                                                }
                                                checkUnfinishedOrders(startDate, value);
                                            }
                                        });
                                    }, 100);
                                }
                            } else {
                                // æ²¡æœ‰æœˆç»“记录,允许自由选择起始日期
                                setTimeout(function() {
                                    var $startDate = layero.find('#startDate');
                                    if ($startDate.length > 0) {
                                        startDateIns = layDate.render({
                                            elem: $startDate[0],
                                            type: 'date',
                                            done: function(value, date, endDate){
                                                // å½“起始日期改变时,重新渲染结束日期选择器,设置最小日期
                                                var currentEndDate = layero.find('#endDate').val();
                                                if (currentEndDate && currentEndDate < value) {
                                                    layero.find('#endDate').val('');
                                                    layero.find('#settleTip').html('<span style="color: #ff5722;">警告:结束日期不能早于起始日期,请重新选择结束日期</span>');
                                                }
                                                // é‡æ–°æ¸²æŸ“结束日期选择器
                                                endDateIns = layDate.render({
                                                    elem: layero.find('#endDate')[0],
                                                    type: 'date',
                                                    min: value,
                                                    done: function(endValue, endDate, endEndDate){
                                                        if (value && endValue < value) {
                                                            layer.msg('结束日期不能早于起始日期', {icon: 2});
                                                            layero.find('#endDate').val('');
                                                            checkUnfinishedOrders(value, '');
                                                            return;
                                                        }
                                                        checkUnfinishedOrders(value, endValue);
                                                    }
                                                });
                                                checkUnfinishedOrders(value, layero.find('#endDate').val());
                                            }
                                        });
                                        layero.find('#settleTip').html('提示:首次月结,请选择起始日期');
                                    }
                                }, 50);
                            }
                        } else if (res.code === 403) {
                            top.location.href = baseUrl + "/";
                        }
                    },
                    error: function() {
                        // å¦‚果获取失败,允许自由选择起始日期
                        setTimeout(function() {
                            var $startDate = layero.find('#startDate');
                            if ($startDate.length > 0) {
                                startDateIns = layDate.render({
                                    elem: $startDate[0],
                                    type: 'date',
                                    done: function(value, date, endDate){
                                        var currentEndDate = layero.find('#endDate').val();
                                        if (currentEndDate && currentEndDate < value) {
                                            layero.find('#endDate').val('');
                                            layero.find('#settleTip').html('<span style="color: #ff5722;">警告:结束日期不能早于起始日期,请重新选择结束日期</span>');
                                        }
                                        endDateIns = layDate.render({
                                            elem: layero.find('#endDate')[0],
                                            type: 'date',
                                            min: value,
                                            done: function(endValue, endDate, endEndDate){
                                                if (value && endValue < value) {
                                                    layer.msg('结束日期不能早于起始日期', {icon: 2});
                                                    layero.find('#endDate').val('');
                                                    checkUnfinishedOrders(value, '');
                                                    return;
                                                }
                                                checkUnfinishedOrders(value, endValue);
                                            }
                                        });
                                        checkUnfinishedOrders(value, layero.find('#endDate').val());
                                    }
                                });
                                layero.find('#settleTip').html('提示:请选择起始日期');
                            }
                        }, 50);
                    }
                });
                // è¡¨å•提交事件
                form.on('submit(startSettleSubmit)', function (data) {
                    var startDate = layero.find('#startDate').val();
                    var endDate = layero.find('#endDate').val();
                    if (!startDate || !endDate) {
                        layer.msg('请选择起始日期和结束日期', {icon: 2});
                        return false;
                    }
                    if (startDate > endDate) {
                        layer.msg('结束日期不能早于起始日期,请重新选择', {icon: 2});
                        return false;
                    }
                    // å°†ç»“束日期设置为当天的 23:59:59
                    var endDateTime = endDate + ' 23:59:59';
                    layer.load(2);
                    $.ajax({
                        url: baseUrl + '/monthlySettle/start/auth',
                        headers: {'token': localStorage.getItem('token')},
                        data: {
                            startDate: startDate,
                            endDate: endDateTime
                        },
                        method: 'POST',
                        success: function (res) {
                            layer.closeAll('loading');
                            if (res.code === 200) {
                                layer.close(dIndex);
                                tableIns.reload({page: {curr: 1}});
                                layer.msg(res.msg || '月结成功', {icon: 1});
                            } else if (res.code === 403) {
                                top.location.href = baseUrl + "/";
                            } else {
                                layer.msg(res.msg || '月结失败', {icon: 2});
                            }
                        },
                        error: function() {
                            layer.closeAll('loading');
                            layer.msg('月结请求失败', {icon: 2});
                        }
                    });
                    return false;
                });
            }
        });
    }
    // æ£€æŸ¥æœªå®Œæˆçš„订单
    function checkUnfinishedOrders(startDate, endDate) {
        if (!startDate && !endDate) {
            $('#settleTip').html('<span style="color: #999;">请选择起始日期和结束日期</span>');
            return;
        }
        if (!startDate) {
            $('#settleTip').html('<span style="color: #999;">请选择起始日期</span>');
            return;
        }
        if (!endDate) {
            $('#settleTip').html('<span style="color: #999;">请选择结束日期</span>');
            return;
        }
        // éªŒè¯æ—¥æœŸèŒƒå›´
        if (startDate > endDate) {
            $('#settleTip').html('<span style="color: #ff5722;">警告:结束日期不能早于起始日期,请重新选择</span>');
            return;
        }
        $.ajax({
            url: baseUrl + '/monthlySettle/checkUnfinished/auth',
            headers: {'token': localStorage.getItem('token')},
            data: {
                startDate: startDate,
                endDate: endDate
            },
            method: 'POST',
            success: function (res) {
                if (res.code === 200) {
                    $('#settleTip').html('<span style="color: #5FB878;">✓ æ—¥æœŸèŒƒå›´æœ‰æ•ˆï¼Œå¯ä»¥æ­£å¸¸è¿›è¡Œæœˆç»“</span>');
                } else {
                    $('#settleTip').html('<span style="color: #ff5722;">警告:' + (res.msg || '月结时间范围内存在未完成的订单,无法进行月结') + '</span>');
                }
            },
            error: function() {
                $('#settleTip').html('<span style="color: #ff5722;">检查失败,请重试</span>');
            }
        });
    }
    // å·¥å…·æ¡ç‚¹å‡»äº‹ä»¶
    table.on('tool(monthlySettle)', function (obj) {
        var data = obj.data;
        var layEvent = obj.event;
        if (layEvent === 'detail') {
            showDetailDialog(data);
        } else if (layEvent === 'delete') {
            deleteSettle(data);
        }
    });
    // æ˜¾ç¤ºæ˜Žç»†å¼¹çª—
    function showDetailDialog(data) {
        layer.load(2);
        $.ajax({
            url: baseUrl + '/monthlySettle/statistics/' + data.id + '/auth',
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                layer.closeAll('loading');
                if (res.code === 200) {
                    var settle = res.data.settle;
                    var details = res.data.details;
                    // å…ˆæ¸²æŸ“模板
                    var template = $('#detailDialog').html();
                    var html = laytpl(template).render(settle);
                    admin.open({
                        type: 1,
                        title: '月结明细 - ' + settle.settleNo,
                        content: html,
                        area: ['90%', '80%'],
                        success: function (layero, dIndex) {
                            // æ¸²æŸ“明细表格(对账单格式)
                            table.render({
                                elem: '#detailTable',
                                data: details,
                                page: true,
                                cellMinWidth: 100,
                                width: '100%',
                                cols: [[
                                    {type: 'numbers', title: '序号', width: 60, align: 'center'},
                                    {field: 'matnr', title: '物料编码', width: 150},
                                    {field: 'maktx', title: '物料名称', width: 200},
                                    {field: 'batch', title: '批次', width: 120},
                                    {field: 'brand', title: '品牌', width: 120},
                                    {
                                        field: 'beginningQty',
                                        align: 'right',
                                        title: '期初库存',
                                        width: 120,
                                        templet: function (d) {
                                            var qty = parseFloat(d.beginningQty || 0);
                                            return qty.toFixed(2);
                                        }
                                    },
                                    {
                                        field: 'endingQty',
                                        align: 'right',
                                        title: '期末库存',
                                        width: 120,
                                        templet: function (d) {
                                            var qty = parseFloat(d.endingQty || 0);
                                            return qty.toFixed(2);
                                        }
                                    },
                                    {
                                        field: 'diffQty',
                                        align: 'right',
                                        title: '差异数量',
                                        width: 120,
                                        templet: function (d) {
                                            var diff = parseFloat(d.diffQty || 0);
                                            if (diff > 0) {
                                                return '<span style="color: #5FB878;">+' + diff.toFixed(2) + '</span>';
                                            } else if (diff < 0) {
                                                return '<span style="color: #ff5722;">' + diff.toFixed(2) + '</span>';
                                            } else {
                                                return diff.toFixed(2);
                                            }
                                        }
                                    },
                                    {
                                        field: 'inQty',
                                        align: 'right',
                                        title: '本期入库',
                                        width: 120,
                                        templet: function (d) {
                                            var qty = parseFloat(d.inQty || 0);
                                            return qty.toFixed(2);
                                        }
                                    },
                                    {
                                        field: 'outQty',
                                        align: 'right',
                                        title: '本期出库',
                                        width: 120,
                                        templet: function (d) {
                                            var qty = parseFloat(d.outQty || 0);
                                            return qty.toFixed(2);
                                        }
                                    }
                                ]]
                            });
                        }
                    });
                } else if (res.code === 403) {
                    top.location.href = baseUrl + "/";
                } else {
                    layer.msg(res.msg || '获取明细失败', {icon: 2});
                }
            }
        });
    }
    // åˆ é™¤æœˆç»“记录
    function deleteSettle(data) {
        layer.confirm('确认要删除月结记录 "' + data.settleNo + '" å—?删除后将清除关联的出入库订单月结信息,可以重新进行月结。', {
            shade: .1,
            skin: 'layui-layer-admin'
        }, function (i) {
            layer.close(i);
            layer.load(2);
            $.ajax({
                url: baseUrl + '/monthlySettle/' + data.id + '/auth',
                headers: {'token': localStorage.getItem('token')},
                method: 'DELETE',
                success: function (res) {
                    layer.closeAll('loading');
                    if (res.code === 200) {
                        tableIns.reload({page: {curr: 1}});
                        layer.msg(res.msg || '删除成功', {icon: 1});
                    } else if (res.code === 403) {
                        top.location.href = baseUrl + "/";
                    } else {
                        layer.msg(res.msg || '删除失败', {icon: 2});
                    }
                },
                error: function() {
                    layer.closeAll('loading');
                    layer.msg('删除失败', {icon: 2});
                }
            });
        });
    }
});
function tableReload(child) {
    var searchData = {};
    $.each($('#search-box [name]').serializeArray(), function() {
        var value = this.value;
        // å¤„理日期范围字段
        if (this.name === 'date_range') {
            // åªå¤„理非空值
            if (value && value.trim() !== '') {
                var dates = value.split(' - ');
                if (dates.length === 2) {
                    var startDate = dates[0].trim();
                    var endDate = dates[1].trim();
                    if (startDate !== '' && endDate !== '') {
                        searchData.startDate = startDate;
                        searchData.endDate = endDate;
                    }
                }
            }
        } else if (this.name === 'settle_no') {
            // åªå¤„理非空值
            var trimmedValue = value ? value.trim() : '';
            if (trimmedValue !== '') {
                searchData.settleNo = trimmedValue;
            }
        }
    });
    // èŽ·å– table å®žä¾‹
    var tableInstance = child ? parent.tableIns : tableIns;
    // å¦‚æžœ searchData ä¸ºç©ºå¯¹è±¡ï¼Œéœ€è¦æ˜¾å¼ä¼ å…¥è¦†ç›–所有可能参数的对象
    // å› ä¸º layui table å¯èƒ½ä¼šåˆå¹¶æ—§çš„参数,即使传入空对象也可能保留旧值
    if (Object.keys(searchData).length === 0) {
        if (tableInstance && tableInstance.config) {
            // å…ˆä¿å­˜æ—§çš„ where ä¸­å¯èƒ½å­˜åœ¨çš„æ‰€æœ‰é”®
            var oldWhereKeys = [];
            if (tableInstance.config.where) {
                for (var key in tableInstance.config.where) {
                    if (tableInstance.config.where.hasOwnProperty(key)) {
                        oldWhereKeys.push(key);
                    }
                }
            }
            // å®Œå…¨æ›¿æ¢ where å¯¹è±¡
            tableInstance.config.where = {};
            // å¦‚果之前有参数,创建一个明确覆盖的对象,将所有旧参数设置为空字符串
            // ä½¿ç”¨ç©ºå­—符串而不是 null,因为 layui å¯èƒ½ä¼šè¿‡æ»¤ null å€¼
            if (oldWhereKeys.length > 0) {
                var overrideWhere = {};
                oldWhereKeys.forEach(function(key) {
                    overrideWhere[key] = ''; // è®¾ç½®ä¸ºç©ºå­—符串来覆盖旧值
                });
                searchData = overrideWhere;
                console.log('创建覆盖对象,旧参数键:', oldWhereKeys, '覆盖对象:', JSON.stringify(overrideWhere));
            } else {
                // å³ä½¿æ²¡æœ‰æ—§å‚数,也创建一个包含所有可能参数的空对象
                // è¿™æ ·å¯ä»¥ç¡®ä¿è¦†ç›–任何可能的旧参数
                searchData = {
                    settleNo: '',
                    startDate: '',
                    endDate: ''
                };
                console.log('创建默认覆盖对象:', JSON.stringify(searchData));
            }
        }
    }
    // æž„建 reload å‚æ•°
    var reloadOptions = {
        where: searchData,
        page: {
            curr: pageCurr
        },
        done: function (res, curr, count) {
            if (res.code === 403) {
                top.location.href = baseUrl+"/";
            }
            pageCurr=curr;
            if (res.data.length === 0 && count !== 0) {
                var reloadTableInstance = child ? parent.tableIns : tableIns;
                // å¦‚æžœ searchData ä¸ºç©ºï¼Œä¹Ÿå®Œå…¨æ›¿æ¢ where å¯¹è±¡
                if (Object.keys(searchData).length === 0 && reloadTableInstance && reloadTableInstance.config) {
                    reloadTableInstance.config.where = {};
                }
                reloadTableInstance.reload({
                    where: searchData,
                    page: {
                        curr: pageCurr-1
                    }
                });
                pageCurr -= 1;
            }
        }
    };
    // è°ƒè¯•:打印 reload å‰çš„配置
    console.log('reload å‰çš„ config.where:', JSON.stringify(tableInstance.config ? tableInstance.config.where : 'no config'));
    console.log('reload æ—¶çš„ where å‚æ•°:', JSON.stringify(reloadOptions.where));
    tableInstance.reload(reloadOptions);
    // è°ƒè¯•:打印 reload åŽçš„配置
    setTimeout(function() {
        console.log('reload åŽçš„ config.where:', JSON.stringify(tableInstance.config ? tableInstance.config.where : 'no config'));
    }, 100);
}
src/main/webapp/static/js/orderPakinLog/order.js
New file
@@ -0,0 +1,354 @@
var insTbCount = 0;
layui.config({
    base: baseUrl + "/static/layui/lay/modules/"
}).use(['layer', 'form', 'table', 'util', 'admin', 'laydate', 'element'], function () {
    var $ = layui.jquery;
    var layer = layui.layer;
    var form = layui.form;
    var table = layui.table;
    var util = layui.util;
    var admin = layui.admin;
    var layDate = layui.laydate;
    var laytpl = layui.laytpl;
    var element = layui.element;
    // æ¸²æŸ“搜索模板
    $.ajax({
        url: baseUrl + "/docType/list/auth",
        headers: { 'token': localStorage.getItem('token') },
        data: {
            limit: 9999,
            pakin: 1
        },
        method: 'POST',
        success: function (res) {
            if (res.code === 200) {
                let template = Handlebars.compile($('#docTypeTpl').html());
                $('#docType-query').html(template(res.data));
                layui.form.render('select');
            } else if (res.code === 403) {
                top.location.href = baseUrl + "/";
            } else {
                layer.msg(res.msg, { icon: 2 })
            }
        }
    })
    // æ¸²æŸ“表格
    var insTb = table.render({
        elem: '#order',
        url: baseUrl + '/order/pakinLog/order/head/page/auth',
        method: 'POST',
        headers: { token: localStorage.getItem('token') },
        page: true,
        cellMinWidth: 100,
        cols: [[
            { type: 'numbers' },
            { field: 'orderNo', title: '单据编号', templet: '#orderNoTpl' },
            { field: 'orderTime', align: 'center', title: '业务时间', },
            { field: 'cstmrName', align: 'center', title: '客户', },
            { field: 'docType$', align: 'center', title: '类型', minWidth: 160, width: 160 },
            { align: 'center', title: '明细', toolbar: '#tbLook', minWidth: 160, width: 160 },
            { field: 'createTime$', title: '创建时间', minWidth: 200, width: 200 },
            { field: 'settle$', align: 'center', title: '状态', templet: '#settleTpl', minWidth: 160, width: 160 },
            { field: 'memo', align: 'center', title: '备注', hide: true },
            { align: 'center', title: '操作', toolbar: '#operate', width: 180 }
        ]],
        request: {
            pageName: 'curr',
            pageSize: 'limit'
        },
        parseData: function (res) {
            return {
                'code': res.code,
                'msg': res.msg,
                'count': res.data.total,
                'data': res.data.records
            }
        },
        response: {
            statusCode: 200
        },
        done: function (res, curr, count) {
            limit();
            if (res.code === 403) {
                top.location.href = baseUrl + "/";
            }
            insTbCount = count;
        }
    });
    // æœç´¢
    form.on('submit(tbSearch)', function (data) {
        insTb.reload({ where: data.field, page: { curr: 1 } });
    });
    // å·¥å…·æ¡ç‚¹å‡»äº‹ä»¶
    table.on('tool(order)', function (obj) {
        var data = obj.data;
        var layEvent = obj.event;
        if (layEvent === 'wrkTrace') {
            showWrkTrace(data.id);
        } else if (layEvent === 'look') {
            var $a = $(obj.tr).find('a[lay-event="look"]');
            var offset = $a.offset();
            var top = offset.top;
            var left = offset.left;
            var hasChangeLog = data.hasChangeLog || false;
            var tabContent = '<div class="layui-tab layui-tab-brief" lay-filter="orderDetailTab">' +
                '<ul class="layui-tab-title">' +
                '<li class="layui-this">单据明细</li>';
            if (hasChangeLog) {
                tabContent += '<li>业务时间变更记录</li>';
            }
            tabContent += '</ul>' +
                '<div class="layui-tab-content" style="padding: 10px 0;">' +
                '<div class="layui-tab-item layui-show">' +
                '<table id="lookSSXMTable" lay-filter="lookSSXMTable"></table>' +
                '</div>';
            if (hasChangeLog) {
                tabContent += '<div class="layui-tab-item">' +
                    '<table id="changeLogTable" lay-filter="changeLogTable"></table>' +
                    '</div>';
            }
            tabContent += '</div></div>';
            layer.open({
                type: 1,
                title: false,
                area: '820px',
                offset: [top + 'px', (left - 530 + $a.outerWidth()) + 'px'],
                shade: .01,
                shadeClose: true,
                fixed: false,
                content: tabContent,
                success: function (layero) {
                    // æ¸²æŸ“单据明细表格
                    table.render({
                        elem: '#lookSSXMTable',
                        method: 'POST',
                        headers: { token: localStorage.getItem('token') },
                        url: baseUrl + '/order/pakinLog/orderDetl/list/auth',
                        where: {
                            order_id: data.id
                        },
                        page: true,
                        cellMinWidth: 100,
                        cols: [[
                            { type: 'numbers' },
                            { field: 'matnr', title: '商品编码', width: 160 },
                            { field: 'maktx', title: '商品名称', width: 160 },
                            { field: 'batch', title: '批号' },
                            { field: 'anfme', title: '数量' },
                            { field: 'workQty', title: '作业数量' },
                            { field: 'qty', title: '完成数量', style: 'font-weight: bold' },
                            { field: 'specs', title: '规格' }
                        ]],
                        request: {
                            pageName: 'curr',
                            pageSize: 'limit'
                        },
                        parseData: function (res) {
                            return {
                                'code': res.code,
                                'msg': res.msg,
                                'count': res.data.total,
                                'data': res.data.records
                            }
                        },
                        response: {
                            statusCode: 200
                        },
                        done: function () {
                            $(layero).find('.layui-table-view').css('margin', '0');
                        },
                        size: ''
                    });
                    // æ ‡ç­¾åˆ‡æ¢äº‹ä»¶
                    var changeLogTableRendered = false;
                    element.on('tab(orderDetailTab)', function(elem){
                        if (hasChangeLog && elem.index === 1 && !changeLogTableRendered) {
                            // åˆ‡æ¢åˆ°å˜æ›´è®°å½•标签时才查询(只查询一次)
                            changeLogTableRendered = true;
                            table.render({
                                elem: '#changeLogTable',
                                method: 'POST',
                                headers: { token: localStorage.getItem('token') },
                                url: baseUrl + '/orderTimeChangeLog/list/byOrderId/auth',
                                where: {
                                    orderId: data.id
                                },
                                page: false,
                                cellMinWidth: 100,
                                cols: [[
                                    { type: 'numbers' },
                                    { field: 'oldOrderTime', title: '原业务时间', width: 180 },
                                    { field: 'newOrderTime', title: '新业务时间', width: 180 },
                                    { field: 'memo', title: '备注', minWidth: 200 },
                                    { field: 'createByName', title: '操作人', width: 120 },
                                    { field: 'createTime$', title: '变更时间', width: 180 }
                                ]],
                                parseData: function (res) {
                                    return {
                                        'code': res.code,
                                        'msg': res.msg,
                                        'count': res.data ? res.data.length : 0,
                                        'data': res.data || []
                                    }
                                },
                                response: {
                                    statusCode: 200
                                }
                            });
                        }
                    });
                }
            });
        } else if (layEvent === 'editOrderTime') {
            // æ£€æŸ¥æ˜¯å¦å·²æœˆç»“
            if (data.monthlySettleId && data.monthlySettleId > 0) {
                layer.msg('该单据已月结,不能修改业务时间', { icon: 2 });
                return;
            }
            showEditOrderTimeDialog(data);
        }
    });
    // ä»»åŠ¡è¿½æº¯
    function showWrkTrace(orderId) {
        let loadIndex = layer.msg('请求中...', { icon: 16, shade: 0.01, time: false });
        $.ajax({
            url: baseUrl + "/order/pakinLog/order/wrk/trace/auth",
            headers: { 'token': localStorage.getItem('token') },
            data: {
                orderId: orderId
            },
            method: 'POST',
            success: function (res) {
                layer.close(loadIndex);
                if (res.code === 200) {
                    laytpl(wrkTraceDialog.innerHTML).render(res.data, function (html) {
                        admin.open({
                            type: 1,
                            title: '任务追溯',
                            area: ['800px', '450px'],
                            shadeClose: true,
                            content: html,
                            success: function (layero, dIndex) {
                                $(layero).children('.layui-layer-content').css('overflow', 'visible');
                                /** ç»Ÿè®¡å›¾è¡¨ */
                                var traceCharts = echarts.init(document.getElementById('wrkTraceCharts'));
                                var traceOptions = {
                                    title: {
                                        text: '总量/作业/完成', x: 'center', y: '38%',
                                        textStyle: { fontSize: 18, color: '#262626', fontWeight: 'normal' },
                                        subtextStyle: { fontSize: 36, color: '#10B4E8' },
                                        itemGap: 20
                                    },
                                    color: ['#10B4E8', '#E0E0E0', '#FF0000'],
                                    tooltip: { trigger: 'item' },
                                    series: [{ name: '数量', type: 'pie', radius: ['75%', '80%'], label: { normal: { show: false } } }]
                                };
                                traceCharts.setOption(traceOptions);
                                // èµ‹å€¼
                                traceCharts.setOption({
                                    title: {
                                        subtext: res.data.totalQty + "/" + res.data.wrkQty + "/" + res.data.endQty
                                    },
                                    series: [
                                        {
                                            data: [
                                                { name: '已作业', value: res.data.wrkQty },
                                                { name: '未作业', value: res.data.totalQty - res.data.wrkQty - res.data.lackQty },
                                                { name: '库存不足', value: res.data.lackQty },
                                            ]
                                        }
                                    ]
                                });
                            }
                        });
                    });
                } else if (res.code === 403) {
                    top.location.href = baseUrl + "/";
                } else {
                    layer.msg(res.msg, { icon: 2 });
                }
            }
        })
    }
    // æ˜¾ç¤ºä¿®æ”¹ä¸šåŠ¡æ—¶é—´å¼¹çª—
    function showEditOrderTimeDialog(data) {
        admin.open({
            type: 1,
            title: '修改业务时间',
            content: $('#editOrderTimeDialog').html(),
            area: '400px',
            success: function (layero, dIndex) {
                // å›žæ˜¾æ•°æ®
                form.val('editOrderTimeForm', {
                    id: data.id,
                    orderTime: data.orderTime
                });
                // åˆå§‹åŒ–业务时间日期选择器(支持选择时分秒)
                layDate.render({
                    elem: '#orderTimeEdit',
                    type: 'datetime',
                    format: 'yyyy-MM-dd HH:mm:ss',
                    value: data.orderTime || '',
                    btns: ['clear', 'confirm'],
                    ready: function(date){
                        // ç¡®ä¿æ—¶åˆ†ç§’选择器显示
                        var layero = this.elem.next();
                        if(layero.length > 0) {
                            layero.find('.laydate-time-list').show();
                        }
                    }
                });
                // è¡¨å•提交事件
                form.on('submit(editOrderTimeSubmit)', function (formData) {
                    // å‰ç«¯æ ¡éªŒï¼šæ£€æŸ¥æ–°æ—§æ—¶é—´æ˜¯å¦ç›¸åŒ
                    var oldOrderTime = data.orderTime;
                    var newOrderTime = formData.field.orderTime;
                    if (oldOrderTime && oldOrderTime === newOrderTime) {
                        layer.msg('新业务时间与原业务时间相同,无需修改', { icon: 2 });
                        return false;
                    }
                    layer.load(2);
                    $.ajax({
                        url: baseUrl + "/order/pakinLog/order/update/orderTime/auth",
                        headers: { 'token': localStorage.getItem('token') },
                        data: {
                            id: formData.field.id,
                            orderTime: formData.field.orderTime,
                            memo: formData.field.memo || ''
                        },
                        method: 'POST',
                        success: function (res) {
                            layer.closeAll('loading');
                            if (res.code === 200) {
                                layer.close(dIndex);
                                insTb.reload({ page: { curr: 1 } });
                                layer.msg(res.msg, { icon: 1 });
                            } else if (res.code === 403) {
                                top.location.href = baseUrl + "/";
                            } else {
                                layer.msg(res.msg, { icon: 2 });
                            }
                        }
                    });
                    return false;
                });
            }
        });
    }
    layDate.render({
        elem: '.layui-laydate-range'
        , type: 'datetime'
        , range: true
    });
});
src/main/webapp/static/js/orderPakoutLog/order.js
New file
@@ -0,0 +1,354 @@
var insTbCount = 0;
layui.config({
    base: baseUrl + "/static/layui/lay/modules/"
}).use(['layer', 'form', 'table', 'util', 'admin', 'laydate', 'element'], function () {
    var $ = layui.jquery;
    var layer = layui.layer;
    var form = layui.form;
    var table = layui.table;
    var util = layui.util;
    var admin = layui.admin;
    var layDate = layui.laydate;
    var laytpl = layui.laytpl;
    var element = layui.element;
    // æ¸²æŸ“搜索模板
    $.ajax({
        url: baseUrl + "/docType/list/auth",
        headers: { 'token': localStorage.getItem('token') },
        data: {
            limit: 9999,
            pakout: 1
        },
        method: 'POST',
        success: function (res) {
            if (res.code === 200) {
                let template = Handlebars.compile($('#docTypeTpl').html());
                $('#docType-query').html(template(res.data));
                layui.form.render('select');
            } else if (res.code === 403) {
                top.location.href = baseUrl + "/";
            } else {
                layer.msg(res.msg, { icon: 2 })
            }
        }
    })
    // æ¸²æŸ“表格
    var insTb = table.render({
        elem: '#order',
        url: baseUrl + '/order/pakoutLog/order/head/page/auth',
        method: 'POST',
        headers: { token: localStorage.getItem('token') },
        page: true,
        cellMinWidth: 100,
        cols: [[
            { type: 'numbers' },
            { field: 'orderNo', title: '单据编号', templet: '#orderNoTpl' },
            { field: 'orderTime', align: 'center', title: '业务时间' },
            { field: 'cstmrName', align: 'center', title: '客户' },
            { field: 'docType$', align: 'center', title: '类型', minWidth: 160, width: 160 },
            { align: 'center', title: '明细', toolbar: '#tbLook', minWidth: 160, width: 160 },
            { field: 'createTime$', title: '创建时间', minWidth: 200, width: 200 },
            { field: 'settle$', align: 'center', title: '状态', templet: '#settleTpl', minWidth: 160, width: 160 },
            { field: 'memo', align: 'center', title: '备注', hide: true },
            { align: 'center', title: '操作', toolbar: '#operate', width: 120 }
        ]],
        request: {
            pageName: 'curr',
            pageSize: 'limit'
        },
        parseData: function (res) {
            return {
                'code': res.code,
                'msg': res.msg,
                'count': res.data.total,
                'data': res.data.records
            }
        },
        response: {
            statusCode: 200
        },
        done: function (res, curr, count) {
            limit();
            if (res.code === 403) {
                top.location.href = baseUrl + "/";
            }
            insTbCount = count;
        }
    });
    // æœç´¢
    form.on('submit(tbSearch)', function (data) {
        insTb.reload({ where: data.field, page: { curr: 1 } });
    });
    // å·¥å…·æ¡ç‚¹å‡»äº‹ä»¶
    table.on('tool(order)', function (obj) {
        var data = obj.data;
        var layEvent = obj.event;
        if (layEvent === 'wrkTrace') {
            showWrkTrace(data.id);
        } else if (layEvent === 'look') {
            var $a = $(obj.tr).find('a[lay-event="look"]');
            var offset = $a.offset();
            var top = offset.top;
            var left = offset.left;
            var hasChangeLog = data.hasChangeLog || false;
            var tabContent = '<div class="layui-tab layui-tab-brief" lay-filter="orderDetailTab">' +
                '<ul class="layui-tab-title">' +
                '<li class="layui-this">单据明细</li>';
            if (hasChangeLog) {
                tabContent += '<li>业务时间变更记录</li>';
            }
            tabContent += '</ul>' +
                '<div class="layui-tab-content" style="padding: 10px 0;">' +
                '<div class="layui-tab-item layui-show">' +
                '<table id="lookSSXMTable" lay-filter="lookSSXMTable"></table>' +
                '</div>';
            if (hasChangeLog) {
                tabContent += '<div class="layui-tab-item">' +
                    '<table id="changeLogTable" lay-filter="changeLogTable"></table>' +
                    '</div>';
            }
            tabContent += '</div></div>';
            layer.open({
                type: 1,
                title: false,
                area: '820px',
                offset: [top + 'px', (left - 530 + $a.outerWidth()) + 'px'],
                shade: .01,
                shadeClose: true,
                fixed: false,
                content: tabContent,
                success: function (layero) {
                    // æ¸²æŸ“单据明细表格
                    table.render({
                        elem: '#lookSSXMTable',
                        method: 'POST',
                        headers: { token: localStorage.getItem('token') },
                        url: baseUrl + '/order/pakoutLog/orderDetl/list/auth',
                        where: {
                            order_id: data.id
                        },
                        page: true,
                        cellMinWidth: 100,
                        cols: [[
                            { type: 'numbers' },
                            { field: 'matnr', title: '商品编码', width: 160 },
                            { field: 'maktx', title: '商品名称', width: 160 },
                            { field: 'batch', title: '批号' },
                            { field: 'anfme', title: '数量' },
                            { field: 'workQty', title: '作业数量' },
                            { field: 'qty', title: '完成数量', style: 'font-weight: bold' },
                            { field: 'specs', title: '规格' }
                        ]],
                        request: {
                            pageName: 'curr',
                            pageSize: 'limit'
                        },
                        parseData: function (res) {
                            return {
                                'code': res.code,
                                'msg': res.msg,
                                'count': res.data.total,
                                'data': res.data.records
                            }
                        },
                        response: {
                            statusCode: 200
                        },
                        done: function () {
                            $(layero).find('.layui-table-view').css('margin', '0');
                        },
                        size: ''
                    });
                    // æ ‡ç­¾åˆ‡æ¢äº‹ä»¶
                    var changeLogTableRendered = false;
                    element.on('tab(orderDetailTab)', function(elem){
                        if (hasChangeLog && elem.index === 1 && !changeLogTableRendered) {
                            // åˆ‡æ¢åˆ°å˜æ›´è®°å½•标签时才查询(只查询一次)
                            changeLogTableRendered = true;
                            table.render({
                                elem: '#changeLogTable',
                                method: 'POST',
                                headers: { token: localStorage.getItem('token') },
                                url: baseUrl + '/orderTimeChangeLog/list/byOrderId/auth',
                                where: {
                                    orderId: data.id
                                },
                                page: false,
                                cellMinWidth: 100,
                                cols: [[
                                    { type: 'numbers' },
                                    { field: 'oldOrderTime', title: '原业务时间', width: 180 },
                                    { field: 'newOrderTime', title: '新业务时间', width: 180 },
                                    { field: 'memo', title: '备注', minWidth: 200 },
                                    { field: 'createByName', title: '操作人', width: 120 },
                                    { field: 'createTime$', title: '变更时间', width: 180 }
                                ]],
                                parseData: function (res) {
                                    return {
                                        'code': res.code,
                                        'msg': res.msg,
                                        'count': res.data ? res.data.length : 0,
                                        'data': res.data || []
                                    }
                                },
                                response: {
                                    statusCode: 200
                                }
                            });
                        }
                    });
                }
            });
        } else if (layEvent === 'editOrderTime') {
            // æ£€æŸ¥æ˜¯å¦å·²æœˆç»“
            if (data.monthlySettleId && data.monthlySettleId > 0) {
                layer.msg('该单据已月结,不能修改业务时间', { icon: 2 });
                return;
            }
            showEditOrderTimeDialog(data);
        }
    });
    // ä»»åŠ¡è¿½æº¯
    function showWrkTrace(orderId) {
        let loadIndex = layer.msg('请求中...', { icon: 16, shade: 0.01, time: false });
        $.ajax({
            url: baseUrl + "/order/pakoutLog/order/wrk/trace/auth",
            headers: { 'token': localStorage.getItem('token') },
            data: {
                orderId: orderId
            },
            method: 'POST',
            success: function (res) {
                layer.close(loadIndex);
                if (res.code === 200) {
                    laytpl(wrkTraceDialog.innerHTML).render(res.data, function (html) {
                        admin.open({
                            type: 1,
                            title: '任务追溯',
                            area: ['800px', '450px'],
                            shadeClose: true,
                            content: html,
                            success: function (layero, dIndex) {
                                $(layero).children('.layui-layer-content').css('overflow', 'visible');
                                /** ç»Ÿè®¡å›¾è¡¨ */
                                var traceCharts = echarts.init(document.getElementById('wrkTraceCharts'));
                                var traceOptions = {
                                    title: {
                                        text: '总量/作业/完成', x: 'center', y: '38%',
                                        textStyle: { fontSize: 18, color: '#262626', fontWeight: 'normal' },
                                        subtextStyle: { fontSize: 36, color: '#10B4E8' },
                                        itemGap: 20
                                    },
                                    color: ['#10B4E8', '#E0E0E0', '#FF0000'],
                                    tooltip: { trigger: 'item' },
                                    series: [{ name: '数量', type: 'pie', radius: ['75%', '80%'], label: { normal: { show: false } } }]
                                };
                                traceCharts.setOption(traceOptions);
                                // èµ‹å€¼
                                traceCharts.setOption({
                                    title: {
                                        subtext: res.data.totalQty + "/" + res.data.wrkQty + "/" + res.data.endQty
                                    },
                                    series: [
                                        {
                                            data: [
                                                { name: '已作业', value: res.data.wrkQty },
                                                { name: '未作业', value: res.data.totalQty - res.data.wrkQty - res.data.lackQty },
                                                { name: '库存不足', value: res.data.lackQty },
                                            ]
                                        }
                                    ]
                                });
                            }
                        });
                    });
                } else if (res.code === 403) {
                    top.location.href = baseUrl + "/";
                } else {
                    layer.msg(res.msg, { icon: 2 });
                }
            }
        })
    }
    // æ˜¾ç¤ºä¿®æ”¹ä¸šåŠ¡æ—¶é—´å¼¹çª—
    function showEditOrderTimeDialog(data) {
        admin.open({
            type: 1,
            title: '修改业务时间',
            content: $('#editOrderTimeDialog').html(),
            area: '400px',
            success: function (layero, dIndex) {
                // å›žæ˜¾æ•°æ®
                form.val('editOrderTimeForm', {
                    id: data.id,
                    orderTime: data.orderTime
                });
                // åˆå§‹åŒ–业务时间日期选择器(支持选择时分秒)
                layDate.render({
                    elem: '#orderTimeEdit',
                    type: 'datetime',
                    format: 'yyyy-MM-dd HH:mm:ss',
                    value: data.orderTime || '',
                    btns: ['clear', 'confirm'],
                    ready: function(date){
                        // ç¡®ä¿æ—¶åˆ†ç§’选择器显示
                        var layero = this.elem.next();
                        if(layero.length > 0) {
                            layero.find('.laydate-time-list').show();
                        }
                    }
                });
                // è¡¨å•提交事件
                form.on('submit(editOrderTimeSubmit)', function (formData) {
                    // å‰ç«¯æ ¡éªŒï¼šæ£€æŸ¥æ–°æ—§æ—¶é—´æ˜¯å¦ç›¸åŒ
                    var oldOrderTime = data.orderTime;
                    var newOrderTime = formData.field.orderTime;
                    if (oldOrderTime && oldOrderTime === newOrderTime) {
                        layer.msg('新业务时间与原业务时间相同,无需修改', { icon: 2 });
                        return false;
                    }
                    layer.load(2);
                    $.ajax({
                        url: baseUrl + "/order/pakoutLog/order/update/orderTime/auth",
                        headers: { 'token': localStorage.getItem('token') },
                        data: {
                            id: formData.field.id,
                            orderTime: formData.field.orderTime,
                            memo: formData.field.memo || ''
                        },
                        method: 'POST',
                        success: function (res) {
                            layer.closeAll('loading');
                            if (res.code === 200) {
                                layer.close(dIndex);
                                insTb.reload({ page: { curr: 1 } });
                                layer.msg(res.msg, { icon: 1 });
                            } else if (res.code === 403) {
                                top.location.href = baseUrl + "/";
                            } else {
                                layer.msg(res.msg, { icon: 2 });
                            }
                        }
                    });
                    return false;
                });
            }
        });
    }
    layDate.render({
        elem: '.layui-laydate-range'
        , type: 'datetime'
        , range: true
    });
});
src/main/webapp/views/monthlySettle/monthlySettle.html
New file
@@ -0,0 +1,124 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>月结管理</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" href="../../static/layui/css/layui.css" media="all">
    <link rel="stylesheet" href="../../static/css/admin.css?v=318" media="all">
    <link rel="stylesheet" href="../../static/css/cool.css" media="all">
</head>
<body>
<div class="layui-fluid">
    <div class="layui-card">
        <div class="layui-card-body">
            <div class="layui-form toolbar"  id="search-box">
                <div class="layui-form-item">
                    <div class="layui-inline">
                        <div class="layui-input-inline mr0">
                            <input name="settle_no" class="layui-input" type="text" placeholder="输入月结编号"/>
                        </div>
                    </div>
                    <div class="layui-inline" style="width: 300px">
                        <div class="layui-input-inline">
                            <input class="layui-input layui-laydate-range" name="date_range" type="text" placeholder="起始日期 - ç»“束日期" autocomplete="off" style="width: 300px">
                        </div>
                    </div>
                    <div class="layui-inline">
                        <button class="layui-btn icon-btn" lay-filter="search" lay-submit>
                            <i class="layui-icon">&#xe615;</i>搜索
                        </button>
                        <button id="startSettleBtn" class="layui-btn icon-btn layui-btn-normal">
                            <i class="layui-icon">&#xe608;</i>发起月结
                        </button>
                        <button type="button" class="layui-btn icon-btn layui-btn-primary" lay-filter="reset" lay-submit>
                            <i class="layui-icon">&#xe669;</i>重置
                        </button>
                    </div>
                </div>
            </div>
            <table class="layui-hide" id="monthlySettle" lay-filter="monthlySettle" ></table>
        </div>
    </div>
</div>
<!-- è¡¨æ ¼æ“ä½œåˆ— -->
<script type="text/html" id="operate">
    <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">查看明细</a>
    <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delete">删除</a>
</script>
<!-- å‘起月结弹窗 -->
<script type="text/html" id="startSettleDialog">
    <form id="startSettleForm" lay-filter="startSettleForm" class="layui-form model-form">
        <div class="layui-form-item">
            <label class="layui-form-label">起始日期:</label>
            <div class="layui-input-block">
                <input id="startDate" name="startDate" placeholder="选择起始日期" type="text" class="layui-input" autocomplete="off" lay-verType="tips" lay-verify="required">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">结束日期:</label>
            <div class="layui-input-block">
                <input id="endDate" name="endDate" placeholder="选择结束日期" type="text" class="layui-input" autocomplete="off" lay-verType="tips" lay-verify="required">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">提示:</label>
            <div class="layui-input-block">
                <div id="settleTip" style="color: #ff5722;"></div>
            </div>
        </div>
        <div class="layui-form-item text-right">
            <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button>
            <button class="layui-btn" lay-filter="startSettleSubmit" lay-submit>确认月结</button>
        </div>
    </form>
</script>
<!-- æœˆç»“明细弹窗 -->
<script type="text/html" id="detailDialog">
    <div style="padding: 20px;">
        <div class="layui-row">
            <div class="layui-col-md6">
                {{# if(d.settleNo) { }}
                <p><strong>月结编号:</strong>{{ d.settleNo }}</p>
                {{# } }}
                {{# if(d.startDate$) { }}
                <p><strong>起始日期:</strong>{{ d.startDate$ }}</p>
                {{# } }}
                {{# if(d.endDate$) { }}
                <p><strong>结束日期:</strong>{{ d.endDate$ }}</p>
                {{# } }}
            </div>
            <div class="layui-col-md6">
                {{# if(d.totalInQty !== null && d.totalInQty !== undefined) { }}
                <p><strong>总入库数量:</strong>{{ d.totalInQty }}</p>
                {{# } }}
                {{# if(d.totalOutQty !== null && d.totalOutQty !== undefined) { }}
                <p><strong>总出库数量:</strong>{{ d.totalOutQty }}</p>
                {{# } }}
                {{# if(d.totalMaterials !== null && d.totalMaterials !== undefined) { }}
                <p><strong>物料种类数:</strong>{{ d.totalMaterials }}</p>
                {{# } }}
            </div>
        </div>
        <hr class="layui-bg-gray">
        <div style="overflow-x: auto; width: 100%;">
            <table id="detailTable" lay-filter="detailTable"></table>
        </div>
    </div>
</script>
<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script>
<script type="text/javascript" src="../../static/js/monthlySettle/monthlySettle.js" charset="utf-8"></script>
</body>
</html>
src/main/webapp/views/orderPakinLog/order.html
New file
@@ -0,0 +1,261 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title></title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" href="../../static/layui/css/layui.css" media="all">
    <link rel="stylesheet" href="../../static/css/admin.css?v=318" media="all">
    <link rel="stylesheet" href="../../static/css/cool.css" media="all">
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style>
        .wrk-trace {
            color: green;
            cursor: pointer;
            margin-left: 6px;
            font-size: 18px;
        }
        .layui-timeline:first-child .layui-timeline-item {
            margin-top: 30px;
        }
    </style>
</head>
<body>
    <!-- æ­£æ–‡å¼€å§‹ -->
    <div class="layui-fluid">
        <div class="layui-card">
            <div class="layui-card-body">
                <!-- è¡¨æ ¼é¡¶éƒ¨å·¥å…·æ  -->
                <div class="layui-form toolbar">
                    <div class="layui-form-item">
                        <div class="layui-inline">
                            <div class="layui-input-inline mr0">
                                <input name="order_no" class="layui-input" type="text" placeholder="输入单据编号" />
                            </div>
                        </div>
                        <div class="layui-inline" style="width: 300px">
                            <div class="layui-input-inline">
                                <input class="layui-input layui-laydate-range" name="create_time" type="text"
                                    placeholder="起始时间 - ç»ˆæ­¢æ—¶é—´" autocomplete="off" style="width: 300px">
                            </div>
                        </div>
                        <div class="layui-inline">
                            <div class="layui-input-inline">
                                <select name="doc_type" id="docType-query">
                                </select>
                            </div>
                        </div>
                        <div class="layui-inline">
                            <div class="layui-input-inline">
                                <select name="settle">
                                    <option value="">选择状态</option>
                                    <option value="1">待处理</option>
                                    <option value="2">作业中</option>
                                    <option value="4">已完成</option>
                                    <option value="6">上报完成</option>
                                </select>
                            </div>
                        </div>
                        <div class="layui-inline">
                            <button class="layui-btn icon-btn" lay-filter="tbSearch" lay-submit>
                                <i class="layui-icon">&#xe615;</i>搜索
                            </button>
                        </div>
                    </div>
                </div>
                <table id="order" lay-filter="order"></table>
            </div>
        </div>
        <div class="layui-card">
            <div class="layui-card-body">
                å…¥åº“历史单据:查询已完成的入库单据历史记录。
            </div>
        </div>
    </div>
    <!-- è¡¨æ ¼æ“ä½œåˆ— -->
    <script type="text/html" id="tbLook">
    <span class="layui-text">
        <a href="javascript:;" lay-event="look">
            <i class="layui-icon" style="font-size: 12px;">&#xe61a;</i> æŸ¥çœ‹å•据明细
        </a>
    </span>
</script>
    <!-- æ“ä½œåˆ— -->
    <script type="text/html" id="operate">
    {{# if(!d.monthlySettleId || d.monthlySettleId == 0){ }}
    <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="editOrderTime">修改业务时间</a>
    {{# } }}
</script>
    <script type="text/html" id="orderNoTpl">
    {{d.orderNo}}
    {{# if(d.settle > 1 && d.settle !== 3){ }}
    <i class="layui-icon layui-icon-about wrk-trace" lay-tips="查看任务追溯" lay-direction="2" lay-offset="-10px,0px" lay-event="wrkTrace"></i>
    {{# } }}
</script>
    <script type="text/html" id="settleTpl">
    <span name="settle"
          {{# if( d.settle === 1){ }}
          class="layui-badge layui-badge-red"
          {{# }else if(d.settle === 2){ }}
          class="layui-badge layui-badge-green"
          {{# }else if(d.settle === 3){ }}
          class="layui-badge layui-badge-gray"
          {{# }else if(d.settle === 4){ }}
          class="layui-badge layui-badge-blue"
          {{# }else if(d.settle === 5){ }}
          class="layui-badge layui-badge-gray"
          {{# }else if(d.settle === 6){ }}
          class="layui-badge layui-badge-gray"
          {{# } }}
    >{{d.settle$}}</span>
</script>
    <!-- è®¢å•任务追溯 -->
    <script id="wrkTraceDialog" type="text/html" style="position: relative">
    <div style="position: absolute; top: 0; left: 0;">
        <div class="layui-card" style="overflow: hidden;">
            <div class="layui-card-header" style="text-align: center;width: 80%;font-weight: inherit;font-size: 18px">{{ d.orderNo }}</div>
            <div class="layui-card-body">
                <div id="wrkTraceCharts" style="height: 300px;width: 400px;transform: translateX(-10%);"></div>
            </div>
        </div>
    </div>
    <div class="layui-row" >
        <div class="layui-col-md5">
            <h1 style="opacity: 0;">Hello World</h1>
        </div>
        <div  class="layui-col-md7" style="">
            {{#  if(d.list.length > 0){ }}
            <ul class="layui-timeline" style="height: 400px; overflow: scroll;">
                {{#  layui.each(d.list, function(index, item){ }}
                <li class="layui-timeline-item">
                    <i class="layui-icon layui-timeline-axis">&#xe63f;</i>
                    <div class="layui-timeline-content layui-text">
                        <div class="layui-timeline-title">
                            <h3 class="inline-block">
                                {{ item.wrkNo }}&nbsp;
                                {{#  if(item.wrkMast.ioType < 100){ }}
                                <span class="layui-badge layui-bg-blue" style="line-height: 20px;">
                                 {{ item.wrkMast.ioType$ }}&nbsp;
                                </span>
                                {{#  } }}
                                {{#  if(item.wrkMast.ioType > 100){ }}
                                <span class="layui-badge layui-bg-orange" style="line-height: 20px;">
                                  {{ item.wrkMast.ioType$ }}&nbsp;
                                </span>
                                {{#  } }}
                                {{#  if(item.wrkMast.wrkSts < 14){ }}
                                <span class="layui-badge layui-bg-red" style="line-height: 20px;">
                                    {{ item.wrkMast.wrkSts$ }}&nbsp;
                                </span>
                                {{#  } }}
                                {{#  if(item.wrkMast.wrkSts >= 14){ }}
                                <span class="layui-badge layui-bg-green" style="line-height: 20px;">
                                    {{ item.wrkMast.wrkSts$ }}&nbsp;
                                </span>
                                {{#  } }}
                            </h3>&emsp;
                            {{ item.wrkMast.ioTime$ }}
                        </div>
                        <table class="layui-table" lay-skin="nob" style="width: 80%">
                            <tbody>
                            {{#  layui.each(item.wrkDetls, function(idx, wrkDetl){ }}
                            <tr style="background: none">
                                <td>No.</td>
                                <td><span class="layui-badge layui-bg-cyan">{{ idx+1 }}</span></td>
                            </tr>
                            <tr style="background: none">
                                <td>品号:</td>
                                <td>{{ wrkDetl.matnr }}</td>
                            </tr>
                            <tr style="background: none">
                                <td>品名:</td>
                                <td>{{ wrkDetl.maktx }}</td>
                            </tr>
                            <tr style="background: none">
                                <td>规格:</td>
                                <td>{{ wrkDetl.specs }}</td>
                            </tr>
                            <tr style="background: none">
                                <td>数量:</td>
                                <td style="font-weight: bold">{{ wrkDetl.anfme }}</td>
                            </tr>
                            <tr style="background: none">
                                <td>条码:</td>
                                <td style="font-weight: bold">{{ wrkDetl.zpallet }}</td>
                            </tr>
                            {{#  }); }}
                            </tbody>
                        </table>
                        <hr class="layui-border-cyan" style="width: 90%; opacity: .6;">
                    </div>
                </li>
                {{#  }); }}
            </ul>
            {{#  } else { }}
            <div style="height: 350px;display: flex;justify-content: center;align-items: center;">
                <h2 style="font-weight: bold;letter-spacing: 2px">暂无任务</h2>
            </div>
            {{#  } }}
        </div>
    </div>
</script>
    <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="../../static/js/handlebars/handlebars-v4.5.3.js"></script>
    <script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script>
    <script type="text/javascript" src="../../static/js/echarts/echarts.min.js" charset="utf-8"></script>
    <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script>
    <script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script>
    <script type="text/javascript" src="../../static/js/orderPakinLog/order.js" charset="utf-8"></script>
    <script type="text/template" id="docTypeTpl">
    <option value="">选择类型</option>
    {{#each records}}
    <option value="{{docId}}">{{docName}}</option>
    {{/each}}
</script>
    <!-- ä¿®æ”¹ä¸šåŠ¡æ—¶é—´å¼¹çª— -->
    <script type="text/html" id="editOrderTimeDialog">
    <form id="editOrderTimeForm" lay-filter="editOrderTimeForm" class="layui-form model-form">
        <input name="id" type="hidden"/>
        <div class="layui-form-item">
            <label class="layui-form-label">业务时间:</label>
            <div class="layui-input-block">
                <input id="orderTimeEdit" name="orderTime" placeholder="选择业务时间" type="text" class="layui-input" autocomplete="off" lay-verType="tips" lay-verify="required">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">变更备注:</label>
            <div class="layui-input-block">
                <textarea name="memo" placeholder="请输入变更备注(可选)" class="layui-textarea" rows="3"></textarea>
            </div>
        </div>
        <div class="layui-form-item text-right">
            <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button>
            <button class="layui-btn" lay-filter="editOrderTimeSubmit" lay-submit>保存</button>
        </div>
    </form>
</script>
</body>
</html>
src/main/webapp/views/orderPakoutLog/order.html
New file
@@ -0,0 +1,261 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title></title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" href="../../static/layui/css/layui.css" media="all">
    <link rel="stylesheet" href="../../static/css/admin.css?v=318" media="all">
    <link rel="stylesheet" href="../../static/css/cool.css" media="all">
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style>
        .wrk-trace {
            color: green;
            cursor: pointer;
            margin-left: 6px;
            font-size: 18px;
        }
        .layui-timeline:first-child .layui-timeline-item {
            margin-top: 30px;
        }
    </style>
</head>
<body>
    <!-- æ­£æ–‡å¼€å§‹ -->
    <div class="layui-fluid">
        <div class="layui-card">
            <div class="layui-card-body">
                <!-- è¡¨æ ¼é¡¶éƒ¨å·¥å…·æ  -->
                <div class="layui-form toolbar">
                    <div class="layui-form-item">
                        <div class="layui-inline">
                            <div class="layui-input-inline mr0">
                                <input name="order_no" class="layui-input" type="text" placeholder="输入单据编号" />
                            </div>
                        </div>
                        <div class="layui-inline" style="width: 300px">
                            <div class="layui-input-inline">
                                <input class="layui-input layui-laydate-range" name="create_time" type="text"
                                    placeholder="起始时间 - ç»ˆæ­¢æ—¶é—´" autocomplete="off" style="width: 300px">
                            </div>
                        </div>
                        <div class="layui-inline">
                            <div class="layui-input-inline">
                                <select name="doc_type" id="docType-query">
                                </select>
                            </div>
                        </div>
                        <div class="layui-inline">
                            <div class="layui-input-inline">
                                <select name="settle">
                                    <option value="">选择状态</option>
                                    <option value="1">待处理</option>
                                    <option value="2">作业中</option>
                                    <option value="4">已完成</option>
                                    <option value="6">上报完成</option>
                                </select>
                            </div>
                        </div>
                        <div class="layui-inline">
                            <button class="layui-btn icon-btn" lay-filter="tbSearch" lay-submit>
                                <i class="layui-icon">&#xe615;</i>搜索
                            </button>
                        </div>
                    </div>
                </div>
                <table id="order" lay-filter="order"></table>
            </div>
        </div>
        <div class="layui-card">
            <div class="layui-card-body">
                å‡ºåº“历史单据:查询已完成的出库单据历史记录。
            </div>
        </div>
    </div>
    <!-- è¡¨æ ¼æ“ä½œåˆ— -->
    <script type="text/html" id="tbLook">
    <span class="layui-text">
        <a href="javascript:;" lay-event="look">
            <i class="layui-icon" style="font-size: 12px;">&#xe61a;</i> æŸ¥çœ‹å•据明细
        </a>
    </span>
</script>
    <!-- æ“ä½œåˆ— -->
    <script type="text/html" id="operate">
    {{# if(!d.monthlySettleId || d.monthlySettleId == 0){ }}
    <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="editOrderTime">修改业务时间</a>
    {{# } }}
</script>
    <script type="text/html" id="orderNoTpl">
    {{d.orderNo}}
    {{# if(d.settle > 1 && d.settle !== 3){ }}
    <i class="layui-icon layui-icon-about wrk-trace" lay-tips="查看任务追溯" lay-direction="2" lay-offset="-10px,0px" lay-event="wrkTrace"></i>
    {{# } }}
</script>
    <script type="text/html" id="settleTpl">
    <span name="settle"
          {{# if( d.settle === 1){ }}
          class="layui-badge layui-badge-red"
          {{# }else if(d.settle === 2){ }}
          class="layui-badge layui-badge-green"
          {{# }else if(d.settle === 3){ }}
          class="layui-badge layui-badge-gray"
          {{# }else if(d.settle === 4){ }}
          class="layui-badge layui-badge-blue"
          {{# }else if(d.settle === 5){ }}
          class="layui-badge layui-badge-gray"
          {{# }else if(d.settle === 6){ }}
          class="layui-badge layui-badge-gray"
          {{# } }}
    >{{d.settle$}}</span>
</script>
    <!-- è®¢å•任务追溯 -->
    <script id="wrkTraceDialog" type="text/html" style="position: relative">
    <div style="position: absolute; top: 0; left: 0;">
        <div class="layui-card" style="overflow: hidden;">
            <div class="layui-card-header" style="text-align: center;width: 80%;font-weight: inherit;font-size: 18px">{{ d.orderNo }}</div>
            <div class="layui-card-body">
                <div id="wrkTraceCharts" style="height: 300px;width: 400px;transform: translateX(-10%);"></div>
            </div>
        </div>
    </div>
    <div class="layui-row" >
        <div class="layui-col-md5">
            <h1 style="opacity: 0;">Hello World</h1>
        </div>
        <div  class="layui-col-md7" style="">
            {{#  if(d.list.length > 0){ }}
            <ul class="layui-timeline" style="height: 400px; overflow: scroll;">
                {{#  layui.each(d.list, function(index, item){ }}
                <li class="layui-timeline-item">
                    <i class="layui-icon layui-timeline-axis">&#xe63f;</i>
                    <div class="layui-timeline-content layui-text">
                        <div class="layui-timeline-title">
                            <h3 class="inline-block">
                                {{ item.wrkNo }}&nbsp;
                                {{#  if(item.wrkMast.ioType < 100){ }}
                                <span class="layui-badge layui-bg-blue" style="line-height: 20px;">
                                 {{ item.wrkMast.ioType$ }}&nbsp;
                                </span>
                                {{#  } }}
                                {{#  if(item.wrkMast.ioType > 100){ }}
                                <span class="layui-badge layui-bg-orange" style="line-height: 20px;">
                                  {{ item.wrkMast.ioType$ }}&nbsp;
                                </span>
                                {{#  } }}
                                {{#  if(item.wrkMast.wrkSts < 14){ }}
                                <span class="layui-badge layui-bg-red" style="line-height: 20px;">
                                    {{ item.wrkMast.wrkSts$ }}&nbsp;
                                </span>
                                {{#  } }}
                                {{#  if(item.wrkMast.wrkSts >= 14){ }}
                                <span class="layui-badge layui-bg-green" style="line-height: 20px;">
                                    {{ item.wrkMast.wrkSts$ }}&nbsp;
                                </span>
                                {{#  } }}
                            </h3>&emsp;
                            {{ item.wrkMast.ioTime$ }}
                        </div>
                        <table class="layui-table" lay-skin="nob" style="width: 80%">
                            <tbody>
                            {{#  layui.each(item.wrkDetls, function(idx, wrkDetl){ }}
                            <tr style="background: none">
                                <td>No.</td>
                                <td><span class="layui-badge layui-bg-cyan">{{ idx+1 }}</span></td>
                            </tr>
                            <tr style="background: none">
                                <td>品号:</td>
                                <td>{{ wrkDetl.matnr }}</td>
                            </tr>
                            <tr style="background: none">
                                <td>品名:</td>
                                <td>{{ wrkDetl.maktx }}</td>
                            </tr>
                            <tr style="background: none">
                                <td>规格:</td>
                                <td>{{ wrkDetl.specs }}</td>
                            </tr>
                            <tr style="background: none">
                                <td>数量:</td>
                                <td style="font-weight: bold">{{ wrkDetl.anfme }}</td>
                            </tr>
                            <tr style="background: none">
                                <td>条码:</td>
                                <td style="font-weight: bold">{{ wrkDetl.zpallet }}</td>
                            </tr>
                            {{#  }); }}
                            </tbody>
                        </table>
                        <hr class="layui-border-cyan" style="width: 90%; opacity: .6;">
                    </div>
                </li>
                {{#  }); }}
            </ul>
            {{#  } else { }}
            <div style="height: 350px;display: flex;justify-content: center;align-items: center;">
                <h2 style="font-weight: bold;letter-spacing: 2px">暂无任务</h2>
            </div>
            {{#  } }}
        </div>
    </div>
</script>
    <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="../../static/js/handlebars/handlebars-v4.5.3.js"></script>
    <script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script>
    <script type="text/javascript" src="../../static/js/echarts/echarts.min.js" charset="utf-8"></script>
    <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script>
    <script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script>
    <script type="text/javascript" src="../../static/js/orderPakoutLog/order.js" charset="utf-8"></script>
    <script type="text/template" id="docTypeTpl">
    <option value="">选择类型</option>
    {{#each records}}
    <option value="{{docId}}">{{docName}}</option>
    {{/each}}
</script>
    <!-- ä¿®æ”¹ä¸šåŠ¡æ—¶é—´å¼¹çª— -->
    <script type="text/html" id="editOrderTimeDialog">
    <form id="editOrderTimeForm" lay-filter="editOrderTimeForm" class="layui-form model-form">
        <input name="id" type="hidden"/>
        <div class="layui-form-item">
            <label class="layui-form-label">业务时间:</label>
            <div class="layui-input-block">
                <input id="orderTimeEdit" name="orderTime" placeholder="选择业务时间" type="text" class="layui-input" autocomplete="off" lay-verType="tips" lay-verify="required">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">变更备注:</label>
            <div class="layui-input-block">
                <textarea name="memo" placeholder="请输入变更备注(可选)" class="layui-textarea" rows="3"></textarea>
            </div>
        </div>
        <div class="layui-form-item text-right">
            <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button>
            <button class="layui-btn" lay-filter="editOrderTimeSubmit" lay-submit>保存</button>
        </div>
    </form>
</script>
</body>
</html>