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 wayPoint;
/** 货位相对于路径方向 */ /** 货位相对于路径方向 */
private String locDirection; private String locDirection;
/** 楼层数据 */
private String catalogCode;
/** 位置编码 */ /** 位置编码 */
private String rack; 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 ledgerRemark;
/** 托盘条码 */ /** 托盘条码 */
private String lpn; private String lpn;
/** 改变前库存位置 */ /** 库存改变数量 */
private String locCodeBefore; private Integer qtyChange;
/** 改变前堆叠层号从0开始 */ /** 入库占用改变数量 */
private Integer layerIndexBefore; private Integer qtyInChange;
/** 改变前库存数量 */ /** 出库占用改变数量 */
private Integer qtyBefore; private Integer qtyOutChange;
/** 改变前入库占用数量 */
private Integer qtyInBefore;
/** 改变前出库占用数量 */
private Integer qtyOutBefore;
/** 改变后堆叠层号从0开始 */ /** 改变后堆叠层号从0开始 */
private Integer layerIndex; 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 wayPoint = createString("wayPoint");
/** 货位相对于路径方向 */ /** 货位相对于路径方向 */
public final StringPath locDirection = createString("locDirection"); public final StringPath locDirection = createString("locDirection");
/** 楼层数据 */
public final StringPath catalogCode = createString("catalogCode");
/** 位置编码 */ /** 位置编码 */
public final StringPath rack = createString("rack"); 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(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(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(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(catalogCode, ColumnMetadata.named("catalog_code").withIndex(6).ofType(Types.VARCHAR).withSize(50));
addMetadata(bay, ColumnMetadata.named("bay").withIndex(7).ofType(Types.INTEGER).withSize(10)); addMetadata(rack, ColumnMetadata.named("rack").withIndex(7).ofType(Types.VARCHAR).withSize(50));
addMetadata(level, ColumnMetadata.named("level").withIndex(8).ofType(Types.INTEGER).withSize(10)); addMetadata(bay, ColumnMetadata.named("bay").withIndex(8).ofType(Types.INTEGER).withSize(10));
addMetadata(cell, ColumnMetadata.named("cell").withIndex(9).ofType(Types.INTEGER).withSize(10)); addMetadata(level, ColumnMetadata.named("level").withIndex(9).ofType(Types.INTEGER).withSize(10));
addMetadata(isLock, ColumnMetadata.named("is_lock").withIndex(10).ofType(Types.TINYINT).withSize(3)); addMetadata(cell, ColumnMetadata.named("cell").withIndex(10).ofType(Types.INTEGER).withSize(10));
addMetadata(isFrozen, ColumnMetadata.named("is_frozen").withIndex(11).ofType(Types.TINYINT).withSize(3)); addMetadata(isLock, ColumnMetadata.named("is_lock").withIndex(11).ofType(Types.TINYINT).withSize(3));
addMetadata(createAt, ColumnMetadata.named("create_at").withIndex(12).ofType(Types.TIMESTAMP)); addMetadata(isFrozen, ColumnMetadata.named("is_frozen").withIndex(12).ofType(Types.TINYINT).withSize(3));
addMetadata(createBy, ColumnMetadata.named("create_by").withIndex(13).ofType(Types.VARCHAR).withSize(50)); addMetadata(createAt, ColumnMetadata.named("create_at").withIndex(13).ofType(Types.TIMESTAMP));
addMetadata(updateAt, ColumnMetadata.named("update_at").withIndex(14).ofType(Types.TIMESTAMP)); addMetadata(createBy, ColumnMetadata.named("create_by").withIndex(14).ofType(Types.VARCHAR).withSize(50));
addMetadata(updateBy, ColumnMetadata.named("update_by").withIndex(15).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; 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.LccModelFloor;
import com.yvan.workbench.model.entity.LccModelWorld; import com.yvan.workbench.model.entity.LccModelWorld;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.clever.core.Assert; import org.clever.core.Assert;
import org.clever.core.Conv; import org.clever.core.Conv;
import org.clever.core.id.SnowFlake; 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.mapper.JacksonMapper;
import org.clever.core.model.request.QueryByPage; import org.clever.core.model.request.QueryByPage;
import org.clever.core.model.request.page.Page; 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.RequestParam;
import org.clever.web.mvc.annotation.Transactional; import org.clever.web.mvc.annotation.Transactional;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map; 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.QLccModelFloor.lccModelFloor;
import static com.yvan.workbench.model.query.QLccModelWorld.lccModelWorld; import static com.yvan.workbench.model.query.QLccModelWorld.lccModelWorld;
@ -27,60 +36,60 @@ public class LccModelManager {
private static String getOtherData(String projectUuid, String projectLabel) { private static String getOtherData(String projectUuid, String projectLabel) {
return StringUtils.trim(String.format(""" return StringUtils.trim(String.format("""
{ {
"project_uuid": "%s", "project_uuid": "%s",
"project_label": "%s", "project_label": "%s",
"project_version": 0, "project_version": 0,
"server": "demo", "server": "demo",
"Tool": { "Tool": {
"Group": [], "Group": [],
"GlobalVariables": [], "GlobalVariables": [],
"UserCommand": [], "UserCommand": [],
"Dashboard": [], "Dashboard": [],
"DataTable": [], "DataTable": [],
"Trigger": [ "Trigger": [
{ {
"name": "OnOpen", "name": "OnOpen",
"fn": "" "fn": ""
}, },
{ {
"name": "OnReset", "name": "OnReset",
"fn": "" "fn": ""
}, },
{ {
"name": "OnStart", "name": "OnStart",
"fn": "" "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
}
}, },
"elevator": [], {
"wall": [], "name": "OnStop",
"pillar": [] "fn": ""
}""".stripIndent(), projectUuid, projectLabel)); }
],
"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() { public static Page<LccModelWorld> projectList() {
return QueryDslUtils.queryByPage( return QueryDslUtils.queryByPage(
QUERY_DSL.selectFrom(lccModelWorld), QUERY_DSL.selectFrom(lccModelWorld),
QueryByPage.getCurrent() QueryByPage.getCurrent()
); );
} }
@ -89,24 +98,24 @@ public class LccModelManager {
Assert.isNotBlank(project.getProjectUuid(), "项目编号必填"); Assert.isNotBlank(project.getProjectUuid(), "项目编号必填");
Assert.isNotBlank(project.getProjectLabel(), "项目标题必填"); Assert.isNotBlank(project.getProjectLabel(), "项目标题必填");
Assert.isTrue( 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.setProjectVersion(1L);
project.setId(SnowFlake.SNOW_FLAKE.nextId()); project.setId(SnowFlake.SNOW_FLAKE.nextId());
project.setDirectoryData(""" project.setDirectoryData("""
[ [
{
"label": "仓库楼层",
"items": [
{ {
"label": "仓库楼层", "catalogCode": "f1",
"items": [ "label": "一楼 (f1)"
{
"catalogCode": "f1",
"label": "一楼 (f1)"
}
]
} }
] ]
""".stripIndent()); }
]
""".stripIndent());
project.setOtherData(getOtherData(project.getProjectUuid(), project.getProjectLabel())); project.setOtherData(getOtherData(project.getProjectUuid(), project.getProjectLabel()));
QUERY_DSL.insert(lccModelWorld).populate(project).execute(); QUERY_DSL.insert(lccModelWorld).populate(project).execute();
return QUERY_DSL.selectFrom(lccModelWorld).where(lccModelWorld.id.eq(project.getId())).fetchOne(); 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) { public static R<?> addOrUpdateWorld(@RequestBody LccModelWorld params) {
Assert.isNotBlank(params.getProjectUuid(), "项目编号必填"); Assert.isNotBlank(params.getProjectUuid(), "项目编号必填");
long count = QUERY_DSL.selectFrom(lccModelWorld) long count = QUERY_DSL.selectFrom(lccModelWorld)
.where(lccModelWorld.projectUuid.eq(params.getProjectUuid())) .where(lccModelWorld.projectUuid.eq(params.getProjectUuid()))
.where(lccModelWorld.projectVersion.eq(1L)) .where(lccModelWorld.projectVersion.eq(1L))
.fetchCount(); .fetchCount();
if (count >= 1) { if (count >= 1) {
QUERY_DSL.update(lccModelWorld) QUERY_DSL.update(lccModelWorld)
.set(lccModelWorld.otherData, params.getOtherData()) .set(lccModelWorld.otherData, params.getOtherData())
.set(lccModelWorld.directoryData, params.getDirectoryData()) .set(lccModelWorld.directoryData, params.getDirectoryData())
.where(lccModelWorld.projectUuid.eq(params.getProjectUuid())) .where(lccModelWorld.projectUuid.eq(params.getProjectUuid()))
.where(lccModelWorld.projectVersion.eq(1L)) .where(lccModelWorld.projectVersion.eq(1L))
.execute(); .execute();
} else { } else {
//noinspection unchecked //noinspection unchecked
Map<String, Object> map = JacksonMapper.getInstance().fromJson(params.getOtherData(), Map.class); 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 catalogCode = Conv.asString(params.get("catalogCode"));
String project_uuid = Conv.asString(params.get("project_uuid")); String project_uuid = Conv.asString(params.get("project_uuid"));
return QUERY_DSL.selectFrom(lccModelFloor) return QUERY_DSL.selectFrom(lccModelFloor)
.where(lccModelFloor.projectUuid.eq(project_uuid)) .where(lccModelFloor.projectUuid.eq(project_uuid))
.where(lccModelFloor.catalogCode.eq(catalogCode)) .where(lccModelFloor.catalogCode.eq(catalogCode))
.orderBy(lccModelFloor.projectVersion.desc()) .orderBy(lccModelFloor.projectVersion.desc())
.fetchFirst(); .fetchFirst();
} }
@Transactional @Transactional
public static R<?> addOrUpdateFloor(@RequestBody LccModelFloor params) { public static R<?> addOrUpdateFloor(@RequestBody LccModelFloor params) {
Assert.isNotBlank(params.getProjectUuid(), "项目编号必填"); Assert.isNotBlank(params.getProjectUuid(), "项目编号必填");
Assert.isNotBlank(params.getCatalogCode(), "楼层编号必填"); Assert.isNotBlank(params.getCatalogCode(), "楼层编号必填");
Assert.notNull(params.getEnvId(), "环境编号必填");
Assert.isNotBlank(params.getItems(), "楼层数据必填"); Assert.isNotBlank(params.getItems(), "楼层数据必填");
if (params.getEnvId() == null || params.getEnvId() <= 0) {
throw new RuntimeException("环境编号必填");
}
long count = QUERY_DSL.selectFrom(lccModelFloor) long count = QUERY_DSL.selectFrom(lccModelFloor)
.where(lccModelFloor.projectUuid.eq(params.getProjectUuid())) .where(lccModelFloor.projectUuid.eq(params.getProjectUuid()))
.where(lccModelFloor.projectVersion.eq(1L)) .where(lccModelFloor.envId.eq(params.getEnvId()))
.where(lccModelFloor.catalogCode.eq(params.getCatalogCode())) .where(lccModelFloor.catalogCode.eq(params.getCatalogCode()))
.fetchCount(); .fetchCount();
if (count >= 1) { if (count >= 1) {
QUERY_DSL.update(lccModelFloor) QUERY_DSL.update(lccModelFloor)
.set(lccModelFloor.items, params.getItems()) .set(lccModelFloor.items, params.getItems())
.where(lccModelFloor.projectUuid.eq(params.getProjectUuid())) .set(lccModelFloor.projectVersion, lccModelFloor.projectVersion.add(1L))
.where(lccModelFloor.projectVersion.eq(1L)) .where(lccModelFloor.projectUuid.eq(params.getProjectUuid()))
.where(lccModelFloor.catalogCode.eq(params.getCatalogCode())) .where(lccModelFloor.envId.eq(params.getEnvId()))
.execute(); .where(lccModelFloor.catalogCode.eq(params.getCatalogCode()))
.execute();
} else { } else {
params.setId(SnowFlake.SNOW_FLAKE.nextId()); params.setId(SnowFlake.SNOW_FLAKE.nextId());
params.setProjectVersion(1L); params.setProjectVersion(1L);
// params.setCreateBy(); // params.setCreateBy();
QUERY_DSL.insert(lccModelFloor).populate(params).execute(); QUERY_DSL.insert(lccModelFloor).populate(params).execute();
} }
batchSaveBasLocation(params);
return R.success(); 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 String projectUuid;
/** 项目版本 */ /** 项目版本 */
private Long projectVersion; private Long projectVersion;
/** 环境ID */
private Long envId;
/** 楼层编号 */ /** 楼层编号 */
private String catalogCode; private String catalogCode;
/** 楼层数据 */ /** 楼层数据 */

Loading…
Cancel
Save