1. 项目背景与核心价值
在传统中药店数字化转型浪潮中,保健品线上销售渠道的缺失成为行业痛点。我们团队基于SSM(Spring+Spring MVC+MyBatis)与Vue.js技术栈,开发了这套专为中药店定制的保健品商城系统。这个方案解决了三个核心问题:一是将传统药材销售流程线上化,二是实现保健品SKU的智能管理,三是通过前后端分离架构提升系统可维护性。
这套系统最显著的特点是采用了"SSM后端+Vue前端"的混合架构模式。后端SSM框架负责业务逻辑处理和数据持久化,而前端Vue.js则实现动态数据渲染和用户交互。这种组合既保留了Java生态的稳定性,又兼具现代前端框架的灵活性。
提示:选择SSM而非Spring Boot是考虑到许多传统中药店已有Java EE技术栈储备,迁移成本更低
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计解析
2.1 后端SSM框架配置要点
在pom.xml中需要特别注意这些依赖配置:
xml复制<!-- MyBatis与Spring整合包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
数据库设计时采用了特殊的药材分类模型:
sql复制CREATE TABLE `herb_category` (
`category_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`parent_id` int(11) DEFAULT NULL COMMENT '父分类ID',
`category_name` varchar(50) NOT NULL COMMENT '分类名称',
`herb_property` varchar(20) DEFAULT NULL COMMENT '药性(温/凉/平等)',
`is_show` tinyint(1) DEFAULT '1' COMMENT '是否展示',
PRIMARY KEY (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.2 前端Vue工程关键配置
使用Vue CLI创建项目时需要添加这些特殊依赖:
bash复制vue add element-ui # 添加UI组件库
npm install vue-router --save # 路由管理
npm install axios --save # HTTP请求库
在vue.config.js中配置代理解决跨域:
javascript复制module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
}
3. 核心功能模块实现
3.1 药材智能搜索系统
采用Elasticsearch实现药材多维度搜索:
java复制// 搜索服务实现类
@Service
public class HerbSearchServiceImpl implements HerbSearchService {
@Autowired
private RestHighLevelClient esClient;
public List<HerbVO> searchHerbs(String keyword, String property) {
SearchRequest request = new SearchRequest("herb_index");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("name", keyword))
.filter(QueryBuilders.termQuery("property", property));
sourceBuilder.query(boolQuery);
request.source(sourceBuilder);
// 执行搜索并处理结果...
}
}
前端实现带药性过滤的搜索组件:
vue复制<template>
<div class="herb-search">
<el-input v-model="keyword" placeholder="输入药材名称"></el-input>
<el-select v-model="property" placeholder="选择药性">
<el-option label="温性" value="warm"></el-option>
<el-option label="凉性" value="cool"></el-option>
</el-select>
<el-button @click="search">搜索</el-button>
</div>
</template>
3.2 购物车与处方配伍检测
实现药材配伍禁忌检查逻辑:
java复制public class HerbCompatibilityChecker {
private static final Map<String, List<String>> INCOMPATIBLE_MAP =
ImmutableMap.of(
"附子", Arrays.asList("贝母","瓜蒌"),
"甘草", Arrays.asList("甘遂","海藻")
);
public static boolean checkCompatibility(List<String> herbNames) {
// 检查药材配伍禁忌逻辑...
}
}
4. 特色功能开发实录
4.1 药材图片智能识别
采用OpenCV实现药材图像特征提取:
python复制# Python服务端处理脚本
import cv2
import numpy as np
def extract_herb_features(image_path):
img = cv2.imread(image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 使用SIFT算法提取特征
sift = cv2.SIFT_create()
kp, des = sift.detectAndCompute(gray, None)
return des.tolist()
前端调用识别接口:
javascript复制async function identifyHerb(imageFile) {
const formData = new FormData()
formData.append('image', imageFile)
try {
const res = await axios.post('/api/herb/identify', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
})
return res.data.matches
} catch (err) {
console.error('识别失败:', err)
return []
}
}
4.2 智能推荐系统实现
基于用户体质分析推荐算法:
java复制public List<HerbVO> recommendHerbs(UserHealthDTO health) {
// 根据体质特征计算推荐权重
Map<String, Double> featureWeights = calculateWeights(
health.getBodyType(),
health.getSymptoms()
);
return herbDao.selectHerbsByCondition(featureWeights)
.stream()
.sorted(Comparator.comparingDouble(h ->
-calculateMatchScore(h, featureWeights)))
.limit(10)
.collect(Collectors.toList());
}
5. 部署与性能优化方案
5.1 生产环境部署要点
Nginx配置示例:
nginx复制server {
listen 80;
server_name herbstore.example.com;
location / {
root /var/www/herb-store/dist;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
}
5.2 性能优化实战技巧
药材列表接口优化方案:
| 优化措施 | 实施方法 | 预期效果 |
|---|---|---|
| 二级缓存 | Redis+Ehcache | QPS提升300% |
| 图片懒加载 | 前端IntersectionObserver | 首屏加载时间减少40% |
| 数据库分片 | 按药材类别水平分表 | 查询延迟降低60% |
MyBatis批量插入优化:
xml复制<insert id="batchInsertHerbs" parameterType="java.util.List">
INSERT INTO herb_info
(name, price, stock) VALUES
<foreach collection="list" item="item" separator=",">
(#{item.name}, #{item.price}, #{item.stock})
</foreach>
</insert>
6. 典型问题排查指南
6.1 Vue跨域问题深度解决
除了基础的代理配置,还需要注意:
- 后端添加CORS支持:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.allowCredentials(true);
}
}
- 处理预检请求(OPTIONS):
java复制@Component
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain chain) {
response.setHeader("Access-Control-Allow-Origin", "*");
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
chain.doFilter(request, response);
}
}
6.2 MyBatis缓存失效分析
常见缓存问题排查表:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 查询结果不更新 | 一级缓存未清除 | 在Mapper方法上加@Options(flushCache=true) |
| 关联对象缺失 | 二级缓存序列化问题 | 实现Serializable接口 |
| 缓存命中率低 | 缓存策略不当 | 调整cache-ref的flushInterval |
7. 项目扩展与进阶方向
7.1 微信小程序集成方案
通过uni-app实现多端兼容:
javascript复制// 小程序端适配代码
uni.request({
url: '/api/herb/list',
success: (res) => {
this.herbList = res.data
}
})
7.2 供应链管理系统对接
ERP接口对接示例:
java复制@FeignClient(name = "erp-service", url = "${erp.service.url}")
public interface ErpServiceClient {
@PostMapping("/inventory/update")
Result<Boolean> updateInventory(
@RequestBody InventoryUpdateDTO dto);
@GetMapping("/supplier/list")
Result<List<SupplierVO>> getSuppliersByHerbId(
@RequestParam("herbId") Long herbId);
}
在开发过程中,我们发现药材属性标注的准确性直接影响推荐系统效果。通过引入专家审核流程,将推荐准确率从78%提升到了93%。另一个实用技巧是在Vue组件中合理使用keep-alive缓存药材详情页,使页面切换速度提升40%。
