package com.zy.asrs.controller;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.core.annotations.ManagerAuth;
|
import com.core.common.R;
|
import com.zy.asrs.domain.path.StationPathResolvedPolicy;
|
import com.zy.asrs.entity.BasMap;
|
import com.zy.asrs.entity.BasStation;
|
import com.zy.asrs.entity.BasStationPathProfile;
|
import com.zy.asrs.entity.BasStationPathRule;
|
import com.zy.asrs.service.BasMapService;
|
import com.zy.asrs.service.BasStationService;
|
import com.zy.asrs.service.BasStationPathProfileService;
|
import com.zy.asrs.service.BasStationPathRuleService;
|
import com.zy.asrs.service.StationPathPolicyService;
|
import com.zy.common.model.NavigateNode;
|
import com.zy.common.utils.NavigateUtils;
|
import com.zy.common.utils.RedisUtil;
|
import com.zy.common.web.BaseController;
|
import com.zy.core.enums.RedisKeyType;
|
import com.zy.system.entity.Config;
|
import com.zy.system.service.ConfigService;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RestController;
|
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Set;
|
|
@RestController
|
@RequestMapping("/basStationPathPolicy")
|
public class BasStationPathPolicyController extends BaseController {
|
|
@Autowired
|
private BasStationPathProfileService basStationPathProfileService;
|
@Autowired
|
private BasStationPathRuleService basStationPathRuleService;
|
@Autowired
|
private ConfigService configService;
|
@Autowired
|
private RedisUtil redisUtil;
|
@Autowired
|
private StationPathPolicyService stationPathPolicyService;
|
@Autowired
|
private BasStationService basStationService;
|
@Autowired
|
private BasMapService basMapService;
|
@Autowired
|
private NavigateUtils navigateUtils;
|
|
@RequestMapping("/data/auth")
|
@ManagerAuth
|
public R data() {
|
Map<String, Object> data = new HashMap<>();
|
data.put("profiles", basStationPathProfileService.list(new QueryWrapper<BasStationPathProfile>().orderByAsc("priority", "id")));
|
data.put("rules", basStationPathRuleService.list(new QueryWrapper<BasStationPathRule>().orderByAsc("priority", "id")));
|
data.put("scoreMode", getSystemConfig("stationPathScoreMode", "legacy"));
|
data.put("defaultProfileCode", getSystemConfig("stationPathDefaultProfileCode", "default"));
|
data.put("stations", buildStationSummaryList());
|
data.put("levList", basMapService.getLevList());
|
return R.ok(data);
|
}
|
|
@RequestMapping("/save/auth")
|
@ManagerAuth
|
public R save(@RequestBody JSONObject payload) {
|
JSONArray profiles = payload.getJSONArray("profiles");
|
JSONArray rules = payload.getJSONArray("rules");
|
|
upsertSystemConfig("站点路径评分模式", "stationPathScoreMode", defaultIfBlank(payload.getString("scoreMode"), "legacy"), "String");
|
upsertSystemConfig("站点路径默认模板编码", "stationPathDefaultProfileCode", defaultIfBlank(payload.getString("defaultProfileCode"), "default"), "String");
|
|
basStationPathProfileService.remove(new QueryWrapper<>());
|
basStationPathRuleService.remove(new QueryWrapper<>());
|
|
List<BasStationPathProfile> profileList = new ArrayList<>();
|
if (profiles != null) {
|
for (int i = 0; i < profiles.size(); i++) {
|
JSONObject item = profiles.getJSONObject(i);
|
if (item == null) {
|
continue;
|
}
|
if (isBlank(item.getString("profileCode"))) {
|
continue;
|
}
|
BasStationPathProfile profile = new BasStationPathProfile();
|
profile.setProfileCode(item.getString("profileCode"));
|
profile.setProfileName(defaultIfBlank(item.getString("profileName"), item.getString("profileCode")));
|
profile.setPriority(item.getInteger("priority") == null ? 100 : item.getInteger("priority"));
|
profile.setStatus(item.getShort("status") == null ? (short) 1 : item.getShort("status"));
|
profile.setMemo(item.getString("memo"));
|
Object configObj = item.get("config");
|
if (configObj != null) {
|
profile.setConfigJson(JSON.toJSONString(configObj));
|
} else {
|
profile.setConfigJson(item.getString("configJson"));
|
}
|
profileList.add(profile);
|
}
|
}
|
if (!profileList.isEmpty()) {
|
basStationPathProfileService.saveBatch(profileList);
|
}
|
|
List<BasStationPathRule> ruleList = new ArrayList<>();
|
if (rules != null) {
|
for (int i = 0; i < rules.size(); i++) {
|
JSONObject item = rules.getJSONObject(i);
|
if (item == null) {
|
continue;
|
}
|
if (isBlank(item.getString("ruleCode"))) {
|
continue;
|
}
|
BasStationPathRule rule = new BasStationPathRule();
|
rule.setRuleCode(item.getString("ruleCode"));
|
rule.setRuleName(defaultIfBlank(item.getString("ruleName"), item.getString("ruleCode")));
|
rule.setPriority(item.getInteger("priority") == null ? 100 : item.getInteger("priority"));
|
rule.setStatus(item.getShort("status") == null ? (short) 1 : item.getShort("status"));
|
rule.setSceneType(item.getString("sceneType"));
|
rule.setStartStationId(item.getInteger("startStationId"));
|
rule.setEndStationId(item.getInteger("endStationId"));
|
rule.setProfileCode(item.getString("profileCode"));
|
rule.setMemo(item.getString("memo"));
|
rule.setHardJson(toJson(item.get("hard"), item.getString("hardJson")));
|
rule.setWaypointJson(toJson(item.get("waypoint"), item.getString("waypointJson")));
|
rule.setSoftJson(toJson(item.get("soft"), item.getString("softJson")));
|
rule.setFallbackJson(toJson(item.get("fallback"), item.getString("fallbackJson")));
|
ruleList.add(rule);
|
}
|
}
|
if (!ruleList.isEmpty()) {
|
basStationPathRuleService.saveBatch(ruleList);
|
}
|
|
refreshSystemConfigCache();
|
stationPathPolicyService.evictCache();
|
return R.ok();
|
}
|
|
@RequestMapping("/resolve/auth")
|
@ManagerAuth
|
public R resolve(@RequestParam Integer startStationId, @RequestParam Integer endStationId) {
|
StationPathResolvedPolicy resolved = stationPathPolicyService.resolvePolicy(startStationId, endStationId);
|
return R.ok(resolved);
|
}
|
|
@RequestMapping("/preview/auth")
|
@ManagerAuth
|
public R preview(@RequestParam Integer startStationId,
|
@RequestParam Integer endStationId,
|
@RequestParam(required = false, defaultValue = "false") Boolean includeMapData) {
|
StationPathResolvedPolicy resolved = stationPathPolicyService.resolvePolicy(startStationId, endStationId);
|
List<NavigateNode> nodes = navigateUtils.calcByStationId(startStationId, endStationId);
|
List<Integer> stationIdList = new ArrayList<>();
|
List<Map<String, Object>> nodeList = new ArrayList<>();
|
Set<Integer> seen = new HashSet<>();
|
for (NavigateNode node : nodes) {
|
JSONObject value = parseNodeValue(node == null ? null : node.getNodeValue());
|
Integer stationId = value == null ? null : value.getInteger("stationId");
|
if (stationId != null && seen.add(stationId)) {
|
stationIdList.add(stationId);
|
}
|
Map<String, Object> item = new HashMap<>();
|
item.put("stationId", stationId);
|
item.put("x", node == null ? null : node.getX());
|
item.put("y", node == null ? null : node.getY());
|
item.put("direction", node == null ? null : node.getDirection());
|
item.put("isInflectionPoint", node != null && Boolean.TRUE.equals(node.getIsInflectionPoint()));
|
item.put("isLiftTransferPoint", node != null && Boolean.TRUE.equals(node.getIsLiftTransferPoint()));
|
nodeList.add(item);
|
}
|
|
BasStation startStation = basStationService.getById(startStationId);
|
Integer lev = startStation == null ? null : startStation.getStationLev();
|
BasMap basMap = Boolean.TRUE.equals(includeMapData) && lev != null
|
? basMapService.getOne(new QueryWrapper<BasMap>().eq("lev", lev))
|
: null;
|
|
Map<String, Object> result = new HashMap<>();
|
result.put("resolvedPolicy", resolved);
|
result.put("pathStationIds", stationIdList);
|
result.put("pathNodes", nodeList);
|
result.put("pathLength", stationIdList.size());
|
result.put("turnCount", countTurnCount(nodeList));
|
result.put("liftTransferCount", countLiftTransferCount(nodeList));
|
result.put("lev", lev);
|
result.put("mapData", basMap == null ? null : basMap.getData());
|
result.put("previewTime", new Date());
|
return R.ok(result);
|
}
|
|
@RequestMapping("/expandSoftPath/auth")
|
@ManagerAuth
|
public R expandSoftPath(@RequestBody JSONObject payload) {
|
Integer startStationId = payload.getInteger("startStationId");
|
Integer endStationId = payload.getInteger("endStationId");
|
if (startStationId == null || endStationId == null) {
|
return R.error("起点和终点不能为空");
|
}
|
|
List<Integer> routePoints = new ArrayList<>();
|
routePoints.add(startStationId);
|
routePoints.addAll(parseStationIdArray(payload.getJSONArray("keyStations")));
|
routePoints.add(endStationId);
|
|
List<Integer> fullPathStationIds = new ArrayList<>();
|
for (int i = 0; i < routePoints.size() - 1; i++) {
|
Integer segmentStart = routePoints.get(i);
|
Integer segmentEnd = routePoints.get(i + 1);
|
if (segmentStart == null || segmentEnd == null) {
|
continue;
|
}
|
if (segmentStart.equals(segmentEnd)) {
|
if (fullPathStationIds.isEmpty()) {
|
fullPathStationIds.add(segmentStart);
|
}
|
continue;
|
}
|
List<NavigateNode> segmentNodes = navigateUtils.calcByStationId(segmentStart, segmentEnd);
|
List<Integer> segmentStationIds = extractStationIds(segmentNodes);
|
if (segmentStationIds.isEmpty()) {
|
return R.error("未找到 " + segmentStart + " 到 " + segmentEnd + " 的可行路径");
|
}
|
appendSegmentPath(fullPathStationIds, segmentStationIds);
|
}
|
|
Map<String, Object> result = new HashMap<>();
|
result.put("startStationId", startStationId);
|
result.put("endStationId", endStationId);
|
result.put("keyStations", routePoints.size() <= 2 ? new ArrayList<>() : routePoints.subList(1, routePoints.size() - 1));
|
result.put("pathStationIds", fullPathStationIds);
|
result.put("pathLength", fullPathStationIds.size());
|
result.put("segmentCount", Math.max(routePoints.size() - 1, 0));
|
result.put("previewTime", new Date());
|
return R.ok(result);
|
}
|
|
private List<Map<String, Object>> buildStationSummaryList() {
|
List<Map<String, Object>> result = new ArrayList<>();
|
List<BasStation> stationList = basStationService.list(new QueryWrapper<BasStation>()
|
.eq("status", 1)
|
.orderByAsc("station_lev", "station_id"));
|
for (BasStation station : stationList) {
|
if (station == null || station.getStationId() == null) {
|
continue;
|
}
|
Map<String, Object> item = new HashMap<>();
|
item.put("stationId", station.getStationId());
|
item.put("stationLev", station.getStationLev());
|
item.put("stationAlias", station.getStationAlias());
|
result.add(item);
|
}
|
return result;
|
}
|
|
private void upsertSystemConfig(String name, String code, String value, String selectType) {
|
String finalValue = value == null ? "" : value.trim();
|
Config config = configService.getOne(new QueryWrapper<Config>().eq("code", code));
|
if (config == null) {
|
config = new Config(name, code, finalValue, (short) 1, (short) 1);
|
config.setSelectType(selectType);
|
configService.save(config);
|
} else {
|
config.setName(name);
|
config.setValue(finalValue);
|
config.setType((short) 1);
|
config.setStatus((short) 1);
|
config.setSelectType(selectType);
|
configService.updateById(config);
|
}
|
}
|
|
private void refreshSystemConfigCache() {
|
HashMap<String, String> systemConfigMap = new HashMap<>();
|
List<Config> configList = configService.list(new QueryWrapper<>());
|
for (Config config : configList) {
|
systemConfigMap.put(config.getCode(), config.getValue());
|
}
|
redisUtil.set(RedisKeyType.SYSTEM_CONFIG_MAP.key, systemConfigMap);
|
}
|
|
private String getSystemConfig(String code, String defaultValue) {
|
Object mapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
|
if (mapObj instanceof Map) {
|
Object value = ((Map<?, ?>) mapObj).get(code);
|
if (value != null) {
|
String text = String.valueOf(value).trim();
|
if (!text.isEmpty()) {
|
return text;
|
}
|
}
|
}
|
return defaultValue;
|
}
|
|
private List<Integer> parseStationIdArray(JSONArray array) {
|
List<Integer> result = new ArrayList<>();
|
if (array == null || array.isEmpty()) {
|
return result;
|
}
|
Set<Integer> seen = new HashSet<>();
|
for (int i = 0; i < array.size(); i++) {
|
Integer stationId = toInteger(array.get(i));
|
if (stationId != null && seen.add(stationId)) {
|
result.add(stationId);
|
}
|
}
|
return result;
|
}
|
|
private List<Integer> extractStationIds(List<NavigateNode> nodes) {
|
List<Integer> stationIdList = new ArrayList<>();
|
Set<Integer> seen = new HashSet<>();
|
for (NavigateNode node : nodes) {
|
JSONObject value = parseNodeValue(node == null ? null : node.getNodeValue());
|
Integer stationId = value == null ? null : value.getInteger("stationId");
|
if (stationId != null && seen.add(stationId)) {
|
stationIdList.add(stationId);
|
}
|
}
|
return stationIdList;
|
}
|
|
private void appendSegmentPath(List<Integer> fullPathStationIds, List<Integer> segmentStationIds) {
|
if (segmentStationIds == null || segmentStationIds.isEmpty()) {
|
return;
|
}
|
for (Integer stationId : segmentStationIds) {
|
if (stationId == null) {
|
continue;
|
}
|
if (fullPathStationIds.isEmpty() || !stationId.equals(fullPathStationIds.get(fullPathStationIds.size() - 1))) {
|
fullPathStationIds.add(stationId);
|
}
|
}
|
}
|
|
private String toJson(Object obj, String fallbackText) {
|
if (obj != null) {
|
return JSON.toJSONString(obj);
|
}
|
return fallbackText;
|
}
|
|
private JSONObject parseNodeValue(String text) {
|
if (isBlank(text)) {
|
return null;
|
}
|
try {
|
return JSON.parseObject(text);
|
} catch (Exception ignore) {
|
return null;
|
}
|
}
|
|
private int countTurnCount(List<Map<String, Object>> nodeList) {
|
if (nodeList == null || nodeList.size() < 3) {
|
return 0;
|
}
|
int count = 0;
|
for (int i = 1; i < nodeList.size() - 1; i++) {
|
Map<String, Object> prev = nodeList.get(i - 1);
|
Map<String, Object> next = nodeList.get(i + 1);
|
Integer prevX = toInteger(prev.get("x"));
|
Integer prevY = toInteger(prev.get("y"));
|
Integer nextX = toInteger(next.get("x"));
|
Integer nextY = toInteger(next.get("y"));
|
if (prevX == null || prevY == null || nextX == null || nextY == null) {
|
continue;
|
}
|
if (!prevX.equals(nextX) && !prevY.equals(nextY)) {
|
count++;
|
}
|
}
|
return count;
|
}
|
|
private int countLiftTransferCount(List<Map<String, Object>> nodeList) {
|
int count = 0;
|
for (Map<String, Object> item : nodeList) {
|
if (Boolean.TRUE.equals(item.get("isLiftTransferPoint"))) {
|
count++;
|
}
|
}
|
return count;
|
}
|
|
private Integer toInteger(Object value) {
|
if (value == null) {
|
return null;
|
}
|
if (value instanceof Integer) {
|
return (Integer) value;
|
}
|
try {
|
return Integer.parseInt(String.valueOf(value));
|
} catch (Exception ignore) {
|
return null;
|
}
|
}
|
|
private String defaultIfBlank(String text, String defaultValue) {
|
return isBlank(text) ? defaultValue : text.trim();
|
}
|
|
private boolean isBlank(String text) {
|
return text == null || text.trim().isEmpty();
|
}
|
}
|