《天玄剑宗宗门任务平台:从零到部署的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
「剑基已固,剑脉初成。愿诸位道友在剑道的道路上稳步前行!」