1. 项目背景与核心价值
智慧乡村管理系统是我最近完成的一个融合传统业务系统与大模型能力的实战项目。这个系统最初源于一个实际需求:许多乡村地区虽然已经部署了基础的信息化管理工具,但村民和基层工作人员在使用过程中仍然面临操作复杂、信息获取效率低等问题。
传统的信息系统往往只解决了"数据电子化"的问题,却没有真正降低使用门槛。比如一个普通的村民想要查询今年的农产品收购政策,可能需要点击多个菜单、填写复杂的查询条件才能找到相关信息。而我们的智慧乡村管理系统通过接入DeepSeek大模型,实现了从"需要用户主动查找"到"系统智能解答"的转变。
这个项目的核心创新点在于:
- 将大模型能力无缝嵌入到Spring Boot + Vue的传统业务系统中
- 实现了基于业务场景的智能问答(如农产品咨询、项目招标指导等)
- 保留了传统业务系统的所有功能,同时大幅提升了易用性
从技术角度看,这个项目展示了如何在一个已有系统中逐步引入AI能力,而不是完全推倒重来。我们选择了JDK1.8和MySQL8.0作为基础环境,确保系统能够兼容大多数乡村现有的服务器配置。
2. 系统架构设计
2.1 整体技术栈选型
在架构设计阶段,我们主要考虑了以下几个因素:
- 乡村基层单位通常不具备专业的IT运维团队,系统必须足够稳定且易于维护
- 现有基础设施往往比较老旧,需要兼容低版本运行环境
- 需要平衡AI功能的创新性与核心业务的稳定性
基于这些考虑,我们最终确定的技术栈如下:
| 层级 | 技术选型 | 选型理由 |
|---|---|---|
| 前端 | Vue 2 + Element UI | 组件丰富,学习曲线平缓,适合快速开发管理类系统 |
| 后端 | Spring Boot 2.7 + JDK1.8 | 成熟稳定,社区资源丰富,兼容老旧服务器 |
| 数据库 | MySQL 8.0 | 开源免费,乡村单位已有使用经验 |
| AI集成 | DeepSeek API | 中文理解能力强,API稳定,适合政务类场景 |
2.2 模块划分与功能设计
系统分为前台和后台两大模块:
前台功能模块:
- 用户门户:登录注册、个人信息管理
- 农产品展示:分类浏览、详情查看、在线预约
- 乡村项目:招标信息查看、在线竞标申请
- 线下活动:活动发布、在线报名
- AI智能助手:全局可访问的问答服务
后台管理模块:
- 数据看板:关键指标可视化
- 用户管理:村民账号审核与管理
- 内容管理:农产品、项目、活动的增删改查
- 系统设置:权限配置、字典管理
2.3 核心业务流程
系统设计的核心业务流程包括:
- 农产品交易流程:展示→咨询→预约→履约
- 项目招标流程:发布→咨询→投标→评审
- 活动管理流程:发布→报名→签到→反馈
在每个流程的关键节点,我们都嵌入了AI能力。例如:
- 当用户查看某个农产品时,可以直接询问"这个苹果的种植方式是否符合有机标准?"
- 在项目投标页面,可以询问"投标文件需要包含哪些必要材料?"
3. 核心实现细节
3.1 后端实现
3.1.1 依赖配置
后端采用Spring Boot框架,主要依赖包括:
xml复制<dependencies>
<!-- Web基础 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 数据库相关 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
<!-- 其他 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
3.1.2 配置文件
application.yml关键配置:
yaml复制server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/smart_village?useSSL=false&serverTimezone=UTC
username: root
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
deepseek:
api-key: sk-your-api-key
base-url: https://api.deepseek.com/v1
model: deepseek-chat
system-prompt: "你是一个智慧乡村助手..."
3.1.3 AI服务层实现
AI服务层的核心是AiConsultService类,主要处理与DeepSeek API的交互:
java复制@Service
public class AiConsultService {
@Value("${deepseek.api-key}")
private String apiKey;
// 其他配置项...
public String chat(String userQuestion, String context) {
List<JSONObject> messages = new ArrayList<>();
// 1. 设置系统角色
JSONObject systemMsg = new JSONObject();
systemMsg.put("role", "system");
systemMsg.put("content", systemPrompt);
messages.add(systemMsg);
// 2. 添加上下文
if (StringUtils.isNotBlank(context)) {
JSONObject contextMsg = new JSONObject();
contextMsg.put("role", "user");
contextMsg.put("content", "参考信息:" + context + "\n问题:" + userQuestion);
messages.add(contextMsg);
} else {
// 无上下文直接提问
JSONObject userMsg = new JSONObject();
userMsg.put("role", "user");
userMsg.put("content", userQuestion);
messages.add(userMsg);
}
// 3. 构建请求体
JSONObject requestBody = new JSONObject();
requestBody.put("model", model);
requestBody.put("messages", messages);
requestBody.put("temperature", 0.7);
// 4. 发送请求
try {
String responseStr = HttpRequest.post(baseUrl + "/chat/completions")
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "application/json")
.body(requestBody.toString())
.timeout(10000)
.execute()
.body();
// 解析响应...
return answer;
} catch (Exception e) {
return "AI服务暂时不可用:" + e.getMessage();
}
}
}
3.1.4 业务控制器
控制器层提供RESTful API接口:
java复制@RestController
@RequestMapping("/api/ai")
public class ConsultController {
@Autowired
private AiConsultService aiConsultService;
@GetMapping("/chat")
public Map<String, Object> chat(@RequestParam String question,
@RequestParam(required = false) Long contextId) {
Map<String, Object> result = new HashMap<>();
String context = "";
if (contextId != null) {
// 根据contextId获取业务上下文
context = businessService.getContext(contextId);
}
String answer = aiConsultService.chat(question, context);
result.put("success", true);
result.put("answer", answer);
return result;
}
}
3.2 前端实现
3.2.1 AI聊天组件
前端采用Vue实现了一个全局可访问的AI聊天组件:
vue复制<template>
<div class="ai-chat-container">
<!-- 悬浮按钮 -->
<div class="chat-toggle-btn" @click="toggleChat">
<i class="el-icon-cpu"></i>
<span>AI助手</span>
</div>
<!-- 聊天窗口 -->
<div class="chat-window" v-show="isOpen">
<div class="chat-header">
<span>智慧乡村AI助手</span>
<i class="el-icon-close" @click="toggleChat"></i>
</div>
<div class="chat-body">
<!-- 消息列表 -->
</div>
<div class="chat-input-area">
<input v-model="inputText" @keyup.enter="sendMessage"/>
<button @click="sendMessage">发送</button>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isOpen: false,
inputText: '',
messages: []
};
},
methods: {
async sendMessage() {
if (!this.inputText.trim()) return;
// 添加到消息列表
this.messages.push({
role: 'user',
content: this.inputText
});
// 调用API
try {
const res = await axios.get('/api/ai/chat', {
params: {
question: this.inputText,
contextId: this.$route.params.id // 当前页面上下文
}
});
this.messages.push({
role: 'ai',
content: res.data.answer
});
} catch (error) {
// 错误处理
}
}
}
};
</script>
3.2.2 业务页面集成
在各个业务页面,我们通过路由参数传递上下文ID:
vue复制<script>
export default {
mounted() {
// 获取当前农产品ID作为上下文
this.productId = this.$route.params.id;
},
methods: {
askAboutProduct(question) {
this.$refs.chatBox.sendMessage(
question,
this.productId
);
}
}
};
</script>
3.3 数据库设计
核心表结构设计:
sql复制-- 农产品表
CREATE TABLE village_product (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
category_id INT,
price DECIMAL(10,2),
description TEXT,
status TINYINT DEFAULT 1
);
-- 项目表
CREATE TABLE village_project (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(200) NOT NULL,
budget DECIMAL(12,2),
deadline DATETIME,
requirements TEXT
);
-- 活动表
CREATE TABLE village_activity (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
start_time DATETIME,
max_participants INT
);
-- 用户预约表
CREATE TABLE user_booking (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT,
target_type VARCHAR(20),
target_id BIGINT,
status VARCHAR(20)
);
4. 部署与运维
4.1 环境准备
系统部署需要以下环境:
- JDK 1.8
- MySQL 8.0+
- Node.js 14+ (前端构建)
4.2 部署步骤
- 数据库部署
bash复制mysql -u root -p < schema.sql
- 后端部署
bash复制mvn clean package
java -jar target/smart-village.jar
- 前端部署
bash复制npm install
npm run build
# 将dist目录内容部署到Nginx
4.3 配置建议
- API密钥管理
- 不要将API密钥直接写在代码中
- 建议使用环境变量或配置中心管理
- 性能调优
yaml复制server:
tomcat:
max-threads: 200
min-spare-threads: 10
- 安全配置
java复制@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/**").authenticated()
.and()
.httpBasic();
}
}
5. 常见问题与解决方案
5.1 AI相关问题
问题1:AI回答与业务数据不一致
- 解决方案:实现RAG模式,先从数据库查询准确数据,再将数据作为上下文提供给AI
问题2:敏感问题处理
- 解决方案:在系统提示词中明确限制回答范围,后端增加内容过滤
5.2 性能问题
问题:API响应慢
- 优化方案:
- 增加缓存层,缓存常见问题的回答
- 实现流式响应,提升用户体验
- 设置合理的超时时间(建议10秒)
5.3 业务集成问题
问题:如何获取业务上下文
- 解决方案:
- 通过URL参数识别当前页面
- 使用Vuex全局状态管理
- 后端根据页面类型查询相关数据
6. 项目总结与经验分享
这个项目的核心价值在于证明了传统业务系统与AI能力可以有机融合,而不是相互替代。在实际落地过程中,我们获得了以下几点重要经验:
- 渐进式改造优于推倒重来
- 保留原有系统的核心功能
- 逐步添加AI能力,先解决高频、痛点场景
- 确保每次改动都能带来可感知的价值提升
- 上下文是关键
- 单纯的问答机器人价值有限
- 必须与业务场景深度结合
- 通过URL参数、页面内容等自动获取上下文
- 用户体验需要特别设计
- AI功能入口要明显但又不干扰主流程
- 回答要简洁准确,避免长篇大论
- 提供"重新生成"、"是否解决"等反馈机制
- 技术选型的平衡
- 前端:Vue + Element UI组合开发效率高
- 后端:Spring Boot生态成熟稳定
- AI:选择API模式而非自研模型,降低成本
这个项目目前已经在多个试点乡村运行,显著降低了系统使用门槛。一位60多岁的村民反馈说:"以前要找政策得让孙子帮忙操作手机,现在直接问这个小助手就行了,它说的比人还明白。"这种实实在在的价值,正是技术应该带来的改变。