diff --git a/inquiry-api/jeecg-module-inquiry/src/main/java/org/jeecg/modules/inquiry/service/IInquiryDashboardService.java b/inquiry-api/jeecg-module-inquiry/src/main/java/org/jeecg/modules/inquiry/service/IInquiryDashboardService.java
index ef95bc1..56825cd 100644
--- a/inquiry-api/jeecg-module-inquiry/src/main/java/org/jeecg/modules/inquiry/service/IInquiryDashboardService.java
+++ b/inquiry-api/jeecg-module-inquiry/src/main/java/org/jeecg/modules/inquiry/service/IInquiryDashboardService.java
@@ -8,7 +8,8 @@ import java.util.Map;
public interface IInquiryDashboardService {
/**
- * 返回看板指标:metrics 列表 + trend + rankings。
+ * 返回看板指标:metrics + trend + rankings + costDates/costRoutes。
+ * rankings 与工单列表同套发起人解析;costRoutes 为近 7 日线路均价(主账工单投影)。
*
* @param range today|7d|30d,默认 today
*/
diff --git a/inquiry-api/jeecg-module-inquiry/src/main/java/org/jeecg/modules/inquiry/service/impl/InquiryDashboardServiceImpl.java b/inquiry-api/jeecg-module-inquiry/src/main/java/org/jeecg/modules/inquiry/service/impl/InquiryDashboardServiceImpl.java
index 81dd91e..7a1fdcc 100644
--- a/inquiry-api/jeecg-module-inquiry/src/main/java/org/jeecg/modules/inquiry/service/impl/InquiryDashboardServiceImpl.java
+++ b/inquiry-api/jeecg-module-inquiry/src/main/java/org/jeecg/modules/inquiry/service/impl/InquiryDashboardServiceImpl.java
@@ -1,12 +1,14 @@
package org.jeecg.modules.inquiry.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.inquiry.domain.TicketStatuses;
import org.jeecg.modules.inquiry.entity.InquiryStaffRole;
import org.jeecg.modules.inquiry.entity.InquiryTicket;
import org.jeecg.modules.inquiry.mapper.InquiryStaffRoleMapper;
import org.jeecg.modules.inquiry.mapper.InquiryTicketMapper;
import org.jeecg.modules.inquiry.service.IInquiryDashboardService;
+import org.jeecg.modules.inquiry.support.InquiryTicketDisplaySupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -18,24 +20,41 @@ import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 看板实时聚合实现(无快照依赖)。
*
- * 计算口径对齐后台原型:询价总数、待处理、TMS 命中率、异常完成率、手工报价占比、
+ * 计算口径:询价总数、待处理、TMS 命中率、异常完成率、手工报价占比、
* 已成交、成交率、反馈率;内部协同时长本期无协同表时返回「-」。
+ * 人员排名与工单列表同一套发起人解析(企微 id → 员工姓名),禁止只认库内空 sales_name。
+ * 成本趋势:近 7 日工单按线路聚合均价(成本价优先,缺省用销售价),非浏览器直连 TMS。
* 线程:只读查询,无写锁。
*/
@Service
public class InquiryDashboardServiceImpl implements IInquiryDashboardService {
private static final ZoneId ZONE = ZoneId.of("Asia/Shanghai");
+ private static final DateTimeFormatter DAY_FMT = DateTimeFormatter.ofPattern("MM-dd");
+ private static final int COST_ROUTE_LIMIT = 16;
+ private static final String[] COST_COLORS = {
+ "#2563eb", "#3b82f6", "#0891b2", "#0e7490", "#6366f1", "#8b5cf6",
+ "#a855f7", "#c026d3", "#db2777", "#e11d48", "#dc2626", "#ea580c",
+ "#d97706", "#65a30d", "#0d9488", "#059669", "#0284c7"
+ };
+
+ /** 单日金额累加(成本趋势用)。 */
+ private static final class DaySum {
+ private BigDecimal sum = BigDecimal.ZERO;
+ private int count;
+ }
@Autowired
private InquiryTicketMapper ticketMapper;
@@ -91,59 +110,306 @@ public class InquiryDashboardServiceImpl implements IInquiryDashboardService {
metricCards.add(card("accepted", "已成交工单", "状态=已成交的工单数量", String.valueOf(deal), false));
metricCards.add(card("dealRate", "报价成交率", "已成交数 ÷ 已报价相关数 × 100%", pct(deal, Math.max(quoted, 1)), false));
long feedbackNumer = deal + lost;
- // 反馈率口径:已成交+未成交(相对周期工单)
metricCards.add(card("feedback", "报价反馈率", "(已成交 + 未成交)÷ 工单数 × 100%", pct(feedbackNumer, total), false));
metricCards.add(card("avgResp", "内部协同平均响应时长", "本期无协同明细表,暂无数据", "-", true));
- // 近 7 日趋势(不受 range 限制,便于折线)
- List