代码暂存
This commit is contained in:
parent
0c95229de0
commit
c8ff345c9f
13
src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java
Normal file
13
src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.wms.constants.enums;
|
||||||
|
|
||||||
|
public enum ConfigMapKeyEnum {
|
||||||
|
MAX_WEIGHT("MAX_WEIGHT"),
|
||||||
|
URL_WCS_TASK("URL_WCS_TASK");
|
||||||
|
private final String configKey;
|
||||||
|
ConfigMapKeyEnum(String configKey) {
|
||||||
|
this.configKey = configKey;
|
||||||
|
}
|
||||||
|
public String getConfigKey() {
|
||||||
|
return configKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.wms.constants.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 入库验证信息枚举
|
||||||
|
*/
|
||||||
|
public enum TaskInValidationEnum {
|
||||||
|
OK(""),
|
||||||
|
NO_REQUEST_BODY("请求参数为空"),
|
||||||
|
NO_VEHICLE_ID("载具号为空"),
|
||||||
|
NO_IN_POINT("起点站台为空"),
|
||||||
|
ERROR_IN_POINT("错误的起点站台"),
|
||||||
|
NO_GOODS_ID("带料入库物料信息为空"),
|
||||||
|
ERROR_GOODS_ID("错误的物料编号"),
|
||||||
|
ERROR_GOODS_NUM("带料入库数量为空"),
|
||||||
|
NO_WEIGHT("重量信息为空"),
|
||||||
|
OVER_WEIGHT("超重");
|
||||||
|
|
||||||
|
private final String errorMessage;
|
||||||
|
TaskInValidationEnum(String errorMessage) {
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
}
|
||||||
|
public String getErrorMessage() {
|
||||||
|
return errorMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,8 +5,8 @@ import com.wms.constants.enums.*;
|
||||||
import com.wms.entity.app.ResponseEntity;
|
import com.wms.entity.app.ResponseEntity;
|
||||||
import com.wms.entity.app.dto.StockDto;
|
import com.wms.entity.app.dto.StockDto;
|
||||||
import com.wms.entity.app.dto.TaskRecordDto;
|
import com.wms.entity.app.dto.TaskRecordDto;
|
||||||
import com.wms.entity.app.query.StockQuery;
|
import com.wms.entity.app.request.StockQuery;
|
||||||
import com.wms.entity.app.query.TaskRecordQuery;
|
import com.wms.entity.app.request.TaskRecordQuery;
|
||||||
import com.wms.service.*;
|
import com.wms.service.*;
|
||||||
import com.wms.utils.excel.ExcelUtils;
|
import com.wms.utils.excel.ExcelUtils;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,11 @@ import com.alibaba.fastjson2.JSON;
|
||||||
import com.wms.annotation.MyLog;
|
import com.wms.annotation.MyLog;
|
||||||
import com.wms.constants.enums.*;
|
import com.wms.constants.enums.*;
|
||||||
import com.wms.entity.app.*;
|
import com.wms.entity.app.*;
|
||||||
|
import com.wms.entity.app.request.GoodsInRequest;
|
||||||
|
import com.wms.entity.app.request.TaskInRequest;
|
||||||
import com.wms.service.*;
|
import com.wms.service.*;
|
||||||
import com.wms.utils.HttpUtils;
|
import com.wms.utils.HttpUtils;
|
||||||
|
import com.wms.utils.StringUtils;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
@ -17,6 +20,11 @@ import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static com.wms.config.InitLocalConfig.configMap;
|
||||||
import static com.wms.utils.StringUtils.convertJsonString;
|
import static com.wms.utils.StringUtils.convertJsonString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -51,6 +59,10 @@ public class TaskController {
|
||||||
* 站台服务
|
* 站台服务
|
||||||
*/
|
*/
|
||||||
private final StandService standService;
|
private final StandService standService;
|
||||||
|
/**
|
||||||
|
* 物料服务
|
||||||
|
*/
|
||||||
|
private GoodsService goodsService;
|
||||||
/**
|
/**
|
||||||
* 请求头部信息
|
* 请求头部信息
|
||||||
*/
|
*/
|
||||||
|
|
@ -66,15 +78,30 @@ public class TaskController {
|
||||||
* @param taskInRequest 入库任务
|
* @param taskInRequest 入库任务
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@PostMapping("/sendGoodsInTask")
|
@PostMapping("/requestIn")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
|
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
|
||||||
@MyLog(logTitle = "入库请求", logMethod = "sendGoodsInTask")
|
@MyLog(logTitle = "入库请求", logMethod = "requestIn")
|
||||||
public String receiveGoodsInTask(@RequestBody TaskInRequestEntity taskInRequest) {
|
public String receiveTaskInRequest(@RequestBody TaskInRequest taskInRequest) {
|
||||||
logger.info("接收到入库请求:{},ip地址:{}", JSON.toJSONString(taskInRequest), HttpUtils.getIpAddr(servletRequest));
|
logger.info("接收到入库请求:{},ip地址:{}", JSON.toJSONString(taskInRequest), HttpUtils.getIpAddr(servletRequest));
|
||||||
// 创建响应信息
|
// 创建响应信息
|
||||||
ResponseEntity response = new ResponseEntity();
|
ResponseEntity response = new ResponseEntity();
|
||||||
try {
|
try {
|
||||||
|
// 验证入库请求
|
||||||
|
String validationInfo = validateTaskInRequest(taskInRequest);
|
||||||
|
if (!Objects.equals(validationInfo, TaskInValidationEnum.OK.getErrorMessage())) {
|
||||||
|
logger.error("入库请求验证错误!{}", validationInfo);
|
||||||
|
response.setCode(ResponseCode.ERROR.getCode());
|
||||||
|
response.setMessage("入库请求验证错误!" + validationInfo);
|
||||||
|
return convertJsonString(response);
|
||||||
|
}
|
||||||
|
// 请求可用库位---悲观锁
|
||||||
|
// 生成入库任务
|
||||||
|
if (taskInRequest.getGoodsList().isEmpty()) {// 空托入库
|
||||||
|
|
||||||
|
} else {// 带料入库
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
logger.info("接收入库请求成功!");
|
logger.info("接收入库请求成功!");
|
||||||
response.setCode(ResponseCode.OK.getCode());
|
response.setCode(ResponseCode.OK.getCode());
|
||||||
|
|
@ -90,4 +117,62 @@ public class TaskController {
|
||||||
return convertJsonString(response);
|
return convertJsonString(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证入库请求
|
||||||
|
* @param taskInRequest 入库请求
|
||||||
|
* @return 验证结果---空为验证通过,否则输出错误信息
|
||||||
|
*/
|
||||||
|
private String validateTaskInRequest(TaskInRequest taskInRequest) {
|
||||||
|
// 验证任务ID
|
||||||
|
if (taskInRequest == null) {
|
||||||
|
return TaskInValidationEnum.NO_REQUEST_BODY.getErrorMessage();
|
||||||
|
}
|
||||||
|
// 验证载具号
|
||||||
|
if (StringUtils.isEmpty(taskInRequest.getVehicleId())) {
|
||||||
|
return TaskInValidationEnum.NO_VEHICLE_ID.getErrorMessage();
|
||||||
|
}
|
||||||
|
// 验证载具号是否重复入库
|
||||||
|
|
||||||
|
// 验证重量
|
||||||
|
if (taskInRequest.getTotalWeight() == null) {
|
||||||
|
return TaskInValidationEnum.NO_WEIGHT.getErrorMessage();
|
||||||
|
}
|
||||||
|
BigDecimal max_weight = BigDecimal.valueOf(10000000);
|
||||||
|
try {
|
||||||
|
max_weight = new BigDecimal(configMap.get(ConfigMapKeyEnum.MAX_WEIGHT.getConfigKey()));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
logger.error("转换配置项---最大承重,发生错误");
|
||||||
|
}
|
||||||
|
if (taskInRequest.getTotalWeight().compareTo(max_weight) > 0) {
|
||||||
|
// 超重
|
||||||
|
return TaskInValidationEnum.OVER_WEIGHT.getErrorMessage();
|
||||||
|
}
|
||||||
|
// 验证起点
|
||||||
|
if (StringUtils.isEmpty(taskInRequest.getOriginPoint())) {
|
||||||
|
return TaskInValidationEnum.NO_IN_POINT.getErrorMessage();
|
||||||
|
} else {
|
||||||
|
if (standService.validateStand(taskInRequest.getOriginPoint(), 1)) {
|
||||||
|
return TaskInValidationEnum.ERROR_IN_POINT.getErrorMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 验证物料信息
|
||||||
|
if (!taskInRequest.getGoodsList().isEmpty()) {
|
||||||
|
for (GoodsInRequest goodsInRequest : taskInRequest.getGoodsList()) {
|
||||||
|
// 验证物料编号
|
||||||
|
if (StringUtils.isEmpty(goodsInRequest.getGoodsId())) {
|
||||||
|
return TaskInValidationEnum.NO_GOODS_ID.getErrorMessage();
|
||||||
|
} else {
|
||||||
|
if (!goodsService.validateGoodsId(goodsInRequest.getGoodsId())) {
|
||||||
|
return TaskInValidationEnum.ERROR_GOODS_ID.getErrorMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 验证数量
|
||||||
|
if (goodsInRequest.getGoodsNum() == null || goodsInRequest.getGoodsNum().compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
return TaskInValidationEnum.ERROR_GOODS_NUM.getErrorMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TaskInValidationEnum.OK.getErrorMessage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.wms.entity.app.dto;
|
package com.wms.entity.app.dto;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
@ -26,25 +28,17 @@ public class GoodsDto {
|
||||||
*/
|
*/
|
||||||
private String itemId;
|
private String itemId;
|
||||||
/**
|
/**
|
||||||
* 用户物料类型
|
* 物料分类
|
||||||
*/
|
*/
|
||||||
private String itemType;
|
private String goodsType;
|
||||||
/**
|
/**
|
||||||
* 库存类别
|
* 有效天数
|
||||||
*/
|
|
||||||
private String invCategory;
|
|
||||||
/**
|
|
||||||
* 存储天数
|
|
||||||
*/
|
*/
|
||||||
private Integer lifeDays;
|
private Integer lifeDays;
|
||||||
/**
|
/**
|
||||||
* 库存组织Id
|
* 仓储分类
|
||||||
*/
|
*/
|
||||||
private String organizationId;
|
private String invCategory;
|
||||||
/**
|
|
||||||
* 库存组织代码
|
|
||||||
*/
|
|
||||||
private String organizationCode;
|
|
||||||
/**
|
/**
|
||||||
* 最后更新日期
|
* 最后更新日期
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
28
src/main/java/com/wms/entity/app/request/GoodsInRequest.java
Normal file
28
src/main/java/com/wms/entity/app/request/GoodsInRequest.java
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.wms.entity.app.request;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ApiModel(value = "入库请求---物料数据")
|
||||||
|
public class GoodsInRequest {
|
||||||
|
@ApiModelProperty(value ="物料编号")
|
||||||
|
private String goodsId;
|
||||||
|
@ApiModelProperty(value ="物料名称")
|
||||||
|
private String goodsName;
|
||||||
|
@ApiModelProperty(value ="物料类型")
|
||||||
|
private String goodsType;
|
||||||
|
@ApiModelProperty(value ="物料单位")
|
||||||
|
private String goodsUnit;
|
||||||
|
@ApiModelProperty(value ="物料数量")
|
||||||
|
private BigDecimal goodsNum;
|
||||||
|
@ApiModelProperty(value ="物料描述")
|
||||||
|
private String goodsDesc;
|
||||||
|
@ApiModelProperty(value ="单个零件重量")
|
||||||
|
private BigDecimal singleWeight;
|
||||||
|
@ApiModelProperty(value ="零件总重量")
|
||||||
|
private BigDecimal weight;
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
package com.wms.entity.app.query;
|
package com.wms.entity.app.request;
|
||||||
|
|
||||||
import com.wms.entity.app.dto.extend.StockDetailInfo;
|
|
||||||
import com.wms.entity.table.Goods;
|
import com.wms.entity.table.Goods;
|
||||||
import com.wms.entity.table.Stock;
|
|
||||||
import com.wms.utils.StringUtils;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.wms.entity.app.query;
|
package com.wms.entity.app.request;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.wms.entity.app.query;
|
package com.wms.entity.app.request;
|
||||||
|
|
||||||
import com.wms.entity.app.dto.extend.StockDetailInfo;
|
import com.wms.entity.app.dto.extend.StockDetailInfo;
|
||||||
import com.wms.entity.table.Stock;
|
import com.wms.entity.table.Stock;
|
||||||
23
src/main/java/com/wms/entity/app/request/TaskInRequest.java
Normal file
23
src/main/java/com/wms/entity/app/request/TaskInRequest.java
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.wms.entity.app.request;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ApiModel(value = "入库请求")
|
||||||
|
public class TaskInRequest {
|
||||||
|
@ApiModelProperty(value ="载具号")
|
||||||
|
private String vehicleId;
|
||||||
|
@ApiModelProperty(value ="起点站台")
|
||||||
|
private String originPoint;
|
||||||
|
@ApiModelProperty(value ="称重")
|
||||||
|
private BigDecimal totalWeight;
|
||||||
|
@ApiModelProperty(value ="用户名")
|
||||||
|
private String userName;
|
||||||
|
@ApiModelProperty(value ="入库物料清单")
|
||||||
|
private List<GoodsInRequest> goodsList;
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.wms.entity.app.query;
|
package com.wms.entity.app.request;
|
||||||
|
|
||||||
import com.wms.entity.app.dto.extend.TaskDetailInfo;
|
import com.wms.entity.app.dto.extend.TaskDetailInfo;
|
||||||
import com.wms.entity.table.TaskRecord;
|
import com.wms.entity.table.TaskRecord;
|
||||||
|
|
@ -13,56 +13,49 @@ import java.util.Date;
|
||||||
@Data
|
@Data
|
||||||
@TableName("tbl_app_goods")
|
@TableName("tbl_app_goods")
|
||||||
public class Goods {
|
public class Goods {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 物料编号
|
* 物料编号
|
||||||
*/
|
*/
|
||||||
@TableId(value = "goods_id")
|
@TableId(value = "goods_id")
|
||||||
private String goodsId;
|
private String goodsId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 物料名称
|
* 物料名称
|
||||||
*/
|
*/
|
||||||
@TableField(value = "goods_name")
|
@TableField(value = "goods_name")
|
||||||
private String goodsName;
|
private String goodsName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单位
|
* 单位
|
||||||
*/
|
*/
|
||||||
|
@TableField(value = "goods_unit")
|
||||||
private String goodsUnit;
|
private String goodsUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 物料ID
|
* 物料ID
|
||||||
*/
|
*/
|
||||||
|
@TableField(value = "item_id")
|
||||||
private String itemId;
|
private String itemId;
|
||||||
/**
|
/**
|
||||||
* 用户物料类型
|
* 物料分类
|
||||||
*/
|
*/
|
||||||
private String itemType;
|
@TableField(value = "goods_type")
|
||||||
|
private String goodsType;
|
||||||
/**
|
/**
|
||||||
* 库存类别
|
* 有效天数
|
||||||
*/
|
|
||||||
private String invCategory;
|
|
||||||
/**
|
|
||||||
* 存储天数
|
|
||||||
*/
|
*/
|
||||||
|
@TableField(value = "life_days")
|
||||||
private Integer lifeDays;
|
private Integer lifeDays;
|
||||||
/**
|
/**
|
||||||
* 库存组织Id
|
* 仓储分类
|
||||||
*/
|
*/
|
||||||
private String organizationId;
|
@TableField(value = "inv_category")
|
||||||
/**
|
private String invCategory;
|
||||||
* 库存组织代码
|
|
||||||
*/
|
|
||||||
private String organizationCode;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最后更新日期
|
* 最后更新日期
|
||||||
*/
|
*/
|
||||||
|
@TableField(value = "last_update_time")
|
||||||
private Date lastUpdateTime;
|
private Date lastUpdateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最后更新用户
|
* 最后更新用户
|
||||||
*/
|
*/
|
||||||
|
@TableField(value = "last_update_user")
|
||||||
private String lastUpdateUser;
|
private String lastUpdateUser;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
package com.wms.mapper;
|
package com.wms.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.wms.entity.table.GoodsDto;
|
import com.wms.entity.table.Goods;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface GoodsMapper extends BaseMapper<GoodsDto> {
|
public interface GoodsMapper extends BaseMapper<Goods> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
package com.wms.mapper;
|
package com.wms.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.wms.entity.table.LocationDto;
|
import com.wms.entity.table.Location;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface LocationMapper extends BaseMapper<LocationDto> {
|
public interface LocationMapper extends BaseMapper<Location> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
package com.wms.mapper;
|
package com.wms.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.wms.entity.table.StandDto;
|
import com.wms.entity.table.Stand;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface StandMapper extends BaseMapper<StandDto> {
|
public interface StandMapper extends BaseMapper<Stand> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,16 @@
|
||||||
package com.wms.service;
|
package com.wms.service;
|
||||||
|
|
||||||
public interface GoodsService {
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.wms.entity.table.Goods;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物料服务
|
||||||
|
*/
|
||||||
|
public interface GoodsService extends IService<Goods> {
|
||||||
|
/**
|
||||||
|
* 验证物料编号是否正确
|
||||||
|
* @param goodsId 物料编号
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
boolean validateGoodsId(String goodsId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,19 @@
|
||||||
package com.wms.service;
|
package com.wms.service;
|
||||||
|
|
||||||
public interface LocationService {
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.wms.entity.table.Location;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 库位服务
|
||||||
|
*/
|
||||||
|
public interface LocationService extends IService<Location> {
|
||||||
|
/**
|
||||||
|
* 查找一个可用库位
|
||||||
|
* @param inPoint 入库站点
|
||||||
|
* @return 结果
|
||||||
|
* nextLocationId, preTaskId
|
||||||
|
*/
|
||||||
|
Map<String, String> getOneLocation(String inPoint);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,17 @@
|
||||||
package com.wms.service;
|
package com.wms.service;
|
||||||
|
|
||||||
/**
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
*
|
import com.wms.entity.table.Stand;
|
||||||
*/
|
|
||||||
public interface StandService {
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 站台服务
|
||||||
|
*/
|
||||||
|
public interface StandService extends IService<Stand> {
|
||||||
|
/**
|
||||||
|
* 验证站台正确性
|
||||||
|
* @param standId 待验证站台
|
||||||
|
* @param taskType 任务类型---1:入库,2:出库,3:拣选,4:盘点
|
||||||
|
* @return 验证结果
|
||||||
|
*/
|
||||||
|
boolean validateStand(String standId, Integer taskType);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
package com.wms.service;
|
package com.wms.service;
|
||||||
|
|
||||||
public interface TaskService{
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.wms.entity.table.Task;
|
||||||
|
|
||||||
|
public interface TaskService extends IService<Task> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package com.wms.service.serviceImplements;
|
package com.wms.service.serviceImplements;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.wms.entity.table.GoodsDto;
|
import com.wms.entity.table.Goods;
|
||||||
import com.wms.mapper.GoodsMapper;
|
import com.wms.mapper.GoodsMapper;
|
||||||
import com.wms.service.GoodsService;
|
import com.wms.service.GoodsService;
|
||||||
import com.wms.utils.StringUtils;
|
import com.wms.utils.StringUtils;
|
||||||
|
|
@ -10,48 +10,23 @@ import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
public class GoodsServiceImplements implements GoodsService {
|
public class GoodsServiceImplements extends ServiceImpl<GoodsMapper, Goods> implements GoodsService {
|
||||||
|
|
||||||
private final GoodsMapper goodsMapper;
|
private final GoodsMapper goodsMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证物料编号
|
||||||
|
* @param goodsId 物料编号
|
||||||
|
* @return 验证结果
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<GoodsDto> selGoods(GoodsDto goods){
|
public boolean validateGoodsId(String goodsId) {
|
||||||
return goodsMapper.selGoods(goods);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GoodsDto selGoodsByGoodsId(String goodsId) {
|
|
||||||
if (StringUtils.isEmpty(goodsId)) {
|
if (StringUtils.isEmpty(goodsId)) {
|
||||||
return null;
|
return false;
|
||||||
} else {
|
}
|
||||||
QueryWrapper<GoodsDto> queryWrapper = new QueryWrapper<>();
|
LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<Goods>()
|
||||||
queryWrapper.eq("goods_id", goodsId);
|
.eq(Goods::getGoodsId, goodsId);
|
||||||
return goodsMapper.selectOne(queryWrapper);
|
return goodsMapper.exists(queryWrapper);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int addGoods(GoodsDto goods) {
|
|
||||||
return goodsMapper.insert(goods);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int modifyGoods(GoodsDto goods) {
|
|
||||||
if (StringUtils.isEmpty(goods.getGoodsId())) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
UpdateWrapper<GoodsDto> updateWrapper = new UpdateWrapper<>();
|
|
||||||
updateWrapper.eq("goods_id", goods.getGoodsId());
|
|
||||||
goodsMapper.update(goods, updateWrapper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int deleteGoods(String goodsId) {
|
|
||||||
return goodsMapper.deleteById(goodsId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,144 @@
|
||||||
package com.wms.service.serviceImplements;
|
package com.wms.service.serviceImplements;
|
||||||
|
|
||||||
import com.wms.entity.table.LocationDto;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.wms.entity.table.Location;
|
||||||
|
import com.wms.entity.table.Stand;
|
||||||
|
import com.wms.entity.table.Task;
|
||||||
import com.wms.mapper.LocationMapper;
|
import com.wms.mapper.LocationMapper;
|
||||||
import com.wms.service.LocationService;
|
import com.wms.service.LocationService;
|
||||||
|
import com.wms.service.StandService;
|
||||||
|
import com.wms.service.TaskService;
|
||||||
|
import com.wms.utils.StringUtils;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
public class LocationServiceImplements implements LocationService {
|
public class LocationServiceImplements extends ServiceImpl<LocationMapper, Location> implements LocationService {
|
||||||
|
/**
|
||||||
|
* 库位
|
||||||
|
*/
|
||||||
private final LocationMapper locationMapper;
|
private final LocationMapper locationMapper;
|
||||||
|
/**
|
||||||
|
* 任务
|
||||||
|
*/
|
||||||
|
private final TaskService taskService;
|
||||||
|
/**
|
||||||
|
* 站台
|
||||||
|
*/
|
||||||
|
private final StandService standService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找一个可用库位
|
||||||
|
* @param inPoint 入库站点
|
||||||
|
* @return 结果
|
||||||
|
* nextLocationId, preTaskId
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<LocationDto> selLocations(LocationDto location) {
|
public Map<String, String> getOneLocation(String inPoint) {
|
||||||
return this.locationMapper.selLocations(location);
|
Map<String, String> resultMap = new HashMap<>();
|
||||||
|
// 查找对应站台
|
||||||
|
LambdaQueryWrapper<Location> locationQueryWrapper = new LambdaQueryWrapper<Location>()
|
||||||
|
.eq(Location::getAreaId, 1)
|
||||||
|
.eq(Location::getLocationStatus, 0)
|
||||||
|
.eq(Location::getLocationType, 1)
|
||||||
|
.eq(Location::getIsLock, 0);
|
||||||
|
// 添加对应设备的查询条件
|
||||||
|
int equipmentId = -1;
|
||||||
|
if (StringUtils.isNotEmpty(inPoint)) {
|
||||||
|
// 查询到入参的站台所对应的设备
|
||||||
|
LambdaQueryWrapper<Stand> standQueryWrapper = new LambdaQueryWrapper<Stand>()
|
||||||
|
.select(Stand::getStandId, Stand::getEquipmentId)
|
||||||
|
.eq(Stand::getStandId, inPoint);
|
||||||
|
Stand queryStand = standService.getOne(standQueryWrapper);
|
||||||
|
if (queryStand != null && queryStand.getEquipmentId() != null) {
|
||||||
|
equipmentId = queryStand.getEquipmentId();
|
||||||
|
locationQueryWrapper.eq(Location::getEquipmentId, queryStand.getEquipmentId());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// 指定设备号
|
||||||
|
if (equipmentId != -1) {
|
||||||
|
locationQueryWrapper.eq(Location::getEquipmentId, equipmentId);
|
||||||
|
locationQueryWrapper.orderByDesc(Location::getWDepth)
|
||||||
|
.orderByAsc(List.of(Location::getWCol, Location::getWLayer, Location::getWRow));
|
||||||
|
List<Location> availableLocations = locationMapper.selectList(locationQueryWrapper);
|
||||||
|
for (Location oneAvailableLocation : availableLocations) {
|
||||||
|
LambdaQueryWrapper<Location> haveTaskQueryWrapper = new LambdaQueryWrapper<Location>()
|
||||||
|
.select(Location::getLocationId)
|
||||||
|
.eq(Location::getWRow, oneAvailableLocation.getWRow())
|
||||||
|
.eq(Location::getWCol, oneAvailableLocation.getWCol())
|
||||||
|
.eq(Location::getWLayer, oneAvailableLocation.getWLayer());
|
||||||
|
List<Location> haveTaskLocations = locationMapper.selectList(haveTaskQueryWrapper);
|
||||||
|
// 判断当前排列层的库位是否有出库或者移库任务
|
||||||
|
for (Location havaTaskLocation : haveTaskLocations) {
|
||||||
|
LambdaQueryWrapper<Task> taskQueryWrapper = new LambdaQueryWrapper<Task>()
|
||||||
|
.select(Task::getTaskId)
|
||||||
|
.eq(Task::getOrigin, havaTaskLocation.getLocationId());
|
||||||
|
if (taskService.count(taskQueryWrapper) > 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 判断是否深度+1有入库任务
|
||||||
|
haveTaskQueryWrapper.clear();
|
||||||
|
LambdaQueryWrapper<Location> plusOneDepthLocationQueryWrapper = new LambdaQueryWrapper<Location>()
|
||||||
|
.select(Location::getLocationId)
|
||||||
|
.eq(Location::getWDepth, oneAvailableLocation.getWDepth() + 1)
|
||||||
|
.eq(Location::getWRow, oneAvailableLocation.getWRow())
|
||||||
|
.eq(Location::getWCol, oneAvailableLocation.getWCol())
|
||||||
|
.eq(Location::getWLayer, oneAvailableLocation.getWLayer());
|
||||||
|
Location plusOneDepthLocation = locationMapper.selectOne(plusOneDepthLocationQueryWrapper);
|
||||||
|
if (plusOneDepthLocation == null) {
|
||||||
|
resultMap.put("nextLocationId", oneAvailableLocation.getLocationId());
|
||||||
|
return resultMap;
|
||||||
|
} else {
|
||||||
|
LambdaQueryWrapper<Task> taskQueryWrapper = new LambdaQueryWrapper<Task>()
|
||||||
|
.select(Task::getTaskId)
|
||||||
|
.eq(Task::getDestination, plusOneDepthLocation.getLocationId());
|
||||||
|
Task plusOneDepthTask = taskService.getOne(taskQueryWrapper);
|
||||||
|
if (plusOneDepthTask != null) {
|
||||||
|
resultMap.put("nextLocationId", oneAvailableLocation.getLocationId());
|
||||||
|
resultMap.put("preTaskId", plusOneDepthTask.getTaskId());
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {// 未指定设备号
|
||||||
|
// TODO
|
||||||
|
// 选择最近未使用的设备
|
||||||
|
LambdaQueryWrapper<Stand> standQueryWrapper = new LambdaQueryWrapper<Stand>()
|
||||||
|
.select(Stand::getStandId, Stand::getEquipmentId)
|
||||||
|
.eq(Stand::getStandStatus, 0)
|
||||||
|
.eq(Stand::getIsLock, 0)
|
||||||
|
.eq(Stand::getStandType, 3)
|
||||||
|
.orderByAsc(Stand::getLastUseTime);
|
||||||
|
Stand queryStand = standService.getOne(standQueryWrapper);
|
||||||
|
if (queryStand != null && queryStand.getEquipmentId() != null) {
|
||||||
|
locationQueryWrapper.eq(Location::getEquipmentId, queryStand.getEquipmentId());
|
||||||
|
} else {
|
||||||
|
locationQueryWrapper.eq(Location::getEquipmentId, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
locationQueryWrapper.orderByDesc(Location::getWDepth)
|
||||||
|
.orderByAsc(List.of(Location::getWCol, Location::getWLayer, Location::getWRow));
|
||||||
|
|
||||||
@Override
|
Location oneAvailableLocation = locationMapper.selectOne(locationQueryWrapper);
|
||||||
public List<LocationDto> selNextLocation(LocationDto location) {
|
if (oneAvailableLocation != null) {
|
||||||
return locationMapper.selNextLocation(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
} else {
|
||||||
public int addLocation(LocationDto location) {
|
|
||||||
return locationMapper.addLocation(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int modifyLocation(LocationDto location) {
|
|
||||||
return this.locationMapper.modifyLocation(location);
|
|
||||||
}
|
}
|
||||||
|
// 查找低一个深度的库位
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<LocationDto> selLocationsWithNum(int equipmentId, int needLocationNum) {
|
|
||||||
return locationMapper.selLocationsWithNum(equipmentId, needLocationNum);
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,48 @@
|
||||||
package com.wms.service.serviceImplements;
|
package com.wms.service.serviceImplements;
|
||||||
|
|
||||||
import com.wms.entity.table.StandDto;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.wms.entity.table.Stand;
|
||||||
import com.wms.mapper.StandMapper;
|
import com.wms.mapper.StandMapper;
|
||||||
import com.wms.service.StandService;
|
import com.wms.service.StandService;
|
||||||
|
import com.wms.utils.StringUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class StandServiceImplements implements StandService {
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
|
public class StandServiceImplements extends ServiceImpl<StandMapper, Stand> implements StandService {
|
||||||
private final StandMapper standMapper;
|
private final StandMapper standMapper;
|
||||||
|
|
||||||
@Autowired
|
/**
|
||||||
public StandServiceImplements(StandMapper standMapper) {
|
* 验证站台正确性
|
||||||
this.standMapper = standMapper;
|
* @param standId 待验证站台
|
||||||
|
* @param taskType 任务类型---1:入库,2:出库,3:拣选,4:盘点
|
||||||
|
* @return 验证结果
|
||||||
|
*/
|
||||||
|
public boolean validateStand(String standId, Integer taskType) {
|
||||||
|
if (StringUtils.isEmpty(standId) || taskType == null) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
LambdaQueryWrapper<Stand> lambdaQueryWrapper = new LambdaQueryWrapper<Stand>()
|
||||||
@Override
|
.eq(Stand::getStandId, standId)
|
||||||
public List<StandDto> selStands(StandDto stand) {
|
.eq(Stand::getStandStatus, 0)// 是否可用
|
||||||
return this.standMapper.selStands(stand);
|
.eq(Stand::getIsLock, 0);// 是否锁定
|
||||||
|
if (taskType == 1) {// 入库
|
||||||
|
lambdaQueryWrapper.eq(Stand::getAllowIn, 1);// 入库
|
||||||
|
} else if (taskType == 2) {// 出库
|
||||||
|
lambdaQueryWrapper.eq(Stand::getAllowOut, 1);// 出库
|
||||||
|
} else if (taskType == 4) {// 盘点
|
||||||
|
lambdaQueryWrapper.eq(Stand::getAllowIn, 1);// 入库
|
||||||
|
lambdaQueryWrapper.eq(Stand::getAllowOut, 1);// 出库
|
||||||
|
} else if (taskType == 3) {// 拣选
|
||||||
|
lambdaQueryWrapper.eq(Stand::getStandType, 2);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return standMapper.exists(lambdaQueryWrapper);
|
||||||
@Override
|
|
||||||
public StandDto selStandById(String standId) {
|
|
||||||
return this.standMapper.selStandById(standId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int addStand(StandDto stand) {
|
|
||||||
return this.standMapper.addStand(stand);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int modifyStand(StandDto stand) {
|
|
||||||
return this.standMapper.modifyStand(stand);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int deleteStand(StandDto stand) {
|
|
||||||
return this.standMapper.deleteStand(stand);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,16 @@
|
||||||
package com.wms.service.serviceImplements;
|
package com.wms.service.serviceImplements;
|
||||||
|
|
||||||
import com.wms.entity.table.TaskDto;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.wms.entity.table.Task;
|
||||||
import com.wms.mapper.TaskMapper;
|
import com.wms.mapper.TaskMapper;
|
||||||
import com.wms.service.TaskService;
|
import com.wms.service.TaskService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class TaskServiceImplements implements TaskService {
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
|
public class TaskServiceImplements extends ServiceImpl<TaskMapper, Task> implements TaskService {
|
||||||
|
|
||||||
private final TaskMapper taskMapper;
|
private final TaskMapper taskMapper;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public TaskServiceImplements(TaskMapper taskMapper) {
|
|
||||||
this.taskMapper = taskMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<TaskDto> selTasks(TaskDto task) {
|
|
||||||
return taskMapper.selTasks(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int addTask(TaskDto task) {
|
|
||||||
return taskMapper.addTask(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int executeTask(TaskDto task) {
|
|
||||||
return taskMapper.executeTask(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int deleteTask(String taskId) {
|
|
||||||
return taskMapper.deleteTask(taskId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,12 @@ spring:
|
||||||
datasource:
|
datasource:
|
||||||
# 主库
|
# 主库
|
||||||
master:
|
master:
|
||||||
# 本地环境
|
|
||||||
# url: jdbc:mysql://localhost:3306/wms_xizhou?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
|
|
||||||
# username: developer
|
|
||||||
# password: developer
|
|
||||||
# 宝开服务器--外网
|
# 宝开服务器--外网
|
||||||
url: jdbc:mysql://112.4.208.194:3001/wms_kate_xuzhou?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
|
url: jdbc:mysql://112.4.208.194:3001/wms_miniload_bk7?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
|
||||||
username: coder
|
username: coder
|
||||||
password: coder
|
password: coder
|
||||||
# 宝开服务器--内网
|
# 宝开服务器--内网
|
||||||
# url: jdbc:mysql://192.168.3.254:3306/wms_kate_xuzhou?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
|
# url: jdbc:mysql://192.168.3.254:3306/wms_miniload_bk7?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
|
||||||
# username: coder
|
# username: coder
|
||||||
# password: coder
|
# password: coder
|
||||||
# 上线环境
|
# 上线环境
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user