代码更新:

1.增加excel的导入导出
2.增加导入记录表
This commit is contained in:
梁州 2024-08-06 16:21:16 +08:00
parent f567677685
commit e7a061942f
46 changed files with 1394 additions and 1236 deletions

11
pom.xml
View File

@ -109,12 +109,12 @@
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.5</version>
<version>5.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
<version>5.3.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
@ -173,7 +173,12 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
<build>

View File

@ -10,6 +10,7 @@ public enum ConfigMapKeyEnum {
START_WORK("START_WORK"),
SEND_TASK("SEND_TASK"),
MAX_VEHICLE_NUMS("MAX_VEHICLE_NUMS"),
MAX_WCS_ACCEPT_NUMS("MAX_WCS_ACCEPT_NUMS"),
SLOC_FILTER_STRING("SLOC_FILTER_STRING"),
URL_WCS_CHANGE_TASK("URL_WCS_CHANGE_TASK");
private final String configKey;

View File

@ -13,6 +13,7 @@ import com.wms.entity.app.request.ConfigQuery;
import com.wms.entity.app.vo.ConfigVo;
import com.wms.entity.table.Config;
import com.wms.service.ConfigService;
import com.wms.system_service.ISystemService;
import com.wms.utils.HttpUtils;
import com.wms.utils.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
@ -51,6 +52,10 @@ public class ConfigController {
* 请求头部信息
*/
private final HttpServletRequest servletRequest;
/**
* 系统服务
*/
private final ISystemService systemService;
/**
* 查找所有配置
@ -122,12 +127,24 @@ public class ConfigController {
rsp.setMessage("更新系统配置时配置id为必须项");
return JSON.toJSONString(rsp);
}
// 更新配置
configService.update(new LambdaUpdateWrapper<Config>()
.set(StringUtils.isNotEmpty(configQuery.getConfigKey()), Config::getConfigKey, configQuery.getConfigKey())
.set(StringUtils.isNotEmpty(configQuery.getConfigType()), Config::getConfigType, configQuery.getConfigType())
.set(StringUtils.isNotEmpty(configQuery.getConfigValue()), Config::getConfigValue, configQuery.getConfigValue())
.set(StringUtils.isNotEmpty(configQuery.getConfigName()), Config::getConfigName, configQuery.getConfigName())
.eq(Config::getConfigId, configQuery.getConfigId()));
// 更新Map
try {
systemService.reloadConfig();
// 返回成功
rsp.setCode(ResponseCode.OK.getCode());
rsp.setMessage("更新系统配置成功!");
} catch (Exception e) {
// 返回成功
rsp.setCode(ResponseCode.OK.getCode());
rsp.setMessage("重载系统配置错误,请手动重载配置。");
}
// 返回成功
rsp.setCode(ResponseCode.OK.getCode());
rsp.setMessage("更新系统配置成功!");

View File

@ -1,23 +1,25 @@
package com.wms.controller;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wms.constants.enums.*;
import com.wms.entity.app.ResponseEntity;
import com.wms.entity.app.dto.LocationDto;
import com.wms.entity.app.dto.StockDto;
import com.wms.entity.app.dto.TaskRecordDto;
import com.wms.entity.app.dto.VehicleDto;
import com.wms.entity.app.request.LocationQuery;
import com.wms.entity.app.request.StockQuery;
import com.wms.entity.app.request.TaskRecordQuery;
import com.wms.entity.app.request.VehicleQuery;
import com.wms.entity.table.Location;
import com.wms.entity.table.Vehicle;
import com.wms.entity.app.vo.FileVo;
import com.wms.entity.table.*;
import com.wms.service.*;
import com.wms.utils.StringUtils;
import com.wms.utils.excel.ExcelUtils;
import com.wms.utils.excel.listener.UploadStocksListener;
import com.wms.utils.excel.style.ExcelContentStyle;
import com.wms.utils.excel.vo.LocationExcelVo;
import com.wms.utils.excel.vo.StockExcelVo;
import com.wms.utils.excel.vo.TaskRecordExcelVo;
import com.wms.utils.excel.vo.VehicleExcelVo;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
@ -32,11 +34,14 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.Collections;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import static com.wms.utils.HttpUtils.getIpAddr;
import static com.wms.utils.StringUtils.convertJsonString;
import static com.wms.utils.WmsUtils.generateId;
/**
*
@ -52,6 +57,7 @@ public class ExcelController {
private final TaskRecordService taskRecordService;// 任务记录服务
private final VehicleService vehicleService;// 载具服务
private final LocationService locationService;// 库位服务
private final UploadRecordService uploadRecordService;// 上传服务
/**
* 导入库存信息
@ -62,22 +68,27 @@ public class ExcelController {
@PostMapping("/uploadStocks")
@ResponseBody
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public String uploadStocks(@RequestPart("file") MultipartFile file) {
public String uploadStocks(@RequestPart("file") MultipartFile file, @RequestPart("obj") FileVo fileVo) {
logger.info("导入库存请求ip{}", getIpAddr(servletRequest));
ResponseEntity response = new ResponseEntity();
try {
List<StockDto> stocksDto = ExcelUtils.readMultipartFile(file, StockDto.class);
// 导入excel
EasyExcel.read(file.getInputStream(), StockExcelVo.class, new UploadStocksListener(stockService)).sheet().doRead();
// 添加导入记录
UploadRecord uploadRecord = new UploadRecord();
uploadRecord.setUploadId(generateId("UPLOAD_"));
uploadRecord.set
uploadRecordService.save(uploadRecord);
response.setCode(ResponseCode.OK.getCode());
response.setMessage("导入库存成功");
response.setReturnData(file);
response.setMessage("导入库存成功。");
} catch (Exception e) {
convertJsonString(e);
logger.error("导入库存异常:{}", convertJsonString(e));
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
response.setCode(ResponseCode.ERROR.getCode());
response.setMessage(e.getMessage());
response.setMessage("导入库存异常。");
}
return JSON.toJSONString(response);
return convertJsonString(response);
}
/**
@ -85,12 +96,31 @@ public class ExcelController {
*
* @param response 请求
*/
@GetMapping("/downloadStockExcel")
@PostMapping("/downloadStockExcel")
@ResponseBody
public void downloadStockExcel(@RequestParam("stockQuery") StockQuery query, HttpServletResponse response) {
logger.info("导出库存记录请求ip{}", getIpAddr(servletRequest));
List<StockDto> stocks = stockService.selectStocks(query.toStockPO());
ExcelUtils.export(response, "库存报表", stocks, StockDto.class);
public void downloadStockExcel(@RequestBody StockQuery stockQuery, HttpServletResponse response) throws IOException {
logger.info("导出库存记录,筛选参数:{}请求ip{}", convertJsonString(stockQuery), getIpAddr(servletRequest));
//设置响应格式
// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("库存报表", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
// 内容样式
HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle();
// 查询参数
List<Stock> stockPoList = stockService.list(new LambdaQueryWrapper<Stock>()
.like(StringUtils.isNotEmpty(stockQuery.getVehicleId()), Stock::getVehicleId, stockQuery.getVehicleId())
.eq(StringUtils.isNotEmpty(stockQuery.getLocationId()), Stock::getLocationId, stockQuery.getLocationId())
.eq(stockQuery.getStockStatus() != null, Stock::getStockStatus, stockQuery.getStockStatus())
.apply(StringUtils.isNotEmpty(stockQuery.getGoodsId()), "goods_related ->> '$.goodsId' like concat('%', {0}, '%')", stockQuery.getGoodsId())
.apply(StringUtils.isNotEmpty(stockQuery.getGoodsName()), "goods_related ->> '$.goodsName' like concat('%', {0}, '%')", stockQuery.getGoodsName()));
EasyExcel.write(response.getOutputStream(), StockExcelVo.class)
.excelType(ExcelTypeEnum.XLSX)
.registerWriteHandler(horizontalCellStyleStrategy)
.sheet("库存")
.doWrite(stockPoList.stream().map(StockExcelVo::of).toList());
}
/**
@ -98,12 +128,25 @@ public class ExcelController {
*
* @param response 请求
*/
@GetMapping("/downloadInRecordExcel")
@PostMapping("/downloadInRecordExcel")
@ResponseBody
public void downloadInRecordExcel(@RequestParam("recordQuery") TaskRecordQuery query, HttpServletResponse response) {
logger.info("导出入库记录请求ip{}", getIpAddr(servletRequest));
List<TaskRecordDto> inRecord = taskRecordService.selectInTaskRecord(query.toTaskRecordPO());
ExcelUtils.export(response, "入库记录报表", inRecord, TaskRecordDto.class);
public void downloadInRecordExcel(@RequestBody TaskRecordQuery query, HttpServletResponse response) throws IOException {
logger.info("导出入库记录,筛选参数:{}请求ip{}", convertJsonString(query), getIpAddr(servletRequest));
//设置响应格式
response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("入库记录", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
// 内容样式
HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle();
// 查询参数
List<TaskRecord> inRecord = taskRecordService.selectInTaskRecord(query.toTaskRecordPO());
EasyExcel.write(response.getOutputStream(), TaskRecordExcelVo.class)
.excelType(ExcelTypeEnum.XLSX)
.registerWriteHandler(horizontalCellStyleStrategy)
.sheet("入库记录")
.doWrite(inRecord.stream().map(TaskRecordExcelVo::of).toList());
}
/**
@ -111,12 +154,25 @@ public class ExcelController {
*
* @param response 请求
*/
@GetMapping("/downloadOutRecordExcel")
@PostMapping("/downloadOutRecordExcel")
@ResponseBody
public void downloadOutRecordExcel(@RequestParam("recordQuery") TaskRecordQuery query, HttpServletResponse response) {
logger.info("导出出库记录请求ip{}", getIpAddr(servletRequest));
List<TaskRecordDto> outRecord = taskRecordService.selectOutTaskRecord(query.toTaskRecordPO());
ExcelUtils.export(response, "出库记录报表", outRecord, TaskRecordDto.class);
public void downloadOutRecordExcel(@RequestBody TaskRecordQuery query, HttpServletResponse response) throws IOException {
logger.info("导出出库记录,筛选参数:{}请求ip{}", convertJsonString(query), getIpAddr(servletRequest));
//设置响应格式
response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("出库记录", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
// 内容样式
HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle();
// 查询参数
List<TaskRecord> inRecord = taskRecordService.selectOutTaskRecord(query.toTaskRecordPO());
EasyExcel.write(response.getOutputStream(), TaskRecordExcelVo.class)
.excelType(ExcelTypeEnum.XLSX)
.registerWriteHandler(horizontalCellStyleStrategy)
.sheet("出库记录")
.doWrite(inRecord.stream().map(TaskRecordExcelVo::of).toList());
}
/**
@ -124,12 +180,25 @@ public class ExcelController {
*
* @param response 请求
*/
@GetMapping("/downloadInventoryRecordExcel")
@PostMapping("/downloadInventoryRecordExcel")
@ResponseBody
public void downloadInventoryRecordExcel(@RequestParam("recordQuery") TaskRecordQuery query, HttpServletResponse response) {
logger.info("导出盘点记录请求ip{}", getIpAddr(servletRequest));
List<TaskRecordDto> inventoryRecord = taskRecordService.selectInventoryTaskRecord(query.toTaskRecordPO());
ExcelUtils.export(response, "盘点记录报表", inventoryRecord, TaskRecordDto.class);
public void downloadInventoryRecordExcel(@RequestBody TaskRecordQuery query, HttpServletResponse response) throws IOException {
logger.info("导出盘点记录,筛选参数:{}请求ip{}", convertJsonString(query), getIpAddr(servletRequest));
//设置响应格式
response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("盘点记录", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
// 内容样式
HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle();
// 查询参数
List<TaskRecord> inRecord = taskRecordService.selectInventoryTaskRecord(query.toTaskRecordPO());
EasyExcel.write(response.getOutputStream(), TaskRecordExcelVo.class)
.excelType(ExcelTypeEnum.XLSX)
.registerWriteHandler(horizontalCellStyleStrategy)
.sheet("盘点记录")
.doWrite(inRecord.stream().map(TaskRecordExcelVo::of).toList());
}
/**
@ -137,20 +206,29 @@ public class ExcelController {
*
* @param response 请求
*/
@GetMapping("/downloadVehicleExcel")
@PostMapping("/downloadVehicleExcel")
@ResponseBody
public void downloadVehicleExcel(@RequestParam("vehicleQuery") VehicleQuery vehicleQuery, HttpServletResponse response) {
logger.info("导出载具记录,查询参数:{}请求ip{}", convertJsonString(vehicleQuery), getIpAddr(servletRequest));
public void downloadVehicleExcel(@RequestBody VehicleQuery vehicleQuery, HttpServletResponse response) throws IOException {
logger.info("导出料箱报表,筛选参数:{}请求ip{}", convertJsonString(vehicleQuery), getIpAddr(servletRequest));
//设置响应格式
response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("盘点记录", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
// 内容样式
HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle();
// 查询参数
List<Vehicle> vehicles = vehicleService.list(new LambdaQueryWrapper<Vehicle>()
.like(StringUtils.isNotEmpty(vehicleQuery.getVehicleId()), Vehicle::getVehicleId, vehicleQuery.getVehicleId())
.like(StringUtils.isNotEmpty(vehicleQuery.getCurrentLocation()), Vehicle::getCurrentLocation, vehicleQuery.getCurrentLocation())
.eq(vehicleQuery.getIsEmpty() != null, Vehicle::getIsEmpty, vehicleQuery.getIsEmpty())
.eq(vehicleQuery.getVehicleStatus() != null, Vehicle::getVehicleStatus, vehicleQuery.getVehicleStatus()));
if (vehicles == null || vehicles.isEmpty()) {
ExcelUtils.export(response, "载具报表", Collections.emptyList(), VehicleDto.class);
} else {
ExcelUtils.export(response, "载具报表", BeanUtil.copyToList(vehicles, VehicleDto.class), VehicleDto.class);
}
EasyExcel.write(response.getOutputStream(), VehicleExcelVo.class)
.excelType(ExcelTypeEnum.XLSX)
.registerWriteHandler(horizontalCellStyleStrategy)
.sheet("料箱报表")
.doWrite(vehicles.stream().map(VehicleExcelVo::of).toList());
}
/**
@ -158,19 +236,28 @@ public class ExcelController {
*
* @param response 请求
*/
@GetMapping("/downloadLocationsExcel")
@PostMapping("/downloadLocationsExcel")
@ResponseBody
public void downloadLocationsExcel(@RequestParam("locationQuery") LocationQuery locationQuery, HttpServletResponse response) {
logger.info("导出库位详情,查询参数:{}请求ip{}", convertJsonString(locationQuery), getIpAddr(servletRequest));
public void downloadLocationsExcel(@RequestBody LocationQuery locationQuery, HttpServletResponse response) throws IOException {
logger.info("导出库位报表,筛选参数:{}请求ip{}", convertJsonString(locationQuery), getIpAddr(servletRequest));
//设置响应格式
response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("库位报表", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
// 内容样式
HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle();
// 查询参数
List<Location> locations = locationService.list(new LambdaQueryWrapper<Location>()
.like(StringUtils.isNotEmpty(locationQuery.getLocationId()), Location::getLocationId, locationQuery.getLocationId())
.eq(locationQuery.getAreaId() != null, Location::getAreaId, locationQuery.getAreaId())
.eq(locationQuery.getIsLock() != null, Location::getIsLock, locationQuery.getIsLock())
.eq(locationQuery.getLocationStatus() != null, Location::getLocationStatus, locationQuery.getLocationStatus()));
if (locations == null || locations.isEmpty()) {
ExcelUtils.export(response, "库位报表", Collections.emptyList(), LocationDto.class);
} else {
ExcelUtils.export(response, "库位报表", BeanUtil.copyToList(locations, LocationDto.class), LocationDto.class);
}
EasyExcel.write(response.getOutputStream(), LocationExcelVo.class)
.excelType(ExcelTypeEnum.XLSX)
.registerWriteHandler(horizontalCellStyleStrategy)
.sheet("库位报表")
.doWrite(locations.stream().map(LocationExcelVo::of).toList());
}
}

View File

@ -50,12 +50,11 @@ public class JobComponent {
* 每2秒执行一次
*/
@Async
// @Scheduled(fixedDelay = 2000)
@Scheduled(fixedDelay = 2000)
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public void executeTasks() {
String sendTask = configMap.get(ConfigMapKeyEnum.SEND_TASK.getConfigKey());
if (StringUtils.isEmpty(sendTask) || !sendTask.equals("1")) {
logger.info("暂停发送任务,跳过...");
return;
}
try {
@ -85,12 +84,11 @@ public class JobComponent {
* 检测工作
*/
@Async
// @Scheduled(fixedDelay = 2000)
@Scheduled(fixedDelay = 2000)
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public void detectWork() {
String startWork = configMap.get(ConfigMapKeyEnum.START_WORK.getConfigKey());
if (StringUtils.isEmpty(startWork) || !startWork.equals("1")) {
logger.info("未开始工作,跳过...");
return;
}
// 轮询工作站台判断是否需要下发任务
@ -117,7 +115,6 @@ public class JobComponent {
}
}
//
// /**
// * 每天查询一次是否有入库后长期未使用的库存
// * 每天晚上9点执行一次

View File

@ -157,7 +157,8 @@ public class TaskController {
Task sameVehicleTempTask = taskService.getOne(new LambdaQueryWrapper<Task>()
.eq(Task::getVehicleId, taskInRequest.getVehicleId())
.eq(Task::getTaskStatus, WmsTaskStatus.TEMP.getCode())
.eq(Task::getTaskType, TaskType.IN.getCode()));
.eq(Task::getTaskType, TaskType.IN.getCode())
.last("limit 1"));
// 生成入库任务
String saveTaskResult;
if (sameVehicleTempTask != null) {// 有相同的箱子任务
@ -301,7 +302,8 @@ public class TaskController {
// TODO 查询条件根据项目要求调整
Stock existStock = stockService.getOne(new LambdaQueryWrapper<Stock>()
.apply("goods_related -> '$.goodsId' = {0}", inTask.getGoodsRelated().getGoodsId())
.eq(Stock::getVehicleId, inTask.getVehicleId()));
.eq(Stock::getVehicleId, inTask.getVehicleId())
.last("limit 1"));
if (existStock != null) {
// 已有库存直接更新数量
existStock.getGoodsRelated().setRemainNum(existStock.getGoodsRelated().getRemainNum().add(inTask.getGoodsRelated().getOpNum()));
@ -859,7 +861,8 @@ public class TaskController {
}
// 查一下物料信息
Goods goodsInfo = goodsService.getOne(new LambdaQueryWrapper<Goods>()
.eq(Goods::getGoodsId, workQuery.getGoodsId()));
.eq(Goods::getGoodsId, workQuery.getGoodsId())
.last("limit 1"));
// 查找工作流
List<WorkFlow> workFlows = workFlowService.list(new LambdaQueryWrapper<WorkFlow>()
.eq(WorkFlow::getWorkStation, standId)
@ -1721,7 +1724,8 @@ public class TaskController {
.eq(StringUtils.isNotEmpty(callEmptyVehicleRequest.getVehicleType1()), Vehicle::getVehicleType, callEmptyVehicleRequest.getVehicleType1())
.eq(Vehicle::getIsEmpty, 1)
.eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode())
.orderByAsc(Vehicle::getLastInTime));
.orderByAsc(Vehicle::getLastInTime)
.last("limit 1"));
if (emptyVehicle != null) {// 有可用的空箱
// 创建一个空箱出库任务
Task emptyVehicleTask = new Task();

View File

@ -1,10 +1,7 @@
package com.wms.entity.app.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.wms.entity.app.dto.extend.StockDetailInfo;
import com.wms.utils.excel.ExcelExport;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;

View File

@ -0,0 +1,59 @@
package com.wms.entity.app.request;
import cn.hutool.core.bean.BeanUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.wms.entity.table.UploadRecord;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
* 上传记录查询
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class UploadRecordQuery extends PageQuery {
/**
* 上传id
*/
@JsonProperty("upload_id")
private String uploadId;
/**
* 文件id
*/
@JsonProperty("file_id")
private String fileId;
/**
* 文件名
*/
@JsonProperty("file_name")
private String fileName;
/**
* 文件类型
*/
@JsonProperty("file_type")
private String fileType;
/**
* 上传时间
*/
@JsonProperty("uploadTime")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime uploadTime;
/**
* 上传人员
*/
@JsonProperty("uploadUser")
private String uploadUser;
/**
* 将UploadRecordQuery转化为UploadRecordPo
* @return UploadRecordPo结果
*/
public UploadRecord toUploadRecordPO() {
return BeanUtil.copyProperties(this, UploadRecord.class);
}
}

View File

@ -0,0 +1,21 @@
package com.wms.entity.app.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* 文件Vo
*/
@Data
public class FileVo {
@JsonProperty("fileId")
private String fileId;
@JsonProperty("name")
private String name;
@JsonProperty("type")
private String type;
@JsonProperty("size")
private String size;
@JsonProperty("userName")
private String userName;
}

View File

@ -1,14 +1,127 @@
package com.wms.entity.app.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.wms.entity.table.Stock;
import com.wms.utils.excel.vo.StockExcelVo;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class StockVo {
/**
* 库存编号
*/
@JsonProperty("stockId")
private String stockId;
/**
* 库位ID
*/
@JsonProperty("locationId")
private String locationId;
/**
* 托盘号
*/
@JsonProperty("vehicleId")
private String vehicleId;
/**
* 重量
*/
@JsonProperty("weight")
private BigDecimal weight;
/**
* 库存状态
* 正常出库中锁定
*/
@JsonProperty("stockStatus")
private Integer stockStatus;
/**
* 创建时间
*/
@JsonProperty("createTime")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
/**
* 最后更新时间
*/
@JsonProperty("lastUpdateTime")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastUpdateTime;
/**
* 最后更新用户
*/
@JsonProperty("lastUpdateUser")
private String lastUpdateUser;
/**
* 是否盘点
*/
@JsonProperty("isInventory")
private Integer isInventory;
/**
* 盘点任务号 盘点出库和盘点入库同样
*/
@JsonProperty("inventoryTaskId")
private String inventoryTaskId;
/**
* 呆滞天数
*/
@JsonProperty("noUseDays")
private Integer noUseDays;
/**
* 物料编号
*/
@JsonProperty("goodsId")
private String goodsId;
/**
* 物料名称
*/
@JsonProperty("goodsName")
private String goodsName;
/**
* 物料状态
*/
@JsonProperty("goodsStatus")
private Integer goodsStatus;
/**
* 剩余数量
*/
@JsonProperty("remainNum")
private BigDecimal remainNum;
/**
* 入库库存总数
*/
@JsonProperty("totalNum")
private BigDecimal totalNum;
/**
* 从数据库实体转换为excel对象
* @param stockPo 数据库实体
* @return excel对象
*/
public static StockExcelVo of(Stock stockPo) {
StockExcelVo stockExcelVo = new StockExcelVo();
stockExcelVo.setStockId(stockPo.getStockId());
stockExcelVo.setLocationId(stockPo.getLocationId());
stockExcelVo.setVehicleId(stockPo.getVehicleId());
stockExcelVo.setWeight(stockPo.getWeight());
stockExcelVo.setStockStatus(stockPo.getStockStatus());
stockExcelVo.setCreateTime(stockPo.getCreateTime());
stockExcelVo.setLastUpdateTime(stockPo.getLastUpdateTime());
stockExcelVo.setLastUpdateUser(stockPo.getLastUpdateUser());
stockExcelVo.setIsInventory(stockPo.getIsInventory());
stockExcelVo.setInventoryTaskId(stockPo.getInventoryTaskId());
stockExcelVo.setNoUseDays(stockPo.getNoUseDays());
stockExcelVo.setGoodsId(stockPo.getGoodsRelated().getGoodsId());
stockExcelVo.setGoodsName(stockPo.getGoodsRelated().getGoodsName());
stockExcelVo.setGoodsStatus(stockPo.getGoodsRelated().getGoodsStatus());
stockExcelVo.setRemainNum(stockPo.getGoodsRelated().getRemainNum());
stockExcelVo.setTotalNum(stockPo.getGoodsRelated().getTotalNum());
return stockExcelVo;
}
}

View File

@ -0,0 +1,49 @@
package com.wms.entity.app.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
* 上传记录Vo
*/
@Data
public class UploadRecordVo {
/**
* 上传id
*/
@JsonProperty("upload_id")
private String uploadId;
/**
* 文件id
*/
@JsonProperty("file_id")
private String fileId;
/**
* 文件名
*/
@JsonProperty("file_name")
private String fileName;
/**
* 文件类型
*/
@JsonProperty("file_type")
private String fileType;
/**
* 上传时间
*/
@JsonProperty("uploadTime")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime uploadTime;
/**
* 上传人员
*/
@JsonProperty("uploadUser")
private String uploadUser;
}

View File

@ -0,0 +1,28 @@
package com.wms.entity.table;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@TableName(value = "tbl_app_inventory_history", autoResultMap = true)
public class InventoryHistory {
@TableId("inventory_id")
private String inventoryId;
@TableField("goods_id")
private String goodsId;
@TableField("stock_num")
private BigDecimal stockNum;
@TableField("real_num")
private BigDecimal realNum;
@TableField("inventory_status")
private Integer inventoryStatus;
@TableField("inventory_user")
private String inventoryUser;
@TableField("inventory_date")
private LocalDateTime inventoryDate;
}

View File

@ -0,0 +1,57 @@
package com.wms.entity.table;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 盘点清单
*/
@Data
@TableName(value = "tbl_app_inventory_list", autoResultMap = true)
public class InventoryList {
/**
* 盘点id
*/
@TableId("inventory_id")
private String inventoryId;
/**
* 料号
*/
@TableField("goods_id")
private String goodsId;
/**
* 库存数量
*/
@TableField("stock_num")
private BigDecimal stockNum;
/**
* 实际数量
*/
@TableField("real_num")
private BigDecimal realNum;
/**
* 盘点状态
*/
@TableField("inventory_status")
private Integer inventoryStatus;
/**
* 盘点用户
*/
@TableField("inventory_user")
private String inventoryUser;
/**
* 盘点日期
*/
@TableField("inventory_date")
private LocalDateTime inventoryDate;
/**
* 清单id
*/
@TableField("list_id")
private String listId;
}

View File

@ -0,0 +1,46 @@
package com.wms.entity.table;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 上传历史
*/
@Data
@TableName(value = "tbl_app_upload_record", autoResultMap = true)
public class UploadRecord {
/**
* 上传id
*/
@TableId("upload_id")
private String uploadId;
/**
* 文件id
*/
@TableField("file_id")
private String fileId;
/**
* 文件名
*/
@TableField("file_name")
private String fileName;
/**
* 文件类型
*/
@TableField("file_type")
private String fileType;
/**
* 上传时间
*/
@TableField("upload_time")
private LocalDateTime uploadTime;
/**
* 上传人员
*/
@TableField("upload_user")
private String uploadUser;
}

View File

@ -1,14 +1,7 @@
package com.wms.entity.test;
import com.wms.utils.excel.ExcelExport;
import com.wms.utils.excel.ExcelImport;
public class ExcelTest {
@ExcelImport("库位")
@ExcelExport("库位")
private String locationId;
@ExcelImport("箱号")
@ExcelExport("箱号")
private String vehicleId;
public ExcelTest(){};

View File

@ -0,0 +1,12 @@
package com.wms.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wms.entity.table.InventoryHistory;
import org.apache.ibatis.annotations.Mapper;
/**
* 盘点清单历史记录Mapper
*/
@Mapper
public interface InventoryHistoryMapper extends BaseMapper<InventoryHistory> {
}

View File

@ -0,0 +1,12 @@
package com.wms.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wms.entity.table.InventoryList;
import org.apache.ibatis.annotations.Mapper;
/**
* 盘点清单Mapper
*/
@Mapper
public interface InventoryListMapper extends BaseMapper<InventoryList> {
}

View File

@ -0,0 +1,13 @@
package com.wms.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wms.entity.table.InventoryList;
import com.wms.entity.table.UploadRecord;
import org.apache.ibatis.annotations.Mapper;
/**
* 盘点清单Mapper
*/
@Mapper
public interface UploadRecordMapper extends BaseMapper<UploadRecord> {
}

View File

@ -0,0 +1,10 @@
package com.wms.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.wms.entity.table.InventoryHistory;
/**
* 盘点记录服务接口
*/
public interface InventoryHistoryService extends IService<InventoryHistory> {
}

View File

@ -0,0 +1,10 @@
package com.wms.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.wms.entity.table.InventoryList;
/**
* 盘点清单服务接口
*/
public interface InventoryListService extends IService<InventoryList> {
}

View File

@ -12,24 +12,24 @@ public interface TaskRecordService extends IService<TaskRecord> {
* @param query 查询参数
* @return 查询结果
*/
List<TaskRecordDto> selectInTaskRecord(TaskRecord query);
List<TaskRecord> selectInTaskRecord(TaskRecord query);
/**
* 查找出库任务记录
* @param query 查询参数
* @return 查询结果
*/
List<TaskRecordDto> selectOutTaskRecord(TaskRecord query);
List<TaskRecord> selectOutTaskRecord(TaskRecord query);
/**
* 查找盘点任务记录
* @param query 查询参数
* @return 查询结果
*/
List<TaskRecordDto> selectInventoryTaskRecord(TaskRecord query);
List<TaskRecord> selectInventoryTaskRecord(TaskRecord query);
/**
* 查找任务记录
* @param query 查询参数
* @return 查询结果
*/
List<TaskRecordDto> selectTaskRecord(TaskRecord query);
List<TaskRecord> selectTaskRecord(TaskRecord query);
}

View File

@ -0,0 +1,11 @@
package com.wms.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.wms.entity.table.InventoryList;
import com.wms.entity.table.UploadRecord;
/**
* 盘点清单服务接口
*/
public interface UploadRecordService extends IService<UploadRecord> {
}

View File

@ -7,7 +7,6 @@ import com.wms.constants.enums.*;
import com.wms.entity.app.ResponseEntity;
import com.wms.entity.app.wcs.WcsStandTaskRequest;
import com.wms.entity.app.wcs.WcsTaskRequest;
import com.wms.entity.table.OutsideVehicles;
import com.wms.entity.table.PickTask;
import com.wms.entity.table.Task;
import com.wms.entity.table.WmsLog;
@ -48,15 +47,21 @@ public class WmsJobServiceImplements implements IWmsJobService {
public void sendCommonTasks() throws Exception {
try {
String max_vehicle_nums = configMap.get(ConfigMapKeyEnum.MAX_VEHICLE_NUMS.getConfigKey());
if (StringUtils.isEmpty(max_vehicle_nums)) {
String max_wcs_accept_nums = configMap.get(ConfigMapKeyEnum.MAX_WCS_ACCEPT_NUMS.getConfigKey());
if (StringUtils.isEmpty(max_vehicle_nums) || StringUtils.isEmpty(max_wcs_accept_nums)) {
logger.error("配置未生成");
return;
}
int maxVehicleNums = Integer.parseInt(max_vehicle_nums);
int maxWcsAcceptNums = Integer.parseInt(max_wcs_accept_nums);
List<String> outsideVehicles = outsideVehiclesService.selectDistinctVehicles();
if (outsideVehicles == null || outsideVehicles.size() >= maxVehicleNums) {
if (outsideVehicles == null) {
outsideVehicles = Collections.emptyList();
} else {
if (outsideVehicles.size() >= maxVehicleNums) {
return;
}
}
int remainVehicleNums = maxVehicleNums - outsideVehicles.size();
// 检索任务表---新建未下发的任务
@ -69,7 +74,7 @@ public class WmsJobServiceImplements implements IWmsJobService {
List<String> taskGroupIds = new ArrayList<>();
if (!allTasks.isEmpty()) {
for (Task task : allTasks) {
if (taskGroupIds.size() >= remainVehicleNums) {
if (taskGroupIds.size() >= remainVehicleNums || taskGroupIds.size() >= maxWcsAcceptNums) {
break;
}
if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务

View File

@ -253,7 +253,8 @@ public class WmsTaskServiceImplements implements IWmsTaskService {
} else if (Objects.equals(stock.getStockStatus(), StockStatus.OUT.getCode())) {
// 查询到当前当前载具对应的任务并同步
Task sameVehicleTask = taskService.getOne(new LambdaQueryWrapper<Task>()
.eq(Task::getVehicleId, stock.getVehicleId()));
.eq(Task::getVehicleId, stock.getVehicleId())
.last("limit 1"));
// 创建出库任务
Task vehicleOutTask = new Task();
vehicleOutTask.setTaskId(generateId("CK_"));

View File

@ -169,6 +169,7 @@ public class WorkServiceImplements implements IWorkService {
workDoingStations.add(workStation);
}
try {
// TODO 分配任务
// 查找当前站台未开始的工作流
List<WorkFlow> currentWorkFlowList = workFlowService.list(new LambdaQueryWrapper<WorkFlow>()
.eq(WorkFlow::getWorkStation, workStation)

View File

@ -0,0 +1,17 @@
package com.wms.service.serviceImplements;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wms.entity.table.InventoryHistory;
import com.wms.mapper.InventoryHistoryMapper;
import com.wms.service.InventoryHistoryService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 盘点记录服务实现
*/
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class InventoryHistoryServiceImpl extends ServiceImpl<InventoryHistoryMapper, InventoryHistory> implements InventoryHistoryService {
}

View File

@ -0,0 +1,17 @@
package com.wms.service.serviceImplements;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wms.entity.table.InventoryList;
import com.wms.mapper.InventoryListMapper;
import com.wms.service.InventoryListService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 盘点清单服务实现
*/
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class InventoryListServiceImpl extends ServiceImpl<InventoryListMapper, InventoryList> implements InventoryListService {
}

View File

@ -22,25 +22,25 @@ public class TaskRecordServiceImplements extends ServiceImpl<TaskRecordMapper, T
private final TaskRecordMapper taskRecordMapper;
@Override
public List<TaskRecordDto> selectInTaskRecord(TaskRecord query) {
public List<TaskRecord> selectInTaskRecord(TaskRecord query) {
query.setTaskType(TaskType.IN.getCode());// 设置为入库
return selectTaskRecord(query);
}
@Override
public List<TaskRecordDto> selectOutTaskRecord(TaskRecord query) {
public List<TaskRecord> selectOutTaskRecord(TaskRecord query) {
query.setTaskType(TaskType.OUT.getCode());// 设置为出库
return selectTaskRecord(query);
}
@Override
public List<TaskRecordDto> selectInventoryTaskRecord(TaskRecord query) {
public List<TaskRecord> selectInventoryTaskRecord(TaskRecord query) {
query.setTaskType(TaskType.INVENTORY.getCode());// 设置为盘点
return selectTaskRecord(query);
}
@Override
public List<TaskRecordDto> selectTaskRecord(TaskRecord query) {
public List<TaskRecord> selectTaskRecord(TaskRecord query) {
LambdaQueryWrapper<TaskRecord> queryWrapper = new LambdaQueryWrapper<TaskRecord>()
.eq(TaskRecord::getTaskType, query.getTaskType())
.like(StringUtils.isNotEmpty(query.getVehicleId()), TaskRecord::getVehicleId, query.getVehicleId());
@ -51,6 +51,6 @@ public class TaskRecordServiceImplements extends ServiceImpl<TaskRecordMapper, T
// 物料名称/描述
.apply(StringUtils.isNotEmpty(query.getGoodsRelated().getGoodsName()), "goods_related ->> '$.goodsName' like concat('%', {0}, '%')", query.getGoodsRelated().getGoodsName());
}
return BeanUtil.copyToList(super.list(queryWrapper), TaskRecordDto.class);
return super.list(queryWrapper);
}
}

View File

@ -0,0 +1,20 @@
package com.wms.service.serviceImplements;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wms.entity.table.InventoryList;
import com.wms.entity.table.UploadRecord;
import com.wms.mapper.InventoryListMapper;
import com.wms.mapper.UploadRecordMapper;
import com.wms.service.InventoryListService;
import com.wms.service.UploadRecordService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 盘点清单服务实现
*/
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class UploadRecordServiceImpl extends ServiceImpl<UploadRecordMapper, UploadRecord> implements UploadRecordService {
}

View File

@ -1,8 +1,6 @@
package com.wms.utils;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.util.Base64;
import java.util.Map;

View File

@ -1,71 +0,0 @@
package com.wms.utils.excel;
import java.util.LinkedHashMap;
public class ExcelClassField {
/** 字段名称 */
private String fieldName;
/** 表头名称 */
private String name;
/** 映射关系 */
private LinkedHashMap<String, String> kvMap;
/** 示例值 */
private Object example;
/** 排序 */
private int sort;
/** 是否为注解字段0-否1-是 */
private int hasAnnotation;
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LinkedHashMap<String, String> getKvMap() {
return kvMap;
}
public void setKvMap(LinkedHashMap<String, String> kvMap) {
this.kvMap = kvMap;
}
public Object getExample() {
return example;
}
public void setExample(Object example) {
this.example = example;
}
public int getSort() {
return sort;
}
public void setSort(int sort) {
this.sort = sort;
}
public int getHasAnnotation() {
return hasAnnotation;
}
public void setHasAnnotation(int hasAnnotation) {
this.hasAnnotation = hasAnnotation;
}
}

View File

@ -1,22 +0,0 @@
package com.wms.utils.excel;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelExport {
/** 字段名称 */
String value();
/** 导出排序先后: 数字越小越靠前默认按Java类字段顺序导出 */
int sort() default 0;
/** 导出映射格式如0-未知;1-男;2-女 */
String kv() default "";
/** 导出模板示例值(有值的话,直接取该值,不做映射) */
String example() default "";
}

View File

@ -1,25 +0,0 @@
package com.wms.utils.excel;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelImport {
/** 字段名称 */
String value();
/** 导出映射格式如0-未知;1-男;2-女 */
String kv() default "";
/** 是否为必填字段(默认为非必填) */
boolean required() default false;
/** 最大长度默认255 */
int maxLength() default 255;
/** 导入唯一性验证(多个字段则取联合验证) */
boolean unique() default false;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
package com.wms.utils.excel.convertor;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
/**
* excel任务状态转换
*/
public class TaskStatusConvertor implements Converter<Integer> {
@Override
public Class<?> supportJavaTypeKey() {
return Integer.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
/**
* 这里是读的时候会调用
*
* @return 转换后的任务状态
*/
@Override
public Integer convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
String cellValue = cellData.getStringValue();
return switch (cellValue.trim()) {
case "重复入库" -> -2;
case "暂存任务" -> -1;
case "任务新建,待下发" -> 0;
case "任务已下发" -> 1;
case "任务开始执行" -> 2;
case "出库完成" -> 3;
case "环线运输" -> 4;
case "拣选中" -> 8;
case "盘点中" -> 9;
case "任务完成" -> 100;
case "任务取消" -> 998;
default -> 999;
};
}
/**
* 这里是写的时候会调用
*
* @return 转换后的任务状态
*/
@Override
public WriteCellData<?> convertToExcelData(WriteConverterContext<Integer> context) {
Integer value = context.getValue();
if (value == -2) {
return new WriteCellData<>("重复入库");
} else if (value == -1) {
return new WriteCellData<>("暂存任务");
} else if (value == 0) {
return new WriteCellData<>("任务新建,待下发");
} else if (value == 1) {
return new WriteCellData<>("任务已下发");
} else if (value == 2) {
return new WriteCellData<>("任务开始执行");
} else if (value == 3) {
return new WriteCellData<>("出库完成");
} else if (value == 4) {
return new WriteCellData<>("环线运输");
} else if (value == 8) {
return new WriteCellData<>("拣选中");
} else if (value == 9) {
return new WriteCellData<>("盘点中");
} else if (value == 100) {
return new WriteCellData<>("任务完成");
} else if (value == 998) {
return new WriteCellData<>("任务取消");
} else {
return new WriteCellData<>("任务异常");
}
}
}

View File

@ -0,0 +1,62 @@
package com.wms.utils.excel.convertor;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
/**
* excel任务类型转换
*/
public class TaskTypeConvertor implements Converter<Integer> {
@Override
public Class<?> supportJavaTypeKey() {
return Integer.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
/**
* 这里是读的时候会调用
*
* @return 转换后的任务类型
*/
@Override
public Integer convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
String cellValue = cellData.getStringValue();
return switch (cellValue.trim()) {
case "入库" -> 1;
case "出库" -> 2;
case "盘点" -> 10;
case "移库" -> 9;
default -> -1;
};
}
/**
* 这里是写的时候会调用
*
* @return 转换后的任务类型
*/
@Override
public WriteCellData<?> convertToExcelData(WriteConverterContext<Integer> context) {
Integer value = context.getValue();
if (value == 1) {
return new WriteCellData<>("入库");
} else if (value == 2) {
return new WriteCellData<>("出库");
} else if (value == 10) {
return new WriteCellData<>("盘点");
} else if (value == 9) {
return new WriteCellData<>("移库");
} else {
return new WriteCellData<>("未知");
}
}
}

View File

@ -0,0 +1,107 @@
package com.wms.utils.excel.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wms.entity.app.dto.extend.StockDetailInfo;
import com.wms.entity.table.Stock;
import com.wms.service.StockService;
import com.wms.utils.excel.vo.StockExcelVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import static com.wms.utils.StringUtils.convertJsonString;
import static com.wms.utils.WmsUtils.generateId;
/**
* 上传库存监听
*/
public class UploadStocksListener implements ReadListener<StockExcelVo> {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 100;
private List<StockExcelVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
private final StockService stockService;
public UploadStocksListener(StockService stockService) {
this.stockService = stockService;
}
@Override
public void onException(Exception exception, AnalysisContext context) throws Exception {
logger.error("处理数据发生异常:{}", convertJsonString(exception));
ReadListener.super.onException(exception, context);
}
/**
* 这个每一条数据解析都会来调用
*
* @param stockExcelVo one row value. It is same as {@link AnalysisContext#readRowHolder()}
* @param analysisContext context
*/
@Override
public void invoke(StockExcelVo stockExcelVo, AnalysisContext analysisContext) {
cachedDataList.add(stockExcelVo);
// 达到BATCH_COUNT了需要去存储一次数据库防止数据几万条数据在内存容易OOM
if (cachedDataList.size() >= BATCH_COUNT) {
logger.info("已经导入{}条数据,开始存储数据库!", cachedDataList.size());
saveData();
// 存储完成清理 list
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
}
/**
* 所有数据解析完成了 都会来调用
*
* @param analysisContext context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();
}
/**
* 存储数据
*/
private void saveData() {
List<Stock> stockList = new ArrayList<>();
for (StockExcelVo stockExcelVo : cachedDataList) {
if (stockService.exists(new LambdaQueryWrapper<Stock>()
.eq(Stock::getVehicleId, stockExcelVo.getVehicleId())
.eq(Stock::getLocationId, stockExcelVo.getLocationId())
.apply("goods_related ->> '$.goodsId' = {0}", stockExcelVo.getGoodsId()))) {
// 重复库存
cachedDataList.remove(stockExcelVo);
continue;
}
Stock stock = new Stock();
stock.setStockId(generateId("ST_"));
stock.setLocationId(stockExcelVo.getLocationId());
stock.setVehicleId(stockExcelVo.getVehicleId());
stock.setWeight(stockExcelVo.getWeight());
stock.setStockStatus(stockExcelVo.getStockStatus());
stock.setCreateTime(stockExcelVo.getCreateTime());
stock.setLastUpdateTime(stockExcelVo.getLastUpdateTime());
stock.setLastUpdateUser(stockExcelVo.getLastUpdateUser());
stock.setIsInventory(stockExcelVo.getIsInventory());
stock.setInventoryTaskId(stockExcelVo.getInventoryTaskId());
stock.setNoUseDays(stockExcelVo.getNoUseDays());
// 物料信息
StockDetailInfo goodsRelated = new StockDetailInfo();
goodsRelated.setGoodsId(stockExcelVo.getGoodsId());
goodsRelated.setGoodsName(stockExcelVo.getGoodsName());
goodsRelated.setGoodsStatus(stockExcelVo.getGoodsStatus());
goodsRelated.setTotalNum(stockExcelVo.getTotalNum());
goodsRelated.setRemainNum(stockExcelVo.getRemainNum());
stock.setGoodsRelated(goodsRelated);
stockList.add(stock);
}
stockService.saveBatch(stockList);
}
}

View File

@ -0,0 +1,31 @@
package com.wms.utils.excel.style;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
public class ExcelContentStyle {
//设置excel内容格式
public static HorizontalCellStyleStrategy getContentStyle(){
//内容策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
//设置样式
contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
contentWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
contentWriteCellStyle.setBorderLeft(BorderStyle.THIN); //设置左边框;
contentWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
contentWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
contentWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
contentWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
contentWriteCellStyle.setTopBorderColor((short) 0); ///设置顶边框颜色;
contentWriteCellStyle.setWrapped(true); //设置自动换行;
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 水平居中
contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
return new HorizontalCellStyleStrategy(contentWriteCellStyle, contentWriteCellStyle);
}
}

View File

@ -0,0 +1,74 @@
package com.wms.utils.excel.vo;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.annotation.ExcelProperty;
import com.wms.entity.table.Location;
import lombok.Data;
@Data
public class LocationExcelVo {
/**
* 库位编号
*/
@ExcelProperty("库位")
private String locationId;
/**
* 库区编号
*/
@ExcelProperty("库区")
private Integer areaId;
/**
* 设备编号
*/
@ExcelProperty("设备号")
private Integer equipmentId;
/**
* 库位类型
*/
@ExcelProperty("库位类型")
private Integer locationType;
/**
*
*/
@ExcelProperty("")
private Integer wRow;
/**
*
*/
@ExcelProperty("")
private Integer wCol;
/**
*
*/
@ExcelProperty("")
private Integer wLayer;
/**
* 深度
*/
@ExcelProperty("深度")
private Integer wDepth;
/**
* 是否锁定
*/
@ExcelProperty("锁定")
private Integer isLock;
/**
* 库位状态
*/
@ExcelProperty("状态")
private Integer locationStatus;
/**
* 载具号
*/
@ExcelProperty("料箱号")
private String vehicleId;
/**
* 从数据库实体转换为excel对象
* @param locationPo 数据库实体
* @return excel对象
*/
public static LocationExcelVo of(Location locationPo) {
return BeanUtil.copyProperties(locationPo, LocationExcelVo.class);
}
}

View File

@ -0,0 +1,122 @@
package com.wms.utils.excel.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.wms.entity.table.Stock;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class StockExcelVo {
/**
* 库存编号
*/
@ExcelProperty("库存编号")
private String stockId;
/**
* 库位ID
*/
@ExcelProperty("库位")
private String locationId;
/**
* 托盘号
*/
@ExcelProperty("箱号")
private String vehicleId;
/**
* 重量
*/
@ExcelProperty("重量")
private BigDecimal weight;
/**
* 库存状态
* 正常出库中锁定
*/
@ExcelProperty("库存状态")
private Integer stockStatus;
/**
* 创建时间
*/
@ExcelProperty("入库时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
/**
* 最后更新时间
*/
@ExcelProperty("最近使用时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastUpdateTime;
/**
* 最后更新用户
*/
@ExcelProperty("最近更新用户")
private String lastUpdateUser;
/**
* 是否盘点
*/
@ExcelProperty("是否盘点")
private Integer isInventory;
/**
* 盘点任务号 盘点出库和盘点入库同样
*/
@ExcelProperty("盘点任务号")
private String inventoryTaskId;
/**
* 呆滞天数
*/
@ExcelProperty("未使用天数")
private Integer noUseDays;
/**
* 物料编号
*/
@ExcelProperty("料号")
private String goodsId;
/**
* 物料名称
*/
@ExcelProperty("物料描述")
private String goodsName;
/**
* 物料状态
*/
@ExcelProperty("物料状态")
private Integer goodsStatus;
/**
* 剩余数量
*/
@ExcelProperty("剩余数量")
private BigDecimal remainNum;
/**
* 入库库存总数
*/
@ExcelProperty("入库数量")
private BigDecimal totalNum;
/**
* 从数据库实体转换为excel对象
* @param stockPo 数据库实体
* @return excel对象
*/
public static StockExcelVo of(Stock stockPo) {
StockExcelVo stockExcelVo = new StockExcelVo();
stockExcelVo.setStockId(stockPo.getStockId());
stockExcelVo.setLocationId(stockPo.getLocationId());
stockExcelVo.setVehicleId(stockPo.getVehicleId());
stockExcelVo.setWeight(stockPo.getWeight());
stockExcelVo.setStockStatus(stockPo.getStockStatus());
stockExcelVo.setCreateTime(stockPo.getCreateTime());
stockExcelVo.setLastUpdateTime(stockPo.getLastUpdateTime());
stockExcelVo.setLastUpdateUser(stockPo.getLastUpdateUser());
stockExcelVo.setIsInventory(stockPo.getIsInventory());
stockExcelVo.setInventoryTaskId(stockPo.getInventoryTaskId());
stockExcelVo.setNoUseDays(stockPo.getNoUseDays());
stockExcelVo.setGoodsId(stockPo.getGoodsRelated().getGoodsId());
stockExcelVo.setGoodsName(stockPo.getGoodsRelated().getGoodsName());
stockExcelVo.setGoodsStatus(stockPo.getGoodsRelated().getGoodsStatus());
stockExcelVo.setRemainNum(stockPo.getGoodsRelated().getRemainNum());
stockExcelVo.setTotalNum(stockPo.getGoodsRelated().getTotalNum());
return stockExcelVo;
}
}

View File

@ -0,0 +1,151 @@
package com.wms.utils.excel.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.wms.entity.table.Stock;
import com.wms.entity.table.TaskRecord;
import com.wms.utils.excel.convertor.TaskStatusConvertor;
import com.wms.utils.excel.convertor.TaskTypeConvertor;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 任务记录Excel对象
*/
@Data
public class TaskRecordExcelVo {
/**
* 任务号
*/
@ExcelProperty("任务id")
private String taskId;
/**
* 任务类型
*/
@ExcelProperty(value = "任务类型", converter = TaskTypeConvertor.class)
private Integer taskType;
/**
* 任务状态
*/
@ExcelProperty(value = "任务类型", converter = TaskStatusConvertor.class)
private Integer taskStatus;
/**
* 起点
*/
@ExcelProperty("起点")
private String origin;
/**
* 终点
*/
@ExcelProperty("终点")
private String destination;
/**
* 任务优先级
*/
@ExcelProperty("优先级")
private Integer taskPriority;
/**
* 任务组
*/
@ExcelProperty("任务组")
private String taskGroup;
/**
* 载具号
*/
@ExcelProperty("料箱号")
private String vehicleId;
/**
* 重量
*/
@ExcelProperty("重量")
private BigDecimal weight;
/**
* 载具尺寸
*/
@ExcelProperty("载具尺寸")
private Integer vehicleSize;
/**
* 创建时间
*/
@ExcelProperty("创建时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
/**
* 完成时间
*/
@ExcelProperty("完成时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private LocalDateTime finishTime;
/**
* 用户名
*/
@ExcelProperty("用户名")
private String userName;
/**
* 物料编号
*/
@ExcelProperty("物料编号")
private String goodsId;
/**
* 物料名称
*/
@ExcelProperty("物料描述")
private String goodsName;
/**
* 操作数量
*/
@ExcelProperty("操作数量")
private BigDecimal opNum;
/**
* 原库存剩余数量
*/
@ExcelProperty("库存数量")
private BigDecimal originNum;
/**
* 前置任务号
*/
@ExcelProperty("前置任务")
private String preTask;
/**
* 是否拣选
*/
@ExcelProperty("是否拣选")
private Integer isPicking;
/**
* 拣选站台
*/
@ExcelProperty("拣选站台")
private String pickStand;
/**
* 从数据库实体转换为excel对象
* @param recordPo 数据库实体
* @return excel对象
*/
public static TaskRecordExcelVo of(TaskRecord recordPo) {
TaskRecordExcelVo recordExcelVo = new TaskRecordExcelVo();
recordExcelVo.setTaskId(recordPo.getTaskId());
recordExcelVo.setTaskType(recordPo.getTaskType());
recordExcelVo.setTaskStatus(recordPo.getTaskStatus());
recordExcelVo.setOrigin(recordPo.getOrigin());
recordExcelVo.setDestination(recordPo.getDestination());
recordExcelVo.setTaskPriority(recordPo.getTaskPriority());
recordExcelVo.setTaskGroup(recordPo.getTaskGroup());
recordExcelVo.setVehicleId(recordPo.getVehicleId());
recordExcelVo.setWeight(recordPo.getWeight());
recordExcelVo.setVehicleSize(recordPo.getVehicleSize());
recordExcelVo.setCreateTime(recordPo.getCreateTime());
recordExcelVo.setFinishTime(recordPo.getFinishTime());
recordExcelVo.setUserName(recordPo.getUserName());
recordExcelVo.setGoodsId(recordPo.getGoodsRelated().getGoodsId());
recordExcelVo.setGoodsName(recordPo.getGoodsRelated().getGoodsName());
recordExcelVo.setOpNum(recordPo.getGoodsRelated().getOpNum());
recordExcelVo.setOriginNum(recordPo.getGoodsRelated().getOriginNum());
recordExcelVo.setPreTask(recordPo.getPreTask());
recordExcelVo.setIsPicking(recordPo.getIsPicking());
recordExcelVo.setPickStand(recordPo.getPickStand());
return recordExcelVo;
}
}

View File

@ -0,0 +1,48 @@
package com.wms.utils.excel.vo;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.wms.entity.table.Vehicle;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class VehicleExcelVo {
/**
* 载具编号
*/
@ExcelProperty("箱号")
private String vehicleId;
/**
* 当前所在位置
*/
@ExcelProperty("库位")
private String currentLocation;
/**
* 载具状态
*/
@ExcelProperty("料箱状态")
private Integer vehicleStatus;
/**
* 是否是空箱
*/
@ExcelProperty("是否空箱")
private Integer isEmpty;
/**
* 上次入库时间
*/
@ExcelProperty("上次入库时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastInTime;
/**
* 从数据库实体转换为excel对象
* @param vehiclePo 数据库实体
* @return excel对象
*/
public static VehicleExcelVo of(Vehicle vehiclePo) {
return BeanUtil.copyProperties(vehiclePo, VehicleExcelVo.class);
}
}

View File

@ -30,6 +30,11 @@ spring:
driver-class-name: com.mysql.cj.jdbc.Driver
profiles:
active: online
servlet:
multipart:
max-file-size: 100MB #设置允许单个文件上传的大小
max-request-size: 1000MB #设置允许上传的总的文件的大小
server:
# 服务端配置
port: 12315

View File

@ -0,0 +1,6 @@
<?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.wms.mapper.InventoryHistoryMapper">
</mapper>

View File

@ -0,0 +1,6 @@
<?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.wms.mapper.InventoryListMapper">
</mapper>

View File

@ -0,0 +1,6 @@
<?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.wms.mapper.UploadRecordMapper">
</mapper>