refactor: 清理代码、优化结构
- 移除订阅消息相关代码(WxSubscribeMessageService、subscribeTemplateId配置) - 提取Result类为独立公共类(common.Result) - 拆分Controller: WxLoginController(登录) + AppointmentController(预约) - 引入Lombok(@Data/@Slf4j/@RequiredArgsConstructor)消除样板代码 - 修正WxLoginResult字段命名(session_key->sessionKey+@JsonProperty) - MySQL驱动升级mysql-connector-java->mysql-connector-j - updateStatus SQL增加status='pending'校验防并发重复审批 - pom.xml配置spring-boot-maven-plugin排除lombok
This commit is contained in:
@@ -30,6 +30,13 @@
|
|||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Spring Boot Test -->
|
<!-- Spring Boot Test -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@@ -39,10 +46,10 @@
|
|||||||
|
|
||||||
<!-- MySQL驱动 -->
|
<!-- MySQL驱动 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
<version>8.0.33</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- MyBatis -->
|
<!-- MyBatis -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mybatis.spring.boot</groupId>
|
<groupId>org.mybatis.spring.boot</groupId>
|
||||||
@@ -64,6 +71,14 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.example.mini_program.common;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Result<T> {
|
||||||
|
|
||||||
|
private int code;
|
||||||
|
private String message;
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
public static <T> Result<T> success(T data) {
|
||||||
|
Result<T> result = new Result<>();
|
||||||
|
result.setCode(0);
|
||||||
|
result.setMessage("success");
|
||||||
|
result.setData(data);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> error(String message) {
|
||||||
|
Result<T> result = new Result<>();
|
||||||
|
result.setCode(-1);
|
||||||
|
result.setMessage(message);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> error(String code, String message) {
|
||||||
|
Result<T> result = new Result<>();
|
||||||
|
result.setCode(-1);
|
||||||
|
result.setMessage(code + ": " + message);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,28 +1,14 @@
|
|||||||
package com.example.mini_program.config;
|
package com.example.mini_program.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Data
|
||||||
@Component
|
@Component
|
||||||
@ConfigurationProperties(prefix = "wx.miniapp")
|
@ConfigurationProperties(prefix = "wx.miniapp")
|
||||||
public class WxMiniAppConfig {
|
public class WxMiniAppConfig {
|
||||||
|
|
||||||
private String appid;
|
private String appid;
|
||||||
private String secret;
|
private String secret;
|
||||||
|
|
||||||
public String getAppid() {
|
|
||||||
return appid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAppid(String appid) {
|
|
||||||
this.appid = appid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSecret() {
|
|
||||||
return secret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSecret(String secret) {
|
|
||||||
this.secret = secret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package com.example.mini_program.controller;
|
||||||
|
|
||||||
|
import com.example.mini_program.common.Result;
|
||||||
|
import com.example.mini_program.entity.VisitApplication;
|
||||||
|
import com.example.mini_program.service.AppointmentService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/wx-mini/appointment")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AppointmentController {
|
||||||
|
|
||||||
|
private final AppointmentService appointmentService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据openid获取最新的一条预约记录
|
||||||
|
*/
|
||||||
|
@GetMapping("/latest")
|
||||||
|
public Result<VisitApplication> getLatest(@RequestParam String openid) {
|
||||||
|
if (openid == null || openid.trim().isEmpty()) {
|
||||||
|
return Result.error("openid不能为空");
|
||||||
|
}
|
||||||
|
return Result.success(appointmentService.getLatest(openid));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户所有预约记录(按创建时间倒序)
|
||||||
|
*/
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<VisitApplication>> getList(@RequestParam String openid) {
|
||||||
|
if (openid == null || openid.trim().isEmpty()) {
|
||||||
|
return Result.error("openid不能为空");
|
||||||
|
}
|
||||||
|
return Result.success(appointmentService.getList(openid));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建预约记录
|
||||||
|
*/
|
||||||
|
@PostMapping("/create")
|
||||||
|
public Result<VisitApplication> create(@RequestBody VisitApplication record) {
|
||||||
|
if (record.getOpenid() == null || record.getOpenid().trim().isEmpty()) {
|
||||||
|
return Result.error("openid不能为空");
|
||||||
|
}
|
||||||
|
if (record.getName() == null || record.getName().trim().isEmpty()) {
|
||||||
|
return Result.error("访客姓名不能为空");
|
||||||
|
}
|
||||||
|
if (record.getPhone() == null || record.getPhone().trim().isEmpty()) {
|
||||||
|
return Result.error("联系电话不能为空");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Result.success(appointmentService.create(record));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error("创建预约失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消预约(仅pending状态可取消,需校验openid)
|
||||||
|
*/
|
||||||
|
@PutMapping("/cancel")
|
||||||
|
public Result<Boolean> cancel(@RequestParam String id, @RequestParam String openid) {
|
||||||
|
if (id == null || id.trim().isEmpty()) {
|
||||||
|
return Result.error("id不能为空");
|
||||||
|
}
|
||||||
|
if (openid == null || openid.trim().isEmpty()) {
|
||||||
|
return Result.error("openid不能为空");
|
||||||
|
}
|
||||||
|
boolean success = appointmentService.cancel(id, openid);
|
||||||
|
return success ? Result.success(true) : Result.error("取消失败,无权限或状态不允许");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批预约(通过/拒绝)
|
||||||
|
*/
|
||||||
|
@PutMapping("/approve")
|
||||||
|
public Result<Boolean> approve(@RequestParam String id, @RequestParam String status) {
|
||||||
|
if (id == null || id.trim().isEmpty()) {
|
||||||
|
return Result.error("id不能为空");
|
||||||
|
}
|
||||||
|
if (!"approved".equals(status) && !"rejected".equals(status)) {
|
||||||
|
return Result.error("status只能为approved或rejected");
|
||||||
|
}
|
||||||
|
boolean success = appointmentService.approve(id, status);
|
||||||
|
return success ? Result.success(true) : Result.error("审批失败,记录不存在或状态不允许");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,28 +1,20 @@
|
|||||||
package com.example.mini_program.controller;
|
package com.example.mini_program.controller;
|
||||||
|
|
||||||
import com.example.mini_program.entity.VisitApplication;
|
import com.example.mini_program.common.Result;
|
||||||
import com.example.mini_program.service.AppointmentService;
|
|
||||||
import com.example.mini_program.service.WxLoginService;
|
import com.example.mini_program.service.WxLoginService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/wx-mini")
|
@RequestMapping("/api/wx-mini")
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class WxLoginController {
|
public class WxLoginController {
|
||||||
|
|
||||||
private final WxLoginService wxLoginService;
|
private final WxLoginService wxLoginService;
|
||||||
private final AppointmentService appointmentService;
|
|
||||||
|
|
||||||
public WxLoginController(WxLoginService wxLoginService, AppointmentService appointmentService) {
|
|
||||||
this.wxLoginService = wxLoginService;
|
|
||||||
this.appointmentService = appointmentService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信小程序登录接口
|
* 微信小程序登录接口
|
||||||
* 接收wx.login的code,换取openid
|
* 接收wx.login的code,换取openid
|
||||||
*
|
|
||||||
* @param code 小程序wx.login获取的code
|
|
||||||
* @return openid等信息
|
|
||||||
*/
|
*/
|
||||||
@GetMapping("/login")
|
@GetMapping("/login")
|
||||||
public Result<WxLoginService.WxLoginResult> login(@RequestParam String code) {
|
public Result<WxLoginService.WxLoginResult> login(@RequestParam String code) {
|
||||||
@@ -38,74 +30,4 @@ public class WxLoginController {
|
|||||||
return Result.error(result.getErrcode(), result.getErrmsg());
|
return Result.error(result.getErrcode(), result.getErrmsg());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据openid获取最新的一条预约记录
|
|
||||||
*
|
|
||||||
* @param openid 微信用户openid
|
|
||||||
* @return 最新的一条预约记录
|
|
||||||
*/
|
|
||||||
@GetMapping("/appointment/latest")
|
|
||||||
public Result<VisitApplication> getLatestAppointment(@RequestParam String openid) {
|
|
||||||
if (openid == null || openid.trim().isEmpty()) {
|
|
||||||
return Result.error("openid不能为空");
|
|
||||||
}
|
|
||||||
VisitApplication appointment = appointmentService.getLatest(openid);
|
|
||||||
return Result.success(appointment);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 统一返回结果类
|
|
||||||
*/
|
|
||||||
public static class Result<T> {
|
|
||||||
private int code;
|
|
||||||
private String message;
|
|
||||||
private T data;
|
|
||||||
|
|
||||||
public static <T> Result<T> success(T data) {
|
|
||||||
Result<T> result = new Result<>();
|
|
||||||
result.setCode(0);
|
|
||||||
result.setMessage("success");
|
|
||||||
result.setData(data);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> Result<T> error(String message) {
|
|
||||||
Result<T> result = new Result<>();
|
|
||||||
result.setCode(-1);
|
|
||||||
result.setMessage(message);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> Result<T> error(String code, String message) {
|
|
||||||
Result<T> result = new Result<>();
|
|
||||||
result.setCode(-1);
|
|
||||||
result.setMessage(code + ": " + message);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCode(int code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMessage() {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMessage(String message) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(T data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
package com.example.mini_program.entity;
|
package com.example.mini_program.entity;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAlias;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
public class VisitApplication {
|
public class VisitApplication {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
@@ -7,116 +11,17 @@ public class VisitApplication {
|
|||||||
private String phone;
|
private String phone;
|
||||||
private String company;
|
private String company;
|
||||||
private String reason;
|
private String reason;
|
||||||
|
|
||||||
|
@JsonAlias("date")
|
||||||
private String visitDate;
|
private String visitDate;
|
||||||
|
|
||||||
|
@JsonAlias("time")
|
||||||
private String visitTime;
|
private String visitTime;
|
||||||
|
|
||||||
private String hostName;
|
private String hostName;
|
||||||
private String area;
|
private String area;
|
||||||
private String status;
|
private String status;
|
||||||
private String statusText;
|
private String statusText;
|
||||||
private String openid;
|
private String openid;
|
||||||
private String createTime;
|
private String createTime;
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPhone() {
|
|
||||||
return phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPhone(String phone) {
|
|
||||||
this.phone = phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCompany() {
|
|
||||||
return company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCompany(String company) {
|
|
||||||
this.company = company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getReason() {
|
|
||||||
return reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReason(String reason) {
|
|
||||||
this.reason = reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVisitDate() {
|
|
||||||
return visitDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVisitDate(String visitDate) {
|
|
||||||
this.visitDate = visitDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVisitTime() {
|
|
||||||
return visitTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVisitTime(String visitTime) {
|
|
||||||
this.visitTime = visitTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHostName() {
|
|
||||||
return hostName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHostName(String hostName) {
|
|
||||||
this.hostName = hostName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getArea() {
|
|
||||||
return area;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setArea(String area) {
|
|
||||||
this.area = area;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(String status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatusText() {
|
|
||||||
return statusText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatusText(String statusText) {
|
|
||||||
this.statusText = statusText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOpenid() {
|
|
||||||
return openid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOpenid(String openid) {
|
|
||||||
this.openid = openid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCreateTime() {
|
|
||||||
return createTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreateTime(String createTime) {
|
|
||||||
this.createTime = createTime;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import com.example.mini_program.entity.VisitApplication;
|
|||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface VisitApplicationMapper {
|
public interface VisitApplicationMapper {
|
||||||
|
|
||||||
@@ -14,4 +16,56 @@ public interface VisitApplicationMapper {
|
|||||||
* @return 最新的一条记录,没有则返回null
|
* @return 最新的一条记录,没有则返回null
|
||||||
*/
|
*/
|
||||||
VisitApplication selectLatestByOpenid(@Param("openid") String openid);
|
VisitApplication selectLatestByOpenid(@Param("openid") String openid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据openid查询所有预约记录(按创建时间倒序)
|
||||||
|
*
|
||||||
|
* @param openid 微信用户openid
|
||||||
|
* @return 预约记录列表
|
||||||
|
*/
|
||||||
|
List<VisitApplication> selectListByOpenid(@Param("openid") String openid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增预约记录
|
||||||
|
*
|
||||||
|
* @param record 预约记录
|
||||||
|
* @return 影响行数
|
||||||
|
*/
|
||||||
|
int insert(VisitApplication record);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID和openid取消预约(仅pending状态可取消)
|
||||||
|
*
|
||||||
|
* @param id 记录ID
|
||||||
|
* @param openid 用户openid
|
||||||
|
* @return 影响行数
|
||||||
|
*/
|
||||||
|
int updateStatusToCancelled(@Param("id") String id, @Param("openid") String openid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID和openid查询记录(用于权限校验)
|
||||||
|
*
|
||||||
|
* @param id 记录ID
|
||||||
|
* @param openid 用户openid
|
||||||
|
* @return 预约记录
|
||||||
|
*/
|
||||||
|
VisitApplication selectByIdAndOpenid(@Param("id") String id, @Param("openid") String openid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询记录
|
||||||
|
*
|
||||||
|
* @param id 记录ID
|
||||||
|
* @return 预约记录
|
||||||
|
*/
|
||||||
|
VisitApplication selectById(@Param("id") String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新审批状态
|
||||||
|
*
|
||||||
|
* @param id 记录ID
|
||||||
|
* @param status 状态值
|
||||||
|
* @param statusText 状态文本
|
||||||
|
* @return 影响行数
|
||||||
|
*/
|
||||||
|
int updateStatus(@Param("id") String id, @Param("status") String status, @Param("statusText") String statusText);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,35 +2,105 @@ package com.example.mini_program.service;
|
|||||||
|
|
||||||
import com.example.mini_program.entity.VisitApplication;
|
import com.example.mini_program.entity.VisitApplication;
|
||||||
import com.example.mini_program.mapper.VisitApplicationMapper;
|
import com.example.mini_program.mapper.VisitApplicationMapper;
|
||||||
import org.slf4j.Logger;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.slf4j.LoggerFactory;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
import java.util.List;
|
||||||
public class AppointmentService {
|
import java.util.UUID;
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(AppointmentService.class);
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AppointmentService {
|
||||||
|
|
||||||
private final VisitApplicationMapper visitApplicationMapper;
|
private final VisitApplicationMapper visitApplicationMapper;
|
||||||
|
|
||||||
public AppointmentService(VisitApplicationMapper visitApplicationMapper) {
|
|
||||||
this.visitApplicationMapper = visitApplicationMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据openid获取最新的一条预约记录
|
* 根据openid获取最新的一条预约记录
|
||||||
*
|
|
||||||
* @param openid 微信用户openid
|
|
||||||
* @return 最新的一条预约记录,没有则返回null
|
|
||||||
*/
|
*/
|
||||||
public VisitApplication getLatest(String openid) {
|
public VisitApplication getLatest(String openid) {
|
||||||
logger.info("查询用户最新预约记录, openid: {}", openid);
|
log.info("查询用户最新预约记录, openid: {}", openid);
|
||||||
VisitApplication result = visitApplicationMapper.selectLatestByOpenid(openid);
|
VisitApplication result = visitApplicationMapper.selectLatestByOpenid(openid);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
logger.info("找到预约记录, id: {}", result.getId());
|
log.info("找到预约记录, id: {}", result.getId());
|
||||||
} else {
|
} else {
|
||||||
logger.info("未找到预约记录");
|
log.info("未找到预约记录");
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户所有预约记录(按创建时间倒序)
|
||||||
|
*/
|
||||||
|
public List<VisitApplication> getList(String openid) {
|
||||||
|
log.info("查询用户预约列表, openid: {}", openid);
|
||||||
|
List<VisitApplication> list = visitApplicationMapper.selectListByOpenid(openid);
|
||||||
|
log.info("查询到 {} 条预约记录", list.size());
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建预约记录
|
||||||
|
*/
|
||||||
|
public VisitApplication create(VisitApplication record) {
|
||||||
|
record.setId(UUID.randomUUID().toString().replace("-", ""));
|
||||||
|
record.setStatus("pending");
|
||||||
|
record.setStatusText("待审核");
|
||||||
|
visitApplicationMapper.insert(record);
|
||||||
|
log.info("创建预约记录成功, id: {}, openid: {}", record.getId(), record.getOpenid());
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消预约(仅pending状态可取消,需校验openid)
|
||||||
|
*/
|
||||||
|
public boolean cancel(String id, String openid) {
|
||||||
|
log.info("取消预约, id: {}, openid: {}", id, openid);
|
||||||
|
|
||||||
|
VisitApplication existing = visitApplicationMapper.selectByIdAndOpenid(id, openid);
|
||||||
|
if (existing == null) {
|
||||||
|
log.warn("预约记录不存在或不属于该用户, id: {}, openid: {}", id, openid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!"pending".equals(existing.getStatus())) {
|
||||||
|
log.warn("预约状态不允许取消, id: {}, status: {}", id, existing.getStatus());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rows = visitApplicationMapper.updateStatusToCancelled(id, openid);
|
||||||
|
if (rows > 0) {
|
||||||
|
log.info("取消预约成功, id: {}", id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
log.warn("取消预约失败, id: {}", id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批预约(通过/拒绝)
|
||||||
|
*/
|
||||||
|
public boolean approve(String id, String status) {
|
||||||
|
log.info("审批预约, id: {}, status: {}", id, status);
|
||||||
|
|
||||||
|
VisitApplication existing = visitApplicationMapper.selectById(id);
|
||||||
|
if (existing == null) {
|
||||||
|
log.warn("预约记录不存在, id: {}", id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!"pending".equals(existing.getStatus())) {
|
||||||
|
log.warn("预约状态不允许审批, id: {}, currentStatus: {}", id, existing.getStatus());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String statusText = "approved".equals(status) ? "已通过" : "已拒绝";
|
||||||
|
int rows = visitApplicationMapper.updateStatus(id, status, statusText);
|
||||||
|
if (rows <= 0) {
|
||||||
|
log.warn("审批更新失败, id: {}", id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("审批成功, id: {}, status: {}", id, statusText);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.example.mini_program.service;
|
package com.example.mini_program.service;
|
||||||
|
|
||||||
import com.example.mini_program.config.WxMiniAppConfig;
|
import com.example.mini_program.config.WxMiniAppConfig;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -11,7 +13,8 @@ import org.springframework.web.client.RestTemplate;
|
|||||||
public class WxLoginService {
|
public class WxLoginService {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(WxLoginService.class);
|
private static final Logger logger = LoggerFactory.getLogger(WxLoginService.class);
|
||||||
private static final String JSCODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";
|
private static final String JSCODE2SESSION_URL =
|
||||||
|
"https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";
|
||||||
|
|
||||||
private final WxMiniAppConfig wxMiniAppConfig;
|
private final WxMiniAppConfig wxMiniAppConfig;
|
||||||
private final RestTemplate restTemplate;
|
private final RestTemplate restTemplate;
|
||||||
@@ -23,9 +26,6 @@ public class WxLoginService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 调用微信接口用code换取openid
|
* 调用微信接口用code换取openid
|
||||||
*
|
|
||||||
* @param code 小程序调用wx.login获取的code
|
|
||||||
* @return 登录结果,包含openid等信息
|
|
||||||
*/
|
*/
|
||||||
public WxLoginResult code2Session(String code) {
|
public WxLoginResult code2Session(String code) {
|
||||||
String url = String.format(JSCODE2SESSION_URL,
|
String url = String.format(JSCODE2SESSION_URL,
|
||||||
@@ -33,17 +33,16 @@ public class WxLoginService {
|
|||||||
wxMiniAppConfig.getSecret(),
|
wxMiniAppConfig.getSecret(),
|
||||||
code);
|
code);
|
||||||
|
|
||||||
logger.info("调用微信jscode2session接口,code: {}", code);
|
logger.info("调用微信jscode2session接口, code: {}", code);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 微信返回text/plain,手动解析JSON字符串
|
|
||||||
String response = restTemplate.getForObject(url, String.class);
|
String response = restTemplate.getForObject(url, String.class);
|
||||||
logger.info("微信返回原始结果: {}", response);
|
logger.info("微信返回原始结果: {}", response);
|
||||||
|
|
||||||
JSONObject json = new JSONObject(response);
|
JSONObject json = new JSONObject(response);
|
||||||
WxLoginResult result = new WxLoginResult();
|
WxLoginResult result = new WxLoginResult();
|
||||||
result.setOpenid(json.optString("openid"));
|
result.setOpenid(json.optString("openid"));
|
||||||
result.setSession_key(json.optString("session_key"));
|
result.setSessionKey(json.optString("session_key"));
|
||||||
result.setUnionid(json.optString("unionid"));
|
result.setUnionid(json.optString("unionid"));
|
||||||
result.setErrcode(json.optString("errcode"));
|
result.setErrcode(json.optString("errcode"));
|
||||||
result.setErrmsg(json.optString("errmsg"));
|
result.setErrmsg(json.optString("errmsg"));
|
||||||
@@ -60,52 +59,15 @@ public class WxLoginService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
public static class WxLoginResult {
|
public static class WxLoginResult {
|
||||||
|
|
||||||
private String session_key;
|
@JsonProperty("session_key")
|
||||||
|
private String sessionKey;
|
||||||
|
|
||||||
private String unionid;
|
private String unionid;
|
||||||
private String openid;
|
private String openid;
|
||||||
private String errcode;
|
private String errcode;
|
||||||
private String errmsg;
|
private String errmsg;
|
||||||
|
|
||||||
public String getSession_key() {
|
|
||||||
return session_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSession_key(String session_key) {
|
|
||||||
this.session_key = session_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUnionid() {
|
|
||||||
return unionid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUnionid(String unionid) {
|
|
||||||
this.unionid = unionid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOpenid() {
|
|
||||||
return openid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOpenid(String openid) {
|
|
||||||
this.openid = openid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getErrcode() {
|
|
||||||
return errcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setErrcode(String errcode) {
|
|
||||||
this.errcode = errcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getErrmsg() {
|
|
||||||
return errmsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setErrmsg(String errmsg) {
|
|
||||||
this.errmsg = errmsg;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,16 +18,60 @@
|
|||||||
<result column="create_time" property="createTime"/>
|
<result column="create_time" property="createTime"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<select id="selectLatestByOpenid" resultMap="BaseResultMap">
|
<sql id="Base_Column_List">
|
||||||
SELECT id, name, phone, company, reason,
|
id, name, phone, company, reason,
|
||||||
DATE_FORMAT(visit_date, '%Y-%m-%d') AS visit_date,
|
DATE_FORMAT(visit_date, '%Y-%m-%d') AS visit_date,
|
||||||
DATE_FORMAT(visit_time, '%H:%i') AS visit_time,
|
DATE_FORMAT(visit_time, '%H:%i') AS visit_time,
|
||||||
host_name, area, status, status_text, openid,
|
host_name, area, status, status_text, openid,
|
||||||
DATE_FORMAT(create_time, '%Y-%m-%dT%H:%i:%s.000+00:00') AS create_time
|
DATE_FORMAT(create_time, '%Y-%m-%dT%H:%i:%s.000+00:00') AS create_time
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectLatestByOpenid" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
FROM visit_application
|
FROM visit_application
|
||||||
WHERE openid = #{openid}
|
WHERE openid = #{openid}
|
||||||
ORDER BY create_time DESC
|
ORDER BY create_time DESC
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectListByOpenid" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM visit_application
|
||||||
|
WHERE openid = #{openid}
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectByIdAndOpenid" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM visit_application
|
||||||
|
WHERE id = #{id} AND openid = #{openid}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insert">
|
||||||
|
INSERT INTO visit_application (id, name, phone, company, reason,
|
||||||
|
visit_date, visit_time, host_name, area,
|
||||||
|
status, status_text, openid, create_time)
|
||||||
|
VALUES (#{id}, #{name}, #{phone}, #{company}, #{reason},
|
||||||
|
#{visitDate}, #{visitTime}, #{hostName}, #{area},
|
||||||
|
#{status}, #{statusText}, #{openid}, NOW())
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateStatusToCancelled">
|
||||||
|
UPDATE visit_application
|
||||||
|
SET status = 'cancelled', status_text = '已取消'
|
||||||
|
WHERE id = #{id} AND openid = #{openid} AND status = 'pending'
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<select id="selectById" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM visit_application
|
||||||
|
WHERE id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<update id="updateStatus">
|
||||||
|
UPDATE visit_application
|
||||||
|
SET status = #{status}, status_text = #{statusText}
|
||||||
|
WHERE id = #{id} AND status = 'pending'
|
||||||
|
</update>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
Reference in New Issue
Block a user