diff --git a/gym-manage-api/gym-member-card/pom.xml b/gym-manage-api/gym-member-card/pom.xml
deleted file mode 100644
index 1801b55..0000000
--- a/gym-manage-api/gym-member-card/pom.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-
-
- 4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 3.5.13
-
-
- cn.novalon.gym.manage
- gym-member-card
- 0.0.1-SNAPSHOT
- gym-member-card
- gym-member-card
-
-
- 21
-
-
-
-
-
- org.springframework.boot
- spring-boot-starter-webflux
-
-
-
-
- org.postgresql
- postgresql
- runtime
-
-
-
-
- cn.novalon.gym.manage
- manage-db
- 1.0.0
- compile
-
-
-
-
- org.projectlombok
- lombok
- 1.18.36
- provided
-
-
-
-
- cn.hutool
- hutool-all
- 5.8.22
-
-
-
-
- org.springframework
- spring-context
-
-
-
-
- org.springframework.boot
- spring-boot-starter-data-redis-reactive
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-starter-json
-
-
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
- exec
-
-
-
-
-
\ No newline at end of file
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/GymMemberCardApplication.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/GymMemberCardApplication.java
deleted file mode 100644
index 00c02f6..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/GymMemberCardApplication.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
-import org.springframework.scheduling.annotation.EnableScheduling;
-
-@SpringBootApplication
-@EnableR2dbcRepositories(basePackages = "cn.novalon.gym.manage.gymmembercard.dao")
-@EnableScheduling
-public class GymMemberCardApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(GymMemberCardApplication.class, args);
- }
-
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/dao/MemberCardDao.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/dao/MemberCardDao.java
deleted file mode 100644
index 8877d8d..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/dao/MemberCardDao.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.dao;
-
-import cn.novalon.gym.manage.gymmembercard.entity.MemberCardEntity;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.r2dbc.repository.Modifying;
-import org.springframework.data.r2dbc.repository.Query;
-import org.springframework.data.r2dbc.repository.R2dbcRepository;
-import org.springframework.stereotype.Repository;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-@Repository
-public interface MemberCardDao extends R2dbcRepository {
-
- /**
- * 根据会员卡ID查询会员卡详情(用于编辑前回显或小程序端展示)
- * @param memberCardId 会员卡ID
- * @return 会员卡完整信息,如果不存在或已删除则返回空
- */
- Mono findByMemberCardIdAndDeletedAtIsNull(Long memberCardId);
-
- /**
- * 条件查询会员卡列表(后台卡种列表展示,支持多条件组合+分页+排序)
- * 注意:模糊查询使用前后缀通配符,若数据量较大可能影响索引效率,建议后期引入全文索引或改用后缀模糊
- * @param status 会员卡状态(上架/下架)
- * @param name 会员卡名称(模糊查询)
- * @param type 会员卡类型
- * @param minPrice 最低价格
- * @param maxPrice 最高价格
- * @param pageable 分页和排序参数
- * @return 符合条件的会员卡列表
- */
- @Query("SELECT * FROM member_card WHERE deleted_at IS NULL " +
- "AND (:status IS NULL OR member_card_status = :status) " +
- "AND (:name IS NULL OR member_card_name LIKE CONCAT('%', :name, '%')) " +
- "AND (:type IS NULL OR member_card_type = :type) " +
- "AND (:minPrice IS NULL OR member_card_price >= :minPrice) " +
- "AND (:maxPrice IS NULL OR member_card_price <= :maxPrice) " +
- "ORDER BY created_at DESC LIMIT :#{#pageable.pageSize} OFFSET :#{#pageable.offset}")
- Flux findWithConditions(Integer status, String name, String type,
- Double minPrice, Double maxPrice, Pageable pageable);
-
- /**
- * 统计符合条件的会员卡总数(配合列表查询使用)
- * @param status 会员卡状态
- * @param name 会员卡名称(模糊查询)
- * @param type 会员卡类型
- * @param minPrice 最低价格
- * @param maxPrice 最高价格
- * @return 符合条件的会员卡数量
- */
- @Query("SELECT COUNT(*) FROM member_card WHERE deleted_at IS NULL " +
- "AND (:status IS NULL OR member_card_status = :status) " +
- "AND (:name IS NULL OR member_card_name LIKE CONCAT('%', :name, '%')) " +
- "AND (:type IS NULL OR member_card_type = :type) " +
- "AND (:minPrice IS NULL OR member_card_price >= :minPrice) " +
- "AND (:maxPrice IS NULL OR member_card_price <= :maxPrice)")
- Mono countWithConditions(Integer status, String name, String type,
- Double minPrice, Double maxPrice);
-
- /**
- * 按状态查询会员卡列表(用于小程序端展示可购买卡列表,只展示上架的卡)
- * @param status 会员卡状态(通常传上架状态)
- * @param pageable 分页和排序参数
- * @return 符合条件的会员卡列表
- */
- Flux findByMemberCardStatusAndDeletedAtIsNull(Integer status, Pageable pageable);
-
- /**
- * 检查会员卡是否已被购买(用于删除前的校验)
- * 注意:此查询关联到 member_card_record 表,建议后续独立至 MemberCardRecordDao
- * @param memberCardId 会员卡ID
- * @return 如果存在关联的会员记录则返回true,否则返回false
- */
- @Query("SELECT EXISTS(SELECT 1 FROM member_card_record WHERE member_card_id = :memberCardId AND deleted_at IS NULL LIMIT 1)")
- Mono existsPurchasedRecord(Long memberCardId);
-
- /**
- * 逻辑删除会员卡(下架卡种,防止已购会员数据异常)
- * @param memberCardId 会员卡ID
- * @return 受影响的行数
- */
- @Modifying
- @Query("UPDATE member_card SET deleted_at = NOW() WHERE member_card_id = :memberCardId AND deleted_at IS NULL")
- Mono logicalDelete(Long memberCardId);
-
- /**
- * 【新增】安全更新会员卡信息(仅允许修改业务相关字段,防止覆盖敏感字段)
- * @param memberCardId 会员卡ID
- * @param name 卡种名称
- * @param price 价格
- * @param durationDays 有效天数
- * @param totalCount 总次数
- * @param denomination 面额
- * @param status 状态
- * @return 受影响的行数
- */
- @Modifying
- @Query("UPDATE member_card SET " +
- "member_card_name = COALESCE(:name, member_card_name), " +
- "member_card_price = COALESCE(:price, member_card_price), " +
- "duration_days = COALESCE(:durationDays, duration_days), " +
- "total_count = COALESCE(:totalCount, total_count), " +
- "denomination = COALESCE(:denomination, denomination), " +
- "member_card_status = COALESCE(:status, member_card_status), " +
- "updated_at = NOW() " +
- "WHERE member_card_id = :memberCardId AND deleted_at IS NULL")
- Mono updateSafe(Long memberCardId, String name, Double price,
- Integer durationDays, Integer totalCount,
- Double denomination, Integer status);
-
- /**
- * 保存卡种信息(新增或更新)
- * - 新增:entity.memberCardId 为 null 时,插入新记录
- * - 更新:entity.memberCardId 不为 null 时,根据ID更新现有记录
- * 注意:直接 save 会更新所有字段,如需安全更新请调用 updateSafe 方法
- * @param entity 卡种信息
- * @return 保存后的实体对象
- */
- @Override
- Mono save(S entity);
-
- /**
- * 批量查询上架的会员卡(用于小程序端展示)
- * @param status 上架状态值
- * @return 上架的会员卡列表
- */
- @Query("SELECT * FROM member_card WHERE deleted_at IS NULL AND member_card_status = :status ORDER BY member_card_price ASC")
- Flux findActiveCards(Integer status);
-}
\ No newline at end of file
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/dao/MemberCardTransactionsDao.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/dao/MemberCardTransactionsDao.java
deleted file mode 100644
index bb3473e..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/dao/MemberCardTransactionsDao.java
+++ /dev/null
@@ -1,173 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.dao;
-
-import cn.novalon.gym.manage.gymmembercard.entity.MemberCardTransactionsEntity;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsAction;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsType;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.r2dbc.repository.Modifying;
-import org.springframework.data.r2dbc.repository.Query;
-import org.springframework.data.r2dbc.repository.R2dbcRepository;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-import java.time.LocalDateTime;
-
-@Repository
-public interface MemberCardTransactionsDao extends R2dbcRepository {
- /**
- * 记录每一次变动
- * 购卡、扣次、续费、退款、过期,均插入一条流水,记录变动前后快照
- * 注意:返回值依赖 PostgreSQL 的 RETURNING 语法,若使用 MySQL 请删除 RETURNING * 并改用 save()
- * @param memberCardId 会员卡ID
- * @param memberId 会员ID
- * @param operationType 操作类型
- * @param changeAmount 变动次数(次卡)
- * @param changeBalance 变动金额(储值卡)
- * @param afterRemainingCount 变动后剩余次数
- * @param afterRemainingBalance 变动后剩余余额
- * @param relatedBizType 关联业务类型
- * @param remark 备注
- * @return 插入的流水记录
- */
- @Modifying
- @Query("INSERT INTO member_card_transactions (member_card_id, member_id, operation_type, change_amount, " +
- "change_balance, after_remaining_count, after_remaining_balance, related_biz_type, remark, created_at, updated_at) " +
- "VALUES (:memberCardId, :memberId, :operationType, :changeAmount, :changeBalance, " +
- ":afterRemainingCount, :afterRemainingBalance, :relatedBizType, :remark, NOW(), NOW()) " +
- "RETURNING *")
- Mono insertTransaction(@Param("memberCardId") Long memberCardId,
- @Param("memberId") Long memberId,
- @Param("operationType") MemberCardTransactionsAction operationType,
- @Param("changeAmount") Integer changeAmount,
- @Param("changeBalance") Double changeBalance,
- @Param("afterRemainingCount") Integer afterRemainingCount,
- @Param("afterRemainingBalance") Double afterRemainingBalance,
- @Param("relatedBizType") MemberCardTransactionsType relatedBizType,
- @Param("remark") String remark);
-
- /**
- * 会员端"使用记录"
- * 按会员ID和时间范围查询,按时间倒序,显示每次变动明细
- * @param memberId 会员ID
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @param pageable 分页参数
- * @return 流水记录列表
- */
- @Query("SELECT * FROM member_card_transactions WHERE member_id = :memberId " +
- "AND created_at BETWEEN :startTime AND :endTime AND deleted_at IS NULL " +
- "ORDER BY created_at DESC LIMIT :#{#pageable.pageSize} OFFSET :#{#pageable.offset}")
- Flux findByMemberIdAndTimeRange(@Param("memberId") Long memberId,
- @Param("startTime") LocalDateTime startTime,
- @Param("endTime") LocalDateTime endTime,
- Pageable pageable);
-
- /**
- * 后台"使用记录查询"
- * 按会员、卡号、操作类型、时间范围等条件组合查询
- * @param memberId 会员ID
- * @param memberCardId 会员卡ID
- * @param operationType 操作类型
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @param pageable 分页参数
- * @return 流水记录列表
- */
- @Query("SELECT * FROM member_card_transactions WHERE deleted_at IS NULL " +
- "AND (:memberId IS NULL OR member_id = :memberId) " +
- "AND (:memberCardId IS NULL OR member_card_id = :memberCardId) " +
- "AND (:operationType IS NULL OR operation_type = :operationType) " +
- "AND (:startTime IS NULL OR created_at >= :startTime) " +
- "AND (:endTime IS NULL OR created_at <= :endTime) " +
- "ORDER BY created_at DESC LIMIT :#{#pageable.pageSize} OFFSET :#{#pageable.offset}")
- Flux findWithConditions(@Param("memberId") Long memberId,
- @Param("memberCardId") Long memberCardId,
- @Param("operationType") MemberCardTransactionsAction operationType,
- @Param("startTime") LocalDateTime startTime,
- @Param("endTime") LocalDateTime endTime,
- Pageable pageable);
-
- /**
- * 统计符合条件的流水总数
- * @param memberId 会员ID
- * @param memberCardId 会员卡ID
- * @param operationType 操作类型
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 流水记录数量
- */
- @Query("SELECT COUNT(*) FROM member_card_transactions WHERE deleted_at IS NULL " +
- "AND (:memberId IS NULL OR member_id = :memberId) " +
- "AND (:memberCardId IS NULL OR member_card_id = :memberCardId) " +
- "AND (:operationType IS NULL OR operation_type = :operationType) " +
- "AND (:startTime IS NULL OR created_at >= :startTime) " +
- "AND (:endTime IS NULL OR created_at <= :endTime)")
- Mono countWithConditions(@Param("memberId") Long memberId,
- @Param("memberCardId") Long memberCardId,
- @Param("operationType") MemberCardTransactionsAction operationType,
- @Param("startTime") LocalDateTime startTime,
- @Param("endTime") LocalDateTime endTime);
-
- /**
- * 按会员卡ID查询所有流水记录(补充常用方法)
- * @param memberCardId 会员卡ID
- * @return 该卡的所有流水记录,按时间倒序
- */
- @Query("SELECT * FROM member_card_transactions WHERE member_card_id = :memberCardId AND deleted_at IS NULL ORDER BY created_at DESC")
- Flux findByMemberCardId(@Param("memberCardId") Long memberCardId);
-
- /**
- * 数据统计 - 统计某卡种的总扣次数
- * @param memberCardId 会员卡ID
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 总扣次数
- */
- @Query("SELECT COALESCE(SUM(change_amount), 0) FROM member_card_transactions " +
- "WHERE member_card_id = :memberCardId AND operation_type = 'DEDUCT' " +
- "AND created_at BETWEEN :startTime AND :endTime AND deleted_at IS NULL")
- Mono sumDeductCountByCardId(@Param("memberCardId") Long memberCardId,
- @Param("startTime") LocalDateTime startTime,
- @Param("endTime") LocalDateTime endTime);
-
- /**
- * 数据统计 - 统计某时间段的续费总金额
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 续费总金额
- */
- @Query("SELECT COALESCE(SUM(change_balance), 0) FROM member_card_transactions " +
- "WHERE operation_type = 'RENEW' AND created_at BETWEEN :startTime AND :endTime AND deleted_at IS NULL")
- Mono sumRenewAmountByTimeRange(@Param("startTime") LocalDateTime startTime,
- @Param("endTime") LocalDateTime endTime);
-
- /**
- * 数据统计 - 统计某会员的购卡总金额
- * @param memberId 会员ID
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 购卡总金额
- */
- @Query("SELECT COALESCE(SUM(change_balance), 0) FROM member_card_transactions " +
- "WHERE member_id = :memberId AND operation_type = 'PURCHASE' " +
- "AND created_at BETWEEN :startTime AND :endTime AND deleted_at IS NULL")
- Mono sumPurchaseAmountByMemberId(@Param("memberId") Long memberId, @Param("startTime") LocalDateTime startTime,
- @Param("endTime") LocalDateTime endTime);
- /**
- * 按会员ID查询所有流水记录
- * @param memberId 会员ID
- * @return 该会员的所有流水记录,按时间倒序
- */
- @Query("SELECT * FROM member_card_transactions WHERE member_id = :memberId ORDER BY created_at DESC")
- Flux findByMemberId(Long memberId);
- /**
- * 按会员卡记录ID查询所有流水记录
- * @param recordId 会员卡记录ID
- * @return 该会员卡的所有流水记录,按时间倒序
- */
- @Query("SELECT * FROM member_card_transactions WHERE member_card_record_id = :recordId ORDER BY created_at DESC")
- Flux findByRecordId(Long recordId);
-
-}
\ No newline at end of file
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/domain/MemberCard.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/domain/MemberCard.java
deleted file mode 100644
index 6a79ba5..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/domain/MemberCard.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.domain;
-
-import cn.novalon.gym.manage.sys.core.domain.BaseDomain;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.time.LocalDateTime;
-
-/*
- *@Author:shizhounian
- *@Date:2026/5/10-05 22:47:31
- */
-@Schema(description = "会员卡类型表")
-public class MemberCard extends BaseDomain {
- //会员卡id
- @Schema(description = "会员卡Id",example = "1")
- private Long memberCardId;
-
- //会员卡名称
- @Schema(description = "会员卡名称",example = "月卡")
- private String memberCardName;
-
- //会员卡类型
- @Schema(description = "会员卡类型",example = "TIME_CARD")
- private String memberCardType;
-
- //会员卡价格
- @Schema(description = "会员卡价格",example = "199.0")
- private Double memberCardPrice;
-
- //会员卡有效天数(时长卡用)
- @Schema(description = "会员卡有效天数",example = "30")
- private Integer memberCardValidityDays;
-
- //会员卡总次数(次卡用)
- @Schema(description = "会员卡总次数",example = "10")
- private Integer memberCardTotalTimes;
-
- //会员卡面额(储值卡用)
- @Schema(description = "会员卡面额",example = "500.0")
- private Double memberCardAmount;
-
- //会员卡状态:0-正常,1-禁用
- @Schema(description = "会员卡状态",example = "0")
- private Integer memberCardStatus;
-
- //会员卡创建时间
- @Schema(description = "会员卡创建时间",example = "2026-05-10 05:22:47")
- private LocalDateTime memberCardCreateTime;
-
- public Long getMemberCardId() {
- return memberCardId;
- }
-
- public void setMemberCardId(Long memberCardId) {
- this.memberCardId = memberCardId;
- }
-
- public String getMemberCardName() {
- return memberCardName;
- }
-
- public void setMemberCardName(String memberCardName) {
- this.memberCardName = memberCardName;
- }
-
- public String getMemberCardType() {
- return memberCardType;
- }
-
- public void setMemberCardType(String memberCardType) {
- this.memberCardType = memberCardType;
- }
-
- public Double getMemberCardPrice() {
- return memberCardPrice;
- }
-
- public void setMemberCardPrice(Double memberCardPrice) {
- this.memberCardPrice = memberCardPrice;
- }
-
- public Integer getMemberCardValidityDays() {
- return memberCardValidityDays;
- }
-
- public void setMemberCardValidityDays(Integer memberCardValidityDays) {
- this.memberCardValidityDays = memberCardValidityDays;
- }
-
- public Integer getMemberCardTotalTimes() {
- return memberCardTotalTimes;
- }
-
- public void setMemberCardTotalTimes(Integer memberCardTotalTimes) {
- this.memberCardTotalTimes = memberCardTotalTimes;
- }
-
- public Double getMemberCardAmount() {
- return memberCardAmount;
- }
-
- public void setMemberCardAmount(Double memberCardAmount) {
- this.memberCardAmount = memberCardAmount;
- }
-
- public Integer getMemberCardStatus() {
- return memberCardStatus;
- }
-
- public void setMemberCardStatus(Integer memberCardStatus) {
- this.memberCardStatus = memberCardStatus;
- }
-
- public LocalDateTime getMemberCardCreateTime() {
- return memberCardCreateTime;
- }
-
- public void setMemberCardCreateTime(LocalDateTime memberCardCreateTime) {
- this.memberCardCreateTime = memberCardCreateTime;
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/domain/MemberCardRecord.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/domain/MemberCardRecord.java
deleted file mode 100644
index a837546..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/domain/MemberCardRecord.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.domain;
-
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardRecordStatus;
-import cn.novalon.gym.manage.sys.core.domain.BaseDomain;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.time.LocalDateTime;
-
-@Schema(description = "会员卡记录")
-public class MemberCardRecord extends BaseDomain {
- @Schema(description = "会员持有卡ID", example = "1")
- private Long memberCardRecordId;
-
- @Schema(description = "会员ID", example = "1001")
- private Long memberId;
-
- @Schema(description = "关联会员卡ID", example = "1")
- private Long memberCardId;
-
- @Schema(description = "状态:ACTIVE-有效, USED_UP-用完, EXPIRED-过期, REFUNDED-已退款", example = "ACTIVE")
- private MemberCardRecordStatus status;
-
- @Schema(description = "剩余次数", example = "10")
- private Integer remainingTimes;
-
- @Schema(description = "剩余余额", example = "500.0")
- private Double remainingAmount;
-
- @Schema(description = "到期时间", example = "2026-06-23 10:00:00")
- private LocalDateTime expireTime;
-
- @Schema(description = "购买订单ID", example = "10001")
- private Long sourceOrderId;
-
- @Schema(description = "购买时间", example = "2026-05-23 10:00:00")
- private LocalDateTime purchaseTime;
-
- public Long getMemberCardRecordId() {
- return memberCardRecordId;
- }
-
- public void setMemberCardRecordId(Long memberCardRecordId) {
- this.memberCardRecordId = memberCardRecordId;
- }
-
- public Long getMemberId() {
- return memberId;
- }
-
- public void setMemberId(Long memberId) {
- this.memberId = memberId;
- }
-
- public Long getMemberCardId() {
- return memberCardId;
- }
-
- public void setMemberCardId(Long memberCardId) {
- this.memberCardId = memberCardId;
- }
-
- public MemberCardRecordStatus getStatus() {
- return status;
- }
-
- public void setStatus(MemberCardRecordStatus status) {
- this.status = status;
- }
-
- public Integer getRemainingTimes() {
- return remainingTimes;
- }
-
- public void setRemainingTimes(Integer remainingTimes) {
- this.remainingTimes = remainingTimes;
- }
-
- public Double getRemainingAmount() {
- return remainingAmount;
- }
-
- public void setRemainingAmount(Double remainingAmount) {
- this.remainingAmount = remainingAmount;
- }
-
- public LocalDateTime getExpireTime() {
- return expireTime;
- }
-
- public void setExpireTime(LocalDateTime expireTime) {
- this.expireTime = expireTime;
- }
-
- public Long getSourceOrderId() {
- return sourceOrderId;
- }
-
- public void setSourceOrderId(Long sourceOrderId) {
- this.sourceOrderId = sourceOrderId;
- }
-
- public LocalDateTime getPurchaseTime() {
- return purchaseTime;
- }
-
- public void setPurchaseTime(LocalDateTime purchaseTime) {
- this.purchaseTime = purchaseTime;
- }
-}
\ No newline at end of file
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/domain/MemberCardTransactions.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/domain/MemberCardTransactions.java
deleted file mode 100644
index aa7928f..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/domain/MemberCardTransactions.java
+++ /dev/null
@@ -1,159 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.domain;
-
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsAction;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsType;
-import cn.novalon.gym.manage.sys.core.domain.BaseDomain;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.time.LocalDateTime;
-
-/*
- *@Author:shizhounian
- *@Date:2026/5/10-05 22:47:31
- */
-@Schema(description = "会员卡流水")
-public class MemberCardTransactions extends BaseDomain {
- //会员卡流水Id
- @Schema(description = "会员卡流水Id",example = "1")
- private Long memberCardTransactionsId;
-
- //会员卡Id
- @Schema(description = "会员卡Id",example = "1")
- private Long memberCardId;
-
- //会员Id
- @Schema(description = "会员Id",example = "1")
- private Long memberId;
-
- //操作类型:PURCHASE(购买) / DEDUCT(扣次/扣费) / RENEW(续费) / REFUND(退款) / EXPIRE(过期)
- @Schema(description = "操作类型",example = "PURCHASE")
- private MemberCardTransactionsAction operationType;
-
- //变动次数(次卡用)
- @Schema(description = "变动次数(次卡用)",example = "1")
- private Integer changeAmount;
-
- //变动金额(储值卡用)
- @Schema(description = "变动金额(储值卡用)",example = "1")
- private Double changeBalance;
-
- //变动后剩余次数
- @Schema(description = "变动后剩余次数",example = "1")
- private Integer afterRemainingCount;
-
- //变动后剩余金额
- @Schema(description = "变动后剩余金额",example = "500.0")
- private Double afterRemainingBalance;
-
- //关联业务类型
- @Schema(description = "关联业务类型",example = "GROUP_CLASS")
- private MemberCardTransactionsType relatedBizType;
-
- //备注
- @Schema(description = "备注",example = "预约团课:瑜伽课扣1次")
- private String remark;
-
- //关联订单ID
- @Schema(description = "关联订单ID",example = "1")
- private Long sourceOrderId;
-
- //创建时间
- @Schema(description = "创建时间",example = "2026-05-10 05:22:47")
- private LocalDateTime createdAt;
-
- public Long getMemberCardTransactionsId() {
- return memberCardTransactionsId;
- }
-
- public void setMemberCardTransactionsId(Long memberCardTransactionsId) {
- this.memberCardTransactionsId = memberCardTransactionsId;
- }
-
- public Long getMemberCardId() {
- return memberCardId;
- }
-
- public void setMemberCardId(Long memberCardId) {
- this.memberCardId = memberCardId;
- }
-
- public Long getMemberId() {
- return memberId;
- }
-
- public void setMemberId(Long memberId) {
- this.memberId = memberId;
- }
-
- public MemberCardTransactionsAction getOperationType() {
- return operationType;
- }
-
- public void setOperationType(MemberCardTransactionsAction operationType) {
- this.operationType = operationType;
- }
-
- public Integer getChangeAmount() {
- return changeAmount;
- }
-
- public void setChangeAmount(Integer changeAmount) {
- this.changeAmount = changeAmount;
- }
-
- public Double getChangeBalance() {
- return changeBalance;
- }
-
- public void setChangeBalance(Double changeBalance) {
- this.changeBalance = changeBalance;
- }
-
- public Integer getAfterRemainingCount() {
- return afterRemainingCount;
- }
-
- public void setAfterRemainingCount(Integer afterRemainingCount) {
- this.afterRemainingCount = afterRemainingCount;
- }
-
- public Double getAfterRemainingBalance() {
- return afterRemainingBalance;
- }
-
- public void setAfterRemainingBalance(Double afterRemainingBalance) {
- this.afterRemainingBalance = afterRemainingBalance;
- }
-
- public MemberCardTransactionsType getRelatedBizType() {
- return relatedBizType;
- }
-
- public void setRelatedBizType(MemberCardTransactionsType relatedBizType) {
- this.relatedBizType = relatedBizType;
- }
-
- public String getRemark() {
- return remark;
- }
-
- public void setRemark(String remark) {
- this.remark = remark;
- }
-
- public Long getSourceOrderId() {
- return sourceOrderId;
- }
-
- public void setSourceOrderId(Long sourceOrderId) {
- this.sourceOrderId = sourceOrderId;
- }
-
- public LocalDateTime getCreatedAt() {
- return createdAt;
- }
-
- public void setCreatedAt(LocalDateTime createdAt) {
- this.createdAt = createdAt;
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/domain/RefundApplication.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/domain/RefundApplication.java
deleted file mode 100644
index 01b5f05..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/domain/RefundApplication.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.domain;
-
-import cn.novalon.gym.manage.sys.core.domain.BaseDomain;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
-/**
- * 退款申请领域对象
- *
- * @author shizhounian
- * @date 2026-05-23 21:11:46
- */
-@Schema(description = "退款申请", example = "refund_application")
-public class RefundApplication extends BaseDomain {
-
- @Schema(description = "退款申请ID", example = "1")
- private Long id;
-
- @Schema(description = "会员卡记录ID", example = "1")
- private Long recordId;
-
- @Schema(description = "会员ID", example = "1")
- private Long memberId;
-
- @Schema(description = "状态:PENDING-待审核, APPROVED-已批准, REJECTED-已拒绝, PROCESSING-处理中, SUCCESS-成功, FAILED-失败", example = "PENDING")
- private String status;
-
- @Schema(description = "退款原因", example = "个人原因申请退款")
- private String reason;
-
- @Schema(description = "申请时间", example = "2026-05-23 21:09:14")
- private LocalDateTime applyTime;
-
- @Schema(description = "审核时间", example = "2026-05-24 10:00:00")
- private LocalDateTime auditTime;
-
- @Schema(description = "审核人ID", example = "1")
- private Long auditorId;
-
- @Schema(description = "审核备注", example = "同意退款")
- private String auditRemark;
-
- @Schema(description = "退款金额", example = "500.00")
- private BigDecimal refundAmount;
-
- public Long getId() {
- return id;
- }
-
- public void setId(Long id) {
- this.id = id;
- }
-
- public Long getRecordId() {
- return recordId;
- }
-
- public void setRecordId(Long recordId) {
- this.recordId = recordId;
- }
-
- public Long getMemberId() {
- return memberId;
- }
-
- public void setMemberId(Long memberId) {
- this.memberId = memberId;
- }
-
- public String getStatus() {
- return status;
- }
-
- public void setStatus(String status) {
- this.status = status;
- }
-
- public String getReason() {
- return reason;
- }
-
- public void setReason(String reason) {
- this.reason = reason;
- }
-
- public LocalDateTime getApplyTime() {
- return applyTime;
- }
-
- public void setApplyTime(LocalDateTime applyTime) {
- this.applyTime = applyTime;
- }
-
- public LocalDateTime getAuditTime() {
- return auditTime;
- }
-
- public void setAuditTime(LocalDateTime auditTime) {
- this.auditTime = auditTime;
- }
-
- public Long getAuditorId() {
- return auditorId;
- }
-
- public void setAuditorId(Long auditorId) {
- this.auditorId = auditorId;
- }
-
- public String getAuditRemark() {
- return auditRemark;
- }
-
- public void setAuditRemark(String auditRemark) {
- this.auditRemark = auditRemark;
- }
-
- public BigDecimal getRefundAmount() {
- return refundAmount;
- }
-
- public void setRefundAmount(BigDecimal refundAmount) {
- this.refundAmount = refundAmount;
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/entity/MemberCardEntity.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/entity/MemberCardEntity.java
deleted file mode 100644
index d57641e..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/entity/MemberCardEntity.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.entity;
-
-import cn.novalon.gym.manage.db.entity.BaseEntity;
-import lombok.Data;
-import org.springframework.data.relational.core.mapping.Column;
-import org.springframework.data.relational.core.mapping.Table;
-
-import java.time.LocalDateTime;
-
-/*
- *@Author:shizhounian
- *@Date:2026/5/10-05 22:47:31
- */
-@Table("member_card")
-public class MemberCardEntity extends BaseEntity {
- //会员卡id
- @Column("member_card_id")
- private Long memberCardId;
-
- //会员卡名称
- @Column("member_card_name")
- private String memberCardName;
-
- //会员卡类型
- @Column("member_card_type")
- private String memberCardType;
-
- //会员卡价格
- @Column("member_card_price")
- private Double memberCardPrice;
-
- //会员卡有效天数(时长卡用)
- @Column("member_card_validity_days")
- private Integer memberCardValidityDays;
-
- //会员卡总次数(次卡用)
- @Column("member_card_total_times")
- private Integer memberCardTotalTimes;
-
- //会员卡面额(储值卡用)
- @Column("member_card_amount")
- private Double memberCardAmount;
-
- //会员卡状态:0-正常,1-禁用
- @Column("member_card_status")
- private Integer memberCardStatus;
-
- //会员卡创建时间
- @Column("member_card_create_time")
- private LocalDateTime memberCardCreateTime;
-
- public Long getMemberCardId() {
- return memberCardId;
- }
-
- public void setMemberCardId(Long memberCardId) {
- this.memberCardId = memberCardId;
- }
-
- public String getMemberCardName() {
- return memberCardName;
- }
-
- public void setMemberCardName(String memberCardName) {
- this.memberCardName = memberCardName;
- }
-
- public String getMemberCardType() {
- return memberCardType;
- }
-
- public void setMemberCardType(String memberCardType) {
- this.memberCardType = memberCardType;
- }
-
- public Double getMemberCardPrice() {
- return memberCardPrice;
- }
-
- public void setMemberCardPrice(Double memberCardPrice) {
- this.memberCardPrice = memberCardPrice;
- }
-
- public Integer getMemberCardValidityDays() {
- return memberCardValidityDays;
- }
-
- public void setMemberCardValidityDays(Integer memberCardValidityDays) {
- this.memberCardValidityDays = memberCardValidityDays;
- }
-
- public Integer getMemberCardTotalTimes() {
- return memberCardTotalTimes;
- }
-
- public void setMemberCardTotalTimes(Integer memberCardTotalTimes) {
- this.memberCardTotalTimes = memberCardTotalTimes;
- }
-
- public Double getMemberCardAmount() {
- return memberCardAmount;
- }
-
- public void setMemberCardAmount(Double memberCardAmount) {
- this.memberCardAmount = memberCardAmount;
- }
-
- public Integer getMemberCardStatus() {
- return memberCardStatus;
- }
-
- public void setMemberCardStatus(Integer memberCardStatus) {
- this.memberCardStatus = memberCardStatus;
- }
-
- public LocalDateTime getMemberCardCreateTime() {
- return memberCardCreateTime;
- }
-
- public void setMemberCardCreateTime(LocalDateTime memberCardCreateTime) {
- this.memberCardCreateTime = memberCardCreateTime;
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/entity/MemberCardRecordEntity.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/entity/MemberCardRecordEntity.java
deleted file mode 100644
index a601f43..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/entity/MemberCardRecordEntity.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.entity;
-
-import cn.novalon.gym.manage.db.entity.BaseEntity;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardRecordStatus;
-import lombok.Data;
-import org.springframework.data.relational.core.mapping.Column;
-import org.springframework.data.relational.core.mapping.Table;
-
-import java.time.LocalDateTime;
-
-/*
- *@Author:shizhounian
- *@Date:2026/5/10-05 22:47:31
- */
-@Table("member_card_record")
-public class MemberCardRecordEntity extends BaseEntity {
- //会员持有卡id
- @Column("member_card_record_id")
- private Long memberCardRecordId;
-
- //会员Id
- @Column("member_id")
- private Long memberId;
-
- //关联会员卡Id
- @Column("member_card_id")
- private Long memberCardId;
-
- //状态:ACTIVE(有效) / USED_UP(用完) / EXPIRED(过期) / REFUNDED(已退款)
- @Column("status")
- private MemberCardRecordStatus status;
-
- //剩余次数
- @Column("remaining_times")
- private Integer remainingTimes;
-
- //剩余余额
- @Column("remaining_amount")
- private Double remainingAmount;
-
- //到期时间
- @Column("expire_time")
- private LocalDateTime expireTime;
-
- //购买订单Id
- @Column("source_order_id")
- private Long sourceOrderId;
-
- //购买时间
- @Column("purchase_time")
- private LocalDateTime purchaseTime;
-
- public Long getMemberCardRecordId() {
- return memberCardRecordId;
- }
-
- public void setMemberCardRecordId(Long memberCardRecordId) {
- this.memberCardRecordId = memberCardRecordId;
- }
-
- public Long getMemberId() {
- return memberId;
- }
-
- public void setMemberId(Long memberId) {
- this.memberId = memberId;
- }
-
- public Long getMemberCardId() {
- return memberCardId;
- }
-
- public void setMemberCardId(Long memberCardId) {
- this.memberCardId = memberCardId;
- }
-
- public MemberCardRecordStatus getStatus() {
- return status;
- }
-
- public void setStatus(MemberCardRecordStatus status) {
- this.status = status;
- }
-
- public Integer getRemainingTimes() {
- return remainingTimes;
- }
-
- public void setRemainingTimes(Integer remainingTimes) {
- this.remainingTimes = remainingTimes;
- }
-
- public Double getRemainingAmount() {
- return remainingAmount;
- }
-
- public void setRemainingAmount(Double remainingAmount) {
- this.remainingAmount = remainingAmount;
- }
-
- public LocalDateTime getExpireTime() {
- return expireTime;
- }
-
- public void setExpireTime(LocalDateTime expireTime) {
- this.expireTime = expireTime;
- }
-
- public Long getSourceOrderId() {
- return sourceOrderId;
- }
-
- public void setSourceOrderId(Long sourceOrderId) {
- this.sourceOrderId = sourceOrderId;
- }
-
- public LocalDateTime getPurchaseTime() {
- return purchaseTime;
- }
-
- public void setPurchaseTime(LocalDateTime purchaseTime) {
- this.purchaseTime = purchaseTime;
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/entity/MemberCardTransactionsEntity.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/entity/MemberCardTransactionsEntity.java
deleted file mode 100644
index 1aedaea..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/entity/MemberCardTransactionsEntity.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.entity;
-
-import cn.novalon.gym.manage.db.entity.BaseEntity;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsAction;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsType;
-import org.springframework.data.relational.core.mapping.Column;
-import org.springframework.data.relational.core.mapping.Table;
-
-import java.time.LocalDateTime;
-
-/*
- *@Author:shizhounian
- *@Date:2026/5/10-05 22:47:31
- */
-@Table("member_card_transactions")
-public class MemberCardTransactionsEntity extends BaseEntity{
-
- @Column("id")
- private Long id;
-
- @Column("member_card_record_id")
- private Long memberCardRecordId;
-
- @Column("member_id")
- private Long memberId;
-
- @Column("member_card_id")
- private Long memberCardId;
-
- @Column("operation_type")
- private MemberCardTransactionsAction operationType;
-
- @Column("change_amount")
- private Integer changeAmount;
-
- @Column("change_balance")
- private Double changeBalance;
-
- @Column("after_remaining_count")
- private Integer afterRemainingCount;
-
- @Column("after_remaining_balance")
- private Double afterRemainingBalance;
-
- @Column("related_biz_type")
- private MemberCardTransactionsType relatedBizType;
-
- @Column("source_order_id")
- private Long sourceOrderId;
-
- @Column("remark")
- private String remark;
-
- @Column("created_at")
- private LocalDateTime createdAt;
-
- public Long getId() {
- return id;
- }
-
- public void setId(Long id) {
- this.id = id;
- }
-
- public Long getMemberCardRecordId() {
- return memberCardRecordId;
- }
-
- public void setMemberCardRecordId(Long memberCardRecordId) {
- this.memberCardRecordId = memberCardRecordId;
- }
-
- public Long getMemberId() {
- return memberId;
- }
-
- public void setMemberId(Long memberId) {
- this.memberId = memberId;
- }
-
- public Long getMemberCardId() {
- return memberCardId;
- }
-
- public void setMemberCardId(Long memberCardId) {
- this.memberCardId = memberCardId;
- }
-
- public MemberCardTransactionsAction getOperationType() {
- return operationType;
- }
-
- public void setOperationType(MemberCardTransactionsAction operationType) {
- this.operationType = operationType;
- }
-
- public Integer getChangeAmount() {
- return changeAmount;
- }
-
- public void setChangeAmount(Integer changeAmount) {
- this.changeAmount = changeAmount;
- }
-
- public Double getChangeBalance() {
- return changeBalance;
- }
-
- public void setChangeBalance(Double changeBalance) {
- this.changeBalance = changeBalance;
- }
-
- public Integer getAfterRemainingCount() {
- return afterRemainingCount;
- }
-
- public void setAfterRemainingCount(Integer afterRemainingCount) {
- this.afterRemainingCount = afterRemainingCount;
- }
-
- public Double getAfterRemainingBalance() {
- return afterRemainingBalance;
- }
-
- public void setAfterRemainingBalance(Double afterRemainingBalance) {
- this.afterRemainingBalance = afterRemainingBalance;
- }
-
- public MemberCardTransactionsType getRelatedBizType() {
- return relatedBizType;
- }
-
- public void setRelatedBizType(MemberCardTransactionsType relatedBizType) {
- this.relatedBizType = relatedBizType;
- }
-
- public Long getSourceOrderId() {
- return sourceOrderId;
- }
-
- public void setSourceOrderId(Long sourceOrderId) {
- this.sourceOrderId = sourceOrderId;
- }
-
- public String getRemark() {
- return remark;
- }
-
- public void setRemark(String remark) {
- this.remark = remark;
- }
-
- public LocalDateTime getCreatedAt() {
- return createdAt;
- }
-
- public void setCreatedAt(LocalDateTime createdAt) {
- this.createdAt = createdAt;
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/entity/RefundApplicationEntity.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/entity/RefundApplicationEntity.java
deleted file mode 100644
index 49fd781..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/entity/RefundApplicationEntity.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.entity;
-
-import cn.novalon.gym.manage.db.entity.BaseEntity;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
-/**
- * 退款申请实体类
- *
- * @author shizhounian
- * @date 2026-05-23 21:09:14
- */
-@Schema(description = "退款申请实体", example = "refund_application")
-public class RefundApplicationEntity extends BaseEntity {
-
- @Schema(description = "退款申请ID", example = "1")
- private Long id;
-
- @Schema(description = "会员卡记录ID", example = "1")
- private Long recordId;
-
- @Schema(description = "会员ID", example = "1")
- private Long memberId;
-
- @Schema(description = "状态:PENDING-待审核, APPROVED-已批准, REJECTED-已拒绝, PROCESSING-处理中, SUCCESS-成功, FAILED-失败", example = "PENDING")
- private String status;
-
- @Schema(description = "退款原因", example = "个人原因申请退款")
- private String reason;
-
- @Schema(description = "申请时间", example = "2026-05-23 21:09:14")
- private LocalDateTime applyTime;
-
- @Schema(description = "审核时间", example = "2026-05-24 10:00:00")
- private LocalDateTime auditTime;
-
- @Schema(description = "审核人ID", example = "1")
- private Long auditorId;
-
- @Schema(description = "审核备注", example = "同意退款")
- private String auditRemark;
-
- @Schema(description = "退款金额", example = "500.00")
- private BigDecimal refundAmount;
-
- public Long getId() {
- return id;
- }
-
- public void setId(Long id) {
- this.id = id;
- }
-
- public Long getRecordId() {
- return recordId;
- }
-
- public void setRecordId(Long recordId) {
- this.recordId = recordId;
- }
-
- public Long getMemberId() {
- return memberId;
- }
-
- public void setMemberId(Long memberId) {
- this.memberId = memberId;
- }
-
- public String getStatus() {
- return status;
- }
-
- public void setStatus(String status) {
- this.status = status;
- }
-
- public String getReason() {
- return reason;
- }
-
- public void setReason(String reason) {
- this.reason = reason;
- }
-
- public LocalDateTime getApplyTime() {
- return applyTime;
- }
-
- public void setApplyTime(LocalDateTime applyTime) {
- this.applyTime = applyTime;
- }
-
- public LocalDateTime getAuditTime() {
- return auditTime;
- }
-
- public void setAuditTime(LocalDateTime auditTime) {
- this.auditTime = auditTime;
- }
-
- public Long getAuditorId() {
- return auditorId;
- }
-
- public void setAuditorId(Long auditorId) {
- this.auditorId = auditorId;
- }
-
- public String getAuditRemark() {
- return auditRemark;
- }
-
- public void setAuditRemark(String auditRemark) {
- this.auditRemark = auditRemark;
- }
-
- public BigDecimal getRefundAmount() {
- return refundAmount;
- }
-
- public void setRefundAmount(BigDecimal refundAmount) {
- this.refundAmount = refundAmount;
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardEvent.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardEvent.java
deleted file mode 100644
index 42e8094..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardEvent.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.enums;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-
-@Schema(description = "会员卡状态机事件")
-public enum MemberCardEvent {
- @Schema(description = "激活卡片")
- ACTIVATE("激活卡片"),
-
- @Schema(description = "使用卡片")
- USE("使用卡片"),
-
- @Schema(description = "续费")
- RENEW("续费"),
-
- @Schema(description = "过期")
- EXPIRE("过期"),
-
- @Schema(description = "退款")
- REFUND("退款"),
-
- @Schema(description = "禁用")
- DISABLE("禁用");
-
- private final String desc;
-
- MemberCardEvent(String desc) {
- this.desc = desc;
- }
-
- public String getDesc() {
- return desc;
- }
-}
\ No newline at end of file
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardRecordStatus.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardRecordStatus.java
deleted file mode 100644
index b4fb006..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardRecordStatus.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.enums;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-
-/*
- *@Author:shizhounian
- *@Date:2026/5/10-05 23:59:29
- */
-@Schema(description = "会员卡状态枚举")
-public enum MemberCardRecordStatus {
- //有效
- @Schema(description = "有效")
- ACTIVE("有效"),
-
- //用完
- @Schema(description = "用完")
- USED_UP("用完"),
-
- //过期
- @Schema(description = "过期")
- EXPIRED("过期"),
-
- //已退款
- @Schema(description = "已退款")
- REFUNDED("已退款");
-
- private final String desc;
-
- MemberCardRecordStatus(String desc) {
- this.desc = desc;
- }
-
- public String getDesc() {
- return desc;
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardTransactionsAction.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardTransactionsAction.java
deleted file mode 100644
index 6be4fc0..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardTransactionsAction.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.enums;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-
-/*
- *@Author:shizhounian
- *@Date:2026/5/10-05 23:59:29
- */
-@Schema(description = "会员卡流水操作枚举")
-public enum MemberCardTransactionsAction {
- //购买
- @Schema(description = "购买")
- PURCHASE("购买"),
-
- //扣次/扣费
- @Schema(description = "扣次/扣费")
- DEDUCT("扣次/扣费"),
-
- //续费
- @Schema(description = "续费")
- RENEW("续费"),
-
- //退款
- @Schema(description = "退款")
- REFUND("退款"),
-
- //过期
- @Schema(description = "过期")
- EXPIRE("过期");
-
- private final String desc;
-
- MemberCardTransactionsAction(String desc) {
- this.desc = desc;
- }
-
- public String getDesc() {
- return desc;
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardTransactionsType.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardTransactionsType.java
deleted file mode 100644
index ae55fe9..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardTransactionsType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.enums;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-
-/*
- *@Author:shizhounian
- *@Date:2026/5/10-05 23:59:29
- */
-@Schema(description = "会员卡流水关联业务类型枚举")
-public enum MemberCardTransactionsType {
- //团课
- @Schema(description = "团课")
- GROUP_CLASS("团课"),
-
- //私教
- @Schema(description = "私教")
- PT_CLASS("私教"),
-
- //签到
- @Schema(description = "签到")
- CHECK_IN("签到");
-
- private final String desc;
-
- MemberCardTransactionsType(String desc) {
- this.desc = desc;
- }
-
- public String getDesc() {
- return desc;
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/IMemberCardRecordRepository.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/IMemberCardRecordRepository.java
deleted file mode 100644
index 6cafcde..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/IMemberCardRecordRepository.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.repository;
-
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardRecord;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardRecordStatus;
-import org.springframework.data.domain.Pageable;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-public interface IMemberCardRecordRepository {
-
- Mono findById(Long id);
-
- Mono save(MemberCardRecord record);
-
- Mono insertActiveRecord(MemberCardRecord record);
-
- Flux findByMemberId(Long memberId, Pageable pageable);
-
- Flux findActiveCardsByMemberId(Long memberId);
-
- Flux findActiveRecords();
-
- Mono updateStatus(Long id, MemberCardRecordStatus status);
-
- Mono deductUsage(Long recordId, Integer deductTimes, Double deductAmount);
-
- Mono renewCard(Long recordId, Integer addTimes, Double addAmount, java.time.LocalDateTime newExpireTime);
-
- Flux findExpiredCards();
-
- Mono validateCountCard(Long recordId, Integer requiredTimes);
-
- Mono validateStoredCard(Long recordId, Double requiredAmount);
-}
\ No newline at end of file
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/IMemberCardRepository.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/IMemberCardRepository.java
deleted file mode 100644
index 8b24397..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/IMemberCardRepository.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.repository;
-
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCard;
-import org.springframework.data.domain.Pageable;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-public interface IMemberCardRepository {
- /**
- * 根据会员卡ID查询会员卡详情(用于编辑前回显或小程序端展示)
- * @param memberCardId 会员卡ID
- * @return 会员卡完整信息,如果不存在或已删除则返回空
- */
- Mono findByMemberCardIdAndDeletedAtIsNull(Long memberCardId);
-
- /**
- * 条件查询会员卡列表(后台卡种列表展示,支持多条件组合+分页+排序)
- * @param status 会员卡状态(上架/下架)
- * @param name 会员卡名称(模糊查询)
- * @param type 会员卡类型
- * @param minPrice 最低价格
- * @param maxPrice 最高价格
- * @param pageable 分页和排序参数
- * @return 符合条件的会员卡列表
- */
- Flux findWithConditions(Integer status, String name, String type,
- Double minPrice, Double maxPrice, Pageable pageable);
-
- /**
- * 统计符合条件的会员卡总数(配合列表查询使用)
- * @param status 会员卡状态
- * @param name 会员卡名称(模糊查询)
- * @param type 会员卡类型
- * @param minPrice 最低价格
- * @param maxPrice 最高价格
- * @return 符合条件的会员卡数量
- */
- Mono countWithConditions(Integer status, String name, String type,
- Double minPrice, Double maxPrice);
-
- /**
- * 按状态查询会员卡列表(用于小程序端展示可购买卡列表,只展示上架的卡)
- * @param status 会员卡状态(通常传上架状态)
- * @param pageable 分页和排序参数
- * @return 符合条件的会员卡列表
- */
- Flux findByMemberCardStatusAndDeletedAtIsNull(Integer status, Pageable pageable);
-
- /**
- * 检查会员卡是否已被购买(用于删除前的校验)
- * @param memberCardId 会员卡ID
- * @return 如果存在关联的会员记录则返回true,否则返回false
- */
- Mono existsPurchasedRecord(Long memberCardId);
-
- /**
- * 逻辑删除会员卡(下架卡种,防止已购会员数据异常)
- * @param memberCardId 会员卡ID
- * @return 受影响的行数
- */
- Mono logicalDelete(Long memberCardId);
-
- /**
- * 保存卡种信息(新增或更新)
- * - 新增:entity.memberCardId 为 null 时,插入新记录
- * - 更新:entity.memberCardId 不为 null 时,根据ID更新现有记录
- * @param entity 卡种信息
- * @return 保存后的实体对象
- */
- Mono save(MemberCard entity);
-
- /**
- * 批量查询上架的会员卡(用于小程序端展示)
- * @param status 上架状态值
- * @return 上架的会员卡列表
- */
- Flux findActiveCards(Integer status);
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/IMemberCardTransactionsRepository.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/IMemberCardTransactionsRepository.java
deleted file mode 100644
index 46ff531..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/IMemberCardTransactionsRepository.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.repository;
-
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardTransactions;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsAction;
-import org.springframework.data.domain.Pageable;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-import java.time.LocalDateTime;
-
-public interface IMemberCardTransactionsRepository {
-
- /**
- * 记录每一次变动
- * @param transactions 流水记录
- * @return 插入的流水记录
- */
- Mono insertTransaction(MemberCardTransactions transactions);
-
- /**
- * 会员端"使用记录"
- * @param memberId 会员ID
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @param pageable 分页参数
- * @return 流水记录列表
- */
- Flux findByMemberIdAndTimeRange(Long memberId, LocalDateTime startTime,
- LocalDateTime endTime, Pageable pageable);
-
- /**
- * 后台"使用记录查询"
- * @param memberId 会员ID
- * @param memberCardId 会员卡ID
- * @param operationType 操作类型
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @param pageable 分页参数
- * @return 流水记录列表
- */
- Flux findWithConditions(Long memberId, Long memberCardId,
- MemberCardTransactionsAction operationType,
- LocalDateTime startTime, LocalDateTime endTime,
- Pageable pageable);
-
- /**
- * 统计符合条件的流水总数
- * @param memberId 会员ID
- * @param memberCardId 会员卡ID
- * @param operationType 操作类型
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 流水记录数量
- */
- Mono countWithConditions(Long memberId, Long memberCardId,
- MemberCardTransactionsAction operationType,
- LocalDateTime startTime, LocalDateTime endTime);
-
- /**
- * 按会员卡ID查询所有流水记录
- * @param memberCardId 会员卡ID
- * @return 该卡的所有流水记录,按时间倒序
- */
- Flux findByMemberCardId(Long memberCardId);
-
- /**
- * 数据统计 - 统计某卡种的总扣次数
- * @param memberCardId 会员卡ID
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 总扣次数
- */
- Mono sumDeductCountByCardId(Long memberCardId, LocalDateTime startTime, LocalDateTime endTime);
-
- /**
- * 数据统计 - 统计某时间段的续费总金额
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 续费总金额
- */
- Mono sumRenewAmountByTimeRange(LocalDateTime startTime, LocalDateTime endTime);
-
- /**
- * 数据统计 - 统计某会员的购卡总金额
- * @param memberId 会员ID
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 购卡总金额
- */
- Mono sumPurchaseAmountByMemberId(Long memberId, LocalDateTime startTime, LocalDateTime endTime);
-
- /**
- * 保存流水记录
- * @param transaction 流水记录
- * @return 保存后的流水记录
- */
- Mono save(MemberCardTransactions transaction);
-
- /**
- * 按会员ID查询所有流水记录
- * @param memberId 会员ID
- * @return 该会员的所有流水记录,按时间倒序
- */
- Flux findByMemberId(Long memberId);
-
- /**
- * 按流水ID查询流水记录
- * @param recordId 流水ID
- * @return 该流水记录
- */
- Flux findByRecordId(Long recordId);
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/IRefundApplicationRepository.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/IRefundApplicationRepository.java
deleted file mode 100644
index 931b1fc..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/IRefundApplicationRepository.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.repository;
-
-import cn.novalon.gym.manage.gymmembercard.domain.RefundApplication;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * 退款申请仓储接口
- *
- * @author shizhounian
- * @date 2026-05-23
- */
-public interface IRefundApplicationRepository {
-
- /**
- * 创建退款申请
- *
- * @param application 退款申请对象
- * @return 创建后的退款申请
- */
- Mono create(RefundApplication application);
-
- /**
- * 根据ID查询退款申请
- *
- * @param id 退款申请ID
- * @return 退款申请对象
- */
- Mono findById(Long id);
-
- /**
- * 根据会员卡记录ID查询退款申请
- *
- * @param recordId 会员卡记录ID
- * @return 退款申请对象
- */
- Mono findByRecordId(Long recordId);
-
- /**
- * 根据会员ID查询退款申请列表
- *
- * @param memberId 会员ID
- * @return 退款申请列表
- */
- Flux findByMemberId(Long memberId);
-
- /**
- * 根据状态查询退款申请列表
- *
- * @param status 状态
- * @return 退款申请列表
- */
- Flux findByStatus(String status);
-
- /**
- * 更新退款申请
- *
- * @param application 退款申请对象
- * @return 更新后的退款申请
- */
- Mono update(RefundApplication application);
-
- /**
- * 审核退款申请
- *
- * @param id 退款申请ID
- * @param status 审核状态(APPROVED/REJECTED)
- * @param auditorId 审核人ID
- * @param auditRemark 审核备注
- * @return 更新后的退款申请
- */
- Mono approve(Long id, String status, Long auditorId, String auditRemark);
-
- /**
- * 删除退款申请(逻辑删除)
- *
- * @param id 退款申请ID
- * @return 受影响的行数
- */
- Mono delete(Long id);
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/impl/MemberCardRecordRepositoryImpl.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/impl/MemberCardRecordRepositoryImpl.java
deleted file mode 100644
index 30406e5..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/impl/MemberCardRecordRepositoryImpl.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.repository.impl;
-
-import cn.novalon.gym.manage.gymmembercard.dao.MemberCardRecordDao;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardRecord;
-import cn.novalon.gym.manage.gymmembercard.entity.MemberCardRecordEntity;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardRecordStatus;
-import cn.novalon.gym.manage.gymmembercard.repository.IMemberCardRecordRepository;
-import cn.novalon.gym.manage.gymmembercard.util.BeanConvertUtil;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
-import org.springframework.stereotype.Repository;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-@Repository
-public class MemberCardRecordRepositoryImpl implements IMemberCardRecordRepository {
- private final MemberCardRecordDao memberCardRecordDao;
- private final BeanConvertUtil beanConvertUtil;
- private final R2dbcEntityTemplate r2dbcEntityTemplate;
-
- public MemberCardRecordRepositoryImpl(MemberCardRecordDao memberCardRecordDao,
- BeanConvertUtil beanConvertUtil,
- R2dbcEntityTemplate r2dbcEntityTemplate) {
- this.memberCardRecordDao = memberCardRecordDao;
- this.beanConvertUtil = beanConvertUtil;
- this.r2dbcEntityTemplate = r2dbcEntityTemplate;
- }
-
- @Override
- public Mono findById(Long id) {
- return memberCardRecordDao.findById(id)
- .map(e -> beanConvertUtil.toBean(e, MemberCardRecord.class));
- }
-
- @Override
- public Mono save(MemberCardRecord record) {
- MemberCardRecordEntity entity = beanConvertUtil.toBean(record, MemberCardRecordEntity.class);
- return memberCardRecordDao.save(entity)
- .map(e -> beanConvertUtil.toBean(e, MemberCardRecord.class));
- }
-
- @Override
- public Mono insertActiveRecord(MemberCardRecord record) {
- MemberCardRecordEntity entity = beanConvertUtil.toBean(record, MemberCardRecordEntity.class);
- return memberCardRecordDao.insertActiveRecord(
- entity.getMemberId(),
- entity.getMemberCardId(),
- entity.getExpireTime(),
- entity.getRemainingTimes(),
- entity.getRemainingAmount(),
- entity.getSourceOrderId())
- .map(e -> beanConvertUtil.toBean(e, MemberCardRecord.class));
- }
-
- @Override
- public Flux findByMemberId(Long memberId, Pageable pageable) {
- return memberCardRecordDao.findByMemberId(memberId, pageable)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCardRecord.class));
- }
-
- @Override
- public Flux findActiveCardsByMemberId(Long memberId) {
- return memberCardRecordDao.findActiveCardsByMemberId(memberId)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCardRecord.class));
- }
-
- @Override
- public Flux findActiveRecords() {
- return memberCardRecordDao.findActiveRecords()
- .map(entity -> beanConvertUtil.toBean(entity, MemberCardRecord.class));
- }
-
- @Override
- public Mono updateStatus(Long id, MemberCardRecordStatus status) {
- return memberCardRecordDao.updateStatus(id, status);
- }
-
- @Override
- public Mono deductUsage(Long recordId, Integer deductTimes, Double deductAmount) {
- return memberCardRecordDao.deductUsage(recordId, deductTimes, deductAmount);
- }
-
- @Override
- public Mono renewCard(Long recordId, Integer addTimes, Double addAmount, java.time.LocalDateTime newExpireTime) {
- return memberCardRecordDao.renewCard(recordId, addTimes, addAmount, newExpireTime);
- }
-
- @Override
- public Flux findExpiredCards() {
- return memberCardRecordDao.findExpiredCards()
- .map(e -> beanConvertUtil.toBean(e, MemberCardRecord.class));
- }
-
- @Override
- public Mono validateCountCard(Long recordId, Integer requiredTimes) {
- return memberCardRecordDao.validateCountCard(recordId, requiredTimes)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCardRecord.class));
- }
-
- @Override
- public Mono validateStoredCard(Long recordId, Double requiredAmount) {
- return memberCardRecordDao.validateStoredCard(recordId, requiredAmount)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCardRecord.class));
- }
-}
\ No newline at end of file
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/impl/MemberCardRepositoryImpl.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/impl/MemberCardRepositoryImpl.java
deleted file mode 100644
index afc3f97..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/impl/MemberCardRepositoryImpl.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.repository.impl;
-
-import cn.novalon.gym.manage.gymmembercard.dao.MemberCardDao;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCard;
-import cn.novalon.gym.manage.gymmembercard.entity.MemberCardEntity;
-import cn.novalon.gym.manage.gymmembercard.repository.IMemberCardRepository;
-import cn.novalon.gym.manage.gymmembercard.util.BeanConvertUtil;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
-import org.springframework.stereotype.Repository;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-@Repository
-public class MemberCardRepositoryImpl implements IMemberCardRepository {
- private final MemberCardDao memberCardDao;
- private final BeanConvertUtil beanConvertUtil;
- private final R2dbcEntityTemplate r2dbcEntityTemplate;
- //构造函数,初始化
- public MemberCardRepositoryImpl(MemberCardDao memberCardDao, BeanConvertUtil beanConvertUtil, R2dbcEntityTemplate r2dbcEntityTemplate) {
- this.memberCardDao = memberCardDao;
- this.beanConvertUtil = beanConvertUtil;
- this.r2dbcEntityTemplate = r2dbcEntityTemplate;
- }
-
- /**
- * 根据会员卡ID查询会员卡详情(用于编辑前回显或小程序端展示)
- * @param memberCardId 会员卡ID
- * @return 会员卡完整信息,如果不存在或已删除则返回空
- */
- @Override
- public Mono findByMemberCardIdAndDeletedAtIsNull(Long memberCardId) {
- return memberCardDao.findByMemberCardIdAndDeletedAtIsNull(memberCardId)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCard.class));
- }
-
- /**
- * 条件查询会员卡列表(后台卡种列表展示,支持多条件组合+分页+排序)
- * @param status 会员卡状态(上架/下架)
- * @param name 会员卡名称(模糊查询)
- * @param type 会员卡类型
- * @param minPrice 最低价格
- * @param maxPrice 最高价格
- * @param pageable 分页和排序参数
- * @return 符合条件的会员卡列表
- */
- @Override
- public Flux findWithConditions(Integer status, String name, String type,
- Double minPrice, Double maxPrice, Pageable pageable) {
- return memberCardDao.findWithConditions(status, name, type, minPrice, maxPrice, pageable)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCard.class));
- }
-
- /**
- * 统计符合条件的会员卡总数(配合列表查询使用)
- * @param status 会员卡状态
- * @param name 会员卡名称(模糊查询)
- * @param type 会员卡类型
- * @param minPrice 最低价格
- * @param maxPrice 最高价格
- * @return 符合条件的会员卡数量
- */
- @Override
- public Mono countWithConditions(Integer status, String name, String type,
- Double minPrice, Double maxPrice) {
- return memberCardDao.countWithConditions(status, name, type, minPrice, maxPrice);
- }
-
- /**
- * 按状态查询会员卡列表(用于小程序端展示可购买卡列表,只展示上架的卡)
- * @param status 会员卡状态(通常传上架状态)
- * @param pageable 分页和排序参数
- * @return 符合条件的会员卡列表
- */
- @Override
- public Flux findByMemberCardStatusAndDeletedAtIsNull(Integer status, Pageable pageable) {
- return memberCardDao.findByMemberCardStatusAndDeletedAtIsNull(status, pageable)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCard.class));
- }
-
- /**
- * 检查会员卡是否已被购买(用于删除前的校验)
- * @param memberCardId 会员卡ID
- * @return 如果存在关联的会员记录则返回true,否则返回false
- */
- @Override
- public Mono existsPurchasedRecord(Long memberCardId) {
- return memberCardDao.existsPurchasedRecord(memberCardId);
- }
-
- /**
- * 逻辑删除会员卡(下架卡种,防止已购会员数据异常)
- * @param memberCardId 会员卡ID
- * @return 受影响的行数
- */
- @Override
- public Mono logicalDelete(Long memberCardId) {
- return memberCardDao.logicalDelete(memberCardId);
- }
-
- /**
- * 安全更新会员卡信息(不覆盖不允许修改的字段)
- * @param memberCardId 会员卡ID
- * @param updateData 需要更新的卡种信息
- * @return 受影响的行数
- */
- public Mono updateSafe(Long memberCardId, MemberCard updateData) {
- MemberCardEntity memberCardEntity = beanConvertUtil.toBean(updateData, MemberCardEntity.class);
- return memberCardDao.updateSafe(
- memberCardId,
- memberCardEntity.getMemberCardName(),
- memberCardEntity.getMemberCardPrice(),
- memberCardEntity.getMemberCardValidityDays(),
- memberCardEntity.getMemberCardTotalTimes(),
- memberCardEntity.getMemberCardAmount(),
- memberCardEntity.getMemberCardStatus()
- );
- }
-
-
- /**
- * 保存卡种信息(新增或更新)
- * - 新增:entity.memberCardId 为 null 时,插入新记录
- * - 更新:entity.memberCardId 不为 null 时,根据ID更新现有记录
- * 建议:更新时优先使用 updateSafe 方法避免全字段覆盖
- * @param entity 卡种信息
- * @return 保存后的实体对象
- */
- @Override
- public Mono save(MemberCard entity) {
- MemberCardEntity cardEntity = beanConvertUtil.toBean(entity, MemberCardEntity.class);
- return memberCardDao.save(cardEntity)
- .map(savedEntity -> beanConvertUtil.toBean(savedEntity, MemberCard.class));
- }
-
- /**
- * 批量查询上架的会员卡(用于小程序端展示)
- * @param status 上架状态值
- * @return 上架的会员卡列表
- */
- @Override
- public Flux findActiveCards(Integer status) {
- return memberCardDao.findActiveCards(status)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCard.class));
- }
-}
\ No newline at end of file
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/impl/MemberCardTransactionsRepositoryImpl.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/impl/MemberCardTransactionsRepositoryImpl.java
deleted file mode 100644
index 4afecbd..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/impl/MemberCardTransactionsRepositoryImpl.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.repository.impl;
-
-import cn.novalon.gym.manage.gymmembercard.dao.MemberCardTransactionsDao;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardTransactions;
-import cn.novalon.gym.manage.gymmembercard.entity.MemberCardTransactionsEntity;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsAction;
-import cn.novalon.gym.manage.gymmembercard.repository.IMemberCardTransactionsRepository;
-import cn.novalon.gym.manage.gymmembercard.util.BeanConvertUtil;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
-import org.springframework.stereotype.Repository;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-import java.time.LocalDateTime;
-
-@Repository
-public class MemberCardTransactionsRepositoryImpl implements IMemberCardTransactionsRepository {
- private final MemberCardTransactionsDao memberCardTransactionsDao;
- private final BeanConvertUtil beanConvertUtil;
- private final R2dbcEntityTemplate r2dbcEntityTemplate;
-
- public MemberCardTransactionsRepositoryImpl(MemberCardTransactionsDao memberCardTransactionsDao, BeanConvertUtil beanConvertUtil, R2dbcEntityTemplate r2dbcEntityTemplate) {
- this.memberCardTransactionsDao = memberCardTransactionsDao;
- this.beanConvertUtil = beanConvertUtil;
- this.r2dbcEntityTemplate = r2dbcEntityTemplate;
- }
-
- /**
- * 记录每一次变动
- * @param transactions 流水记录
- * @return 插入的流水记录
- */
- @Override
- public Mono insertTransaction(MemberCardTransactions transactions) {
- MemberCardTransactionsEntity entity = beanConvertUtil.toBean(transactions, MemberCardTransactionsEntity.class);
- return memberCardTransactionsDao.insertTransaction(
- entity.getMemberCardId(),
- entity.getMemberId(),
- entity.getOperationType(),
- entity.getChangeAmount(),
- entity.getChangeBalance(),
- entity.getAfterRemainingCount(),
- entity.getAfterRemainingBalance(),
- entity.getRelatedBizType(),
- entity.getRemark())
- .map(e -> beanConvertUtil.toBean(e, MemberCardTransactions.class));
- }
-
- /**
- * 会员端"使用记录"
- * @param memberId 会员ID
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @param pageable 分页参数
- * @return 流水记录列表
- */
- @Override
- public Flux findByMemberIdAndTimeRange(Long memberId, LocalDateTime startTime,
- LocalDateTime endTime, Pageable pageable) {
- return memberCardTransactionsDao.findByMemberIdAndTimeRange(memberId, startTime, endTime, pageable)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCardTransactions.class));
- }
-
- /**
- * 后台"使用记录查询"
- * @param memberId 会员ID
- * @param memberCardId 会员卡ID
- * @param operationType 操作类型
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @param pageable 分页参数
- * @return 流水记录列表
- */
- @Override
- public Flux findWithConditions(Long memberId, Long memberCardId,
- MemberCardTransactionsAction operationType,
- LocalDateTime startTime, LocalDateTime endTime,
- Pageable pageable) {
- return memberCardTransactionsDao.findWithConditions(memberId, memberCardId, operationType,
- startTime, endTime, pageable)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCardTransactions.class));
- }
-
- /**
- * 统计符合条件的流水总数
- * @param memberId 会员ID
- * @param memberCardId 会员卡ID
- * @param operationType 操作类型
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 流水记录数量
- */
- @Override
- public Mono countWithConditions(Long memberId, Long memberCardId,
- MemberCardTransactionsAction operationType,
- LocalDateTime startTime, LocalDateTime endTime) {
- return memberCardTransactionsDao.countWithConditions(memberId, memberCardId,
- operationType, startTime, endTime);
- }
-
- /**
- * 按会员卡ID查询所有流水记录
- * @param memberCardId 会员卡ID
- * @return 该卡的所有流水记录,按时间倒序
- */
- @Override
- public Flux findByMemberCardId(Long memberCardId) {
- return memberCardTransactionsDao.findByMemberCardId(memberCardId)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCardTransactions.class));
- }
-
- /**
- * 数据统计 - 统计某卡种的总扣次数
- * @param memberCardId 会员卡ID
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 总扣次数
- */
- @Override
- public Mono sumDeductCountByCardId(Long memberCardId, LocalDateTime startTime, LocalDateTime endTime) {
- return memberCardTransactionsDao.sumDeductCountByCardId(memberCardId, startTime, endTime);
- }
-
- /**
- * 数据统计 - 统计某时间段的续费总金额
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 续费总金额
- */
- @Override
- public Mono sumRenewAmountByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
- return memberCardTransactionsDao.sumRenewAmountByTimeRange(startTime, endTime);
- }
-
- /**
- * 数据统计 - 统计某会员的购卡总金额
- * @param memberId 会员ID
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 购卡总金额
- */
- @Override
- public Mono sumPurchaseAmountByMemberId(Long memberId, LocalDateTime startTime, LocalDateTime endTime) {
- return memberCardTransactionsDao.sumPurchaseAmountByMemberId(memberId, startTime, endTime);
- }
- /**
- * 保存流水记录
- * @param transaction 流水记录
- * @return 保存后的流水记录
- */
- @Override
- public Mono save(MemberCardTransactions transaction) {
- MemberCardTransactionsEntity entity = beanConvertUtil.toBean(transaction, MemberCardTransactionsEntity.class);
- return memberCardTransactionsDao.save(entity)
- .map(savedEntity -> beanConvertUtil.toBean(savedEntity, MemberCardTransactions.class));
- }
-
- @Override
- public Flux findByMemberId(Long memberId) {
- return memberCardTransactionsDao.findByMemberId(memberId)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCardTransactions.class));
- }
-
- @Override
- public Flux findByRecordId(Long recordId) {
- return memberCardTransactionsDao.findByRecordId(recordId)
- .map(entity -> beanConvertUtil.toBean(entity, MemberCardTransactions.class));
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/impl/RefundApplicationRepositoryImpl.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/impl/RefundApplicationRepositoryImpl.java
deleted file mode 100644
index ca85d61..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/repository/impl/RefundApplicationRepositoryImpl.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.repository.impl;
-
-import cn.novalon.gym.manage.gymmembercard.dao.RefundApplicationDao;
-import cn.novalon.gym.manage.gymmembercard.domain.RefundApplication;
-import cn.novalon.gym.manage.gymmembercard.entity.RefundApplicationEntity;
-import cn.novalon.gym.manage.gymmembercard.repository.IRefundApplicationRepository;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Repository;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-import java.time.LocalDateTime;
-
-/**
- * 退款申请仓储实现类
- *
- * @author shizhounian
- * @date 2026-05-23 21:16:36
- */
-@Repository
-@RequiredArgsConstructor
-public class RefundApplicationRepositoryImpl implements IRefundApplicationRepository {
-
- private final RefundApplicationDao refundApplicationDao;
-
- @Override
- public Mono create(RefundApplication application) {
- RefundApplicationEntity entity = new RefundApplicationEntity();
- entity.setRecordId(application.getRecordId());
- entity.setMemberId(application.getMemberId());
- entity.setStatus(application.getStatus() != null ? application.getStatus() : "PENDING");
- entity.setReason(application.getReason());
- entity.setApplyTime(application.getApplyTime() != null ? application.getApplyTime() : LocalDateTime.now());
- entity.setRefundAmount(application.getRefundAmount());
-
- return refundApplicationDao.save(entity)
- .map(this::convertToDomain);
- }
-
- @Override
- public Mono findById(Long id) {
- return refundApplicationDao.findById(id)
- .map(this::convertToDomain);
- }
-
- @Override
- public Mono findByRecordId(Long recordId) {
- return refundApplicationDao.findByRecordId(recordId)
- .map(this::convertToDomain);
- }
-
- @Override
- public Flux findByMemberId(Long memberId) {
- return refundApplicationDao.findByMemberId(memberId)
- .map(this::convertToDomain);
- }
-
- @Override
- public Flux findByStatus(String status) {
- return refundApplicationDao.findByStatus(status)
- .map(this::convertToDomain);
- }
-
- @Override
- public Mono update(RefundApplication application) {
- return refundApplicationDao.findById(application.getId())
- .flatMap(entity -> {
- if (application.getStatus() != null) {
- entity.setStatus(application.getStatus());
- }
- if (application.getReason() != null) {
- entity.setReason(application.getReason());
- }
- if (application.getAuditTime() != null) {
- entity.setAuditTime(application.getAuditTime());
- }
- if (application.getAuditorId() != null) {
- entity.setAuditorId(application.getAuditorId());
- }
- if (application.getAuditRemark() != null) {
- entity.setAuditRemark(application.getAuditRemark());
- }
- if (application.getRefundAmount() != null) {
- entity.setRefundAmount(application.getRefundAmount());
- }
- return refundApplicationDao.save(entity);
- })
- .map(this::convertToDomain);
- }
-
- @Override
- public Mono approve(Long id, String status, Long auditorId, String auditRemark) {
- return refundApplicationDao.approve(id, status, auditorId, auditRemark)
- .flatMap(rows -> {
- if (rows > 0) {
- return refundApplicationDao.findById(id)
- .map(this::convertToDomain);
- }
- return Mono.empty();
- });
- }
-
- @Override
- public Mono delete(Long id) {
- return refundApplicationDao.logicalDelete(id);
- }
-
- /**
- * Entity转Domain
- */
- private RefundApplication convertToDomain(RefundApplicationEntity entity) {
- RefundApplication domain = new RefundApplication();
- domain.setId(entity.getId());
- domain.setRecordId(entity.getRecordId());
- domain.setMemberId(entity.getMemberId());
- domain.setStatus(entity.getStatus());
- domain.setReason(entity.getReason());
- domain.setApplyTime(entity.getApplyTime());
- domain.setAuditTime(entity.getAuditTime());
- domain.setAuditorId(entity.getAuditorId());
- domain.setAuditRemark(entity.getAuditRemark());
- domain.setRefundAmount(entity.getRefundAmount());
- return domain;
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/IMemberCardTransactionsService.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/IMemberCardTransactionsService.java
deleted file mode 100644
index 06b1bf2..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/IMemberCardTransactionsService.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.sevice;
-
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardTransactions;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsAction;
-import org.springframework.data.domain.Pageable;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-import java.time.LocalDateTime;
-
-public interface IMemberCardTransactionsService {
-
- /**
- * 记录每一次变动
- * @param transactions 流水记录
- * @return 插入的流水记录
- */
- Mono insertTransaction(MemberCardTransactions transactions);
-
- /**
- * 会员端"使用记录"
- * @param memberId 会员ID
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @param pageable 分页参数
- * @return 流水记录列表
- */
- Flux findByMemberIdAndTimeRange(Long memberId, LocalDateTime startTime,
- LocalDateTime endTime, Pageable pageable);
-
- /**
- * 后台"使用记录查询"
- * @param memberId 会员ID
- * @param memberCardId 会员卡ID
- * @param operationType 操作类型
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @param pageable 分页参数
- * @return 流水记录列表
- */
- Flux findWithConditions(Long memberId, Long memberCardId,
- MemberCardTransactionsAction operationType,
- LocalDateTime startTime, LocalDateTime endTime,
- Pageable pageable);
-
- /**
- * 统计符合条件的流水总数
- * @param memberId 会员ID
- * @param memberCardId 会员卡ID
- * @param operationType 操作类型
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 流水记录数量
- */
- Mono countWithConditions(Long memberId, Long memberCardId,
- MemberCardTransactionsAction operationType,
- LocalDateTime startTime, LocalDateTime endTime);
-
- /**
- * 按会员卡ID查询所有流水记录
- * @param memberCardId 会员卡ID
- * @return 该卡的所有流水记录,按时间倒序
- */
- Flux findByMemberCardId(Long memberCardId);
-
- /**
- * 数据统计 - 统计某卡种的总扣次数
- * @param memberCardId 会员卡ID
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 总扣次数
- */
- Mono sumDeductCountByCardId(Long memberCardId, LocalDateTime startTime, LocalDateTime endTime);
-
- /**
- * 数据统计 - 统计某时间段的续费总金额
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 续费总金额
- */
- Mono sumRenewAmountByTimeRange(LocalDateTime startTime, LocalDateTime endTime);
-
- /**
- * 数据统计 - 统计某会员的购卡总金额
- * @param memberId 会员ID
- * @param startTime 开始时间
- * @param endTime 结束时间
- * @return 购卡总金额
- */
- Mono sumPurchaseAmountByMemberId(Long memberId, LocalDateTime startTime, LocalDateTime endTime);
-
- /**
- * 创建交易记录
- * @param transaction 交易记录
- * @return 创建的交易记录
- */
- Mono createTransaction(MemberCardTransactions transaction);
-
- /**
- * 查询会员的交易记录
- * @param memberId 会员ID
- * @return 交易记录列表
- */
- Flux findByMemberId(Long memberId);
-
- /**
- * 查询会员卡记录的交易历史
- * @param recordId 会员卡记录ID
- * @return 交易记录列表
- */
- Flux findByRecordId(Long recordId);
-}
\ No newline at end of file
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/impl/MemberCardTransactionsServiceImpl.java b/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/impl/MemberCardTransactionsServiceImpl.java
deleted file mode 100644
index 119c4bf..0000000
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/impl/MemberCardTransactionsServiceImpl.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package cn.novalon.gym.manage.gymmembercard.sevice.impl;
-
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardTransactions;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsAction;
-import cn.novalon.gym.manage.gymmembercard.repository.IMemberCardTransactionsRepository;
-import cn.novalon.gym.manage.gymmembercard.sevice.IMemberCardTransactionsService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.domain.Pageable;
-import org.springframework.stereotype.Service;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-import java.time.LocalDateTime;
-
-@Slf4j
-@Service
-public class MemberCardTransactionsServiceImpl implements IMemberCardTransactionsService {
- private final IMemberCardTransactionsRepository memberCardTransactionsRepository;
-
- public MemberCardTransactionsServiceImpl(IMemberCardTransactionsRepository memberCardTransactionsRepository) {
- this.memberCardTransactionsRepository = memberCardTransactionsRepository;
- }
-
- @Override
- public Mono insertTransaction(MemberCardTransactions transactions) {
- return memberCardTransactionsRepository.insertTransaction(transactions);
- }
-
- @Override
- public Flux findByMemberIdAndTimeRange(Long memberId, LocalDateTime startTime,
- LocalDateTime endTime, Pageable pageable) {
- return memberCardTransactionsRepository.findByMemberIdAndTimeRange(memberId, startTime, endTime, pageable);
- }
-
- @Override
- public Flux findWithConditions(Long memberId, Long memberCardId,
- MemberCardTransactionsAction operationType,
- LocalDateTime startTime, LocalDateTime endTime,
- Pageable pageable) {
- return memberCardTransactionsRepository.findWithConditions(memberId, memberCardId, operationType,
- startTime, endTime, pageable);
- }
-
- @Override
- public Mono countWithConditions(Long memberId, Long memberCardId,
- MemberCardTransactionsAction operationType,
- LocalDateTime startTime, LocalDateTime endTime) {
- return memberCardTransactionsRepository.countWithConditions(memberId, memberCardId,
- operationType, startTime, endTime);
- }
-
- @Override
- public Flux findByMemberCardId(Long memberCardId) {
- return memberCardTransactionsRepository.findByMemberCardId(memberCardId);
- }
-
- @Override
- public Mono sumDeductCountByCardId(Long memberCardId, LocalDateTime startTime, LocalDateTime endTime) {
- return memberCardTransactionsRepository.sumDeductCountByCardId(memberCardId, startTime, endTime);
- }
-
- @Override
- public Mono sumRenewAmountByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
- return memberCardTransactionsRepository.sumRenewAmountByTimeRange(startTime, endTime);
- }
-
- @Override
- public Mono sumPurchaseAmountByMemberId(Long memberId, LocalDateTime startTime, LocalDateTime endTime) {
- return memberCardTransactionsRepository.sumPurchaseAmountByMemberId(memberId, startTime, endTime);
- }
-
- @Override
- public Mono createTransaction(MemberCardTransactions transaction) {
- return memberCardTransactionsRepository.save(transaction)
- .then()
- .doOnSuccess(v -> log.info("创建会员卡交易记录: memberId={}, cardId={}, type={}",
- transaction.getMemberId(), transaction.getMemberCardId(), transaction.getOperationType()));
- }
-
- @Override
- public Flux findByMemberId(Long memberId) {
- return memberCardTransactionsRepository.findByMemberId(memberId);
- }
-
- @Override
- public Flux findByRecordId(Long recordId) {
- return memberCardTransactionsRepository.findByRecordId(recordId);
- }
-}
diff --git a/gym-manage-api/gym-member-card/src/main/resources/sql b/gym-manage-api/gym-member-card/src/main/resources/sql
deleted file mode 100644
index 509e01f..0000000
--- a/gym-manage-api/gym-member-card/src/main/resources/sql
+++ /dev/null
@@ -1,132 +0,0 @@
--- ============================================
--- 会员卡类型表
--- ============================================
-CREATE TABLE IF NOT EXISTS member_card (
- member_card_id BIGSERIAL PRIMARY KEY,
- member_card_name VARCHAR(100) NOT NULL,
- member_card_type VARCHAR(20) NOT NULL,
- member_card_price DECIMAL(10, 2) NOT NULL,
- member_card_validity_days INTEGER,
- member_card_total_times INTEGER,
- member_card_amount DECIMAL(10, 2),
- member_card_status INTEGER DEFAULT 1 NOT NULL,
- extra_config JSONB DEFAULT '{}'::jsonb,
- created_at TIMESTAMPTZ DEFAULT NOW(),
- updated_at TIMESTAMPTZ DEFAULT NOW(),
- deleted_at TIMESTAMPTZ
-);
-
-COMMENT ON TABLE member_card IS '会员卡类型表';
-COMMENT ON COLUMN member_card.member_card_id IS '会员卡ID';
-COMMENT ON COLUMN member_card.member_card_name IS '会员卡名称';
-COMMENT ON COLUMN member_card.member_card_type IS '会员卡类型:TIME_CARD-时长卡, COUNT_CARD-次卡, STORED_VALUE_CARD-储值卡';
-COMMENT ON COLUMN member_card.member_card_price IS '会员卡价格';
-COMMENT ON COLUMN member_card.member_card_validity_days IS '有效天数(时长卡用)';
-COMMENT ON COLUMN member_card.member_card_total_times IS '总次数(次卡用)';
-COMMENT ON COLUMN member_card.member_card_amount IS '面额(储值卡用)';
-COMMENT ON COLUMN member_card.member_card_status IS '状态:0-下架, 1-上架';
-COMMENT ON COLUMN member_card.extra_config IS '扩展配置(JSON格式,用于未来组合卡等)';
-
--- ============================================
--- 会员卡记录表(会员持有的卡)
--- ============================================
-CREATE TABLE IF NOT EXISTS member_card_record (
- member_card_record_id BIGSERIAL PRIMARY KEY,
- member_id BIGINT NOT NULL,
- member_card_id BIGINT NOT NULL,
- status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
- remaining_times INTEGER DEFAULT 0,
- remaining_amount DECIMAL(10, 2) DEFAULT 0.00,
- expire_time TIMESTAMPTZ,
- source_order_id BIGINT,
- purchase_time TIMESTAMPTZ DEFAULT NOW(),
- version INTEGER DEFAULT 0 NOT NULL,
- card_composition JSONB DEFAULT NULL,
- created_at TIMESTAMPTZ DEFAULT NOW(),
- updated_at TIMESTAMPTZ DEFAULT NOW(),
- deleted_at TIMESTAMPTZ
- -- 移除外键约束,改用应用层验证
-);
-
--- 索引优化
-CREATE INDEX idx_member_card_record_member_id ON member_card_record(member_id);
-CREATE INDEX idx_member_card_record_status ON member_card_record(status);
-CREATE INDEX idx_member_card_record_expire_time ON member_card_record(expire_time);
-CREATE INDEX idx_member_card_record_member_status ON member_card_record(member_id, status);
-CREATE INDEX idx_member_card_record_status_expire ON member_card_record(status, expire_time)
- WHERE status = 'ACTIVE';
-
-COMMENT ON TABLE member_card_record IS '会员卡记录表';
-COMMENT ON COLUMN member_card_record.member_card_record_id IS '会员卡记录ID';
-COMMENT ON COLUMN member_card_record.member_id IS '会员ID';
-COMMENT ON COLUMN member_card_record.member_card_id IS '会员卡类型ID';
-COMMENT ON COLUMN member_card_record.status IS '状态:ACTIVE-有效, USED_UP-用完, EXPIRED-过期, REFUNDED-已退款';
-COMMENT ON COLUMN member_card_record.remaining_times IS '剩余次数';
-COMMENT ON COLUMN member_card_record.remaining_amount IS '剩余金额';
-COMMENT ON COLUMN member_card_record.expire_time IS '到期时间';
-COMMENT ON COLUMN member_card_record.source_order_id IS '来源订单ID';
-COMMENT ON COLUMN member_card_record.purchase_time IS '购买时间';
-COMMENT ON COLUMN member_card_record.version IS '乐观锁版本号';
-COMMENT ON COLUMN member_card_record.card_composition IS '卡片组成(JSON格式,用于组合卡)';
-
--- ============================================
--- 会员卡交易流水表
--- ============================================
-CREATE TABLE IF NOT EXISTS member_card_transactions (
- id BIGSERIAL PRIMARY KEY,
- member_card_record_id BIGINT NOT NULL,
- member_id BIGINT NOT NULL,
- member_card_id BIGINT NOT NULL,
- operation_type VARCHAR(20) NOT NULL,
- change_amount INTEGER DEFAULT 0,
- change_balance DECIMAL(10, 2) DEFAULT 0.00,
- after_remaining_count INTEGER DEFAULT 0,
- after_remaining_balance DECIMAL(10, 2) DEFAULT 0.00,
- related_biz_type VARCHAR(20),
- source_order_id BIGINT,
- remark VARCHAR(500),
- is_archived BOOLEAN DEFAULT FALSE NOT NULL,
- archived_at TIMESTAMPTZ,
- created_at TIMESTAMPTZ DEFAULT NOW()
- -- 移除外键约束,改用应用层验证
-);
-
--- 退款申请表
-CREATE TABLE IF NOT EXISTS refund_application (
- id BIGSERIAL PRIMARY KEY,
- record_id BIGINT NOT NULL,
- member_id BIGINT NOT NULL,
- status VARCHAR(20) NOT NULL DEFAULT 'PENDING', -- PENDING/APPROVED/REJECTED/PROCESSING/SUCCESS/FAILED
- reason VARCHAR(500),
- apply_time TIMESTAMPTZ DEFAULT NOW(),
- audit_time TIMESTAMPTZ,
- auditor_id BIGINT,
- audit_remark VARCHAR(500),
- refund_amount DECIMAL(10, 2),
- created_at TIMESTAMPTZ DEFAULT NOW(),
- updated_at TIMESTAMPTZ DEFAULT NOW()
-);
-
-CREATE INDEX idx_refund_application_record_id ON refund_application(record_id);
-CREATE INDEX idx_refund_application_status ON refund_application(status);
-
-COMMENT ON TABLE refund_application IS '退款申请表';
-COMMENT ON COLUMN refund_application.status IS '状态:PENDING-待审核, APPROVED-已批准, REJECTED-已拒绝, PROCESSING-处理中, SUCCESS-成功, FAILED-失败';
-
-
--- 索引优化
-CREATE INDEX idx_member_card_transactions_member_id ON member_card_transactions(member_id);
-CREATE INDEX idx_member_card_transactions_record_id ON member_card_transactions(member_card_record_id);
-CREATE INDEX idx_member_card_transactions_created_at ON member_card_transactions(created_at);
-CREATE INDEX idx_member_card_transactions_member_type_time
- ON member_card_transactions(member_id, operation_type, created_at);
-
-COMMENT ON TABLE member_card_transactions IS '会员卡交易流水表';
-COMMENT ON COLUMN member_card_transactions.operation_type IS '操作类型:PURCHASE-购买, DEDUCT-扣次/扣费, RENEW-续费, REFUND-退款, EXPIRE-过期';
-COMMENT ON COLUMN member_card_transactions.change_amount IS '变动次数';
-COMMENT ON COLUMN member_card_transactions.change_balance IS '变动金额';
-COMMENT ON COLUMN member_card_transactions.after_remaining_count IS '变动后剩余次数';
-COMMENT ON COLUMN member_card_transactions.after_remaining_balance IS '变动后剩余金额';
-COMMENT ON COLUMN member_card_transactions.related_biz_type IS '关联业务类型:GROUP_CLASS-团课, PT_CLASS-私教, CHECK_IN-签到';
-COMMENT ON COLUMN member_card_transactions.is_archived IS '是否已归档';
-COMMENT ON COLUMN member_card_transactions.archived_at IS '归档时间';
diff --git a/gym-manage-api/gym-member/.gitignore b/gym-manage-api/gym-member/.gitignore
new file mode 100644
index 0000000..9d5d968
--- /dev/null
+++ b/gym-manage-api/gym-member/.gitignore
@@ -0,0 +1,47 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Maven ###
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+
+### System Files ###
+.DS_Store
+Thumbs.db
diff --git a/gym-manage-api/gym-member/CARD_MERGE_REPORT.md b/gym-manage-api/gym-member/CARD_MERGE_REPORT.md
new file mode 100644
index 0000000..9995bbe
--- /dev/null
+++ b/gym-manage-api/gym-member/CARD_MERGE_REPORT.md
@@ -0,0 +1,199 @@
+# gym-member-card 模块合并到 gym-member 完成报告
+
+## 合并概述
+将 `gym-member-card` 模块的功能合并到 `gym-member` 模块的 `card` 子包中,保持功能不变,代码风格以 `gym-member` 为基准。
+
+## 已完成的工作
+
+### 1. 目录结构创建 ✅
+在 `gym-member/src/main/java/cn/novalon/gym/manage/member/card` 下创建了以下子目录:
+- `entity/` - 实体类
+- `dto/` - 数据传输对象
+- `vo/` - 视图对象
+- `repository/` - 数据访问层
+- `service/` - 服务接口
+- `service/impl/` - 服务实现
+- `handler/` - 业务处理器
+- `enums/` - 枚举类
+- `util/` - 工具类
+
+### 2. 实体类重构(Entity)✅
+按照 gym-member 的风格(使用 Lombok),创建了以下实体类:
+
+| 原文件 | 新文件 | 说明 |
+|--------|--------|------|
+| MemberCardEntity.java + MemberCard.java | card/entity/MemberCard.java | 会员卡类型实体 |
+| MemberCardRecordEntity.java + MemberCardRecord.java | card/entity/MemberCardRecord.java | 会员持卡记录实体 |
+| MemberCardTransactionsEntity.java | card/entity/MemberCardTransaction.java | 交易流水实体 |
+| RefundApplicationEntity.java | card/entity/RefundApplication.java | 退款申请实体 |
+
+**主要改进:**
+- 使用 `@Data`, `@Builder`, `@NoArgsConstructor`, `@AllArgsConstructor` Lombok 注解
+- 继承 `cn.novalon.gym.manage.member.entity.BaseEntity`
+- 移除手动编写的 getter/setter
+- 添加规范的 JavaDoc 注释
+
+### 3. 枚举类创建 ✅
+创建了以下枚举类:
+
+| 原文件 | 新文件 | 说明 |
+|--------|--------|------|
+| MemberCardType.java | card/enums/MemberCardType.java | 会员卡类型 |
+| MemberCardRecordStatus.java | card/enums/MemberCardRecordStatus.java | 卡片状态 |
+| MemberCardTransactionsAction.java | card/enums/TransactionType.java | 交易操作类型 |
+| MemberCardTransactionsType.java | card/enums/BizType.java | 关联业务类型 |
+| MemberCardEvent.java | card/enums/CardEvent.java | 状态机事件 |
+
+### 4. Repository 层合并 ✅
+将原有的 DAO 接口整合为 Repository 接口,直接继承 `R2dbcRepository`:
+
+| 原文件 | 新文件 | 说明 |
+|--------|--------|------|
+| MemberCardDao.java | card/repository/MemberCardRepository.java | 会员卡类型 Repository |
+| MemberCardRecordDao.java | card/repository/MemberCardRecordRepository.java | 持卡记录 Repository |
+| MemberCardTransactionsDao.java | card/repository/MemberCardTransactionRepository.java | 交易流水 Repository |
+| RefundApplicationDao.java | card/repository/RefundApplicationRepository.java | 退款申请 Repository |
+
+**主要改进:**
+- 统一命名规范(移除 Dao,使用 Repository)
+- 继承 `R2dbcRepository`
+- 保留所有自定义查询方法
+- 更新参数类型为新的实体类
+
+### 5. 数据库 Schema 迁移 ✅
+将会员卡相关的表结构添加到 `gym-member/src/main/resources/db/schema.sql`:
+
+新增表:
+- `member_card` - 会员卡类型表
+- `member_card_record` - 会员持卡记录表
+- `member_card_transactions` - 交易流水表
+- `refund_application` - 退款申请表
+
+包含完整的索引和注释。
+
+### 6. pom.xml 依赖更新 ✅
+在 `gym-member/pom.xml` 中添加了 Redis 响应式支持:
+```xml
+
+ org.springframework.boot
+ spring-boot-starter-data-redis-reactive
+
+```
+
+## 待完成的工作
+
+### 需要手动复制的文件(约30个)
+
+以下文件需要从 `gym-member-card` 复制到 `gym-member/card`,并修改包名:
+
+#### Handler 层(8个文件)
+源路径:`gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/`
+目标路径:`gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/`
+
+- DistributedLockService.java
+- ExpirationReminderService.java
+- MemberCardHandler.java
+- MemberCardRecordHandler.java
+- MemberCardScheduledHandler.java
+- MemberCardStateMachine.java
+- MemberCardTransactionHandler.java
+- RefundSagaHandler.java
+
+#### Service 接口层(4个文件)
+源路径:`gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/`
+目标路径:`gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/`
+
+注意:目录名从 `sevice`(拼写错误)改为 `service`
+
+- IMemberCardService.java
+- IMemberCardRecordService.java
+- IMemberCardTransactionsService.java
+- IRefundApplicationService.java
+
+#### Service 实现层(4个文件)
+源路径:`gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/impl/`
+目标路径:`gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/impl/`
+
+- MemberCardServiceImpl.java
+- MemberCardRecordServiceImpl.java
+- MemberCardTransactionsServiceImpl.java
+- RefundApplicationServiceImpl.java
+
+#### Util 工具类(1个文件)
+源路径:`gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/util/`
+目标路径:`gym-member/src/main/java/cn/novalon/gym/manage/member/card/util/`
+
+- BeanConvertUtil.java
+
+### 批量替换规则
+
+复制每个文件后,需要进行以下文本替换:
+
+1. **包名替换:**
+ ```
+ package cn.novalon.gym.manage.gymmembercard -> package cn.novalon.gym.manage.member.card
+ ```
+
+2. **导入语句替换:**
+ ```
+ import cn.novalon.gym.manage.gymmembercard -> import cn.novalon.gym.manage.member.card
+ ```
+
+3. **BaseEntity 导入替换:**
+ ```
+ import cn.novalon.gym.manage.db.entity.BaseEntity -> import cn.novalon.gym.manage.member.entity.BaseEntity
+ ```
+
+4. **BaseDomain 处理(如果存在):**
+ ```
+ import cn.novalon.gym.manage.sys.core.domain.BaseDomain -> (注释掉或删除)
+ ```
+
+5. **Repository 引用更新(如果需要):**
+ ```
+ IMemberCardRepository -> MemberCardRepository
+ IMemberCardRecordRepository -> MemberCardRecordRepository
+ IMemberCardTransactionsRepository -> MemberCardTransactionRepository
+ IRefundApplicationRepository -> RefundApplicationRepository
+ ```
+
+## 验证步骤
+
+完成文件复制后,执行以下验证:
+
+1. **编译验证:**
+ ```bash
+ cd gym-manage-api/gym-member
+ mvn clean compile
+ ```
+
+2. **检查是否有编译错误:**
+ - 修复任何缺失的导入
+ - 确认所有依赖类都已正确迁移
+ - 检查枚举引用是否正确
+
+3. **运行测试(如果有):**
+ ```bash
+ mvn test
+ ```
+
+## 注意事项
+
+1. **包名一致性:** 确保所有文件中的包声明和导入语句都正确更新
+2. **依赖注入:** Spring 的 `@Autowired` 或构造函数注入应自动工作,因为使用了相同的注解
+3. **数据库兼容性:** schema.sql 已追加新表,不会影响现有表
+4. **Redis 配置:** 确保 application.yml 中有 Redis 配置(如果需要分布式锁功能)
+5. **定时任务:** MemberCardScheduledHandler 和 ExpirationReminderService 可能需要启用 `@EnableScheduling`
+
+## 自动化脚本
+
+项目根目录下提供了两个辅助脚本:
+- `gym-member-card/migrate_to_member.py` - Python 迁移脚本
+- `gym-member-card/migrate-to-member.ps1` - PowerShell 迁移脚本
+
+可以运行这些脚本来自动完成文件复制和包名替换。
+
+---
+
+**生成时间:** 2026-05-27
+**合并状态:** 基础架构完成,待复制业务逻辑文件
diff --git a/gym-manage-api/gym-member/MEMBER_USER_TABLE_SIMPLE.sql b/gym-manage-api/gym-member/MEMBER_USER_TABLE_SIMPLE.sql
new file mode 100644
index 0000000..aef3540
--- /dev/null
+++ b/gym-manage-api/gym-member/MEMBER_USER_TABLE_SIMPLE.sql
@@ -0,0 +1,58 @@
+-- ============================================
+-- member_user 表 - 简洁版建表语句
+-- ============================================
+-- 用途:直接复制执行,快速创建会员表
+-- ============================================
+
+CREATE TABLE IF NOT EXISTS member_user (
+ -- 主键和基础字段
+ id BIGSERIAL PRIMARY KEY,
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ -- 会员核心字段
+ member_no VARCHAR(50) NOT NULL UNIQUE,
+ nickname VARCHAR(100),
+ phone VARCHAR(255),
+ gender INTEGER DEFAULT 0,
+ birthday TIMESTAMP,
+ address VARCHAR(500),
+ avatar VARCHAR(500),
+ subscribed BOOLEAN DEFAULT FALSE,
+ last_login_at TIMESTAMP,
+
+ -- 微信相关字段
+ union_id VARCHAR(100),
+ miniapp_open_id VARCHAR(100),
+ official_open_id VARCHAR(100),
+
+ -- 软删除字段
+ is_deleted BOOLEAN DEFAULT FALSE
+);
+
+-- 创建索引
+CREATE UNIQUE INDEX IF NOT EXISTS idx_member_user_member_no ON member_user(member_no);
+CREATE INDEX IF NOT EXISTS idx_member_user_union_id ON member_user(union_id);
+CREATE INDEX IF NOT EXISTS idx_member_user_miniapp_openid ON member_user(miniapp_open_id);
+CREATE INDEX IF NOT EXISTS idx_member_user_official_openid ON member_user(official_open_id);
+CREATE INDEX IF NOT EXISTS idx_member_user_phone ON member_user(phone);
+CREATE INDEX IF NOT EXISTS idx_member_user_is_deleted ON member_user(is_deleted);
+
+-- 添加注释
+COMMENT ON TABLE member_user IS '会员表';
+COMMENT ON COLUMN member_user.id IS '主键ID';
+COMMENT ON COLUMN member_user.created_at IS '创建时间';
+COMMENT ON COLUMN member_user.updated_at IS '更新时间';
+COMMENT ON COLUMN member_user.member_no IS '会员编号(唯一)';
+COMMENT ON COLUMN member_user.nickname IS '昵称';
+COMMENT ON COLUMN member_user.phone IS '手机号(AES加密存储)';
+COMMENT ON COLUMN member_user.gender IS '性别:0-未知,1-男,2-女';
+COMMENT ON COLUMN member_user.birthday IS '生日';
+COMMENT ON COLUMN member_user.address IS '地址';
+COMMENT ON COLUMN member_user.avatar IS '头像URL';
+COMMENT ON COLUMN member_user.subscribed IS '是否关注服务号';
+COMMENT ON COLUMN member_user.last_login_at IS '最后登录时间';
+COMMENT ON COLUMN member_user.union_id IS '微信UnionID(跨应用唯一标识)';
+COMMENT ON COLUMN member_user.miniapp_open_id IS '小程序OpenID';
+COMMENT ON COLUMN member_user.official_open_id IS '服务号OpenID';
+COMMENT ON COLUMN member_user.is_deleted IS '是否删除(软删除标记)';
diff --git a/gym-manage-api/gym-member/pom.xml b/gym-manage-api/gym-member/pom.xml
new file mode 100644
index 0000000..f62cbb0
--- /dev/null
+++ b/gym-manage-api/gym-member/pom.xml
@@ -0,0 +1,250 @@
+
+
+ 4.0.0
+
+
+ cn.novalon.gym.manage
+ gym-manage-api
+ 1.0.0
+
+
+ gym-member
+ jar
+
+ Gym Member
+ Member Management Module - Frontend User Services
+
+
+
+ cn.novalon.gym.manage
+ manage-common
+ ${project.version}
+
+
+ cn.novalon.gym.manage
+ manage-db
+ ${project.version}
+
+
+ cn.novalon.gym.manage
+ manage-sys
+ ${project.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ org.springdoc
+ springdoc-openapi-starter-webflux-ui
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.data
+ spring-data-commons
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
+ io.projectreactor
+ reactor-test
+ test
+
+
+ io.github.resilience4j
+ resilience4j-spring-boot3
+
+
+ io.github.resilience4j
+ resilience4j-reactor
+
+
+ org.testcontainers
+ testcontainers
+ 1.21.4
+ test
+
+
+ org.testcontainers
+ postgresql
+ 1.21.4
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ 1.21.4
+ test
+
+
+ com.h2database
+ h2
+ test
+
+
+ io.r2dbc
+ r2dbc-h2
+ test
+
+
+ org.postgresql
+ r2dbc-postgresql
+ test
+
+
+
+ com.github.binarywang
+ weixin-java-miniapp
+ 4.6.0
+
+
+ com.github.binarywang
+ weixin-java-mp
+ 4.6.0
+
+
+ cn.hutool
+ hutool-all
+ 5.8.25
+
+
+ org.springframework.boot
+ spring-boot-starter-data-elasticsearch
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis-reactive
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.4.2
+
+
+ default-jar
+ package
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.11.0
+
+ 21
+ 21
+
+
+ org.mapstruct
+ mapstruct-processor
+ 1.5.5.Final
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+ 0.2.0
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.12
+
+
+ prepare-agent
+
+ prepare-agent
+
+
+
+ report
+ verify
+
+ report
+
+
+
+ check
+ verify
+
+ check
+
+
+
+
+ BUNDLE
+
+
+ INSTRUCTION
+ COVEREDRATIO
+ 0.60
+
+
+
+
+
+
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+ 4.8.6.0
+
+
+ com.github.spotbugs
+ spotbugs
+ 4.8.6
+
+
+
+
+ spotbugs-check
+ verify
+
+ check
+
+
+
+
+ Max
+ High
+ true
+ spotbugs-exclude.xml
+
+
+
+
+
diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/entity/MemberCard.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/entity/MemberCard.java
new file mode 100644
index 0000000..684d401
--- /dev/null
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/entity/MemberCard.java
@@ -0,0 +1,64 @@
+package cn.novalon.gym.manage.member.card.entity;
+
+import cn.novalon.gym.manage.member.entity.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import org.springframework.data.relational.core.mapping.Column;
+import org.springframework.data.relational.core.mapping.Table;
+
+import java.time.LocalDateTime;
+
+/**
+ * 会员卡类型实体 - 对应 member_card 表
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@Table("member_card")
+public class MemberCard extends BaseEntity {
+
+ // 会员卡ID
+ @Column("member_card_id")
+ private Long memberCardId;
+
+ // 会员卡名称
+ @Column("member_card_name")
+ private String memberCardName;
+
+ // 会员卡类型:TIME_CARD-时长卡, COUNT_CARD-次卡, STORED_VALUE_CARD-储值卡
+ @Column("member_card_type")
+ private String memberCardType;
+
+ // 会员卡价格
+ @Column("member_card_price")
+ private Double memberCardPrice;
+
+ // 有效天数(时长卡用)
+ @Column("member_card_validity_days")
+ private Integer memberCardValidityDays;
+
+ // 总次数(次卡用)
+ @Column("member_card_total_times")
+ private Integer memberCardTotalTimes;
+
+ // 面额(储值卡用)
+ @Column("member_card_amount")
+ private Double memberCardAmount;
+
+ // 状态:0-下架, 1-上架
+ @Column("member_card_status")
+ private Integer memberCardStatus;
+
+ // 扩展配置(JSON格式)
+ @Column("extra_config")
+ private String extraConfig;
+
+}
diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/entity/MemberCardRecord.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/entity/MemberCardRecord.java
new file mode 100644
index 0000000..98d5e4b
--- /dev/null
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/entity/MemberCardRecord.java
@@ -0,0 +1,73 @@
+package cn.novalon.gym.manage.member.card.entity;
+
+import cn.novalon.gym.manage.member.card.enums.MemberCardRecordStatus;
+import cn.novalon.gym.manage.member.entity.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import org.springframework.data.relational.core.mapping.Column;
+import org.springframework.data.relational.core.mapping.Table;
+
+import java.time.LocalDateTime;
+
+/**
+ * 会员卡记录实体(会员持有的卡)- 对应 member_card_record 表
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@Table("member_card_record")
+public class MemberCardRecord extends BaseEntity {
+
+ // 会员持有卡ID
+ @Column("member_card_record_id")
+ private Long memberCardRecordId;
+
+ // 会员ID
+ @Column("member_id")
+ private Long memberId;
+
+ // 关联会员卡ID
+ @Column("member_card_id")
+ private Long memberCardId;
+
+ // 状态:ACTIVE-有效, USED_UP-用完, EXPIRED-过期, REFUNDED-已退款
+ @Column("status")
+ private MemberCardRecordStatus status;
+
+ // 剩余次数
+ @Column("remaining_times")
+ private Integer remainingTimes;
+
+ // 剩余金额
+ @Column("remaining_amount")
+ private Double remainingAmount;
+
+ // 到期时间
+ @Column("expire_time")
+ private LocalDateTime expireTime;
+
+ // 来源订单ID
+ @Column("source_order_id")
+ private Long sourceOrderId;
+
+ // 购买时间
+ @Column("purchase_time")
+ private LocalDateTime purchaseTime;
+
+ // 乐观锁版本号
+ @Column("version")
+ private Integer version;
+
+ // 卡片组成(JSON格式,用于组合卡)
+ @Column("card_composition")
+ private String cardComposition;
+
+}
diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/entity/MemberCardTransaction.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/entity/MemberCardTransaction.java
new file mode 100644
index 0000000..29abd08
--- /dev/null
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/entity/MemberCardTransaction.java
@@ -0,0 +1,78 @@
+package cn.novalon.gym.manage.member.card.entity;
+
+import cn.novalon.gym.manage.member.entity.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import org.springframework.data.relational.core.mapping.Column;
+import org.springframework.data.relational.core.mapping.Table;
+
+/**
+ * 会员卡交易流水实体 - 对应 member_card_transactions 表
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@Table("member_card_transactions")
+public class MemberCardTransaction extends BaseEntity {
+
+ // 交易ID
+ @Column("member_card_record_id")
+ private Long memberCardRecordId;
+
+ // 会员ID
+ @Column("member_id")
+ private Long memberId;
+
+ // 会员卡ID
+ @Column("member_card_id")
+ private Long memberCardId;
+
+ // 操作类型:PURCHASE-购买, DEDUCT-扣次/扣费, RENEW-续费, REFUND-退款, EXPIRE-过期
+ @Column("operation_type")
+ private String operationType;
+
+ // 变动次数
+ @Column("change_amount")
+ private Integer changeAmount;
+
+ // 变动金额
+ @Column("change_balance")
+ private Double changeBalance;
+
+ // 变动后剩余次数
+ @Column("after_remaining_count")
+ private Integer afterRemainingCount;
+
+ // 变动后剩余金额
+ @Column("after_remaining_balance")
+ private Double afterRemainingBalance;
+
+ // 关联业务类型:GROUP_CLASS-团课, PT_CLASS-私教, CHECK_IN-签到
+ @Column("related_biz_type")
+ private String relatedBizType;
+
+ // 来源订单ID
+ @Column("source_order_id")
+ private Long sourceOrderId;
+
+ // 备注
+ @Column("remark")
+ private String remark;
+
+ // 是否已归档
+ @Column("is_archived")
+ private Boolean isArchived;
+
+ // 归档时间
+ @Column("archived_at")
+ private java.time.LocalDateTime archivedAt;
+
+}
diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/entity/RefundApplication.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/entity/RefundApplication.java
new file mode 100644
index 0000000..88547bc
--- /dev/null
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/entity/RefundApplication.java
@@ -0,0 +1,66 @@
+package cn.novalon.gym.manage.member.card.entity;
+
+import cn.novalon.gym.manage.member.card.enums.RefundStatus;
+import cn.novalon.gym.manage.member.entity.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import org.springframework.data.relational.core.mapping.Column;
+import org.springframework.data.relational.core.mapping.Table;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 退款申请实体 - 对应 refund_application 表
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@Table("refund_application")
+public class RefundApplication extends BaseEntity {
+
+ // 会员卡记录ID
+ @Column("record_id")
+ private Long recordId;
+
+ // 会员ID
+ @Column("member_id")
+ private Long memberId;
+
+ // 状态:PENDING-待审核, APPROVED-已批准, REJECTED-已拒绝, PROCESSING-处理中, SUCCESS-成功, FAILED-失败
+ @Column("status")
+ private RefundStatus status;
+
+ // 退款原因
+ @Column("reason")
+ private String reason;
+
+ // 申请时间
+ @Column("apply_time")
+ private LocalDateTime applyTime;
+
+ // 审核时间
+ @Column("audit_time")
+ private LocalDateTime auditTime;
+
+ // 审核人ID
+ @Column("auditor_id")
+ private Long auditorId;
+
+ // 审核备注
+ @Column("audit_remark")
+ private String auditRemark;
+
+ // 退款金额
+ @Column("refund_amount")
+ private BigDecimal refundAmount;
+
+}
diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/BizType.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/BizType.java
new file mode 100644
index 0000000..b53f839
--- /dev/null
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/BizType.java
@@ -0,0 +1,24 @@
+package cn.novalon.gym.manage.member.card.enums;
+
+/**
+ * 会员卡流水关联业务类型枚举
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
+public enum BizType {
+
+ GROUP_CLASS("团课"),
+ PT_CLASS("私教"),
+ CHECK_IN("签到");
+
+ private final String desc;
+
+ BizType(String desc) {
+ this.desc = desc;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/CardEvent.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/CardEvent.java
new file mode 100644
index 0000000..db3f8ee
--- /dev/null
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/CardEvent.java
@@ -0,0 +1,27 @@
+package cn.novalon.gym.manage.member.card.enums;
+
+/**
+ * 会员卡状态机事件枚举
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
+public enum CardEvent {
+
+ ACTIVATE("激活卡片"),
+ USE("使用卡片"),
+ RENEW("续费"),
+ EXPIRE("过期"),
+ REFUND("退款"),
+ DISABLE("禁用");
+
+ private final String desc;
+
+ CardEvent(String desc) {
+ this.desc = desc;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/MemberCardRecordStatus.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/MemberCardRecordStatus.java
new file mode 100644
index 0000000..fe27fe7
--- /dev/null
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/MemberCardRecordStatus.java
@@ -0,0 +1,25 @@
+package cn.novalon.gym.manage.member.card.enums;
+
+/**
+ * 会员卡记录状态枚举
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
+public enum MemberCardRecordStatus {
+
+ ACTIVE("有效"),
+ USED_UP("用完"),
+ EXPIRED("过期"),
+ REFUNDED("已退款");
+
+ private final String desc;
+
+ MemberCardRecordStatus(String desc) {
+ this.desc = desc;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardType.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/MemberCardType.java
similarity index 50%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardType.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/MemberCardType.java
index decb62a..207d1ff 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/enums/MemberCardType.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/MemberCardType.java
@@ -1,16 +1,15 @@
-package cn.novalon.gym.manage.gymmembercard.enums;
+package cn.novalon.gym.manage.member.card.enums;
-import io.swagger.v3.oas.annotations.media.Schema;
-
-@Schema(description = "会员卡类型枚举")
+/**
+ * 会员卡类型枚举
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
public enum MemberCardType {
- @Schema(description = "时长卡")
+
TIME_CARD("时长卡"),
-
- @Schema(description = "次卡")
COUNT_CARD("次卡"),
-
- @Schema(description = "储值卡")
STORED_VALUE_CARD("储值卡");
private final String desc;
@@ -22,4 +21,4 @@ public enum MemberCardType {
public String getDesc() {
return desc;
}
-}
\ No newline at end of file
+}
diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/RefundStatus.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/RefundStatus.java
new file mode 100644
index 0000000..c350f31
--- /dev/null
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/RefundStatus.java
@@ -0,0 +1,27 @@
+package cn.novalon.gym.manage.member.card.enums;
+
+/**
+ * 退款申请状态枚举
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
+public enum RefundStatus {
+
+ PENDING("待审核"),
+ APPROVED("已批准"),
+ REJECTED("已拒绝"),
+ PROCESSING("处理中"),
+ SUCCESS("成功"),
+ FAILED("失败");
+
+ private final String desc;
+
+ RefundStatus(String desc) {
+ this.desc = desc;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/TransactionType.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/TransactionType.java
new file mode 100644
index 0000000..5ae8c94
--- /dev/null
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/enums/TransactionType.java
@@ -0,0 +1,26 @@
+package cn.novalon.gym.manage.member.card.enums;
+
+/**
+ * 会员卡流水操作类型枚举
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
+public enum TransactionType {
+
+ PURCHASE("购买"),
+ DEDUCT("扣次/扣费"),
+ RENEW("续费"),
+ REFUND("退款"),
+ EXPIRE("过期");
+
+ private final String desc;
+
+ TransactionType(String desc) {
+ this.desc = desc;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/DistributedLockService.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/DistributedLockService.java
similarity index 93%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/DistributedLockService.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/DistributedLockService.java
index 08f57ae..c7098af 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/DistributedLockService.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/DistributedLockService.java
@@ -1,4 +1,4 @@
-package cn.novalon.gym.manage.gymmembercard.handler;
+package cn.novalon.gym.manage.member.card.handler;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
@@ -8,9 +8,9 @@ import java.util.concurrent.locks.ReentrantLock;
/**
* 分布式锁服务(简化版,使用本地锁)
- *
- * @author shizhounian
- * @date 2026-05-23
+ *
+ * @author 付嘉
+ * @date 2026-05-27
*/
@Component
public class DistributedLockService {
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/ExpirationReminderService.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/ExpirationReminderService.java
similarity index 96%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/ExpirationReminderService.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/ExpirationReminderService.java
index 3050327..c063de9 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/ExpirationReminderService.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/ExpirationReminderService.java
@@ -1,6 +1,6 @@
-package cn.novalon.gym.manage.gymmembercard.handler;
+package cn.novalon.gym.manage.member.card.handler;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardRecord;
+import cn.novalon.gym.manage.member.card.entity.MemberCardRecord;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -16,6 +16,12 @@ import java.time.Duration;
import java.time.LocalDateTime;
import java.util.UUID;
+/**
+ * 会员卡到期提醒服务
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
@Slf4j
@Component
@RequiredArgsConstructor
@@ -84,7 +90,7 @@ public class ExpirationReminderService {
return reminderFlux.then();
}
- /**
+ /**
* 定时任务:每分钟扫描到期的提醒并发送
*/
@Scheduled(fixedRate = 60000)
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardHandler.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardHandler.java
similarity index 95%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardHandler.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardHandler.java
index 1744819..b697999 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardHandler.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardHandler.java
@@ -1,8 +1,8 @@
-package cn.novalon.gym.manage.gymmembercard.handler;
+package cn.novalon.gym.manage.member.card.handler;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCard;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardRecord;
-import cn.novalon.gym.manage.gymmembercard.sevice.IMemberCardService;
+import cn.novalon.gym.manage.member.card.entity.MemberCard;
+import cn.novalon.gym.manage.member.card.entity.MemberCardRecord;
+import cn.novalon.gym.manage.member.card.service.IMemberCardService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
@@ -15,9 +15,9 @@ import reactor.core.publisher.Mono;
/**
* 会员卡管理处理器
- *
- * @author shizhounian
- * @date 2026-05-23
+ *
+ * @author 付嘉
+ * @date 2026-05-27
*/
@Slf4j
@Component
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardRecordHandler.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardRecordHandler.java
similarity index 93%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardRecordHandler.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardRecordHandler.java
index 77ee607..7928a7c 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardRecordHandler.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardRecordHandler.java
@@ -1,8 +1,8 @@
-package cn.novalon.gym.manage.gymmembercard.handler;
+package cn.novalon.gym.manage.member.card.handler;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardRecord;
-import cn.novalon.gym.manage.gymmembercard.sevice.IMemberCardRecordService;
-import cn.novalon.gym.manage.gymmembercard.sevice.IMemberCardService;
+import cn.novalon.gym.manage.member.card.entity.MemberCardRecord;
+import cn.novalon.gym.manage.member.card.service.IMemberCardRecordService;
+import cn.novalon.gym.manage.member.card.service.IMemberCardService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
@@ -11,6 +11,12 @@ import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
+/**
+ * 会员卡记录管理处理器
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
@Component
@Tag(name = "会员卡记录管理", description = "会员卡购买、续费、使用、退款等核心业务")
public class MemberCardRecordHandler {
@@ -109,4 +115,4 @@ public class MemberCardRecordHandler {
private Integer addDays;
private Long sourceOrderId;
}
-}
\ No newline at end of file
+}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardScheduledHandler.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardScheduledHandler.java
similarity index 86%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardScheduledHandler.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardScheduledHandler.java
index de6108b..0c4181f 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardScheduledHandler.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardScheduledHandler.java
@@ -1,9 +1,9 @@
-package cn.novalon.gym.manage.gymmembercard.handler;
+package cn.novalon.gym.manage.member.card.handler;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardRecord;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardEvent;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardRecordStatus;
-import cn.novalon.gym.manage.gymmembercard.repository.IMemberCardRecordRepository;
+import cn.novalon.gym.manage.member.card.entity.MemberCardRecord;
+import cn.novalon.gym.manage.member.card.enums.CardEvent;
+import cn.novalon.gym.manage.member.card.enums.MemberCardRecordStatus;
+import cn.novalon.gym.manage.member.card.repository.MemberCardRecordRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
@@ -12,17 +12,23 @@ import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
+/**
+ * 会员卡定时任务处理器
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
@Slf4j
@Component
@RequiredArgsConstructor
public class MemberCardScheduledHandler {
- private final IMemberCardRecordRepository recordRepository;
+ private final MemberCardRecordRepository recordRepository;
private final ExpirationReminderService expirationReminderService;
private final MemberCardStateMachine stateMachine;
private final DistributedLockService distributedLockService;
- /**
+ /**
* 每日凌晨2点检查过期会员卡
*/
@Scheduled(cron = "0 0 2 * * ?")
@@ -38,7 +44,7 @@ public class MemberCardScheduledHandler {
recordRepository.findActiveRecords()
.filter(record -> record.getExpireTime() != null && record.getExpireTime().isBefore(now))
.flatMap(record ->
- stateMachine.transition(record.getStatus(), MemberCardEvent.EXPIRE)
+ stateMachine.transition(record.getStatus(), CardEvent.EXPIRE)
.flatMap(newState -> {
record.setStatus(newState);
return recordRepository.save(record);
@@ -55,9 +61,8 @@ public class MemberCardScheduledHandler {
).subscribe();
}
- /**
+ /**
* 每日凌晨3点检查是否有遗漏的到期提醒(兜底机制)
- * 主要依赖购卡/续费时的主动调用和每分钟扫描任务,此任务仅用于异常恢复
*/
@Scheduled(cron = "0 0 3 * * ?")
public void checkAndSendExpirationReminders() {
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardStateMachine.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardStateMachine.java
similarity index 56%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardStateMachine.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardStateMachine.java
index e48386e..94c8738 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardStateMachine.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardStateMachine.java
@@ -1,8 +1,8 @@
-package cn.novalon.gym.manage.gymmembercard.handler;
+package cn.novalon.gym.manage.member.card.handler;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardRecord;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardEvent;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardRecordStatus;
+import cn.novalon.gym.manage.member.card.entity.MemberCardRecord;
+import cn.novalon.gym.manage.member.card.enums.CardEvent;
+import cn.novalon.gym.manage.member.card.enums.MemberCardRecordStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
@@ -10,36 +10,42 @@ import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;
+/**
+ * 会员卡状态机处理器
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
@Slf4j
@Component
public class MemberCardStateMachine {
- private final Map> stateTransitionMap;
+ private final Map> stateTransitionMap;
public MemberCardStateMachine() {
this.stateTransitionMap = buildStateTransitionMap();
}
- private Map> buildStateTransitionMap() {
- Map> map = new HashMap<>();
+ private Map> buildStateTransitionMap() {
+ Map> map = new HashMap<>();
// ACTIVE 状态可以转换的事件
- Map activeTransitions = new HashMap<>();
- activeTransitions.put(MemberCardEvent.USE, MemberCardRecordStatus.ACTIVE);
- activeTransitions.put(MemberCardEvent.RENEW, MemberCardRecordStatus.ACTIVE);
- activeTransitions.put(MemberCardEvent.EXPIRE, MemberCardRecordStatus.EXPIRED);
- activeTransitions.put(MemberCardEvent.REFUND, MemberCardRecordStatus.REFUNDED);
+ Map activeTransitions = new HashMap<>();
+ activeTransitions.put(CardEvent.USE, MemberCardRecordStatus.ACTIVE);
+ activeTransitions.put(CardEvent.RENEW, MemberCardRecordStatus.ACTIVE);
+ activeTransitions.put(CardEvent.EXPIRE, MemberCardRecordStatus.EXPIRED);
+ activeTransitions.put(CardEvent.REFUND, MemberCardRecordStatus.REFUNDED);
map.put(MemberCardRecordStatus.ACTIVE, activeTransitions);
// USED_UP 状态可以转换的事件
- Map usedUpTransitions = new HashMap<>();
- usedUpTransitions.put(MemberCardEvent.RENEW, MemberCardRecordStatus.ACTIVE);
- usedUpTransitions.put(MemberCardEvent.REFUND, MemberCardRecordStatus.REFUNDED);
+ Map usedUpTransitions = new HashMap<>();
+ usedUpTransitions.put(CardEvent.RENEW, MemberCardRecordStatus.ACTIVE);
+ usedUpTransitions.put(CardEvent.REFUND, MemberCardRecordStatus.REFUNDED);
map.put(MemberCardRecordStatus.USED_UP, usedUpTransitions);
// EXPIRED 状态可以转换的事件
- Map expiredTransitions = new HashMap<>();
- expiredTransitions.put(MemberCardEvent.RENEW, MemberCardRecordStatus.ACTIVE);
+ Map expiredTransitions = new HashMap<>();
+ expiredTransitions.put(CardEvent.RENEW, MemberCardRecordStatus.ACTIVE);
map.put(MemberCardRecordStatus.EXPIRED, expiredTransitions);
// REFUNDED 状态是终态,不允许任何转换
@@ -47,9 +53,9 @@ public class MemberCardStateMachine {
return map;
}
- public Mono canTransition(MemberCardRecordStatus currentState, MemberCardEvent event) {
+ public Mono canTransition(MemberCardRecordStatus currentState, CardEvent event) {
return Mono.fromSupplier(() -> {
- Map transitions = stateTransitionMap.get(currentState);
+ Map transitions = stateTransitionMap.get(currentState);
if (transitions == null) {
return false;
}
@@ -57,9 +63,9 @@ public class MemberCardStateMachine {
});
}
- public Mono transition(MemberCardRecordStatus currentState, MemberCardEvent event) {
+ public Mono transition(MemberCardRecordStatus currentState, CardEvent event) {
return Mono.fromSupplier(() -> {
- Map transitions = stateTransitionMap.get(currentState);
+ Map transitions = stateTransitionMap.get(currentState);
if (transitions == null || !transitions.containsKey(event)) {
log.error("Invalid state transition: currentState={}, event={}", currentState, event);
throw new IllegalStateException(
@@ -71,7 +77,7 @@ public class MemberCardStateMachine {
});
}
- public Mono validateTransition(MemberCardRecord card, MemberCardEvent event) {
+ public Mono validateTransition(MemberCardRecord card, CardEvent event) {
return canTransition(card.getStatus(), event)
.flatMap(canTransition -> {
if (!canTransition) {
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardTransactionHandler.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardTransactionHandler.java
similarity index 76%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardTransactionHandler.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardTransactionHandler.java
index ead4283..771248a 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/MemberCardTransactionHandler.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/MemberCardTransactionHandler.java
@@ -1,9 +1,9 @@
-package cn.novalon.gym.manage.gymmembercard.handler;
+package cn.novalon.gym.manage.member.card.handler;
import cn.hutool.db.PageResult;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardTransactions;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsAction;
-import cn.novalon.gym.manage.gymmembercard.sevice.IMemberCardTransactionsService;
+import cn.novalon.gym.manage.member.card.entity.MemberCardTransaction;
+import cn.novalon.gym.manage.member.card.enums.TransactionType;
+import cn.novalon.gym.manage.member.card.service.IMemberCardTransactionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Validator;
@@ -19,20 +19,22 @@ import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
import java.util.List;
-/*
- *@Author:shizhounian
- *@Date:2026/5/17-05 20:10:22
+/**
+ * 会员卡流水管理处理器
+ *
+ * @author 付嘉
+ * @date 2026-05-27
*/
@Component
@Tag(name = "会员卡流水管理", description = "会员卡流水相关操作")
public class MemberCardTransactionHandler {
- private final IMemberCardTransactionsService memberCardTransactionsService;
+ private final IMemberCardTransactionService memberCardTransactionService;
private final Validator validator;
- public MemberCardTransactionHandler(IMemberCardTransactionsService memberCardTransactionsService,
+ public MemberCardTransactionHandler(IMemberCardTransactionService memberCardTransactionService,
Validator validator) {
- this.memberCardTransactionsService = memberCardTransactionsService;
+ this.memberCardTransactionService = memberCardTransactionService;
this.validator = validator;
}
@@ -41,8 +43,8 @@ public class MemberCardTransactionHandler {
*/
@Operation(summary = "插入流水记录", description = "购卡、扣次、续费、退款、过期时插入流水")
public Mono insertTransaction(ServerRequest request) {
- return request.bodyToMono(MemberCardTransactions.class)
- .flatMap(memberCardTransactionsService::insertTransaction)
+ return request.bodyToMono(MemberCardTransaction.class)
+ .flatMap(memberCardTransactionService::insertTransaction)
.flatMap(record -> ServerResponse.ok().bodyValue(record));
}
@@ -61,8 +63,8 @@ public class MemberCardTransactionHandler {
Pageable pageable = PageRequest.of(page, size, Sort.by("created_at").descending());
return ServerResponse.ok()
- .body(memberCardTransactionsService.findByMemberIdAndTimeRange(
- memberId, startTime, endTime, pageable), MemberCardTransactions.class);
+ .body(memberCardTransactionService.findByMemberIdAndTimeRange(
+ memberId, startTime, endTime, pageable), MemberCardTransaction.class);
}
/**
@@ -72,25 +74,25 @@ public class MemberCardTransactionHandler {
public Mono getTransactionsWithConditions(ServerRequest request) {
Long memberId = request.queryParam("memberId").map(Long::parseLong).orElse(null);
Long memberCardId = request.queryParam("memberCardId").map(Long::parseLong).orElse(null);
- MemberCardTransactionsAction operationType = request.queryParam("operationType")
- .map(s -> MemberCardTransactionsAction.valueOf(s.toUpperCase())).orElse(null);
+ TransactionType operationType = request.queryParam("operationType")
+ .map(s -> TransactionType.valueOf(s.toUpperCase())).orElse(null);
LocalDateTime startTime = request.queryParam("startTime").map(LocalDateTime::parse).orElse(null);
LocalDateTime endTime = request.queryParam("endTime").map(LocalDateTime::parse).orElse(null);
int page = request.queryParam("page").map(Integer::parseInt).orElse(0);
int size = request.queryParam("size").map(Integer::parseInt).orElse(10);
Pageable pageable = PageRequest.of(page, size, Sort.by("created_at").descending());
- Mono countMono = memberCardTransactionsService.countWithConditions(
+ Mono countMono = memberCardTransactionService.countWithConditions(
memberId, memberCardId, operationType, startTime, endTime);
- Flux flux = memberCardTransactionsService.findWithConditions(
+ Flux flux = memberCardTransactionService.findWithConditions(
memberId, memberCardId, operationType, startTime, endTime, pageable);
return Mono.zip(countMono, flux.collectList())
.flatMap(tuple -> {
Long total = tuple.getT1();
- List list = tuple.getT2();
+ List list = tuple.getT2();
// 构造 PageResult,内部自动计算总页数
- PageResult result = new PageResult<>(page, size, total.intValue());
+ PageResult result = new PageResult<>(page, size, total.intValue());
result.addAll(list);
return ServerResponse.ok().bodyValue(result);
});
@@ -103,8 +105,8 @@ public class MemberCardTransactionHandler {
public Mono getTransactionsByCardId(ServerRequest request) {
Long memberCardId = Long.parseLong(request.pathVariable("cardId"));
return ServerResponse.ok()
- .body(memberCardTransactionsService.findByMemberCardId(memberCardId),
- MemberCardTransactions.class);
+ .body(memberCardTransactionService.findByMemberCardId(memberCardId),
+ MemberCardTransaction.class);
}
/**
@@ -117,7 +119,7 @@ public class MemberCardTransactionHandler {
.map(LocalDateTime::parse).orElse(LocalDateTime.now().minusMonths(1));
LocalDateTime endTime = request.queryParam("endTime")
.map(LocalDateTime::parse).orElse(LocalDateTime.now());
- return memberCardTransactionsService.sumDeductCountByCardId(memberCardId, startTime, endTime)
+ return memberCardTransactionService.sumDeductCountByCardId(memberCardId, startTime, endTime)
.flatMap(count -> ServerResponse.ok().bodyValue(count));
}
@@ -130,7 +132,7 @@ public class MemberCardTransactionHandler {
.map(LocalDateTime::parse).orElse(LocalDateTime.now().minusMonths(1));
LocalDateTime endTime = request.queryParam("endTime")
.map(LocalDateTime::parse).orElse(LocalDateTime.now());
- return memberCardTransactionsService.sumRenewAmountByTimeRange(startTime, endTime)
+ return memberCardTransactionService.sumRenewAmountByTimeRange(startTime, endTime)
.flatMap(amount -> ServerResponse.ok().bodyValue(amount));
}
@@ -144,7 +146,7 @@ public class MemberCardTransactionHandler {
.map(LocalDateTime::parse).orElse(LocalDateTime.now().minusMonths(1));
LocalDateTime endTime = request.queryParam("endTime")
.map(LocalDateTime::parse).orElse(LocalDateTime.now());
- return memberCardTransactionsService.sumPurchaseAmountByMemberId(memberId, startTime, endTime)
+ return memberCardTransactionService.sumPurchaseAmountByMemberId(memberId, startTime, endTime)
.flatMap(amount -> ServerResponse.ok().bodyValue(amount));
}
-}
\ No newline at end of file
+}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/RefundSagaHandler.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/RefundSagaHandler.java
similarity index 64%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/RefundSagaHandler.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/RefundSagaHandler.java
index 32c0ca1..fd42204 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/handler/RefundSagaHandler.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/handler/RefundSagaHandler.java
@@ -1,12 +1,12 @@
-package cn.novalon.gym.manage.gymmembercard.handler;
+package cn.novalon.gym.manage.member.card.handler;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardRecord;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardTransactions;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardEvent;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardRecordStatus;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsAction;
-import cn.novalon.gym.manage.gymmembercard.repository.IMemberCardRecordRepository;
-import cn.novalon.gym.manage.gymmembercard.sevice.IMemberCardTransactionsService;
+import cn.novalon.gym.manage.member.card.entity.MemberCardRecord;
+import cn.novalon.gym.manage.member.card.entity.MemberCardTransaction;
+import cn.novalon.gym.manage.member.card.enums.CardEvent;
+import cn.novalon.gym.manage.member.card.enums.MemberCardRecordStatus;
+import cn.novalon.gym.manage.member.card.enums.TransactionType;
+import cn.novalon.gym.manage.member.card.repository.MemberCardRecordRepository;
+import cn.novalon.gym.manage.member.card.service.IMemberCardTransactionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -15,19 +15,25 @@ import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.List;
+/**
+ * 退款 Saga 处理器
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
@Slf4j
@Component
@RequiredArgsConstructor
public class RefundSagaHandler {
- private final IMemberCardRecordRepository recordRepository;
- private final IMemberCardTransactionsService transactionsService;
+ private final MemberCardRecordRepository recordRepository;
+ private final IMemberCardTransactionService transactionService;
private final MemberCardStateMachine stateMachine;
public Mono executeRefund(Long recordId) {
return recordRepository.findById(recordId)
.switchIfEmpty(Mono.error(new RuntimeException("会员卡记录不存在")))
- .flatMap(record -> stateMachine.validateTransition(record, MemberCardEvent.REFUND)
+ .flatMap(record -> stateMachine.validateTransition(record, CardEvent.REFUND)
.then(Mono.defer(() -> doExecuteRefund(recordId, record))));
}
@@ -55,7 +61,7 @@ public class RefundSagaHandler {
}
private Mono updateCardStatus(Long recordId, MemberCardRecordStatus status) {
- return recordRepository.updateStatus(recordId, status)
+ return recordRepository.updateStatus(recordId, status.name())
.flatMap(rows -> {
if (rows == 0) {
return Mono.error(new RuntimeException("更新会员卡状态失败"));
@@ -65,29 +71,31 @@ public class RefundSagaHandler {
}
private Mono createRefundTransaction(MemberCardRecord record) {
- MemberCardTransactions transaction = new MemberCardTransactions();
- transaction.setMemberId(record.getMemberId());
- transaction.setMemberCardId(record.getMemberCardId());
- transaction.setOperationType(MemberCardTransactionsAction.REFUND);
- transaction.setChangeAmount(-record.getRemainingTimes());
- transaction.setChangeBalance(-record.getRemainingAmount());
- transaction.setAfterRemainingCount(0);
- transaction.setAfterRemainingBalance(0.0);
- transaction.setRemark("会员卡退款");
+ MemberCardTransaction transaction = MemberCardTransaction.builder()
+ .memberId(record.getMemberId())
+ .memberCardId(record.getMemberCardId())
+ .operationType(TransactionType.REFUND.name())
+ .changeAmount(-record.getRemainingTimes())
+ .changeBalance(-record.getRemainingAmount())
+ .afterRemainingCount(0)
+ .afterRemainingBalance(0.0)
+ .remark("会员卡退款")
+ .build();
- return transactionsService.createTransaction(transaction);
+ return transactionService.createTransaction(transaction);
}
private Mono createReversalTransaction(MemberCardRecord record) {
- MemberCardTransactions reversal = new MemberCardTransactions();
- reversal.setMemberId(record.getMemberId());
- reversal.setMemberCardId(record.getMemberCardId());
- reversal.setOperationType(MemberCardTransactionsAction.REFUND);
- reversal.setChangeAmount(record.getRemainingTimes());
- reversal.setChangeBalance(record.getRemainingAmount());
- reversal.setRemark("退款冲正");
+ MemberCardTransaction reversal = MemberCardTransaction.builder()
+ .memberId(record.getMemberId())
+ .memberCardId(record.getMemberCardId())
+ .operationType(TransactionType.REFUND.name())
+ .changeAmount(record.getRemainingTimes())
+ .changeBalance(record.getRemainingAmount())
+ .remark("退款冲正")
+ .build();
- return transactionsService.createTransaction(reversal);
+ return transactionService.createTransaction(reversal);
}
private Mono executeSaga(List steps, List rollbackSteps) {
@@ -123,4 +131,4 @@ public class RefundSagaHandler {
}
private record SagaStep(String description, Mono operation, Mono rollbackOperation) {}
-}
\ No newline at end of file
+}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/dao/MemberCardRecordDao.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/repository/MemberCardRecordRepository.java
similarity index 54%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/dao/MemberCardRecordDao.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/repository/MemberCardRecordRepository.java
index 728d82c..b18f53c 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/dao/MemberCardRecordDao.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/repository/MemberCardRecordRepository.java
@@ -1,32 +1,39 @@
-package cn.novalon.gym.manage.gymmembercard.dao;
+package cn.novalon.gym.manage.member.card.repository;
-import cn.novalon.gym.manage.gymmembercard.entity.MemberCardRecordEntity;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardRecordStatus;
+import cn.novalon.gym.manage.member.card.entity.MemberCardRecord;
import org.springframework.data.domain.Pageable;
import org.springframework.data.r2dbc.repository.Modifying;
import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.r2dbc.repository.R2dbcRepository;
-import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
+/**
+ * 会员卡记录 Repository(会员持有的卡)
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
@Repository
-public interface MemberCardRecordDao extends R2dbcRepository {
+public interface MemberCardRecordRepository extends R2dbcRepository {
+ /**
+ * 插入新的激活卡记录
+ */
@Modifying
@Query("INSERT INTO member_card_record (member_id, member_card_id, status, expire_time, remaining_times, remaining_amount, source_order_id, purchase_time, created_at, updated_at) " +
"VALUES (:memberId, :memberCardId, 'ACTIVE', :expireTime, :remainingTimes, :remainingAmount, :sourceOrderId, NOW(), NOW(), NOW()) " +
"RETURNING *")
- Mono insertActiveRecord(@Param("memberId") Long memberId,
- @Param("memberCardId") Long memberCardId,
- @Param("expireTime") LocalDateTime expireTime,
- @Param("remainingTimes") Integer remainingTimes,
- @Param("remainingAmount") Double remainingAmount,
- @Param("sourceOrderId") Long sourceOrderId);
+ Mono insertActiveRecord(Long memberId, Long memberCardId,
+ LocalDateTime expireTime, Integer remainingTimes,
+ Double remainingAmount, Long sourceOrderId);
+ /**
+ * 扣减使用次数/金额
+ */
@Modifying
@Query("UPDATE member_card_record SET " +
"remaining_times = remaining_times - :deductTimes, " +
@@ -36,52 +43,67 @@ public interface MemberCardRecordDao extends R2dbcRepository= :deductTimes " +
"AND remaining_amount >= :deductAmount")
- Mono deductUsage(@Param("recordId") Long recordId,
- @Param("deductTimes") Integer deductTimes,
- @Param("deductAmount") Double deductAmount);
+ Mono deductUsage(Long recordId, Integer deductTimes, Double deductAmount);
+ /**
+ * 续费卡片
+ */
@Modifying
@Query("UPDATE member_card_record SET remaining_times = remaining_times + :addTimes, " +
"remaining_amount = remaining_amount + :addAmount, expire_time = :newExpireTime, updated_at = NOW() " +
"WHERE member_card_record_id = :recordId AND deleted_at IS NULL")
- Mono renewCard(@Param("recordId") Long recordId,
- @Param("addTimes") Integer addTimes,
- @Param("addAmount") Double addAmount,
- @Param("newExpireTime") LocalDateTime newExpireTime);
+ Mono renewCard(Long recordId, Integer addTimes, Double addAmount, LocalDateTime newExpireTime);
+ /**
+ * 更新卡片状态
+ */
@Modifying
@Query("UPDATE member_card_record SET status = :status, updated_at = NOW() " +
"WHERE member_card_record_id = :recordId AND deleted_at IS NULL")
- Mono updateStatus(@Param("recordId") Long recordId,
- @Param("status") MemberCardRecordStatus status);
+ Mono updateStatus(Long recordId, String status);
+ /**
+ * 查询会员的有效卡片
+ */
@Query("SELECT * FROM member_card_record WHERE member_id = :memberId AND status = 'ACTIVE' AND deleted_at IS NULL ORDER BY expire_time ASC")
- Flux findActiveCardsByMemberId(@Param("memberId") Long memberId);
+ Flux findActiveCardsByMemberId(Long memberId);
+ /**
+ * 查询会员的所有卡片(分页)
+ */
@Query("SELECT mcr.* FROM member_card_record mcr " +
- "INNER JOIN member m ON mcr.member_id = m.member_id " +
+ "INNER JOIN member_user m ON mcr.member_id = m.id " +
"WHERE mcr.member_id = :memberId AND mcr.deleted_at IS NULL " +
"ORDER BY mcr.purchase_time DESC LIMIT :#{#pageable.pageSize} OFFSET :#{#pageable.offset}")
- Flux findByMemberId(@Param("memberId") Long memberId, Pageable pageable);
+ Flux findByMemberId(Long memberId, Pageable pageable);
+ /**
+ * 验证次卡是否有足够次数
+ */
@Query("SELECT * FROM member_card_record WHERE member_card_record_id = :recordId " +
"AND status = 'ACTIVE' AND deleted_at IS NULL " +
"AND expire_time > NOW() " +
"AND remaining_times >= :requiredTimes")
- Mono validateCountCard(@Param("recordId") Long recordId,
- @Param("requiredTimes") Integer requiredTimes);
+ Mono validateCountCard(Long recordId, Integer requiredTimes);
+ /**
+ * 验证储值卡是否有足够余额
+ */
@Query("SELECT * FROM member_card_record WHERE member_card_record_id = :recordId " +
"AND status = 'ACTIVE' AND deleted_at IS NULL " +
"AND expire_time > NOW() " +
"AND remaining_amount >= :requiredAmount")
- Mono validateStoredCard(@Param("recordId") Long recordId,
- @Param("requiredAmount") Double requiredAmount);
+ Mono validateStoredCard(Long recordId, Double requiredAmount);
+ /**
+ * 查询已过期的卡片
+ */
@Query("SELECT * FROM member_card_record WHERE status = 'ACTIVE' AND expire_time < NOW() AND deleted_at IS NULL LIMIT 500")
- Flux findExpiredCards();
+ Flux findExpiredCards();
+ /**
+ * 查询所有有效记录
+ */
@Query("SELECT * FROM member_card_record WHERE status = 'ACTIVE' AND deleted_at IS NULL")
- Flux findActiveRecords();
-
-}
\ No newline at end of file
+ Flux findActiveRecords();
+}
diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/repository/MemberCardRepository.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/repository/MemberCardRepository.java
new file mode 100644
index 0000000..c45dd9e
--- /dev/null
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/repository/MemberCardRepository.java
@@ -0,0 +1,91 @@
+package cn.novalon.gym.manage.member.card.repository;
+
+import cn.novalon.gym.manage.member.card.entity.MemberCard;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.r2dbc.repository.Modifying;
+import org.springframework.data.r2dbc.repository.Query;
+import org.springframework.data.r2dbc.repository.R2dbcRepository;
+import org.springframework.stereotype.Repository;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+/**
+ * 会员卡类型 Repository
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
+@Repository
+public interface MemberCardRepository extends R2dbcRepository {
+
+ /**
+ * 根据会员卡ID查询(未删除的)
+ */
+ Mono findByMemberCardIdAndDeletedAtIsNull(Long memberCardId);
+
+ /**
+ * 条件查询会员卡列表
+ */
+ @Query("SELECT * FROM member_card WHERE deleted_at IS NULL " +
+ "AND (:status IS NULL OR member_card_status = :status) " +
+ "AND (:name IS NULL OR member_card_name LIKE CONCAT('%', :name, '%')) " +
+ "AND (:type IS NULL OR member_card_type = :type) " +
+ "AND (:minPrice IS NULL OR member_card_price >= :minPrice) " +
+ "AND (:maxPrice IS NULL OR member_card_price <= :maxPrice) " +
+ "ORDER BY created_at DESC LIMIT :#{#pageable.pageSize} OFFSET :#{#pageable.offset}")
+ Flux findWithConditions(Integer status, String name, String type,
+ Double minPrice, Double maxPrice, Pageable pageable);
+
+ /**
+ * 统计符合条件的会员卡总数
+ */
+ @Query("SELECT COUNT(*) FROM member_card WHERE deleted_at IS NULL " +
+ "AND (:status IS NULL OR member_card_status = :status) " +
+ "AND (:name IS NULL OR member_card_name LIKE CONCAT('%', :name, '%')) " +
+ "AND (:type IS NULL OR member_card_type = :type) " +
+ "AND (:minPrice IS NULL OR member_card_price >= :minPrice) " +
+ "AND (:maxPrice IS NULL OR member_card_price <= :maxPrice)")
+ Mono countWithConditions(Integer status, String name, String type,
+ Double minPrice, Double maxPrice);
+
+ /**
+ * 按状态查询会员卡列表
+ */
+ Flux findByMemberCardStatusAndDeletedAtIsNull(Integer status, Pageable pageable);
+
+ /**
+ * 检查会员卡是否已被购买
+ */
+ @Query("SELECT EXISTS(SELECT 1 FROM member_card_record WHERE member_card_id = :memberCardId AND deleted_at IS NULL LIMIT 1)")
+ Mono existsPurchasedRecord(Long memberCardId);
+
+ /**
+ * 逻辑删除会员卡
+ */
+ @Modifying
+ @Query("UPDATE member_card SET deleted_at = NOW() WHERE member_card_id = :memberCardId AND deleted_at IS NULL")
+ Mono logicalDelete(Long memberCardId);
+
+ /**
+ * 安全更新会员卡信息
+ */
+ @Modifying
+ @Query("UPDATE member_card SET " +
+ "member_card_name = COALESCE(:name, member_card_name), " +
+ "member_card_price = COALESCE(:price, member_card_price), " +
+ "member_card_validity_days = COALESCE(:durationDays, member_card_validity_days), " +
+ "member_card_total_times = COALESCE(:totalCount, member_card_total_times), " +
+ "member_card_amount = COALESCE(:denomination, member_card_amount), " +
+ "member_card_status = COALESCE(:status, member_card_status), " +
+ "updated_at = NOW() " +
+ "WHERE member_card_id = :memberCardId AND deleted_at IS NULL")
+ Mono updateSafe(Long memberCardId, String name, Double price,
+ Integer durationDays, Integer totalCount,
+ Double denomination, Integer status);
+
+ /**
+ * 批量查询上架的会员卡
+ */
+ @Query("SELECT * FROM member_card WHERE deleted_at IS NULL AND member_card_status = :status ORDER BY member_card_price ASC")
+ Flux findActiveCards(Integer status);
+}
diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/repository/MemberCardTransactionRepository.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/repository/MemberCardTransactionRepository.java
new file mode 100644
index 0000000..7f33e53
--- /dev/null
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/repository/MemberCardTransactionRepository.java
@@ -0,0 +1,121 @@
+package cn.novalon.gym.manage.member.card.repository;
+
+import cn.novalon.gym.manage.member.card.entity.MemberCardTransaction;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.r2dbc.repository.Modifying;
+import org.springframework.data.r2dbc.repository.Query;
+import org.springframework.data.r2dbc.repository.R2dbcRepository;
+import org.springframework.stereotype.Repository;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.time.LocalDateTime;
+
+/**
+ * 会员卡交易流水 Repository
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
+@Repository
+public interface MemberCardTransactionRepository extends R2dbcRepository {
+
+ /**
+ * 插入交易流水记录
+ */
+ @Modifying
+ @Query("INSERT INTO member_card_transactions (member_card_record_id, member_card_id, member_id, operation_type, change_amount, " +
+ "change_balance, after_remaining_count, after_remaining_balance, related_biz_type, source_order_id, remark, created_at) " +
+ "VALUES (:memberCardRecordId, :memberCardId, :memberId, :operationType, :changeAmount, :changeBalance, " +
+ ":afterRemainingCount, :afterRemainingBalance, :relatedBizType, :sourceOrderId, :remark, NOW()) " +
+ "RETURNING *")
+ Mono insertTransaction(Long memberCardRecordId, Long memberCardId, Long memberId,
+ String operationType, Integer changeAmount,
+ Double changeBalance, Integer afterRemainingCount,
+ Double afterRemainingBalance, String relatedBizType,
+ Long sourceOrderId, String remark);
+
+ /**
+ * 查询会员的使用记录(按时间范围)
+ */
+ @Query("SELECT * FROM member_card_transactions WHERE member_id = :memberId " +
+ "AND created_at BETWEEN :startTime AND :endTime " +
+ "ORDER BY created_at DESC LIMIT :#{#pageable.pageSize} OFFSET :#{#pageable.offset}")
+ Flux findByMemberIdAndTimeRange(Long memberId,
+ LocalDateTime startTime,
+ LocalDateTime endTime,
+ Pageable pageable);
+
+ /**
+ * 条件查询流水记录
+ */
+ @Query("SELECT * FROM member_card_transactions " +
+ "AND (:memberId IS NULL OR member_id = :memberId) " +
+ "AND (:memberCardId IS NULL OR member_card_id = :memberCardId) " +
+ "AND (:operationType IS NULL OR operation_type = :operationType) " +
+ "AND (:startTime IS NULL OR created_at >= :startTime) " +
+ "AND (:endTime IS NULL OR created_at <= :endTime) " +
+ "ORDER BY created_at DESC LIMIT :#{#pageable.pageSize} OFFSET :#{#pageable.offset}")
+ Flux findWithConditions(Long memberId, Long memberCardId,
+ String operationType,
+ LocalDateTime startTime,
+ LocalDateTime endTime,
+ Pageable pageable);
+
+ /**
+ * 统计符合条件的流水总数
+ */
+ @Query("SELECT COUNT(*) FROM member_card_transactions " +
+ "AND (:memberId IS NULL OR member_id = :memberId) " +
+ "AND (:memberCardId IS NULL OR member_card_id = :memberCardId) " +
+ "AND (:operationType IS NULL OR operation_type = :operationType) " +
+ "AND (:startTime IS NULL OR created_at >= :startTime) " +
+ "AND (:endTime IS NULL OR created_at <= :endTime)")
+ Mono countWithConditions(Long memberId, Long memberCardId,
+ String operationType,
+ LocalDateTime startTime,
+ LocalDateTime endTime);
+
+ /**
+ * 按会员卡ID查询所有流水
+ */
+ @Query("SELECT * FROM member_card_transactions WHERE member_card_id = :memberCardId ORDER BY created_at DESC")
+ Flux findByMemberCardId(Long memberCardId);
+
+ /**
+ * 按会员ID查询所有流水
+ */
+ @Query("SELECT * FROM member_card_transactions WHERE member_id = :memberId ORDER BY created_at DESC")
+ Flux findByMemberId(Long memberId);
+
+ /**
+ * 按会员卡记录ID查询所有流水
+ */
+ @Query("SELECT * FROM member_card_transactions WHERE member_card_record_id = :recordId ORDER BY created_at DESC")
+ Flux findByRecordId(Long recordId);
+
+ /**
+ * 统计某卡种的总扣次数
+ */
+ @Query("SELECT COALESCE(SUM(change_amount), 0) FROM member_card_transactions " +
+ "WHERE member_card_id = :memberCardId AND operation_type = 'DEDUCT' " +
+ "AND created_at BETWEEN :startTime AND :endTime")
+ Mono sumDeductCountByCardId(Long memberCardId,
+ LocalDateTime startTime,
+ LocalDateTime endTime);
+
+ /**
+ * 统计某时间段的续费总金额
+ */
+ @Query("SELECT COALESCE(SUM(change_balance), 0) FROM member_card_transactions " +
+ "WHERE operation_type = 'RENEW' AND created_at BETWEEN :startTime AND :endTime")
+ Mono sumRenewAmountByTimeRange(LocalDateTime startTime, LocalDateTime endTime);
+
+ /**
+ * 统计某会员的购卡总金额
+ */
+ @Query("SELECT COALESCE(SUM(change_balance), 0) FROM member_card_transactions " +
+ "WHERE member_id = :memberId AND operation_type = 'PURCHASE' " +
+ "AND created_at BETWEEN :startTime AND :endTime")
+ Mono sumPurchaseAmountByMemberId(Long memberId, LocalDateTime startTime, LocalDateTime endTime);
+}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/dao/RefundApplicationDao.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/repository/RefundApplicationRepository.java
similarity index 53%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/dao/RefundApplicationDao.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/repository/RefundApplicationRepository.java
index 3dca6d4..ae9f288 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/dao/RefundApplicationDao.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/repository/RefundApplicationRepository.java
@@ -1,63 +1,47 @@
-package cn.novalon.gym.manage.gymmembercard.dao;
+package cn.novalon.gym.manage.member.card.repository;
-import cn.novalon.gym.manage.gymmembercard.entity.RefundApplicationEntity;
+import cn.novalon.gym.manage.member.card.entity.RefundApplication;
import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.r2dbc.repository.R2dbcRepository;
+import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
- * 退款申请数据访问对象
- *
- * @author shizhounian
- * @date 2026-05-23
+ * 退款申请 Repository
+ *
+ * @author 付嘉
+ * @date 2026-05-27
*/
-public interface RefundApplicationDao extends R2dbcRepository {
+@Repository
+public interface RefundApplicationRepository extends R2dbcRepository {
/**
* 根据会员卡记录ID查询退款申请
- *
- * @param recordId 会员卡记录ID
- * @return 退款申请实体
*/
@Query("SELECT * FROM refund_application WHERE record_id = :recordId AND deleted_at IS NULL LIMIT 1")
- Mono findByRecordId(Long recordId);
+ Mono findByRecordId(Long recordId);
/**
* 根据会员ID查询退款申请列表
- *
- * @param memberId 会员ID
- * @return 退款申请列表
*/
@Query("SELECT * FROM refund_application WHERE member_id = :memberId AND deleted_at IS NULL ORDER BY created_at DESC")
- Flux findByMemberId(Long memberId);
+ Flux findByMemberId(Long memberId);
/**
* 根据状态查询退款申请列表
- *
- * @param status 状态
- * @return 退款申请列表
*/
@Query("SELECT * FROM refund_application WHERE status = :status AND deleted_at IS NULL ORDER BY created_at DESC")
- Flux findByStatus(String status);
+ Flux findByStatus(String status);
/**
- * 审核退款申请(更新状态、审核人、审核时间、备注)
- *
- * @param id 退款申请ID
- * @param status 审核状态
- * @param auditorId 审核人ID
- * @param auditRemark 审核备注
- * @return 受影响的行数
+ * 审核退款申请
*/
@Query("UPDATE refund_application SET status = :status, auditor_id = :auditorId, audit_time = NOW(), audit_remark = :auditRemark, updated_at = NOW() WHERE id = :id")
Mono approve(Long id, String status, Long auditorId, String auditRemark);
/**
* 逻辑删除退款申请
- *
- * @param id 退款申请ID
- * @return 受影响的行数
*/
@Query("UPDATE refund_application SET deleted_at = NOW() WHERE id = :id")
Mono logicalDelete(Long id);
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/IMemberCardRecordService.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/IMemberCardRecordService.java
similarity index 77%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/IMemberCardRecordService.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/IMemberCardRecordService.java
index 06e1cdd..32348f5 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/IMemberCardRecordService.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/IMemberCardRecordService.java
@@ -1,10 +1,16 @@
-package cn.novalon.gym.manage.gymmembercard.sevice;
+package cn.novalon.gym.manage.member.card.service;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardRecord;
+import cn.novalon.gym.manage.member.card.entity.MemberCardRecord;
import org.springframework.data.domain.Pageable;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
+/**
+ * 会员卡记录服务接口
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
public interface IMemberCardRecordService {
Mono findById(Long id);
@@ -19,11 +25,11 @@ public interface IMemberCardRecordService {
Mono renewCard(Long recordId, Integer addTimes, Double addAmount, java.time.LocalDateTime newExpireTime);
- Mono updateStatus(Long recordId, cn.novalon.gym.manage.gymmembercard.enums.MemberCardRecordStatus status);
+ Mono updateStatus(Long recordId, String status);
Mono validateCountCard(Long recordId, Integer requiredTimes);
Mono validateStoredCard(Long recordId, Double requiredAmount);
Flux findExpiredCards();
-}
\ No newline at end of file
+}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/IMemberCardService.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/IMemberCardService.java
similarity index 84%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/IMemberCardService.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/IMemberCardService.java
index 255dfe7..ec5a3c3 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/IMemberCardService.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/IMemberCardService.java
@@ -1,11 +1,17 @@
-package cn.novalon.gym.manage.gymmembercard.sevice;
+package cn.novalon.gym.manage.member.card.service;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCard;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardRecord;
+import cn.novalon.gym.manage.member.card.entity.MemberCard;
+import cn.novalon.gym.manage.member.card.entity.MemberCardRecord;
import org.springframework.data.domain.Pageable;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
+/**
+ * 会员卡服务接口
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
public interface IMemberCardService {
Mono findByMemberCardIdAndDeletedAtIsNull(Long memberCardId);
@@ -35,4 +41,4 @@ public interface IMemberCardService {
Mono refundCard(Long recordId);
Mono processExpiredCards();
-}
\ No newline at end of file
+}
diff --git a/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/IMemberCardTransactionService.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/IMemberCardTransactionService.java
new file mode 100644
index 0000000..516b393
--- /dev/null
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/IMemberCardTransactionService.java
@@ -0,0 +1,93 @@
+package cn.novalon.gym.manage.member.card.service;
+
+import cn.novalon.gym.manage.member.card.entity.MemberCardTransaction;
+import cn.novalon.gym.manage.member.card.enums.TransactionType;
+import org.springframework.data.domain.Pageable;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.time.LocalDateTime;
+
+/**
+ * 会员卡交易流水服务接口
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
+public interface IMemberCardTransactionService {
+
+ /**
+ * 记录每一次变动
+ * @param transaction 流水记录
+ * @return 插入的流水记录
+ */
+ Mono insertTransaction(MemberCardTransaction transaction);
+
+ /**
+ * 会员端"使用记录"
+ * @param memberId 会员ID
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @param pageable 分页参数
+ * @return 流水记录列表
+ */
+ Flux findByMemberIdAndTimeRange(Long memberId, LocalDateTime startTime,
+ LocalDateTime endTime, Pageable pageable);
+
+ /**
+ * 后台"使用记录查询"
+ * @param memberId 会员ID
+ * @param memberCardId 会员卡ID
+ * @param operationType 操作类型
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @param pageable 分页参数
+ * @return 流水记录列表
+ */
+ Flux findWithConditions(Long memberId, Long memberCardId,
+ TransactionType operationType,
+ LocalDateTime startTime, LocalDateTime endTime,
+ Pageable pageable);
+
+ /**
+ * 统计符合条件的流水总数
+ */
+ Mono countWithConditions(Long memberId, Long memberCardId,
+ TransactionType operationType,
+ LocalDateTime startTime, LocalDateTime endTime);
+
+ /**
+ * 按会员卡ID查询所有流水记录
+ */
+ Flux findByMemberCardId(Long memberCardId);
+
+ /**
+ * 数据统计 - 统计某卡种的总扣次数
+ */
+ Mono sumDeductCountByCardId(Long memberCardId, LocalDateTime startTime, LocalDateTime endTime);
+
+ /**
+ * 数据统计 - 统计某时间段的续费总金额
+ */
+ Mono sumRenewAmountByTimeRange(LocalDateTime startTime, LocalDateTime endTime);
+
+ /**
+ * 数据统计 - 统计某会员的购卡总金额
+ */
+ Mono sumPurchaseAmountByMemberId(Long memberId, LocalDateTime startTime, LocalDateTime endTime);
+
+ /**
+ * 创建交易记录
+ */
+ Mono createTransaction(MemberCardTransaction transaction);
+
+ /**
+ * 查询会员的交易记录
+ */
+ Flux findByMemberId(Long memberId);
+
+ /**
+ * 查询会员卡记录的交易历史
+ */
+ Flux findByRecordId(Long recordId);
+}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/IRefundApplicationService.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/IRefundApplicationService.java
similarity index 75%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/IRefundApplicationService.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/IRefundApplicationService.java
index 56fa066..669a42b 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/IRefundApplicationService.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/IRefundApplicationService.java
@@ -1,13 +1,13 @@
-package cn.novalon.gym.manage.gymmembercard.sevice;
+package cn.novalon.gym.manage.member.card.service;
-import cn.novalon.gym.manage.gymmembercard.domain.RefundApplication;
+import cn.novalon.gym.manage.member.card.entity.RefundApplication;
import reactor.core.publisher.Mono;
/**
- * 退款申请服务
- *
- * @author shizhounian
- * @date 2026-05-23
+ * 退款申请服务接口
+ *
+ * @author 付嘉
+ * @date 2026-05-27
*/
public interface IRefundApplicationService {
@@ -30,4 +30,4 @@ public interface IRefundApplicationService {
* 根据记录ID查询申请
*/
Mono findByRecordId(Long recordId);
-}
\ No newline at end of file
+}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/impl/MemberCardRecordServiceImpl.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/impl/MemberCardRecordServiceImpl.java
similarity index 69%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/impl/MemberCardRecordServiceImpl.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/impl/MemberCardRecordServiceImpl.java
index 598c435..874a342 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/impl/MemberCardRecordServiceImpl.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/impl/MemberCardRecordServiceImpl.java
@@ -1,10 +1,8 @@
-package cn.novalon.gym.manage.gymmembercard.sevice.impl;
+package cn.novalon.gym.manage.member.card.service.impl;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardRecord;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardRecordStatus;
-import cn.novalon.gym.manage.gymmembercard.repository.IMemberCardRecordRepository;
-import cn.novalon.gym.manage.gymmembercard.sevice.IMemberCardRecordService;
-import org.springframework.beans.factory.annotation.Qualifier;
+import cn.novalon.gym.manage.member.card.entity.MemberCardRecord;
+import cn.novalon.gym.manage.member.card.repository.MemberCardRecordRepository;
+import cn.novalon.gym.manage.member.card.service.IMemberCardRecordService;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
@@ -12,17 +10,45 @@ import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
+/**
+ * 会员卡记录服务实现
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
@Service
public class MemberCardRecordServiceImpl implements IMemberCardRecordService {
- private final IMemberCardRecordRepository memberCardRecordRepository;
+ private final MemberCardRecordRepository memberCardRecordRepository;
- public MemberCardRecordServiceImpl(IMemberCardRecordRepository memberCardRecordRepository) {
+ public MemberCardRecordServiceImpl(MemberCardRecordRepository memberCardRecordRepository) {
this.memberCardRecordRepository = memberCardRecordRepository;
}
+ @Override
+ public Mono findById(Long recordId) {
+ return memberCardRecordRepository.findById(recordId);
+ }
+
+ @Override
+ public Flux findByMemberId(Long memberId, Pageable pageable) {
+ return memberCardRecordRepository.findByMemberId(memberId, pageable);
+ }
+
+ @Override
+ public Flux findActiveCardsByMemberId(Long memberId) {
+ return memberCardRecordRepository.findActiveCardsByMemberId(memberId);
+ }
+
@Override
public Mono insertActiveRecord(MemberCardRecord record) {
- return memberCardRecordRepository.insertActiveRecord(record);
+ return memberCardRecordRepository.insertActiveRecord(
+ record.getMemberId(),
+ record.getMemberCardId(),
+ record.getExpireTime(),
+ record.getRemainingTimes(),
+ record.getRemainingAmount(),
+ record.getSourceOrderId()
+ );
}
@Override
@@ -36,20 +62,10 @@ public class MemberCardRecordServiceImpl implements IMemberCardRecordService {
}
@Override
- public Mono updateStatus(Long recordId, MemberCardRecordStatus status) {
+ public Mono updateStatus(Long recordId, String status) {
return memberCardRecordRepository.updateStatus(recordId, status);
}
- @Override
- public Flux findActiveCardsByMemberId(Long memberId) {
- return memberCardRecordRepository.findActiveCardsByMemberId(memberId);
- }
-
- @Override
- public Flux findByMemberId(Long memberId, Pageable pageable) {
- return memberCardRecordRepository.findByMemberId(memberId, pageable);
- }
-
@Override
public Mono validateCountCard(Long recordId, Integer requiredTimes) {
return memberCardRecordRepository.validateCountCard(recordId, requiredTimes);
@@ -64,9 +80,4 @@ public class MemberCardRecordServiceImpl implements IMemberCardRecordService {
public Flux findExpiredCards() {
return memberCardRecordRepository.findExpiredCards();
}
-
- @Override
- public Mono findById(Long recordId) {
- return memberCardRecordRepository.findById(recordId);
- }
}
diff --git a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/impl/MemberCardServiceImpl.java b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/impl/MemberCardServiceImpl.java
similarity index 78%
rename from gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/impl/MemberCardServiceImpl.java
rename to gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/impl/MemberCardServiceImpl.java
index 379dded..939704d 100644
--- a/gym-manage-api/gym-member-card/src/main/java/cn/novalon/gym/manage/gymmembercard/sevice/impl/MemberCardServiceImpl.java
+++ b/gym-manage-api/gym-member/src/main/java/cn/novalon/gym/manage/member/card/service/impl/MemberCardServiceImpl.java
@@ -1,20 +1,20 @@
-package cn.novalon.gym.manage.gymmembercard.sevice.impl;
+package cn.novalon.gym.manage.member.card.service.impl;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCard;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardRecord;
-import cn.novalon.gym.manage.gymmembercard.domain.MemberCardTransactions;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardEvent;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardRecordStatus;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardTransactionsAction;
-import cn.novalon.gym.manage.gymmembercard.enums.MemberCardType;
-import cn.novalon.gym.manage.gymmembercard.handler.DistributedLockService;
-import cn.novalon.gym.manage.gymmembercard.handler.ExpirationReminderService;
-import cn.novalon.gym.manage.gymmembercard.handler.MemberCardStateMachine;
-import cn.novalon.gym.manage.gymmembercard.handler.RefundSagaHandler;
-import cn.novalon.gym.manage.gymmembercard.repository.IMemberCardRecordRepository;
-import cn.novalon.gym.manage.gymmembercard.repository.IMemberCardRepository;
-import cn.novalon.gym.manage.gymmembercard.sevice.IMemberCardService;
-import cn.novalon.gym.manage.gymmembercard.sevice.IMemberCardTransactionsService;
+import cn.novalon.gym.manage.member.card.entity.MemberCard;
+import cn.novalon.gym.manage.member.card.entity.MemberCardRecord;
+import cn.novalon.gym.manage.member.card.entity.MemberCardTransaction;
+import cn.novalon.gym.manage.member.card.enums.CardEvent;
+import cn.novalon.gym.manage.member.card.enums.MemberCardRecordStatus;
+import cn.novalon.gym.manage.member.card.enums.MemberCardType;
+import cn.novalon.gym.manage.member.card.enums.TransactionType;
+import cn.novalon.gym.manage.member.card.handler.DistributedLockService;
+import cn.novalon.gym.manage.member.card.handler.ExpirationReminderService;
+import cn.novalon.gym.manage.member.card.handler.MemberCardStateMachine;
+import cn.novalon.gym.manage.member.card.handler.RefundSagaHandler;
+import cn.novalon.gym.manage.member.card.repository.MemberCardRecordRepository;
+import cn.novalon.gym.manage.member.card.repository.MemberCardRepository;
+import cn.novalon.gym.manage.member.card.service.IMemberCardService;
+import cn.novalon.gym.manage.member.card.service.IMemberCardTransactionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
@@ -23,27 +23,33 @@ import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
+/**
+ * 会员卡服务实现
+ *
+ * @author 付嘉
+ * @date 2026-05-27
+ */
@Slf4j
@Service
public class MemberCardServiceImpl implements IMemberCardService {
- private final IMemberCardRepository memberCardRepository;
- private final IMemberCardRecordRepository recordRepository;
- private final IMemberCardTransactionsService transactionsService;
+ private final MemberCardRepository memberCardRepository;
+ private final MemberCardRecordRepository recordRepository;
+ private final IMemberCardTransactionService transactionService;
private final MemberCardStateMachine stateMachine;
private final DistributedLockService distributedLockService;
private final ExpirationReminderService expirationReminderService;
private final RefundSagaHandler refundSagaHandler;
- public MemberCardServiceImpl(IMemberCardRepository memberCardRepository,
- IMemberCardRecordRepository recordRepository,
- IMemberCardTransactionsService transactionsService,
+ public MemberCardServiceImpl(MemberCardRepository memberCardRepository,
+ MemberCardRecordRepository recordRepository,
+ IMemberCardTransactionService transactionService,
MemberCardStateMachine stateMachine,
DistributedLockService distributedLockService,
ExpirationReminderService expirationReminderService,
RefundSagaHandler refundSagaHandler) {
this.memberCardRepository = memberCardRepository;
this.recordRepository = recordRepository;
- this.transactionsService = transactionsService;
+ this.transactionService = transactionService;
this.stateMachine = stateMachine;
this.distributedLockService = distributedLockService;
this.expirationReminderService = expirationReminderService;
@@ -109,7 +115,7 @@ public class MemberCardServiceImpl implements IMemberCardService {
Mono.defer(() -> createCardRecord(memberId, memberCardId, sourceOrderId, card))
);
})
- .flatMap(record -> createTransaction(record, MemberCardTransactionsAction.PURCHASE, "购买会员卡")
+ .flatMap(record -> createTransaction(record, TransactionType.PURCHASE, "购买会员卡")
.thenReturn(record))
.flatMap(record -> expirationReminderService.scheduleExpirationReminder(record)
.then(Mono.just(record)));
@@ -118,12 +124,13 @@ public class MemberCardServiceImpl implements IMemberCardService {
private Mono createCardRecord(Long memberId, Long memberCardId,
Long sourceOrderId, MemberCard card) {
return Mono.defer(() -> {
- MemberCardRecord record = new MemberCardRecord();
- record.setMemberId(memberId);
- record.setMemberCardId(memberCardId);
- record.setSourceOrderId(sourceOrderId);
- record.setPurchaseTime(LocalDateTime.now());
- record.setStatus(MemberCardRecordStatus.ACTIVE);
+ MemberCardRecord record = MemberCardRecord.builder()
+ .memberId(memberId)
+ .memberCardId(memberCardId)
+ .sourceOrderId(sourceOrderId)
+ .purchaseTime(LocalDateTime.now())
+ .status(MemberCardRecordStatus.ACTIVE)
+ .build();
MemberCardType cardType = MemberCardType.valueOf(card.getMemberCardType());
LocalDateTime now = LocalDateTime.now();
@@ -148,7 +155,14 @@ public class MemberCardServiceImpl implements IMemberCardService {
return Mono.error(new RuntimeException("不支持的会员卡类型"));
}
- return recordRepository.insertActiveRecord(record);
+ return recordRepository.insertActiveRecord(
+ record.getMemberId(),
+ record.getMemberCardId(),
+ record.getExpireTime(),
+ record.getRemainingTimes(),
+ record.getRemainingAmount(),
+ record.getSourceOrderId()
+ );
});
}
@@ -157,7 +171,7 @@ public class MemberCardServiceImpl implements IMemberCardService {
Integer addDays, Long sourceOrderId) {
return recordRepository.findById(recordId)
.switchIfEmpty(Mono.error(new RuntimeException("会员卡记录不存在")))
- .flatMap(originalRecord -> stateMachine.validateTransition(originalRecord, MemberCardEvent.RENEW)
+ .flatMap(originalRecord -> stateMachine.validateTransition(originalRecord, CardEvent.RENEW)
.then(Mono.just(originalRecord)))
.flatMap(originalRecord -> memberCardRepository.findByMemberCardIdAndDeletedAtIsNull(originalRecord.getMemberCardId())
.switchIfEmpty(Mono.error(new RuntimeException("会员卡类型不存在")))
@@ -188,7 +202,7 @@ public class MemberCardServiceImpl implements IMemberCardService {
int currentTimes = record.getRemainingTimes() != null ? record.getRemainingTimes() : 0;
int timesToAdd = addTimes != null ? addTimes : card.getMemberCardTotalTimes();
record.setRemainingTimes(currentTimes + timesToAdd);
- if (record.getStatus() == MemberCardRecordStatus.USED_UP) {
+ if (MemberCardRecordStatus.USED_UP.equals(record.getStatus())) {
record.setStatus(MemberCardRecordStatus.ACTIVE);
}
break;
@@ -196,7 +210,7 @@ public class MemberCardServiceImpl implements IMemberCardService {
double currentAmount = record.getRemainingAmount() != null ? record.getRemainingAmount() : 0.0;
double amountToAdd = addAmount != null ? addAmount : card.getMemberCardAmount();
record.setRemainingAmount(currentAmount + amountToAdd);
- if (record.getStatus() == MemberCardRecordStatus.USED_UP) {
+ if (MemberCardRecordStatus.USED_UP.equals(record.getStatus())) {
record.setStatus(MemberCardRecordStatus.ACTIVE);
}
break;
@@ -205,7 +219,7 @@ public class MemberCardServiceImpl implements IMemberCardService {
}
return recordRepository.save(record)
- .flatMap(updatedRecord -> createTransaction(updatedRecord, MemberCardTransactionsAction.RENEW, "续费会员卡")
+ .flatMap(updatedRecord -> createTransaction(updatedRecord, TransactionType.RENEW, "续费会员卡")
.then(expirationReminderService.scheduleExpirationReminder(updatedRecord))
.thenReturn(updatedRecord));
}
@@ -214,7 +228,7 @@ public class MemberCardServiceImpl implements IMemberCardService {
public Mono useCard(Long recordId, Integer deductTimes, Double deductAmount) {
return recordRepository.findById(recordId)
.switchIfEmpty(Mono.error(new RuntimeException("会员卡记录不存在")))
- .flatMap(record -> stateMachine.validateTransition(record, MemberCardEvent.USE)
+ .flatMap(record -> stateMachine.validateTransition(record, CardEvent.USE)
.then(Mono.just(record)))
.flatMap(record -> memberCardRepository.findByMemberCardIdAndDeletedAtIsNull(record.getMemberCardId())
.switchIfEmpty(Mono.error(new RuntimeException("会员卡类型不存在")))
@@ -231,7 +245,7 @@ public class MemberCardServiceImpl implements IMemberCardService {
private Mono