diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/dto/UpdateMemberInfoDto.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/dto/UpdateMemberInfoDto.java new file mode 100644 index 0000000..835347c --- /dev/null +++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/dto/UpdateMemberInfoDto.java @@ -0,0 +1,30 @@ +package cn.novalon.gym.manage.member.dto; + +import lombok.Data; + +import java.util.Date; + +/** + * 更新会员信息Dto + * + * @author 付嘉 + * @date 2026-05-10 + */ +@Data +public class UpdateMemberInfoDto { + + // 昵称 + private String nickname; + + // 性别 + private Integer gender; + + // 生日 + private Date birthday; + + // 头像 + private String avatar; + + // 地址 + private String address; +} diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/handler/MemberHandler.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/handler/MemberHandler.java index 271d499..a54c8eb 100644 --- a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/handler/MemberHandler.java +++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/handler/MemberHandler.java @@ -1,6 +1,7 @@ package cn.novalon.gym.manage.member.handler; import cn.novalon.gym.manage.member.dto.AdminUpdatePhoneDto; +import cn.novalon.gym.manage.member.dto.UpdateMemberInfoDto; import cn.novalon.gym.manage.member.service.MemberService; import cn.novalon.gym.manage.member.service.WechatAuthService; import cn.novalon.gym.manage.member.service.WechatOfficialService; @@ -52,6 +53,35 @@ public class MemberHandler { }); } + /** + * 更新会员信息 + * + * PUT /api/member/info + * Header: X-Member-Id: 123 + * Body: { + * "nickname": "新昵称", + * "gender": 1, + * "birthday": "2000-01-01", + * "avatar": "https://example.com/avatar.jpg", + * "address": "北京市朝阳区" + * } + */ + public Mono updateMemberInfo(ServerRequest request) { + + String memberIdStr = request.headers().firstHeader("X-Member-Id"); + long memberId = NumberUtils.toLong(memberIdStr, 0L); + + if (memberId <= 0) throw new IllegalArgumentException("更新会员信息失败: memberId 无效"); + + log.info("更新会员信息, memberId: {}", memberId); + + return request.bodyToMono(UpdateMemberInfoDto.class) + .flatMap(updateDto -> memberService.updateMemberInfo(memberId, updateDto)) + .flatMap(info -> ServerResponse.ok() + .contentType(MediaType.APPLICATION_JSON) + .bodyValue(info)); + } + /** * 绑定手机号(微信小程序) * diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/service/MemberService.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/service/MemberService.java index 23a2ea8..aa4ea33 100644 --- a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/service/MemberService.java +++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/service/MemberService.java @@ -1,5 +1,6 @@ package cn.novalon.gym.manage.member.service; +import cn.novalon.gym.manage.member.dto.UpdateMemberInfoDto; import cn.novalon.gym.manage.member.vo.MemberInfoVO; import reactor.core.publisher.Mono; @@ -19,6 +20,15 @@ public interface MemberService { */ Mono getMemberInfo(Long memberId); + /** + * 会员更新个人信息 + * + * @param memberId 会员ID + * @param updateDto 更新信息DTO + * @return 更新后的会员信息 + */ + Mono updateMemberInfo(Long memberId, UpdateMemberInfoDto updateDto); + /** * 管理端更新会员手机号 * diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/service/impl/MemberServiceImpl.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/service/impl/MemberServiceImpl.java index 6509616..d9c3e4c 100644 --- a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/service/impl/MemberServiceImpl.java +++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/service/impl/MemberServiceImpl.java @@ -1,5 +1,6 @@ package cn.novalon.gym.manage.member.service.impl; +import cn.novalon.gym.manage.member.dto.UpdateMemberInfoDto; import cn.novalon.gym.manage.member.vo.MemberInfoVO; import cn.novalon.gym.manage.member.entity.Member; import cn.novalon.gym.manage.member.repository.MemberRepository; @@ -40,6 +41,40 @@ public class MemberServiceImpl implements MemberService { .map(this::buildMemberInfoResponse); } + @Override + public Mono updateMemberInfo(Long memberId, UpdateMemberInfoDto updateDto) { + log.info("会员更新个人信息, memberId: {}", memberId); + + return memberRepository.findById(memberId) + .switchIfEmpty(Mono.defer(() -> { + log.error("会员不存在: memberId={}", memberId); + return Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND, "会员不存在")); + })) + .flatMap(member -> { + if (updateDto.getNickname() != null) { + member.setNickname(updateDto.getNickname()); + } + if (updateDto.getGender() != null) { + member.setGender(updateDto.getGender()); + } + if (updateDto.getBirthday() != null) { + member.setBirthday(updateDto.getBirthday()); + } + if (updateDto.getAvatar() != null) { + member.setAvatar(updateDto.getAvatar()); + } + if (updateDto.getAddress() != null) { + member.setAddress(updateDto.getAddress()); + } + + return memberRepository.save(member); + }) + .map(savedMember -> { + log.info("会员信息更新成功, memberId: {}", savedMember.getId()); + return buildMemberInfoResponse(savedMember); + }); + } + // 会员信息响应 private MemberInfoVO buildMemberInfoResponse(Member member) { String phone = member.getPhone(); diff --git a/gym-manage-api/manage-app/src/main/java/cn/novalon/gym/manage/app/config/SystemRouter.java b/gym-manage-api/manage-app/src/main/java/cn/novalon/gym/manage/app/config/SystemRouter.java index f5b549e..12d6cd0 100644 --- a/gym-manage-api/manage-app/src/main/java/cn/novalon/gym/manage/app/config/SystemRouter.java +++ b/gym-manage-api/manage-app/src/main/java/cn/novalon/gym/manage/app/config/SystemRouter.java @@ -204,6 +204,7 @@ public class SystemRouter { // ========== 会员模块路由 - 会员信息 ========== .GET("/api/member/info", memberHandler::getMemberInfo) + .PUT("/api/member/info", memberHandler::updateMemberInfo) .POST("/api/member/phone/bind", memberHandler::bindPhone) .GET("/api/member/subscribe/status", memberHandler::checkSubscribeStatus) diff --git a/gym-manage-api/manage-app/src/main/resources/application-dev.yml b/gym-manage-api/manage-app/src/main/resources/application-dev.yml index 8f5e8dc..33e428e 100644 --- a/gym-manage-api/manage-app/src/main/resources/application-dev.yml +++ b/gym-manage-api/manage-app/src/main/resources/application-dev.yml @@ -12,11 +12,15 @@ spring: max-life-time: 30m acquire-timeout: 3s flyway: + url: jdbc:postgresql://localhost:55432/manage_system + user: novalon + password: novalon123 enabled: true locations: classpath:db/migration baseline-on-migrate: true validate-on-migrate: true + jwt: secret: novalon-gym-manage-jwt-secret-key-for-development-only-2026 expiration: 86400000 diff --git a/gym-manage-api/manage-app/src/main/resources/application.yml b/gym-manage-api/manage-app/src/main/resources/application.yml index 9305b16..807415e 100644 --- a/gym-manage-api/manage-app/src/main/resources/application.yml +++ b/gym-manage-api/manage-app/src/main/resources/application.yml @@ -15,8 +15,8 @@ spring: - org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration r2dbc: url: r2dbc:postgresql://${DB_HOST:localhost}:${DB_PORT:55432}/${DB_NAME:manage_system} - username: ${DB_USERNAME:postgres} - password: ${DB_PASSWORD:postgres} + username: ${DB_USERNAME:novalon} + password: ${DB_PASSWORD:novalon123} pool: initial-size: 10 max-size: 50 @@ -25,8 +25,8 @@ spring: acquire-timeout: 5s datasource: url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:55432}/${DB_NAME:manage_system} - username: ${DB_USERNAME:postgres} - password: ${DB_PASSWORD:postgres} + username: ${DB_USERNAME:novalon} + password: ${DB_PASSWORD:novalon123} driver-class-name: org.postgresql.Driver flyway: enabled: true @@ -38,6 +38,8 @@ spring: user: name: disabled password: disabled + profiles: + active: dev management: endpoints: