随着数字化健康管理需求的不断增长,针对特定人群的健康信息平台应运而生。本系统采用经典的SSM(Spring+SpringMVC+MyBatis)框架架构,构建了一个专注于女性健康领域的综合管理平台。该平台不仅提供了基础的健康数据记录与追踪功能,还整合了健康知识库、社区交流、健康产品电商等模块,形成了完整的健康服务生态。
系统架构与技术栈
平台采用典型的三层架构设计,实现了表现层、业务逻辑层和数据访问层的清晰分离。Spring Framework作为核心容器,负责管理所有Bean的生命周期和依赖注入,通过声明式事务管理确保数据操作的原子性和一致性。SpringMVC框架处理Web请求的分发和响应,基于注解的控制器设计使得URL映射更加直观。持久层选用MyBatis框架,其灵活的SQL映射机制和动态SQL能力特别适合复杂的健康数据查询场景。
技术栈配置如下:
<!-- Spring核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- MyBatis整合Spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
数据库设计亮点
订单表设计的业务逻辑处理
ordermsg表的设计体现了复杂的电商业务逻辑,通过状态字段的精细划分支持完整的订单生命周期管理:
CREATE TABLE `ordermsg` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`ddno` varchar(255) DEFAULT NULL COMMENT '订单号',
`memberid` varchar(255) DEFAULT NULL COMMENT '会员ID',
`productid` varchar(255) DEFAULT NULL COMMENT '商品ID',
`num` int(11) DEFAULT NULL COMMENT '购买数量',
`total` double(255,2) DEFAULT NULL COMMENT '订单总额',
`fkstatus` varchar(255) DEFAULT NULL COMMENT '付款状态',
`shstatus` varchar(11) DEFAULT NULL COMMENT '收货状态',
`addr` varchar(255) DEFAULT NULL COMMENT '收货地址',
`savetime` varchar(255) DEFAULT NULL COMMENT '下单时间',
`delstatus` varchar(255) DEFAULT NULL COMMENT '删除状态',
`shfs` varchar(255) DEFAULT NULL COMMENT '配送方式',
`zffs` varchar(255) DEFAULT NULL COMMENT '支付方式',
`saver` varchar(255) DEFAULT NULL COMMENT '操作人',
`isdd` varchar(255) DEFAULT NULL COMMENT '是否订单',
`fid` varchar(255) DEFAULT NULL COMMENT '父级ID',
`goodsid` varchar(255) DEFAULT NULL COMMENT '商品ID',
`goodstype` varchar(255) DEFAULT NULL COMMENT '商品类型',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=39 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='订单表'
该表设计的亮点在于:
- 状态机设计:通过
fkstatus(付款状态)、shstatus(收货状态)、delstatus(删除状态)等多个状态字段,完整描述了订单从创建到完成的整个生命周期 - 业务扩展性:
isdd字段支持订单与预订单的区分,fid字段支持订单拆分和合并的复杂业务场景 - 审计追踪:
saver字段记录操作人,savetime记录操作时间,满足业务审计需求
商品信息表的多级分类设计
product表采用两级分类架构,支持灵活的商品组织方式:
CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`productno` varchar(255) DEFAULT NULL COMMENT '商品编号',
`productname` varchar(255) DEFAULT NULL COMMENT '商品名称',
`filename` varchar(255) DEFAULT NULL COMMENT '图片名称',
`price` decimal(10,2) DEFAULT NULL COMMENT '现价',
`tprice` decimal(10,2) DEFAULT NULL COMMENT '原价',
`fid` varchar(255) DEFAULT NULL COMMENT '一级分类ID',
`sid` varchar(255) DEFAULT NULL COMMENT '二级分类ID',
`content` text DEFAULT NULL COMMENT '商品详情',
`delstatus` varchar(255) DEFAULT NULL COMMENT '删除状态',
`issj` varchar(255) DEFAULT NULL COMMENT '是否上架',
`istj` varchar(255) DEFAULT NULL COMMENT '是否推荐',
`saver` varchar(255) DEFAULT NULL COMMENT '操作人',
`productid` varchar(255) DEFAULT NULL COMMENT '商品ID',
`leibie` varchar(255) DEFAULT NULL COMMENT '类别',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=153 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='商品表'
该表通过fid和sid字段实现商品的多级分类,配合issj(上架状态)和istj(推荐状态)实现商品的动态管理。价格字段使用decimal(10,2)类型确保金额计算的精确性。
核心功能实现
健康知识管理与展示
平台内置了完善的健康知识库系统,通过news和xinwen表存储健康资讯和科普文章。前端页面采用响应式设计,确保在不同设备上都能获得良好的阅读体验。

