天玄剑宗宗门任务平台:从零到部署的Spring Boot实战(阶段一:练气期 - 筑基固本,开宗立派)

48 阅读10分钟

《天玄剑宗宗门任务平台:从零到部署的Spring Boot实战》

阶段一:练气期 - 筑基固本,开宗立派

「练气期乃修仙之始,需筑基固本,方能踏上大道」

在练气期阶段,我们专注于构建最基础的系统框架,如同修士打坐炼气,为后续的突破打下坚实基础。这个阶段的目标是快速搭建一个可运行的核心系统,让弟子能够完成基础的注册、登录和任务接取功能。

技术栈:基础功法

  • Spring Boot 3.0 - 剑宗心法根基
  • Spring Security + JWT - 护体剑气
  • MyBatis-Plus - 基础吐纳术
  • MySQL 8.0 - 剑脉根基
  • Maven - 功法运转周天

数据库设计:剑脉初成

-- 弟子表(修士根基)
CREATE TABLE `sword_cultivator` (
  `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '弟子ID',
  `disciple_name` VARCHAR(50) NOT NULL UNIQUE COMMENT '道号',
  `password` VARCHAR(100) NOT NULL COMMENT '加密心法',
  `cultivation_realm` VARCHAR(20) NOT NULL DEFAULT '炼气期' COMMENT '修为境界',
  `merit_points` INT NOT NULL DEFAULT 0 COMMENT '功德点',
  `sword_root` VARCHAR(10) NOT NULL COMMENT '剑根属性:金木水火土',
  `created_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '入宗时间',
  `updated_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) COMMENT='天玄剑宗弟子信息表';

-- 剑宗任务表(历练机缘)
CREATE TABLE `sword_sect_mission` (
  `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '任务ID',
  `mission_name` VARCHAR(100) NOT NULL COMMENT '任务名称',
  `mission_type` VARCHAR(20) NOT NULL COMMENT '任务类型:SWORD_DISCIPLINE-剑道修行, HERB-采药, BEAST-御兽',
  `difficulty` VARCHAR(10) NOT NULL COMMENT '任务难度:EASY-简单, MEDIUM-中等, HARD-困难',
  `reward_merits` INT NOT NULL COMMENT '功德奖励',
  `description` TEXT COMMENT '任务描述',
  `required_realm` VARCHAR(20) DEFAULT '炼气期' COMMENT '接取要求境界',
  `status` VARCHAR(20) DEFAULT 'AVAILABLE' COMMENT '任务状态',
  `created_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
) COMMENT='天玄剑宗任务表';

-- 任务接取记录(修行历程)
CREATE TABLE `sword_mission_accept` (
  `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '记录ID',
  `mission_id` BIGINT NOT NULL COMMENT '任务ID',
  `cultivator_id` BIGINT NOT NULL COMMENT '弟子ID',
  `accept_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '接取时间',
  `completion_time` DATETIME COMMENT '完成时间',
  `status` VARCHAR(20) DEFAULT 'IN_PROGRESS' COMMENT '接取状态',
  FOREIGN KEY (`mission_id`) REFERENCES `sword_sect_mission` (`id`),
  FOREIGN KEY (`cultivator_id`) REFERENCES `sword_cultivator` (`id`)
) COMMENT='天玄剑宗任务接取记录表';

项目结构:剑阁开辟

tianxuan-sword-platform/
├── src/main/java/com/tianxuan/sword/
│   ├── TianxuanSwordApplication.java    # 剑宗大殿
│   ├── config/                         # 功法配置
│   │   ├── SecurityConfig.java         # 护宗剑阵
│   │   └── MybatisPlusConfig.java      # 藏剑阁配置
│   ├── controller/                     # 执剑堂
│   │   ├── AuthController.java         # 身份验证
│   │   └── MissionController.java      # 任务管理
│   ├── entity/                         # 修士本体
│   │   ├── SwordCultivator.java        # 弟子实体
│   │   ├── SwordSectMission.java       # 任务实体
│   │   └── SwordMissionAccept.java     # 接取记录
│   ├── mapper/                         # 神识连接
│   │   ├── SwordCultivatorMapper.java  # 弟子神识
│   │   ├── SwordSectMissionMapper.java # 任务神识
│   │   └── SwordMissionAcceptMapper.java # 记录神识
│   ├── service/                        # 功法运转
│   │   ├── AuthService.java            # 身份验证功法
│   │   └── MissionService.java         # 任务管理功法
│   ├── dto/                           # 传讯玉简
│   │   ├── RegisterRequest.java        # 入宗申请
│   │   └── LoginRequest.java           # 登录请求
│   ├── util/                          # 法宝工具
│   │   └── JwtTokenProvider.java       # 身份玉牌
│   └── security/                      # 护法体系
│       └── BusinessException.java      # 修炼异常
├── src/main/resources/
│   ├── application.yml                 # 剑宗灵脉
│   └── mapper/                         # 功法图谱
└── pom.xml                            # 功法总纲

核心功法修炼

1. 剑宗大殿(启动类)
/**
 * 天玄剑宗大殿 - 项目启动类
 * 注解说明:
 * @SpringBootApplication - 标注为Spring Boot应用,开启自动配置
 * @MapperScan - 扫描MyBatis Mapper接口
 */
@SpringBootApplication
@MapperScan("com.tianxuan.sword.mapper")
public class TianxuanSwordApplication {
    public static void main(String[] args) {
        SpringApplication.run(TianxuanSwordApplication.class, args);
        System.out.println("================================================");
        System.out.println("⚔️  天玄剑宗任务平台 - 练气期 · 启动成功!");
        System.out.println("📍 剑宗地址: http://localhost:8080");
        System.out.println("📚 剑诀文档: http://localhost:8080/api");
        System.out.println("💎 当前境界: 练气期 · MVP版本");
        System.out.println("================================================");
    }
}
2. 剑宗灵脉配置
# application.yml - 剑宗灵脉配置
spring:
  # 数据源配置 - 连接剑脉数据库
  datasource:
    url: jdbc:mysql://localhost:3306/tianxuan_sword?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  
  # JSON序列化配置
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

# 服务器配置
server:
  port: 8080
  servlet:
    context-path: /api

# 日志配置 - 修炼记录
logging:
  level:
    com.tianxuan.sword: debug
    org.springframework.security: debug
3. 修士本体(实体类)
/**
 * 剑宗弟子实体 - 修士本体
 * 注解说明:
 * @Data - Lombok注解,自动生成getter/setter
 * @TableName - MyBatis-Plus表名映射
 * @TableId - 主键注解
 */
@Data
@TableName("sword_cultivator")
public class SwordCultivator {
    @TableId(type = IdType.AUTO)
    private Long id;
    
    @TableField("disciple_name")
    private String discipleName;        // 道号
    
    private String password;            // 加密心法
    
    @TableField("cultivation_realm")
    private String cultivationRealm = "炼气期";  // 修为境界
    
    @TableField("merit_points")
    private Integer meritPoints = 0;    // 功德点
    
    @TableField("sword_root")
    private String swordRoot;           // 剑根属性
    
    @TableField("created_time")
    private Date createdTime;           // 入宗时间
    
    @TableField("updated_time")
    private Date updatedTime;           // 更新时间
    
    /**
     * 检查是否满足境界要求
     * @param requiredRealm 要求境界
     * @return 是否满足
     */
    public boolean canAcceptMission(String requiredRealm) {
        List<String> realmOrder = Arrays.asList("炼气期", "筑基期", "金丹期", "元婴期", "化神期");
        int currentIndex = realmOrder.indexOf(this.cultivationRealm);
        int requiredIndex = realmOrder.indexOf(requiredRealm);
        return currentIndex >= requiredIndex;
    }
}

/**
 * 剑宗任务实体 - 历练机缘
 */
@Data
@TableName("sword_sect_mission")
public class SwordSectMission {
    @TableId(type = IdType.AUTO)
    private Long id;
    
    @TableField("mission_name")
    private String missionName;         // 任务名称
    
    @TableField("mission_type")
    private String missionType;         // 任务类型
    
    private String difficulty;          // 任务难度
    
    @TableField("reward_merits")
    private Integer rewardMerits;       // 功德奖励
    
    private String description;         // 任务描述
    
    @TableField("required_realm")
    private String requiredRealm = "炼气期";  // 境界要求
    
    private String status = "AVAILABLE"; // 任务状态
    
    @TableField("created_time")
    private Date createdTime;           // 创建时间
}
4. 护宗剑阵(安全配置)
/**
 * 护宗剑阵配置 - Spring Security配置类
 * 注解说明:
 * @Configuration - 标注为配置类
 * @EnableWebSecurity - 启用Web安全
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    /**
     * 安全过滤器链 - 配置访问权限
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf().disable()  // 禁用CSRF保护(API项目通常不需要)
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/auth/**").permitAll()        // 认证接口公开
                .requestMatchers("/mission/list").permitAll()   // 任务列表公开
                .anyRequest().authenticated()                   // 其他接口需要认证
            )
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)  // 无状态会话
            );
        
        return http.build();
    }
    
    /**
     * 密码编码器 - BCrypt加密
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
5. 身份玉牌(JWT工具)
/**
 * 身份玉牌提供者 - JWT令牌工具类
 * 功能:生成、验证JWT令牌
 */
@Component
public class JwtTokenProvider {
    
    // 玉牌密钥(实际项目中应从配置读取)
    private final String SECRET_KEY = "天玄剑宗剑心通明剑气长存剑道永恒";
    private final long EXPIRATION_TIME = 86400000; // 24小时
    
    /**
     * 生成身份玉牌
     * @param cultivator 弟子信息
     * @return JWT令牌
     */
    public String generateToken(SwordCultivator cultivator) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("discipleName", cultivator.getDiscipleName());
        claims.put("realm", cultivator.getCultivationRealm());
        claims.put("swordRoot", cultivator.getSwordRoot());
        
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(cultivator.getId().toString())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }
    
    /**
     * 验证玉牌有效性
     * @param token JWT令牌
     * @return 是否有效
     */
    public boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            log.warn("无效的身份玉牌: {}", e.getMessage());
            return false;
        }
    }
    
    /**
     * 从玉牌中提取弟子ID
     * @param token JWT令牌
     * @return 弟子ID
     */
    public Long getCultivatorIdFromToken(String token) {
        Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
        return Long.parseLong(claims.getSubject());
    }
}
6. 入宗功法(认证服务)
/**
 * 认证服务 - 处理弟子注册登录
 * 注解说明:
 * @Service - 标注为业务服务组件
 * @Slf4j - Lombok日志注解
 * @Transactional - 事务管理
 */
@Service
@Slf4j
@Transactional
public class AuthService {
    
    @Autowired
    private SwordCultivatorMapper cultivatorMapper;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private JwtTokenProvider jwtTokenProvider;
    
    /**
     * 弟子入宗注册
     * @param request 注册请求
     * @return JWT令牌
     */
    public String register(RegisterRequest request) {
        log.info("开始处理弟子入宗申请: {}", request.getDiscipleName());
        
        // 检查道号是否已存在
        if (cultivatorMapper.selectByDiscipleName(request.getDiscipleName()) != null) {
            throw new BusinessException("道号【" + request.getDiscipleName() + "】已被占用,请换个道号");
        }
        
        // 创建新弟子
        SwordCultivator cultivator = new SwordCultivator();
        cultivator.setDiscipleName(request.getDiscipleName());
        cultivator.setPassword(passwordEncoder.encode(request.getPassword()));
        cultivator.setSwordRoot(request.getSwordRoot());
        cultivator.setCreatedTime(new Date());
        
        cultivatorMapper.insert(cultivator);
        log.info("🎉 新弟子入宗成功: {},剑根: {}", request.getDiscipleName(), request.getSwordRoot());
        
        return jwtTokenProvider.generateToken(cultivator);
    }
    
    /**
     * 弟子登录
     * @param request 登录请求
     * @return JWT令牌
     */
    public String login(LoginRequest request) {
        log.info("弟子尝试登录: {}", request.getDiscipleName());
        
        SwordCultivator cultivator = cultivatorMapper.selectByDiscipleName(request.getDiscipleName());
        if (cultivator == null || !passwordEncoder.matches(request.getPassword(), cultivator.getPassword())) {
            throw new BusinessException("道号或心法口令错误,请重新尝试");
        }
        
        log.info("✅ 弟子登录成功: {},境界: {}", cultivator.getDiscipleName(), cultivator.getCultivationRealm());
        return jwtTokenProvider.generateToken(cultivator);
    }
}
7. 任务管理功法(核心业务)
/**
 * 任务服务 - 剑宗任务管理核心功法
 */
@Service
@Slf4j
@Transactional
public class MissionService {
    
    @Autowired
    private SwordSectMissionMapper missionMapper;
    
    @Autowired
    private SwordMissionAcceptMapper missionAcceptMapper;
    
    @Autowired
    private SwordCultivatorMapper cultivatorMapper;
    
    /**
     * 获取可接取的任务列表
     * @return 任务列表
     */
    public List<SwordSectMission> getAvailableMissions() {
        List<SwordSectMission> missions = missionMapper.selectAvailableMissions();
        log.debug("查询到 {} 个可接取任务", missions.size());
        return missions;
    }
    
    /**
     * 接取剑宗任务
     * @param missionId 任务ID
     * @param cultivatorId 弟子ID
     */
    public void acceptMission(Long missionId, Long cultivatorId) {
        SwordSectMission mission = missionMapper.selectById(missionId);
        SwordCultivator cultivator = cultivatorMapper.selectById(cultivatorId);
        
        if (mission == null) {
            throw new BusinessException("任务不存在,可能已被取消");
        }
        
        // 检查任务状态
        if (!"AVAILABLE".equals(mission.getStatus())) {
            throw new BusinessException("该任务已被其他道友接取");
        }
        
        // 检查修为要求
        if (!cultivator.canAcceptMission(mission.getRequiredRealm())) {
            throw new BusinessException("修为不足,需要达到【" + mission.getRequiredRealm() + "】才能接取此任务");
        }
        
        // 创建接取记录
        SwordMissionAccept accept = new SwordMissionAccept();
        accept.setMissionId(missionId);
        accept.setCultivatorId(cultivatorId);
        accept.setAcceptTime(new Date());
        accept.setStatus("IN_PROGRESS");
        missionAcceptMapper.insert(accept);
        
        // 更新任务状态
        mission.setStatus("TAKEN");
        missionMapper.updateById(mission);
        
        log.info("📝 弟子 {} 接取了任务: {},任务难度: {}", 
                cultivator.getDiscipleName(), mission.getMissionName(), mission.getDifficulty());
    }
    
    /**
     * 完成任务并获得奖励
     * @param missionId 任务ID
     * @param cultivatorId 弟子ID
     */
    public void completeMission(Long missionId, Long cultivatorId) {
        SwordMissionAccept accept = missionAcceptMapper.selectByMissionAndCultivator(missionId, cultivatorId);
        SwordSectMission mission = missionMapper.selectById(missionId);
        SwordCultivator cultivator = cultivatorMapper.selectById(cultivatorId);
        
        if (accept == null || !"IN_PROGRESS".equals(accept.getStatus())) {
            throw new BusinessException("未找到进行中的任务记录");
        }
        
        // 发放功德奖励
        int reward = mission.getRewardMerits();
        cultivator.setMeritPoints(cultivator.getMeritPoints() + reward);
        cultivatorMapper.updateById(cultivator);
        
        // 更新接取记录
        accept.setStatus("COMPLETED");
        accept.setCompletionTime(new Date());
        missionAcceptMapper.updateById(accept);
        
        // 更新任务状态
        mission.setStatus("COMPLETED");
        missionMapper.updateById(mission);
        
        log.info("🎊 弟子 {} 完成任务【{}】,获得 {} 功德点,当前总功德: {}", 
                cultivator.getDiscipleName(), mission.getMissionName(), reward, cultivator.getMeritPoints());
    }
}
8. 执剑堂(控制器层)
/**
 * 认证控制器 - 处理身份验证相关请求
 */
@RestController
@RequestMapping("/auth")
public class AuthController {
    
    @Autowired
    private AuthService authService;
    
    /**
     * 弟子入宗注册
     */
    @PostMapping("/register")
    public ResponseEntity<ApiResponse<String>> register(@RequestBody @Valid RegisterRequest request) {
        String token = authService.register(request);
        return ResponseEntity.ok(ApiResponse.success("入宗成功,欢迎新道友!", token));
    }
    
    /**
     * 弟子登录
     */
    @PostMapping("/login")
    public ResponseEntity<ApiResponse<String>> login(@RequestBody @Valid LoginRequest request) {
        String token = authService.login(request);
        return ResponseEntity.ok(ApiResponse.success("登录成功,欢迎回来!", token));
    }
}

/**
 * 任务控制器 - 处理任务相关请求
 */
@RestController
@RequestMapping("/mission")
public class MissionController {
    
    @Autowired
    private MissionService missionService;
    
    @Autowired
    private JwtTokenProvider jwtTokenProvider;
    
    /**
     * 获取可接取任务列表
     */
    @GetMapping("/list")
    public ResponseEntity<ApiResponse<List<SwordSectMission>>> getAvailableMissions() {
        List<SwordSectMission> missions = missionService.getAvailableMissions();
        return ResponseEntity.ok(ApiResponse.success("获取任务列表成功", missions));
    }
    
    /**
     * 接取任务
     */
    @PostMapping("/{missionId}/accept")
    public ResponseEntity<ApiResponse<Void>> acceptMission(
            @PathVariable Long missionId,
            @RequestHeader("Authorization") String token) {
        
        Long cultivatorId = extractCultivatorId(token);
        missionService.acceptMission(missionId, cultivatorId);
        return ResponseEntity.ok(ApiResponse.success("接取任务成功,祝道友历练顺利!"));
    }
    
    /**
     * 完成任务
     */
    @PostMapping("/{missionId}/complete")
    public ResponseEntity<ApiResponse<Void>> completeMission(
            @PathVariable Long missionId,
            @RequestHeader("Authorization") String token) {
        
        Long cultivatorId = extractCultivatorId(token);
        missionService.completeMission(missionId, cultivatorId);
        return ResponseEntity.ok(ApiResponse.success("任务完成,功德点已发放!"));
    }
    
    /**
     * 从令牌中提取弟子ID
     */
    private Long extractCultivatorId(String token) {
        String jwtToken = token.replace("Bearer ", "");
        return jwtTokenProvider.getCultivatorIdFromToken(jwtToken);
    }
}

剑脉初始化(数据库脚本)

-- 初始化剑宗任务
INSERT INTO `sword_sect_mission` 
(`mission_name`, `mission_type`, `difficulty`, `reward_merits`, `description`, `required_realm`) 
VALUES
('基础剑诀练习', 'SWORD_DISCIPLINE', 'EASY', 15, '练习天玄剑宗基础剑诀一百遍,巩固剑道根基', '炼气期'),
('剑阁打扫', 'DISCIPLINE', 'EASY', 8, '打扫剑阁,擦拭宝剑,保持剑阁整洁', '炼气期'),
('后山采药', 'HERB', 'EASY', 12, '前往后山采集止血草和聚气草,注意避开毒虫', '炼气期'),
('驱逐妖兽', 'BEAST', 'MEDIUM', 35, '驱逐骚扰山下村民的低阶妖兽,维护宗门声誉', '筑基期'),
('剑阵护法', 'SWORD_DISCIPLINE', 'MEDIUM', 30, '协助长老维护护宗剑阵,学习剑阵知识', '筑基期'),
('炼丹助手', 'DISCIPLINE', 'MEDIUM', 28, '协助炼丹长老处理药材,学习基础炼丹术', '筑基期'),
('秘境探索', 'HERB', 'HARD', 85, '探索未知秘境,采集稀有灵草和剑道传承', '元婴期');

-- 创建测试弟子(密码均为:123456)
INSERT INTO `sword_cultivator` 
(`disciple_name`, `password`, `sword_root`) 
VALUES
('青云剑子', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iKTV2Ui.', '金'),
('明月剑仙', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iKTV2Ui.', '水'),
('烈阳剑尊', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iKTV2Ui.', '火');

修炼测试:运转周天

使用Postman测试练气期功能:

1. 入宗注册
POST http://localhost:8080/api/auth/register
Content-Type: application/json

{
  "discipleName": "新入剑子",
  "password": "123456",
  "swordRoot": "木"
}
2. 登录获取玉牌
POST http://localhost:8080/api/auth/login
Content-Type: application/json

{
  "discipleName": "青云剑子",
  "password": "123456"
}
3. 查看任务列表
GET http://localhost:8080/api/mission/list
4. 接取任务
POST http://localhost:8080/api/mission/1/accept
Authorization: Bearer {你的JWT令牌}

练气期修炼成果

🎯 已掌握功法:

  • 剑宗大殿启动 - Spring Boot应用成功运行
  • 弟子入宗系统 - 完整的注册登录流程
  • 身份玉牌机制 - JWT令牌认证系统
  • 基础任务管理 - 任务查看、接取、完成全流程
  • 功德点系统 - 任务奖励自动发放
  • 境界验证 - 修为要求检查机制

🛡️ 护法体系:

  • 道号唯一性验证
  • 心法口令加密存储
  • 境界要求自动检查
  • 任务状态完整性保护

📊 修炼记录:

  • 完整的日志记录系统
  • 统一异常处理
  • 标准化API响应格式

下一步修炼:筑基期

「练气已成,筑基在即。下一阶段我们将为剑宗添加更多神通妙用!」

在筑基期,我们将重点修炼:

  • 任务发布与管理功能
  • 弟子个人信息管理
  • 功德榜排名系统
  • 基础的前端界面
  • 数据缓存优化

当前境界: 🟢 练气期 · MVP
下一境界: 🟡 筑基期 · 核心功能
功法仓库: git checkout realm-qi-refining

「剑基已固,剑脉初成。愿诸位道友在剑道的道路上稳步前行!」