35 changed files with 1207 additions and 859 deletions
@ -0,0 +1,37 @@ |
|||||
|
package com.yvan.logisticsEnv; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
@Data |
||||
|
public class EnvConfig implements Serializable { |
||||
|
|
||||
|
private MqttConfig mqtt; |
||||
|
|
||||
|
private MysqlConfig mysql; |
||||
|
|
||||
|
private RedisConfig redis; |
||||
|
|
||||
|
@Data |
||||
|
public static class MqttConfig { |
||||
|
private String brokerUrl; |
||||
|
private String username; |
||||
|
private String password; |
||||
|
private String websocket; |
||||
|
} |
||||
|
|
||||
|
@Data |
||||
|
public static class MysqlConfig { |
||||
|
private String jdbcUrl; |
||||
|
private String username; |
||||
|
private String password; |
||||
|
} |
||||
|
|
||||
|
@Data |
||||
|
public static class RedisConfig { |
||||
|
private String host; |
||||
|
private int port; |
||||
|
private String password; |
||||
|
} |
||||
|
} |
||||
@ -1,18 +0,0 @@ |
|||||
package com.yvan.logisticsEnv; |
|
||||
|
|
||||
import lombok.Data; |
|
||||
|
|
||||
import java.io.Serializable; |
|
||||
|
|
||||
@Data |
|
||||
public class EnvPayload implements Serializable { |
|
||||
|
|
||||
private MqttConfig mqtt; |
|
||||
|
|
||||
@Data |
|
||||
public static class MqttConfig { |
|
||||
private String brokerUrl; |
|
||||
private String username; |
|
||||
private String password; |
|
||||
} |
|
||||
} |
|
||||
@ -1,29 +0,0 @@ |
|||||
package com.yvan.logisticsEnv; |
|
||||
|
|
||||
import lombok.Getter; |
|
||||
import lombok.Setter; |
|
||||
|
|
||||
/** |
|
||||
* 环境启动参数 |
|
||||
*/ |
|
||||
@Getter |
|
||||
@Setter |
|
||||
public class EnvStartParam { |
|
||||
|
|
||||
public String clientId; |
|
||||
|
|
||||
/** |
|
||||
* 是否虚拟仿真环境 |
|
||||
*/ |
|
||||
private boolean isVirtual; |
|
||||
|
|
||||
/** |
|
||||
* 时间倍速(仿真环境专用) |
|
||||
*/ |
|
||||
private Integer timeRate; |
|
||||
|
|
||||
/** |
|
||||
* Env环境配置 |
|
||||
*/ |
|
||||
private EnvPayload envPayload; |
|
||||
} |
|
||||
@ -1,88 +0,0 @@ |
|||||
package com.yvan.logisticsEnv; |
|
||||
|
|
||||
import com.galaxis.rcs.common.enums.EnvStatus; |
|
||||
import com.google.common.collect.Lists; |
|
||||
import com.yvan.logisticsModel.ExecutorItem; |
|
||||
import lombok.Getter; |
|
||||
import lombok.Setter; |
|
||||
|
|
||||
import java.util.Date; |
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* 物流仓储环境上下文 |
|
||||
*/ |
|
||||
@Getter |
|
||||
@Setter |
|
||||
public class LogisticsEnv { |
|
||||
/** |
|
||||
* 项目ID |
|
||||
*/ |
|
||||
public final String projectUUID; |
|
||||
|
|
||||
/** |
|
||||
* 环境ID |
|
||||
*/ |
|
||||
public final long envId; |
|
||||
|
|
||||
private EnvStartParam startParam; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 是否为虚拟环境 |
|
||||
*/ |
|
||||
private boolean isVirtual; |
|
||||
|
|
||||
/** |
|
||||
* 是否正在运行 |
|
||||
*/ |
|
||||
private boolean isRunning; |
|
||||
|
|
||||
/** |
|
||||
* 环境开始时间 |
|
||||
*/ |
|
||||
private long startTime; |
|
||||
|
|
||||
/** |
|
||||
* 环境停止时间 |
|
||||
*/ |
|
||||
private long stopTime; |
|
||||
|
|
||||
/** |
|
||||
* 时间流速倍率 |
|
||||
*/ |
|
||||
private int timeRate; |
|
||||
|
|
||||
public LogisticsEnv(String projectUUID, long envId) { |
|
||||
this.projectUUID = projectUUID; |
|
||||
this.envId = envId; |
|
||||
} |
|
||||
|
|
||||
public void start(EnvStartParam param) { |
|
||||
if (this.isRunning) { |
|
||||
throw new IllegalStateException("环境已经在运行中"); |
|
||||
} |
|
||||
this.startParam = param; |
|
||||
this.isRunning = true; |
|
||||
this.startTime = System.currentTimeMillis(); |
|
||||
this.stopTime = 0L; |
|
||||
this.timeRate = this.startParam.getTimeRate(); |
|
||||
} |
|
||||
|
|
||||
public long currentTimeMillis() { |
|
||||
if (!this.isVirtual) { |
|
||||
// 正式环境,返回系统当前时间
|
|
||||
return System.currentTimeMillis(); |
|
||||
} |
|
||||
if (!this.isRunning) { |
|
||||
return this.stopTime; |
|
||||
} |
|
||||
|
|
||||
long realCost = System.currentTimeMillis() - this.startTime; |
|
||||
return this.startTime + (realCost * this.timeRate); |
|
||||
} |
|
||||
|
|
||||
public Date getCurrentDate() { |
|
||||
return new Date(this.currentTimeMillis()); |
|
||||
} |
|
||||
} |
|
||||
@ -1,30 +0,0 @@ |
|||||
package com.yvan.logisticsEnv; |
|
||||
|
|
||||
import java.util.HashMap; |
|
||||
import java.util.Map; |
|
||||
|
|
||||
public class LogisticsEnvManager { |
|
||||
|
|
||||
Map<String, LogisticsEnv> envs = new HashMap<>(); |
|
||||
|
|
||||
/** |
|
||||
* 启动参数 |
|
||||
*/ |
|
||||
public void startEnv(EnvStartParam param) { |
|
||||
|
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 复制环境, 返回新环境ID |
|
||||
*/ |
|
||||
public String cloneEnv(String envId) { |
|
||||
throw new RuntimeException(); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 重置环境 |
|
||||
*/ |
|
||||
public String resetEnv(String envId) { |
|
||||
throw new RuntimeException(); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,31 @@ |
|||||
|
package com.yvan.workbench.autoconfigure; |
||||
|
|
||||
|
import com.yvan.workbench.service.LccAutoStartService; |
||||
|
import com.yvan.workbench.service.LccMapService; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.boot.autoconfigure.AutoConfigureOrder; |
||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.core.Ordered; |
||||
|
|
||||
|
@Slf4j |
||||
|
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE) |
||||
|
@Configuration |
||||
|
@EnableConfigurationProperties(LccConfigProperties.class) |
||||
|
public class LccAutoConfiguration { |
||||
|
@Bean |
||||
|
public LccConfigProperties lccConfigProperties() { |
||||
|
return new LccConfigProperties(); |
||||
|
} |
||||
|
|
||||
|
@Bean |
||||
|
public LccAutoStartService lccAutoStartService() { |
||||
|
return new LccAutoStartService(this.lccConfigProperties()); |
||||
|
} |
||||
|
|
||||
|
@Bean |
||||
|
public LccMapService lccMapService() { |
||||
|
return new LccMapService(this.lccConfigProperties()); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
package com.yvan.workbench.autoconfigure; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
|
||||
|
@Data |
||||
|
@ConfigurationProperties(prefix = LccConfigProperties.PREFIX) |
||||
|
public class LccConfigProperties { |
||||
|
public static final String PREFIX = "lcc"; |
||||
|
private String location; |
||||
|
private AutoStartItem[] autoStart; |
||||
|
|
||||
|
@Data |
||||
|
public static class AutoStartItem { |
||||
|
private String projectUuid; |
||||
|
private Long envId; |
||||
|
} |
||||
|
} |
||||
@ -1,6 +1,15 @@ |
|||||
package com.yvan.workbench.controller; |
package com.yvan.workbench.controller; |
||||
|
|
||||
public class LccController { |
import com.yvan.workbench.SpringContext; |
||||
|
import com.yvan.workbench.service.LccMapService; |
||||
|
import org.clever.core.model.response.R; |
||||
|
|
||||
|
/** |
||||
|
* /api/workbench/LccController@get1 |
||||
|
*/ |
||||
|
public class LccController { |
||||
|
public static R<?> getAllProjects() { |
||||
|
var mapService = SpringContext.HOLDER.getBean(LccMapService.class); |
||||
|
return R.success(mapService.getAllProjects()); |
||||
|
} |
||||
} |
} |
||||
|
|||||
@ -1,34 +0,0 @@ |
|||||
package com.yvan.workbench.model.entity; |
|
||||
|
|
||||
import lombok.Data; |
|
||||
import java.io.Serializable; |
|
||||
import java.util.Date; |
|
||||
|
|
||||
/** |
|
||||
* (lcc_model_floor) |
|
||||
*/ |
|
||||
@Data |
|
||||
public class LccModelFloor implements Serializable { |
|
||||
/** */ |
|
||||
private Long id; |
|
||||
/** 项目编号 */ |
|
||||
private String projectUuid; |
|
||||
/** 项目版本 */ |
|
||||
private Long projectVersion; |
|
||||
/** 环境ID */ |
|
||||
private Long envId; |
|
||||
/** 楼层编号 */ |
|
||||
private String catalogCode; |
|
||||
/** 楼层数据 */ |
|
||||
private String items; |
|
||||
/** */ |
|
||||
private Boolean autoStart; |
|
||||
/** 创建时间,默认为当前时间 */ |
|
||||
private Date createAt; |
|
||||
/** 创建人 */ |
|
||||
private String createBy; |
|
||||
/** 最后更新时间,默认为当前时间,并在更新时自动更新 */ |
|
||||
private Date updateAt; |
|
||||
/** 更新人 */ |
|
||||
private String updateBy; |
|
||||
} |
|
||||
@ -1,35 +0,0 @@ |
|||||
package com.yvan.workbench.model.entity; |
|
||||
|
|
||||
import lombok.Data; |
|
||||
|
|
||||
import java.io.Serializable; |
|
||||
import java.util.Date; |
|
||||
|
|
||||
/** |
|
||||
* (lcc_model_world) |
|
||||
*/ |
|
||||
@Data |
|
||||
public class LccModelWorld implements Serializable { |
|
||||
/** */ |
|
||||
private Long id; |
|
||||
/** 项目编号 */ |
|
||||
private String projectUuid; |
|
||||
/** 项目标题 */ |
|
||||
private String projectLabel; |
|
||||
/** 项目版本 */ |
|
||||
private Long projectVersion; |
|
||||
/** 所在服务器 */ |
|
||||
private String server; |
|
||||
/** 目录数据 */ |
|
||||
private String directoryData; |
|
||||
/** 其他数据 */ |
|
||||
private String otherData; |
|
||||
/** 创建时间,默认为当前时间 */ |
|
||||
private Date createAt; |
|
||||
/** 创建人 */ |
|
||||
private String createBy; |
|
||||
/** 最后更新时间,默认为当前时间,并在更新时自动更新 */ |
|
||||
private Date updateAt; |
|
||||
/** 更新人 */ |
|
||||
private String updateBy; |
|
||||
} |
|
||||
@ -0,0 +1,27 @@ |
|||||
|
package com.yvan.workbench.model.entity; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
@Data |
||||
|
public class LccProject { |
||||
|
private String projectUuid; |
||||
|
private String projectLabel; |
||||
|
private String projectFileLocation; |
||||
|
private CatalogGroup[] directoryData; |
||||
|
private Map<String, Object> otherData; |
||||
|
|
||||
|
@Data |
||||
|
public static class CatalogGroup { |
||||
|
private String label; |
||||
|
private CatalogItem[] items; |
||||
|
} |
||||
|
|
||||
|
@Data |
||||
|
public static class CatalogItem { |
||||
|
private String catalogCode; |
||||
|
private String label; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
package com.yvan.workbench.model.entity; |
||||
|
|
||||
|
import com.yvan.logisticsEnv.EnvConfig; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
|
||||
|
@Data |
||||
|
public class LccProjectEnv { |
||||
|
private Long envId; |
||||
|
private String envName; |
||||
|
private Boolean isVirtual; |
||||
|
private EnvConfig envConfig; |
||||
|
private String fileLocation; |
||||
|
} |
||||
@ -1,80 +0,0 @@ |
|||||
package com.yvan.workbench.model.query; |
|
||||
|
|
||||
import static com.querydsl.core.types.PathMetadataFactory.*; |
|
||||
import com.querydsl.core.types.dsl.*; |
|
||||
import com.querydsl.core.types.*; |
|
||||
import com.querydsl.sql.*; |
|
||||
import java.sql.Types; |
|
||||
import com.yvan.workbench.model.entity.LccModelFloor; |
|
||||
import java.util.Date; |
|
||||
|
|
||||
/** |
|
||||
* (lcc_model_floor) |
|
||||
*/ |
|
||||
@SuppressWarnings("ALL") |
|
||||
public class QLccModelFloor extends RelationalPathBase<LccModelFloor> { |
|
||||
/** lcc_model_floor表 */ |
|
||||
public static final QLccModelFloor lccModelFloor = new QLccModelFloor("lcc_model_floor"); |
|
||||
|
|
||||
/** */ |
|
||||
public final NumberPath<Long> id = createNumber("id", Long.class); |
|
||||
/** 项目编号 */ |
|
||||
public final StringPath projectUuid = createString("projectUuid"); |
|
||||
/** 项目版本 */ |
|
||||
public final NumberPath<Long> projectVersion = createNumber("projectVersion", Long.class); |
|
||||
/** 环境ID */ |
|
||||
public final NumberPath<Long> envId = createNumber("envId", Long.class); |
|
||||
/** 楼层编号 */ |
|
||||
public final StringPath catalogCode = createString("catalogCode"); |
|
||||
/** 楼层数据 */ |
|
||||
public final StringPath items = createString("items"); |
|
||||
/** */ |
|
||||
public final BooleanPath autoStart = createBoolean("autoStart"); |
|
||||
/** 创建时间,默认为当前时间 */ |
|
||||
public final DateTimePath<Date> createAt = createDateTime("createAt", Date.class); |
|
||||
/** 创建人 */ |
|
||||
public final StringPath createBy = createString("createBy"); |
|
||||
/** 最后更新时间,默认为当前时间,并在更新时自动更新 */ |
|
||||
public final DateTimePath<Date> updateAt = createDateTime("updateAt", Date.class); |
|
||||
/** 更新人 */ |
|
||||
public final StringPath updateBy = createString("updateBy"); |
|
||||
|
|
||||
public QLccModelFloor(String variable) { |
|
||||
super(LccModelFloor.class, forVariable(variable), "rcs2_tw_zhanghui", "lcc_model_floor"); |
|
||||
addMetadata(); |
|
||||
} |
|
||||
|
|
||||
public QLccModelFloor(String variable, String schema, String table) { |
|
||||
super(LccModelFloor.class, forVariable(variable), schema, table); |
|
||||
addMetadata(); |
|
||||
} |
|
||||
|
|
||||
public QLccModelFloor(String variable, String schema) { |
|
||||
super(LccModelFloor.class, forVariable(variable), schema, "lcc_model_floor"); |
|
||||
addMetadata(); |
|
||||
} |
|
||||
|
|
||||
public QLccModelFloor(Path<? extends LccModelFloor> path) { |
|
||||
super(path.getType(), path.getMetadata(), "rcs2_tw_zhanghui", "lcc_model_floor"); |
|
||||
addMetadata(); |
|
||||
} |
|
||||
|
|
||||
public QLccModelFloor(PathMetadata metadata) { |
|
||||
super(LccModelFloor.class, metadata, "rcs2_tw_zhanghui", "lcc_model_floor"); |
|
||||
addMetadata(); |
|
||||
} |
|
||||
|
|
||||
private void addMetadata() { |
|
||||
addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(Types.BIGINT).withSize(19)); |
|
||||
addMetadata(projectUuid, ColumnMetadata.named("project_uuid").withIndex(2).ofType(Types.VARCHAR).withSize(36)); |
|
||||
addMetadata(projectVersion, ColumnMetadata.named("project_version").withIndex(3).ofType(Types.BIGINT).withSize(19)); |
|
||||
addMetadata(envId, ColumnMetadata.named("env_id").withIndex(4).ofType(Types.BIGINT).withSize(19)); |
|
||||
addMetadata(catalogCode, ColumnMetadata.named("catalogCode").withIndex(5).ofType(Types.VARCHAR).withSize(255)); |
|
||||
addMetadata(items, ColumnMetadata.named("items").withIndex(6).ofType(Types.LONGVARCHAR).withSize(16777215)); |
|
||||
addMetadata(autoStart, ColumnMetadata.named("auto_start").withIndex(7).ofType(Types.BIT).withSize(3)); |
|
||||
addMetadata(createAt, ColumnMetadata.named("create_at").withIndex(8).ofType(Types.TIMESTAMP)); |
|
||||
addMetadata(createBy, ColumnMetadata.named("create_by").withIndex(9).ofType(Types.VARCHAR).withSize(255)); |
|
||||
addMetadata(updateAt, ColumnMetadata.named("update_at").withIndex(10).ofType(Types.TIMESTAMP)); |
|
||||
addMetadata(updateBy, ColumnMetadata.named("update_by").withIndex(11).ofType(Types.VARCHAR).withSize(255)); |
|
||||
} |
|
||||
} |
|
||||
@ -1,86 +0,0 @@ |
|||||
package com.yvan.workbench.model.query; |
|
||||
|
|
||||
import com.querydsl.core.types.Path; |
|
||||
import com.querydsl.core.types.PathMetadata; |
|
||||
import com.querydsl.core.types.dsl.DateTimePath; |
|
||||
import com.querydsl.core.types.dsl.NumberPath; |
|
||||
import com.querydsl.core.types.dsl.StringPath; |
|
||||
import com.querydsl.sql.ColumnMetadata; |
|
||||
import com.querydsl.sql.RelationalPathBase; |
|
||||
import com.yvan.workbench.model.entity.LccModelWorld; |
|
||||
|
|
||||
import java.sql.Types; |
|
||||
import java.util.Date; |
|
||||
|
|
||||
import static com.querydsl.core.types.PathMetadataFactory.forVariable; |
|
||||
|
|
||||
/** |
|
||||
* (lcc_model_world) |
|
||||
*/ |
|
||||
@SuppressWarnings("ALL") |
|
||||
public class QLccModelWorld extends RelationalPathBase<LccModelWorld> { |
|
||||
/** lcc_model_world表 */ |
|
||||
public static final QLccModelWorld lccModelWorld = new QLccModelWorld("lcc_model_world"); |
|
||||
|
|
||||
/** */ |
|
||||
public final NumberPath<Long> id = createNumber("id", Long.class); |
|
||||
/** 项目编号 */ |
|
||||
public final StringPath projectUuid = createString("projectUuid"); |
|
||||
/** 项目标题 */ |
|
||||
public final StringPath projectLabel = createString("projectLabel"); |
|
||||
/** 项目版本 */ |
|
||||
public final NumberPath<Long> projectVersion = createNumber("projectVersion", Long.class); |
|
||||
/** 所在服务器 */ |
|
||||
public final StringPath server = createString("server"); |
|
||||
/** 目录数据 */ |
|
||||
public final StringPath directoryData = createString("directoryData"); |
|
||||
/** 其他数据 */ |
|
||||
public final StringPath otherData = createString("otherData"); |
|
||||
/** 创建时间,默认为当前时间 */ |
|
||||
public final DateTimePath<Date> createAt = createDateTime("createAt", Date.class); |
|
||||
/** 创建人 */ |
|
||||
public final StringPath createBy = createString("createBy"); |
|
||||
/** 最后更新时间,默认为当前时间,并在更新时自动更新 */ |
|
||||
public final DateTimePath<Date> updateAt = createDateTime("updateAt", Date.class); |
|
||||
/** 更新人 */ |
|
||||
public final StringPath updateBy = createString("updateBy"); |
|
||||
|
|
||||
public QLccModelWorld(String variable) { |
|
||||
super(LccModelWorld.class, forVariable(variable), "test", "lcc_model_world"); |
|
||||
addMetadata(); |
|
||||
} |
|
||||
|
|
||||
public QLccModelWorld(String variable, String schema, String table) { |
|
||||
super(LccModelWorld.class, forVariable(variable), schema, table); |
|
||||
addMetadata(); |
|
||||
} |
|
||||
|
|
||||
public QLccModelWorld(String variable, String schema) { |
|
||||
super(LccModelWorld.class, forVariable(variable), schema, "lcc_model_world"); |
|
||||
addMetadata(); |
|
||||
} |
|
||||
|
|
||||
public QLccModelWorld(Path<? extends LccModelWorld> path) { |
|
||||
super(path.getType(), path.getMetadata(), "test", "lcc_model_world"); |
|
||||
addMetadata(); |
|
||||
} |
|
||||
|
|
||||
public QLccModelWorld(PathMetadata metadata) { |
|
||||
super(LccModelWorld.class, metadata, "test", "lcc_model_world"); |
|
||||
addMetadata(); |
|
||||
} |
|
||||
|
|
||||
private void addMetadata() { |
|
||||
addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(Types.BIGINT).withSize(19)); |
|
||||
addMetadata(projectUuid, ColumnMetadata.named("project_uuid").withIndex(2).ofType(Types.VARCHAR).withSize(36)); |
|
||||
addMetadata(projectLabel, ColumnMetadata.named("project_label").withIndex(3).ofType(Types.VARCHAR).withSize(255)); |
|
||||
addMetadata(projectVersion, ColumnMetadata.named("project_version").withIndex(4).ofType(Types.BIGINT).withSize(19)); |
|
||||
addMetadata(server, ColumnMetadata.named("server").withIndex(5).ofType(Types.VARCHAR).withSize(255)); |
|
||||
addMetadata(directoryData, ColumnMetadata.named("directory_data").withIndex(6).ofType(Types.LONGVARCHAR).withSize(65535)); |
|
||||
addMetadata(otherData, ColumnMetadata.named("other_data").withIndex(7).ofType(Types.LONGVARCHAR).withSize(65535)); |
|
||||
addMetadata(createAt, ColumnMetadata.named("create_at").withIndex(8).ofType(Types.TIMESTAMP)); |
|
||||
addMetadata(createBy, ColumnMetadata.named("create_by").withIndex(9).ofType(Types.VARCHAR).withSize(255)); |
|
||||
addMetadata(updateAt, ColumnMetadata.named("update_at").withIndex(10).ofType(Types.TIMESTAMP)); |
|
||||
addMetadata(updateBy, ColumnMetadata.named("update_by").withIndex(11).ofType(Types.VARCHAR).withSize(255)); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,43 @@ |
|||||
|
package com.yvan.workbench.service; |
||||
|
|
||||
|
import com.galaxis.rcs.RCSService; |
||||
|
import com.google.common.base.Strings; |
||||
|
import com.yvan.logisticsModel.LogisticsRuntimeService; |
||||
|
import com.yvan.workbench.autoconfigure.LccConfigProperties; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.context.SmartLifecycle; |
||||
|
|
||||
|
@Slf4j |
||||
|
public class LccAutoStartService implements SmartLifecycle { |
||||
|
private final LccConfigProperties lccConfigProperties; |
||||
|
|
||||
|
public LccAutoStartService(LccConfigProperties lccConfigProperties) { |
||||
|
this.lccConfigProperties = lccConfigProperties; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void start() { |
||||
|
var autoStartItems = this.lccConfigProperties.getAutoStart(); |
||||
|
for (var item : autoStartItems) { |
||||
|
String projectUUID = item.getProjectUuid(); |
||||
|
Long envId = item.getEnvId(); |
||||
|
|
||||
|
if (Strings.isNullOrEmpty(projectUUID) || envId == null || envId <= 0) { |
||||
|
log.warn("Skipping auto start for project UUID '{}' and env ID '{}', invalid configuration.", projectUUID, envId); |
||||
|
continue; // 跳过无效的配置
|
||||
|
} |
||||
|
|
||||
|
RCSService.projectStart(projectUUID, envId); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void stop() { |
||||
|
LogisticsRuntimeService.INSTANCE.stopAll(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean isRunning() { |
||||
|
return LogisticsRuntimeService.INSTANCE.isRunning(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,291 @@ |
|||||
|
package com.yvan.workbench.service; |
||||
|
|
||||
|
import com.google.common.base.Joiner; |
||||
|
import com.google.common.base.Strings; |
||||
|
import com.google.common.collect.Lists; |
||||
|
import com.yvan.workbench.autoconfigure.LccConfigProperties; |
||||
|
import com.yvan.workbench.model.entity.LccProject; |
||||
|
import com.yvan.workbench.model.entity.LccProjectEnv; |
||||
|
import lombok.SneakyThrows; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.commons.io.FileUtils; |
||||
|
import org.apache.commons.io.FilenameUtils; |
||||
|
import org.clever.core.mapper.JacksonMapper; |
||||
|
|
||||
|
import java.io.File; |
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
import java.util.List; |
||||
|
import java.util.Objects; |
||||
|
|
||||
|
@Slf4j |
||||
|
public class LccMapService { |
||||
|
private final LccConfigProperties config; |
||||
|
|
||||
|
public LccMapService(LccConfigProperties lccConfigProperties) { |
||||
|
this.config = lccConfigProperties; |
||||
|
} |
||||
|
|
||||
|
@SneakyThrows |
||||
|
public LccProject getProjectById(String projectUuid) { |
||||
|
checkProjectUuid(projectUuid, false); |
||||
|
var projectFile = new File(this.config.getLocation() + "/" + projectUuid + "/project.json"); |
||||
|
|
||||
|
if (!projectFile.exists() || !projectFile.isFile()) { |
||||
|
throw new RuntimeException( |
||||
|
String.format("LccMapService.getProjectById() - project '%s' does not exist or is not a file", projectFile.getAbsolutePath()) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
log.info("load project file: {}", projectFile.getAbsolutePath()); |
||||
|
String content = Joiner.on("\n").join(FileUtils.readLines(projectFile, StandardCharsets.UTF_8)); |
||||
|
var project = JacksonMapper.getInstance().fromJson(content, LccProject.class); |
||||
|
project.setProjectFileLocation( |
||||
|
FilenameUtils.normalize(projectFile.getAbsolutePath(), true) |
||||
|
); |
||||
|
return project; |
||||
|
} |
||||
|
|
||||
|
@SneakyThrows |
||||
|
public LccProjectEnv getEnvById(String projectUuid, Long envId) { |
||||
|
checkProjectUuid(projectUuid, false); |
||||
|
var projectFile = new File(this.config.getLocation() + "/" + projectUuid + "/envs/" + envId + ".json"); |
||||
|
if (!projectFile.exists() || !projectFile.isFile()) { |
||||
|
throw new RuntimeException( |
||||
|
String.format("LccMapService.getEnvById() - env '%s' does not exist or is not a file", projectFile.getAbsolutePath()) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
log.info("load project file: {}", projectFile.getAbsolutePath()); |
||||
|
String content = Joiner.on("\n").join(FileUtils.readLines(projectFile, StandardCharsets.UTF_8)); |
||||
|
if (Strings.isNullOrEmpty(content)) { |
||||
|
throw new RuntimeException( |
||||
|
String.format("LccMapService.getEnvById() - env '%s' content is empty", projectFile.getAbsolutePath()) |
||||
|
); |
||||
|
} |
||||
|
if (!content.contains("envConfig")) { |
||||
|
throw new RuntimeException( |
||||
|
String.format("LccMapService.getEnvById() - env '%s' content is not a valid LccProjectEnv", projectFile.getAbsolutePath()) |
||||
|
); |
||||
|
} |
||||
|
var envInfo = JacksonMapper.getInstance().fromJson(content, LccProjectEnv.class); |
||||
|
envInfo.setFileLocation( |
||||
|
FilenameUtils.normalize(projectFile.getAbsolutePath(), true) |
||||
|
); |
||||
|
return envInfo; |
||||
|
} |
||||
|
|
||||
|
@SneakyThrows |
||||
|
public List<LccProject> getAllProjects() { |
||||
|
var mapLoc = new File(this.config.getLocation()); |
||||
|
|
||||
|
// 扫描 mapLoc 目录下所有的文件夹,并且文件夹中包含有 project.json 文件存在,就讲她反序列化为 LccProject 对象
|
||||
|
if (!mapLoc.exists() || !mapLoc.isDirectory()) { |
||||
|
throw new RuntimeException( |
||||
|
String.format("LccMapService.getAllProjects() - mapLoc '%s' does not exist or is not a directory", mapLoc.getAbsolutePath()) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
List<LccProject> list = Lists.newArrayList(); |
||||
|
for (File projectFolder : Objects.requireNonNull(mapLoc.listFiles())) { |
||||
|
if (projectFolder.isDirectory()) { |
||||
|
File projectFile = new File(projectFolder, "project.json"); |
||||
|
if (projectFile.exists() && projectFile.isFile()) { |
||||
|
// 反序列化 project.json 文件为 LccProject 对象
|
||||
|
log.info("load project file: {}", projectFile.getAbsolutePath()); |
||||
|
String content = Joiner.on("\n").join(FileUtils.readLines(projectFile, StandardCharsets.UTF_8)); |
||||
|
if (Strings.isNullOrEmpty(content)) { |
||||
|
continue; |
||||
|
} |
||||
|
if (!content.contains("directoryData")) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
var modelWorld = JacksonMapper.getInstance().fromJson(content, LccProject.class); |
||||
|
modelWorld.setProjectFileLocation( |
||||
|
FilenameUtils.normalize(projectFile.getAbsolutePath(), true) |
||||
|
); |
||||
|
list.add(modelWorld); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return list; |
||||
|
} |
||||
|
|
||||
|
public void checkProjectUuid(String projectUuid, boolean checkExists) { |
||||
|
// 检查项目编号是否符合规范
|
||||
|
if (Strings.isNullOrEmpty(projectUuid)) { |
||||
|
throw new RuntimeException("projectUuid cannot be null or empty"); |
||||
|
} |
||||
|
if (!projectUuid.matches("^[a-zA-Z0-9_\\-]+$")) { |
||||
|
throw new RuntimeException("projectUuid must be alphanumeric, underscores or hyphens"); |
||||
|
} |
||||
|
|
||||
|
// 检查项目文件名是否存在
|
||||
|
if (checkExists) { |
||||
|
var names = getAllProjectNames(); |
||||
|
if (names.contains(projectUuid)) { |
||||
|
throw new RuntimeException("projectUuid '" + projectUuid + "' has already exists, please use another one"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@SneakyThrows |
||||
|
public void saveProject(LccProject project) { |
||||
|
// 检查项目编号是否符合规范
|
||||
|
checkProjectUuid(project.getProjectUuid(), false); |
||||
|
|
||||
|
// 检查项目目录是否存在
|
||||
|
var mapLoc = new File(this.config.getLocation()); |
||||
|
if (!mapLoc.exists() || !mapLoc.isDirectory()) { |
||||
|
throw new RuntimeException( |
||||
|
String.format("LccMapService.saveProject() - mapLoc '%s' does not exist or is not a directory", mapLoc.getAbsolutePath()) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// 创建项目目录
|
||||
|
var projectDir = new File(mapLoc, project.getProjectUuid()); |
||||
|
if (!projectDir.exists()) { |
||||
|
projectDir.mkdirs(); |
||||
|
} |
||||
|
|
||||
|
// 这个字段不保存
|
||||
|
project.setProjectFileLocation(""); |
||||
|
|
||||
|
// 保存 project.json 文件
|
||||
|
var projectFile = new File(projectDir, "project.json"); |
||||
|
|
||||
|
// 如果 project.json 文件与 content 内容不一致,则跟新覆盖写入
|
||||
|
String contentOrigin = projectFile.exists() ? Joiner.on("\n").join(FileUtils.readLines(projectFile, StandardCharsets.UTF_8)) : ""; |
||||
|
String content = JacksonMapper.getInstance().toJsonPretty(project); |
||||
|
if (!content.equals(contentOrigin)) { |
||||
|
// 内容不一致时,更新项目的更新时间和更新人
|
||||
|
log.info("write project file: {}", projectFile.getAbsolutePath()); |
||||
|
FileUtils.writeStringToFile(projectFile, content, StandardCharsets.UTF_8); |
||||
|
} else { |
||||
|
log.info("project file no change, ignore write, path:{}", projectFile.getAbsolutePath()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@SneakyThrows |
||||
|
public String loadFloor(String projectUuid, String catalogCode) { |
||||
|
// 检查项目编号/楼层编号是否符合规范, 防止注入漏洞
|
||||
|
checkProjectUuid(projectUuid, false); |
||||
|
checkProjectUuid(catalogCode, false); |
||||
|
|
||||
|
// 检查项目目录是否存在
|
||||
|
var mapLoc = new File(this.config.getLocation()); |
||||
|
if (!mapLoc.exists() || !mapLoc.isDirectory()) { |
||||
|
throw new RuntimeException( |
||||
|
String.format("LccMapService.saveProject() - mapLoc '%s' does not exist or is not a directory", mapLoc.getAbsolutePath()) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// 创建项目目录
|
||||
|
var floorFile = new File(mapLoc, projectUuid + "/floor/" + catalogCode + ".json"); |
||||
|
if (!floorFile.exists() || !floorFile.isFile()) { |
||||
|
throw new RuntimeException( |
||||
|
String.format("LccMapService.loadFloor() - '%s' does not exist or is not a file", floorFile.getAbsolutePath()) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
log.info("load floor file: {}", floorFile.getAbsolutePath()); |
||||
|
String content = Joiner.on("\n").join(FileUtils.readLines(floorFile, StandardCharsets.UTF_8)); |
||||
|
if (Strings.isNullOrEmpty(content)) { |
||||
|
// 如果内容为空,则返回空数组
|
||||
|
content = "[]"; |
||||
|
} |
||||
|
return content; |
||||
|
} |
||||
|
|
||||
|
@SneakyThrows |
||||
|
public void saveFloor(String projectUuid, String catalogCode, String items) { |
||||
|
// 检查项目编号/楼层编号是否符合规范, 防止注入漏洞
|
||||
|
checkProjectUuid(projectUuid, false); |
||||
|
checkProjectUuid(catalogCode, false); |
||||
|
|
||||
|
if (Strings.isNullOrEmpty(items)) { |
||||
|
items = "[]"; |
||||
|
} |
||||
|
|
||||
|
// 检查项目目录是否存在
|
||||
|
var mapLoc = new File(this.config.getLocation()); |
||||
|
if (!mapLoc.exists() || !mapLoc.isDirectory()) { |
||||
|
throw new RuntimeException( |
||||
|
String.format("LccMapService.saveFloor() - mapLoc '%s' does not exist or is not a directory", mapLoc.getAbsolutePath()) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// 创建项目目录
|
||||
|
var floorDir = new File(mapLoc, projectUuid + "/floor"); |
||||
|
if (!floorDir.exists()) { |
||||
|
floorDir.mkdirs(); |
||||
|
} |
||||
|
|
||||
|
// 保存楼层数据到文件
|
||||
|
var floorFile = new File(floorDir, catalogCode + ".json"); |
||||
|
log.info("write floor file: {}", floorFile.getAbsolutePath()); |
||||
|
FileUtils.writeStringToFile(floorFile, items, StandardCharsets.UTF_8); |
||||
|
} |
||||
|
|
||||
|
@SneakyThrows |
||||
|
public List<LccProjectEnv> getAllEnv(String projectUuid) { |
||||
|
checkProjectUuid(projectUuid, false); |
||||
|
|
||||
|
var envLoc = new File(this.config.getLocation() + "/" + projectUuid + "/envs"); |
||||
|
|
||||
|
// 扫描 mapLoc 目录下所有的文件夹,并且文件夹中包含有 project.json 文件存在,就讲她反序列化为 LccProject 对象
|
||||
|
if (!envLoc.exists() || !envLoc.isDirectory()) { |
||||
|
throw new RuntimeException( |
||||
|
String.format("LccMapService.getAllProjects() - mapLoc '%s' does not exist or is not a directory", envLoc.getAbsolutePath()) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
List<LccProjectEnv> list = Lists.newArrayList(); |
||||
|
for (File propFile : Objects.requireNonNull(envLoc.listFiles())) { |
||||
|
if (propFile.exists() && propFile.isFile() && propFile.getName().endsWith(".json")) { |
||||
|
// 反序列化 project.json 文件为 LccProject 对象
|
||||
|
log.info("load env file: {}", propFile.getAbsolutePath()); |
||||
|
String content = Joiner.on("\n").join(FileUtils.readLines(propFile, StandardCharsets.UTF_8)); |
||||
|
if (Strings.isNullOrEmpty(content)) { |
||||
|
continue; |
||||
|
} |
||||
|
if (!content.contains("envConfig")) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
var envInfo = JacksonMapper.getInstance().fromJson(content, LccProjectEnv.class); |
||||
|
envInfo.setFileLocation( |
||||
|
FilenameUtils.normalize(propFile.getAbsolutePath(), true) |
||||
|
); |
||||
|
list.add(envInfo); |
||||
|
} |
||||
|
} |
||||
|
return list; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public List<String> getAllProjectNames() { |
||||
|
var mapLoc = new File(this.config.getLocation()); |
||||
|
|
||||
|
// 扫描 mapLoc 目录下所有的文件夹,并且文件夹中包含有 project.json 文件存在,就讲她反序列化为 LccProject 对象
|
||||
|
if (!mapLoc.exists() || !mapLoc.isDirectory()) { |
||||
|
throw new RuntimeException( |
||||
|
String.format("LccMapService.getAllProjects() - mapLoc '%s' does not exist or is not a directory", mapLoc.getAbsolutePath()) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
List<String> list = Lists.newArrayList(); |
||||
|
for (File projectFolder : Objects.requireNonNull(mapLoc.listFiles())) { |
||||
|
if (projectFolder.isDirectory()) { |
||||
|
File projectFile = new File(projectFolder, "project.json"); |
||||
|
if (projectFile.exists() && projectFile.isFile()) { |
||||
|
list.add(projectFolder.getName()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return list; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue