package com.vincent.rsf.server.ai.service.provider;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.vincent.rsf.server.ai.model.AiDiagnosticToolResult;
|
import com.vincent.rsf.server.ai.model.AiPromptContext;
|
import com.vincent.rsf.server.manager.entity.DeviceSite;
|
import com.vincent.rsf.server.manager.mapper.DeviceSiteMapper;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.util.ArrayList;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
@Service
|
public class AiDeviceSiteSummaryService implements AiDiagnosticDataProvider {
|
|
private static final String TOOL_CODE = "device_site_summary";
|
private static final String TOOL_NAME = "设备站点摘要";
|
|
@Resource
|
private DeviceSiteMapper deviceSiteMapper;
|
|
/**
|
* 返回设备站点工具默认顺序。
|
*/
|
@Override
|
public int getOrder() {
|
return 30;
|
}
|
|
/**
|
* 返回设备站点工具编码。
|
*/
|
@Override
|
public String getToolCode() {
|
return TOOL_CODE;
|
}
|
|
/**
|
* 返回设备站点工具展示名。
|
*/
|
@Override
|
public String getToolName() {
|
return TOOL_NAME;
|
}
|
|
/**
|
* 返回设备站点工具默认说明。
|
*/
|
@Override
|
public String getDefaultToolPrompt() {
|
return "结合设备站点摘要判断设备状态、巷道分布和最近更新站点。";
|
}
|
|
/**
|
* 汇总站点状态、设备分布和最近更新站点,生成设备站点摘要。
|
*/
|
@Override
|
public AiDiagnosticToolResult buildDiagnosticData(AiPromptContext context) {
|
String summary = buildDeviceSiteSummary(context);
|
String severity = summary.contains("未查询到") ? "WARN" : "INFO";
|
return new AiDiagnosticToolResult()
|
.setToolCode(getToolCode())
|
.setToolName(getToolName())
|
.setSeverity(severity)
|
.setSummaryText(summary);
|
}
|
|
/**
|
* 基于 man_device_site 生成设备站点总览。
|
*/
|
private String buildDeviceSiteSummary(AiPromptContext context) {
|
List<DeviceSite> deviceSites = deviceSiteMapper.selectList(new LambdaQueryWrapper<DeviceSite>()
|
.select(DeviceSite::getSite, DeviceSite::getName, DeviceSite::getType, DeviceSite::getDevice,
|
DeviceSite::getDeviceCode, DeviceSite::getDeviceSite, DeviceSite::getStatus,
|
DeviceSite::getChannel, DeviceSite::getUpdateTime)
|
.eq(DeviceSite::getTenantId, context.getTenantId())
|
.orderByDesc(DeviceSite::getUpdateTime)
|
.last("limit 50"));
|
|
if (deviceSites.isEmpty()) {
|
return "当前未查询到 man_device_site 设备站点数据,请提示用户核对基础数据或租户配置。";
|
}
|
|
Map<String, Long> statusCounters = new LinkedHashMap<>();
|
Map<String, Long> deviceCounters = new LinkedHashMap<>();
|
Map<String, Long> channelCounters = new LinkedHashMap<>();
|
for (DeviceSite deviceSite : deviceSites) {
|
String status = resolveStatus(deviceSite.getStatus());
|
String device = emptyToDefault(deviceSite.getDevice$(), "未配置设备类型");
|
String channel = deviceSite.getChannel() == null ? "未配置巷道" : "巷道" + deviceSite.getChannel();
|
statusCounters.put(status, statusCounters.getOrDefault(status, 0L) + 1);
|
deviceCounters.put(device, deviceCounters.getOrDefault(device, 0L) + 1);
|
channelCounters.put(channel, channelCounters.getOrDefault(channel, 0L) + 1);
|
}
|
|
StringBuilder summary = new StringBuilder();
|
summary.append("以下是基于 man_device_site 的实时设备站点摘要,请结合任务和库存数据综合判断:");
|
summary.append("\n设备站点总览:共 ").append(deviceSites.size()).append(" 条有效站点记录。");
|
summary.append("\n站点状态分布:").append(formatCounter(statusCounters)).append("。");
|
summary.append("\n设备类型分布:").append(formatCounter(deviceCounters)).append("。");
|
summary.append("\n巷道分布:").append(formatCounter(channelCounters)).append("。");
|
summary.append("\n最近更新站点 TOP5:").append(formatLatestSites(deviceSites.subList(0, Math.min(deviceSites.size(), 5)))).append("。");
|
return summary.toString();
|
}
|
|
/**
|
* 格式化计数类摘要。
|
*/
|
private String formatCounter(Map<String, Long> counter) {
|
List<String> parts = new ArrayList<>();
|
for (Map.Entry<String, Long> item : counter.entrySet()) {
|
parts.add(item.getKey() + " " + item.getValue() + " 条");
|
}
|
return String.join(",", parts);
|
}
|
|
/**
|
* 格式化最近更新站点列表。
|
*/
|
private String formatLatestSites(List<DeviceSite> deviceSites) {
|
List<String> parts = new ArrayList<>();
|
for (DeviceSite deviceSite : deviceSites) {
|
parts.add(emptyToDefault(deviceSite.getName(), emptyToDefault(deviceSite.getSite(), "未命名站点"))
|
+ "("
|
+ resolveStatus(deviceSite.getStatus())
|
+ ",设备 "
|
+ emptyToDefault(deviceSite.getDevice$(), "-")
|
+ ",接驳位 "
|
+ emptyToDefault(deviceSite.getDeviceCode(), "-")
|
+ ",巷道 "
|
+ (deviceSite.getChannel() == null ? "-" : deviceSite.getChannel())
|
+ ")");
|
}
|
return String.join(";", parts);
|
}
|
|
/**
|
* 将站点状态码转成可读文本。
|
*/
|
private String resolveStatus(Integer status) {
|
if (status == null) {
|
return "未知状态";
|
}
|
return status == 1 ? "正常" : status == 0 ? "冻结" : "状态" + status;
|
}
|
|
/**
|
* 统一处理空值展示。
|
*/
|
private String emptyToDefault(String value, String defaultValue) {
|
return value == null || value.trim().isEmpty() ? defaultValue : value;
|
}
|
}
|