更新子模块

This commit is contained in:
MMS 2025-06-02 02:25:05 +08:00
parent c8a23f841a
commit 531d48a74e
10 changed files with 92 additions and 49 deletions

View File

@ -1,22 +1,21 @@
package com.sxpcwlkj.docApi.controller; package com.sxpcwlkj.docApi.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaIgnore; import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.github.binarywang.wxpay.service.WxPayService;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType; import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.WxPayKit; import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.sxpcwlkj.authority.LoginObject; import com.sxpcwlkj.authority.LoginObject;
import com.sxpcwlkj.common.code.entity.WxCodeBo; import com.sxpcwlkj.common.code.entity.WxCodeBo;
import com.sxpcwlkj.common.enums.DeviceEnum;
import com.sxpcwlkj.common.enums.WxCodeStatusEnum; import com.sxpcwlkj.common.enums.WxCodeStatusEnum;
import com.sxpcwlkj.common.utils.*; import com.sxpcwlkj.common.utils.*;
import com.sxpcwlkj.docApi.entity.DocOrder; import com.sxpcwlkj.docApi.entity.DocOrder;
import com.sxpcwlkj.docApi.entity.DocProduct; import com.sxpcwlkj.docApi.entity.DocProduct;
import com.sxpcwlkj.docApi.entity.DocUser; import com.sxpcwlkj.docApi.entity.DocUser;
import com.sxpcwlkj.docApi.entity.bo.DocOrderBo;
import com.sxpcwlkj.docApi.entity.bo.MyRequest; import com.sxpcwlkj.docApi.entity.bo.MyRequest;
import com.sxpcwlkj.docApi.entity.vo.DocOrderVo; import com.sxpcwlkj.docApi.entity.vo.DocOrderVo;
import com.sxpcwlkj.docApi.entity.vo.DocUserVo; import com.sxpcwlkj.docApi.entity.vo.DocUserVo;
@ -25,10 +24,9 @@ import com.sxpcwlkj.docApi.mapper.DocOrderMapper;
import com.sxpcwlkj.docApi.mapper.DocProductMapper; import com.sxpcwlkj.docApi.mapper.DocProductMapper;
import com.sxpcwlkj.docApi.service.DocOrderService; import com.sxpcwlkj.docApi.service.DocOrderService;
import com.sxpcwlkj.docApi.service.DocUserService; import com.sxpcwlkj.docApi.service.DocUserService;
import com.sxpcwlkj.docApi.utils.DocBaseTool;
import com.sxpcwlkj.docApi.utils.DocR; import com.sxpcwlkj.docApi.utils.DocR;
import com.sxpcwlkj.framework.utils.SignUtil;
import com.sxpcwlkj.redis.RedisUtil; import com.sxpcwlkj.redis.RedisUtil;
import com.sxpcwlkj.redis.constant.RedisConstant;
import com.sxpcwlkj.wx.service.WxCodeService; import com.sxpcwlkj.wx.service.WxCodeService;
import com.sxpcwlkj.wx.service.WxOrderService; import com.sxpcwlkj.wx.service.WxOrderService;
import com.sxpcwlkj.wx.service.WxService; import com.sxpcwlkj.wx.service.WxService;
@ -39,6 +37,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.time.Duration;
import java.util.*; import java.util.*;
/** /**
@ -48,8 +47,8 @@ import java.util.*;
@Validated @Validated
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@RequestMapping("/vpapi/meb") @RequestMapping("/doc-api/meb/v1")
public class DocUserController extends DocBaseTool { public class DocUserController{
private final DocUserService docUserService; private final DocUserService docUserService;
private final DocOrderMapper docOrderMapper; private final DocOrderMapper docOrderMapper;
@ -68,10 +67,10 @@ public class DocUserController extends DocBaseTool {
*/ */
@SaIgnore @SaIgnore
@PostMapping("/userinfo") @PostMapping("/userinfo")
public DocR<DocUserVo> userinfo(HttpServletRequest request, HttpServletResponse response){ public R<DocUserVo> userinfo(HttpServletRequest request, HttpServletResponse response){
DocUserVo docUserVo = docUserService.selectVoById(getUserId(request)); DocUserVo docUserVo = LoginObject.getLoginObject(DocUserVo.class);
if(docUserVo==null){ if(docUserVo==null){
return DocR.error("99910","会话过期"); return R.fail("会话过期");
} }
docOrderMapper.delete(new LambdaQueryWrapper<DocOrder>().eq(DocOrder::getUid,docUserVo.getUid()) docOrderMapper.delete(new LambdaQueryWrapper<DocOrder>().eq(DocOrder::getUid,docUserVo.getUid())
.eq(DocOrder::getStatus,0) .eq(DocOrder::getStatus,0)
@ -103,8 +102,8 @@ public class DocUserController extends DocBaseTool {
docUserVo.setVip_date(DateUtil.getStrToDate("2025-01-01 00:00:00")); docUserVo.setVip_date(DateUtil.getStrToDate("2025-01-01 00:00:00"));
docUserVo.setType("usr"); docUserVo.setType("usr");
} }
CookieUtil.setCookie(response,"mss",getToken(docUserVo.getUid()),1000*60*60*24*7);
return DocR.ok(docUserVo); return R.success(docUserVo);
} }
@ -114,7 +113,7 @@ public class DocUserController extends DocBaseTool {
*/ */
@SaIgnore @SaIgnore
@PostMapping("/oauth-authorize") @PostMapping("/oauth-authorize")
public DocR<Map<String,String>> oauthAuthorize(){ public R<Map<String,String>> oauthAuthorize(){
Map<String,String> data= new HashMap<>(); Map<String,String> data= new HashMap<>();
String state=RandomUtil.getRandomUUID(); String state=RandomUtil.getRandomUUID();
String codeUrl= wxCodeService.getCode(new WxCodeBo(state) String codeUrl= wxCodeService.getCode(new WxCodeBo(state)
@ -123,33 +122,36 @@ public class DocUserController extends DocBaseTool {
.paramData(state)); .paramData(state));
data.put("url",codeUrl); data.put("url",codeUrl);
data.put("state",state); data.put("state",state);
return DocR.ok(data); return R.success(data);
} }
/** /**
* 登录二维码轮询 * 登录二维码轮询
* @param request 请求 * @param bo 请求
* @return 登录状态 * @return 登录状态
*/ */
@SaIgnore @SaIgnore
@PostMapping("/oauth-polling") @PostMapping("/oauth-polling")
public DocR<Map<String,String>> oauthPolling(@RequestBody MyRequest bo){ public R<Map<String,String>> oauthPolling(@RequestBody MyRequest bo,HttpServletRequest request, HttpServletResponse response){
String state = bo.getState(); String state = bo.getState();
Map<String,String> data= new HashMap<>(); Map<String,String> data= new HashMap<>();
data.put("status","0"); data.put("status","0");
if(state==null){ if(state==null){
return DocR.error("50001","state不能为空"); return R.fail("state不能为空");
} }
//登录二维码 //登录二维码
WxCodeBo wxCodeBo= wxCodeService.getCodeState(new WxCodeBo(state).typeDocLogin()); WxCodeBo wxCodeBo= wxCodeService.getCodeState(new WxCodeBo(state).typeDocLogin());
if(Objects.equals(wxCodeBo.getState(), WxCodeStatusEnum.SUCCEED.getValue())){ if(Objects.equals(wxCodeBo.getState(), WxCodeStatusEnum.SUCCEED.getValue())){
log.info(wxCodeBo.getOpenId()); log.info(wxCodeBo.getOpenId());
DocUser docUser= docUserService.bindingOpenId(wxCodeBo.getOpenId()); DocUser vo= docUserService.bindingOpenId(wxCodeBo.getOpenId());
data.put("status","1"); data.put("status","1");
data.put("token",getToken(docUser.getUid())); String token = LoginObject.loginToken(vo.getUid(), DeviceEnum.PC.getType(), 10000000L, "id", vo.getUid());
RedisUtil.setCacheObject(RedisConstant.PC_KEY+vo.getUid(),vo, Duration.ofSeconds(10000000L));
data.put("token",token);
CookieUtil.setCookie(response,"token",token,1000*60*60*24*7);
} }
return DocR.ok(data); return R.success(data);
} }
@ -158,10 +160,10 @@ public class DocUserController extends DocBaseTool {
* @param request 请求 * @param request 请求
* @return 商品列表 * @return 商品列表
*/ */
@SaIgnore @SaCheckLogin
@PostMapping("/product-list") @PostMapping("/product-list")
public DocR<Map<String,Object>> productList(HttpServletRequest request){ public R<Map<String,Object>> productList(HttpServletRequest request){
String uid= getUserId(request); String uid= LoginObject.getLoginId();
List<DocProduct> docProducts= docProductMapper.selectList(new LambdaQueryWrapper<DocProduct>().eq(DocProduct::getStatus,1).orderByAsc(DocProduct::getSort)); List<DocProduct> docProducts= docProductMapper.selectList(new LambdaQueryWrapper<DocProduct>().eq(DocProduct::getStatus,1).orderByAsc(DocProduct::getSort));
Map<String,Object> endData= new HashMap<>(); Map<String,Object> endData= new HashMap<>();
List<Map<String,String>> data= new ArrayList<>(); List<Map<String,String>> data= new ArrayList<>();
@ -175,7 +177,7 @@ public class DocUserController extends DocBaseTool {
DocUserVo docUserVo= docUserService.selectVoById(uid); DocUserVo docUserVo= docUserService.selectVoById(uid);
if(docUserVo==null){ if(docUserVo==null){
return DocR.error("99910","会话过期"); return R.fail("会话过期");
} }
Map<String,Object> orderInfo= new HashMap<>(); Map<String,Object> orderInfo= new HashMap<>();
orderInfo.put("openId",docUserVo.getOpenId()); orderInfo.put("openId",docUserVo.getOpenId());
@ -197,7 +199,7 @@ public class DocUserController extends DocBaseTool {
} }
endData.put("items",data); endData.put("items",data);
return DocR.ok(endData); return R.success(endData);
} }
@ -206,20 +208,39 @@ public class DocUserController extends DocBaseTool {
* @param request 请求 * @param request 请求
* @return 登录状态 * @return 登录状态
*/ */
@SaIgnore @SaCheckLogin
@PostMapping("/product-buy-qry") @PostMapping("/product-buy-qry")
public DocR<Map<String,String>> productBuyQry(@RequestBody MyRequest bo,HttpServletRequest request){ public R<Map<String,String>> productBuyQry(@RequestBody MyRequest bo,HttpServletRequest request){
String prodId = bo.getProd_id(); String prodId = bo.getProd_id();
Map<String,String> data= new HashMap<>(); Map<String,String> data= new HashMap<>();
data.put("status","0"); data.put("status","0");
if(prodId==null){ if(prodId==null){
return DocR.error("50001","prodId不能为空"); return R.fail("prodId不能为空");
} }
data.put("status",docOrderService.selectPayState(prodId,getUserId(request))); data.put("status",docOrderService.selectPayState(prodId,LoginObject.getLoginId()));
return DocR.ok(data); return R.success(data);
} }
/**
* 退出登录
*/
@SaCheckLogin
@PostMapping("/logout")
public R<String> logout(HttpServletResponse response){
StpUtil.logout();
CookieUtil.setCookie(response,"token","",0);
return R.success("退出成功!");
}
/**
* 支付回调-官方微信
* @param req 请求
* @param resp 响应
* @param body 请求体
* @return 响应
*/
@SaIgnore @SaIgnore
@PostMapping("/notify") @PostMapping("/notify")
public String notify(HttpServletRequest req, HttpServletResponse resp, @RequestBody String body){ public String notify(HttpServletRequest req, HttpServletResponse resp, @RequestBody String body){
@ -253,6 +274,7 @@ public class DocUserController extends DocBaseTool {
/** /**
* 微信支付WxPay
* 异步通知 * 异步通知
*/ */
@RequestMapping(value = "/payNotify", method = {RequestMethod.POST, RequestMethod.GET}) @RequestMapping(value = "/payNotify", method = {RequestMethod.POST, RequestMethod.GET})

View File

@ -4,7 +4,6 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWT; import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTHeader; import cn.hutool.jwt.JWTHeader;
import cn.hutool.jwt.JWTUtil; import cn.hutool.jwt.JWTUtil;
import com.sxpcwlkj.common.exception.MmsException;
import jakarta.servlet.http.Cookie; import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -15,13 +14,16 @@ import java.util.Map;
import static cn.hutool.core.lang.Singleton.put; import static cn.hutool.core.lang.Singleton.put;
/**
* @author shanpengnian
*/
@Slf4j @Slf4j
public class DocBaseTool { public class JwtUtil {
private final String KEY= "4548912314JKJ85HT=="; private final String KEY= "4548912314JKJ85HT==";
public String getUserId(HttpServletRequest request){ public String getId(HttpServletRequest request){
String cookie = getCookieValue(request,"mss"); String cookie = getCookieValue(request,"token");
if(cookie!=null){ if(cookie!=null){
if (StrUtil.isBlank(cookie) || cookie.split("\\.").length != 3) { if (StrUtil.isBlank(cookie) || cookie.split("\\.").length != 3) {
log.error("无效的JWT格式: " + cookie); log.error("无效的JWT格式: " + cookie);
@ -31,18 +33,18 @@ public class DocBaseTool {
if(verify){ if(verify){
final JWT jwt = JWTUtil.parseToken(cookie); final JWT jwt = JWTUtil.parseToken(cookie);
jwt.getHeader(JWTHeader.TYPE); jwt.getHeader(JWTHeader.TYPE);
return jwt.getPayload("uid").toString(); return jwt.getPayload("id").toString();
} }
} }
return "-1"; return "-1";
} }
public String getToken(String uid){ public String createToken(String id){
Map<String, Object> map = new HashMap<String, Object>() { Map<String, Object> map = new HashMap<String, Object>() {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
{ {
put("uid", uid); put("id", id);
put("expire_time", System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7); put("expire_time", System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7);
} }
}; };

View File

@ -83,13 +83,13 @@ spring:
--- # Sa-Token配置 --- # Sa-Token配置
sa-token: sa-token:
# token名称 (同时也是cookie名称) # token名称 (同时也是cookie名称)
token-name: Authorization token-name: docToken
# token 有效期(单位:秒) 默认30天-1 代表永久有效 # token 有效期(单位:秒) 默认30天-1 代表永久有效
timeout: 86400 timeout: 86400
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
active-timeout: 1800 active-timeout: 1800
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
is-concurrent: true is-concurrent: false
# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token
is-share: false is-share: false
# 是否尝试从header里读取token # 是否尝试从header里读取token
@ -97,7 +97,7 @@ sa-token:
# 是否在header读取不到token时继续从请求题参数里继续尝试读取 # 是否在header读取不到token时继续从请求题参数里继续尝试读取
is-read-body: true is-read-body: true
# 是否尝试从cookie里读取token # 是否尝试从cookie里读取token
is-read-cookie: false is-read-cookie: true
# token前缀 # token前缀
# token-prefix: "Token_" # token-prefix: "Token_"
# jwt秘钥 # jwt秘钥

View File

@ -9,6 +9,7 @@ import cn.hutool.core.lang.Console;
import com.sxpcwlkj.common.enums.DeviceEnum; import com.sxpcwlkj.common.enums.DeviceEnum;
import com.sxpcwlkj.common.enums.ErrorCodeEnum; import com.sxpcwlkj.common.enums.ErrorCodeEnum;
import com.sxpcwlkj.common.exception.LoginException; import com.sxpcwlkj.common.exception.LoginException;
import com.sxpcwlkj.common.exception.MmsException;
import com.sxpcwlkj.common.utils.MapstructUtil; import com.sxpcwlkj.common.utils.MapstructUtil;
import com.sxpcwlkj.common.utils.StringUtil; import com.sxpcwlkj.common.utils.StringUtil;
import com.sxpcwlkj.redis.RedisUtil; import com.sxpcwlkj.redis.RedisUtil;
@ -94,6 +95,7 @@ public class LoginObject<T> {
* @return 当前登录用户 * @return 当前登录用户
*/ */
public static <T> T getLoginObject(Class<T> clazz) { public static <T> T getLoginObject(Class<T> clazz) {
if (isLogin()) { if (isLogin()) {
try { try {
if (getLoginId() != null) { if (getLoginId() != null) {
@ -105,6 +107,9 @@ public class LoginObject<T> {
if (DeviceEnum.ADMIN.getType().equals(device)){ if (DeviceEnum.ADMIN.getType().equals(device)){
object = RedisUtil.getCacheObject(RedisConstant.ADMIN_KEY + StpUtil.getLoginIdAsLong()); object = RedisUtil.getCacheObject(RedisConstant.ADMIN_KEY + StpUtil.getLoginIdAsLong());
} }
if (DeviceEnum.PC.getType().equals(device)){
object = RedisUtil.getCacheObject(RedisConstant.PC_KEY + StpUtil.getLoginIdAsLong());
}
return MapstructUtil.convert(object, clazz); return MapstructUtil.convert(object, clazz);
} }
@ -114,7 +119,8 @@ public class LoginObject<T> {
} }
//请先登录 //请先登录
throw new NotLoginException(ErrorCodeEnum.USER_NOT_LOGIN.getValue(), DeviceEnum.MOBILE.getType(), "0"); throw new MmsException(ErrorCodeEnum.USER_NOT_LOGIN.getValue(),ErrorCodeEnum.USER_NOT_LOGIN.getKey());
// throw new NotLoginException(ErrorCodeEnum.USER_NOT_LOGIN.getValue(), DeviceEnum.MOBILE.getType(), "0");
} }
/** /**
@ -122,12 +128,18 @@ public class LoginObject<T> {
* *
* @param id 标识ID * @param id 标识ID
* @param device 登录设备 * @param device 登录设备
* @param timeout 过期时间 * @param timeout 过期时间/
* @param jwtKey JWL key * @param jwtKey JWL key
* @param jwtValue JWT value * @param jwtValue JWT value
* @return 登录token * @return 登录token
*/ */
public static String loginToken(String id, String device, Long timeout, String jwtKey, String jwtValue) { public static String loginToken(String id, String device, Long timeout, String jwtKey, String jwtValue) {
Console.log("当前会话TokenName", StpUtil.getTokenName());
if(StpUtil.isLogin()){
// 获取当前会话的token值
Console.log("当前会话已登录,无需重复登录", StpUtil.getTokenName());
return StpUtil.getTokenValue();
}
//根据用户id进行登录 //根据用户id进行登录
SaLoginModel saLoginModel = new SaLoginModel(); SaLoginModel saLoginModel = new SaLoginModel();
if (StringUtil.isNotEmpty(device)) { if (StringUtil.isNotEmpty(device)) {

View File

@ -20,7 +20,11 @@ public enum DeviceEnum {
/** /**
* 移动端 * 移动端
*/ */
MOBILE("MOBILE"); MOBILE("MOBILE"),
/**
* PC端
*/
PC("PC");
private final String type; private final String type;

View File

@ -5,6 +5,7 @@ import lombok.Getter;
/** /**
* 接口返回错误码枚举 * 接口返回错误码枚举
* @author shanpengnian
*/ */
public enum ErrorCodeEnum implements IEnum { public enum ErrorCodeEnum implements IEnum {

View File

@ -3,6 +3,7 @@ package com.sxpcwlkj.common.exception;
import com.sxpcwlkj.common.enums.ErrorCode; import com.sxpcwlkj.common.enums.ErrorCode;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.springframework.http.HttpStatus;
import java.io.Serial; import java.io.Serial;
@ -37,6 +38,7 @@ public class MmsException extends RuntimeException {
public MmsException(String message) { public MmsException(String message) {
this.message = message; this.message = message;
this.code = HttpStatus.INTERNAL_SERVER_ERROR.value();
} }
public MmsException(String message, Integer code) { public MmsException(String message, Integer code) {

View File

@ -1,10 +1,13 @@
package com.sxpcwlkj.common.exception; package com.sxpcwlkj.common.exception;
import com.sxpcwlkj.common.enums.ErrorCodeEnum; import com.sxpcwlkj.common.enums.ErrorCodeEnum;
import lombok.Setter;
/** /**
* 用户登陆信息过期异常 * 用户登陆信息过期异常
* @author xijue
*/ */
@Setter
public class TokenExpireException extends RuntimeException { public class TokenExpireException extends RuntimeException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -27,9 +30,5 @@ public class TokenExpireException extends RuntimeException {
return message; return message;
} }
public void setMessage(String message) {
this.message = message;
}
} }

View File

@ -258,7 +258,7 @@ public class GlobalException {
HttpServletRequest request) { HttpServletRequest request) {
String requestUrl = request.getRequestURI(); String requestUrl = request.getRequestURI();
log.error("请求地址'{}','{}'.", requestUrl, e.getMessage()); log.error("请求地址'{}','{}'.", requestUrl, e.getMessage());
return R.fail(HttpStatus.TEMPORARY_REDIRECT.value(), e.getMessage()); return R.fail(e.getCode(), e.getMessage());
} }

View File

@ -10,6 +10,7 @@ public class RedisConstant {
// user换成前缀key // user换成前缀key
public static final String ADMIN_KEY="admin:"; public static final String ADMIN_KEY="admin:";
public static final String MOBILE_KEY="mobile:member:"; public static final String MOBILE_KEY="mobile:member:";
public static final String PC_KEY="pc:member:";
public static final String ENCRYPTION_SERVER_PORT="encryption:server:"; public static final String ENCRYPTION_SERVER_PORT="encryption:server:";
public static final String ENCRYPTION_APP_ID="encryption:"; public static final String ENCRYPTION_APP_ID="encryption:";
public static final String COOKIE_APP_ID="cookie:"; public static final String COOKIE_APP_ID="cookie:";