土地配置表设计.md 11 KB

土地配置表设计

为了将土地类型属性和升级材料从硬编码改为数据表配置,我们设计了以下两个表:

1. 土地类型配置表 (farm_land_types)

存储不同土地类型的属性,如产量加成、灾害抵抗等。

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 初始数据

-- 注意:数值为百分比格式,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)

存储土地升级路径和所需材料。

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 初始数据

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: 结束时间

示例:

{
  "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 方法

/**
 * 获取升级所需材料
 *
 * @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 方法

/**
 * 验证升级路径是否有效
 *
 * @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 方法

/**
 * 检查升级条件是否满足
 *
 * @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 方法

/**
 * 判断是否为特殊土地类型
 *
 * @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. 前端适配:前端代码可能需要调整,以适应新的数据结构