Browse Source

保存数据时,生成货架信息

master
修宁 6 months ago
parent
commit
564356d3dc
  1. 2
      servo/src/main/java/com/galaxis/rcs/common/entity/LccBasLocation.java
  2. 16
      servo/src/main/java/com/galaxis/rcs/common/entity/LccInvLedger.java
  3. 23
      servo/src/main/java/com/galaxis/rcs/common/query/QLccBasLocation.java
  4. 368
      servo/src/main/java/com/yvan/workbench/controller/LccModelManager.java
  5. 2
      servo/src/main/java/com/yvan/workbench/model/entity/LccModelFloor.java

2
servo/src/main/java/com/galaxis/rcs/common/entity/LccBasLocation.java

@ -19,6 +19,8 @@ public class LccBasLocation implements Serializable {
private String wayPoint;
/** 货位相对于路径方向 */
private String locDirection;
/** 楼层数据 */
private String catalogCode;
/** 位置编码 */
private String rack;
/** 货架列 */

16
servo/src/main/java/com/galaxis/rcs/common/entity/LccInvLedger.java

@ -21,16 +21,12 @@ public class LccInvLedger implements Serializable {
private String ledgerRemark;
/** 托盘条码 */
private String lpn;
/** 改变前库存位置 */
private String locCodeBefore;
/** 改变前堆叠层号从0开始 */
private Integer layerIndexBefore;
/** 改变前库存数量 */
private Integer qtyBefore;
/** 改变前入库占用数量 */
private Integer qtyInBefore;
/** 改变前出库占用数量 */
private Integer qtyOutBefore;
/** 库存改变数量 */
private Integer qtyChange;
/** 入库占用改变数量 */
private Integer qtyInChange;
/** 出库占用改变数量 */
private Integer qtyOutChange;
/** 改变后堆叠层号从0开始 */
private Integer layerIndex;
/** 改变前库存位置 */

23
servo/src/main/java/com/galaxis/rcs/common/query/QLccBasLocation.java

@ -26,6 +26,8 @@ public class QLccBasLocation extends RelationalPathBase<LccBasLocation> {
public final StringPath wayPoint = createString("wayPoint");
/** 货位相对于路径方向 */
public final StringPath locDirection = createString("locDirection");
/** 楼层数据 */
public final StringPath catalogCode = createString("catalogCode");
/** 位置编码 */
public final StringPath rack = createString("rack");
/** 货架列 */
@ -78,15 +80,16 @@ public class QLccBasLocation extends RelationalPathBase<LccBasLocation> {
addMetadata(locType, ColumnMetadata.named("loc_type").withIndex(3).ofType(Types.VARCHAR).withSize(20));
addMetadata(wayPoint, ColumnMetadata.named("way_point").withIndex(4).ofType(Types.VARCHAR).withSize(50));
addMetadata(locDirection, ColumnMetadata.named("loc_direction").withIndex(5).ofType(Types.VARCHAR).withSize(10));
addMetadata(rack, ColumnMetadata.named("rack").withIndex(6).ofType(Types.VARCHAR).withSize(50));
addMetadata(bay, ColumnMetadata.named("bay").withIndex(7).ofType(Types.INTEGER).withSize(10));
addMetadata(level, ColumnMetadata.named("level").withIndex(8).ofType(Types.INTEGER).withSize(10));
addMetadata(cell, ColumnMetadata.named("cell").withIndex(9).ofType(Types.INTEGER).withSize(10));
addMetadata(isLock, ColumnMetadata.named("is_lock").withIndex(10).ofType(Types.TINYINT).withSize(3));
addMetadata(isFrozen, ColumnMetadata.named("is_frozen").withIndex(11).ofType(Types.TINYINT).withSize(3));
addMetadata(createAt, ColumnMetadata.named("create_at").withIndex(12).ofType(Types.TIMESTAMP));
addMetadata(createBy, ColumnMetadata.named("create_by").withIndex(13).ofType(Types.VARCHAR).withSize(50));
addMetadata(updateAt, ColumnMetadata.named("update_at").withIndex(14).ofType(Types.TIMESTAMP));
addMetadata(updateBy, ColumnMetadata.named("update_by").withIndex(15).ofType(Types.VARCHAR).withSize(50));
addMetadata(catalogCode, ColumnMetadata.named("catalog_code").withIndex(6).ofType(Types.VARCHAR).withSize(50));
addMetadata(rack, ColumnMetadata.named("rack").withIndex(7).ofType(Types.VARCHAR).withSize(50));
addMetadata(bay, ColumnMetadata.named("bay").withIndex(8).ofType(Types.INTEGER).withSize(10));
addMetadata(level, ColumnMetadata.named("level").withIndex(9).ofType(Types.INTEGER).withSize(10));
addMetadata(cell, ColumnMetadata.named("cell").withIndex(10).ofType(Types.INTEGER).withSize(10));
addMetadata(isLock, ColumnMetadata.named("is_lock").withIndex(11).ofType(Types.TINYINT).withSize(3));
addMetadata(isFrozen, ColumnMetadata.named("is_frozen").withIndex(12).ofType(Types.TINYINT).withSize(3));
addMetadata(createAt, ColumnMetadata.named("create_at").withIndex(13).ofType(Types.TIMESTAMP));
addMetadata(createBy, ColumnMetadata.named("create_by").withIndex(14).ofType(Types.VARCHAR).withSize(50));
addMetadata(updateAt, ColumnMetadata.named("update_at").withIndex(15).ofType(Types.TIMESTAMP));
addMetadata(updateBy, ColumnMetadata.named("update_by").withIndex(16).ofType(Types.VARCHAR).withSize(50));
}
}

368
servo/src/main/java/com/yvan/workbench/controller/LccModelManager.java

@ -1,11 +1,16 @@
package com.yvan.workbench.controller;
import com.galaxis.rcs.common.entity.LccBasLocation;
import com.galaxis.rcs.common.entity.StoreLocation;
import com.galaxis.rcs.ptr.JacksonUtils;
import com.yvan.workbench.model.entity.LccModelFloor;
import com.yvan.workbench.model.entity.LccModelWorld;
import org.apache.commons.lang3.StringUtils;
import org.clever.core.Assert;
import org.clever.core.Conv;
import org.clever.core.id.SnowFlake;
import org.clever.core.json.JsonArrayWrapper;
import org.clever.core.json.JsonWrapper;
import org.clever.core.mapper.JacksonMapper;
import org.clever.core.model.request.QueryByPage;
import org.clever.core.model.request.page.Page;
@ -17,8 +22,12 @@ import org.clever.web.mvc.annotation.RequestBody;
import org.clever.web.mvc.annotation.RequestParam;
import org.clever.web.mvc.annotation.Transactional;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.galaxis.rcs.common.query.QLccBasLocation.lccBasLocation;
import static com.yvan.workbench.model.query.QLccModelFloor.lccModelFloor;
import static com.yvan.workbench.model.query.QLccModelWorld.lccModelWorld;
@ -27,60 +36,60 @@ public class LccModelManager {
private static String getOtherData(String projectUuid, String projectLabel) {
return StringUtils.trim(String.format("""
{
"project_uuid": "%s",
"project_label": "%s",
"project_version": 0,
"server": "demo",
"Tool": {
"Group": [],
"GlobalVariables": [],
"UserCommand": [],
"Dashboard": [],
"DataTable": [],
"Trigger": [
{
"name": "OnOpen",
"fn": ""
},
{
"name": "OnReset",
"fn": ""
},
{
"name": "OnStart",
"fn": ""
},
{
"name": "OnStop",
"fn": ""
}
],
"gridHelper": {
"axesEnabled": true,
"axesSize": 5,
"axesColor": 14540253,
"axesWidth": 2,
"gridEnabled": true,
"gridSize": 1000,
"gridDivisions": 1000,
"gridColor": 14540253,
"gridOpacity": 1,
"backgroundColor": 16119285,
"snapEnabled": true,
"snapDistance": 0.25
}
{
"project_uuid": "%s",
"project_label": "%s",
"project_version": 0,
"server": "demo",
"Tool": {
"Group": [],
"GlobalVariables": [],
"UserCommand": [],
"Dashboard": [],
"DataTable": [],
"Trigger": [
{
"name": "OnOpen",
"fn": ""
},
{
"name": "OnReset",
"fn": ""
},
{
"name": "OnStart",
"fn": ""
},
"elevator": [],
"wall": [],
"pillar": []
}""".stripIndent(), projectUuid, projectLabel));
{
"name": "OnStop",
"fn": ""
}
],
"gridHelper": {
"axesEnabled": true,
"axesSize": 5,
"axesColor": 14540253,
"axesWidth": 2,
"gridEnabled": true,
"gridSize": 1000,
"gridDivisions": 1000,
"gridColor": 14540253,
"gridOpacity": 1,
"backgroundColor": 16119285,
"snapEnabled": true,
"snapDistance": 0.25
}
},
"elevator": [],
"wall": [],
"pillar": []
}""".stripIndent(), projectUuid, projectLabel));
}
public static Page<LccModelWorld> projectList() {
return QueryDslUtils.queryByPage(
QUERY_DSL.selectFrom(lccModelWorld),
QueryByPage.getCurrent()
QUERY_DSL.selectFrom(lccModelWorld),
QueryByPage.getCurrent()
);
}
@ -89,24 +98,24 @@ public class LccModelManager {
Assert.isNotBlank(project.getProjectUuid(), "项目编号必填");
Assert.isNotBlank(project.getProjectLabel(), "项目标题必填");
Assert.isTrue(
QUERY_DSL.selectFrom(lccModelWorld).where(lccModelWorld.projectUuid.eq(project.getProjectUuid())).fetchCount() <= 0,
"项目编号重复"
QUERY_DSL.selectFrom(lccModelWorld).where(lccModelWorld.projectUuid.eq(project.getProjectUuid())).fetchCount() <= 0,
"项目编号重复"
);
project.setProjectVersion(1L);
project.setId(SnowFlake.SNOW_FLAKE.nextId());
project.setDirectoryData("""
[
[
{
"label": "仓库楼层",
"items": [
{
"label": "仓库楼层",
"items": [
{
"catalogCode": "f1",
"label": "一楼 (f1)"
}
]
"catalogCode": "f1",
"label": "一楼 (f1)"
}
]
""".stripIndent());
}
]
""".stripIndent());
project.setOtherData(getOtherData(project.getProjectUuid(), project.getProjectLabel()));
QUERY_DSL.insert(lccModelWorld).populate(project).execute();
return QUERY_DSL.selectFrom(lccModelWorld).where(lccModelWorld.id.eq(project.getId())).fetchOne();
@ -116,16 +125,16 @@ public class LccModelManager {
public static R<?> addOrUpdateWorld(@RequestBody LccModelWorld params) {
Assert.isNotBlank(params.getProjectUuid(), "项目编号必填");
long count = QUERY_DSL.selectFrom(lccModelWorld)
.where(lccModelWorld.projectUuid.eq(params.getProjectUuid()))
.where(lccModelWorld.projectVersion.eq(1L))
.fetchCount();
.where(lccModelWorld.projectUuid.eq(params.getProjectUuid()))
.where(lccModelWorld.projectVersion.eq(1L))
.fetchCount();
if (count >= 1) {
QUERY_DSL.update(lccModelWorld)
.set(lccModelWorld.otherData, params.getOtherData())
.set(lccModelWorld.directoryData, params.getDirectoryData())
.where(lccModelWorld.projectUuid.eq(params.getProjectUuid()))
.where(lccModelWorld.projectVersion.eq(1L))
.execute();
.set(lccModelWorld.otherData, params.getOtherData())
.set(lccModelWorld.directoryData, params.getDirectoryData())
.where(lccModelWorld.projectUuid.eq(params.getProjectUuid()))
.where(lccModelWorld.projectVersion.eq(1L))
.execute();
} else {
//noinspection unchecked
Map<String, Object> map = JacksonMapper.getInstance().fromJson(params.getOtherData(), Map.class);
@ -143,35 +152,232 @@ public class LccModelManager {
String catalogCode = Conv.asString(params.get("catalogCode"));
String project_uuid = Conv.asString(params.get("project_uuid"));
return QUERY_DSL.selectFrom(lccModelFloor)
.where(lccModelFloor.projectUuid.eq(project_uuid))
.where(lccModelFloor.catalogCode.eq(catalogCode))
.orderBy(lccModelFloor.projectVersion.desc())
.fetchFirst();
.where(lccModelFloor.projectUuid.eq(project_uuid))
.where(lccModelFloor.catalogCode.eq(catalogCode))
.orderBy(lccModelFloor.projectVersion.desc())
.fetchFirst();
}
@Transactional
public static R<?> addOrUpdateFloor(@RequestBody LccModelFloor params) {
Assert.isNotBlank(params.getProjectUuid(), "项目编号必填");
Assert.isNotBlank(params.getCatalogCode(), "楼层编号必填");
Assert.notNull(params.getEnvId(), "环境编号必填");
Assert.isNotBlank(params.getItems(), "楼层数据必填");
if (params.getEnvId() == null || params.getEnvId() <= 0) {
throw new RuntimeException("环境编号必填");
}
long count = QUERY_DSL.selectFrom(lccModelFloor)
.where(lccModelFloor.projectUuid.eq(params.getProjectUuid()))
.where(lccModelFloor.projectVersion.eq(1L))
.where(lccModelFloor.catalogCode.eq(params.getCatalogCode()))
.fetchCount();
.where(lccModelFloor.projectUuid.eq(params.getProjectUuid()))
.where(lccModelFloor.envId.eq(params.getEnvId()))
.where(lccModelFloor.catalogCode.eq(params.getCatalogCode()))
.fetchCount();
if (count >= 1) {
QUERY_DSL.update(lccModelFloor)
.set(lccModelFloor.items, params.getItems())
.where(lccModelFloor.projectUuid.eq(params.getProjectUuid()))
.where(lccModelFloor.projectVersion.eq(1L))
.where(lccModelFloor.catalogCode.eq(params.getCatalogCode()))
.execute();
.set(lccModelFloor.items, params.getItems())
.set(lccModelFloor.projectVersion, lccModelFloor.projectVersion.add(1L))
.where(lccModelFloor.projectUuid.eq(params.getProjectUuid()))
.where(lccModelFloor.envId.eq(params.getEnvId()))
.where(lccModelFloor.catalogCode.eq(params.getCatalogCode()))
.execute();
} else {
params.setId(SnowFlake.SNOW_FLAKE.nextId());
params.setProjectVersion(1L);
// params.setCreateBy();
QUERY_DSL.insert(lccModelFloor).populate(params).execute();
}
batchSaveBasLocation(params);
return R.success();
}
/**
* 保存库存货位数据
*/
private static void batchSaveBasLocation(LccModelFloor params) {
// 删除旧的楼层数据
QUERY_DSL.delete(lccBasLocation)
.where(lccBasLocation.envId.eq(params.getEnvId()))
.where(lccBasLocation.catalogCode.eq(params.getCatalogCode()))
.execute();
// ================================== 从 params.items 中解析出货位数据
var items = JacksonUtils.parseList(params.getItems(), HashMap.class);
var storeMap = new HashMap<String, LccBasLocation>();
for (Map<String, Object> item : items) {
String type = Conv.asString(item.get("t"));
String id = Conv.asString(item.get("id"));
if ("rack".equals(type)) {
// 循环 bays / levelHeight 生成存储位
List<Map<String, Object>> bays = (List<Map<String, Object>>) (((Map) item.get("dt")).get("bays"));
int bayIndex = 0;
for (Map<String, Object> bay : bays) {
List levelHeight = (List) bay.get("levelHeight");
for (int level = 0; level < levelHeight.size(); level++) {
// 生成存储位
var storeLoc = new StoreLocation(id, bayIndex, level, 0);
LccBasLocation basLocation = new LccBasLocation();
storeMap.put(storeLoc.toString(), basLocation);
basLocation.setLocCode(storeLoc.toString());
basLocation.setLocType(type);
basLocation.setWayPoint("N/A");
basLocation.setLocDirection("N/A");
basLocation.setRack(id);
basLocation.setBay(bayIndex);
basLocation.setLevel(level);
}
bayIndex++;
}
} else if ("gstore".equals(type)) {
// 地堆存储位只有一个格子
var storeLoc = new StoreLocation(id, 0, 0, 0);
LccBasLocation basLocation = new LccBasLocation();
storeMap.put(storeLoc.toString(), basLocation);
basLocation.setLocCode(storeLoc.toString());
basLocation.setLocType(type);
basLocation.setWayPoint("N/A");
basLocation.setLocDirection("N/A");
basLocation.setRack(id);
basLocation.setBay(0);
basLocation.setLevel(0);
}
}
// ================================== 从 params.items 中解析出地标连接数据
for (Map<String, Object> item : items) {
String type = Conv.asString(item.get("t"));
String id = Conv.asString(item.get("id"));
if (!"way".equals(type)) {
continue;
}
// 解析 linkStore 数据
List<Map<String, Object>> linkStore = (List<Map<String, Object>>) (((Map) item.get("dt")).get("linkStore"));
if (linkStore != null) {
for (Map<String, Object> link : linkStore) {
String rackId = Conv.asString(link.get("item"));
int bay = Conv.asInteger(link.get("bay"));
int level = Conv.asInteger(link.get("level"));
int cell = Conv.asInteger(link.get("cell"));
String direction = Conv.asString(link.get("direction"));
// 生成存储位
var storeLoc = new StoreLocation(rackId, bay, level, cell);
LccBasLocation basLocation = storeMap.get(storeLoc.toString());
if (basLocation != null) {
basLocation.setWayPoint(id);
basLocation.setLocDirection(direction);
}
}
}
}
// 全部写进数据库
var action = QUERY_DSL.insert(lccBasLocation);
for (LccBasLocation basLocation : storeMap.values()) {
basLocation.setEnvId(params.getEnvId());
basLocation.setCatalogCode(params.getCatalogCode());
basLocation.setCell(0);
basLocation.setIsLock(0);
basLocation.setIsFrozen(0);
basLocation.setUpdateAt(new Date());
basLocation.setCreateAt(new Date());
basLocation.setCreateBy("yvan");
basLocation.setUpdateBy("yvan");
action.populate(basLocation).addBatch();
}
if (action.getBatchCount() > 0) {
action.execute();
}
// ================= JSON 结构
/*
提取货架信息
1. t=rack 的情况下读取 bays 数组并且枚举里面的 levelHeight 数组按数量生成 loc_code
{
"id": "rack1",
"t": "rack",
"v": true,
"dt": {
"bays": [
{ "levelHeight": [ 0.001, 1.21 ], },
{ "levelHeight": [ 0.001, 1.21 ], }
],
},
}
2. t=gstore 的情况下
{
"id": "105_105",
"t": "gstore",
}
提取路标信息
{
"id": "1_2",
"t": "way",
"dt": {
"linkStore": [
{
"item": "rack1",
"bay": 0, "level": 0, "cell": 0, "direction": "up"
},
{
"item": "rack1",
"bay": 0, "level": 1, "cell": 0, "direction": "up"
}
]
}
}
{
"id": "1_2",
"t": "way",
"dt": {
"linkStore": [
{
"item": "rack1",
"bay": 0, "level": 0, "cell": 0, "direction": "up"
},
{
"item": "rack1",
"bay": 0, "level": 1, "cell": 0, "direction": "up"
}
]
}
}
{
"id": "4_2",
"t": "way",
"dt": {
"linkStore": [
{
"item": "105_105",
"bay": 0,
"level": 0,
"cell": 0,
"direction": "down"
}
]
}
}
生成实体
LccBasLocation basLocation = new LccBasLocation();
basLocation.setEnvId(params.getEnvId());
basLocation.setCatalogCode(params.getCatalogCode());
basLocation.setLocType("t");
basLocation.setWayPoint("way.id");
basLocation.setLocDirection("linkStore.direction");
basLocation.setRack("rack.id");
basLocation.setBay("rack.id");
basLocation.setLevel("rack.id");
basLocation.setCell("rack.id");
basLocation.setIsLock(0);
basLocation.setIsFrozen(0);
*/
}
}

2
servo/src/main/java/com/yvan/workbench/model/entity/LccModelFloor.java

@ -15,6 +15,8 @@ public class LccModelFloor implements Serializable {
private String projectUuid;
/** 项目版本 */
private Long projectVersion;
/** 环境ID */
private Long envId;
/** 楼层编号 */
private String catalogCode;
/** 楼层数据 */

Loading…
Cancel
Save