西藏巴青项目

大屏畜牧资源技术方案.md 19KB

大屏 — 畜牧资源统计 — 技术方案

依据:同目录 大屏畜牧资源功能需求.md v1.4。核心总览取农村三资与畜牧产品产量;其余区块为 AI 诊断既有表。本模块为大屏只读看板统计移动端「畜牧资源」资讯视图 v_livestock_resource


1. 技术架构

说明
后端 RuoYi v3.9.2springboot2 分支):JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid
数据库 MySQL 5.7.39,InnoDB,utf8mb4
前端 ruoyi-screen 畜牧资源专题页(/livestock-resources);切换 statYear 拉取看板主数据(本期单接口
代码包 com.ruoyi.web.modules.screenLivestockResourceScreenController / ILivestockResourceScreenService / vo / support

分层ControllerILivestockResourceScreenService(口径编排、statDate/statDateTime)→ LivestockResourceScreenMapper(只读 SQL)+ LivestockResourceScreenSupport(7 日/24 小时补点、分类归一、占比、分档、关键词)。

场景 行为
进入 / 切换 statYear 调用 §3.1
数据权限 全县聚合;不按提问人/机构过滤
统计日 statDate 复用 HomeScreenSupport.resolveStatDate(Y)Y=当前年 → 今日(Asia/Shanghai);历史年 → Y-12-31
统计时刻 statDateTime 请求时 LocalDateTime.now(Asia/Shanghai);响应回显用
年内上界 会话 create_time;AI 消息 create_timestatDate 23:59:59(当前年)
「今日」四项 仅当 Y = 当前自然年时按 statDate 自然日统计;否则固定 0
用户结构 biz_consult_user 全表快照Y
7 日 / 分时 7 日以 statDate 滚动;分时为 距 statDateTime 最近 24 整点小时与 Y 无关
已隐藏会话 过滤 vet_visible(对齐功能需求 §2.18#2
性能 默认实时聚合;可选 §2.3 缓存表

依赖表(只读)

用途
biz_consult_session AI 会话数、用户去重、7 日/24 小时会话、分档分母
biz_consult_message 提问量(AI 回复)、耗时、分类、状态、关键词语料
biz_consult_user 新老用户结构
biz_rural_three_assets 核心总览 + 农村三资区块:经营性/非经营性/固定资产
biz_livestock_product_output 核心总览 + 产量月度趋势
biz_vaccination_data 核心总览 + 疫苗接种区块
biz_three_assets_problem_report 三资具体问题上报按等级
biz_medical_resource 核心总览:兽医人数
biz_tech_service_personnel 核心总览:科技特派员、农业事业单位

业务常量(与 ConsultSessionRules / AiConsultConstants 一致)

常量
consult_type AI 问诊 2
sender_role 提问人 / AI 1 / 3
AI 消息 sender_user_id 0
msg_type 文本 1
提问分类编码 14(养殖技巧/疾病诊疗/用药指导/设备操作)

2. 数据库设计

2.1 本模块业务表

无新增业务台账表。 DDL:sql/biz_consult_session.sqlsql/biz_consult_message.sqlsql/biz_consult_user.sql

当前问诊表 del_flag;纳入条件为:consult_type=2 的会话及其消息。已隐藏(vet_visible=0仍统计

2.2 时间边界(公共参数)

statYear = YstatDatestatDateTime§1

边界 表达式
年区间起 Y-01-01 00:00:00
年区间止(会话 create_time、AI 消息 create_time statDate 23:59:59
统计日区间 statDate 00:00:00statDate 23:59:59
近 7 日 [statDate − 6 日 00:00:00, statDate 23:59:59]
最近 24 小时 [floor(statDateTime 到整点) − 23 小时, floor(statDateTime 到整点) + 59 分 59 秒];SQL 按 DATE_FORMAT(create_time,'%Y%m%d%H') 分组

会话别名(下文)s = biz_consult_session,条件 s.consult_type = 2
AI 消息别名m_ai = biz_consult_messagem_ai.sender_role = 3 AND m_ai.sender_user_id = 0,且 EXISTS 关联 s.id = m_ai.session_id
提问人消息别名m_ask = biz_consult_messagem_ask.sender_role = 1,且关联 AI 会话 s

2.3 可选表 biz_livestock_resource_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 分钟

2.4 查询口径(按表)

2.4.1 核心总览

指标 数据源与 SQL 要点 statYear
经营性固定资产(万元) biz_rural_three_assetsSUM(operating_fixed_assets),全县各村 随 Y 变
非经营性固定资产(万元) 同上:SUM(non_operating_fixed_assets) 随 Y 变
肉产量(万吨) biz_livestock_product_output:所选年 最大 stat_month 全县 SUM(meat_output) 随 Y
奶产量(万吨) 同上:SUM(milk_output) 随 Y
免疫率(%) biz_vaccination_data:所选年最大月 (SUM(实免)/SUM(应免))×100,2 位小数;应免和为 0 → 0.00 随 Y
兽医(人) biz_medical_resourceresource_type='004001'del_flag='0' 计数 随 Y 变
科技特派员(人) biz_tech_service_personnel.envoy_total_count(单例 id=1) 随 Y 变
农业事业单位(人) 同上 agri_total_count 随 Y 变

无填报月或无行时对应产量/免疫率为 0;固定资产/人员无行时为 0

2.4.2 近 7 日活跃度

维度 SQL 要点
会话数/日 DATE(s.create_time) 分组,COUNT(s.id)
提问量/日 DATE(m_ai.create_time) 分组,COUNT(m_ai.id)

应用层:固定输出 7 个点(statDate−6statDate),缺日补 0

2.4.3 用户结构 biz_consult_user

类型 条件
新用户 DATEDIFF(last_use_time, first_use_time) <= 180
老用户 > 180

COUNT(*) 各一类;占比 = 人数 / (新+老),Y 条件。

2.4.4 提问分类 / 模型调用 / 热点榜(同源)

条件
统计行 m_aisender_role=3sender_user_id=0),create_time ∈ 年区间
分类键 同会话内 send_time ≤ m_ai.send_time 的最近提问人消息 ai_category;空 → UNCAT
条数 GROUP BY 分类键 COUNT(*)MAX(m_ai.create_time) 供热点二次排序
占比 分类 AI 回复条数 / 当年全部 AI 回复 × 100
热点 Top5 条数降序;同分按 lastEventTime 降序;取 5

2.4.5 分时使用热度(最近 24 小时)

维度 SQL 要点
会话 s.create_time ∈ 24h 窗口,GROUP BY DATE_FORMAT(create_time,'%Y%m%d%H')
提问量 m_ai.create_time ∈ 24h 窗口,同上分组

应用层:固定 24 桶(锚点整点向前 23 小时);bucketStart=HH:mmbucketDateTime=yyyy-MM-dd HH:mmhourlyHeat.windowEnd = 锚点整点 yyyy-MM-dd HH:mm

2.4.6 单次会话提问数量分布

子查询:按 session_id 统计年内 m_ai 条数 reply_cnt,再分档:

档位 code reply_cnt
LIGHT 1~2
NORMAL 3~4
ACTIVE 5~10
DEEP >10

COUNT(session_id) / 年内会话总数 → 占比;四档固定返回,无数据为 0。

2.4.7 会话状态分布

状态 条件
OK 正常应答 m_ai.cost_time IS NOT NULL含 0
FAIL 调用失败 m_ai.cost_time IS NULL

年内 COUNT(*) 及占比;两者之和 = 年内 AI 消息总数。

2.4.8 高频关键词

条件
语料 m_ask.msg_type = 1m_ask.content 非空,m_ask.send_time ∈ 年区间
处理 LivestockResourceScreenSupport.extractTopKeywords(texts, 30):分词 + 停用词(application.yml 可配路径或内置短表)

2.5 索引建议(既有表)

建议
biz_consult_session (consult_type, create_time)(consult_type, update_time)
biz_consult_message (session_id, sender_role, create_time)(create_time, sender_role)

2.6 Mapper 方法(建议)

Mapper 方法 说明
LivestockResourceScreenMapper selectOverview(...) 总览 8 项(可拆 2~3 条 SQL)
selectDailySessionCounts(start, end) 7 日会话
selectDailyAiReplyCounts(start, end) 7 日提问量
selectUserStructure() 新老用户
selectAskerCategoryCounts(yearStart, yearEnd) AI 回复按分类键聚合
selectAiReplyTotal(yearStart, yearEnd) 分类占比分母(年内 AI 回复总数)
selectHourlySessionCounts(windowStart, windowEnd) 最近 24h 会话
selectHourlyAiReplyCounts(windowStart, windowEnd) 最近 24h 提问量
selectSessionReplyBuckets(yearStart, yearEnd) 四档会话数
selectYearSessionTotal(yearStart, yearEnd) 年内会话总数
selectAiReplyStatusCounts(yearStart, yearEnd) 正常/失败
selectTextAskerContents(yearStart, yearEnd) 关键词语料
selectDistinctSessionYears() 可选年份下拉

XML:mapper/screen/LivestockResourceScreenMapper.xml


3. 接口设计

统一响应AjaxResultcode / msg / data)。

Base Path/bigScreen/livestockResource

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

# 说明 Method URI
3.1 看板主数据(十区块合一) GET /bigScreen/livestockResource/dashboard

前端:进入页 / 切换 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
statDateTime string yyyy-MM-dd HH:mm:ss,24h 窗口终点
availableYears int[] biz_consult_sessionconsult_type=2YEAR(create_time) 并集 + 当前年,降序
overview object 核心总览 §3.1.1
ruralThreeAssets object 农村三资数据
problemReportShare object 三资问题上报按等级
productOutputTrend object 畜牧产品产量月度趋势
vaccinationOverview object 疫苗接种免疫率
appointment object 线下服务预约:三项台账人数/机构数(不随年);monthlyStacked 为所选年 1~最大月预约次数
techEnvoyStructure object 科技特派员:党员/其他、男/女占比与人数
agriUnitStructure object 农业事业单位:员级/初级/中级/高级/管理级人数
agriClassroom object 农技课堂(自首页迁入)
trainingTrend object 实战培训报名:所选年 1~库中最大月;monthly[].statYear/month/activityCount/enrolledCount

已屏蔽(不再返回): activityTrenduserStructurecategorySharemodelCallAnalysishourlyHeatsessionReplyDistributionreplyStatusDistributionhotTopicstopKeywords

3.1.1 overview

字段 类型 说明
operatingFixedAssets decimal 经营性固定资产(万元),2 位小数
nonOperatingFixedAssets decimal 非经营性固定资产(万元),2 位小数
meatOutput decimal 肉产量(万吨),所选年最大填报月全县合计,4 位小数
milkOutput decimal 奶产量(万吨),同上
immunityRate decimal 免疫率(%),所选年最大填报月 (实免和/应免和)×100,2 位小数
vetCount long 兽医人数(004001 且未删除)
techEnvoyCount long 科技特派员总人数
agriUnitCount long 农业事业单位总人数

3.1.1a ruralThreeAssets

字段 类型 说明
operatingFixedAssets / nonOperatingFixedAssets / fixedAssets decimal 全县合计(万元),2 位小数;不随年变

3.1.1b problemReportShare

字段 类型 说明
totalCount long 所选年上报总次数
items[] array levelCode/levelName/count/ratio(一般/重点/重大)

3.1.1c productOutputTrend

字段 类型 说明
maxMonth int|null 所选年最大填报月
monthlySeries[] array 1~N:month/meatOutput/milkOutput(万吨,4 位)

3.1.1d vaccinationOverview

字段 类型 说明
statMonth int|null 最大填报月
immunityRate decimal 免疫率 %,2 位
shouldVaccinateCount / actualVaccinateCount long 应免/实免合计

3.1.1e appointment

字段 类型 说明
annualVetCount int 兽医人员数:biz_medical_resource resource_type=004001del_flag=0随年变
annualExpertCount int 专家人员数:biz_tech_resource resource_type=004005del_flag=0随年变
annualOrgCount int 诊疗机构数:biz_medical_resource resource_type=004003del_flag=0随年变
monthlyStacked[] array 所选年 1~最大月:statYear/month/vetCount/expertCount/orgCount(预约次数,排除 status 2/3)

3.1.2 activityTrend

字段 类型 说明
dailySeries array 固定 7

dailySeries[]

字段 说明
date yyyy-MM-dd
sessionCount 会话数
questionCount 提问量(AI 回复)

3.1.3 userStructure

字段 类型 说明
newUserCount long 新用户
oldUserCount long 老用户
newUserRatio decimal 占比 0~100
oldUserRatio decimal 占比 0~100

3.1.4 categoryShare

字段 类型 说明
totalAskerMessages long 分母:年内全部 AI 回复(字段名沿用,与提问人无关)
items array 分类项

items[]categoryCodecategoryNamecountratio(0~100,1 位小数)。固定含 14 + UNCAT(未分类),无数据 count=0

3.1.5 modelCallAnalysis[]

categoryShare.items 同源(可复用引用):categoryCodecategoryNamecount。展示为柱状图时前端取 count

3.1.6 hourlyHeat

字段 类型 说明
windowEnd string 锚点整点 yyyy-MM-dd HH:mm
hourlySeries array 固定 24

hourlySeries[]bucketStartHH:mm)、bucketDateTimeyyyy-MM-dd HH:mm,悬停)、sessionCountquestionCount

