土地配置表设计.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 '产量加成',
  `disaster_resistance` decimal(5,2) NOT NULL DEFAULT '0.00' COMMENT '灾害抵抗',
  `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 初始数据

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),
(2, '红土地', 'RED', 0.10, 0.05, 1, 0),
(3, '黑土地', 'BLACK', 0.25, 0.10, 1, 0),
(4, '金色特殊土地', 'GOLD', 0.50, 0.15, 7, 1),
(5, '蓝色特殊土地', 'BLUE', 0.40, 0.25, 7, 1),
(6, '紫色特殊土地', 'PURPLE', 0.60, 0.10, 7, 1);

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. 前端适配:前端代码可能需要调整,以适应新的数据结构