西藏巴青项目

大屏交易销售技术方案.md 14KB

大屏 — 交易销售统计 — 技术方案

依据:同目录 大屏交易销售功能需求.md v1.0。数据源为交易市场平台既有表(订单、明细、供应商、承销商、日度行情、等级重量配置等)。本模块为大屏只读看板农资商城相关表与指标本期不设计、不实现(对齐功能需求 §3.2)。


1. 技术架构

说明
后端 RuoYi v3.9.2springboot2 分支):JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid
数据库 MySQL 5.7.39,InnoDB,utf8mb4
前端 大屏交易销售专题页;切换 statYear 拉取看板主数据(本期单接口
代码包 com.ruoyi.web.modules.screenTradeSalesScreenController / ITradeSalesScreenService / vo / support

分层ControllerITradeSalesScreenService(口径编排、statDate 计算)→ TradeSalesScreenMapper(只读 SQL)+ TradeSalesScreenSupport(行情 7 日聚合、12 月补 0、占比)。

场景 行为
进入 / 切换 statYear 调用 §3.1
数据权限 全县聚合;不按供应商/用户过滤
统计日 statDate Y = 当前年 → 今日(Asia/Shanghai);Y 为历史年 → Y-12-31
年内订单上界 finish_timestatDate 23:59:59(当前年);历史年 ≤ Y-12-31 23:59:59
入驻商铺数 biz_supplier 实时快照statYear
产地行情近 7 日 statDate 为终点 [statDate−6, statDate]与 Y 无关
按月图表 横轴固定 12 月;缺月、当前年晚于 statDate 的月份均为 0
性能 默认实时聚合;可选 §2.3 缓存表

依赖表(只读,本期)

用途
biz_trade_order 已完成订单汇总、按月趋势、销售去向关联
biz_trade_order_line 品质等级(grade_code)按行统计
biz_supplier 入驻商铺数(有效供应商)
biz_distributor 销售去向 sales_destination(1 本市 / 2 本省 / 3 外省)
biz_market_daily_quote 产地行情近 7 日
biz_trade_market 解析默认行情市场(名称「巴青牦牛交易市场」)
biz_grade_weight_config 等级编码 → 展示名称

不包含:农资商城订单、店铺、品类、评价等任意表与字段。


2. 数据库设计

2.1 本模块业务表

无新增业务台账表。 业务 DDL 以 sql/biz_trade_order.sqlsql/biz_supplier.sqlsql/biz_distributor.sqlsql/biz_market_daily_quote.sqlsql/biz_trade_market.sqlsql/biz_grade_weight_config.sql 为准。

2.2 公共参数

statYear = YstatDate§1

边界 表达式
年区间起 Y-01-01 00:00:00
年区间止(已完成订单) statDate 23:59:59(见 §1
行情 7 日起 statDate − 6 日(含)
行情 7 日止 statDate(含)
按月分组键 MONTH(finish_time),应用层补全 1~12

默认行情市场(配置)

说明
优先 application.ymlbigscreen.trade-sales.default-market-name(默认 巴青牦牛交易市场
解析 biz_trade_marketdel_flag='0'market_name 等于配置值 → 取 id 作为 trade_market_id 过滤条件
未匹配 hasQuoteData=false,行情区块空态;日志告警

2.3 可选表 biz_trade_sales_screen_cache(性能优化)

非本期必建。

字段 类型 说明
id bigint(20) 主键
stat_year int(11) 统计年份
payload_json mediumtext §3.1 响应 JSON
expire_time datetime 过期时间
create_time datetime 写入时间

索引UNIQUE uk_stat_year (stat_year)。TTL 建议 1~5 分钟(与功能需求 §7.3 一致)。

2.4 查询口径(按表)

交易订单 biz_trade_order(对齐功能需求 §2.5

条件
纳入 del_flag='0' AND order_status='1'(已完成)
按年 finish_time[年区间起, 年区间止]
总览 COUNT(*) 订单笔数;SUM(total_heads)SUM(total_amount)
按月 GROUP BY MONTH(finish_time) → 当月 SUM(total_heads)SUM(total_amount)

销售去向(对齐 §2.8

条件
关联 biz_trade_order o JOIN biz_distributor d ON o.distributor_id = d.id AND d.del_flag='0'
订单 §2.4 已完成且在 Y 年内
分组 d.sales_destination(1 / 2 / 3)
指标 SUM(o.total_heads)(头);占比分母 = 当年已完成订单 SUM(total_heads)

应用层固定返回 3 档(本市 / 本省 / 外省),无数据为 0 头、ratio=0

品质等级 biz_trade_order_line(对齐 §2.9

条件
关联 line JOIN biz_trade_order o(同上已完成、年内)
分组 line.grade_code
名称 聚合时 max(line.grade_name);无快照时回退 biz_grade_weight_config.grade_name
指标 COUNT(*) 明细行(头);占比分母 = 当年已完成订单明细总行数
空等级 grade_code IS NULL 的行不计入品质占比;若分母为 0 → hasGradeData=false

应用层按配置表 sort_order 输出各等级;配置表有而当年无数据的等级 count=0ratio=0(可选,与产品约定;默认仅返回 count>0 的等级 + 固定四档补 0,推荐固定返回配置表全部等级便于饼图)。

入驻商铺 biz_supplier(对齐 §2.10

条件
指标 COUNT(*)
条件 del_flag='0'
Y 年份条件

日度行情 biz_market_daily_quote(对齐 §2.6、§2.7

条件
范围 del_flag='0' AND trade_market_id = {默认市场ID} AND quote_date BETWEEN 7 日起止
原始行 窗口内全部日度记录(含多维度:公母、重量档等)

应用层按 quote_date 聚合(TradeSalesScreenSupport

聚合项 规则
当日最低价 该日各条 price_minMIN
当日最高价 该日各条 price_maxMAX
当日均价 该日各条 avg_price算术平均
7 日卡片 7 个自然日「当日均价」有效值的平均;7 日内「当日最低价」的最小、「当日最高价」的最大;lastQuoteDate = 窗口内最大 quote_date
价格单位 窗口内 quote_date 最大那天的记录中 create_time 最新一条的 price_unit(1 元/头 / 2 元/斤)
缺日 7 日横轴仍输出该日;minPrice/maxPrice/avgPrice 均为 0(对齐功能需求 §5.3.2 默认)

2.5 索引建议(既有表)

建议
biz_trade_order (order_status, del_flag, finish_time)idx_finish_time
biz_trade_order_line (order_id)(已有 idx_order_id
biz_market_daily_quote (trade_market_id, quote_date, del_flag)
biz_distributor 沿用 idx_sales_destination

2.6 Mapper 扩展(建议)

Mapper 方法 说明
TradeSalesScreenMapper selectTradeOverviewByYear(y, endTime) 总览三项
TradeSalesScreenMapper selectMonthlyTradeByYear(y, endTime) 按月头数、金额
TradeSalesScreenMapper selectSalesDestinationByYear(y, endTime) 三档头数
TradeSalesScreenMapper selectQualityGradeByYear(y, endTime) grade_code 计数
TradeSalesScreenMapper selectQuotesInWindow(marketId, startDate, endDate) 行情原始行
TradeSalesScreenMapper selectDistinctFinishYears() 可选年份
BizSupplierMapper countForScreen() 可复用首页 countForScreen()

XML:mapper/screen/TradeSalesScreenMapper.xml


3. 接口设计

统一响应AjaxResultcode / msg / data)。

权限标识(示例)bigScreen:tradeSales:query

Base Path/bigScreen/tradeSales

# 说明 Method URI 权限
3.1 看板主数据(五区块合一) GET /bigScreen/tradeSales/dashboard bigScreen:tradeSales:query

前端:进入页 / 切换 statYear / 手动刷新 → 仅调用 3.1


3.1 看板主数据

Query

参数 类型 必填 说明
statYear string Y 四位年份;非法 → 业务异常(复用 AchievementReportValidation.parseStatYear
forceRefresh boolean N 默认 falsetrue 时跳过 §2.3 缓存

响应 data(顶层)

字段 类型 说明
statYear int 回显
statDate string 统计时点 yyyy-MM-dd
availableYears int[] biz_trade_order 已完成订单 YEAR(finish_time) 并集 + 当前年,降序
tradeOverview object 交易总览 §3.1.1
originQuote object 产地行情 §3.1.2
tradeMonthlyTrend array 数额趋势 §3.1.3
salesDestination array 销售去向 §3.1.4
qualityGrade object 品质等级 §3.1.5

3.1.1 tradeOverview

字段 类型 说明
orderCount long 牦牛交易订单数(笔)
tradeHeads long 牦牛交易量(头)
tradeAmount decimal 牦牛交易总额(元)
supplierCount long 入驻商铺数(家),实时

3.1.2 originQuote

字段 类型 说明
hasQuoteData boolean 7 日内是否存在行情登记
avgPrice7d decimal 7 日均价;无数据可为 null
minPrice7d decimal 7 日最低价
maxPrice7d decimal 7 日最高价
lastQuoteDate string 最近行情日 yyyy-MM-dd;无则 null
priceUnit int 1 元/头 / 2 元/斤
priceUnitLabel string 元/头
dailyTrend array 固定 7 条,按日期升序

dailyTrend[]

字段 说明
quoteDate yyyy-MM-dd
minPrice / maxPrice / avgPrice 当日聚合价;缺日为 0

3.1.3 tradeMonthlyTrend[]

固定 12 条。

字段 说明
month 1~12
tradeHeads 该月已完成订单总头数
tradeAmount 该月已完成订单总金额(元)

month > statDate.getMonth()Y 为当前年时两项为 0

3.1.4 salesDestination[]

固定 3 条。

字段 说明
salesDestination 1 / 2 / 3
salesDestinationName 本市 / 本省 / 外省
tradeHeads 头数
ratio 占比 0~100 数值(如 33.3 表示 33.3%),保留 1 位小数

3.1.5 qualityGrade

字段 说明
hasGradeData 当年是否存在 grade_code 非空的已完成明细
totalHeads 参与占比计算的明细总行数
items 数组

items[]

字段 说明
gradeCode A / B / C / D
gradeName 一级 / 二级等
tradeHeads 头数
ratio 占比 0~100,保留 1 位小数

响应示例(节选)

{
  "statYear": 2026,
  "statDate": "2026-05-20",
  "availableYears": [2026, 2025],
  "tradeOverview": {
    "orderCount": 12,
    "tradeHeads": 48,
    "tradeAmount": 960000.00,
    "supplierCount": 5
  },
  "originQuote": {
    "hasQuoteData": true,
    "avgPrice7d": 32.5,
    "minPrice7d": 30.0,
    "maxPrice7d": 35.0,
    "lastQuoteDate": "2026-05-20",
    "priceUnit": 2,
    "priceUnitLabel": "元/斤",
    "dailyTrend": [
      { "quoteDate": "2026-05-14", "minPrice": 31.0, "maxPrice": 33.0, "avgPrice": 32.0 }
    ]
  },
  "tradeMonthlyTrend": [
    { "month": 1, "tradeHeads": 10, "tradeAmount": 200000.00 },
    { "month": 12, "tradeHeads": 0, "tradeAmount": 0 }
  ],
  "salesDestination": [
    { "salesDestination": 1, "salesDestinationName": "本市", "tradeHeads": 20, "ratio": 41.7 }
  ],
  "qualityGrade": {
    "hasGradeData": true,
    "totalHeads": 48,
    "items": [
      { "gradeCode": "B", "gradeName": "二级", "tradeHeads": 30, "ratio": 62.5 }
    ]
  }
}

服务端逻辑(摘要)

1. year = parseStatYear(statYear); statDate = resolveStatDate(year); endTime = statDate 23:59:59
2. tradeOverview = orderMapper 总览(year, endTime) + supplierMapper.countForScreen()
3. tradeMonthlyTrend = orderMapper 按月 + buildMonthlySeries(12, year, statDate)
4. salesDestination = orderMapper JOIN distributor + fill3Buckets + ratio
5. qualityGrade = lineMapper 分组 + join grade_config + ratio; hasGradeData
6. marketId = resolveDefaultMarketId(configName)
7. rows = quoteMapper 7日窗口(marketId); originQuote = Support.aggregateQuote7d(rows, statDate)
8. availableYears = distinct finish years ∪ current year
9. return AjaxResult.success(vo)

4. 菜单与权限(示例)

类型 名称 权限标识
菜单 大屏交易销售 bigScreen:tradeSales:query

SQL 示例:sql/big_screen_trade_sales_perm.sql(挂载「大屏」父菜单下)。


5. 交付清单

  • TradeSalesScreenController + ITradeSalesScreenService + VO + TradeSalesScreenSupport
  • TradeSalesScreenMapper + XML(§2.6
  • application.yml 默认行情市场名配置项
  • 单元测试:历史年 statDate、12 月补 0、供应商数不随 Y 变、行情 7 日聚合、去向三档合计、品质占比
  • 接口测试:GET /bigScreen/tradeSales/dashboard
  • 菜单权限 SQL;依赖 biz_trade_order_line.grade_codebiz_grade_weight_config 已执行

6. 修订记录

版本 日期 说明
1.0 2026-05-20 初稿:无新表;单接口五区块;对齐 大屏交易销售功能需求.md v1.0;农资商城不纳入