3.1.7 sessionReplyDistribution[]

固定 4 条。

字段 说明
bandCode LIGHT / NORMAL / ACTIVE / DEEP
bandName 轻度 / 一般 / 活跃 / 深度
sessionCount 会话数
ratio 占年内会话总数 %

3.1.8 replyStatusDistribution

字段 说明
totalAiReplies 年内 AI 回复总数
items 固定 2 条:OK(正常应答)、FAIL(调用失败),含 countratio

3.1.9 hotTopics[]

最多 5 条:categoryCodecategoryNamecountratio,按 ratiocount 降序。

3.1.10 topKeywords[]

最多 30 条:keywordcount

响应示例(节选)

{
  "statYear": 2026,
  "statDate": "2026-05-20",
  "statDateTime": "2026-05-20 15:30:00",
  "overview": {
    "operatingFixedAssets": 100.50,
    "nonOperatingFixedAssets": 200.25,
    "meatOutput": 1.2000,
    "milkOutput": 3.4000,
    "immunityRate": 90.00,
    "vetCount": 15,
    "techEnvoyCount": 30,
    "agriUnitCount": 40
  },
  "activityTrend": {
    "dailySeries": [
      { "date": "2026-05-14", "sessionCount": 3, "questionCount": 10 }
    ]
  },
  "categoryShare": {
    "totalAskerMessages": 500,
    "items": [
      { "categoryCode": "2", "categoryName": "疾病诊疗", "count": 200, "ratio": 40.0 }
    ]
  }
}

