Browse Source

feat(physical): 添加预报名功能模块

- 创建预报名实体类 PhysicalTournamentsRegistration
- 实现预报名服务接口 IPhysicalTournamentsRegistrationService
- 开发预报名控制器 PhysicalTournamentsRegistrationController
- 添加预报名数据传输对象 PhysicalTournamentsRegistrationBo 和返回对象 PhysicalTournamentsRegistrationVo
- 实现预报名数据库映射 PhysicalTournamentsRegistrationMapper
- 配置 MyBatis 映射文件 PhysicalTournamentsRegistrationMapper.xml
- 实现预报名服务业务逻辑 PhysicalTournamentsRegistrationServiceImpl
- 添加用户实名认证相关实体、映射器和配置文件
- 实现预报名审核功能和状态管理
- 集成用户信息和赛事信息关联查询
fugui001 3 weeks ago
parent
commit
605c1329c7
13 changed files with 1243 additions and 0 deletions
  1. 111 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/UserRealInfo.java
  2. 109 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/bo/UserRealInfoBo.java
  3. 147 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/vo/UserRealInfoVo.java
  4. 21 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/UserRealInfoMapper.java
  5. 116 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/controller/PhysicalTournamentsRegistrationController.java
  6. 76 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/PhysicalTournamentsRegistration.java
  7. 81 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/bo/PhysicalTournamentsRegistrationBo.java
  8. 111 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/vo/PhysicalTournamentsRegistrationVo.java
  9. 42 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/mapper/PhysicalTournamentsRegistrationMapper.java
  10. 76 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/service/IPhysicalTournamentsRegistrationService.java
  11. 212 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/service/impl/PhysicalTournamentsRegistrationServiceImpl.java
  12. 32 0
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/UserRealInfoMapper.xml
  13. 109 0
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/physical/PhysicalTournamentsRegistrationMapper.xml

+ 111 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/UserRealInfo.java

@@ -0,0 +1,111 @@
+package org.dromara.business.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 用户实名对象 user_real_info
+ *
+ * @author Lion Li
+ * @date 2026-01-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("user_real_info")
+public class UserRealInfo extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+    /**
+     * 用户名
+     */
+    private String userName;
+
+    /**
+     * 证件号码
+     */
+    private String idCardNumber;
+
+    /**
+     * 真实姓名
+     */
+    private String realName;
+
+    /**
+     * 证件类型
+     */
+    private String idCardType;
+
+    /**
+     * 性别(0:女, 1:男)
+     */
+    private Long sex;
+
+    /**
+     * 国家
+     */
+    private String country;
+
+    /**
+     * 地区
+     */
+    private String regional;
+
+    /**
+     * 存储身份证正面照片的路径或者URL地址。
+     */
+    private String idCardFrontImage;
+
+    /**
+     * 存储身份证背面照片的路径或者URL地址
+     */
+    private String idCardBackImage;
+
+    /**
+     * 实名认证状态(pending:待审核, approved:已通过, rejected:未通过)
+     */
+    private String verificationStatus;
+
+    /**
+     * 审核人员备注
+     */
+    private String reviewNotes;
+
+    /**
+     * 审核人员
+     */
+    private String auditUser;
+
+    /**
+     * 实名认证 0 未通过 1 已通过
+     */
+    private Long isPass;
+
+    /**
+     * 认证ID
+     */
+    private String certifyId;
+
+    /**
+     * 认证随机生成ID
+     */
+    private String outerOrderNo;
+
+
+}

+ 109 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/bo/UserRealInfoBo.java

