为了将土地类型属性和升级材料从硬编码改为数据表配置,我们设计了以下两个表:
存储不同土地类型的属性,如产量加成、灾害抵抗等。
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%,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%灾害抵抗
存储土地升级路径和所需材料。
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='土地升级配置表';
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}');
conditions 字段是一个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"
}
}
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
/**
* 获取升级所需材料
*
* @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'] ?? [];
}
/**
* 验证升级路径是否有效
*
* @param int $currentType 当前土地类型
* @param int $targetType 目标土地类型
* @return bool 是否有效
*/
public function isValidUpgradePath(int $currentType, int $targetType): bool
{
// 从数据库中检查是否存在升级配置
return $this->landUpgradeConfigRepository->existsByFromAndToType($currentType, $targetType);
}
/**
* 检查升级条件是否满足
*
* @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' => ''];
}
/**
* 判断是否为特殊土地类型
*
* @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;
}