Files
apes-Authon-history/docs/账权平台-项目说明书.html
T
figmar 9cbb1f7695 init: apes-Authon-history — 剥离历史与源码分析归档
- docs/: 源码分析报告、代码深度解析、项目说明书、独立服务化方案
- backend/: 账权模块提取说明(提取原则、文件清单、耦合度验证)
- frontend/: 前端剥离方案、剥离历史与说明、框架修改详情
2026-08-09 13:04:04 +08:00

1045 lines
49 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>账权平台 — 项目说明书</title>
<style>
:root {
--primary: #2563eb;
--primary-light: #dbeafe;
--success: #16a34a;
--success-light: #dcfce7;
--warning: #ea580c;
--warning-light: #fed7aa;
--danger: #dc2626;
--bg: #f8fafc;
--card-bg: #ffffff;
--border: #e2e8f0;
--text: #1e293b;
--text-light: #64748b;
--text-lighter: #94a3b8;
--code-bg: #f1f5f9;
--shadow: 0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.06);
--shadow-lg: 0 10px 25px rgba(0,0,0,.08), 0 4px 6px rgba(0,0,0,.04);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.7;
font-size: 15px;
}
/* Cover */
.cover {
background: linear-gradient(135deg, #1e3a5f 0%, #2563eb 100%);
color: white;
padding: 80px 40px 60px;
text-align: center;
position: relative;
overflow: hidden;
}
.cover::before {
content: '';
position: absolute;
top: -50%;
right: -20%;
width: 500px;
height: 500px;
background: rgba(255,255,255,.05);
border-radius: 50%;
}
.cover h1 { font-size: 2.6em; font-weight: 700; margin-bottom: 12px; letter-spacing: 2px; }
.cover .subtitle { font-size: 1.25em; opacity: .9; margin-bottom: 30px; }
.cover .meta { display: inline-flex; gap: 30px; font-size: .9em; opacity: .8; }
.cover .meta span { display: flex; align-items: center; gap: 6px; }
/* Container */
.container { max-width: 1100px; margin: 0 auto; padding: 0 24px; }
/* TOC */
.toc {
background: var(--card-bg);
border: 1px solid var(--border);
border-radius: 12px;
padding: 28px 32px;
margin: -30px auto 30px;
box-shadow: var(--shadow-lg);
position: relative;
z-index: 10;
}
.toc h2 { font-size: 1.2em; margin-bottom: 16px; color: var(--primary); }
.toc ol { list-style: none; counter-reset: toc; }
.toc > ol > li { counter-increment: toc; margin-bottom: 6px; }
.toc > ol > li::before {
content: counter(toc);
display: inline-block;
width: 24px; height: 24px;
background: var(--primary-light);
color: var(--primary);
border-radius: 6px;
text-align: center;
line-height: 24px;
font-size: .8em;
font-weight: 600;
margin-right: 10px;
}
.toc a { color: var(--text); text-decoration: none; transition: color .15s; }
.toc a:hover { color: var(--primary); }
/* Section */
.section {
background: var(--card-bg);
border: 1px solid var(--border);
border-radius: 12px;
padding: 32px;
margin-bottom: 24px;
box-shadow: var(--shadow);
}
.section h2 {
font-size: 1.5em;
color: var(--text);
margin-bottom: 20px;
padding-bottom: 12px;
border-bottom: 2px solid var(--primary-light);
display: flex;
align-items: center;
gap: 10px;
}
.section h2 .icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px; height: 32px;
background: var(--primary);
color: white;
border-radius: 8px;
font-size: .7em;
}
.section h3 {
font-size: 1.15em;
color: var(--text);
margin: 24px 0 12px;
padding-left: 12px;
border-left: 3px solid var(--primary);
}
.section h4 { font-size: 1em; color: var(--text); margin: 16px 0 8px; }
/* Cards */
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; margin: 16px 0; }
.card {
background: var(--bg);
border: 1px solid var(--border);
border-radius: 10px;
padding: 18px;
transition: box-shadow .2s, transform .2s;
}
.card:hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); }
.card-title { font-weight: 600; margin-bottom: 8px; color: var(--primary); }
.card-desc { font-size: .9em; color: var(--text-light); }
/* Table */
.table-wrap { overflow-x: auto; margin: 16px 0; border-radius: 8px; border: 1px solid var(--border); }
table { width: 100%; border-collapse: collapse; font-size: .9em; }
th { background: var(--bg); font-weight: 600; text-align: left; padding: 10px 14px; border-bottom: 2px solid var(--border); white-space: nowrap; }
td { padding: 9px 14px; border-bottom: 1px solid var(--border); }
tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--bg); }
/* Badge */
.badge {
display: inline-block;
padding: 2px 10px;
border-radius: 20px;
font-size: .8em;
font-weight: 500;
}
.badge-blue { background: var(--primary-light); color: var(--primary); }
.badge-green { background: var(--success-light); color: var(--success); }
.badge-orange { background: var(--warning-light); color: var(--warning); }
/* Code */
code {
background: var(--code-bg);
padding: 2px 6px;
border-radius: 4px;
font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
font-size: .85em;
color: #be185d;
}
.code-block {
background: #1e293b;
color: #e2e8f0;
padding: 16px 20px;
border-radius: 8px;
overflow-x: auto;
margin: 12px 0;
font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
font-size: .85em;
line-height: 1.6;
}
/* Info box */
.info-box {
background: var(--primary-light);
border-left: 4px solid var(--primary);
padding: 14px 18px;
border-radius: 0 8px 8px 0;
margin: 16px 0;
font-size: .9em;
}
.info-box.success { background: var(--success-light); border-color: var(--success); }
.info-box.warning { background: var(--warning-light); border-color: var(--warning); }
/* Architecture diagram */
.arch-diagram {
background: var(--bg);
border: 1px solid var(--border);
border-radius: 10px;
padding: 24px;
margin: 16px 0;
text-align: center;
}
.arch-layer {
display: flex;
justify-content: center;
gap: 12px;
margin-bottom: 8px;
flex-wrap: wrap;
}
.arch-layer:last-child { margin-bottom: 0; }
.arch-box {
background: white;
border: 2px solid var(--border);
border-radius: 8px;
padding: 10px 18px;
font-size: .85em;
font-weight: 500;
min-width: 100px;
}
.arch-box.primary { border-color: var(--primary); background: var(--primary-light); color: var(--primary); }
.arch-box.success { border-color: var(--success); background: var(--success-light); color: var(--success); }
.arch-box.warning { border-color: var(--warning); background: var(--warning-light); color: var(--warning); }
.arch-arrow { color: var(--text-lighter); font-size: 1.2em; margin: 2px 0; }
/* Feature list */
.feature-list { list-style: none; }
.feature-list li {
padding: 8px 0;
padding-left: 24px;
position: relative;
font-size: .92em;
}
.feature-list li::before {
content: '▸';
position: absolute;
left: 0;
color: var(--primary);
font-weight: 700;
}
/* Stats */
.stats-row { display: flex; gap: 16px; margin: 20px 0; flex-wrap: wrap; }
.stat-item {
flex: 1;
min-width: 140px;
background: linear-gradient(135deg, var(--primary) 0%, #1d4ed8 100%);
color: white;
border-radius: 10px;
padding: 20px;
text-align: center;
}
.stat-item .num { font-size: 2em; font-weight: 700; }
.stat-item .label { font-size: .85em; opacity: .85; margin-top: 4px; }
.stat-item.green { background: linear-gradient(135deg, var(--success) 0%, #15803d 100%); }
.stat-item.orange { background: linear-gradient(135deg, var(--warning) 0%, #c2410c 100%); }
.stat-item.dark { background: linear-gradient(135deg, #334155 0%, #1e293b 100%); }
/* Footer */
.footer {
text-align: center;
padding: 40px 20px;
color: var(--text-lighter);
font-size: .85em;
}
@media (max-width: 768px) {
.cover { padding: 50px 20px 40px; }
.cover h1 { font-size: 1.8em; }
.container { padding: 0 12px; }
.section { padding: 20px; }
.card-grid { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<!-- ==================== 封面 ==================== -->
<div class="cover">
<h1>账权平台</h1>
<div class="subtitle">项目技术说明书</div>
<div class="meta">
<span>版本 1.0.0</span>
<span>2026-08-05</span>
<span>cn.apes</span>
</div>
</div>
<div class="container">
<!-- ==================== 目录 ==================== -->
<div class="toc">
<h2>目录</h2>
<ol>
<li><a href="#sec1">项目概述</a></li>
<li><a href="#sec2">系统架构</a></li>
<li><a href="#sec3">后端服务 (saas-service)</a></li>
<li><a href="#sec4">前端应用 (saas-web)</a></li>
<li><a href="#sec5">核心功能模块</a></li>
<li><a href="#sec6">LLM / AI Agent 平台</a></li>
<li><a href="#sec7">多租户与权限体系</a></li>
<li><a href="#sec8">API 接口概览</a></li>
<li><a href="#sec9">部署与配置</a></li>
<li><a href="#sec10">项目目录结构</a></li>
</ol>
</div>
<!-- ==================== 1. 项目概述 ==================== -->
<div class="section" id="sec1">
<h2><span class="icon">1</span>项目概述</h2>
<p>账权平台是一套面向农业产业链的 <strong>多租户 SaaS 综合管理平台</strong>,涵盖智慧农业、产品溯源、自助过磅、AI 智能助手等核心业务域。平台采用前后端分离架构,后端基于 <strong>Spring Boot + MyBatis Plus</strong>,前端基于 <strong>Vue 2 + Element UI</strong>,通过多租户动态数据源实现企业级数据隔离。</p>
<div class="stats-row">
<div class="stat-item">
<div class="num">62</div>
<div class="label">后端 Controller</div>
</div>
<div class="stat-item green">
<div class="num">85+</div>
<div class="label">前端页面</div>
</div>
<div class="stat-item orange">
<div class="num">10+</div>
<div class="label">业务模块</div>
</div>
<div class="stat-item dark">
<div class="num">85+</div>
<div class="label">Mapper 接口</div>
</div>
</div>
<h3>项目组成</h3>
<div class="table-wrap">
<table>
<thead>
<tr><th>子项目</th><th>技术栈</th><th>说明</th><th>端口</th></tr>
</thead>
<tbody>
<tr>
<td><strong>saas-service</strong></td>
<td>Java 11 / Spring Boot 2.2.1</td>
<td>后端服务,提供全部 REST API</td>
<td><code>7777</code>(生产) / <code>8202</code>(开发)</td>
</tr>
<tr>
<td><strong>saas-web</strong></td>
<td>Vue 2.7 / Element UI 2.15</td>
<td>前端管理控制台</td>
<td><code>8201</code>(开发)</td>
</tr>
</tbody>
</table>
</div>
<h3>核心业务域</h3>
<div class="card-grid">
<div class="card">
<div class="card-title">智慧农业</div>
<div class="card-desc">园区/地块/作物管理、灌溉计划、水肥一体机、电磁阀控制、农事计划、投入品管理、设备数据上报、摄像头监控</div>
</div>
<div class="card">
<div class="card-title">产品溯源</div>
<div class="card-desc">溯源码生成与绑定、码货关联、采收/加工/质检全链条、仓储出入库、物流追踪、溯源大屏</div>
</div>
<div class="card">
<div class="card-title">自助过磅</div>
<div class="card-desc">车辆/司机/IC卡管理、北斗卡借还追踪、称重票据、报警规则、过磅工作台、小票打印</div>
</div>
<div class="card">
<div class="card-title">AI Agent 平台</div>
<div class="card-desc">多厂商 LLM 配置、Agent 编排、Groovy 动态工具、Function Calling、技能注入、多轮对话、调用审计</div>
</div>
<div class="card">
<div class="card-title">多租户 SaaS</div>
<div class="card-desc">企业认证、套餐配额管理、角色权限体系、SSO 单点登录、AccessToken 开放平台</div>
</div>
<div class="card">
<div class="card-title">伙伴云集成</div>
<div class="card-desc">伙伴云低代码平台深度对接、表结构同步、数据 CRUD 代理、SSO 登录、AMIS 页面配置</div>
</div>
</div>
</div>
<!-- ==================== 2. 系统架构 ==================== -->
<div class="section" id="sec2">
<h2><span class="icon">2</span>系统架构</h2>
<h3>整体架构图</h3>
<div class="arch-diagram">
<div class="arch-layer">
<div class="arch-box primary" style="min-width: 200px;">浏览器 / 移动端 / 外部系统</div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box primary" style="min-width: 200px;">Nginx 反向代理</div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box success" style="min-width: 160px;">saas-web<br><small>Vue 2 + Element UI</small></div>
<div class="arch-box success" style="min-width: 160px;">saas-service<br><small>Spring Boot REST API</small></div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box">MySQL<br><small>cloud (主库)</small></div>
<div class="arch-box">MySQL<br><small>user (租户库)</small></div>
<div class="arch-box">Redis<br><small>DB7 / DB9</small></div>
<div class="arch-box">阿里云 OSS<br><small>文件存储</small></div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box warning">阿里云 DashScope<br><small>LLM API</small></div>
<div class="arch-box warning">伙伴云 OpenAPI<br><small>低代码平台</small></div>
<div class="arch-box warning">萤石云 API<br><small>视频监控</small></div>
<div class="arch-box warning">阿里云 ASR<br><small>语音识别</small></div>
<div class="arch-box warning">n8n<br><small>工作流引擎</small></div>
</div>
</div>
<h3>技术栈总览</h3>
<div class="table-wrap">
<table>
<thead>
<tr><th>类别</th><th>后端 (saas-service)</th><th>前端 (saas-web)</th></tr>
</thead>
<tbody>
<tr><td>核心框架</td><td>Spring Boot 2.2.1 / Java 11</td><td>Vue 2.7.14</td></tr>
<tr><td>路由/状态</td><td></td><td>Vue Router 3.5 / Vuex 3.1</td></tr>
<tr><td>ORM / 数据</td><td>MyBatis Plus 3.5.7 + 动态数据源 3.6.1</td><td></td></tr>
<tr><td>UI 组件</td><td></td><td>Element UI 2.15.13</td></tr>
<tr><td>缓存</td><td>Redis + Redisson 3.35.0</td><td>localStorage</td></tr>
<tr><td>HTTP</td><td>Spring MVC</td><td>Axios 0.18.1</td></tr>
<tr><td>对象存储</td><td>阿里云 OSS SDK 3.17.4</td><td></td></tr>
<tr><td>LLM / AI</td><td>DashScope (OpenAI 兼容) + Groovy 3.0.19</td><td>Monaco Editor / marked / highlight.js</td></tr>
<tr><td>WebSocket</td><td>Spring WebSocket + Java-WebSocket</td><td>原生 WebSocket (ASR)</td></tr>
<tr><td>工具库</td><td>Hutool 5.8.16 / Lombok / Apache POI</td><td>ECharts 5.4 / 高德地图 / WangEditor</td></tr>
<tr><td>构建工具</td><td>Maven</td><td>Vue CLI 4.4.4 / Webpack</td></tr>
</tbody>
</table>
</div>
</div>
<!-- ==================== 3. 后端服务 ==================== -->
<div class="section" id="sec3">
<h2><span class="icon">3</span>后端服务 (saas-service)</h2>
<h3>3.1 基本信息</h3>
<div class="table-wrap">
<table>
<tbody>
<tr><td width="180">GroupId / ArtifactId</td><td><code>cn.apes / saas-service</code></td></tr>
<tr><td>版本</td><td>1.0.0-SNAPSHOT</td></tr>
<tr><td>主启动类</td><td><code>cn.apes.CloudApplication</code>(启用 @EnableAsync / @EnableScheduling</td></tr>
<tr><td>根包</td><td><code>cn.apes.cloud</code></td></tr>
<tr><td>生产端口</td><td>7777</td></tr>
<tr><td>开发端口</td><td>8202</td></tr>
</tbody>
</table>
</div>
<h3>3.2 包结构</h3>
<div class="code-block">
cn.apes.cloud
├── config/ # 配置类(12个):RedissonConfig, OssConfig, DataSourceConfig...
├── controller/ # REST 控制器(62个)
│ └── traceability/ # 溯源模块控制器(9个)
├── domain/ # 数据模型层
│ ├── entity/ # 核心实体(43个)
│ ├── dto/ # 数据传输对象(35个)
│ ├── vo/ # 视图对象(5个)
│ ├── huoban/ # 伙伴云数据模型(11个)
│ ├── traceability/ # 溯源数据模型(22个)
│ └── weight/ # 称重数据模型(13个)
├── filter/ # AccessToken 鉴权过滤器
├── groovy/ # Groovy 脚本执行引擎
│ ├── GroovyExecutorService.java # 编译+缓存+执行
│ ├── GroovyToolExecutor.java # 工具接口
│ └── JsonSchemaValidator.java # 入参校验
├── mapper/ # MyBatis Mapper85个)
│ └── traceability/ # 溯源 Mapper20个)
├── service/ # 业务逻辑层
│ ├── impl/ # 服务实现(90个)
│ │ └── huoban/ # 伙伴云服务(6个)
├── task/ # 定时任务(摄像头抓图)
├── util/ # 工具类
└── websocket/ # ASR 语音识别 WebSocket 代理</div>
<h3>3.3 数据源配置</h3>
<p>采用 <code>baomidou dynamic-datasource</code> 实现多数据源动态切换,通过自定义 <code>@TenantSource</code> 注解 + AOP 切面,根据请求头 <code>X-Tenant-ID</code> 自动切换数据源。</p>
<div class="table-wrap">
<table>
<thead><tr><th>数据源</th><th>目标数据库</th><th>用途</th></tr></thead>
<tbody>
<tr><td><code>cloud</code>(主库)</td><td>MySQL 192.168.1.161:3306/cloud</td><td>平台核心数据(用户、企业、权限、LLM 配置等)</td></tr>
<tr><td><code>user</code>(租户库)</td><td>MySQL 192.168.1.161:3306/user</td><td>租户业务数据(溯源、农业、称重等)</td></tr>
<tr><td><code>huoban</code></td><td>伙伴云 MySQL</td><td>直连伙伴云数据库(数据同步/CRUD</td></tr>
</tbody>
</table>
</div>
<div class="info-box">
<strong>多租户切换原理:</strong>请求头 <code>X-Tenant-ID</code> 值为 <code>user</code>/<code>zx</code>/<code>plant</code> 时,<code>DataSourceHeaderAspect</code> 切面自动调用 <code>DynamicDataSourceContextHolder.push()</code> 切换到对应数据源。默认使用 <code>user</code> 数据源。
</div>
<h3>3.4 核心配置类</h3>
<div class="table-wrap">
<table>
<thead><tr><th>配置类</th><th>功能</th></tr></thead>
<tbody>
<tr><td>RedissonConfiguration</td><td>Redisson 客户端,DB7(主业务)+ DB9(辅助),JsonJackson 编解码</td></tr>
<tr><td>OssConfiguration</td><td>阿里云 OSS,桶 <code>zq-cloud</code>,区域 <code>oss-cn-beijing</code></td></tr>
<tr><td>DataSourceHeaderAspect</td><td>多租户数据源切换 AOP 切面</td></tr>
<tr><td>AccessTokenFilterConfig</td><td>AccessToken 外部 API 鉴权过滤器注册</td></tr>
<tr><td>WebSocketConfig</td><td>ASR 语音识别 WebSocket 端点 <code>/asr/ws</code></td></tr>
</tbody>
</table>
</div>
<h3>3.5 定时任务</h3>
<div class="card">
<div class="card-title">摄像头定时抓图 (CameraCaptureTask)</div>
<div class="card-desc">每小时执行一次,遍历所有摄像头调用萤石云 API 抓图,记录成功/失败统计日志。</div>
</div>
</div>
<!-- ==================== 4. 前端应用 ==================== -->
<div class="section" id="sec4">
<h2><span class="icon">4</span>前端应用 (saas-web)</h2>
<h3>4.1 基本信息</h3>
<div class="table-wrap">
<table>
<tbody>
<tr><td width="180">项目名称</td><td>saas-web(账权平台)</td></tr>
<tr><td>框架</td><td>Vue 2.7.14 + Vue Router 3.5.2 (History 模式) + Vuex 3.1.0</td></tr>
<tr><td>UI 组件库</td><td>Element UI 2.15.13(中文语言包)</td></tr>
<tr><td>构建工具</td><td>Vue CLI 4.4.4 + Webpack + Sass</td></tr>
<tr><td>开发端口</td><td>8201host: 0.0.0.0</td></tr>
<tr><td>输出目录</td><td>saas-web</td></tr>
</tbody>
</table>
</div>
<h3>4.2 目录结构</h3>
<div class="code-block">
src/
├── main.js # 应用入口
├── App.vue # 根组件
├── api/ # API 接口层(35个文件)
├── assets/ # 静态资源
├── components/ # 公共组件(面包屑/标签页/AI助手/大屏组件等)
├── config/ # 全局配置
├── layout/ # 布局(TopHeader + Sidebar + TagsView
├── router/ # 路由配置(静态路由 + 动态路由注册)
├── store/ # Vuexuser / settings / tagsView
├── styles/ # 全局样式(SCSS 变量/Mixin/Element UI 覆盖)
├── utils/ # 工具函数(16个文件)
└── views/ # 页面视图(85+文件,41个子目录)</div>
<h3>4.3 布局架构</h3>
<div class="arch-diagram">
<div class="arch-layer">
<div class="arch-box primary" style="min-width: 300px;">layout/index.vue(主布局容器)</div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box success">TopHeader<br><small>Logo + 应用Tab + 用户菜单</small></div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box">Sidebar<br><small>三级树形菜单</small></div>
<div class="arch-box" style="min-width: 200px;">el-main<br><small>TagsView + keep-alive</small></div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box warning">router-view(页面内容)</div>
<div class="arch-box warning">iframeView(内嵌页面)</div>
</div>
</div>
<div class="info-box">
<strong>独立大屏页面</strong><code>noLayout: true</code>)不使用主布局,可脱离侧栏/顶栏独立访问,支持通过 URL Token 参数从外部系统直接跳转。包括:智慧农业大屏、武鸣沃柑大脑、溯源大屏。
</div>
<h3>4.4 动态路由系统</h3>
<p>前端路由分为<strong>静态路由</strong>(登录/注册/认证等)和<strong>动态路由</strong>两部分。动态路由通过 <code>menuApi.handleMenu()</code> 根据后端返回的菜单数据动态注册:</p>
<div class="table-wrap">
<table>
<thead><tr><th>menuType</th><th>类型</th><th>路由前缀</th><th>加载方式</th></tr></thead>
<tbody>
<tr><td>1</td><td>普通页面</td><td><code>/common/{menuPath}</code></td><td>动态 import vuePath 组件</td></tr>
<tr><td>2</td><td>伙伴云内嵌</td><td><code>/common/huoban/{id}</code></td><td>加载 huoban/index 组件</td></tr>
<tr><td>3</td><td>支付页面</td><td><code>/common/payment/{id}</code></td><td>加载 payment/index 组件</td></tr>
<tr><td>4</td><td>Web 内嵌</td><td><code>/common/web/{id}</code></td><td>加载 web/index 组件</td></tr>
</tbody>
</table>
</div>
<h3>4.5 Vuex 状态管理</h3>
<div class="table-wrap">
<table>
<thead><tr><th>模块</th><th>核心 State</th><th>说明</th></tr></thead>
<tbody>
<tr>
<td>user</td>
<td>loginUser, menuList, currentCustomer, huobanToken, appList, currentApp, allAppMenus</td>
<td>用户登录态、企业信息、菜单树、多应用切换</td>
</tr>
<tr>
<td>settings</td>
<td>sidebarCollapsed</td>
<td>侧栏折叠状态</td>
</tr>
<tr>
<td>tagsView</td>
<td>visitedViews, cachedViews</td>
<td>标签页管理,支持 localStorage 持久化</td>
</tr>
</tbody>
</table>
</div>
<h3>4.6 第三方库</h3>
<div class="card-grid">
<div class="card"><div class="card-title">ECharts 5.4</div><div class="card-desc">数据可视化图表,用于大屏和报表</div></div>
<div class="card"><div class="card-title">高德地图</div><div class="card-desc">园区地图标注、物流轨迹追踪</div></div>
<div class="card"><div class="card-title">Monaco Editor</div><div class="card-desc">VS Code 内核代码编辑器,支持 Java/Groovy/JSON/SQL 语法高亮</div></div>
<div class="card"><div class="card-title">WangEditor</div><div class="card-desc">富文本编辑器,用于内容编辑</div></div>
<div class="card"><div class="card-title">html2canvas</div><div class="card-desc">网页截图,用于大屏导出</div></div>
<div class="card"><div class="card-title">marked + highlight.js</div><div class="card-desc">Markdown 渲染 + 代码高亮,用于 AI 对话展示</div></div>
<div class="card"><div class="card-title">qrcodejs2</div><div class="card-desc">二维码生成,用于溯源码</div></div>
<div class="card"><div class="card-title">萤石云 SDK</div><div class="card-desc">视频监控实时流播放</div></div>
</div>
</div>
<!-- ==================== 5. 核心功能模块 ==================== -->
<div class="section" id="sec5">
<h2><span class="icon">5</span>核心功能模块</h2>
<h3>5.1 用户与企业认证</h3>
<ul class="feature-list">
<li><strong>用户注册/登录</strong>:密码登录 + 微信小程序登录(code2Session</li>
<li><strong>企业认证</strong>:提交营业执照 → 平台审核 → 认证通过/驳回 → 重新提交</li>
<li><strong>多企业切换</strong>:一个用户可关联多个企业,支持切换当前企业</li>
<li><strong>SSO 单点登录</strong>:支持企业配置 SSO,对接伙伴云 SSO 登录</li>
<li><strong>AccessToken</strong>:外部 API 鉴权令牌,支持 IP 白名单、过期时间、启用/停用</li>
</ul>
<h3>5.2 智慧农业(飞翼)</h3>
<ul class="feature-list">
<li><strong>园区 & 地块管理</strong>:园区信息 CRUD、地块信息管理(坐标、面积、作物关联)</li>
<li><strong>作物管理</strong>:作物信息、物候期管理(生长期阶段定义)</li>
<li><strong>农事计划</strong>:施肥/灌溉/采收计划制定与执行跟踪</li>
<li><strong>灌溉系统</strong>:灌溉计划管理、定时执行、执行记录、电磁阀远程控制</li>
<li><strong>水肥一体机</strong>:设备管理、母液罐配置、加药操作、加药日志、设备布局可视化</li>
<li><strong>投入品管理</strong>:肥料/农药等投入品库存管理、出入库日志</li>
<li><strong>设备数据上报</strong>:传感器数据采集(温湿度、土壤等)</li>
<li><strong>摄像头监控</strong>:萤石云摄像头管理、定时抓图、抓图日志</li>
<li><strong>可视化大屏</strong>:园区数据可视化大屏,含地图、图表、设备状态</li>
</ul>
<h3>5.3 产品溯源</h3>
<ul class="feature-list">
<li><strong>溯源码管理</strong>:批量生成、码列表查询、绑定/解绑/作废/启用</li>
<li><strong>码货绑定</strong>:批量导入绑定、未绑定码查询、父子码关联</li>
<li><strong>全链条追溯</strong>:土地 → 采收 → 加工 → 质检 → 入库 → 出库 → 物流 → 反馈/召回</li>
<li><strong>资质与证书</strong>:企业资质管理、产品合格证生成</li>
<li><strong>仓储管理</strong>:入库/出库记录、库存查询、库位平面图</li>
<li><strong>溯源大屏</strong>:冷库温湿度、利用率、分级图表、采收进度、物流轨迹地图</li>
<li><strong>H5 溯源页</strong>:消费者扫码查看产品全链条溯源信息</li>
</ul>
<h3>5.4 自助过磅</h3>
<ul class="feature-list">
<li><strong>称重票据</strong>:一次称重 / 二次称重 / 编辑 / 打印全流程</li>
<li><strong>车辆 & 司机管理</strong>:车辆记录、司机信息、IC 卡管理</li>
<li><strong>北斗卡管理</strong>:借用 / 归还 / 追踪记录、报警规则与报警记录</li>
<li><strong>过磅工作台</strong>:自助过磅操作界面</li>
<li><strong>小票打印</strong>:独立打印页面,支持热敏打印机</li>
</ul>
<h3>5.5 套餐与配额管理</h3>
<ul class="feature-list">
<li><strong>套餐方案</strong>:定义套餐包含的应用、权限、配额</li>
<li><strong>客户套餐</strong>:为客户分配套餐,管理配额增减</li>
<li><strong>配额管理</strong>:系统配额定义(如溯源码数量、AI 调用次数等)</li>
<li><strong>套餐延期</strong>:延期申请 → 审核 → 生效</li>
<li><strong>配额变更日志</strong>:完整记录配额增减历史</li>
</ul>
<h3>5.6 伙伴云集成</h3>
<ul class="feature-list">
<li><strong>双模式集成</strong>:直连伙伴云 MySQL<code>@DS("huoban")</code>+ 伙伴云 OpenAPI 代理</li>
<li><strong>表结构同步</strong>:自动同步伙伴云表格结构到本地配置</li>
<li><strong>数据 CRUD 代理</strong>:通过平台 API 操作伙伴云表格数据</li>
<li><strong>SSO 登录</strong>:平台 Token → 伙伴云 Token 免密登录</li>
<li><strong>AMIS 低代码</strong>:支持 AMIS 页面配置和动态渲染</li>
<li><strong>自动化按钮</strong>:伙伴云自动化工作流触发</li>
</ul>
</div>
<!-- ==================== 6. LLM / AI Agent 平台 ==================== -->
<div class="section" id="sec6">
<h2><span class="icon">6</span>LLM / AI Agent 平台</h2>
<p>平台内置完整的 <strong>LLM Agent 管理引擎</strong>,支持多厂商模型配置、Agent 编排、Groovy 动态工具、Function Calling 多轮对话、技能注入和全链路审计。</p>
<h3>6.1 架构层次</h3>
<div class="arch-diagram">
<div class="arch-layer">
<div class="arch-box primary" style="min-width: 280px;">Agent 配置 (LlmAgentConfig)<br><small>System Prompt / User Prompt / Output Type</small></div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box">厂商配置<br><small>LlmProviderConfig</small></div>
<div class="arch-box">模型配置<br><small>LlmModelConfig</small></div>
<div class="arch-box">关联工具<br><small>LlmAgentTool → LlmTool</small></div>
<div class="arch-box">关联技能<br><small>LlmAgentSkill → AiSkill</small></div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box success" style="min-width: 280px;">LLM 调用 (DashScope OpenAI 兼容 API)<br><small>多轮对话 + Function Calling(最多10轮)</small></div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box warning">GroovyExecutorService<br><small>动态编译执行工具脚本</small></div>
<div class="arch-box warning">LlmConversationMessage<br><small>消息持久化</small></div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box">LlmCallLog<br><small>调用日志审计</small></div>
<div class="arch-box">LlmToolLog<br><small>工具执行日志</small></div>
</div>
</div>
<h3>6.2 核心能力</h3>
<div class="card-grid">
<div class="card">
<div class="card-title">多厂商模型配置</div>
<div class="card-desc">支持配置多个 LLM 厂商(API Key、BaseUrl),每个厂商下可配置多个模型(chat/embedding/image),支持视觉模型</div>
</div>
<div class="card">
<div class="card-title">Function Calling</div>
<div class="card-desc">自动检测 LLM 返回的 tool_calls,执行对应 Groovy 工具脚本,将结果回传给 LLM 继续推理,最多 10 轮防止死循环</div>
</div>
<div class="card">
<div class="card-title">Groovy 动态工具</div>
<div class="card-desc">使用 GroovyClassLoader 动态编译脚本,编译结果缓存(ConcurrentHashMap),支持 JSON Schema 入参校验,无需重启即可添加新工具</div>
</div>
<div class="card">
<div class="card-title">技能系统</div>
<div class="card-desc">AiSkill 技能内容注入 System Prompt,为 Agent 提供领域知识,一个 Agent 可关联多个技能</div>
</div>
<div class="card">
<div class="card-title">多轮对话</div>
<div class="card-desc">LlmConversation 会话管理 + LlmConversationMessage 消息持久化,支持 system/user/assistant/tool_call/tool_result 多种消息类型</div>
</div>
<div class="card">
<div class="card-title">提示词模板</div>
<div class="card-desc">支持 <code>&#123;&#123;variable&#125;&#125;</code> 格式的变量替换,通过 userParams 传入动态参数</div>
</div>
<div class="card">
<div class="card-title">多模态输入</div>
<div class="card-desc">支持图片 URLimage_url)和视频 URLvideo_url)输入,兼容视觉理解模型</div>
</div>
<div class="card">
<div class="card-title">输出类型控制</div>
<div class="card-desc">支持 text / json / markdown 三种输出格式,通过 response_format 控制</div>
</div>
<div class="card">
<div class="card-title">全链路审计</div>
<div class="card-desc">LlmCallLog 记录每次调用的 Token 用量、耗时、状态;LlmToolLog 记录工具执行的输入/输出/耗时/错误</div>
</div>
<div class="card">
<div class="card-title">ASR 语音识别</div>
<div class="card-desc">WebSocket 代理阿里云实时 ASRfun-asr-realtime),PCM 16kHz 音频流式传输,前端实时显示转写结果</div>
</div>
</div>
<h3>6.3 前端 AI 页面</h3>
<div class="table-wrap">
<table>
<thead><tr><th>页面</th><th>路径</th><th>功能</th></tr></thead>
<tbody>
<tr><td>智能对话</td><td><code>/ai/chat</code></td><td>多轮对话界面,支持图片/视频上传、Markdown 渲染</td></tr>
<tr><td>Agent 配置</td><td><code>/system/agent</code></td><td>Agent CRUD、工具/技能关联、调试</td></tr>
<tr><td>模型管理</td><td><code>/system/model</code></td><td>厂商/模型配置</td></tr>
<tr><td>工具管理</td><td><code>/system/tool</code></td><td>Groovy 工具脚本编辑(Monaco Editor+ 执行测试</td></tr>
<tr><td>技能管理</td><td><code>/system/skill</code></td><td>AI 技能 CRUD</td></tr>
<tr><td>对话历史</td><td><code>/ai/conversation</code></td><td>会话列表 + 消息详情</td></tr>
<tr><td>调用日志</td><td><code>/system/callLog</code></td><td>LLM 调用日志查询 + 统计</td></tr>
</tbody>
</table>
</div>
</div>
<!-- ==================== 7. 多租户与权限 ==================== -->
<div class="section" id="sec7">
<h2><span class="icon">7</span>多租户与权限体系</h2>
<h3>7.1 多租户架构</h3>
<div class="info-box">
<strong>实现方式:</strong>基于 <code>baomidou dynamic-datasource</code> + 自定义 <code>@TenantSource</code> 注解 + AOP 切面,通过 HTTP 请求头 <code>X-Tenant-ID</code> 实现透明数据源切换。
</div>
<div class="table-wrap">
<table>
<thead><tr><th>租户标识</th><th>数据源</th><th>说明</th></tr></thead>
<tbody>
<tr><td><code>user</code>(默认)</td><td>user 数据库</td><td>标准租户业务数据</td></tr>
<tr><td><code>zx</code></td><td>zx 数据库</td><td>专线租户</td></tr>
<tr><td><code>plant</code></td><td>plant 数据库</td><td>种植租户</td></tr>
</tbody>
</table>
</div>
<h3>7.2 权限体系</h3>
<div class="arch-diagram">
<div class="arch-layer">
<div class="arch-box primary">套餐 (PackagePlan)</div>
<div class="arch-box"></div>
<div class="arch-box primary">应用 (App)</div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box success">菜单 (Menu)</div>
<div class="arch-box"></div>
<div class="arch-box success">权限 (Permission)</div>
</div>
<div class="arch-arrow"></div>
<div class="arch-layer">
<div class="arch-box warning">角色 (Role)</div>
<div class="arch-box"></div>
<div class="arch-box warning">成员 (Member)</div>
</div>
</div>
<ul class="feature-list">
<li><strong>套餐 → 应用</strong>:套餐方案定义客户可使用的应用列表和配额</li>
<li><strong>应用 → 菜单/权限</strong>:每个应用有独立的菜单树和权限项</li>
<li><strong>角色 → 权限</strong>:角色绑定权限项,支持按应用分组</li>
<li><strong>成员 → 角色</strong>:企业成员分配角色,按企业维度管理</li>
<li><strong>前端动态路由</strong>:登录后根据权限动态生成路由和菜单</li>
</ul>
<h3>7.3 AccessToken 开放平台</h3>
<p>为外部系统提供安全的 API 调用机制:</p>
<ul class="feature-list">
<li>Token 通过 <code>X-Access-Token</code><code>Authorization: Bearer</code> 传递</li>
<li>支持 IP 白名单限制</li>
<li>支持启用/停用/重新生成</li>
<li>校验通过后将用户/企业信息注入请求上下文</li>
<li>配额扣减:开放接口可扣减客户套餐配额</li>
</ul>
</div>
<!-- ==================== 8. API 接口概览 ==================== -->
<div class="section" id="sec8">
<h2><span class="icon">8</span>API 接口概览</h2>
<p>后端共 <strong>62 个 Controller</strong>,提供 300+ REST API 端点。所有接口前缀为 <code>/api/user-service/</code>(通过 Nginx 代理)。</p>
<h3>8.1 接口模块总览</h3>
<div class="table-wrap">
<table>
<thead><tr><th>模块</th><th>主要 Controller</th><th>路径前缀</th><th>核心端点</th></tr></thead>
<tbody>
<tr><td rowspan="2">用户认证</td><td>UserController</td><td><code>/user</code></td><td>loginPwd, register, getCurrentUser, selectCustomer, certifyEnterprise</td></tr>
<tr><td>CommonController</td><td><code>/common</code></td><td>upload, code2Session, huobanWebLogin</td></tr>
<tr><td>客户管理</td><td>CustomerController</td><td><code>/customer</code></td><td>pageCustomer, saveCustomer, employee/page, auditCertification, syncTenantsToHuoban</td></tr>
<tr><td>权限管理</td><td>PermissionController</td><td><code>/permission</code></td><td>currentMenus, getMyPermissionCodes, saveRole, setRolePermission, setMemberRole</td></tr>
<tr><td>AccessToken</td><td>AccessTokenController</td><td><code>/sysAccessToken</code></td><td>create, page, revoke, regenerate</td></tr>
<tr><td rowspan="7">LLM / AI</td><td>LlmChatController</td><td><code>/llmChat</code></td><td><strong>start</strong>(新对话), <strong>continue</strong>(多轮对话)</td></tr>
<tr><td>LlmAgentConfigController</td><td><code>/llmAgent</code></td><td>page, add, update, delete, <strong>debug</strong>, <strong>call/{id}</strong></td></tr>
<tr><td>LlmProviderConfigController</td><td><code>/llmProvider</code></td><td>page, add, update, delete, list</td></tr>
<tr><td>LlmModelConfigController</td><td><code>/llmModel</code></td><td>page, add, update, delete, list</td></tr>
<tr><td>LlmToolController + GroovyToolExecuteController</td><td><code>/llmTool</code></td><td>CRUD, <strong>execute</strong>(执行 Groovy 脚本), clearCache</td></tr>
<tr><td>LlmConversationController</td><td><code>/llmConversation</code></td><td>add, detail, listByAgent, messages, close, delete</td></tr>
<tr><td>LlmCallLogController</td><td><code>/llmCallLog</code></td><td>page, detail, statistics, batchDelete</td></tr>
<tr><td>伙伴云</td><td>HuobanController / Huoban2Controller</td><td><code>/huoban</code> / <code>/huoban2</code></td><td>syncTables, data, create, update, upsert, webLogin, automationCall</td></tr>
<tr><td rowspan="4">溯源</td><td>TraceCodeController</td><td><code>/trace/code</code></td><td>task/generate, list/bind, bind/batchImport, relation/add</td></tr>
<tr><td>TraceCategoryController</td><td><code>/trace/category</code></td><td>分类 CRUD</td></tr>
<tr><td>TraceWarehouseController</td><td><code>/trace/warehouse</code></td><td>入库/出库 CRUD</td></tr>
<tr><td>TraceQualityController</td><td><code>/trace/quality</code></td><td>质检 CRUD</td></tr>
<tr><td rowspan="3">智慧农业</td><td>FeiParkInfoController / PlotInfoController</td><td><code>/park</code> / <code>/fei/plot</code></td><td>园区/地块 CRUD</td></tr>
<tr><td>FeiIrrigationPlanController</td><td><code>/irrigation/plan</code></td><td>灌溉计划 CRUD + toggle 开关</td></tr>
<tr><td>FeiFertigationDeviceController</td><td><code>/fertigation-device</code></td><td>设备 CRUD, dosing(加药), save-layout</td></tr>
<tr><td>称重</td><td>WeightController</td><td><code>/weight</code></td><td>ticket(磅单), device, driver, card, beidou, alarmRule</td></tr>
<tr><td>套餐配额</td><td>CustomerPackageController</td><td><code>/customerPackage</code></td><td>myPackages, increaseQuota, decreaseQuota, submitExtendApply</td></tr>
<tr><td>开放平台</td><td>OpenController</td><td><code>/open</code></td><td>trackingConfig/getByCustomerId, customerPackage/decreaseQuota</td></tr>
</tbody>
</table>
</div>
<h3>8.2 前端 API 代理配置</h3>
<div class="table-wrap">
<table>
<thead><tr><th>代理前缀</th><th>目标</th><th>路径重写</th></tr></thead>
<tbody>
<tr><td><code>/api/user-service</code></td><td><code>http://localhost:8202</code></td><td><code>^/api/user-service</code><code>/</code></td></tr>
<tr><td><code>/n8n</code></td><td><code>https://n8n.ccoop.cc</code></td><td><code>^/n8n</code><code>""</code></td></tr>
</tbody>
</table>
</div>
</div>
<!-- ==================== 9. 部署与配置 ==================== -->
<div class="section" id="sec9">
<h2><span class="icon">9</span>部署与配置</h2>
<h3>9.1 后端部署</h3>
<div class="table-wrap">
<table>
<thead><tr><th>配置项</th><th>生产环境 (prod)</th><th>开发环境 (local)</th></tr></thead>
<tbody>
<tr><td>服务端口</td><td>7777</td><td>8202</td></tr>
<tr><td>主数据源</td><td>192.168.1.161:3306/cloud</td><td>192.168.31.201:3389/cloud</td></tr>
<tr><td>伙伴云数据源</td><td>192.168.1.161:3306/user</td><td>192.168.31.201:3389/user</td></tr>
<tr><td>Redis</td><td>192.168.1.165:6403, DB7</td><td>192.168.31.201:7890, DB7</td></tr>
<tr><td>OSS</td><td colspan="2">oss-cn-beijing.aliyuncs.com, bucket: zq-cloud</td></tr>
<tr><td>伙伴云 API</td><td colspan="2">https://hb.zhangquyun.com/server/api</td></tr>
<tr><td>LLM API</td><td colspan="2">https://dashscope.aliyuncs.com/compatible-mode/v1</td></tr>
<tr><td>文件上传限制</td><td colspan="2">max-file-size: 20MB, max-request-size: 200MB</td></tr>
<tr><td>构建命令</td><td colspan="2"><code>mvn clean package -Pprod</code><code>./publish.sh</code></td></tr>
<tr><td>启动命令</td><td colspan="2"><code>java -jar saas-service.jar --spring.profiles.active=prod</code></td></tr>
</tbody>
</table>
</div>
<h3>9.2 前端部署</h3>
<div class="table-wrap">
<table>
<thead><tr><th>配置项</th><th></th></tr></thead>
<tbody>
<tr><td>开发启动</td><td><code>npm run dev</code>(端口 8201</td></tr>
<tr><td>生产构建</td><td><code>npm run build:prod</code> → 输出到 <code>saas-web/</code> 目录</td></tr>
<tr><td>预发布构建</td><td><code>npm run build:stage</code></td></tr>
<tr><td>构建脚本</td><td><code>./publish.sh</code></td></tr>
<tr><td>部署方式</td><td>Nginx 静态文件 + 反向代理到后端</td></tr>
</tbody>
</table>
</div>
<h3>9.3 数据库</h3>
<div class="info-box">
<strong>数据库引擎:</strong>MySQL 8.0+,字符集 UTF-8,时区 GMT+8<br>
<strong>逻辑删除:</strong>全局字段 <code>isDel</code>1=已删除,0=正常),MyBatis Plus 自动处理<br>
<strong>数据库导出:</strong><code>db-export/cloud_full_*.sql</code>(完整建库脚本)
</div>
<h3>9.4 环境依赖</h3>
<div class="table-wrap">
<table>
<thead><tr><th>组件</th><th>版本要求</th><th>用途</th></tr></thead>
<tbody>
<tr><td>JDK</td><td>11+</td><td>后端运行时</td></tr>
<tr><td>Maven</td><td>3.6+</td><td>后端构建</td></tr>
<tr><td>Node.js</td><td>8.9+</td><td>前端构建</td></tr>
<tr><td>MySQL</td><td>8.0+</td><td>数据库</td></tr>
<tr><td>Redis</td><td>6.0+</td><td>缓存/分布式锁</td></tr>
<tr><td>Nginx</td><td>1.18+</td><td>反向代理/静态文件</td></tr>
</tbody>
</table>
</div>
</div>
<!-- ==================== 10. 项目目录结构 ==================== -->
<div class="section" id="sec10">
<h2><span class="icon">10</span>项目目录结构</h2>
<h3>10.1 后端 (service-master)</h3>
<div class="code-block">
service-master/
├── pom.xml # Maven 配置
├── publish.sh # 发布脚本
├── src/
│ ├── main/
│ │ ├── java/cn/apes/
│ │ │ ├── CloudApplication.java # 主启动类
│ │ │ └── cloud/
│ │ │ ├── config/ # 配置类(12个)
│ │ │ ├── controller/ # 控制器(62个)
│ │ │ ├── domain/ # 数据模型
│ │ │ ├── filter/ # 过滤器
│ │ │ ├── groovy/ # Groovy 引擎
│ │ │ ├── mapper/ # Mapper 接口(85个)
│ │ │ ├── service/ # 业务逻辑(90个实现类)
│ │ │ ├── task/ # 定时任务
│ │ │ ├── util/ # 工具类
│ │ │ └── websocket/ # WebSocket 处理器
│ │ └── resources/
│ │ ├── application.yml # 主配置
│ │ ├── application-prod.yml # 生产配置
│ │ └── application-local.yml # 开发配置
│ └── test/ # 测试代码
├── docs/ # API 文档(15个)
├── sql/ # SQL 脚本
├── db-export/ # 数据库导出
└── logs/ # 日志文件</div>
<h3>10.2 前端 (web-master)</h3>
<div class="code-block">
web-master/
├── package.json # 依赖配置
├── vue.config.js # Vue CLI 配置
├── publish.sh # 发布脚本
├── src/
│ ├── main.js # 应用入口
│ ├── App.vue # 根组件
│ ├── api/ # API 接口(35个文件)
│ │ └── fei/ # 智慧农业子接口
│ ├── assets/ # 静态资源
│ ├── components/ # 公共组件
│ │ ├── ai/ # AI 组件
│ │ ├── brain/ # 大脑组件
│ │ └── tracing/screen/ # 溯源大屏组件(18个)
│ ├── config/ # 全局配置
│ ├── layout/ # 布局组件
│ │ └── components/ # TopHeader / Sidebar / TagsView
│ ├── router/ # 路由配置
│ ├── store/ # Vuexuser / settings / tagsView
│ ├── styles/ # 全局样式
│ ├── utils/ # 工具函数(16个文件)
│ └── views/ # 页面视图(85+文件)
│ ├── ai/ # AI 对话
│ ├── customer/ # 客户管理
│ ├── fei/ # 智慧农业
│ ├── huoban/ # 伙伴云
│ ├── system/ # 系统管理
│ ├── trace/ # 溯源管理
│ ├── tracing/ # 溯源追踪
│ └── weight/ # 自助过磅
├── docs/ # 文档
├── public/ # 公共静态文件
└── logs/ # 日志</div>
</div>
<!-- ==================== Footer ==================== -->
<div class="footer">
<p>账权平台 · 项目技术说明书 · 2026-08-05</p>
<p>GroupId: cn.apes · 后端: saas-service · 前端: saas-web</p>
</div>
</div>
</body>
</html>