提交
This commit is contained in:
@@ -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) */;
|
||||
+4
@@ -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"}
|
||||
+3
@@ -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"}}
|
||||
+122
@@ -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;
|
||||
}
|
||||
}
|
||||
+17
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user