生活服务类小程序开发正成为互联网创业的热点领域,头皮理疗预约小程序作为其中的细分品类,具有广阔的市场前景和用户需求。基于微信小程序原生开发或uniapp框架,结合Java后端和MySQL数据库,可构建一个功能完善、性能稳定且易于维护的头皮理疗预约平台。本文将从零开始,详细阐述头皮理疗预约小程序的完整开发流程,包括系统架构设计、核心功能模块实现、商家管理后台开发等关键环节,提供可直接复用的代码片段和详细解释。
一、技术选型与系统架构设计
在开发头皮理疗预约小程序前,需先确定合适的技术栈。根据参考产品MrJudy的开发经验,以及当前主流技术趋势,建议采用以下技术组合:
前端框架:优先选择uniapp开发,其基于Vue.js的语法和跨平台能力可显著提升开发效率。若项目未来有扩展多端(如APP、H5)的需求,uniapp能实现”一次开发,多端发布”,降低维护成本。同时,对于微信生态中深度集成的功能(如支付、分享),可结合微信小程序原生组件使用,确保最佳用户体验。
后端框架:推荐使用Spring Boot,因其具备轻量级、配置简单、企业级支持等特点。在MrJudy项目中,陶冶工程师团队正是采用Java(SSM框架)开发后端,积累了丰富的经验。Spring Boot相比传统SSM框架,能进一步简化配置,提升开发效率,同时提供强大的RESTful API支持。
数据库:采用MySQL作为主数据库,存储用户信息、订单数据、服务项目等结构化数据。对于非结构化数据(如图片、评价文本)和缓存需求,可结合Redis使用,提升系统性能。
系统整体架构采用分层设计,包括表现层、业务逻辑层和数据访问层。表现层由uniapp构建,业务逻辑层由Spring Boot实现,数据访问层通过MyBatis或JPA与MySQL数据库交互。这种架构使各层职责清晰,便于开发、维护和扩展,同时保证数据的安全性和一致性。
// Spring Boot配置示例
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/business/**").hasRole("BUSINESS")
.anyRequest().authenticated();
}
}
二、数据库表结构设计
数据库设计是系统开发的基础,合理的表结构可提升系统性能和可维护性。以下是头皮理疗预约小程序的核心数据库表设计:
用户表(users):存储用户基本信息,包括会员等级和积分。
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
open_id VARCHAR(100) NOT NULL UNIQUE,
mobile VARCHAR(20),
nickname VARCHAR(50),
integral INT DEFAULT 0,
current_level INT,
created_time DATETIME,
updated_time DATETIME
);
会员等级表(member_levels):定义不同会员等级的积分要求和权益。
CREATE TABLE member_levels (
id INT PRIMARY KEY AUTO_INCREMENT,
level_name VARCHAR(20) NOT NULL,
integral_threshold INT NOT NULL,
discount_rate DECIMAL(3,2) NOT NULL,
created_time DATETIME
);
服务项目表(service_projects):存储可预约的头皮理疗服务项目信息。
CREATE TABLE service_projects (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
price DECIMAL(10,2) NOT NULL,
duration INT NOT NULL,
image_url VARCHAR(200),
max_appointments INT NOT NULL,
created_time DATETIME,
updated_time DATETIME
);
理疗师表(therapists):存储理疗师信息及其可提供的服务项目。
CREATE TABLE therapists (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
skill_set VARCHAR(200),
available_time VARCHAR(100),
created_time DATETIME,
updated_time DATETIME
);
排班表(schedules):记录理疗师的每日可预约时间段和剩余名额。
CREATE TABLE schedules (
id INT PRIMARY KEY AUTO_INCREMENT,
therapist_id INT NOT NULL,
service_project_id INT NOT NULL,
date DATE NOT NULL,
time_slot VARCHAR(20) NOT NULL,
remaining_slots INT NOT NULL,
created_time DATETIME,
updated_time DATETIME,
FOREIGN KEY (therapist_id) REFERENCES therapists(id),
FOREIGN KEY (service_project_id) REFERENCES service_projects(id)
);
订单表(orders):记录用户预约信息和状态。
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
therapist_id INT NOT NULL,
service_project_id INT NOT NULL,
order_status ENUM('PENDING', 'RESERVED', 'COMPLETED', 'CANCELLED') NOT NULL,
reserve_date DATE NOT NULL,
reserve_time_slot VARCHAR(20) NOT NULL,
payment_amount DECIMAL(10,2) NOT NULL,
integral_used INT,
coupon_id INT,
payment_method VARCHAR(20),
created_time DATETIME,
updated_time DATETIME,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (therapist_id) REFERENCES therapists(id),
FOREIGN KEY (service_project_id) REFERENCES service_projects(id),
FOREIGN KEY (coupon_id) REFERENCES coupons(id)
);
优惠券表(coupons):存储优惠券信息及其使用状态。
CREATE TABLE coupons (
id INT PRIMARY KEY AUTO_INCREMENT,
type ENUM('DISCOUNT', 'FIXED', 'FULL_REDUCTION') NOT NULL,
value DECIMAL(10,2) NOT NULL,
validity_start DATE NOT NULL,
validity_end DATE NOT NULL,
issuance_id INT,
created_time DATETIME,
updated_time DATETIME,
FOREIGN KEY (issuance_id) REFERENCES coupon_issuance(id)
);
评价表(comments):存储用户对服务的评价信息。
CREATE TABLE comments (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
therapist_id INT NOT NULL,
order_id INT NOT NULL,
rating INT NOT NULL,
comment_text VARCHAR(500),
images JSON,
created_time DATETIME,
updated_time DATETIME,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (therapist_id) REFERENCES therapists(id),
FOREIGN KEY (order_id) REFERENCES orders(id)
);
积分记录表(integral_records):记录用户积分变动历史。
CREATE TABLE integral_records (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
integral_type ENUM('CONSUME', 'EVALUATE', 'SIGNIN') NOT NULL,
integral_value INT NOT NULL,
related_order_id INT,
created_time DATETIME,
FOREIGN KEY (user_id) REFERENCES users(id)
);
消息提醒表(messages):存储系统通知信息。
CREATE TABLE messages (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
content VARCHAR(200) NOT NULL,
read_status BOOLEAN DEFAULT false,
created_time DATETIME,
FOREIGN KEY (user_id) REFERENCES users(id)
);
三、用户注册登录与会员体系实现
用户注册登录是小程序的基础功能,采用微信授权登录可简化用户操作并确保安全性。会员体系则能提升用户粘性,促进消费。
微信授权登录实现:通过wx.login()
获取用户code,后端调用微信接口换取openID,绑定用户信息并生成JWT令牌。
// Spring Boot控制器示例
@RestController
@RequestMapping("/api/login")
public class WechatLoginController {
@Autowired
private WeChatProperties weChatProperties;
@PostMapping
public ResponseEntity<LoginResponse> wechatLogin(@RequestParam String code) {
// 通过code换取openId
String openId = weChatService.getOpenId(code, weChatProperties.getAppid(), weChatProperties.getSecret());
// 检查用户是否存在
User user = userService.getUserByOpenId(openId);
if (user == null) {
user = userService.createUserByOpenId(openId);
}
// 生成JWT令牌
String token = jwtService.generateToken(user.getId(), user.getOpenId());
return ResponseEntity.ok(new LoginResponse(token));
}
}
JWT生成与解析:使用jjwt库实现令牌的生成和验证,确保接口安全。
// JWT工具类示例
@Component
public class JwtUtil {
@Value("${jwt.secret}")
private String secret;
public String generateToken(String openId) {
return Jwts.builder()
.setSubject(openId)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 10小时有效期
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
}
public String extractOpenId(String token) {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secret).parse ClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
}
会员等级管理:根据用户积分自动升级会员等级,提供相应折扣。
// 会员服务类示例
@Service
public class MemberLevelService {
@Autowired
private MemberLevelRepository memberLevelRepository;
@Autowired
private UserService userService;
public void checkAndUpgradeMemberLevel(Long userId) {
User user = userService.getUserById(userId);
MemberLevel currentLevel = memberLevelRepository.findById(user.getCurrentLevel()).orElse(null);
if (currentLevel != null) {
MemberLevel nextLevel = memberLevelRepository.findByIntegralThresholdLessThanEqualOrderByIdDesc(user.getIntegral()).stream().findFirst().orElse(currentLevel);
if (!nextLevel.equals(currentLevel)) {
user.setCurrentLevel(nextLevel.getId());
userService.updateUser(user);
}
}
}
}
四、服务项目展示与预约管理
服务项目展示是用户了解和选择理疗服务的关键环节,预约管理则涉及复杂的业务逻辑,需确保数据一致性。
服务项目分页展示:通过RESTful API获取服务项目列表,支持分页和筛选。
// 服务项目控制器示例
@RestController
@RequestMapping("/api/service-projects")
public class ServiceProjectController {
@Autowired
private ServiceProjectService serviceProjectService;
@GetMapping
public ResponseEntity<PageResponse<ServiceProject>> listServiceProjects(
@RequestParam(required = false, defaultValue = "1") Integer page,
@RequestParam(required = false, defaultValue = "10") Integer size
) {
Pageable pageable = PageRequest.of(page - 1, size);
Page<ServiceProject> pageResult = serviceProjectService.listServiceProjects(pageable);
return ResponseEntity.ok(new PageResponse<>(pageResult));
}
}
理疗师详情展示:关联服务项目和排班信息,提供完整的理疗师介绍。
// 理疗师控制器示例
@RestController
@RequestMapping("/api/therapists")
public class TherapistController {
@Autowired
private TherapistService therapistService;
@GetMapping("/{id}")
public ResponseEntity<TherapistDetailVO> getTherapistDetail(@PathVariable Long id) {
TherapistDetailVO therapistDetailVO = therapistService.getTherapistDetail(id);
return ResponseEntity.ok(therapistDetailVO);
}
}
预约冲突检测:在用户提交预约前,检查理疗师在选定时间段的剩余可预约名额。
// 预约服务类示例
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private ScheduleRepository scheduleRepository;
public boolean checkAppointmentConflict(Long therapistId, Date reserveDate, String reserveTimeSlot) {
Schedule schedule = scheduleRepository.findByTherapistIdAndDateAndTimeSlot(therapistId, reserveDate, reserveTimeSlot);
return schedule != null && schedule.getRemainingSlots() > 0;
}
}
预约提交与订单创建:在事务中更新订单状态和排班表的剩余名额。
// 预约提交接口示例
@PostMapping("/api/orders")
@Transactional
public ResponseEntity createOrder(@RequestBody OrderRequest orderRequest) {
// 检查预约冲突
if (!orderService.checkAppointmentConflict(orderRequest.getTherapistId(), orderRequest.getReserveDate(), orderRequest.getReserveTimeSlot())) {
return ResponseEntity.badRequest().body("预约时间已满,请选择其他时间段");
}
// 创建订单
Order order = orderService.createOrder(orderRequest);
// 更新排班表剩余名额
scheduleService.decreaseRemainingSlots(order.getTherapistId(), order.getReserveDate(), order.getReserveTimeSlot());
return ResponseEntity.ok(order);
}
五、支付功能实现
支付功能是小程序的核心交易环节,需确保安全、稳定且用户体验良好。
微信支付统一下单接口:生成支付订单,调用微信支付API。
// 微信支付服务类示例
@Service
public class WxPayService {
@Value("${wx.pay.appId}")
private String appId;
@Value("${wx.pay.mchId}")
private String mchId;
@Value("${wx.pay.key}")
private String key;
@Value("${wx.pay.notifyUrl}")
private String notifyUrl;
public Map<String, String> unifiedOrder(Order order) {
// 构建统一下单请求参数
Map<String, String> requestParams = new HashMap<>();
requestParams.put("appid", appId);
requestParams.put("mch_id", mchId);
requestParams.put("nonce_str", UUID.randomUUID().toString().replace("-", ""));
requestParams.put("body", "头皮理疗预约");
requestParams.put("out_trade_no", order.getId().toString());
requestParams.put("total_fee", String.valueOf(order.getPaymentAmount() * 100)); // 以分为单位
requestParams.put("spbill_create_ip", "123.12.12.123");
requestParams.put("notify_url", notifyUrl);
requestParams.put("trade_type", "JSAPI");
requestParams.put("openid", order.getUser().getOpenId());
// 生成签名
String sign = WxPayUtil.createSign(requestParams, key);
requestParams.put("sign", sign);
// 发起统一下单请求
String xml = WxPayUtil.mapToXml(requestParams);
String result = HttpClientUtil.doPost("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);
Map<String, String> resultMap = WxPayUtil.xmlToMap(result);
// 返回前端需要的支付参数
Map<String, String> payParams = new HashMap<>();
payParams.put("appId", appId);
payParams.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
payParams.put("nonceStr", UUID.randomUUID().toString().replace("-", ""));
payParams.put("package", "prepay_id=" + resultMap.get("prepay_id"));
payParams.put("signType", "MD5");
payParams.put("paySign", WxPayUtil.createSign(payParams, key));
return payParams;
}
}
微信支付回调处理:接收微信支付结果通知,更新订单状态。
// 微信支付回调控制器示例
@PostMapping("/api/pay/notify")
public String payNotify(HttpServletRequest request) {
try {
String xmlData = IOUtils.toString(request.getInputStream(), "UTF-8");
Map<String, String> data = WxPayUtil.parseXml(xmlData);
// 验证签名
String sign = data.get("sign");
if (WxPayUtil.generateSign(data, key).equals(sign)) {
// 处理业务逻辑,例如更新订单状态
String outTradeNo = data.get("out_trade_no");
orderService.updateOrderPaid(outTradeNo);
return "<xml><return_code>SUCCESS</return_code></xml>";
}
} catch (Exception e) {
e.printStackTrace();
}
return "<xml><return_code>FAIL</return_code></xml>";
}
优惠券与积分抵扣:在支付前计算最终金额,扣除用户积分并核销优惠券。
// 优惠券服务类示例
@Service
public class CouponService {
@Autowired
private CouponRepository couponRepository;
@Autowired
private Coupon IssuanceRepository coupon IssuanceRepository;
public Coupon applyCoupon(Long userId, Long couponId, Double orderAmount) {
Coupon coupon = couponRepository.findById(couponId).orElse(null);
if (coupon == null || coupon.getIsUsed()) {
return null;
}
Coupon Issuance coupon Issuance = coupon IssuanceRepository.findById(coupon.getIssuanceId()).orElse(null);
if (coupon Issuance == null || coupon Issuance.getEndDate().before(new Date())) {
return null;
}
// 校验优惠券使用条件
if (coupon.getType().equals("FULL_REDUCTION") && orderAmount < coupon.getValue()) {
return null;
}
coupon.setIsUsed(true);
couponRepository.save(coupon);
return coupon;
}
}
六、评价反馈与消息提醒
评价反馈能帮助商家了解服务质量,促进改进;消息提醒则能增强用户粘性,提高活跃度。
评价提交接口:用户完成服务后可提交评价,包含评分、文本和图片。
// 评价控制器示例
@RestController
@RequestMapping("/api/comments")
public class CommentController {
@Autowired
private CommentService commentService;
@PostMapping
public ResponseEntity createComment(@RequestBody CommentRequest commentRequest) {
// 检查用户是否有权限提交该订单的评价
if (orderService.checkCommentPermission(commentRequest.getUserId(), commentRequest.getOrderId())) {
Comment comment = commentService.createComment(commentRequest);
return ResponseEntity.ok(comment);
}
return ResponseEntity.badRequest().body("无权限提交该订单评价");
}
}
消息提醒实现:系统自动发送预约成功、优惠券过期等通知。
// 消息服务类示例
@Service
public class MessageService {
@Autowired
private MessageRepository messageRepository;
public void sendAppointmentSuccessMessage(Long userId, Long orderId) {
Message message = new Message();
message.setUserId(userId);
message.setContent("您的头皮理疗预约已成功,请准时到达");
message.setMessageType("APPOINTMENT_SUCCESS");
messageRepository.save(message);
}
public void sendCouponExpirationMessage(Long userId, Long couponId) {
Coupon coupon = couponRepository.findById(couponId).orElse(null);
if (coupon != null && coupon.getEndDate().before(new Date().plusDays(3))) {
Message message = new Message();
message.setUserId(userId);
message.setContent("您的优惠券即将过期,请尽快使用");
message.setMessageType("COUPON_EXPIRATION");
messageRepository.save(message);
}
}
}
七、商家管理后台开发
商家管理后台是商家运营的核心工具,需提供订单管理、数据统计、优惠券发放和内容管理等功能。
订单管理实现:商家可查看和管理订单状态,包括已完成、待支付等。
// 商家订单控制器示例
@RestController
@RequestMapping("/api/admin/orders")
@PreAuthorize("hasRole('ADMIN')")
public class AdminOrderController {
@Autowired
private OrderRepository orderRepository;
@GetMapping
public ResponseEntity<PageResponse<Order>> listOrders(
@RequestParam(required = false) String status,
@RequestParam(required = false) Date date,
@RequestParam(required = false, defaultValue = "1") Integer page,
@RequestParam(required = false, defaultValue = "10") Integer size
) {
// 构建查询条件
ExampleMatcher matcher = ExampleMatcher.matching()
.withMatcher("status", ExampleMatcher.GenericPropertyMatchers.contains())
.withMatcher("reserveDate", ExampleMatcher.GenericPropertyMatchers.contains());
OrderExample orderExample = new OrderExample();
orderExample.createCriteria()
.andStatusLike(status)
.andReserveDateLike(date);
Pageable pageable = PageRequest.of(page - 1, size);
Page<Order> pageResult = orderRepository.findAll(orderExample, pageable);
return ResponseEntity.ok(new PageResponse<>(pageResult));
}
@PutMapping("/{id}/status")
@Transactional
public ResponseEntity updateOrderStatus(
@PathVariable Long id,
@RequestParam String newStatus
) {
Order order = orderRepository.findById(id).orElse(null);
if (order == null) {
return ResponseEntity.badRequest().body("订单不存在");
}
// 校验新状态是否合法
if (newStatus.equals("COMPLETED")) {
// 更新评价状态等
orderService.markOrderCompleted(order.getId());
}
order.setOrderStatus(newStatus);
orderRepository.save(order);
return ResponseEntity.ok(order);
}
}
数据统计分析:集成ECharts展示订单量、用户评价分布等数据。
// 统计服务类示例
@Service
public class StatisticsService {
@Autowired
private OrderRepository orderRepository;
public MonthlyOrderStatistics getMonthlyOrderStatistics() {
// 获取当前月份
YearMonth currentMonth = YearMonth.now();
// 查询各月份订单数量
List<MonthlyOrderCount> monthlyOrderCounts = orderRepository.countOrdersByMonth(currentMonth.minusMonths(11), currentMonth);
// 构建统计结果
MonthlyOrderStatistics statistics = new MonthlyOrderStatistics();
statistics.getMonthlyOrderCounts().addAll(monthlyOrderCounts);
return statistics;
}
}
优惠券发放批次管理:商家可创建优惠券发放批次,控制发放数量和有效期。
// 优惠券发放服务类示例
@Service
public class CouponIssuanceService {
@Autowired
private CouponIssuanceRepository couponIssuanceRepository;
@Autowired
private CouponRepository couponRepository;
public CouponIssuance createCouponIssuance(CouponIssuanceRequest issuanceRequest) {
CouponIssuance issuance = new CouponIssuance();
issuance.setBatchName(issuanceRequest.getBatchName());
issuance.setTotalCoupons(issuanceRequest.getTotalCoupons());
issuance.setStartDate(issuanceRequest.getStartDate());
issuance.setEndDate(issuanceRequest.getEndDate());
issuance.setTargetUsers(issuanceRequest.getTargetUsers());
issuance = couponIssuanceRepository.save(issuance);
// 生成优惠券
for (int i = 0; i < issuanceRequest.getTotalCoupons(); i++) {
Coupon coupon = new Coupon();
coupon.setType(issuanceRequest.getType());
coupon.setValue(issuanceRequest.getValue());
coupon.setValidityStart(issuanceRequest.getStartDate());
coupon.setValidityEnd(issuanceRequest.getEndDate());
coupon.setIssuanceId(issuance.getId());
couponRepository.save(coupon);
}
return issuance;
}
}
内容管理实现:商家可管理服务项目和理疗师信息,包括图片上传和信息编辑。
// 服务项目控制器示例
@RestController
@RequestMapping("/api/admin/service-projects")
@PreAuthorize("hasRole('ADMIN')")
public class AdminServiceProjectController {
@Autowired
private ServiceProjectRepository serviceProjectRepository;
@PostMapping
public ResponseEntity createServiceProject(@RequestBody ServiceProjectRequest projectRequest) {
ServiceProject project = new ServiceProject();
project.setName(projectRequest.getName());
project.setPrice(projectRequest.getPrice());
project.setDuration(projectRequest.getDuration());
project.setMaxAppointments(projectRequest.getMaxAppointments());
projectRepository.save(project);
return ResponseEntity.ok(project);
}
@PostMapping("/upload")
public ResponseEntity uploadServiceProjectImage(@RequestParam("file") MultipartFile file) {
// 上传图片到服务器并返回URL
String imageUrl = fileService.upload(file);
return ResponseEntity.ok(imageUrl);
}
}
八、总结与展望
系统整体架构流程图
头皮理疗预约小程序的开发是一项系统工程,需要前后端紧密配合,合理设计架构和数据库表结构。通过采用Spring Boot+uniapp+MySQL的技术栈,结合微信生态的特性,可构建一个功能完善、性能稳定且易于维护的平台。
核心功能实现要点:
用户注册登录需采用微信授权机制,结合JWT令牌进行安全认证
服务项目展示需支持分页和筛选,理疗师详情需关联排班信息
预约管理需实现冲突检测和事务处理,确保数据一致性
支付功能需集成微信支付API,处理优惠券和积分抵扣逻辑
评价反馈和消息提醒需设计相应的API和前端展示界面
未来扩展方向:
可考虑引入微服务架构,将用户、订单、支付等模块拆分为独立服务
增加更多数据分析功能,如用户行为分析、服务项目热度预测等
支持多平台扩展,利用uniapp的跨端能力发布到支付宝、APP等平台
引入AI技术,如智能客服、服务推荐系统等,提升用户体验
集成更多第三方服务,如地图导航、人脸识别等,增强功能多样性
通过本文提供的完整开发流程和代码示例,开发者可快速上手并构建一个高质量的头皮理疗预约小程序。在实际开发中,建议采用敏捷开发模式,分阶段实现功能模块,及时测试和优化,确保系统稳定运行并提供良好的用户体验。
暂无评论内容