控制器层实现知识内容的动态加载和分页展示:
@Controller
@RequestMapping("/news")
public class NewsController {
@Autowired
private NewsService newsService;
@RequestMapping("/list")
public String getNewsList(
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "size", defaultValue = "10") Integer size,
Model model) {
// 使用PageHelper实现分页
PageHelper.startPage(page, size);
List<News> newsList = newsService.findAll();
PageInfo<News> pageInfo = new PageInfo<>(newsList);
model.addAttribute("newsList", newsList);
model.addAttribute("pageInfo", pageInfo);
return "news/list";
}
@RequestMapping("/detail/{id}")
public String getNewsDetail(@PathVariable("id") Integer id, Model model) {
News news = newsService.findById(id);
model.addAttribute("news", news);
return "news/detail";
}
}
服务层实现业务逻辑处理和数据校验:
@Service
@Transactional
public class NewsServiceImpl implements NewsService {
@Autowired
private NewsMapper newsMapper;
@Override
public List<News> findAll() {
return newsMapper.selectAll();
}
@Override
public News findById(Integer id) {
if (id == null || id <= 0) {
throw new IllegalArgumentException("新闻ID不合法");
}
return newsMapper.selectByPrimaryKey(id);
}
@Override
public void save(News news) {
// 参数校验
if (news.getTitle() == null || news.getTitle().trim().isEmpty()) {
throw new IllegalArgumentException("新闻标题不能为空");
}
// 设置默认值
if (news.getSavetime() == null) {
news.setSavetime(new Date());
}
newsMapper.insert(news);
}
}
个人健康数据管理
用户可以通过个人中心记录和查看各项健康指标,系统提供趋势分析和数据可视化功能:

健康数据实体类设计:
@Entity
@Table(name = "health_record")
public class HealthRecord {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "user_id")
private Integer userId;
@Column(name = "record_type")
private String recordType; // 记录类型:weight, sleep, cycle等
@Column(name = "record_value")
private Double recordValue;
@Column(name = "record_date")
@Temporal(TemporalType.DATE)
private Date recordDate;
@Column(name = "remark")
private String remark;
@Column(name = "create_time")
@Temporal(TemporalType.TIMESTAMP)
private Date createTime;
// Getter和Setter方法
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public Integer getUserId() { return userId; }
public void setUserId(Integer userId) { this.userId = userId; }
public String getRecordType() { return recordType; }
public void setRecordType(String recordType) { this.recordType = recordType; }
public Double getRecordValue() { return recordValue; }
public void setRecordValue(Double recordValue) { this.recordValue = recordValue; }
public Date getRecordDate() { return recordDate; }
public void setRecordDate(Date recordDate) { this.recordDate = recordDate; }
public String getRemark() { return remark; }
public void setRemark(String remark) { this.remark = remark; }
public Date getCreateTime() { return createTime; }
public void setCreateTime(Date createTime) { this.createTime = createTime; }
}
数据访问层使用MyBatis的动态SQL实现复杂查询:
<!-- HealthRecordMapper.xml -->
<mapper namespace="com.mapper.HealthRecordMapper">
<resultMap id="BaseResultMap" type="com.entity.HealthRecord">
<id column="id" property="id" />
<result column="user_id" property="userId" />
<result column="record_type" property="recordType" />
<result column="record_value" property="recordValue" />
<result column="record_date" property="recordDate" />
<result column="remark" property="remark" />
<result column="create_time" property="createTime" />
</resultMap>
<select id="selectByCondition" parameterType="map" resultMap="BaseResultMap">
SELECT * FROM health_record
WHERE user_id = #{userId}
<if test="recordType != null and recordType != ''">
AND record_type = #{recordType}
</if>
<if test="startDate != null">
AND record_date >= #{startDate}
</if>
<if test="endDate != null">
AND record_date <= #{endDate}
</if>
ORDER BY record_date DESC
</select>
<select id="selectTrendData" parameterType="map" resultType="map">
SELECT
record_date as date,
AVG(record_value) as avgValue,
COUNT(*) as recordCount
FROM health_record
WHERE user_id = #{userId}
AND record_type = #{recordType}
AND record_date BETWEEN #{startDate} AND #{endDate}
GROUP BY record_date
ORDER BY record_date
</select>
</mapper>
电商购物车与订单管理
平台集成了健康产品电商功能,支持完整的购物流程:

