diff --git a/gym-manage-api/manage-app/src/main/java/cn/novalon/gym/manage/app/config/SystemRouter.java b/gym-manage-api/manage-app/src/main/java/cn/novalon/gym/manage/app/config/SystemRouter.java index c869da3..98c3859 100644 --- a/gym-manage-api/manage-app/src/main/java/cn/novalon/gym/manage/app/config/SystemRouter.java +++ b/gym-manage-api/manage-app/src/main/java/cn/novalon/gym/manage/app/config/SystemRouter.java @@ -5,6 +5,7 @@ import cn.novalon.gym.manage.sys.handler.auth.PasswordDiagnosticHandler; import cn.novalon.gym.manage.sys.handler.config.SysConfigHandler; import cn.novalon.gym.manage.sys.handler.dictionary.DictionaryHandler; import cn.novalon.gym.manage.sys.handler.dict.SysDictHandler; +import cn.novalon.gym.manage.sys.handler.groupCourse.GroupCourseHandler; import cn.novalon.gym.manage.sys.handler.log.SysLogHandler; import cn.novalon.gym.manage.sys.handler.log.OperationLogHandler; import cn.novalon.gym.manage.sys.handler.menu.MenuHandler; @@ -51,7 +52,8 @@ public class SystemRouter { SysUserMessageHandler messageHandler, SysFileHandler fileHandler, SysPermissionHandler permissionHandler, - PasswordDiagnosticHandler passwordDiagnosticHandler) { + PasswordDiagnosticHandler passwordDiagnosticHandler, + GroupCourseHandler groupCourseHandler) { return route() // ========== 诊断路由 ========== @@ -192,6 +194,9 @@ public class SystemRouter { .POST("/api/permissions", permissionHandler::createPermission) .PUT("/api/permissions/{id}", permissionHandler::updatePermission) .DELETE("/api/permissions/{id}", permissionHandler::deletePermission) + + // ========== 团课路由 ========== + .GET("/api/groupCourse", groupCourseHandler::getAllGroupCourse) .build(); } diff --git a/gym-manage-api/manage-app/src/main/resources/application-dev.yml b/gym-manage-api/manage-app/src/main/resources/application-dev.yml index 8f5e8dc..9cfe50c 100644 --- a/gym-manage-api/manage-app/src/main/resources/application-dev.yml +++ b/gym-manage-api/manage-app/src/main/resources/application-dev.yml @@ -12,6 +12,9 @@ spring: max-life-time: 30m acquire-timeout: 3s flyway: + url: jdbc:postgresql://localhost:55432/manage_system + user: novalon + password: novalon123 enabled: true locations: classpath:db/migration baseline-on-migrate: true diff --git a/gym-manage-api/manage-app/src/main/resources/application.yml b/gym-manage-api/manage-app/src/main/resources/application.yml index 9305b16..0d7edda 100644 --- a/gym-manage-api/manage-app/src/main/resources/application.yml +++ b/gym-manage-api/manage-app/src/main/resources/application.yml @@ -25,8 +25,8 @@ spring: acquire-timeout: 5s datasource: url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:55432}/${DB_NAME:manage_system} - username: ${DB_USERNAME:postgres} - password: ${DB_PASSWORD:postgres} + username: ${DB_USERNAME:novalon} + password: ${DB_PASSWORD:novalon123} driver-class-name: org.postgresql.Driver flyway: enabled: true @@ -38,6 +38,8 @@ spring: user: name: disabled password: disabled + profiles: + active: dev management: endpoints: diff --git a/gym-manage-api/manage-db/pom.xml b/gym-manage-api/manage-db/pom.xml index 392f5e3..2c54f5b 100644 --- a/gym-manage-api/manage-db/pom.xml +++ b/gym-manage-api/manage-db/pom.xml @@ -99,6 +99,8 @@ spring-boot-starter-test test + + diff --git a/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/converter/GroupCourseConverter.java b/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/converter/GroupCourseConverter.java new file mode 100644 index 0000000..87b66ad --- /dev/null +++ b/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/converter/GroupCourseConverter.java @@ -0,0 +1,55 @@ +package cn.novalon.gym.manage.db.converter;/* + * @author:liwentao + * @date:2026/4/26-04-26-13:18 + */ + +import cn.hutool.core.bean.BeanUtil; +import cn.novalon.gym.manage.db.entity.GroupCourseEntity; +import cn.novalon.gym.manage.sys.core.domain.GroupCourse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class GroupCourseConverter { + public GroupCourse toDomain(GroupCourseEntity entity){ + if(entity == null){ + return null; + } + GroupCourse groupCourse = new GroupCourse(); + BeanUtil.copyProperties(entity,groupCourse); + log.info("转换bean,entity-domain:",groupCourse); + return groupCourse; + } + + public GroupCourseEntity toEntity(GroupCourse domain){ + if(domain == null){ + return null; + } + GroupCourseEntity entity = new GroupCourseEntity(); + BeanUtil.copyProperties(domain,entity); + log.info("转换bean,domain-entity:",entity); + return entity; + } + + public List toDomainList(List entities){ + if (entities == null) { + return null; + } + return entities.stream() + .map(this::toDomain) + .collect(Collectors.toList()); + } + + public List toEntityList(List groupCourses){ + if (groupCourses == null) { + return null; + } + return groupCourses.stream() + .map(this::toEntity) + .collect(Collectors.toList()); + } +} diff --git a/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/dao/GroupCourseDao.java b/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/dao/GroupCourseDao.java new file mode 100644 index 0000000..0855162 --- /dev/null +++ b/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/dao/GroupCourseDao.java @@ -0,0 +1,23 @@ +package cn.novalon.gym.manage.db.dao; + +import cn.novalon.gym.manage.db.entity.GroupCourseEntity; +import cn.novalon.gym.manage.db.entity.SysUserEntity; +import org.springframework.data.domain.Sort; +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 GroupCourseDao extends R2dbcRepository { + + Mono findByIdIsAndDeletedAtIsNull(Long id); + + Flux findAll(); + + Flux findAll(Sort sort); + + Flux findAllByDeletedAtIsNull(); + + Flux findAllByDeletedAtIsNull(Sort sort); +} diff --git a/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/entity/GroupCourseBookingEntity.java b/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/entity/GroupCourseBookingEntity.java new file mode 100644 index 0000000..f414735 --- /dev/null +++ b/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/entity/GroupCourseBookingEntity.java @@ -0,0 +1,75 @@ +package cn.novalon.gym.manage.db.entity; + +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +import java.util.Date; + +/** + * @author:liwentao + * @date:2026/4/25-04-25-17:50 + * 团课预约记录表 + */ + +@Table("group_course_booking") +public class GroupCourseBookingEntity extends BaseEntity { + + //团课id + @Column("course_id") + private Long courseId; + + //用户id + @Column("user_id") + private Long userId; + + //预约时间 + @Column("booking_time") + private Date bookingTime; + + //状态:0-已预约,1-已取消,2-已出席,3-缺席 + @Column("status") + private Long status; + //取消时间 + @Column("cancel_time") + private Date cancelTime; + + public Long getCourseId() { + return courseId; + } + + public void setCourseId(Long courseId) { + this.courseId = courseId; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public Date getBookingTime() { + return bookingTime; + } + + public void setBookingTime(Date bookingTime) { + this.bookingTime = bookingTime; + } + + public Long getStatus() { + return status; + } + + public void setStatus(Long status) { + this.status = status; + } + + public Date getCancelTime() { + return cancelTime; + } + + public void setCancelTime(Date cancelTime) { + this.cancelTime = cancelTime; + } +} diff --git a/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/entity/GroupCourseEntity.java b/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/entity/GroupCourseEntity.java new file mode 100644 index 0000000..67cc612 --- /dev/null +++ b/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/entity/GroupCourseEntity.java @@ -0,0 +1,148 @@ +package cn.novalon.gym.manage.db.entity; +/** + * @author:liwentao + * @date:2026/4/25-04-25-17:34 + * 团课表 + */ + +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +import java.time.LocalDateTime; +import java.util.Date; + +@Table("group_course") +public class GroupCourseEntity extends BaseEntity { + + //课程名称 + @Column("course_name") + private String courseName; + + //教练id + @Column("coach_id") + private Long coachId; + + //课程类型 + @Column("course_type") + private Long courseType; + + //开始时间 + @Column("start_time") + private LocalDateTime startTime; + + //结束时间 + @Column("end_time") + private LocalDateTime endTime; + + //最大参与人数 + @Column("max_members") + private Integer maxMembers; + + //当前参与人数 + @Column("current_members") + private Integer currentMembers; + + //课程状态:0-正常,1-已取消,2-已结束 + @Column("status") + private Long status; + + //上课地点 + @Column("location") + private String location; + + //封面图URL + @Column("cover_image") + private String coverImage; + + //课程描述 + @Column("description") + private String description; + + public String getCourseName() { + return courseName; + } + + public void setCourseName(String courseName) { + this.courseName = courseName; + } + + public Long getCoachId() { + return coachId; + } + + public void setCoachId(Long coachId) { + this.coachId = coachId; + } + + public Long getCourseType() { + return courseType; + } + + public void setCourseType(Long courseType) { + this.courseType = courseType; + } + + public LocalDateTime getStartTime() { + return startTime; + } + + public void setStartTime(LocalDateTime startTime) { + this.startTime = startTime; + } + + public LocalDateTime getEndTime() { + return endTime; + } + + public void setEndTime(LocalDateTime endTime) { + this.endTime = endTime; + } + + public Integer getMaxMembers() { + return maxMembers; + } + + public void setMaxMembers(Integer maxMembers) { + this.maxMembers = maxMembers; + } + + public Integer getCurrentMembers() { + return currentMembers; + } + + public void setCurrentMembers(Integer currentMembers) { + this.currentMembers = currentMembers; + } + + public Long getStatus() { + return status; + } + + public void setStatus(Long status) { + this.status = status; + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getCoverImage() { + return coverImage; + } + + public void setCoverImage(String coverImage) { + this.coverImage = coverImage; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/repository/GroupCourseRepository.java b/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/repository/GroupCourseRepository.java new file mode 100644 index 0000000..d4846b9 --- /dev/null +++ b/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/repository/GroupCourseRepository.java @@ -0,0 +1,57 @@ +package cn.novalon.gym.manage.db.repository; + +import cn.novalon.gym.manage.db.converter.GroupCourseConverter; +import cn.novalon.gym.manage.db.dao.GroupCourseDao; +import cn.novalon.gym.manage.sys.core.domain.GroupCourse; +import cn.novalon.gym.manage.sys.core.repository.IGroupCourseRepository; +import org.springframework.data.domain.Sort; +import org.springframework.data.r2dbc.core.R2dbcEntityTemplate; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * @author:liwentao + * @date:2026/4/26-04-26-14:16 + */ +@Repository +public class GroupCourseRepository implements IGroupCourseRepository { + private final GroupCourseDao groupCourseDao; + private final GroupCourseConverter groupCourseConverter; + private final R2dbcEntityTemplate r2dbcEntityTemplate; + + public GroupCourseRepository(GroupCourseDao groupCourseDao,GroupCourseConverter groupCourseConverter, + R2dbcEntityTemplate r2dbcEntityTemplate){ + this.groupCourseDao = groupCourseDao; + this.groupCourseConverter = groupCourseConverter; + this.r2dbcEntityTemplate = r2dbcEntityTemplate; + } + + @Override + public Mono findByIdAndDeletedAtIsNull(Long id) { + return groupCourseDao.findByIdIsAndDeletedAtIsNull(id) + .map(groupCourseConverter::toDomain); + } + + @Override + public Flux findAll() { + return groupCourseDao.findAll() + .map(groupCourseConverter::toDomain); + } + + public Flux findAll(Sort sort) { + return groupCourseDao.findAll(sort) + .map(groupCourseConverter::toDomain); + } + + @Override + public Flux findByDeletedAtIsNull() { + return groupCourseDao.findAllByDeletedAtIsNull() + .map(groupCourseConverter::toDomain); + } + + public Flux findByDeletedAtIsNull(Sort sort) { + return groupCourseDao.findAllByDeletedAtIsNull(sort) + .map(groupCourseConverter::toDomain); + } +} diff --git a/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/repository/SysUserRepository.java b/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/repository/SysUserRepository.java index c0feccc..2fb85ee 100644 --- a/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/repository/SysUserRepository.java +++ b/gym-manage-api/manage-db/src/main/java/cn/novalon/gym/manage/db/repository/SysUserRepository.java @@ -10,6 +10,7 @@ import cn.novalon.gym.manage.sys.core.query.SysUserQuery; import cn.novalon.gym.manage.sys.core.repository.ISysUserRepository; import cn.novalon.gym.manage.common.dto.PageRequest; import cn.novalon.gym.manage.common.dto.PageResponse; +import cn.novalon.gym.manage.sys.dto.response.UserResponse; import org.springframework.data.domain.Sort; import org.springframework.data.r2dbc.core.R2dbcEntityTemplate; import org.springframework.data.relational.core.query.Query; diff --git a/gym-manage-api/manage-db/src/main/resources/db/migration/V6__Create_GroupCourse_table.sql b/gym-manage-api/manage-db/src/main/resources/db/migration/V6__Create_GroupCourse_table.sql new file mode 100644 index 0000000..4b82d66 --- /dev/null +++ b/gym-manage-api/manage-db/src/main/resources/db/migration/V6__Create_GroupCourse_table.sql @@ -0,0 +1,71 @@ +-- ============================================ +-- 团课相关表 +-- ============================================ + +-- 团课课程表 +CREATE TABLE IF NOT EXISTS group_course ( + id BIGSERIAL PRIMARY KEY, + course_name VARCHAR(100) NOT NULL, + coach_id BIGINT, + course_type BIGINT, + start_time TIMESTAMP NOT NULL, + end_time TIMESTAMP NOT NULL, + max_members INTEGER DEFAULT 20, + current_members INTEGER DEFAULT 0, + status VARCHAR(1) DEFAULT '0', + location VARCHAR(255), + cover_image VARCHAR(500), + description TEXT, + create_by VARCHAR(50), + update_by VARCHAR(50), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP +); + +-- 团课预约记录表 +CREATE TABLE IF NOT EXISTS group_course_booking ( + id BIGSERIAL PRIMARY KEY, + course_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + booking_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + status VARCHAR(1) DEFAULT '0', + cancel_time TIMESTAMP, + create_by VARCHAR(50), + update_by VARCHAR(50), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP +); + +COMMENT ON TABLE group_course IS '团课课程表'; +COMMENT ON COLUMN group_course.id IS '主键ID'; +COMMENT ON COLUMN group_course.course_name IS '课程名称'; +COMMENT ON COLUMN group_course.coach_id IS '教练ID(关联sys_user)'; +COMMENT ON COLUMN group_course.course_type IS '课程类型(如瑜伽/普拉提/动感单车)'; +COMMENT ON COLUMN group_course.start_time IS '开始时间'; +COMMENT ON COLUMN group_course.end_time IS '结束时间'; +COMMENT ON COLUMN group_course.max_members IS '最大参与人数'; +COMMENT ON COLUMN group_course.current_members IS '当前参与人数'; +COMMENT ON COLUMN group_course.status IS '状态(0正常 1已取消 2已结束)'; +COMMENT ON COLUMN group_course.location IS '上课地点'; +COMMENT ON COLUMN group_course.cover_image IS '封面图URL'; +COMMENT ON COLUMN group_course.description IS '课程描述'; +COMMENT ON COLUMN group_course.create_by IS '创建人'; +COMMENT ON COLUMN group_course.update_by IS '更新人'; +COMMENT ON COLUMN group_course.created_at IS '创建时间'; +COMMENT ON COLUMN group_course.updated_at IS '更新时间'; +COMMENT ON COLUMN group_course.deleted_at IS '删除时间(软删除)'; + +COMMENT ON TABLE group_course_booking IS '团课预约记录表'; +COMMENT ON COLUMN group_course_booking.id IS '主键ID'; +COMMENT ON COLUMN group_course_booking.course_id IS '团课ID'; +COMMENT ON COLUMN group_course_booking.user_id IS '用户ID'; +COMMENT ON COLUMN group_course_booking.booking_time IS '预约时间'; +COMMENT ON COLUMN group_course_booking.status IS '状态(0已预约 1已取消 2已出席 3缺席)'; +COMMENT ON COLUMN group_course_booking.cancel_time IS '取消时间'; +COMMENT ON COLUMN group_course_booking.create_by IS '创建人'; +COMMENT ON COLUMN group_course_booking.update_by IS '更新人'; +COMMENT ON COLUMN group_course_booking.created_at IS '创建时间'; +COMMENT ON COLUMN group_course_booking.updated_at IS '更新时间'; +COMMENT ON COLUMN group_course_booking.deleted_at IS '删除时间(软删除)'; \ No newline at end of file diff --git a/gym-manage-api/manage-db/src/main/resources/db/migration/V7__Insert_GroupCourse_test_data.sql b/gym-manage-api/manage-db/src/main/resources/db/migration/V7__Insert_GroupCourse_test_data.sql new file mode 100644 index 0000000..30d85c7 --- /dev/null +++ b/gym-manage-api/manage-db/src/main/resources/db/migration/V7__Insert_GroupCourse_test_data.sql @@ -0,0 +1,19 @@ +-- 测试数据1: 进行中的瑜伽课程 (已有部分学员) +INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at) VALUES + ('清晨流瑜伽', 101, 1, '2026-05-10 09:00:00', '2026-05-10 10:30:00', 15, 8, '1', 'A座3楼瑜伽教室', '/images/yoga_flow.jpg', '适合有一定基础的学员,通过流畅的体式连接呼吸,唤醒身体能量。', 'admin', '2026-05-01 10:00:00', '2026-05-01 10:00:00'); + +-- 测试数据2: 即将开始的搏击课 (几乎满员) +INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at) VALUES + ('燃脂搏击', 102, 2, '2026-05-12 18:30:00', '2026-05-12 19:30:00', 20, 19, '1', '综合训练区', '/images/kickboxing.jpg', '高强度间歇训练,配合音乐快速燃脂,释放压力。', 'coach_zhang', '2026-05-02 14:30:00', '2026-05-02 14:30:00'); + +-- 测试数据3: 已结束的私教小团课 (课程号已满) +INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at) VALUES + ('蜜桃臀塑造', 103, 3, '2026-04-25 19:00:00', '2026-04-25 20:00:00', 10, 10, '2', '私教专区', '/images/glute.jpg', '针对性训练臀部肌肉群,打造完美臀线。小班教学,动作一对一纠正。', 'coach_li', '2026-04-20 09:15:00', '2026-04-20 09:15:00'); + +-- 测试数据4: 即将开始的动感单车 (名额充足,尚未有人报名) +INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at) VALUES + ('极速燃脂单车', 104, 2, '2026-05-15 19:30:00', '2026-05-15 20:20:00', 25, 0, '0', '单车房', '/images/spinning.jpg', '跟随音乐节奏变换阻力和速度,体验爬坡与冲刺的快感,一节课消耗800大卡。', 'admin', '2026-05-06 11:00:00', '2026-05-06 11:00:00'); + +-- 测试数据5: 已删除/作废的课程 (deleted_at 不为空) +INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at, deleted_at) VALUES + ('周末冥想修复', 101, 1, '2026-05-03 15:00:00', '2026-05-03 16:00:00', 12, 3, '3', '冥想室', '/images/meditation.jpg', '通过呼吸和正念冥想,深度放松身心,缓解一周疲劳。', 'coach_wang', '2026-04-28 08:00:00', '2026-04-28 08:00:00', '2026-04-29 16:20:00'); \ No newline at end of file diff --git a/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/config/SecurityConfig.java b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/config/SecurityConfig.java index 4df2a4b..b68cf04 100644 --- a/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/config/SecurityConfig.java +++ b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/config/SecurityConfig.java @@ -50,7 +50,11 @@ public class SecurityConfig { spec.pathMatchers("/api/auth/**").permitAll() .pathMatchers("/api/public/**").permitAll() .pathMatchers("/ws/**").permitAll() - .pathMatchers("/actuator/**").permitAll(); + .pathMatchers("/actuator/**").permitAll() + //========TODO lwt 以下是测试接口,生产时必关======== + .pathMatchers("/api/users/**").permitAll() + .pathMatchers("/api/groupCourse/**").permitAll(); + if (isDevOrTest) { spec.pathMatchers("/swagger-ui.html").permitAll() diff --git a/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/domain/GroupCourse.java b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/domain/GroupCourse.java new file mode 100644 index 0000000..11b9949 --- /dev/null +++ b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/domain/GroupCourse.java @@ -0,0 +1,146 @@ +package cn.novalon.gym.manage.sys.core.domain; +/** + * @author:liwentao + * @date:2026/4/26-04-26-13:20 + */ + +import io.swagger.v3.oas.annotations.media.Schema; +import org.springframework.data.relational.core.mapping.Column; + +import java.time.LocalDateTime; +import java.util.Date; +@Schema(description = "") +public class GroupCourse extends BaseDomain{ + + //课程名称 + @Schema(description = "团课名", example = "Push-up") + private String courseName; + + //教练id + @Schema(description = "教练id", example = "1") + private Long coachId; + + //课程类型 + @Schema(description = "课程类型", example = "1") + private Long courseType; + + //开始时间 + @Schema(description = "开始时间", example = "2026-01-01") + private LocalDateTime startTime; + + //结束时间 + @Schema(description = "结束时间", example = "2026-01-02") + private LocalDateTime endTime; + + //最大参与人数 + @Schema(description = "最大参与人数", example = "20") + private Integer maxMembers; + + //当前参与人数 + @Schema(description = "当前参与人数", example = "2") + private Integer currentMembers; + + //课程状态:0-正常,1-已取消,2-已结束 + @Schema(description = "课程状态", example = "0") + private Long status; + + //上课地点 + @Schema(description = "上课地点", example = "龙泉驿区幸福路") + private String location; + + //封面图URL + @Schema(description = "封面图URL", example = "https://12345.com") + private String coverImage; + + //课程描述 + @Schema(description = "课程描述", example = "从入门到入土") + private String description; + + public String getCourseName() { + return courseName; + } + + public void setCourseName(String courseName) { + this.courseName = courseName; + } + + public Long getCoachId() { + return coachId; + } + + public void setCoachId(Long coachId) { + this.coachId = coachId; + } + + public Long getCourseType() { + return courseType; + } + + public void setCourseType(Long courseType) { + this.courseType = courseType; + } + + public LocalDateTime getStartTime() { + return startTime; + } + + public void setStartTime(LocalDateTime startTime) { + this.startTime = startTime; + } + + public LocalDateTime getEndTime() { + return endTime; + } + + public void setEndTime(LocalDateTime endTime) { + this.endTime = endTime; + } + + public Integer getMaxMembers() { + return maxMembers; + } + + public void setMaxMembers(Integer maxMembers) { + this.maxMembers = maxMembers; + } + + public Integer getCurrentMembers() { + return currentMembers; + } + + public void setCurrentMembers(Integer currentMembers) { + this.currentMembers = currentMembers; + } + + public Long getStatus() { + return status; + } + + public void setStatus(Long status) { + this.status = status; + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getCoverImage() { + return coverImage; + } + + public void setCoverImage(String coverImage) { + this.coverImage = coverImage; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/repository/IGroupCourseRepository.java b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/repository/IGroupCourseRepository.java new file mode 100644 index 0000000..2d020d4 --- /dev/null +++ b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/repository/IGroupCourseRepository.java @@ -0,0 +1,14 @@ +package cn.novalon.gym.manage.sys.core.repository; + +import cn.novalon.gym.manage.sys.core.domain.GroupCourse; +import org.springframework.data.domain.Sort; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface IGroupCourseRepository { + Mono findByIdAndDeletedAtIsNull(Long id); + Flux findAll(); + Flux findAll(Sort sort); + Flux findByDeletedAtIsNull(); + Flux findByDeletedAtIsNull(Sort sort); +} diff --git a/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/service/IGroupCourseService.java b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/service/IGroupCourseService.java new file mode 100644 index 0000000..28efd2e --- /dev/null +++ b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/service/IGroupCourseService.java @@ -0,0 +1,11 @@ +package cn.novalon.gym.manage.sys.core.service; + +import cn.novalon.gym.manage.sys.core.domain.GroupCourse; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public interface IGroupCourseService { + Mono findById(Long id); + Flux findAll(); + Flux findAll(boolean includeDeleted); +} diff --git a/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/service/impl/GroupCourseService.java b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/service/impl/GroupCourseService.java new file mode 100644 index 0000000..2b1fcbf --- /dev/null +++ b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/service/impl/GroupCourseService.java @@ -0,0 +1,42 @@ +package cn.novalon.gym.manage.sys.core.service.impl; + +import cn.novalon.gym.manage.sys.audit.service.IAuditLogService; +import cn.novalon.gym.manage.sys.core.domain.GroupCourse; +import cn.novalon.gym.manage.sys.core.repository.IGroupCourseRepository; +import cn.novalon.gym.manage.sys.core.service.IGroupCourseService; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * @author:liwentao + * @date:2026/4/26-04-26-14:12 + */ +@Service +public class GroupCourseService implements IGroupCourseService { + private final IGroupCourseRepository groupCourseRepository; + private final IAuditLogService auditLogService; + public GroupCourseService(IGroupCourseRepository groupCourseRepository, IAuditLogService auditLogService){ + this.groupCourseRepository = groupCourseRepository; + this.auditLogService = auditLogService; + } + + @Override + public Mono findById(Long id) { + return groupCourseRepository.findByIdAndDeletedAtIsNull(id); + } + + @Override + public Flux findAll() { + return groupCourseRepository.findAll(); + } + + @Override + public Flux findAll(boolean includeDeleted) { + if(includeDeleted){ + return groupCourseRepository.findAll(); + }else{ + return groupCourseRepository.findByDeletedAtIsNull(); + } + } +} diff --git a/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/service/impl/SysUserService.java b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/service/impl/SysUserService.java index 3d7bf64..ee1da91 100644 --- a/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/service/impl/SysUserService.java +++ b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/core/service/impl/SysUserService.java @@ -15,6 +15,7 @@ import cn.novalon.gym.manage.sys.core.repository.IUserRoleRepository; import cn.novalon.gym.manage.sys.core.service.ISysUserService; import cn.novalon.gym.manage.sys.core.command.CreateUserCommand; import cn.novalon.gym.manage.sys.core.command.UpdateUserCommand; +import cn.novalon.gym.manage.sys.dto.response.UserResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; diff --git a/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/handler/groupCourse/GroupCourseHandler.java b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/handler/groupCourse/GroupCourseHandler.java new file mode 100644 index 0000000..b439351 --- /dev/null +++ b/gym-manage-api/manage-sys/src/main/java/cn/novalon/gym/manage/sys/handler/groupCourse/GroupCourseHandler.java @@ -0,0 +1,40 @@ +package cn.novalon.gym.manage.sys.handler.groupCourse; + +import cn.novalon.gym.manage.sys.core.domain.GroupCourse; +import cn.novalon.gym.manage.sys.core.service.IGroupCourseService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Validator; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +/** + * @author:liwentao + * @date:2026/4/26-04-26-14:30 + */ +@Component +@Tag(name="团课管理",description = "团课相关操作") +public class GroupCourseHandler { + private final IGroupCourseService groupCourseService; + private final Validator validator; + public GroupCourseHandler(IGroupCourseService groupCourseService,Validator validator){ + this.groupCourseService = groupCourseService; + this.validator = validator; + } + + @Operation(summary = "获取所有用户", description = "获取系统中所有用户列表") + public Mono getAllGroupCourse(ServerRequest request){ + boolean includeDeleted = Boolean.valueOf(request.queryParam("includeDeleted").orElse("false")); + return ServerResponse.ok() + .body(groupCourseService.findAll(includeDeleted), GroupCourse.class); + } + + public Mono getGroupCourseById(ServerRequest request){ + Long id = Long.valueOf(request.pathVariable("id")); + return groupCourseService.findById(id) + .flatMap(groupCourse -> ServerResponse.ok().bodyValue(groupCourse)) + .switchIfEmpty(ServerResponse.notFound().build()); + } +} diff --git a/gym-manage-api/pom.xml b/gym-manage-api/pom.xml index df2e4c2..aec5848 100644 --- a/gym-manage-api/pom.xml +++ b/gym-manage-api/pom.xml @@ -221,6 +221,13 @@ lombok true + + + + cn.hutool + hutool-all + 5.8.38 +