This commit is contained in:
chenglijuan
2026-04-21 11:30:56 +08:00
commit 14e6058725
23 changed files with 721 additions and 0 deletions
@@ -0,0 +1,11 @@
package com.example.mini_program;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MiniProgramApplication {
public static void main(String[] args) {
SpringApplication.run(MiniProgramApplication.class, args);
}
}
@@ -0,0 +1,13 @@
package main.java.com.example.mini_program.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello, Spring Boot!";
}
}
@@ -0,0 +1,15 @@
package main.java.com.example.mini_program.controller.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class Demo3Application {
public static void main(String[] args) {
SpringApplication.run(Demo3Application.class, args);
}
}
@@ -0,0 +1,36 @@
package main.java.com.example.mini_program.controller.demo.mini;
import com.example.demo.mini.entity.VisitApplication;
import com.example.demo.mini.mapper.VisitApplicationMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class AppointmentService {
private static final Logger logger = LoggerFactory.getLogger(AppointmentService.class);
private final VisitApplicationMapper visitApplicationMapper;
public AppointmentService(VisitApplicationMapper visitApplicationMapper) {
this.visitApplicationMapper = visitApplicationMapper;
}
/**
* 根据openid获取最新的一条预约记录
*
* @param openid 微信用户openid
* @return 最新的一条预约记录,没有则返回null
*/
public VisitApplication getLatest(String openid) {
logger.info("查询用户最新预约记录, openid: {}", openid);
VisitApplication result = visitApplicationMapper.selectLatestByOpenid(openid);
if (result != null) {
logger.info("找到预约记录, id: {}", result.getId());
} else {
logger.info("未找到预约记录");
}
return result;
}
}
@@ -0,0 +1,109 @@
package main.java.com.example.mini_program.controller.demo.mini;
import com.example.demo.mini.entity.VisitApplication;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/wx-mini")
public class WxLoginController {
private final WxLoginService wxLoginService;
private final AppointmentService appointmentService;
public WxLoginController(WxLoginService wxLoginService, AppointmentService appointmentService) {
this.wxLoginService = wxLoginService;
this.appointmentService = appointmentService;
}
/**
* 微信小程序登录接口
* 接收wx.login的code,换取openid
*
* @param code 小程序wx.login获取的code
* @return openid等信息
*/
@GetMapping("/login")
public Result<WxLoginResult> login(@RequestParam String code) {
if (code == null || code.trim().isEmpty()) {
return Result.error("code不能为空");
}
WxLoginResult result = wxLoginService.code2Session(code);
if ("0".equals(result.getErrcode())|| "".equals(result.getErrcode())) {
return Result.success(result);
} else {
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;
}
}
}
@@ -0,0 +1,50 @@
package main.java.com.example.mini_program.controller.demo.mini;
public class WxLoginResult {
private String session_key;
private String unionid;
private String openid;
private String errcode;
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;
}
}
@@ -0,0 +1,61 @@
package main.java.com.example.mini_program.controller.demo.mini;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class WxLoginService {
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 final WxMiniAppConfig wxMiniAppConfig;
private final RestTemplate restTemplate;
public WxLoginService(WxMiniAppConfig wxMiniAppConfig) {
this.wxMiniAppConfig = wxMiniAppConfig;
this.restTemplate = new RestTemplate();
}
/**
* 调用微信接口用code换取openid
*
* @param code 小程序调用wx.login获取的code
* @return 登录结果,包含openid等信息
*/
public WxLoginResult code2Session(String code) {
String url = String.format(JSCODE2SESSION_URL,
wxMiniAppConfig.getAppid(),
wxMiniAppConfig.getSecret(),
code);
logger.info("调用微信jscode2session接口,code: {}", code);
try {
// 微信返回text/plain,手动解析JSON字符串
String response = restTemplate.getForObject(url, String.class);
logger.info("微信返回原始结果: {}", response);
JSONObject json = new JSONObject(response);
WxLoginResult result = new WxLoginResult();
result.setOpenid(json.optString("openid"));
result.setSession_key(json.optString("session_key"));
result.setUnionid(json.optString("unionid"));
result.setErrcode(json.optString("errcode"));
result.setErrmsg(json.optString("errmsg"));
logger.info("解析后结果: openid={}, unionid={}, errcode={}",
result.getOpenid(), result.getUnionid(), result.getErrcode());
return result;
} catch (Exception e) {
logger.error("调用微信接口失败", e);
WxLoginResult errorResult = new WxLoginResult();
errorResult.setErrcode("-1");
errorResult.setErrmsg("系统错误: " + e.getMessage());
return errorResult;
}
}
}
@@ -0,0 +1,28 @@
package main.java.com.example.mini_program.controller.demo.mini;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxMiniAppConfig {
private String appid;
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,54 @@
-- --------------------------------------------------------
-- 主机: txy.588580.xyz
-- 服务器版本: 5.7.44 - MySQL Community Server (GPL)
-- 服务器操作系统: Linux
-- HeidiSQL 版本: 12.17.0.7270
-- --------------------------------------------------------
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-- 导出 mini 的数据库结构
CREATE DATABASE IF NOT EXISTS `mini` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `mini`;
-- 导出 表 mini.visit_application 结构
CREATE TABLE IF NOT EXISTS `visit_application` (
`id` varchar(32) NOT NULL COMMENT '主键ID',
`name` varchar(50) NOT NULL COMMENT '访客姓名',
`phone` varchar(20) NOT NULL COMMENT '联系电话',
`company` varchar(100) DEFAULT NULL COMMENT '公司名称',
`reason` varchar(500) DEFAULT NULL COMMENT '来访原因',
`visit_date` date NOT NULL COMMENT '来访日期',
`visit_time` time DEFAULT '00:00:00' COMMENT '来访时间',
`host_name` varchar(50) DEFAULT NULL COMMENT '接待人姓名',
`area` varchar(50) DEFAULT NULL COMMENT '访问区域',
`status` varchar(20) NOT NULL DEFAULT 'pending' COMMENT '状态',
`status_text` varchar(50) DEFAULT NULL COMMENT '状态文本描述',
`openid` varchar(64) DEFAULT NULL COMMENT '微信用户openid',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_status` (`status`),
KEY `idx_visit_date` (`visit_date`),
KEY `idx_openid` (`openid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='访问申请记录表';
-- 正在导出表 mini.visit_application 的数据:~4 rows (大约)
INSERT INTO `visit_application` (`id`, `name`, `phone`, `company`, `reason`, `visit_date`, `visit_time`, `host_name`, `area`, `status`, `status_text`, `openid`, `create_time`) VALUES
('16a235b169e3405200194dd91bc3e36f', '吴松', '12311111111', 'hj', 'jkk', '2026-04-18', '00:00:00', 'clj', 'B区-办公楼', 'cancelled', '已取消', 'ogzdF3d3Z494n28mxsUUHvASiePE', '2026-04-18 08:26:58'),
('5f19df4769e3444d001856492c09fb78', 'k', '12224446798', 'j', '你说的这个是同步svn上的所有文件,还是某一个文件夹下的文件q', '2026-04-18', '00:00:00', 'lj', 'A区-生产车间', 'pending', '待审核', 'ogzdF3d3Z494n28mxsUUHvASiePE', '2026-04-18 08:43:57'),
('6cd8d0ff69e5f0f9004d447951241305', '陈良', '15056476763', '安影', '测试', '2026-04-20', '10:00:00', '虞欢溢', 'A区-生产车间', 'pending', '待审核', 'ogzdF3a-l23Vfpq14b7QEp1VEukg', '2026-04-20 09:25:13'),
('8b925adc69e5d944004a593558e0a944', '程利娟', '19805853215', '哈哈科技有限公司', '参观', '2026-04-21', '13:00:00', '生产部长', 'A区-生产车间', 'pending', '待审核', 'ogzdF3Vv42nydiUnY6lEW0ufK4Q0', '2026-04-20 07:44:04');
/*!40103 SET TIME_ZONE=IFNULL(@OLD_TIME_ZONE, 'system') */;
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40111 SET SQL_NOTES=IFNULL(@OLD_SQL_NOTES, 1) */;
@@ -0,0 +1,4 @@
{"_id":"16a235b169e3405200194dd91bc3e36f","name":"吴松","phone":"12311111111","company":"hj","reason":"jkk","time":"00:00","hostName":"clj","area":"B区-办公楼","statusText":"已取消","date":"2026-04-18","status":"cancelled","createTime":{"$date":"2026-04-18T08:26:58.102Z"},"_openid":"ogzdF3d3Z494n28mxsUUHvASiePE"}
{"_id":"5f19df4769e3444d001856492c09fb78","statusText":"待审核","createTime":{"$date":"2026-04-18T08:43:57.985Z"},"_openid":"ogzdF3d3Z494n28mxsUUHvASiePE","phone":"12224446798","company":"j","reason":"你说的这个是同步svn上的所有文件,还是某一个文件夹下的文件q","date":"2026-04-18","time":"00:00","hostName":"lj","status":"pending","name":"k","area":"A区-生产车间"}
{"_id":"8b925adc69e5d944004a593558e0a944","_openid":"ogzdF3Vv42nydiUnY6lEW0ufK4Q0","name":"程利娟","company":"哈哈科技有限公司","reason":"参观","date":"2026-04-21","hostName":"生产部长","area":"A区-生产车间","status":"pending","createTime":{"$date":"2026-04-20T07:44:04.124Z"},"phone":"19805853215","time":"13:00","statusText":"待审核"}
{"_id":"6cd8d0ff69e5f0f9004d447951241305","name":"陈良","phone":"15056476763","reason":"测试","hostName":"虞欢溢","statusText":"待审核","createTime":{"$date":"2026-04-20T09:25:13.364Z"},"_openid":"ogzdF3a-l23Vfpq14b7QEp1VEukg","company":"安影","date":"2026-04-20","time":"10:00","area":"A区-生产车间","status":"pending"}
@@ -0,0 +1,3 @@
{"_id":"775c8c1769e34030001852fa5df8d835","_openid":"ogzdF3d3Z494n28mxsUUHvASiePE","avatarUrl":"wxfile://tmp_087ba7d96bc1da49c25cf77a6c2b6a90f03fffddcc59aecf.png","nickName":"i","createTime":{"$date":"2026-04-18T08:26:24.337Z"},"lastLoginTime":{"$date":"2026-04-20T09:47:25.222Z"}}
{"_id":"5065eed869e341aa0019a9352a21b8e4","_openid":"ogzdF3Vv42nydiUnY6lEW0ufK4Q0","avatarUrl":"http://tmp/q2RwR6L5kT1v2b4bd91956654d901dfa7b6cd59aa006.jpeg","nickName":"23","createTime":{"$date":"2026-04-18T08:32:42.356Z"},"lastLoginTime":{"$date":"2026-04-20T07:42:43.764Z"}}
{"_id":"775c8c1769e5f0cd00499e73707f0bb9","_openid":"ogzdF3a-l23Vfpq14b7QEp1VEukg","createTime":{"$date":"2026-04-20T09:24:29.069Z"},"lastLoginTime":{"$date":"2026-04-20T09:24:29.069Z"}}
@@ -0,0 +1,122 @@
package main.java.com.example.mini_program.controller.demo.mini.entity;
public class VisitApplication {
private String id;
private String name;
private String phone;
private String company;
private String reason;
private String visitDate;
private String visitTime;
private String hostName;
private String area;
private String status;
private String statusText;
private String openid;
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;
}
}
@@ -0,0 +1,17 @@
package main.java.com.example.mini_program.controller.demo.mini.mapper;
import com.example.demo.mini.entity.VisitApplication;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface VisitApplicationMapper {
/**
* 根据openid查询最新的一条预约记录
*
* @param openid 微信用户openid
* @return 最新的一条记录,没有则返回null
*/
VisitApplication selectLatestByOpenid(@Param("openid") String openid);
}