自动化立体仓库 - WMS系统
5dca49269399c21333b16d62945c7f74570f9ad5..c7b54b961679677b84fbbd5f0555748064479382
2025-12-25 chen.llin
库存明细API
c7b54b 对比 | 目录
2025-12-25 chen.llin
出入库历史 +月结管理 按钮权限+sql
5232d8 对比 | 目录
2个文件已添加
8个文件已修改
361 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/MonthlySettleController.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OpenController.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/param/OpenLocDetlQueryParam.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MonthlySettleServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/sql/按钮权限.sql 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/css/common.css 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/monthlySettle/monthlySettle.js 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/monthlySettle/monthlySettle.html 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/orderPakinLog/order.html 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/orderPakoutLog/order.html 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/MonthlySettleController.java
@@ -4,15 +4,19 @@
import com.core.annotations.ManagerAuth;
import com.core.common.R;
import com.zy.asrs.entity.MonthlySettle;
import com.zy.asrs.entity.MonthlySettleDetail;
import com.zy.asrs.entity.param.DateRangeParam;
import com.zy.asrs.entity.param.MonthlySettleQueryParam;
import com.zy.asrs.entity.result.MonthlySettleStatisticsVO;
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.ArrayList;
import java.util.Date;
import java.util.List;
@RestController
public class MonthlySettleController extends BaseController {
@@ -131,5 +135,34 @@
        return R.ok("删除成功");
    }
    /**
     * å¯¼å‡ºæœˆç»“明细
     */
    @RequestMapping(value = "/monthlySettle/detail/export/{id}/auth")
    @ManagerAuth(memo = "导出月结明细")
    public R exportDetail(@PathVariable("id") Long id) {
        // èŽ·å–æœˆç»“ç»Ÿè®¡ä¿¡æ¯
        MonthlySettleStatisticsVO statistics = monthlySettleService.getSettleStatistics(id);
        if (statistics == null || statistics.getDetails() == null) {
            return R.error("月结明细不存在");
        }
        List<MonthlySettleDetail> details = statistics.getDetails();
        // å®šä¹‰å¯¼å‡ºå­—段
        List<String> fields = new ArrayList<>();
        fields.add("matnr");
        fields.add("maktx");
        fields.add("batch");
        fields.add("brand");
        fields.add("beginningQty");
        fields.add("endingQty");
        fields.add("diffQty");
        fields.add("inQty");
        fields.add("outQty");
        return R.ok(exportSupport(details, fields));
    }
}
src/main/java/com/zy/asrs/controller/OpenController.java
@@ -4,11 +4,16 @@
import com.core.annotations.AppAuth;
import com.core.common.*;
import com.core.exception.CoolException;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.zy.asrs.entity.AgvCallbackDto;
import com.zy.asrs.entity.LocDetl;
import com.zy.asrs.entity.param.MatSyncParam;
import com.zy.asrs.entity.param.OpenLocDetlQueryParam;
import com.zy.asrs.entity.param.OpenOrderCompleteParam;
import com.zy.asrs.entity.param.OpenOrderPakinParam;
import com.zy.asrs.entity.param.OpenOrderPakoutParam;
import com.zy.asrs.service.LocDetlService;
import com.zy.asrs.service.OpenService;
import com.zy.common.model.DetlDto;
import com.zy.common.model.MesPakinParam;
@@ -18,10 +23,12 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * Created by vincent on 2022/4/8
@@ -38,6 +45,9 @@
    @Autowired
    private OpenService openService;
    @Resource
    private LocDetlService locDetlService;
    @PostMapping("/api/agv_callback")
    @AppAuth(memo = "agv任务回调")