@@ -0,0 +1,109 @@
+package org.dromara.business.domain.bo;
+
+import org.dromara.business.domain.UserRealInfo;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 用户实名业务对象 user_real_info
+ *
+ * @author Lion Li
+ * @date 2026-01-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = UserRealInfo.class, reverseConvertGenerate = false)
+public class UserRealInfoBo extends BaseEntity {
+
+    /**
+     *
+     */
+    @NotNull(message = "不能为空", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+    /**
+     * 用户名
+     */
+    private String userName;
+
+    /**
+     * 证件号码
+     */
+    private String idCardNumber;
+
+    /**
+     * 真实姓名
+     */
+    private String realName;
+
+    /**
+     * 证件类型
+     */
+    private String idCardType;
+
+    /**
+     * 性别(0:女, 1:男)
+     */
+    private Long sex;
+
+    /**
+     * 国家
+     */
+    private String country;
+
+    /**
+     * 地区
+     */
+    private String regional;
+
+    /**
+     * 存储身份证正面照片的路径或者URL地址。
+     */
+    private String idCardFrontImage;
+
+    /**
+     * 存储身份证背面照片的路径或者URL地址
+     */
+    private String idCardBackImage;
+
+    /**
+     * 实名认证状态(pending:待审核, approved:已通过, rejected:未通过)
+     */
+    private String verificationStatus;
+
+    /**
+     * 审核人员备注
+     */
+    private String reviewNotes;
+
+    /**
+     * 审核人员
+     */
+    private String auditUser;
+
+    /**
+     * 实名认证 0 未通过 1 已通过
+     */
+    private Long isPass;
+
+    /**
+     * 认证ID
+     */
+    private String certifyId;
+
+    /**
+     * 认证随机生成ID
+     */
+    private String outerOrderNo;
+
+
+}

+ 147 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/domain/vo/UserRealInfoVo.java

@@ -0,0 +1,147 @@
+package org.dromara.business.domain.vo;
+
+import org.dromara.business.domain.UserRealInfo;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+
+/**
+ * 用户实名视图对象 user_real_info
+ *
+ * @author Lion Li
+ * @date 2026-01-16
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = UserRealInfo.class)
+public class UserRealInfoVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 用户id
+     */
+    @ExcelProperty(value = "用户id")
+    private Long userId;
+
+    /**
+     * 用户名
+     */
+    @ExcelProperty(value = "用户名")
+    private String userName;
+
+    /**
+     * 证件号码
+     */
+    @ExcelProperty(value = "证件号码")
+    private String idCardNumber;
+
+    /**
+     * 真实姓名
+     */
+    @ExcelProperty(value = "真实姓名")
+    private String realName;
+
+    /**
+     * 证件类型
+     */
+    @ExcelProperty(value = "证件类型")
+    private String idCardType;
+
+    /**
+     * 性别(0:女, 1:男)
+     */
+    @ExcelProperty(value = "性别", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=:女,,1=:男")
+    private Long sex;
+
+    /**
+     * 国家
+     */
+    @ExcelProperty(value = "国家")
+    private String country;
+
+    /**
+     * 地区
+     */
+    @ExcelProperty(value = "地区")
+    private String regional;
+
+    /**
+     * 存储身份证正面照片的路径或者URL地址。
+     */
+    @ExcelProperty(value = "存储身份证正面照片的路径或者URL地址。")
+    private String idCardFrontImage;
+
+    /**
+     * 存储身份证正面照片的路径或者URL地址。Url
+     */
+    @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "idCardFrontImage")
+    private String idCardFrontImageUrl;
+    /**
+     * 存储身份证背面照片的路径或者URL地址
+     */
+    @ExcelProperty(value = "存储身份证背面照片的路径或者URL地址")
+    private String idCardBackImage;
+
+    /**
+     * 存储身份证背面照片的路径或者URL地址Url
+     */
+    @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "idCardBackImage")
+    private String idCardBackImageUrl;
+    /**
+     * 实名认证状态(pending:待审核, approved:已通过, rejected:未通过)
+     */
+    @ExcelProperty(value = "实名认证状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "p=ending:待审核,,a=pproved:已通过,,r=ejected:未通过")
+    private String verificationStatus;
+
+    /**
+     * 审核人员备注
+     */
+    @ExcelProperty(value = "审核人员备注")
+    private String reviewNotes;
+
+    /**
+     * 审核人员
+     */
+    @ExcelProperty(value = "审核人员")
+    private String auditUser;
+
+    /**
+     * 实名认证 0 未通过 1 已通过
+     */
+    @ExcelProperty(value = "实名认证 0 未通过 1 已通过")
+    private Long isPass;
+
+    /**
+     * 认证ID
+     */
+    @ExcelProperty(value = "认证ID")
+    private String certifyId;
+
+    /**
+     * 认证随机生成ID
+     */
+    @ExcelProperty(value = "认证随机生成ID")
+    private String outerOrderNo;
+
+
+}

+ 21 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/business/mapper/UserRealInfoMapper.java