购物车业务逻辑实现:
@Service
@Transactional
public class CartServiceImpl implements CartService {
@Autowired
private ProductMapper productMapper;
@Autowired
private CartMapper cartMapper;
@Override
public void addToCart(Integer userId, Integer productId, Integer quantity) {
// 检查商品是否存在且上架
Product product = productMapper.selectByPrimaryKey(productId);
if (product == null || !"是".equals(product.getIssj())) {
throw new RuntimeException("商品不存在或已下架");
}
// 检查库存
if (quantity > product.getStock()) {
throw new RuntimeException("库存不足");
}
// 检查购物车中是否已存在该商品
CartItem cartItem = cartMapper.selectByUserAndProduct(userId, productId);
if (cartItem != null) {
// 更新数量
cartItem.setQuantity(cartItem.getQuantity() + quantity);
cartMapper.updateQuantity(cartItem);
} else {
// 新增购物车项
cartItem = new CartItem();
cartItem.setUserId(userId);
cartItem.setProductId(productId);
cartItem.setQuantity(quantity);
cartItem.setUnitPrice(product.getPrice());
cartItem.setCreateTime(new Date());
cartMapper.insert(cartItem);
}
}
@Override
public CartVO getCartDetail(Integer userId) {
List<CartItemVO> items = cartMapper.selectCartItemsByUser(userId);
CartVO cartVO = new CartVO();
cartVO.setItems(items);
// 计算总价
double totalAmount = items.stream()
.mapToDouble(item -> item.getQuantity() * item.getUnitPrice().doubleValue())
.sum();
cartVO.setTotalAmount(BigDecimal.valueOf(totalAmount));
return cartVO;
}
}
订单创建和支付流程:
@Controller
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping("/create")
@ResponseBody
public ResultVO createOrder(@RequestBody OrderCreateDTO createDTO,
HttpSession session) {
try {
User user = (User) session.getAttribute("currentUser");
if (user == null) {
return ResultVO.error("请先登录");
}
OrderVO orderVO = orderService.createOrder(user.getId(), createDTO);
return ResultVO.success("订单创建成功", orderVO);
} catch (BusinessException e) {
return ResultVO.error(e.getMessage());
}
}
@PostMapping("/pay")
@ResponseBody
public ResultVO payOrder(@RequestParam String orderNo,
@RequestParam String payType) {
try {
PaymentResult result = orderService.processPayment(orderNo, payType);
return ResultVO.success("支付成功", result);
} catch (PaymentException e) {
return ResultVO.error("支付失败: " + e.getMessage());
}
}
}
实体模型设计
系统采用面向对象的实体设计,每个实体类对应数据库中的一张表,通过注解实现ORM映射:
// 基础实体类
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Integer id;
@Column(name = "create_time")
@Temporal(TemporalType.TIMESTAMP)
protected Date createTime;
@Column(name = "update_time")
@Temporal(TemporalType.TIMESTAMP)
protected Date updateTime;
@PrePersist
protected void onCreate() {
createTime = new Date();
updateTime = new Date();
}
@PreUpdate
protected void onUpdate() {
updateTime = new Date();
}
// Getter和Setter方法
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public Date getCreateTime() { return createTime; }
public void setCreateTime(Date createTime) { this.createTime = createTime; }
public Date getUpdateTime() { return updateTime; }
public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; }
}
// 用户实体继承基础实体
@Entity
@Table(name = "member")
public class User extends BaseEntity {
@Column(name = "username", unique = true, nullable = false)
private String username;
@Column(name = "password", nullable = false)
private String password;
@Column(name = "email")
private String email;
@Column(name = "phone")
private String phone;
@Column(name = "gender")
private String gender;
@Column(name = "birthday")
@Temporal(TemporalType.DATE)
private Date birthday;
@Column(name = "status")
private String status = "active";
// 一对多关系:用户与地址
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Address> addresses = new ArrayList<>();
// 一对多关系:用户与订单
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Order> orders = new ArrayList<>();
// Getter和Setter方法
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPhone() { return phone; }
public void setPhone(String phone) { this.phone = phone; }
public String getGender() { return gender; }
public void setGender(String gender) { this.gender = gender; }
public Date getBirthday() { return birthday; }
public void setBirthday(Date birthday) { this.birthday = birthday; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public List<Address> getAddresses() { return addresses; }
public void setAddresses(List<Address> addresses) { this.addresses = addresses; }
public List<Order> getOrders() { return orders;