@@ -210,6 +220,32 @@
        return R.ok().add(openService.queryStock());
    }
    /**
     * åº“存明细查询
     */
    @PostMapping("/locDetl/list/default/v1")
    @AppAuth(memo = "库存明细查询")
    public R queryLocDetlList(@RequestHeader(required = false) String appkey,
                              @RequestBody OpenLocDetlQueryParam param,
                              HttpServletRequest request) {
        auth(appkey, param, request);
        if (Cools.isEmpty(param)) {
            return R.parse(BaseRes.PARAM);
        }
        EntityWrapper<LocDetl> wrapper = new EntityWrapper<>();
        Map<String, Object> paramMap = param.toQueryMap();
        excludeTrash(paramMap);
        param.convertToWrapper(wrapper);
        allLike(LocDetl.class, paramMap.keySet(), wrapper, param.getCondition());
        if (!Cools.isEmpty(param.getOrderByField())) {
            wrapper.orderBy(humpToLine(param.getOrderByField()), "asc".equals(param.getOrderByType()));
        }
        Integer curr = param.getCurr() != null ? param.getCurr() : 1;
        Integer limit = param.getLimit() != null ? param.getLimit() : 10;
        return R.ok(locDetlService.selectPage(new Page<>(curr, limit), wrapper));
    }
    private void auth(String appkey, Object obj, HttpServletRequest request) {
        log.info("{}接口被访问;appkey:{};请求数据:{}", request.getRequestURI(), appkey, JSON.toJSONString(obj));
        request.setAttribute("cache", obj);
src/main/java/com/zy/asrs/entity/param/OpenLocDetlQueryParam.java
New file
@@ -0,0 +1,133 @@
package com.zy.asrs.entity.param;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.core.common.DateUtils;
import com.zy.asrs.entity.LocDetl;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
 * åº“存明细查询参数
 */
@Data
public class OpenLocDetlQueryParam {
    private static final String RANGE_TIME_LINK = " - ";
    @ApiModelProperty(value = "当前页码", example = "1")
    private Integer curr = 1;
    @ApiModelProperty(value = "每页数量", example = "10")
    private Integer limit = 10;
    @ApiModelProperty(value = "排序字段")
    private String orderByField;
    @ApiModelProperty(value = "排序类型", example = "asc")
    private String orderByType;
    @ApiModelProperty(value = "通用查询条件")
    private String condition;
    @ApiModelProperty(value = "库位号")
    private String locNo;
    @ApiModelProperty(value = "托盘号")
    private String zpallet;
    @ApiModelProperty(value = "物料编码")
    private String matnr;
    @ApiModelProperty(value = "规格")
    private String specs;
    @ApiModelProperty(value = "冻结状态")
    private String frozen;
    /**
     * å°†æŸ¥è¯¢å‚数转换为 EntityWrapper æŸ¥è¯¢æ¡ä»¶
     * @param wrapper EntityWrapper å¯¹è±¡
     */
    public void convertToWrapper(EntityWrapper<LocDetl> wrapper) {
        if (!Cools.isEmpty(locNo)) {
            String val = String.valueOf(locNo);
            if (val.contains(RANGE_TIME_LINK)) {
                String[] dates = val.split(RANGE_TIME_LINK);
                wrapper.ge("loc_no", DateUtils.convert(dates[0]));
                wrapper.le("loc_no", DateUtils.convert(dates[1]));
            } else {
                wrapper.eq("loc_no", locNo);
            }
        }
        if (!Cools.isEmpty(zpallet)) {
            String val = String.valueOf(zpallet);
            if (val.contains(RANGE_TIME_LINK)) {
                String[] dates = val.split(RANGE_TIME_LINK);
                wrapper.ge("zpallet", DateUtils.convert(dates[0]));
                wrapper.le("zpallet", DateUtils.convert(dates[1]));
            } else {
                wrapper.like("zpallet", zpallet);
            }
        }
        if (!Cools.isEmpty(matnr)) {
            String val = String.valueOf(matnr);
            if (val.contains(RANGE_TIME_LINK)) {
                String[] dates = val.split(RANGE_TIME_LINK);
                wrapper.ge("matnr", DateUtils.convert(dates[0]));
                wrapper.le("matnr", DateUtils.convert(dates[1]));
            } else {
                wrapper.like("matnr", matnr);
            }
        }
        if (!Cools.isEmpty(specs)) {
            String val = String.valueOf(specs);
            if (val.contains(RANGE_TIME_LINK)) {
                String[] dates = val.split(RANGE_TIME_LINK);
                wrapper.ge("specs", DateUtils.convert(dates[0]));
                wrapper.le("specs", DateUtils.convert(dates[1]));
            } else {
                wrapper.like("specs", specs);
            }
        }
        if (!Cools.isEmpty(frozen)) {
            String val = String.valueOf(frozen);
            if (val.contains(RANGE_TIME_LINK)) {
                String[] dates = val.split(RANGE_TIME_LINK);
                wrapper.ge("frozen", DateUtils.convert(dates[0]));
                wrapper.le("frozen", DateUtils.convert(dates[1]));
            } else {
                wrapper.like("frozen", frozen);
            }
        }
    }
    /**
     * è½¬æ¢ä¸ºæŸ¥è¯¢æ¡ä»¶ Map(用于 excludeTrash å’Œ allLike)
     * @return Map å¯¹è±¡
     */
    public Map<String, Object> toQueryMap() {
        Map<String, Object> paramMap = new HashMap<>();
        if (!Cools.isEmpty(locNo)) {
            paramMap.put("locNo", locNo);
        }
        if (!Cools.isEmpty(zpallet)) {
            paramMap.put("zpallet", zpallet);
        }
        if (!Cools.isEmpty(matnr)) {
            paramMap.put("matnr", matnr);
        }
        if (!Cools.isEmpty(specs)) {
            paramMap.put("specs", specs);
        }
        if (!Cools.isEmpty(frozen)) {
            paramMap.put("frozen", frozen);
        }
        return paramMap;
    }
}
src/main/java/com/zy/asrs/service/impl/MonthlySettleServiceImpl.java
@@ -498,8 +498,6 @@
        detail.setInQty(inQty);
        detail.setOutQty(outQty);
        detail.setEndingQty(endingQty);
        // stock_qty å­—段已废弃,实际库存等于期末库存,不再单独存储
        // detail.setStockQty(endingQty);
        detail.setDiffQty(diffQty);
        // æ—¶é—´ä¿¡æ¯
        detail.setCreateTime(new Date());
src/main/resources/sql/°´Å¥È¨ÏÞ.sql
New file
@@ -0,0 +1,24 @@
--  æœˆç»“
insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'monthlySettle/monthlySettle.html', N'月结管理', null, '2', null, '1');
insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'monthlySettle#btn-view', N'查询',    ''     , '3', '0', '1');
insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'monthlySettle#btn-add', N'发起月结',   ''     , '3', '1', '1');
insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'monthlySettle#btn-export', N'导出',   ''    , '3', '2', '1');
insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'monthlySettle#btn-delete', N'删除',  ''     , '3', '3', '1');
-- å…¥åº“历史订单
insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'orderPakinLog/order.html', N'入库历史单据', null, '2', null, '1');
insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'orderPakinLog#btn-view', N'查询',       ''   , '3', '0', '1');
insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'orderPakinLog#btn-edit', N'修改业务时间',   ''   , '3', '1', '1');
-- å‡ºåº“历史订单
insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'orderPakoutLog/order.html', N'出库历史单据', null, '2', null, '1');
insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'orderPakoutLog#btn-view', N'查询',       ''    , '3', '0', '1');
insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'orderPakoutLog#btn-edit', N'修改业务时间',   ''  , '3', '1', '1');
src/main/webapp/static/css/common.css
@@ -206,6 +206,9 @@
#btn-into {
    display: none;
}
.btn-view {
    display: none;
}
/*修改复选框颜色*/
/*.layui-form-checked[lay-skin=primary] i {*/
src/main/webapp/static/js/monthlySettle/monthlySettle.js
@@ -29,7 +29,7 @@
            {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}
            {align: 'center', title: '操作', toolbar: '#operate', width: 240}
        ]],
        request: {
            pageName: 'curr',
@@ -368,6 +368,8 @@
        var layEvent = obj.event;
        if (layEvent === 'detail') {
            showDetailDialog(data);
        } else if (layEvent === 'export') {
            exportDetail(data);
        } else if (layEvent === 'delete') {
            deleteSettle(data);
        }
@@ -478,6 +480,50 @@
        });
    }
    // å¯¼å‡ºæœˆç»“明细
    function exportDetail(data) {
        layer.confirm('确定导出月结明细 "' + data.settleNo + '" å—?', {
            shade: .1,
            skin: 'layui-layer-admin'
        }, function (i) {
            layer.close(i);
            layer.load(2);
            $.ajax({
                url: baseUrl + '/monthlySettle/detail/export/' + data.id + '/auth',
                headers: {'token': localStorage.getItem('token')},
                method: 'POST',
                success: function (res) {
                    layer.closeAll('loading');
                    if (res.code === 200) {
                        // å®šä¹‰è¡¨å¤´
                        var titles = [
                            '物料编码',
                            '物料名称',
                            '批次',
                            '品牌',
                            '期初库存',
                            '期末库存',
                            '差异数量',
                            '本期入库',
                            '本期出库'
                        ];
                        // ä½¿ç”¨ table.exportFile å¯¼å‡º
                        table.exportFile(titles, res.data, 'xls');
                        layer.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 deleteSettle(data) {
        layer.confirm('确认要删除月结记录 "' + data.settleNo + '" å—?删除后将清除关联的出入库订单月结信息,可以重新进行月结。', {
src/main/webapp/views/monthlySettle/monthlySettle.html
@@ -9,6 +9,31 @@
    <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">
    <style>
        .btn-add {
            display: none;
        }
        .btn-edit {
            display: none;
        }
        .btn-complete {
            display: none;
        }
        .btn-delete {
            display: none;
        }
        .btn-export {
            display: none;
        }
        .btn-view {
            display: none;
        }
    </style>
</head>
<body>
@@ -28,10 +53,10 @@
                        </div>
                    </div>
                    <div class="layui-inline">
                        <button class="layui-btn icon-btn" lay-filter="search" lay-submit>
                        <button class="layui-btn icon-btn btn-view" lay-filter="search" lay-submit>
                            <i class="layui-icon">&#xe615;</i>搜索
                        </button>
                        <button id="startSettleBtn" class="layui-btn icon-btn layui-btn-normal">
                        <button id="startSettleBtn" class="layui-btn icon-btn layui-btn-normal btn-add">
                            <i class="layui-icon">&#xe608;</i>发起月结
                        </button>
                        <button type="button" class="layui-btn icon-btn layui-btn-primary" lay-filter="reset" lay-submit>
@@ -47,8 +72,9 @@
<!-- è¡¨æ ¼æ“ä½œåˆ— -->
<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>
    <a class="layui-btn layui-btn-normal layui-btn-xs btn-export" lay-event="export">导出</a>
    <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">明细</a>
    <a class="layui-btn layui-btn-danger layui-btn-xs btn-delete" lay-event="delete">删除</a>
</script>
<!-- å‘起月结弹窗 -->
src/main/webapp/views/orderPakinLog/order.html
@@ -25,6 +25,26 @@
        .layui-timeline:first-child .layui-timeline-item {
            margin-top: 30px;
        }
        .btn-add {
            display: none;
        }
        .btn-edit {
            display: none;
        }
        .btn-complete {
            display: none;
        }
        .btn-delete {
            display: none;
        }
        .btn-view {
            display: none;
        }
    </style>
</head>
@@ -66,7 +86,7 @@
                            </div>
                        </div>
                        <div class="layui-inline">
                            <button class="layui-btn icon-btn" lay-filter="tbSearch" lay-submit>
                            <button class="layui-btn icon-btn btn-view" lay-filter="tbSearch" lay-submit>
                                <i class="layui-icon">&#xe615;</i>搜索
                            </button>
                        </div>
@@ -92,7 +112,7 @@
    <!-- æ“ä½œåˆ— -->
    <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>
    <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="editOrderTime">修改业务时间</a>
    {{# } }}
</script>
    <script type="text/html" id="orderNoTpl">
src/main/webapp/views/orderPakoutLog/order.html
@@ -25,6 +25,26 @@
        .layui-timeline:first-child .layui-timeline-item {
            margin-top: 30px;
        }
        .btn-add {
            display: none;
        }
        .btn-edit {
            display: none;
        }
        .btn-complete {
            display: none;
        }
        .btn-delete {
            display: none;
        }
        .btn-view {
            display: none;
        }
    </style>
</head>
@@ -66,7 +86,7 @@
                            </div>
                        </div>
                        <div class="layui-inline">
                            <button class="layui-btn icon-btn" lay-filter="tbSearch" lay-submit>
                            <button class="layui-btn icon-btn btn-view" lay-filter="tbSearch" lay-submit>
                                <i class="layui-icon">&#xe615;</i>搜索
                            </button>
                        </div>
@@ -92,7 +112,7 @@
    <!-- æ“ä½œåˆ— -->
    <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>
    <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="editOrderTime">修改业务时间</a>
    {{# } }}
</script>
    <script type="text/html" id="orderNoTpl">