@@ -0,0 +1,21 @@
+package org.dromara.business.mapper;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import org.dromara.business.domain.UserRealInfo;
+import org.dromara.business.domain.vo.UserRealInfoVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 用户实名Mapper接口
+ *
+ * @author Lion Li
+ * @date 2026-01-16
+ */
+@DS("mysql2")
+public interface UserRealInfoMapper extends BaseMapperPlus<UserRealInfo, UserRealInfoVo> {
+
+    @InterceptorIgnore(tenantLine = "true")
+    UserRealInfoVo selectUserRealInfoByUserId(Long userId);
+
+}

+ 116 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/controller/PhysicalTournamentsRegistrationController.java

@@ -0,0 +1,116 @@
+package org.dromara.physical.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.physical.domain.bo.PhysicalTournamentsRegistrationBo;
+import org.dromara.physical.domain.vo.PhysicalTournamentsRegistrationVo;
+import org.dromara.physical.service.IPhysicalTournamentsRegistrationService;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 预报名
+ *
+ * @author Lion Li
+ * @date 2026-01-16
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/physical/tournamentsRegistration")
+public class PhysicalTournamentsRegistrationController extends BaseController {
+
+    private final IPhysicalTournamentsRegistrationService physicalTournamentsRegistrationService;
+
+    /**
+     * 查询预报名列表
+     */
+    @SaCheckPermission("physical:tournamentsRegistration:list")
+    @GetMapping("/list")
+    public TableDataInfo<PhysicalTournamentsRegistrationVo> list(PhysicalTournamentsRegistrationBo bo, PageQuery pageQuery) {
+        return physicalTournamentsRegistrationService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出预报名列表
+     */
+    @SaCheckPermission("physical:tournamentsRegistration:export")
+    @Log(title = "预报名", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(PhysicalTournamentsRegistrationBo bo, HttpServletResponse response) {
+        List<PhysicalTournamentsRegistrationVo> list = physicalTournamentsRegistrationService.queryList(bo);
+        ExcelUtil.exportExcel(list, "预报名", PhysicalTournamentsRegistrationVo.class, response);
+    }
+
+    /**
+     * 获取预报名详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("physical:tournamentsRegistration:query")
+    @GetMapping("/{id}")
+    public R<PhysicalTournamentsRegistrationVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable Long id) {
+        return R.ok(physicalTournamentsRegistrationService.queryById(id));
+    }
+
+    /**
+     * 新增预报名
+     */
+    @SaCheckPermission("physical:tournamentsRegistration:add")
+    @Log(title = "预报名", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody PhysicalTournamentsRegistrationBo bo) {
+        return toAjax(physicalTournamentsRegistrationService.insertByBo(bo));
+    }
+
+    /**
+     * 修改预报名
+     */
+    @SaCheckPermission("physical:tournamentsRegistration:edit")
+    @Log(title = "预报名", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody PhysicalTournamentsRegistrationBo bo) {
+        return toAjax(physicalTournamentsRegistrationService.updateByBo(bo));
+    }
+
+    /**
+     * 删除预报名
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("physical:tournamentsRegistration:remove")
+    @Log(title = "预报名", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable Long[] ids) {
+        return toAjax(physicalTournamentsRegistrationService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+
+    @Log(title = "审核预报名", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping("/auditTournamentsRegistration")
+    public R<Void> auditTournamentsRegistration(@Validated(EditGroup.class) @RequestBody PhysicalTournamentsRegistrationBo bo) {
+        return toAjax(physicalTournamentsRegistrationService.auditTournamentsRegistration(bo));
+    }
+
+
+
+}

+ 76 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/PhysicalTournamentsRegistration.java

@@ -0,0 +1,76 @@
+package org.dromara.physical.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.util.Date;
+import java.io.Serial;
+
+/**
+ * 预报名对象 physical_tournaments_registration
+ *
+ * @author Lion Li
+ * @date 2026-01-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("physical_tournaments_registration")
+public class PhysicalTournamentsRegistration extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 预报名ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 用户ID(对应玩家表)
+     */
+    private Long userId;
+
+    /**
+     * 锦标联赛-赛事ID(外键,关联physical_league_tournament表)
+     */
+    private Long leagueTournamentId;
+
+    /**
+     * 上传的审核图片地址(如OSS链接)
+     */
+    private String imageUrl;
+
+    /**
+     * 审核状态:pending=待审核,approved=已通过,rejected=已拒绝
+     */
+    private String status;
+
+    /**
+     * 审核备注(如拒绝原因)
+     */
+    private String remark;
+
+    /**
+     * 提交时间
+     */
+    private Date createdAt;
+
+    /**
+     * 审核时间
+     */
+    private Date auditedAt;
+
+    /**
+     * 审核人ID(可选)
+     */
+    private Long auditorId;
+
+    /**
+     * 审核人姓名(可选)
+     */
+    private String auditorName;
+
+
+}

+ 81 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/bo/PhysicalTournamentsRegistrationBo.java

@@ -0,0 +1,81 @@
+package org.dromara.physical.domain.bo;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.physical.domain.PhysicalTournamentsRegistration;
+
+/**
+ * 预报名业务对象 physical_tournaments_registration
+ *
+ * @author Lion Li
+ * @date 2026-01-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = PhysicalTournamentsRegistration.class, reverseConvertGenerate = false)
+public class PhysicalTournamentsRegistrationBo extends BaseEntity {
+
+    /**
+     * 预报名ID
+     */
+    @NotNull(message = "预报名ID不能为空", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 用户ID(对应玩家表)
+     */
+    //@NotNull(message = "用户ID(对应玩家表)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long userId;
+
+    /**
+     * 锦标联赛-赛事ID(外键,关联physical_league_tournament表)
+     */
+    //@NotNull(message = "锦标联赛-赛事ID(外键,关联physical_league_tournament表)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long leagueTournamentId;
+
+    /**
+     * 上传的审核图片地址(如OSS链接)
+     */
+    private String imageUrl;
+
+    /**
+     * 审核状态:pending=待审核,approved=已通过,rejected=已拒绝
+     */
+    //@NotBlank(message = "审核状态:pending=待审核,approved=已通过,rejected=已拒绝不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String status;
+
+    /**
+     * 审核备注(如拒绝原因)
+     */
+    private String remark;
+
+    /**
+     * 提交时间
+     */
+/*    private Date createdAt;*/
+
+    /**
+     * 审核时间
+     */
+    private Date auditedAt;
+
+    /**
+     * 审核人ID(可选)
+     */
+    private Long auditorId;
+
+    /**
+     * 审核人姓名(可选)
+     */
+    private String auditorName;
+
+    private String createdAtStart;
+    private String createdAtEnd;
+}

+ 111 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/domain/vo/PhysicalTournamentsRegistrationVo.java

@@ -0,0 +1,111 @@
+package org.dromara.physical.domain.vo;
+
+import java.util.Date;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.physical.domain.PhysicalTournamentsRegistration;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+
+/**
+ * 预报名视图对象 physical_tournaments_registration
+ *
+ * @author Lion Li
+ * @date 2026-01-16
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = PhysicalTournamentsRegistration.class)
+public class PhysicalTournamentsRegistrationVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 预报名ID
+     */
+    //@ExcelProperty(value = "预报名ID")
+    private Long id;
+
+    /**
+     * 提交时间
+     */
+    @ExcelProperty(value = "提交日期")
+    private Date createdAt;
+
+    /**
+     * 用户ID(对应玩家表)
+     */
+    @ExcelProperty(value = "用户ID")
+    //@ExcelDictFormat(readConverterExp = "对=应玩家表")
+    private Long userId;
+
+    @ExcelProperty(value = "登录名称")
+    private String userName;
+
+    @ExcelProperty(value = "用户姓名")
+    private String realName;
+
+    /**
+     * 锦标联赛-赛事ID(外键,关联physical_league_tournament表)
+     */
+    //@ExcelProperty(value = "锦标联赛-赛事ID", converter = ExcelDictConvert.class)
+    private Long leagueTournamentId;
+
+    @ExcelProperty(value = "预报名比赛")
+    private String leagueTournamentName;
+
+    /**
+     * 上传的审核图片地址(如OSS链接)
+     */
+    @ExcelProperty(value = "审核图片")
+    //@ExcelDictFormat(readConverterExp = "如=OSS链接")
+    private String imageUrl;
+
+    /**
+     * 审核状态:pending=待审核,approved=已通过,rejected=已拒绝
+     */
+    //@ExcelProperty(value = "审核状态:pending=待审核,approved=已通过,rejected=已拒绝")
+    private String status;
+
+    @ExcelProperty(value = "审核状态")
+    private String statusText;
+
+    /**
+     * 审核备注(如拒绝原因)
+     */
+    @ExcelProperty(value = "审核备注")
+    //@ExcelDictFormat(readConverterExp = "如=拒绝原因")
+    private String remark;
+
+
+
+    /**
+     * 审核时间
+     */
+    @ExcelProperty(value = "审核时间")
+    private Date auditedAt;
+
+    /**
+     * 审核人ID(可选)
+     */
+    //@ExcelProperty(value = "审核人ID", converter = ExcelDictConvert.class)
+   // @ExcelDictFormat(readConverterExp = "可=选")
+    private Long auditorId;
+
+    /**
+     * 审核人姓名(可选)
+     */
+    @ExcelProperty(value = "审核人姓名")
+   // @ExcelDictFormat(readConverterExp = "可=选")
+    private String auditorName;
+
+
+}

+ 42 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/mapper/PhysicalTournamentsRegistrationMapper.java

@@ -0,0 +1,42 @@
+package org.dromara.physical.mapper;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.physical.domain.PhysicalTournamentsRegistration;
+import org.dromara.physical.domain.vo.PhysicalTournamentsRegistrationVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 预报名Mapper接口
+ *
+ * @author Lion Li
+ * @date 2026-01-16
+ */
+@DS("mysql2")
+public interface PhysicalTournamentsRegistrationMapper extends BaseMapperPlus<PhysicalTournamentsRegistration, PhysicalTournamentsRegistrationVo> {
+
+    @InterceptorIgnore(tenantLine = "true")
+    Page<PhysicalTournamentsRegistrationVo> selectPhysicalTournamentsRegistrationPage(@Param("page") Page<PhysicalTournamentsRegistration> page, @Param("ew") Wrapper<PhysicalTournamentsRegistration> wrapper);
+
+    @InterceptorIgnore(tenantLine = "true")
+    PhysicalTournamentsRegistrationVo selectPhysicalTournamentsRegistrationById(Long id);
+
+    @InterceptorIgnore(tenantLine = "true")
+    int updatePhysicalTournamentsRegistration(PhysicalTournamentsRegistration update);
+
+    @InterceptorIgnore(tenantLine = "true")
+    int insertPhysicalTournamentsRegistration(PhysicalTournamentsRegistration insert);
+
+    @InterceptorIgnore(tenantLine = "true")
+    int deletePhysicalTournamentsRegistrationByIds(@Param("ids") Collection<Long> ids);
+
+    @InterceptorIgnore(tenantLine = "true")
+    List<PhysicalTournamentsRegistrationVo> selectPhysicalTournamentsRegistrationList(@Param("ew") Wrapper<PhysicalTournamentsRegistration> wrapper);
+
+}

+ 76 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/service/IPhysicalTournamentsRegistrationService.java

@@ -0,0 +1,76 @@
+package org.dromara.physical.service;
+
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.physical.domain.bo.PhysicalTournamentsRegistrationBo;
+import org.dromara.physical.domain.vo.PhysicalTournamentsRegistrationVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 预报名Service接口
+ *
+ * @author Lion Li
+ * @date 2026-01-16
+ */
+public interface IPhysicalTournamentsRegistrationService {
+
+    /**
+     * 查询预报名
+     *
+     * @param id 主键
+     * @return 预报名
+     */
+    PhysicalTournamentsRegistrationVo queryById(Long id);
+
+    /**
+     * 分页查询预报名列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 预报名分页列表
+     */
+    TableDataInfo<PhysicalTournamentsRegistrationVo> queryPageList(PhysicalTournamentsRegistrationBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的预报名列表
+     *
+     * @param bo 查询条件
+     * @return 预报名列表
+     */
+    List<PhysicalTournamentsRegistrationVo> queryList(PhysicalTournamentsRegistrationBo bo);
+
+    /**
+     * 新增预报名
+     *
+     * @param bo 预报名
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(PhysicalTournamentsRegistrationBo bo);
+
+    /**
+     * 修改预报名
+     *
+     * @param bo 预报名
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(PhysicalTournamentsRegistrationBo bo);
+
+    /**
+     * 校验并批量删除预报名信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 预报名审核
+     *
+     * @param bo 预报名
+     * @return 是否审核成功
+     */
+    Boolean auditTournamentsRegistration(PhysicalTournamentsRegistrationBo bo);
+}

+ 212 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/physical/service/impl/PhysicalTournamentsRegistrationServiceImpl.java

@@ -0,0 +1,212 @@
+package org.dromara.physical.service.impl;
+
+import org.dromara.business.domain.vo.UserRealInfoVo;
+import org.dromara.business.domain.vo.UserVo;
+import org.dromara.business.mapper.UserMapper;
+import org.dromara.business.mapper.UserRealInfoMapper;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.physical.domain.PhysicalTournamentsRegistration;
+import org.dromara.physical.domain.bo.PhysicalTournamentsRegistrationBo;
+import org.dromara.physical.domain.vo.PhysicalLeagueTournamentVo;
+import org.dromara.physical.domain.vo.PhysicalTournamentsRegistrationVo;
+import org.dromara.physical.mapper.PhysicalLeagueTournamentMapper;
+import org.dromara.physical.mapper.PhysicalTournamentsRegistrationMapper;
+import org.dromara.physical.service.IPhysicalTournamentsRegistrationService;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 预报名Service业务层处理
+ *
+ * @author Lion Li
+ * @date 2026-01-16
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class PhysicalTournamentsRegistrationServiceImpl implements IPhysicalTournamentsRegistrationService {
+
+    private final PhysicalTournamentsRegistrationMapper baseMapper;
+
+    private final UserMapper userMapper;
+
+    private final UserRealInfoMapper userRealInfoMapper;
+
+    private final PhysicalLeagueTournamentMapper physicalLeagueTournamentMapper;
+
+
+
+    /**
+     * 查询预报名
+     *
+     * @param id 主键
+     * @return 预报名
+     */
+    @Override
+    public PhysicalTournamentsRegistrationVo queryById(Long id){
+        return baseMapper.selectPhysicalTournamentsRegistrationById(id);
+    }
+
+    /**
+     * 分页查询预报名列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 预报名分页列表
+     */
+    @Override
+    public TableDataInfo<PhysicalTournamentsRegistrationVo> queryPageList(PhysicalTournamentsRegistrationBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<PhysicalTournamentsRegistration> lqw = buildQueryWrapper(bo);
+        Page<PhysicalTournamentsRegistrationVo> result = baseMapper.selectPhysicalTournamentsRegistrationPage(pageQuery.build(), lqw);
+        List<PhysicalTournamentsRegistrationVo> physicalTournamentsRegistrationVoList = result.getRecords();
+        physicalTournamentsRegistrationVoList.forEach(physicalTournamentsRegistrationVo -> {
+            Long userId=physicalTournamentsRegistrationVo.getUserId();
+            UserVo userVo = userMapper.selectVoByIdInfo(userId);
+            if(userVo!=null){
+                //用户名称
+                physicalTournamentsRegistrationVo.setUserName(userVo.getNickName());
+            }
+            //用户姓名
+            UserRealInfoVo userRealInfoVo = userRealInfoMapper.selectUserRealInfoByUserId(userId);
+            if(userRealInfoVo!=null){
+                physicalTournamentsRegistrationVo.setRealName(userRealInfoVo.getRealName());
+            }
+            PhysicalLeagueTournamentVo physicalLeagueTournamentVo = physicalLeagueTournamentMapper.selectPhysicalLeagueTournamentById(physicalTournamentsRegistrationVo.getId());
+            if(physicalLeagueTournamentVo!=null){
+                physicalTournamentsRegistrationVo.setLeagueTournamentName(physicalLeagueTournamentVo.getTitle());
+            }
+
+        });
+
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的预报名列表
+     *
+     * @param bo 查询条件
+     * @return 预报名列表
+     */
+    @Override
+    public List<PhysicalTournamentsRegistrationVo> queryList(PhysicalTournamentsRegistrationBo bo) {
+        LambdaQueryWrapper<PhysicalTournamentsRegistration> lqw = buildQueryWrapper(bo);
+        List<PhysicalTournamentsRegistrationVo> physicalTournamentsRegistrationVoList = baseMapper.selectPhysicalTournamentsRegistrationList(lqw);
+        for (PhysicalTournamentsRegistrationVo physicalTournamentsRegistrationVo : physicalTournamentsRegistrationVoList) {
+            Long userId=physicalTournamentsRegistrationVo.getUserId();
+            UserVo userVo = userMapper.selectVoByIdInfo(userId);
+            if(userVo!=null){
+                //用户名称
+                physicalTournamentsRegistrationVo.setUserName(userVo.getNickName());
+            }
+            //用户姓名
+            UserRealInfoVo userRealInfoVo = userRealInfoMapper.selectUserRealInfoByUserId(userId);
+            if(userRealInfoVo!=null){
+                physicalTournamentsRegistrationVo.setRealName(userRealInfoVo.getRealName());
+            }
+            PhysicalLeagueTournamentVo physicalLeagueTournamentVo = physicalLeagueTournamentMapper.selectPhysicalLeagueTournamentById(physicalTournamentsRegistrationVo.getId());
+            if(physicalLeagueTournamentVo!=null){
+                physicalTournamentsRegistrationVo.setLeagueTournamentName(physicalLeagueTournamentVo.getTitle());
+            }
+            if(physicalTournamentsRegistrationVo.getStatus().equals("approved")){
+                physicalTournamentsRegistrationVo.setStatusText(("已通过"));
+            }else if(physicalTournamentsRegistrationVo.getStatus().equals("pending")){
+                physicalTournamentsRegistrationVo.setStatusText(("待审核"));
+            }else if(physicalTournamentsRegistrationVo.getStatus().equals("rejected")){
+                physicalTournamentsRegistrationVo.setStatusText(("未通过"));
+            }
+        }
+        return physicalTournamentsRegistrationVoList;
+    }
+
+    private LambdaQueryWrapper<PhysicalTournamentsRegistration> buildQueryWrapper(PhysicalTournamentsRegistrationBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<PhysicalTournamentsRegistration> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(PhysicalTournamentsRegistration::getCreatedAt);
+        lqw.ge(bo.getCreatedAtStart() != null, PhysicalTournamentsRegistration::getCreatedAt, bo.getCreatedAtStart());
+        lqw.le(bo.getCreatedAtEnd() != null, PhysicalTournamentsRegistration::getCreatedAt, bo.getCreatedAtEnd());
+        lqw.eq(bo.getUserId() != null, PhysicalTournamentsRegistration::getUserId, bo.getUserId());
+        lqw.eq(bo.getLeagueTournamentId() != null, PhysicalTournamentsRegistration::getLeagueTournamentId, bo.getLeagueTournamentId());
+        lqw.eq(StringUtils.isNotBlank(bo.getImageUrl()), PhysicalTournamentsRegistration::getImageUrl, bo.getImageUrl());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), PhysicalTournamentsRegistration::getStatus, bo.getStatus());
+       /* lqw.eq(bo.getCreatedAt() != null, PhysicalTournamentsRegistration::getCreatedAt, bo.getCreatedAt());*/
+        lqw.eq(bo.getAuditedAt() != null, PhysicalTournamentsRegistration::getAuditedAt, bo.getAuditedAt());
+        lqw.eq(bo.getAuditorId() != null, PhysicalTournamentsRegistration::getAuditorId, bo.getAuditorId());
+        lqw.like(StringUtils.isNotBlank(bo.getAuditorName()), PhysicalTournamentsRegistration::getAuditorName, bo.getAuditorName());
+        return lqw;
+    }
+
+    /**
+     * 新增预报名
+     *
+     * @param bo 预报名
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(PhysicalTournamentsRegistrationBo bo) {
+        PhysicalTournamentsRegistration add = MapstructUtils.convert(bo, PhysicalTournamentsRegistration.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insertPhysicalTournamentsRegistration(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改预报名
+     *
+     * @param bo 预报名
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(PhysicalTournamentsRegistrationBo bo) {
+        PhysicalTournamentsRegistration update = MapstructUtils.convert(bo, PhysicalTournamentsRegistration.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updatePhysicalTournamentsRegistration(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(PhysicalTournamentsRegistration entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除预报名信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deletePhysicalTournamentsRegistrationByIds(ids) > 0;
+    }
+
+    @Override
+    public Boolean auditTournamentsRegistration(PhysicalTournamentsRegistrationBo bo) {
+        PhysicalTournamentsRegistration update = MapstructUtils.convert(bo, PhysicalTournamentsRegistration.class);
+        validEntityBeforeSave(update);
+        update.setAuditedAt(new Date());
+        update.setAuditorName(StringUtils.isEmpty(LoginHelper.getLoginUser().getUsername())?LoginHelper.getLoginUser().getNickname() : LoginHelper.getLoginUser().getUsername());
+        update.setAuditorId(LoginHelper.getLoginUser().getUserId());
+        return baseMapper.updatePhysicalTournamentsRegistration(update) > 0;
+    }
+}

+ 32 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/business/UserRealInfoMapper.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.business.mapper.UserRealInfoMapper">
+
+    <select id="selectUserRealInfoByUserId" resultType="org.dromara.business.domain.vo.UserRealInfoVo">
+        SELECT
+            id,
+            user_id,
+            user_name,
+            id_card_number,
+            real_name,
+            id_card_type,
+            sex,
+            country,
+            regional,
+            id_card_front_image,
+            id_card_back_image,
+            verification_status,
+            create_time,
+            update_time,
+            review_notes,
+            audit_user,
+            is_pass,
+            certify_id,
+            outer_order_no
+        FROM user_real_info WHERE user_id = #{userId}
+    </select>
+
+
+</mapper>

+ 109 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/physical/PhysicalTournamentsRegistrationMapper.xml

@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.physical.mapper.PhysicalTournamentsRegistrationMapper">
+
+
+    <!-- 查询全部(显式列出所有列) -->
+    <select id="selectPhysicalTournamentsRegistrationPage" resultType="org.dromara.physical.domain.vo.PhysicalTournamentsRegistrationVo">
+        SELECT
+            id,
+            user_id,
+            league_tournament_id,
+            image_url,
+            status,
+            remark,
+            created_at,
+            audited_at,
+            auditor_id,
+            auditor_name
+        FROM physical_tournaments_registration  ${ew.customSqlSegment}
+    </select>
+
+
+    <select id="selectPhysicalTournamentsRegistrationById" resultType="org.dromara.physical.domain.vo.PhysicalTournamentsRegistrationVo">
+        SELECT
+            id,
+            user_id,
+            league_tournament_id,
+            image_url,
+            status,
+            remark,
+            created_at,
+            audited_at,
+            auditor_id,
+            auditor_name
+        FROM physical_tournaments_registration   where id = #{id}
+    </select>
+
+    <select id="selectPhysicalTournamentsRegistrationList" resultType="org.dromara.physical.domain.vo.PhysicalTournamentsRegistrationVo">
+        SELECT
+            id,
+            user_id,
+            league_tournament_id,
+            image_url,
+            status,
+            remark,
+            created_at,
+            audited_at,
+            auditor_id,
+            auditor_name
+        FROM physical_tournaments_registration  ${ew.customSqlSegment}
+    </select>
+
+    <!-- 插入(全字段,但允许部分为空) -->
+    <insert id="insertPhysicalTournamentsRegistration" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
+        INSERT INTO physical_tournaments_registration (
+            user_id,
+            league_tournament_id,
+            image_url,
+            status,
+            remark,
+            created_at,
+            audited_at,
+            auditor_id,
+            auditor_name
+        ) VALUES (
+                     #{userId},
+                     #{leagueTournamentId},
+                     #{imageUrl},
+                     #{status},
+                     #{remark},
+                     #{createdAt},
+                     #{auditedAt},
+                     #{auditorId},
+                     #{auditorName}
+                 )
+    </insert>
+
+    <!-- 更新(仅更新非空字段) -->
+    <update id="updatePhysicalTournamentsRegistration">
+        UPDATE physical_tournaments_registration
+        <set>
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="leagueTournamentId != null">league_tournament_id = #{leagueTournamentId},</if>
+            <if test="imageUrl != null">image_url = #{imageUrl},</if>
+            <if test="status != null and status != ''">status = #{status},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="createdAt != null">created_at = #{createdAt},</if>
+            <if test="auditedAt != null">audited_at = #{auditedAt},</if>
+            <if test="auditorId != null">auditor_id = #{auditorId},</if>
+            <if test="auditorName != null and auditorName != ''">auditor_name = #{auditorName},</if>
+        </set>
+        WHERE id = #{id}
+    </update>
+
+    <delete id="deletePhysicalTournamentsRegistrationByIds">
+        DELETE FROM physical_tournaments_registration
+        <where>
+            id IN
+            <foreach item="id" collection="ids" open="(" separator="," close=")">
+                <if test="id > 0">
+                    #{id}
+                </if>
+            </foreach>
+        </where>
+    </delete>
+
+</mapper>