服务端逻辑(摘要)

1. year = parseStatYear(statYear)
2. statDate = resolveStatDate(year); statDateTime = now(Shanghai)
3. yearStart/end, dayStart/end, sevenStart, window24Start = Support.bounds(...)
4. overview = 三资 SUM + 所选年产量最大月 SUM(meat/milk)
5. activityTrend = Mapper 7日 + buildDailySeries(7, statDate)
6. userStructure = Mapper 新老 + ratio
7. category = Mapper 分类 + total;categoryShare/modelCall/hotTopics = Support.buildCategoryViews(...)
8. hourlyHeat = Mapper 24h + buildHourlySeries(24, statDateTime)
9. sessionReplyDistribution = Mapper 分档 + ratio
10. replyStatusDistribution = Mapper OK/FAIL + ratio
11. topKeywords = Support.extractTopKeywords(Mapper 文本语料, 30)
12. availableYears = distinct session years ∪ current year
13. return AjaxResult.success(vo)

4. 菜单与权限(示例)

类型 名称 权限标识
菜单 大屏畜牧资源 bigScreen:livestockResource:query

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


5. 交付清单

  • LivestockResourceScreenController + ILivestockResourceScreenService + VO + LivestockResourceScreenSupport
  • LivestockResourceScreenMapper + XML(§2.6
  • ruoyi-screen 对接 GET /bigScreen/livestockResource/dashboard(本期不改前端)
  • 单元测试:历史年今日为 0、7 日补 0、统计日 24 桶、分类占比、耗时含 0
  • 接口测试:MockMvc dashboard
  • 菜单权限 SQL;依赖 biz_consult_user、消息 cost_time/ai_category 字段已上线

6. 修订记录

版本 日期 说明
1.11 2026-07-24 看板屏蔽 AI 问诊九区块:活跃度/用户结构/分类/模型调用/分时/会话分布/状态/热门/关键词
1.10 2026-07-24 线下服务预约三项汇总改为资源台账:兽医 004001、机构 004003、专家 004005
1.9 2026-07-24 线下服务预约月度改为所选年 1~最大月
1.8 2026-07-24 实战培训报名改为所选年 1~最大月;前端横轴仅月、悬停显年月
1.7 2026-07-24 迁入线下预约/农技课堂/实战培训;新增科技特派员双层结构、农业事业单位职级柱图
1.6 2026-07-24 新增农村三资/问题上报/产量趋势/疫苗接种四区块
1.5 2026-07-24 核心总览扩展为 8 项:增免疫率、兽医、科技特派员、农业事业单位
1.4 2026-07-24 核心总览改为三资固定资产 + 所选年最大月肉/奶产量
1.0 2026-05-20 初稿:无新表;单接口十区块;对齐 大屏畜牧资源功能需求.md v1.1
1.2 2026-05-20 对齐草稿:今日活跃 update_time、日新增双时间、AI 回复+分类归因、统计日 0~23 时分、create_time 消息归属