完成会员查看个人信息,会员编辑个人基础信息功能

This commit is contained in:
2026-05-04 13:15:21 +08:00
parent f853cb73b5
commit 8f020d577f
16 changed files with 774 additions and 3 deletions
@@ -50,6 +50,7 @@ public class SecurityConfig {
spec.pathMatchers("/api/auth/**").permitAll()
.pathMatchers("/api/public/**").permitAll()
.pathMatchers("/ws/**").permitAll()
.pathMatchers("/api/gymMember/**").permitAll()
.pathMatchers("/actuator/**").permitAll();
if (isDevOrTest) {
@@ -0,0 +1,37 @@
package cn.novalon.gym.manage.sys.core.command;
import java.time.LocalDateTime;
public record UpdateGymMemberCommand(
Long id,
String username,
String email,
Long gender,
LocalDateTime birthday,
String province,
String city,
String district,
String address,
String emergency_contact,
String emergency_phone,
String avatar_url,
String remark
) {
public static UpdateGymMemberCommand of(
Long id,
String username,
String email,
Long gender,
LocalDateTime birthday,
String province,
String city,
String district,
String address,
String emergency_contact,
String emergency_phone,
String avatar_url,
String remark
){
return new UpdateGymMemberCommand(id, username, email, gender, birthday, province, city, district, address, emergency_contact, emergency_phone, avatar_url, remark);
}
}
@@ -0,0 +1,9 @@
package cn.novalon.gym.manage.sys.core.repository;
import cn.novalon.gym.manage.sys.core.domain.GymMember;
import reactor.core.publisher.Mono;
public interface IGymMemberRepository {
Mono<GymMember> findById(Long id);
Mono<GymMember> update(GymMember gymMember);
}
@@ -0,0 +1,11 @@
package cn.novalon.gym.manage.sys.core.service;
import cn.novalon.gym.manage.sys.core.command.UpdateGymMemberCommand;
import cn.novalon.gym.manage.sys.core.domain.GymMember;
import reactor.core.publisher.Mono;
public interface IGymMemberService {
Mono<GymMember> findById(Long id);
Mono<GymMember> updateMember(GymMember gymMember);
Mono<GymMember> updateMember(UpdateGymMemberCommand updateGymMemberCommand);
}
@@ -0,0 +1,104 @@
package cn.novalon.gym.manage.sys.core.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.novalon.gym.manage.sys.audit.AuditLogHelper;
import cn.novalon.gym.manage.sys.audit.service.IAuditLogService;
import cn.novalon.gym.manage.sys.core.command.UpdateGymMemberCommand;
import cn.novalon.gym.manage.sys.core.domain.GymMember;
import cn.novalon.gym.manage.sys.core.repository.IGymMemberRepository;
import cn.novalon.gym.manage.sys.core.service.IGymMemberService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
/**
* @author:liwentao
* @date:2026/5/4-05-04-10:27
*/
@Service
public class GymMemberService implements IGymMemberService {
private static final Logger logger = LoggerFactory.getLogger(SysUserService.class);
private final IGymMemberRepository gymMemberRepository;
private final PasswordEncoder passwordEncoder;
private final IAuditLogService auditLogService;
public GymMemberService(
IGymMemberRepository gymMemberRepository,
@Qualifier("passwordEncoder") PasswordEncoder passwordEncoder,
@Lazy IAuditLogService auditLogService){
this.gymMemberRepository = gymMemberRepository;
this.passwordEncoder = passwordEncoder;
this.auditLogService = auditLogService;
}
@Override
public Mono<GymMember> findById(Long id) {
return gymMemberRepository.findById(id);
}
@Override
public Mono<GymMember> updateMember(GymMember gymMember) {
gymMember.setUpdatedAt(LocalDateTime.now());
return gymMemberRepository.findById(gymMember.getId())
.flatMap(before -> gymMemberRepository.update(gymMember)
.flatMap(saved-> AuditLogHelper.record(auditLogService,"GymMember",saved.getId(),"UPDATE",before,saved)
.thenReturn(saved)));
}
@Override
public Mono<GymMember> updateMember(UpdateGymMemberCommand updateGymMemberCommand) {
return gymMemberRepository.findById(updateGymMemberCommand.id())
.switchIfEmpty(Mono.error(new RuntimeException("User not found")))
.flatMap( gymMember -> {
GymMember member = new GymMember();
BeanUtil.copyProperties(gymMember,member);
if(updateGymMemberCommand.username() != null){
gymMember.setUsername(updateGymMemberCommand.username());
}
if(updateGymMemberCommand.email() != null){
gymMember.setEmail(updateGymMemberCommand.email());
}
if(updateGymMemberCommand.gender() != null){
gymMember.setGender(updateGymMemberCommand.gender());
}
if(updateGymMemberCommand.birthday() != null){
gymMember.setBirthday(updateGymMemberCommand.birthday());
}
if(updateGymMemberCommand.province() != null){
gymMember.setProvince(updateGymMemberCommand.province());
}
if(updateGymMemberCommand.city() != null){
gymMember.setCity(updateGymMemberCommand.city());
}
if(updateGymMemberCommand.district() != null){
gymMember.setDistrict(updateGymMemberCommand.district());
}
if(updateGymMemberCommand.address() != null){
gymMember.setAddress(updateGymMemberCommand.address());
}
if(updateGymMemberCommand.emergency_contact() != null){
gymMember.setEmergencyContact(updateGymMemberCommand.emergency_contact());
}
if(updateGymMemberCommand.emergency_phone() != null){
gymMember.setEmergencyPhone(updateGymMemberCommand.emergency_phone());
}
if(updateGymMemberCommand.avatar_url() != null){
gymMember.setAvatarUrl(updateGymMemberCommand.avatar_url());
}
if(updateGymMemberCommand.remark() != null){
gymMember.setRemark(updateGymMemberCommand.remark());
}
gymMember.setUpdatedAt(LocalDateTime.now());
return gymMemberRepository.update(gymMember)
.flatMap(saved -> AuditLogHelper
.record(auditLogService,"GymMember",saved.getId(),"UPDATE",member,saved)
.thenReturn(saved));
});
}
}
@@ -0,0 +1,133 @@
package cn.novalon.gym.manage.sys.dto.request;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
/**
* @author:liwentao
* @date:2026/5/4-05-04-12:14
*/
@Schema(description = "用户基础信息更新请求")
public class GymUpdateRequest {
@Schema(description = "用户名", example = "zhangsan")
private String username;
@Schema(description = "邮箱", example = "newemail@example.com")
private String email;
@Schema(description = "性别", example = "")
private Long gender;
@Schema(description = "生日", example = "2005-04-17")
private LocalDateTime birthday;
@Schema(description = "省份", example = "四川")
private String province;
@Schema(description = "城市", example = "内江市")
private String city;
@Schema(description = "区县", example = "市中区")
private String district;
@Schema(description = "详细地址", example = "xxx街")
private String address;
@Schema(description = "紧急联系人姓名", example = "李四")
private String emergency_contact;
@Schema(description = "紧急联系人电话", example = "123456789")
private String emergency_phone;
@Schema(description = "头像URL地址", example = "")
private String avatar_url;
@Schema(description = "备注", example = "")
private String remark;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmergency_contact() {
return emergency_contact;
}
public void setEmergency_contact(String emergency_contact) {
this.emergency_contact = emergency_contact;
}
public String getEmergency_phone() {
return emergency_phone;
}
public void setEmergency_phone(String emergency_phone) {
this.emergency_phone = emergency_phone;
}
public String getAvatar_url() {
return avatar_url;
}
public void setAvatar_url(String avatar_url) {
this.avatar_url = avatar_url;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Long getGender() {
return gender;
}
public void setGender(Long gender) {
this.gender = gender;
}
public LocalDateTime getBirthday() {
return birthday;
}
public void setBirthday(LocalDateTime birthday) {
this.birthday = birthday;
}
}
@@ -0,0 +1,63 @@
package cn.novalon.gym.manage.sys.handler.gymMember;
import cn.novalon.gym.manage.sys.core.command.UpdateGymMemberCommand;
import cn.novalon.gym.manage.sys.core.service.IGymMemberService;
import cn.novalon.gym.manage.sys.dto.request.GymUpdateRequest;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Validator;
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;
/**
* @author:liwentao
* @date:2026/5/4-05-04-10:56
*/
@Component
@Tag(name = "顾客管理", description = "顾客相关操作")
public class GymMemberHandler {
private final IGymMemberService gymMemberService;
private final Validator validator;
public GymMemberHandler(
IGymMemberService gymMemberService,
Validator validator
){
this.gymMemberService = gymMemberService;
this.validator = validator;
}
@Operation(summary = "根据id查询用户", description = "获取用户信息")
public Mono<ServerResponse> getUserById(ServerRequest request){
Long id = Long.valueOf(request.pathVariable("id"));
return gymMemberService.findById(id)
.flatMap(gymMember -> ServerResponse.ok().bodyValue(gymMember))
.switchIfEmpty(ServerResponse.notFound().build());
}
public Mono<ServerResponse> updateMemberBaseInfo(ServerRequest request){
Long id = Long.valueOf(request.pathVariable("id"));
return request.bodyToMono(GymUpdateRequest.class)
.map(req -> {
return UpdateGymMemberCommand.of(
id,
req.getUsername(),
req.getEmail(),
req.getGender(),
req.getBirthday(),
req.getProvince(),
req.getCity(),
req.getDistrict(),
req.getAddress(),
req.getEmergency_contact(),
req.getEmergency_phone(),
req.getAvatar_url(),
req.getRemark()
);
})
.flatMap(gymMemberService::updateMember)
.flatMap(gymMember -> ServerResponse.ok().bodyValue(gymMember))
.switchIfEmpty(ServerResponse.notFound().build());
}
}