rsf-open-api/pom.xml
@@ -21,7 +21,7 @@ <artifactId>rsf-common</artifactId> <version>1.0.0</version> </dependency> <!-- OpenFeign:转发调用立库 WMS 接口 --> <!-- OpenFeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> rsf-open-api/src/main/java/com/vincent/rsf/openApi/controller/MonitorController.java
@@ -1,9 +1,11 @@ package com.vincent.rsf.openApi.controller; import com.vincent.rsf.openApi.entity.dto.CommonResponse; import com.vincent.rsf.openApi.feign.wms.WmsServerFeignClient; import com.vincent.rsf.openApi.service.MonitorService; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -21,6 +23,34 @@ @Autowired private MonitorService monitorService; @Autowired private WmsServerFeignClient wmsServerFeignClient; @GetMapping("/queryLoc") @ApiOperation("大屏:库位库存统计") public Map<String, Object> queryLoc() { return wmsServerFeignClient.openAsrsQueryLoc(); } @GetMapping("/line/charts") @ApiOperation("大屏:入出库折线图数据") public Map<String, Object> lineCharts() { return wmsServerFeignClient.openAsrsLineCharts(); } @GetMapping("/locDetl/statistics") @ApiOperation("大屏:库存明细分页统计") public Map<String, Object> locDetlStatistics() { return wmsServerFeignClient.openAsrsLocDetlStatistics(); } @PostMapping("/queryTask") @ApiOperation("大屏:任务查询") public Map<String, Object> queryTask(@RequestBody Map<String, Object> body) { return wmsServerFeignClient.openAsrsQueryTask(body); } /** * 获取出入库流水记录 * @return rsf-open-api/src/main/java/com/vincent/rsf/openApi/feign/wms/WmsServerFeignClient.java
@@ -4,6 +4,7 @@ import com.vincent.rsf.openApi.entity.params.ErpOpParams; import com.vincent.rsf.openApi.feign.wms.fallback.WmsServerFeignClientFallbackFactory; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -52,4 +53,20 @@ /** 库存汇总查询(对接协议 8.5) */ @PostMapping("/rsf-server/erp/inventory/summary") Map<String, Object> inventorySummary(@RequestBody Map<String, Object> params); /** 大屏:库位库存统计 */ @GetMapping("/rsf-server/monitor/queryLoc") Map<String, Object> openAsrsQueryLoc(); /** 大屏:入出库折线图数据 */ @GetMapping("/rsf-server/monitor/line/charts") Map<String, Object> openAsrsLineCharts(); /** 大屏:库存明细分页统计 */ @GetMapping("/rsf-server/monitor/locDetl/statistics") Map<String, Object> openAsrsLocDetlStatistics(); /** 大屏:任务查询 */ @PostMapping("/rsf-server/monitor/queryTask") Map<String, Object> openAsrsQueryTask(@RequestBody Map<String, Object> body); } rsf-open-api/src/main/java/com/vincent/rsf/openApi/feign/wms/fallback/WmsServerFeignClientFallback.java
@@ -88,43 +88,67 @@ @Override public Map<String, Object> queryOrderAndDetls(ErpOpParams params) { log.error("调用立库WMS Server订单信息查询接口失败,触发降级", cause); log.error("调用WMS Server订单信息查询接口失败,触发降级", cause); return errorResponse(); } @Override public Map<String, Object> updateOrderDetls(List<Map<String, Object>> body) { log.error("调用立库WMS Server订单修改接口失败,触发降级", cause); log.error("调用WMS Server订单修改接口失败,触发降级", cause); return errorResponse(); } @Override public Map<String, Object> orderDel(List<Map<String, Object>> body) { log.error("调用立库WMS Server取消单据接口失败,触发降级", cause); log.error("调用WMS Server取消单据接口失败,触发降级", cause); return errorResponse(); } @Override public Map<String, Object> syncMatnrs(ErpMatnrParms params) { log.error("调用立库WMS Server物料信息同步接口失败,触发降级", cause); log.error("调用WMS Server物料信息同步接口失败,触发降级", cause); return errorResponse(); } @Override public Map<String, Object> queryLocsDetls(Map<String, Object> params) { log.error("调用立库WMS Server库位信息查询接口失败,触发降级", cause); log.error("调用WMS Server库位信息查询接口失败,触发降级", cause); return errorResponse(); } @Override public Map<String, Object> inventoryDetails(Map<String, Object> params) { log.error("调用立库WMS Server库存明细查询接口失败,触发降级", cause); log.error("调用WMS Server库存明细查询接口失败,触发降级", cause); return errorResponse(); } @Override public Map<String, Object> inventorySummary(Map<String, Object> params) { log.error("调用立库WMS Server库存汇总查询接口失败,触发降级", cause); log.error("调用WMS Server库存汇总查询接口失败,触发降级", cause); return errorResponse(); } @Override public Map<String, Object> openAsrsQueryLoc() { log.error("调用 monitor/queryLoc 失败,触发降级", cause); return errorResponse(); } @Override public Map<String, Object> openAsrsLineCharts() { log.error("调用 monitor/line/charts 失败,触发降级", cause); return errorResponse(); } @Override public Map<String, Object> openAsrsLocDetlStatistics() { log.error("调用 monitor/locDetl/statistics 失败,触发降级", cause); return errorResponse(); } @Override public Map<String, Object> openAsrsQueryTask(Map<String, Object> body) { log.error("调用 monitor/queryTask 失败,触发降级", cause); return errorResponse(); } } rsf-server/src/main/java/com/vincent/rsf/server/api/controller/open/param/QueryTaskParam.java
New file @@ -0,0 +1,12 @@ package com.vincent.rsf.server.api.controller.open.param; import lombok.Data; /** * 开放任务查询入参(与 gsl QueryTaskParam 字段一致) */ @Data public class QueryTaskParam { private String taskNo; } rsf-server/src/main/java/com/vincent/rsf/server/api/controller/pda/MonitorController.java
@@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.vincent.rsf.framework.common.R; import com.vincent.rsf.server.api.controller.open.param.QueryTaskParam; import com.vincent.rsf.server.api.service.MonitorService; import com.vincent.rsf.server.api.service.OpenAsrsService; import com.vincent.rsf.server.common.domain.BaseParam; import com.vincent.rsf.server.common.domain.PageParam; import com.vincent.rsf.server.common.utils.FieldsUtils; @@ -16,6 +18,7 @@ import com.vincent.rsf.server.system.controller.BaseController; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -38,6 +41,34 @@ @Autowired private WarehouseStockService warehouseStockService; @Autowired private OpenAsrsService openAsrsService; @GetMapping("/queryLoc") @ApiOperation("大屏:库位库存统计") public R queryLoc() { return openAsrsService.queryLoc(); } @GetMapping("/line/charts") @ApiOperation("大屏:入出库折线图数据") public R locIoLineCharts() { return openAsrsService.locIoLineCharts(); } @GetMapping("/locDetl/statistics") @ApiOperation("大屏:库存明细分页统计") public R locDetlStatistics() { return openAsrsService.locDetlStatistics(); } @PostMapping("/queryTask") @ApiOperation("大屏:任务查询") public R queryTask(@RequestBody QueryTaskParam param) { return openAsrsService.queryTask(param); } /** * 获取出入库流水记录 * @return rsf-server/src/main/java/com/vincent/rsf/server/api/service/OpenAsrsService.java
New file @@ -0,0 +1,18 @@ package com.vincent.rsf.server.api.service; import com.vincent.rsf.framework.common.R; import com.vincent.rsf.server.api.controller.open.param.QueryTaskParam; /** * 开放 ASRS 查询(电视机等),返回格式对齐 gsl OpenController */ public interface OpenAsrsService { R queryLoc(); R locIoLineCharts(); R locDetlStatistics(); R queryTask(QueryTaskParam param); } rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/OpenAsrsServiceImpl.java
New file @@ -0,0 +1,196 @@ package com.vincent.rsf.server.api.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.vincent.rsf.framework.common.BaseRes; import com.vincent.rsf.framework.common.Cools; import com.vincent.rsf.framework.common.R; import com.vincent.rsf.server.api.controller.open.param.QueryTaskParam; import com.vincent.rsf.server.api.service.OpenAsrsService; import com.vincent.rsf.server.manager.controller.dto.LocStockDto; import com.vincent.rsf.server.manager.entity.Task; import com.vincent.rsf.server.manager.entity.TaskItem; import com.vincent.rsf.server.manager.enums.LocStsType; import com.vincent.rsf.server.manager.mapper.OpenAsrsMapper; import com.vincent.rsf.server.manager.service.LocService; import com.vincent.rsf.server.manager.service.TaskItemService; import com.vincent.rsf.server.manager.service.TaskService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @Service public class OpenAsrsServiceImpl implements OpenAsrsService { @Resource private OpenAsrsMapper openAsrsMapper; @Resource private LocService locService; @Resource private TaskService taskService; @Resource private TaskItemService taskItemService; @Override public R queryLoc() { List<Map<String, Object>> rows = openAsrsMapper.countLocGroupByUseStatus(); int f = countStatus(rows, LocStsType.LOC_STS_TYPE_F.type); int o = countStatus(rows, LocStsType.LOC_STS_TYPE_O.type); int d = countStatus(rows, LocStsType.LOC_STS_TYPE_D.type); int r = countStatus(rows, LocStsType.LOC_STS_TYPE_R.type); int s = countStatus(rows, LocStsType.LOC_STS_TYPE_S.type); int x = countStatus(rows, LocStsType.LOC_STS_TYPE_X.type); int oqty = o + d; int uqty = r + s; List<Map<String, Object>> pie = new ArrayList<>(); pie.add(pieSlice("在库", f)); pie.add(pieSlice("空", oqty)); pie.add(pieSlice("使用", uqty)); pie.add(pieSlice("禁用", x)); int total = f + oqty + uqty + x; int used = f + uqty; double usedPr = 0D; if (total > 0) { usedPr = BigDecimal.valueOf(used) .multiply(BigDecimal.valueOf(100)) .divide(BigDecimal.valueOf(total), 1, RoundingMode.HALF_UP) .doubleValue(); } return R.ok( Cools.add("pie", pie) .add("stockCount", f) .add("emptyCount", oqty) .add("disableCount", x) .add("total", total) .add("used", used) .add("usedPr", usedPr) ); } private static int countStatus(List<Map<String, Object>> rows, String status) { if (rows == null) { return 0; } for (Map<String, Object> row : rows) { Object st = row.get("st"); if (st != null && status.equals(String.valueOf(st))) { Object cnt = row.get("cnt"); if (cnt instanceof Number) { return ((Number) cnt).intValue(); } } } return 0; } private static Map<String, Object> pieSlice(String name, int value) { Map<String, Object> m = new LinkedHashMap<>(); m.put("name", name); m.put("value", value); return m; } @Override public R locIoLineCharts() { List<Map<String, Object>> dbRows = openAsrsMapper.aggregateInOutByDay(); Map<String, int[]> byDay = new HashMap<>(); if (dbRows != null) { for (Map<String, Object> row : dbRows) { String ymd = row.get("ymd") == null ? null : String.valueOf(row.get("ymd")); if (ymd == null || ymd.isEmpty()) { continue; } int inq = toInt(row.get("inqty")); int outq = toInt(row.get("outqty")); byDay.put(ymd, new int[]{inq, outq}); } } List<Map<String, Object>> list = new ArrayList<>(); List<Integer> data1 = new ArrayList<>(); List<Integer> data2 = new ArrayList<>(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DATE, -12); for (int i = 0; i < 12; i++) { calendar.add(Calendar.DATE, 1); String str = sf.format(calendar.getTime()); int[] pair = byDay.get(str); if (pair != null) { data1.add(pair[0]); data2.add(pair[1]); } else { data1.add(0); data2.add(0); } } Map<String, Object> inqty = new LinkedHashMap<>(); inqty.put("name", "入库数量"); inqty.put("data", data1.toArray(new Integer[0])); list.add(inqty); Map<String, Object> outqty = new LinkedHashMap<>(); outqty.put("name", "出库数量"); outqty.put("data", data2.toArray(new Integer[0])); list.add(outqty); Map<String, Object> map = new LinkedHashMap<>(); map.put("rows", list); return R.ok(map); } private static int toInt(Object o) { if (o == null) { return 0; } if (o instanceof Number) { return ((Number) o).intValue(); } try { return new BigDecimal(o.toString()).intValue(); } catch (Exception e) { return 0; } } @Override public R locDetlStatistics() { Page<Object> page = new Page<>(1, 100); return R.ok(locService.getLocDetls(page)); } @Override public synchronized R queryTask(QueryTaskParam param) { if (Cools.isEmpty(param)) { return R.parse(BaseRes.PARAM); } if (Cools.isEmpty(param.getTaskNo())) { return R.error("任务号[taskNo]不能为空"); } Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskCode, param.getTaskNo())); if (task == null) { return R.error("任务不存在"); } List<TaskItem> wrkDetls = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId())); Map<String, Object> map = new LinkedHashMap<>(); map.put("taskNo", param.getTaskNo()); map.put("ioType", task.getTaskType()); map.put("wrkDetls", wrkDetls); return R.ok().add(map); } } rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/OpenAsrsMapper.java
New file @@ -0,0 +1,28 @@ package com.vincent.rsf.server.manager.mapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import java.util.List; import java.util.Map; /** * 开放 ASRS 查询(电视机等),SQL 与 gsl 视图统计语义对齐到本库表结构 */ @Mapper public interface OpenAsrsMapper { @Select("SELECT use_status AS st, COUNT(*) AS cnt FROM man_loc WHERE (deleted IS NULL OR deleted = 0) GROUP BY use_status") List<Map<String, Object>> countLocGroupByUseStatus(); /** * 按日汇总已完成入/出库任务次数(与 gsl asr_sta_inout_view 折线图用途一致) */ @Select("SELECT DATE_FORMAT(COALESCE(end_time, update_time, create_time), '%Y-%m-%d') AS ymd, " + "SUM(CASE WHEN task_type IN (1,10,53,54,57) AND IFNULL(task_status,0) IN (98,99,100) THEN 1 ELSE 0 END) AS inqty, " + "SUM(CASE WHEN task_type IN (101,103,104,107,110) AND IFNULL(task_status,0) IN (198,199,200) THEN 1 ELSE 0 END) AS outqty " + "FROM man_task_log WHERE (deleted IS NULL OR deleted = 0) " + "AND COALESCE(end_time, update_time, create_time) >= DATE_SUB(CURDATE(), INTERVAL 14 DAY) " + "GROUP BY ymd ORDER BY ymd") List<Map<String, Object>> aggregateInOutByDay(); }