feat: 前端账权剥离完成 — 移除业务模块,保留账权 + 系统配置 + AI/LLM

- 删除 82 个业务页面(fei/trace/weight/tracing/irrigation/huoban 等 18 目录)
- 删除 30+ 个业务 API 文件
- 删除业务组件(brain/tracing/MarkdownContent 原版)
- 删除业务 Utils(ezviz/tracing/huoban/markdown/wangEdit)
- 修改 8 个框架文件(router/main.js/request.js/store/vue.config.js/package.json/index.html/.gitignore)
- 修复 9 个残留引用(TopHeader/iframeView/menuApi/permissionApi/home/login/customer/uiConfig)
- 新建简化版 MarkdownContent.vue(使用 marked + highlight.js)
- 保留 monaco-editor 依赖(AI 工具编辑器需要)
- 添加 README.md
- npm run build:prod 验证通过
This commit is contained in:
gitea-publish
2026-08-09 12:36:09 +08:00
parent 10bea07624
commit 8ebd1ca157
176 changed files with 220 additions and 60091 deletions
-618
View File
@@ -1,618 +0,0 @@
# AI Helper 表单集成文档
## 概述
AI Helper 是一个可全局集成的 AI 对话组件,支持两种展示模式:
- **图标模式(icon)**:悬浮图标 + 可拖拽弹框,默认展示在页面右下角
- **输入框模式(input)**:将对话输入框直接嵌入到页面指定位置,无弹框、无关闭按钮
两种模式均支持文本输入、图片上传、视频上传,输入框会根据内容自动调整高度。
---
## 快速开始
### 1. 引入组件
```vue
<template>
<div>
<!-- 你的页面内容 -->
<!-- 在页面底部引入 AI Helper -->
<ai-helper :agent_id="agentId" />
</div>
</template>
<script>
import AiHelper from '@/components/ai/ai_helper.vue'
export default {
components: { AiHelper },
data() {
return {
agentId: '1' // Agent ID
}
}
}
</script>
```
---
## Props 参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| agent_id | String/Number | 是 | - | Agent 配置 ID,用于加载对应的 Agent 配置 |
| user_prompt | String | 否 | '' | 用户提示词,提供上下文数据,调用大模型时作为额外上下文传递 |
| display | String | 否 | 'icon' | 展示模式:`icon`(悬浮图标+弹框)/ `input`(嵌入式输入框) |
| input_title | String | 否 | '' | 输入框标题,显示在输入框上方,用于说明输入内容的用途 |
| default_input | String | 否 | '' | 默认的用户输入文案,组件初始化时自动填充到输入框中 |
---
## Events 事件
| 事件名 | 参数 | 说明 |
|--------|------|------|
| result | Object | 大模型返回结果时触发 |
### result 事件数据结构
```javascript
{
content: '返回的文本内容', // String - 原始返回内容
tokens: { // Object - Token 统计
total: 150,
prompt: 100,
completion: 50
},
contentObject: {}, // Object - JSON 格式返回内容(仅 outputType 为 json 时)
agentId: '1', // String/Number - 当前 Agent ID
timestamp: '2026-06-26T17:00:00.000Z' // String - 时间戳
}
```
---
## 展示模式说明
### 模式 1:图标模式(display="icon"
默认模式。页面右下角显示一个悬浮图标,点击后弹出可拖拽的对话弹框。
- 悬浮图标可拖拽移动
- 弹框可拖拽移动,带标题栏和关闭按钮
- 弹框内包含统一输入框(文本 + 上传)
```vue
<!-- 默认就是 icon 模式无需显式指定 -->
<ai-helper agent_id="1" />
<!-- 等价于 -->
<ai-helper agent_id="1" display="icon" />
```
### 模式 2:输入框模式(display="input"
将对话输入框直接嵌入到页面中组件放置的位置,没有悬浮图标、没有弹框、没有关闭按钮。
- 组件挂载后自动加载 Agent 信息(无需点击)
- 统一输入框直接显示在页面中
- 文本输入区域根据内容自动增高(最小 3 行,最大 200px 后滚动)
- 支持图片/视频上传图标(根据 Agent 配置自动显示)
```vue
<ai-helper agent_id="1" display="input" />
```
### 统一输入框结构
两种模式共用同一个输入框设计,将文本输入、图片上传、视频上传整合为一个区域:
```
┌─────────────────────────────────┐
│ [已上传的图片/视频预览] │
│ │
│ 请输入内容... │
│ │
│ 📷 🎬 [发送] │
└─────────────────────────────────┘
```
- 文本区域:自动高度,最小 3 行(66px),最大 200px 后出现滚动条
- 左下角:图片上传 📷 和视频上传 🎬 图标按钮(根据 Agent 配置显示)
- 右下角:发送按钮
- 已上传文件在输入框顶部以缩略图形式预览,支持点击删除
---
## 基础集成示例
### 示例 1:最简集成(图标模式)
```vue
<template>
<page-box>
<div>你的页面内容</div>
<ai-helper agent_id="1" />
</page-box>
</template>
<script>
import AiHelper from '@/components/ai/ai_helper.vue'
import PageBox from '@/components/pageBox.vue'
export default {
components: { AiHelper, PageBox }
}
</script>
```
### 示例 2:监听返回结果
```vue
<template>
<page-box>
<div>你的页面内容</div>
<!-- 监听 result 事件 -->
<ai-helper
agent_id="1"
@result="onAiResult"
/>
<!-- 展示结果 -->
<div v-if="aiResult">
<h3>AI 分析结果</h3>
<p>{{ aiResult.content }}</p>
</div>
</page-box>
</template>
<script>
import AiHelper from '@/components/ai/ai_helper.vue'
import PageBox from '@/components/pageBox.vue'
export default {
components: { AiHelper, PageBox },
data() {
return {
aiResult: null
}
},
methods: {
onAiResult(data) {
this.aiResult = data
console.log('AI 返回:', data.content)
console.log('Token 统计:', data.tokens)
}
}
}
</script>
```
### 示例 3:传递上下文数据
```vue
<template>
<page-box>
<!-- 表单内容 -->
<el-form :model="form">
<el-form-item label="姓名">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="电话">
<el-input v-model="form.phone" />
</el-form-item>
</el-form>
<!-- 传递表单数据作为上下文 -->
<ai-helper
agent_id="1"
:user_prompt="contextData"
@result="onAiResult"
/>
</page-box>
</template>
<script>
import AiHelper from '@/components/ai/ai_helper.vue'
import PageBox from '@/components/pageBox.vue'
export default {
components: { AiHelper, PageBox },
data() {
return {
form: {
name: '',
phone: ''
}
}
},
computed: {
// 将表单数据转为上下文字符串
contextData() {
return `当前表单数据:
姓名:${this.form.name}
电话:${this.form.phone}`
}
},
methods: {
onAiResult(data) {
// 处理 AI 返回结果
if (data.contentObject) {
// JSON 格式结果
console.log('JSON 结果:', data.contentObject)
} else {
// 文本格式结果
console.log('文本结果:', data.content)
}
}
}
}
</script>
```
### 示例 4:输入框模式嵌入表单
将 AI 输入框直接嵌入到表单页面中,作为页面的一部分,而非悬浮弹框:
```vue
<template>
<page-box title="智能分析">
<!-- 表单内容 -->
<el-form :model="form" label-width="100px">
<el-form-item label="客户名称">
<el-input v-model="form.customerName" />
</el-form-item>
<el-form-item label="联系电话">
<el-input v-model="form.phone" />
</el-form-item>
</el-form>
<!-- AI 输入框直接嵌入页面 -->
<div style="margin-top: 20px;">
<ai-helper
agent_id="5"
display="input"
input_title="智能分析助手"
default_input="请帮我分析这个客户的基本信息"
:user_prompt="aiContext"
@result="handleAiResult"
/>
</div>
<!-- AI 结果展示 -->
<el-card v-if="aiResult" style="margin-top: 20px">
<div slot="header">AI 分析结果</div>
<pre>{{ aiResult.content }}</pre>
</el-card>
</page-box>
</template>
<script>
import AiHelper from '@/components/ai/ai_helper.vue'
import PageBox from '@/components/pageBox.vue'
export default {
components: { AiHelper, PageBox },
data() {
return {
form: {
customerName: '',
phone: ''
},
aiResult: null
}
},
computed: {
aiContext() {
return `请根据以下客户信息进行分析:
客户名称:${this.form.customerName}
联系电话:${this.form.phone}`
}
},
methods: {
handleAiResult(data) {
this.aiResult = data
}
}
}
</script>
```
### 示例 5:表单场景完整集成(图标模式)
```vue
<template>
<page-box title="客户信息录入">
<el-form :model="form" label-width="100px">
<el-form-item label="客户名称">
<el-input v-model="form.customerName" />
</el-form-item>
<el-form-item label="联系电话">
<el-input v-model="form.phone" />
</el-form-item>
<el-form-item label="地址">
<el-input v-model="form.address" type="textarea" />
</el-form-item>
</el-form>
<!-- AI Helper 集成 -->
<ai-helper
agent_id="5"
:user_prompt="aiContext"
@result="handleAiResult"
/>
<!-- AI 结果展示区域 -->
<el-card v-if="aiResult" style="margin-top: 20px">
<div slot="header">AI 分析结果</div>
<div v-if="aiResult.contentObject">
<p>建议标签{{ aiResult.contentObject.tags }}</p>
<p>建议分类{{ aiResult.contentObject.category }}</p>
</div>
<div v-else>
<pre>{{ aiResult.content }}</pre>
</div>
</el-card>
</page-box>
</template>
<script>
import AiHelper from '@/components/ai/ai_helper.vue'
import PageBox from '@/components/pageBox.vue'
export default {
components: { AiHelper, PageBox },
data() {
return {
form: {
customerName: '',
phone: '',
address: ''
},
aiResult: null
}
},
computed: {
aiContext() {
return `请根据以下客户信息进行分析:
客户名称:${this.form.customerName}
联系电话:${this.form.phone}
地址:${this.form.address}
请以 JSON 格式返回分析结果,包含 tags(标签数组)和 category(分类)。`
}
},
methods: {
handleAiResult(data) {
this.aiResult = data
}
}
}
</script>
```
### 示例 6:使用输入框标题和默认文案
在 input 模式下,可以使用 `input_title``default_input` 参数来优化用户体验:
```vue
<template>
<page-box title="施肥方案管理">
<el-form :model="form" label-width="100px">
<el-form-item label="作物">
<el-select v-model="form.cropId" placeholder="请选择作物">
<el-option v-for="crop in cropList" :key="crop.id" :label="crop.name" :value="crop.id" />
</el-select>
</el-form-item>
<el-form-item label="物候期">
<el-select v-model="form.phenologyId" placeholder="请选择物候期">
<el-option v-for="p in phenologyList" :key="p.id" :label="p.name" :value="p.id" />
</el-select>
</el-form-item>
</el-form>
<!-- AI 输入框带标题和默认文案 -->
<div style="margin-top: 20px;">
<ai-helper
agent_id="4"
display="input"
input_title="智能施肥方案生成"
default_input="请根据选择的作物和物候期,制定科学的施肥方案"
:user_prompt="aiContext"
@result="handleAiResult"
/>
</div>
</page-box>
</template>
<script>
import AiHelper from '@/components/ai/ai_helper.vue'
import PageBox from '@/components/pageBox.vue'
export default {
components: { AiHelper, PageBox },
data() {
return {
form: {
cropId: null,
phenologyId: null
},
cropList: [],
phenologyList: []
}
},
computed: {
aiContext() {
const crop = this.cropList.find(c => c.id === this.form.cropId)
const phenology = this.phenologyList.find(p => p.id === this.form.phenologyId)
return `当前选择的作物:${crop ? crop.name : '未选择'}
当前物候期:${phenology ? phenology.name : '未选择'}
请根据以上信息制定施肥方案,返回 JSON 格式:
{
"formulaName": "配方名称",
"applyType": "施肥方式",
"totalAmount": 总用量,
"details": [...]
}`
}
},
methods: {
handleAiResult(data) {
if (data.contentObject) {
// 回填表单
console.log('AI 返回的施肥方案:', data.contentObject)
}
}
}
}
</script>
```
**参数说明:**
- `input_title="智能施肥方案生成"`:在输入框上方显示标题,帮助用户理解该输入框的用途
- `default_input="请根据选择的作物和物候期,制定科学的施肥方案"`:组件初始化时自动填充到输入框,用户可以在此基础上修改或直接发送
---
## 组件功能说明
| 功能 | 说明 |
|------|------|
| 悬浮图标 | icon 模式下显示在页面右下角,可拖拽移动 |
| 对话弹框 | icon 模式下点击图标打开,可拖拽移动,无遮罩层 |
| 嵌入式输入框 | input 模式下直接嵌入页面,无弹框无关闭按钮 |
| 统一输入框 | 文本输入 + 图片上传 + 视频上传整合为一个输入区域 |
| 自动高度 | 文本输入区域根据内容自动增高,最小 3 行,最大 200px |
| 图片上传 | 根据 Agent 配置 `supportImage` 自动显示上传图标 |
| 视频上传 | 根据 Agent 配置 `supportVideo` 自动显示上传图标 |
| 文件预览 | 已上传的图片/视频在输入框顶部以缩略图预览,支持删除 |
| 结果输出 | 调用成功后通过 `@result` 事件抛出 |
---
## 表单快速填充场景
### 场景说明
在业务系统中,很多表单需要用户手动填写大量字段。通过集成 AI Helper(Agent ID = 4),可以实现表单快速填充:
1. 用户通过 AI 对话描述需求(如"帮我填一个客户信息,张三,电话 13800138000"
2. AI 分析用户输入,返回 JSON 格式的表单数据
3. 前端监听 `@result` 事件,将返回的 JSON 数据自动回填到表单中
### 接入步骤
#### 步骤 1:整理表单字段信息
整理目标表单的所有字段,包含以下信息:
| 属性名 | 类型 | 含义 |
|--------|------|------|
| 字段名 | 数据类型 | 字段说明 |
例如:
| 属性名 | 类型 | 含义 |
|--------|------|------|
| plateNumber | String | 车牌号 |
| vehicleType | String | 车型 |
| driverId | Long | 司机ID |
#### 步骤 2:构建 user_prompt
将字段信息告诉 AI,让它知道需要返回什么格式:
```javascript
computed: {
aiPrompt() {
return `请根据用户描述填充表单,返回 JSON 格式:
{
"plateNumber": "车牌号",
"vehicleType": "车型",
"driverId": 司机ID
}
只返回 JSON,不要其他内容。`
}
}
```
#### 步骤 3:集成组件并处理回调
```vue
<template>
<page-box>
<el-form :model="form">
<!-- 你的表单字段 -->
</el-form>
<ai-helper
agent_id="4"
:user_prompt="aiPrompt"
@result="handleAiResult"
/>
</page-box>
</template>
<script>
export default {
computed: {
aiPrompt() {
return `根据用户描述填充表单,返回 JSON:
{
"plateNumber": "车牌号",
"vehicleType": "车型",
"driverId": 司机ID
}
只返回 JSON。`
}
},
methods: {
handleAiResult(data) {
if (data.contentObject) {
// 回填表单
Object.keys(data.contentObject).forEach(key => {
if (this.form.hasOwnProperty(key)) {
this.$set(this.form, key, data.contentObject[key])
}
})
this.$message.success('已填充')
}
}
}
}
</script>
```
### 关键点
1. **Agent ID = 4**:表单快速填充固定使用
2. **字段说明要清晰**:告诉 AI 字段名、类型、含义
3. **返回 JSON 格式**Agent 的 outputType 必须配置为 json
4. **自动回填**:根据返回的 JSON key 匹配表单字段名
---
## 注意事项
1. **Agent ID 必须有效**:确保传入的 `agent_id` 在后端 `llm_agent_config` 表中存在且状态为启用
2. **user_prompt 为可选**:不传则仅使用 Agent 配置的系统提示词和用户提示词模板
3. **结果格式**:根据 Agent 的 `outputType` 配置,`contentObject` 仅在 `outputType=json` 时有值
4. **组件位置**
- icon 模式:建议放在页面模板的最外层或 `page-box` 内部,确保悬浮层级正确
- input 模式:放在表单或内容区域中需要嵌入输入框的位置即可
5. **Token 统计**:每次调用会返回 Token 消耗统计,可用于成本监控
6. **display 模式选择**
- icon 模式适合全局辅助工具,用户按需打开
- input 模式适合 AI 驱动的业务页面,输入框作为页面核心功能的一部分
---
## 前置条件
- 需要在后台 Agent 管理中配置好对应的 Agent(系统提示词、模型等)
- 确保 `/static/ai_helper.png``/static/ai_helper_bai.png` 图标文件存在
-40
View File
@@ -1,40 +0,0 @@
# Agent 调用文档
## 调用 Agent
```javascript
import llmAgentApi from '@/api/llmAgentApi'
llmAgentApi.callAgent(agentId, {
userParams: {
input: '用户输入内容',
imageUrls: ['https://example.com/img1.jpg'], // 可选,图片 URL 列表
videoUrls: ['https://example.com/video1.mp4'] // 可选,视频 URL 列表
}
})
```
### 返回
```javascript
{
code: 1,
data: {
content: '模型输出内容',
tokens: { prompt: 100, completion: 200, total: 300 }
}
}
```
---
## 图片/视频上传
先通过公共接口上传文件获取 URL
```javascript
// 上传接口:POST /api/user-service/common/upload
// 返回:{ code: 1, data: 'https://oss.example.com/file.jpg' }
```
再将 URL 放入 `imageUrls``videoUrls` 数组传给 `callAgent`
-83
View File
@@ -1,83 +0,0 @@
# 前端代理配置说明
## 当前 Vue 开发环境代理配置
```javascript
// vue.config.js
devServer: {
proxy: {
'/api/user-service': {
target: 'https://cloud.zhangquyun.com/api/user-service',
changeOrigin: true,
pathRewrite: {
'^/api/user-service': '/'
}
},
'/n8n': {
target: 'https://n8n.ccoop.cc',
changeOrigin: true,
pathRewrite: {
'^/n8n': ''
}
}
}
}
```
## Nginx 代理配置
```nginx
server {
listen 80;
server_name your-domain.com;
# 前端静态资源
root /path/to/saas-web/dist;
index index.html;
# API 代理 - 用户服务
location /api/user-service/ {
proxy_pass https://cloud.zhangquyun.com/;
proxy_set_header Host cloud.zhangquyun.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# SSL 相关
proxy_ssl_server_name on;
proxy_ssl_name cloud.zhangquyun.com;
}
# n8n 工作流代理
location /n8n/ {
proxy_pass https://n8n.ccoop.cc/;
proxy_set_header Host n8n.ccoop.cc;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# SSL 相关
proxy_ssl_server_name on;
proxy_ssl_name n8n.ccoop.cc;
}
# 前端路由 - SPA 模式
location / {
try_files $uri $uri/ /index.html;
}
}
```
## 代理规则说明
| 前端请求路径 | 代理目标 | 重写后路径 |
|------------|---------|-----------|
| `/api/user-service/customer/getCurrentUser` | `https://cloud.zhangquyun.com` | `/customer/getCurrentUser` |
| `/n8n/api/v1/workflows` | `https://n8n.ccoop.cc` | `/api/v1/workflows` |
## 注意事项
1. **路径重写**Vue 的 `pathRewrite: { '^/api/user-service': '/' }` 会把 `/api/user-service/xxx` 变成 `/xxx`
2. **SSL 代理**:目标地址是 HTTPS,需要配置 `proxy_ssl_server_name on`
3. **Host 头**:必须设置正确的 Host 头,否则后端可能拒绝请求
4. **CORS**:如果前端和 API 不在同一域名,需要配置 CORS 或使用代理
-202
View File
@@ -1,202 +0,0 @@
# 电磁阀管理接口文档
## 接口前缀
`/api/user-service/fei/solenoid/valve`
## 1. 分页查询电磁阀列表
**请求方式**: POST
**请求路径**: `/page`
### 请求参数
```json
{
"pageIndex": 1, // 页码(必填)
"pageSize": 10, // 每页数量(必填)
"valveName": "电磁阀A", // 阀门名称(模糊查询,可选)
"valveCode": "SV-001", // 阀门编号(精确查询,可选)
"parkId": 1, // 园区ID(可选)
"plotId": 1, // 地块ID(可选)
"valveStatus": 0, // 阀门状态 0-关闭 1-开启(可选)
"onlineStatus": 1 // 在线状态 0-离线 1-在线(可选)
}
```
### 响应示例
```json
{
"code": 1,
"msg": "ok",
"data": {
"records": [
{
"id": 1,
"valveName": "电磁阀A01",
"valveCode": "SV-2026-001",
"parkId": 1,
"plotId": 1,
"longitude": 108.365432,
"latitude": 22.842156,
"installLocation": "A区1号地块入口",
"valveStatus": 0,
"onlineStatus": 1,
"lastActionTime": null,
"remark": "测试数据1",
"parkName": "示例园区",
"plotName": "A3",
"createTime": "2026-07-07 20:52:25",
"updateTime": "2026-07-07 20:52:25",
"isDel": 0
}
],
"total": 2,
"size": 10,
"current": 1,
"pages": 1
}
}
```
## 2. 查询电磁阀详情
**请求方式**: POST
**请求路径**: `/detail`
### 请求参数
```json
{
"id": 1 // 电磁阀ID(必填)
}
```
### 响应示例
```json
{
"code": 1,
"msg": "ok",
"data": {
"id": 1,
"valveName": "电磁阀A01",
"valveCode": "SV-2026-001",
"parkId": 1,
"plotId": 1,
"longitude": 108.365432,
"latitude": 22.842156,
"installLocation": "A区1号地块入口",
"valveStatus": 0,
"onlineStatus": 1,
"lastActionTime": null,
"remark": "测试数据1",
"parkName": "示例园区",
"plotName": "A3",
"createTime": "2026-07-07 20:52:25",
"updateTime": "2026-07-07 20:52:25",
"isDel": 0
}
}
```
## 3. 新增电磁阀
**请求方式**: POST
**请求路径**: `/add`
### 请求参数
```json
{
"valveName": "电磁阀A01", // 阀门名称(必填)
"valveCode": "SV-2026-001", // 阀门编号(必填,唯一)
"parkId": 1, // 园区ID(必填)
"plotId": 1, // 地块ID(可选)
"longitude": 108.365432, // 经度(可选)
"latitude": 22.842156, // 纬度(可选)
"installLocation": "A区1号地块入口", // 安装位置描述(可选)
"valveStatus": 0, // 阀门状态 0-关闭 1-开启(可选,默认0)
"onlineStatus": 1, // 在线状态 0-离线 1-在线(可选,默认0)
"remark": "备注信息" // 备注(可选)
}
```
### 响应示例
```json
{
"code": 1,
"msg": "ok",
"data": null
}
```
## 4. 更新电磁阀
**请求方式**: POST
**请求路径**: `/update`
### 请求参数
```json
{
"id": 1, // 电磁阀ID(必填)
"valveName": "电磁阀A01-修改", // 阀门名称(可选)
"valveCode": "SV-2026-001", // 阀门编号(可选,唯一)
"parkId": 1, // 园区ID(可选)
"plotId": 1, // 地块ID(可选)
"longitude": 108.365500, // 经度(可选)
"latitude": 22.842200, // 纬度(可选)
"installLocation": "新位置", // 安装位置描述(可选)
"valveStatus": 1, // 阀门状态 0-关闭 1-开启(可选)
"onlineStatus": 1, // 在线状态 0-离线 1-在线(可选)
"remark": "更新后的备注" // 备注(可选)
}
```
### 响应示例
```json
{
"code": 1,
"msg": "ok",
"data": null
}
```
## 5. 删除电磁阀
**请求方式**: POST
**请求路径**: `/delete`
### 请求参数
```json
{
"id": 1 // 电磁阀ID(必填)
}
```
### 响应示例
```json
{
"code": 1,
"msg": "ok",
"data": null
}
```
## 字段说明
### 电磁阀字段
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | Long | 主键ID |
| valveName | String | 阀门名称 |
| valveCode | String | 阀门编号(唯一) |
| parkId | Long | 园区ID |
| plotId | Long | 地块ID |
| longitude | BigDecimal | 经度 |
| latitude | BigDecimal | 纬度 |
| installLocation | String | 安装位置描述 |
| valveStatus | Integer | 阀门状态 0-关闭 1-开启 |
| onlineStatus | Integer | 在线状态 0-离线 1-在线 |
| lastActionTime | Date | 最后操作时间 |
| remark | String | 备注 |
| parkName | String | 园区名称(非数据库字段,用于展示) |
| plotName | String | 地块名称(非数据库字段,用于展示) |
| createTime | Date | 创建时间 |
| updateTime | Date | 更新时间 |
| isDel | Integer | 逻辑删除 0-正常 1-删除 |
-32
View File
@@ -1,32 +0,0 @@
-- 电磁阀数据批量插入
-- 生成时间: 2026-07-07 21:13
-- 数据来源: 设备接口返回的26个电磁阀
-- 说明: did 为控制器设备ID(全部相同), valve_code 使用 did-index 组合保证唯一
INSERT INTO fei_solenoid_valve (valve_name, valve_code, park_id, plot_id, longitude, latitude, install_location, valve_status, online_status, last_action_time, remark, is_del, create_time, update_time) VALUES
('电磁阀-1', '864865086276673-1', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-2', '864865086276673-2', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-3', '864865086276673-3', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-4', '864865086276673-4', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-5', '864865086276673-5', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-6', '864865086276673-6', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-7', '864865086276673-7', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-8', '864865086276673-8', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-9', '864865086276673-9', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-10', '864865086276673-10', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-11', '864865086276673-11', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-12', '864865086276673-12', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-13', '864865086276673-13', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-14', '864865086276673-14', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-15', '864865086276673-15', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-16', '864865086276673-16', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-17', '864865086276673-17', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-18', '864865086276673-18', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-19', '864865086276673-19', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-20', '864865086276673-20', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-21', '864865086276673-21', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-22', '864865086276673-22', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-23', '864865086276673-23', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-24', '864865086276673-24', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-25', '864865086276673-25', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW()),
('电磁阀-26', '864865086276673-26', 1, NULL, NULL, NULL, NULL, 0, 1, NULL, NULL, 0, NOW(), NOW());
-23
View File
@@ -1,23 +0,0 @@
-- 电磁阀灌溉记录表
CREATE TABLE `fei_solenoid_valve_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`valve_id` bigint(20) NOT NULL COMMENT '电磁阀ID',
`valve_code` varchar(64) DEFAULT NULL COMMENT '阀门编号',
`park_id` bigint(20) DEFAULT NULL COMMENT '所属园区ID',
`plot_id` bigint(20) DEFAULT NULL COMMENT '所属地块ID',
`flow_rate` decimal(10,2) DEFAULT NULL COMMENT '流量(立方米/小时)',
`start_time` datetime NOT NULL COMMENT '开始灌溉时间',
`end_time` datetime DEFAULT NULL COMMENT '结束灌溉时间',
`duration_minutes` int(11) DEFAULT NULL COMMENT '灌溉时长(分钟)',
`total_water` decimal(10,2) DEFAULT NULL COMMENT '总灌溉量(立方米)',
`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态 0-未关阀 1-已关阀',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_del` tinyint(1) DEFAULT '0' COMMENT '逻辑删除 0-正常 1-删除',
PRIMARY KEY (`id`),
KEY `idx_valve_id` (`valve_id`),
KEY `idx_park_id` (`park_id`),
KEY `idx_plot_id` (`plot_id`),
KEY `idx_status` (`status`),
KEY `idx_start_time` (`start_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='电磁阀灌溉记录表';