# 土地配置表设计 为了将土地类型属性和升级材料从硬编码改为数据表配置,我们设计了以下两个表: ## 1. 土地类型配置表 (farm_land_types) 存储不同土地类型的属性,如产量加成、灾害抵抗等。 ```sql CREATE TABLE `farm_land_types` ( `id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT COMMENT '土地类型ID', `name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '土地类型名称', `code` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '土地类型编码', `output_bonus` decimal(5,2) NOT NULL DEFAULT '0.00' COMMENT '产量加成(百分比格式,1=1%)', `disaster_resistance` decimal(5,2) NOT NULL DEFAULT '0.00' COMMENT '灾害抵抗(百分比格式,1=1%)', `unlock_house_level` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '解锁所需房屋等级', `is_special` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否为特殊土地', `icon` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '图标路径', `description` text COLLATE utf8mb4_unicode_ci COMMENT '描述', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `idx_code` (`code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='土地类型配置表'; ``` ### 1.1 初始数据 ```sql -- 注意:数值为百分比格式,1=1%,10=10% INSERT INTO `farm_land_types` (`id`, `name`, `code`, `output_bonus`, `disaster_resistance`, `unlock_house_level`, `is_special`) VALUES (1, '普通土地', 'NORMAL', 0.00, 0.00, 1, 0), -- 0%产量加成,0%灾害抵抗 (2, '红土地', 'RED', 10.00, 5.00, 1, 0), -- 10%产量加成,5%灾害抵抗 (3, '黑土地', 'BLACK', 25.00, 10.00, 1, 0), -- 25%产量加成,10%灾害抵抗 (4, '金色特殊土地', 'GOLD', 50.00, 15.00, 7, 1), -- 50%产量加成,15%灾害抵抗 (5, '蓝色特殊土地', 'BLUE', 40.00, 25.00, 7, 1), -- 40%产量加成,25%灾害抵抗 (6, '紫色特殊土地', 'PURPLE', 60.00, 10.00, 7, 1); -- 60%产量加成,10%灾害抵抗 ``` ## 2. 土地升级配置表 (farm_land_upgrade_configs) 存储土地升级路径和所需材料。 ```sql CREATE TABLE `farm_land_upgrade_configs` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', `from_type_id` tinyint(3) unsigned NOT NULL COMMENT '起始土地类型ID', `to_type_id` tinyint(3) unsigned NOT NULL COMMENT '目标土地类型ID', `materials` json NOT NULL COMMENT '升级所需材料', `conditions` json DEFAULT NULL COMMENT '其他升级条件', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `idx_from_to` (`from_type_id`,`to_type_id`), KEY `idx_from_type` (`from_type_id`), KEY `idx_to_type` (`to_type_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='土地升级配置表'; ``` ### 2.1 初始数据 ```sql INSERT INTO `farm_land_upgrade_configs` (`from_type_id`, `to_type_id`, `materials`, `conditions`) VALUES (1, 2, '{"materials": [{"item_name": "木材", "amount": 10}]}', NULL), (2, 3, '{"materials": [{"item_name": "石材", "amount": 10}]}', NULL), (3, 4, '{"materials": [{"item_name": "钢材", "amount": 10}, {"item_name": "钻石", "amount": 5}]}', '{"house_level_min": 7, "special_land_check": true}'), (3, 5, '{"materials": [{"item_name": "钢材", "amount": 10}, {"item_name": "钻石", "amount": 5}]}', '{"house_level_min": 7, "special_land_check": true}'), (3, 6, '{"materials": [{"item_name": "钢材", "amount": 10}, {"item_name": "钻石", "amount": 5}]}', '{"house_level_min": 7, "special_land_check": true}'); ``` ### 2.2 条件字段说明 `conditions` 字段是一个JSON对象,可以包含以下属性: 1. **house_level_min**: 最低房屋等级要求 2. **special_land_check**: 是否检查特殊土地数量限制 3. **user_level_min**: 最低用户等级要求(可选) 4. **quest_completed**: 需要完成的任务ID(可选) 5. **time_limited**: 时间限制配置(可选) - start_time: 开始时间 - end_time: 结束时间 示例: ```json { "house_level_min": 7, "special_land_check": true, "user_level_min": 10, "quest_completed": [101, 102], "time_limited": { "start_time": "2023-01-01 00:00:00", "end_time": "2023-12-31 23:59:59" } } ``` ## 3. 与现有数据库的关系 ### 3.1 关系图更新 ``` farm_user_referrals ^ | | farm_users (1) ------ (N) farm_lands | | | | | | | | | | | | | v v | farm_house_configs farm_crops | | | | | | | v | farm_seeds | | | | | v | farm_harvest_logs -----+ | | v farm_team_profits farm_land_types <---- farm_lands ^ | v farm_land_upgrade_configs ``` ### 3.2 关系说明 1. **土地与土地类型**:土地表中的 land_type 字段关联到 farm_land_types 表的 id 字段 2. **土地升级配置**:farm_land_upgrade_configs 表通过 from_type_id 和 to_type_id 字段关联到 farm_land_types 表 ## 4. 代码修改 ### 4.1 修改 LandLogic 类中的 getUpgradeMaterials 方法 ```php /** * 获取升级所需材料 * * @param int $currentType 当前土地类型 * @param int $targetType 目标土地类型 * @return array 升级所需材料 */ public function getUpgradeMaterials(int $currentType, int $targetType): array { // 从数据库中获取升级配置 $upgradeConfig = $this->landUpgradeConfigRepository->findByFromAndToType($currentType, $targetType); if (!$upgradeConfig) { return []; } return json_decode($upgradeConfig->materials, true)['materials'] ?? []; } ``` ### 4.2 修改 LandLogic 类中的 isValidUpgradePath 方法 ```php /** * 验证升级路径是否有效 * * @param int $currentType 当前土地类型 * @param int $targetType 目标土地类型 * @return bool 是否有效 */ public function isValidUpgradePath(int $currentType, int $targetType): bool { // 从数据库中检查是否存在升级配置 return $this->landUpgradeConfigRepository->existsByFromAndToType($currentType, $targetType); } ``` ### 4.3 添加 LandLogic 类中的 checkUpgradeConditions 方法 ```php /** * 检查升级条件是否满足 * * @param int $userId 用户ID * @param int $currentType 当前土地类型 * @param int $targetType 目标土地类型 * @return array ['success' => bool, 'message' => string] 检查结果和消息 */ public function checkUpgradeConditions(int $userId, int $currentType, int $targetType): array { // 从数据库中获取升级配置 $upgradeConfig = $this->landUpgradeConfigRepository->findByFromAndToType($currentType, $targetType); if (!$upgradeConfig) { return ['success' => false, 'message' => '无效的升级路径']; } // 解析条件 $conditions = json_decode($upgradeConfig->conditions, true); if (empty($conditions)) { return ['success' => true, 'message' => '']; } // 检查房屋等级条件 if (isset($conditions['house_level_min'])) { $houseLevel = $this->farmUserRepository->findByUserId($userId)->house_level; if ($houseLevel < $conditions['house_level_min']) { return [ 'success' => false, 'message' => "房屋等级不足,需要{$conditions['house_level_min']}级房屋" ]; } } // 检查特殊土地数量限制 if (isset($conditions['special_land_check']) && $conditions['special_land_check']) { $landType = $this->landTypeRepository->find($targetType); if ($landType && $landType->is_special) { if (!$this->canHaveMoreSpecialLand($userId, $targetType)) { return [ 'success' => false, 'message' => '已达到特殊土地上限' ]; } } } // 检查用户等级条件 if (isset($conditions['user_level_min'])) { $userLevel = $this->userRepository->findById($userId)->level; if ($userLevel < $conditions['user_level_min']) { return [ 'success' => false, 'message' => "用户等级不足,需要达到{$conditions['user_level_min']}级" ]; } } // 检查任务完成条件 if (isset($conditions['quest_completed']) && !empty($conditions['quest_completed'])) { $questIds = $conditions['quest_completed']; foreach ($questIds as $questId) { if (!$this->questService->isQuestCompleted($userId, $questId)) { return [ 'success' => false, 'message' => "需要完成指定任务" ]; } } } // 检查时间限制条件 if (isset($conditions['time_limited'])) { $now = time(); $startTime = strtotime($conditions['time_limited']['start_time']); $endTime = strtotime($conditions['time_limited']['end_time']); if ($now < $startTime || $now > $endTime) { return [ 'success' => false, 'message' => "不在升级开放时间内" ]; } } return ['success' => true, 'message' => '']; } ``` ### 4.4 修改 LandLogic 类中的 isSpecialLandType 方法 ```php /** * 判断是否为特殊土地类型 * * @param int $landType 土地类型 * @return bool 是否为特殊土地 */ public function isSpecialLandType(int $landType): bool { // 从数据库中获取土地类型配置 $landTypeConfig = $this->landTypeRepository->find($landType); if (!$landTypeConfig) { return false; } return (bool)$landTypeConfig->is_special; } ``` ## 5. 优势 1. **灵活配置**:可以通过后台管理界面修改土地类型属性和升级材料,无需修改代码 2. **易于扩展**:可以轻松添加新的土地类型和升级路径 3. **数据一致性**:避免硬编码导致的数据不一致问题 4. **便于管理**:集中管理所有土地相关配置 ## 6. 注意事项 1. **数据迁移**:实施此方案需要编写数据迁移脚本,将现有的枚举值转换为数据表记录 2. **代码修改**:需要修改相关的业务逻辑代码,使用数据库配置替代硬编码 3. **缓存策略**:由于配置数据频繁访问但很少修改,应实施适当的缓存策略 4. **前端适配**:前端代码可能需要调整,以适应新的数据结构