Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e518d5d0a0 | ||
|
|
ffcea3104e | ||
|
|
af707e1bb4 |
+6
-7
@@ -1,6 +1,7 @@
|
||||
package cn.novalon.gym.manage.auth.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@@ -8,7 +9,7 @@ import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 手机号一键登录请求DTO
|
||||
* uniapp官方一键登录流程:前端通过云函数获取access_token和openid传给后端换取手机号
|
||||
* uniapp官方一键登录流程:前端通过云函数获取手机号,直接传给后端
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@@ -16,13 +17,11 @@ import lombok.NoArgsConstructor;
|
||||
@AllArgsConstructor
|
||||
public class PhoneLoginDto {
|
||||
|
||||
@NotBlank(message = "access_token不能为空")
|
||||
private String accessToken;
|
||||
|
||||
@NotBlank(message = "openid不能为空")
|
||||
private String openid;
|
||||
@NotBlank(message = "手机号不能为空")
|
||||
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
|
||||
private String phone;
|
||||
|
||||
private String nickname;
|
||||
|
||||
private String avatar;
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -2,7 +2,6 @@ package cn.novalon.gym.manage.auth.handler;
|
||||
|
||||
import cn.novalon.gym.manage.auth.dto.PhoneCodeLoginDto;
|
||||
import cn.novalon.gym.manage.auth.dto.PhoneLoginDto;
|
||||
import cn.novalon.gym.manage.auth.dto.SendCodeRequest;
|
||||
import cn.novalon.gym.manage.auth.service.PhoneAuthService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -39,8 +38,8 @@ public class PhoneAuthHandler {
|
||||
public Mono<ServerResponse> sendSmsCode(ServerRequest request) {
|
||||
log.info("收到发送短信验证码请求");
|
||||
|
||||
return request.bodyToMono(SendCodeRequest.class)
|
||||
.flatMap(req -> phoneAuthService.sendSmsCode(req.getPhone()))
|
||||
return request.bodyToMono(PhoneLoginDto.class)
|
||||
.flatMap(dto -> phoneAuthService.sendSmsCode(dto.getPhone()))
|
||||
.flatMap(success -> ServerResponse.ok()
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(Map.of("success", success, "message", success ? "验证码发送成功" : "验证码发送失败")));
|
||||
|
||||
+13
-65
@@ -1,6 +1,5 @@
|
||||
package cn.novalon.gym.manage.auth.service.impl;
|
||||
|
||||
import cn.novalon.gym.manage.auth.config.SmsProperties;
|
||||
import cn.novalon.gym.manage.auth.dto.PhoneCodeLoginDto;
|
||||
import cn.novalon.gym.manage.auth.dto.PhoneLoginDto;
|
||||
import cn.novalon.gym.manage.auth.service.PhoneAuthService;
|
||||
@@ -16,13 +15,6 @@ import cn.novalon.gym.manage.member.util.AesUtil;
|
||||
import cn.novalon.gym.manage.member.util.EsSyncUtils;
|
||||
import cn.novalon.gym.manage.member.util.MemberNoGenerator;
|
||||
import cn.novalon.gym.manage.sys.security.JwtTokenProvider;
|
||||
import com.aliyuncs.DefaultAcsClient;
|
||||
import com.aliyuncs.IAcsClient;
|
||||
import com.aliyuncs.dypnsapi.model.v20170525.GetMobileRequest;
|
||||
import com.aliyuncs.dypnsapi.model.v20170525.GetMobileResponse;
|
||||
import com.aliyuncs.exceptions.ClientException;
|
||||
import com.aliyuncs.exceptions.ServerException;
|
||||
import com.aliyuncs.profile.DefaultProfile;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -43,7 +35,6 @@ public class PhoneAuthServiceImpl implements PhoneAuthService {
|
||||
private final EsSyncUtils esSyncUtils;
|
||||
private final JwtTokenProvider jwtTokenProvider;
|
||||
private final SmsService smsService;
|
||||
private final SmsProperties smsProperties;
|
||||
|
||||
private EsSyncUtils.EntitySyncer<Member, MemberES, String> memberSyncer;
|
||||
|
||||
@@ -54,63 +45,19 @@ public class PhoneAuthServiceImpl implements PhoneAuthService {
|
||||
|
||||
@Override
|
||||
public Mono<PhoneLoginVO> oneClickLogin(PhoneLoginDto request) {
|
||||
log.info("手机号一键登录请求, accessToken: {}, openid: {}", request.getAccessToken(), request.getOpenid());
|
||||
log.info("手机号一键登录, phone: {}", request.getPhone());
|
||||
|
||||
return Mono.fromCallable(() -> getPhoneByToken(request.getAccessToken(), request.getOpenid()))
|
||||
.flatMap(phone -> {
|
||||
log.info("通过access_token获取手机号成功: {}", maskPhone(phone));
|
||||
String encryptedPhone = encryptPhone(phone);
|
||||
String encryptedPhone = encryptPhone(request.getPhone());
|
||||
|
||||
return memberRepository.findByPhone(encryptedPhone)
|
||||
.flatMap(existingMember -> {
|
||||
log.info("手机号已注册,直接登录, memberId: {}", existingMember.getId());
|
||||
return doLogin(existingMember, false, request);
|
||||
})
|
||||
.switchIfEmpty(Mono.defer(() -> {
|
||||
log.info("手机号未注册,创建新会员");
|
||||
return createNewMemberAndLogin(request, encryptedPhone);
|
||||
}));
|
||||
return memberRepository.findByPhone(encryptedPhone)
|
||||
.flatMap(existingMember -> {
|
||||
log.info("手机号已注册,直接登录, memberId: {}", existingMember.getId());
|
||||
return doLogin(existingMember, false, request);
|
||||
})
|
||||
.onErrorResume(e -> {
|
||||
log.error("一键登录失败", e);
|
||||
return Mono.error(new SystemException(ErrorCode.AUTH_PHONE_ERROR, "手机号获取失败: " + e.getMessage()));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过access_token和openid获取手机号
|
||||
* 使用阿里云DYPNS API
|
||||
*/
|
||||
private String getPhoneByToken(String accessToken, String openid) throws Exception {
|
||||
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", smsProperties.getAccessKeyId(), smsProperties.getAccessKeySecret());
|
||||
IAcsClient client = new DefaultAcsClient(profile);
|
||||
GetMobileRequest request = new GetMobileRequest();
|
||||
request.setAccessToken(accessToken);
|
||||
|
||||
try {
|
||||
GetMobileResponse response = client.getAcsResponse(request);
|
||||
if ("OK".equals(response.getCode())) {
|
||||
return response.getGetMobileResultDTO().getMobile();
|
||||
}
|
||||
log.warn("DYPNS API返回错误: code={}, message={}", response.getCode(), response.getMessage());
|
||||
throw new SystemException(ErrorCode.AUTH_PHONE_ERROR, "手机号获取失败: " + response.getMessage());
|
||||
} catch (ServerException e) {
|
||||
log.error("阿里云DYPNS API服务端异常", e);
|
||||
throw new SystemException(ErrorCode.AUTH_PHONE_ERROR, "手机号获取失败");
|
||||
} catch (ClientException e) {
|
||||
log.error("阿里云DYPNS API客户端异常", e);
|
||||
throw new SystemException(ErrorCode.AUTH_PHONE_ERROR, "手机号获取失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号脱敏显示
|
||||
*/
|
||||
private String maskPhone(String phone) {
|
||||
if (phone == null || phone.length() < 11) {
|
||||
return phone;
|
||||
}
|
||||
return phone.substring(0, 3) + "****" + phone.substring(7);
|
||||
.switchIfEmpty(Mono.defer(() -> {
|
||||
log.info("手机号未注册,创建新会员");
|
||||
return createNewMemberAndLogin(request, encryptedPhone);
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -140,6 +87,7 @@ public class PhoneAuthServiceImpl implements PhoneAuthService {
|
||||
.switchIfEmpty(Mono.defer(() -> {
|
||||
log.info("手机号未注册,创建新会员");
|
||||
PhoneLoginDto registerRequest = new PhoneLoginDto();
|
||||
registerRequest.setPhone(request.getPhone());
|
||||
return createNewMemberAndLogin(registerRequest, encryptedPhone);
|
||||
}));
|
||||
});
|
||||
@@ -205,7 +153,7 @@ public class PhoneAuthServiceImpl implements PhoneAuthService {
|
||||
vo.setNeedCompleteInfo(needCompleteInfo);
|
||||
vo.setNickname(member.getNickname());
|
||||
vo.setAvatar(member.getAvatar());
|
||||
vo.setPhone(member.getPhone() != null ? decryptPhone(member.getPhone()) : null);
|
||||
vo.setPhone(decryptPhone(member.getPhone()));
|
||||
return vo;
|
||||
}
|
||||
|
||||
@@ -226,4 +174,4 @@ public class PhoneAuthServiceImpl implements PhoneAuthService {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
package cn.novalon.gym.manage.checkIn.config;
|
||||
|
||||
import cn.novalon.gym.manage.checkIn.websocket.MyWebSocketHandler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.reactive.HandlerMapping;
|
||||
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.reactive.socket.WebSocketHandler;
|
||||
import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Configuration
|
||||
public class WebSocketConfig {
|
||||
|
||||
@Autowired
|
||||
private MyWebSocketHandler myWebSocketHandler;
|
||||
|
||||
/**
|
||||
* 注册 WebSocket 路由映射
|
||||
* 路径对应前端连接的 ws://xxx/webSocket/checkIn
|
||||
*/
|
||||
@Bean
|
||||
public HandlerMapping webSocketMapping() {
|
||||
Map<String, WebSocketHandler> map = new HashMap<>();
|
||||
map.put("/webSocket/checkIn", myWebSocketHandler);
|
||||
|
||||
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
|
||||
mapping.setUrlMap(map);
|
||||
mapping.setOrder(10); // 设置优先级
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册 WebSocket 处理器适配器(必须)
|
||||
*/
|
||||
@Bean
|
||||
public WebSocketHandlerAdapter handlerAdapter() {
|
||||
return new WebSocketHandlerAdapter();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -206,4 +206,4 @@ public class SignInRecord {
|
||||
public void restore() {
|
||||
this.isDelete = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-5
@@ -2,8 +2,6 @@ package cn.novalon.gym.manage.checkIn.handler;
|
||||
|
||||
import cn.novalon.gym.manage.checkIn.service.impl.CheckServiceImpl;
|
||||
import cn.novalon.gym.manage.checkIn.websocket.MyWebSocketHandler;
|
||||
import cn.novalon.gym.manage.checkIn.vo.SignInRecordVO;
|
||||
import cn.novalon.gym.manage.checkIn.vo.SignInStatsVO;
|
||||
import cn.novalon.gym.manage.sys.util.AuthUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -14,7 +12,6 @@ import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import cn.novalon.gym.manage.checkIn.websocket.MyWebSocketHandler;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
@@ -39,7 +36,6 @@ public class CheckInHandler {
|
||||
public Mono<ServerResponse> checkIn(ServerRequest request) {
|
||||
|
||||
Long memberId = authUtil.getMemberIdOrThrow(request);
|
||||
|
||||
return request.bodyToMono(Map.class)
|
||||
.flatMap(body -> {
|
||||
String qrContent = (String) body.get("qrContent");
|
||||
@@ -194,4 +190,4 @@ public class CheckInHandler {
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(Map.of("code", 200, "message", "success", "data", stats)));
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -78,4 +78,4 @@ public interface ICheckInService {
|
||||
* @return 签到统计VO
|
||||
*/
|
||||
Mono<SignInStatsVO> getDailySignInStats(LocalDate date);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -2,8 +2,6 @@ package cn.novalon.gym.manage.checkIn.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.hutool.extra.qrcode.QrCodeUtil;
|
||||
import cn.hutool.extra.qrcode.QrConfig;
|
||||
import cn.novalon.gym.manage.checkIn.config.QRCodeConfig;
|
||||
import cn.novalon.gym.manage.checkIn.constant.QRRedisKey;
|
||||
import cn.novalon.gym.manage.checkIn.entity.SignInRecord;
|
||||
@@ -21,6 +19,8 @@ import cn.novalon.gym.manage.member.entity.MemberCardRecord;
|
||||
import cn.novalon.gym.manage.member.enums.MemberCardType;
|
||||
import cn.novalon.gym.manage.member.repository.MemberCardRecordRepository;
|
||||
import cn.novalon.gym.manage.member.repository.MemberCardRepository;
|
||||
import cn.hutool.extra.qrcode.QrCodeUtil;
|
||||
import cn.hutool.extra.qrcode.QrConfig;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
+1
-1
@@ -199,4 +199,4 @@ public class MyWebSocketHandler implements WebSocketHandler {
|
||||
cleanupTimeoutConnections();
|
||||
return qrContentToSink.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,12 +93,6 @@
|
||||
<artifactId>javase</artifactId>
|
||||
<version>3.5.3</version>
|
||||
</dependency>
|
||||
<!-- 阿里云OSS SDK -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>3.17.4</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
package cn.novalon.gym.manage.groupcourse.util;
|
||||
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import com.aliyun.oss.model.PutObjectRequest;
|
||||
//import com.aliyun.oss.OSS;
|
||||
//import com.aliyun.oss.OSSClientBuilder;
|
||||
//import com.aliyun.oss.model.PutObjectRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,5 @@
|
||||
package cn.novalon.gym.manage.member.service.impl;
|
||||
|
||||
import cn.novalon.gym.manage.common.util.RedisUtil;
|
||||
import cn.novalon.gym.manage.member.entity.MemberCard;
|
||||
import cn.novalon.gym.manage.member.entity.MemberCardRecord;
|
||||
import cn.novalon.gym.manage.member.entity.MemberCardTransaction;
|
||||
@@ -16,6 +15,7 @@ import cn.novalon.gym.manage.member.repository.MemberCardRecordRepository;
|
||||
import cn.novalon.gym.manage.member.repository.MemberCardRepository;
|
||||
import cn.novalon.gym.manage.member.service.IMemberCardService;
|
||||
import cn.novalon.gym.manage.member.service.IMemberCardTransactionService;
|
||||
import cn.novalon.gym.manage.common.util.RedisUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
-- ============================================
|
||||
-- 签到记录表(sign_in_record)
|
||||
-- ============================================
|
||||
|
||||
-- Step 1: 创建 sign_in_record 表
|
||||
CREATE TABLE IF NOT EXISTS sign_in_record (
|
||||
-- ========== 主键和基础字段 ==========
|
||||
id BIGSERIAL PRIMARY KEY, -- 自增主键
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 记录创建时间
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 记录更新时间
|
||||
|
||||
-- ========== 会员相关字段 ==========
|
||||
member_id BIGINT NOT NULL, -- 会员ID,关联member_user表
|
||||
member_card_id BIGINT, -- 签到时使用的会员卡ID
|
||||
|
||||
-- ========== 签到核心字段 ==========
|
||||
sign_in_time TIMESTAMP NOT NULL, -- 签到入场时间
|
||||
sign_in_type VARCHAR(20) NOT NULL, -- 签到方式:QR_CODE-扫码签到,MANUAL-手动签到,FACE-人脸识别
|
||||
sign_in_status VARCHAR(20) NOT NULL DEFAULT 'SUCCESS', -- 签到状态:SUCCESS-成功,FAILED-失败
|
||||
|
||||
-- ========== 验证和错误信息 ==========
|
||||
verification_details TEXT, -- JSONB格式,存储会员卡验证时的快照数据
|
||||
fail_reason VARCHAR(500), -- 失败时的具体原因文案
|
||||
|
||||
-- ========== 操作人信息 ==========
|
||||
operator_id BIGINT, -- 操作人ID(前台人员),自助签到时为NULL
|
||||
operator_name VARCHAR(100), -- 操作人姓名冗余
|
||||
|
||||
-- ========== 设备和环境信息 ==========
|
||||
device_info VARCHAR(200), -- 签到设备标识或型号
|
||||
ip_address VARCHAR(50), -- 客户端IP地址
|
||||
source VARCHAR(20) NOT NULL, -- 签到来源:MINI_PROGRAM-小程序扫码,PC_BACKEND-后台管理端
|
||||
|
||||
-- ========== 软删除字段 ==========
|
||||
is_delete BOOLEAN DEFAULT FALSE -- 软删除标识:false-未删除,true-已删除
|
||||
);
|
||||
|
||||
-- Step 2: 创建索引
|
||||
-- 会员ID索引(加速按会员查询签到记录)
|
||||
CREATE INDEX IF NOT EXISTS idx_sign_in_record_member_id ON sign_in_record(member_id);
|
||||
|
||||
-- 签到时间索引(加速按时间范围查询)
|
||||
CREATE INDEX IF NOT EXISTS idx_sign_in_record_sign_in_time ON sign_in_record(sign_in_time);
|
||||
|
||||
-- 签到状态索引(加速按状态筛选)
|
||||
CREATE INDEX IF NOT EXISTS idx_sign_in_record_sign_in_status ON sign_in_record(sign_in_status);
|
||||
|
||||
-- 会员卡ID索引(加速按会员卡查询)
|
||||
CREATE INDEX IF NOT EXISTS idx_sign_in_record_member_card_id ON sign_in_record(member_card_id);
|
||||
|
||||
-- 操作人ID索引(加速按操作人查询)
|
||||
CREATE INDEX IF NOT EXISTS idx_sign_in_record_operator_id ON sign_in_record(operator_id);
|
||||
|
||||
-- 签到来源索引(加速按来源统计)
|
||||
CREATE INDEX IF NOT EXISTS idx_sign_in_record_source ON sign_in_record(source);
|
||||
|
||||
-- 软删除索引(加速查询未删除的记录)
|
||||
CREATE INDEX IF NOT EXISTS idx_sign_in_record_is_delete ON sign_in_record(is_delete);
|
||||
|
||||
-- 复合索引:会员ID + 签到时间(加速会员签到历史查询)
|
||||
CREATE INDEX IF NOT EXISTS idx_sign_in_record_member_time ON sign_in_record(member_id, sign_in_time);
|
||||
|
||||
-- 复合索引:签到状态 + 签到时间(加速统计数据查询)
|
||||
CREATE INDEX IF NOT EXISTS idx_sign_in_record_status_time ON sign_in_record(sign_in_status, sign_in_time);
|
||||
|
||||
-- 复合索引:签到日期(用于每日统计,使用表达式索引)
|
||||
CREATE INDEX IF NOT EXISTS idx_sign_in_record_sign_in_date ON sign_in_record(DATE(sign_in_time));
|
||||
|
||||
-- Step 3: 添加外键约束(可选,根据业务需求决定)
|
||||
-- 注意:如果member_user表使用了软删除,外键约束可能需要谨慎使用
|
||||
-- ALTER TABLE sign_in_record
|
||||
-- ADD CONSTRAINT fk_sign_in_record_member
|
||||
-- FOREIGN KEY (member_id) REFERENCES member_user(id) ON DELETE SET NULL;
|
||||
|
||||
-- Step 4: 添加注释
|
||||
COMMENT ON TABLE sign_in_record IS '会员到店签到记录表';
|
||||
|
||||
COMMENT ON COLUMN sign_in_record.id IS '自增主键';
|
||||
COMMENT ON COLUMN sign_in_record.created_at IS '记录创建时间';
|
||||
COMMENT ON COLUMN sign_in_record.updated_at IS '记录更新时间';
|
||||
|
||||
COMMENT ON COLUMN sign_in_record.member_id IS '会员ID,关联member_user表';
|
||||
COMMENT ON COLUMN sign_in_record.member_card_id IS '签到时使用的会员卡ID';
|
||||
|
||||
COMMENT ON COLUMN sign_in_record.sign_in_time IS '签到入场时间';
|
||||
COMMENT ON COLUMN sign_in_record.sign_in_type IS '签到方式:QR_CODE-扫码签到,MANUAL-手动签到,FACE-人脸识别';
|
||||
COMMENT ON COLUMN sign_in_record.sign_in_status IS '签到状态:SUCCESS-成功,FAILED-失败';
|
||||
|
||||
COMMENT ON COLUMN sign_in_record.verification_details IS 'JSON格式,存储会员卡验证时的快照数据(包含卡类型、剩余次数/金额、有效期等)';
|
||||
COMMENT ON COLUMN sign_in_record.fail_reason IS '失败时的具体原因文案';
|
||||
|
||||
COMMENT ON COLUMN sign_in_record.operator_id IS '操作人ID(前台人员),自助签到时为NULL';
|
||||
COMMENT ON COLUMN sign_in_record.operator_name IS '操作人姓名冗余(避免关联查询)';
|
||||
|
||||
COMMENT ON COLUMN sign_in_record.device_info IS '签到设备标识或型号';
|
||||
COMMENT ON COLUMN sign_in_record.ip_address IS '客户端IP地址';
|
||||
COMMENT ON COLUMN sign_in_record.source IS '签到来源:MINI_PROGRAM-小程序扫码,PC_BACKEND-后台管理端';
|
||||
|
||||
COMMENT ON COLUMN sign_in_record.is_delete IS '软删除标识:false-未删除,true-已删除';
|
||||
+1
-1
@@ -63,7 +63,7 @@ public class JwtAuthenticationFilter extends AbstractGatewayFilterFactory<JwtAut
|
||||
path.equals("/api/auth/login") ||
|
||||
path.equals("/api/groupCourse/page") ||
|
||||
path.startsWith("/api/checkIn") ||
|
||||
path.startsWith("/api/payment") ||
|
||||
path.startsWith("/api/payment") ||
|
||||
path.startsWith("/actuator/info");
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ signature:
|
||||
max-age-minutes: ${SIGNATURE_MAX_AGE_MINUTES:5}
|
||||
nonce-cache-size: ${SIGNATURE_NONCE_CACHE_SIZE:10000}
|
||||
whitelist:
|
||||
paths: ${SIGNATURE_WHITELIST_PATHS:/actuator/health,/actuator/info,/api/auth/login,/api/auth/register,/api/member/auth/miniapp/login,/api/member/auth/mp/callback,/api/groupCourse/**}
|
||||
paths: ${SIGNATURE_WHITELIST_PATHS:/actuator/health,/actuator/info,/api/auth/login,/api/auth/register,/api/member/auth/miniapp/login,/api/member/auth/mp/callback}
|
||||
|
||||
resilience:
|
||||
enabled: ${RESILIENCE_ENABLED:true}
|
||||
|
||||
+6
-5
@@ -1,4 +1,4 @@
|
||||
package cn.novalon.gym.manage.sys.config;
|
||||
package cn.novalon.gym.manage.sys.config;
|
||||
|
||||
import cn.novalon.gym.manage.sys.audit.OperationLogWebFilter;
|
||||
import cn.novalon.gym.manage.sys.security.JwtAuthenticationFilter;
|
||||
@@ -21,7 +21,7 @@ public class SecurityConfig {
|
||||
private final OperationLogWebFilter operationLogWebFilter;
|
||||
private final Environment environment;
|
||||
|
||||
public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter,
|
||||
public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter,
|
||||
OperationLogWebFilter operationLogWebFilter,
|
||||
Environment environment) {
|
||||
this.jwtAuthenticationFilter = jwtAuthenticationFilter;
|
||||
@@ -33,11 +33,11 @@ public class SecurityConfig {
|
||||
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
|
||||
String[] activeProfiles = environment.getActiveProfiles();
|
||||
final boolean isDevOrTest;
|
||||
|
||||
|
||||
isDevOrTest = java.util.Arrays.stream(activeProfiles)
|
||||
.anyMatch(profile -> "dev".equals(profile) || "test".equals(profile) || "h2-test".equals(profile));
|
||||
|
||||
logger.info("SecurityConfig初始化: 当前环境={}, Swagger启用状态={}",
|
||||
|
||||
logger.info("SecurityConfig初始化: 当前环境={}, Swagger启用状态={}",
|
||||
activeProfiles.length > 0 ? String.join(",", activeProfiles) : "default", isDevOrTest);
|
||||
|
||||
http
|
||||
@@ -66,6 +66,7 @@ public class SecurityConfig {
|
||||
.pathMatchers("/api/payment/notify").permitAll()
|
||||
.pathMatchers("/api/payment/refund").permitAll();
|
||||
|
||||
|
||||
if (isDevOrTest) {
|
||||
spec.pathMatchers("/swagger-ui.html").permitAll()
|
||||
.pathMatchers("/swagger-ui/**").permitAll()
|
||||
|
||||
Reference in New Issue
Block a user