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.web.BaseController;
|
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 StationPathPolicyService stationPathPolicyService;
|
@Autowired
|
private BasStationService basStationService;
|
@Autowired
|
private BasMapService basMapService;
|
@Autowired
|
private NavigateUtils navigateUtils;
|
|
@RequestMapping("/data/auth")
|
@ManagerAuth
|
public R data() {
|
List<BasStationPathProfile> profileList = basStationPathProfileService.list(new QueryWrapper<BasStationPathProfile>()
|
.orderByDesc("is_default")
|
.orderByAsc("priority", "id"));
|
Map<String, Object> data = new HashMap<>();
|
data.put("profiles", profileList);
|
data.put("rules", basStationPathRuleService.list(new QueryWrapper<BasStationPathRule>().orderByAsc("priority", "id")));
|
data.put("scoreMode", "twoStage");
|
data.put("defaultProfileCode", resolveDefaultProfileCode(profileList));
|
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");
|
|
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.setIsDefault((short) 0);
|
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()) {
|
return R.error("至少需要保留一个模板");
|
}
|
|
String defaultProfileCode = defaultIfBlank(payload.getString("defaultProfileCode"), profileList.get(0).getProfileCode());
|
BasStationPathProfile defaultProfile = null;
|
for (BasStationPathProfile profile : profileList) {
|
if (profile != null && defaultProfileCode.equals(profile.getProfileCode())) {
|
profile.setIsDefault((short) 1);
|
defaultProfile = profile;
|
break;
|
}
|
}
|
if (defaultProfile == null) {
|
return R.error("默认模板编码没有对应模板");
|
}
|
if (!Short.valueOf((short) 1).equals(defaultProfile.getStatus())) {
|
return R.error("默认模板必须启用");
|
}
|
|
basStationPathProfileService.remove(new QueryWrapper<>());
|
basStationPathRuleService.remove(new QueryWrapper<>());
|
|
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);
|
}
|
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 String resolveDefaultProfileCode(List<BasStationPathProfile> profileList) {
|
if (profileList == null || profileList.isEmpty()) {
|
return "default";
|
}
|
for (BasStationPathProfile profile : profileList) {
|
if (profile != null
|
&& Short.valueOf((short) 1).equals(profile.getIsDefault())
|
&& !isBlank(profile.getProfileCode())) {
|
return profile.getProfileCode();
|
}
|
}
|
for (BasStationPathProfile profile : profileList) {
|
if (profile != null && "default".equals(profile.getProfileCode())) {
|
return profile.getProfileCode();
|
}
|
}
|
for (BasStationPathProfile profile : profileList) {
|
if (profile != null && !isBlank(profile.getProfileCode())) {
|
return profile.getProfileCode();
|
}
|
}
|
return "default";
|
}
|
|
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();
|
}
|
}
|