9cbb1f7695
- docs/: 源码分析报告、代码深度解析、项目说明书、独立服务化方案 - backend/: 账权模块提取说明(提取原则、文件清单、耦合度验证) - frontend/: 前端剥离方案、剥离历史与说明、框架修改详情
1045 lines
49 KiB
HTML
1045 lines
49 KiB
HTML
<!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 Mapper(85个)
|
||
│ └── traceability/ # 溯源 Mapper(20个)
|
||
├── 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>8201(host: 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/ # Vuex(user / 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>{{variable}}</code> 格式的变量替换,通过 userParams 传入动态参数</div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-title">多模态输入</div>
|
||
<div class="card-desc">支持图片 URL(image_url)和视频 URL(video_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 代理阿里云实时 ASR(fun-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/ # Vuex(user / 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>
|