配置表设计.md 21 KB

任务模块配置表设计

1. 概述

任务模块的配置表是为客户端提供的JSON格式配置文件,用于定义任务的基本信息、完成条件、奖励内容等。本文档详细介绍了任务模块配置表的设计,包括配置表结构、字段说明、生成方式以及使用方法。

2. 配置表结构

任务模块的配置表主要包括以下几个部分:

  1. 任务基础配置表 - 定义任务的基本信息
  2. 任务条件配置表 - 定义任务的完成条件
  3. 任务奖励配置表 - 定义任务的奖励内容
  4. 任务消耗配置表 - 定义任务的接取消耗

2.1 任务基础配置表

任务基础配置表定义了任务的基本信息,包括任务ID、名称、描述、类型、等级要求等。

文件名task_config.json

结构示例

{
  "tasks": [
    {
      "id": 1001,
      "name": "每日登录",
      "description": "每天登录游戏",
      "type": "daily",
      "category_id": 1,
      "level_required": 1,
      "max_completions": 1,
      "reset_type": "daily",
      "sort_order": 100,
      "display_params": {
        "icon": "login_icon.png",
        "background": "daily_task_bg.png",
        "color": "#FF5733"
      },
      "conditions": [1001],
      "rewards": [1001, 1002],
      "costs": []
    },
    {
      "id": 1002,
      "name": "种植10次作物",
      "description": "种植10次任意作物",
      "type": "daily",
      "category_id": 2,
      "level_required": 2,
      "max_completions": 1,
      "reset_type": "daily",
      "sort_order": 90,
      "display_params": {
        "icon": "plant_icon.png",
        "background": "daily_task_bg.png",
        "color": "#33FF57"
      },
      "conditions": [1002],
      "rewards": [1003, 1004],
      "costs": []
    }
  ],
  "categories": [
    {
      "id": 1,
      "name": "每日任务",
      "code": "daily",
      "description": "每天可完成的任务",
      "sort_order": 100
    },
    {
      "id": 2,
      "name": "成就任务",
      "code": "achievement",
      "description": "一次性完成的成就任务",
      "sort_order": 90
    }
  ]
}

字段说明

字段 类型 必填 描述
id int 任务ID
name string 任务名称
description string 任务描述
type string 任务类型(daily, weekly, achievement, event, tutorial, team)
category_id int 任务分类ID
level_required int 所需等级
max_completions int 最大完成次数
reset_type string 重置类型(none, daily, weekly, monthly)
sort_order int 排序权重(数值越大越靠前)
display_params object 显示参数,如图标、背景、颜色等
conditions array 任务条件ID列表
rewards array 任务奖励ID列表
costs array 任务接取消耗ID列表

2.2 任务条件配置表

任务条件配置表定义了任务的完成条件,包括条件ID、条件类型、目标值等。

文件名task_condition_config.json

结构示例

{
  "conditions": [
    {
      "id": 1001,
      "task_id": 1001,
      "condition_code": "login",
      "condition_type": "progress",
      "target_value": 1,
      "params": {},
      "operator": "=",
      "sort_order": 1,
      "is_required": true
    },
    {
      "id": 1002,
      "task_id": 1002,
      "condition_code": "plant_crop",
      "condition_type": "progress",
      "target_value": 10,
      "params": {
        "crop_id": 0
      },
      "operator": ">=",
      "sort_order": 1,
      "is_required": true
    }
  ],
  "condition_types": [
    {
      "code": "login",
      "name": "登录游戏",
      "description": "登录游戏",
      "param_schema": {}
    },
    {
      "code": "plant_crop",
      "name": "种植作物",
      "description": "种植作物",
      "param_schema": {
        "crop_id": {
          "type": "integer",
          "required": false,
          "description": "作物ID,0表示任意作物"
        }
      }
    }
  ]
}

字段说明

字段 类型 必填 描述
id int 条件ID
task_id int 任务ID
condition_code string 条件代码
condition_type string 条件类型(prerequisite=前置条件,progress=进度条件)
target_value int 目标值
params object 条件参数
operator string 运算符(=, >=, <=)
sort_order int 排序顺序
is_required bool 是否必须满足此条件

2.3 任务奖励配置表

任务奖励配置表定义了任务的奖励内容,包括奖励ID、奖励类型、奖励数量等。

文件名task_reward_config.json

结构示例

{
  "rewards": [
    {
      "id": 1001,
      "task_id": 1001,
      "reward_type": "currency",
      "reward_param1": "gold",
      "reward_param2": "1",
      "quantity": 100,
      "extra_data": {},
      "sort_order": 1
    },
    {
      "id": 1002,
      "task_id": 1001,
      "reward_type": "item",
      "reward_param1": "seed",
      "reward_param2": "1001",
      "quantity": 5,
      "extra_data": {},
      "sort_order": 2
    },
    {
      "id": 1003,
      "task_id": 1002,
      "reward_type": "currency",
      "reward_param1": "gold",
      "reward_param2": "1",
      "quantity": 200,
      "extra_data": {},
      "sort_order": 1
    },
    {
      "id": 1004,
      "task_id": 1002,
      "reward_type": "experience",
      "reward_param1": "player",
      "reward_param2": "1",
      "quantity": 50,
      "extra_data": {},
      "sort_order": 2
    }
  ]
}

字段说明

字段 类型 必填 描述
id int 奖励ID
task_id int 任务ID
reward_type string 奖励类型(item, currency, experience, feature_unlock等)
reward_param1 string 奖励参数1(如物品类型、货币类型等)
reward_param2 string 奖励参数2(如物品ID、货币ID等)
quantity int 奖励数量
extra_data object 额外数据
sort_order int 排序权重

2.4 任务消耗配置表

任务消耗配置表定义了任务的接取消耗,包括消耗ID、消耗类型、消耗数量等。

文件名task_cost_config.json

结构示例

{
  "costs": [
    {
      "id": 1001,
      "task_id": 1003,
      "cost_type": "currency",
      "cost_param1": "gold",
      "cost_param2": "1",
      "quantity": 50,
      "extra_data": {},
      "sort_order": 1
    },
    {
      "id": 1002,
      "task_id": 1003,
      "cost_type": "item",
      "cost_param1": "ticket",
      "cost_param2": "1001",
      "quantity": 1,
      "extra_data": {},
      "sort_order": 2
    }
  ]
}

字段说明

字段 类型 必填 描述
id int 消耗ID
task_id int 任务ID
cost_type string 消耗类型(currency, item, energy, ticket等)
cost_param1 string 消耗参数1(如货币类型、物品类型等)
cost_param2 string 消耗参数2(如货币ID、物品ID等)
quantity int 消耗数量
extra_data object 额外数据
sort_order int 排序权重

3. 配置表生成方式

任务模块的配置表可以通过以下几种方式生成:

3.1 数据库导出

通过数据库查询导出配置表数据:

use App\Module\Task\Models\Task;
use App\Module\Task\Models\TaskCategory;
use App\Module\Task\Models\TaskAchievementCondition;
use App\Module\Task\Models\TaskCondition;
use App\Module\Task\Models\TaskReward;
use App\Module\Task\Models\TaskCost;

// 导出任务基础配置表
public function exportTaskConfig()
{
    $tasks = Task::with(['achievementConditions', 'rewards', 'costs'])->get();
    $categories = TaskCategory::all();
    
    $taskConfig = [
        'tasks' => [],
        'categories' => []
    ];
    
    foreach ($tasks as $task) {
        $taskConfig['tasks'][] = [
            'id' => $task->id,
            'name' => $task->name,
            'description' => $task->description,
            'type' => $task->type,
            'category_id' => $task->category_id,
            'level_required' => $task->level_required,
            'max_completions' => $task->max_completions,
            'reset_type' => $task->reset_type,
            'sort_order' => $task->sort_order,
            'display_params' => $task->display_params,
            'conditions' => $task->achievementConditions->pluck('id')->toArray(),
            'rewards' => $task->rewards->pluck('id')->toArray(),
            'costs' => $task->costs->pluck('id')->toArray()
        ];
    }
    
    foreach ($categories as $category) {
        $taskConfig['categories'][] = [
            'id' => $category->id,
            'name' => $category->name,
            'code' => $category->code,
            'description' => $category->description,
            'sort_order' => $category->sort_order
        ];
    }
    
    return json_encode($taskConfig, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}

// 导出任务条件配置表
public function exportTaskConditionConfig()
{
    $conditions = TaskAchievementCondition::with('condition')->get();
    $conditionTypes = TaskCondition::all();
    
    $conditionConfig = [
        'conditions' => [],
        'condition_types' => []
    ];
    
    foreach ($conditions as $condition) {
        $conditionConfig['conditions'][] = [
            'id' => $condition->id,
            'task_id' => $condition->task_id,
            'condition_code' => $condition->condition->code,
            'condition_type' => $condition->condition_type,
            'target_value' => $condition->target_value,
            'params' => $condition->params,
            'operator' => $condition->operator,
            'sort_order' => $condition->sort_order,
            'is_required' => $condition->is_required
        ];
    }
    
    foreach ($conditionTypes as $type) {
        $conditionConfig['condition_types'][] = [
            'code' => $type->code,
            'name' => $type->name,
            'description' => $type->description,
            'param_schema' => $type->param_schema
        ];
    }
    
    return json_encode($conditionConfig, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}

// 导出任务奖励配置表
public function exportTaskRewardConfig()
{
    $rewards = TaskReward::all();
    
    $rewardConfig = [
        'rewards' => []
    ];
    
    foreach ($rewards as $reward) {
        $rewardConfig['rewards'][] = [
            'id' => $reward->id,
            'task_id' => $reward->task_id,
            'reward_type' => $reward->reward_type,
            'reward_param1' => $reward->reward_param1,
            'reward_param2' => $reward->reward_param2,
            'quantity' => $reward->quantity,
            'extra_data' => $reward->extra_data,
            'sort_order' => $reward->sort_order
        ];
    }
    
    return json_encode($rewardConfig, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}

// 导出任务消耗配置表
public function exportTaskCostConfig()
{
    $costs = TaskCost::all();
    
    $costConfig = [
        'costs' => []
    ];
    
    foreach ($costs as $cost) {
        $costConfig['costs'][] = [
            'id' => $cost->id,
            'task_id' => $cost->task_id,
            'cost_type' => $cost->cost_type,
            'cost_param1' => $cost->cost_param1,
            'cost_param2' => $cost->cost_param2,
            'quantity' => $cost->quantity,
            'extra_data' => $cost->extra_data,
            'sort_order' => $cost->sort_order
        ];
    }
    
    return json_encode($costConfig, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}

3.2 命令行工具

通过命令行工具生成配置表:

namespace App\Module\Task\Commands;

use Illuminate\Console\Command;
use App\Module\Task\Services\TaskConfigService;

class GenerateTaskConfigCommand extends Command
{
    /**
     * 命令名称
     *
     * @var string
     */
    protected $signature = 'task:generate-config {--output=public/configs}';

    /**
     * 命令描述
     *
     * @var string
     */
    protected $description = '生成任务模块配置表';

    /**
     * 任务配置服务
     *
     * @var TaskConfigService
     */
    protected $configService;

    /**
     * 创建命令实例
     *
     * @param TaskConfigService $configService
     * @return void
     */
    public function __construct(TaskConfigService $configService)
    {
        parent::__construct();
        $this->configService = $configService;
    }

    /**
     * 执行命令
     *
     * @return int
     */
    public function handle()
    {
        $outputPath = $this->option('output');
        
        // 确保输出目录存在
        if (!is_dir($outputPath)) {
            mkdir($outputPath, 0755, true);
        }
        
        // 生成任务基础配置表
        $taskConfig = $this->configService->exportTaskConfig();
        file_put_contents("$outputPath/task_config.json", $taskConfig);
        $this->info("任务基础配置表已生成:$outputPath/task_config.json");
        
        // 生成任务条件配置表
        $conditionConfig = $this->configService->exportTaskConditionConfig();
        file_put_contents("$outputPath/task_condition_config.json", $conditionConfig);
        $this->info("任务条件配置表已生成:$outputPath/task_condition_config.json");
        
        // 生成任务奖励配置表
        $rewardConfig = $this->configService->exportTaskRewardConfig();
        file_put_contents("$outputPath/task_reward_config.json", $rewardConfig);
        $this->info("任务奖励配置表已生成:$outputPath/task_reward_config.json");
        
        // 生成任务消耗配置表
        $costConfig = $this->configService->exportTaskCostConfig();
        file_put_contents("$outputPath/task_cost_config.json", $costConfig);
        $this->info("任务消耗配置表已生成:$outputPath/task_cost_config.json");
        
        return 0;
    }
}

4. 配置表使用方法

4.1 客户端使用

客户端可以通过HTTP请求获取配置表,然后解析JSON数据:

// 获取任务基础配置表
fetch('/configs/task_config.json')
  .then(response => response.json())
  .then(data => {
    // 处理任务基础配置数据
    console.log(data.tasks);
    console.log(data.categories);
  });

// 获取任务条件配置表
fetch('/configs/task_condition_config.json')
  .then(response => response.json())
  .then(data => {
    // 处理任务条件配置数据
    console.log(data.conditions);
    console.log(data.condition_types);
  });

// 获取任务奖励配置表
fetch('/configs/task_reward_config.json')
  .then(response => response.json())
  .then(data => {
    // 处理任务奖励配置数据
    console.log(data.rewards);
  });

// 获取任务消耗配置表
fetch('/configs/task_cost_config.json')
  .then(response => response.json())
  .then(data => {
    // 处理任务消耗配置数据
    console.log(data.costs);
  });

4.2 服务端使用

服务端可以通过配置服务读取配置表:

namespace App\Module\Task\Services;

use Illuminate\Support\Facades\File;

class TaskConfigService
{
    /**
     * 配置文件路径
     *
     * @var string
     */
    protected $configPath = 'public/configs';
    
    /**
     * 获取任务基础配置
     *
     * @return array
     */
    public function getTaskConfig()
    {
        $configFile = "{$this->configPath}/task_config.json";
        
        if (File::exists($configFile)) {
            return json_decode(File::get($configFile), true);
        }
        
        return [
            'tasks' => [],
            'categories' => []
        ];
    }
    
    /**
     * 获取任务条件配置
     *
     * @return array
     */
    public function getTaskConditionConfig()
    {
        $configFile = "{$this->configPath}/task_condition_config.json";
        
        if (File::exists($configFile)) {
            return json_decode(File::get($configFile), true);
        }
        
        return [
            'conditions' => [],
            'condition_types' => []
        ];
    }
    
    /**
     * 获取任务奖励配置
     *
     * @return array
     */
    public function getTaskRewardConfig()
    {
        $configFile = "{$this->configPath}/task_reward_config.json";
        
        if (File::exists($configFile)) {
            return json_decode(File::get($configFile), true);
        }
        
        return [
            'rewards' => []
        ];
    }
    
    /**
     * 获取任务消耗配置
     *
     * @return array
     */
    public function getTaskCostConfig()
    {
        $configFile = "{$this->configPath}/task_cost_config.json";
        
        if (File::exists($configFile)) {
            return json_decode(File::get($configFile), true);
        }
        
        return [
            'costs' => []
        ];
    }
}

5. 配置表更新机制

5.1 定时更新

通过定时任务定期更新配置表:

// 在App\Console\Kernel.php中注册定时任务
protected function schedule(Schedule $schedule)
{
    // 每天凌晨2点更新任务配置表
    $schedule->command('task:generate-config')->dailyAt('02:00');
}

5.2 手动更新

通过后台管理界面手动更新配置表:

// 在后台控制器中添加更新配置表的方法
public function generateConfig()
{
    Artisan::call('task:generate-config');
    
    return redirect()->back()->with('success', '任务配置表已更新');
}

6. 配置表版本控制

为了确保客户端使用最新的配置表,可以实现版本控制机制:

6.1 版本号文件

创建一个版本号文件,记录配置表的版本信息:

{
  "version": "1.0.0",
  "update_time": "2023-06-10 12:00:00",
  "files": [
    {
      "name": "task_config.json",
      "version": "1.0.0",
      "md5": "a1b2c3d4e5f6g7h8i9j0"
    },
    {
      "name": "task_condition_config.json",
      "version": "1.0.0",
      "md5": "b2c3d4e5f6g7h8i9j0k1"
    },
    {
      "name": "task_reward_config.json",
      "version": "1.0.0",
      "md5": "c3d4e5f6g7h8i9j0k1l2"
    },
    {
      "name": "task_cost_config.json",
      "version": "1.0.0",
      "md5": "d4e5f6g7h8i9j0k1l2m3"
    }
  ]
}

6.2 版本检查接口

提供一个版本检查接口,让客户端检查配置表是否需要更新:

// 在API控制器中添加版本检查方法
public function checkConfigVersion()
{
    $versionFile = public_path('configs/version.json');
    
    if (File::exists($versionFile)) {
        $version = json_decode(File::get($versionFile), true);
        
        return response()->json([
            'success' => true,
            'data' => $version
        ]);
    }
    
    return response()->json([
        'success' => false,
        'message' => '版本文件不存在'
    ]);
}

7. 最佳实践

  1. 保持配置表简洁:只包含客户端需要的数据,避免包含敏感信息
  2. 使用CDN加速:将配置表部署到CDN,提高访问速度
  3. 增量更新:实现增量更新机制,减少数据传输量
  4. 压缩配置表:使用gzip等压缩算法减小配置表大小
  5. 缓存配置表:客户端缓存配置表,减少网络请求
  6. 版本控制:实现版本控制机制,确保客户端使用最新的配置表
  7. 备份配置表:定期备份配置表,防止数据丢失

8. 常见问题与解决方案

8.1 配置表过大

可能的原因:

  • 包含了过多不必要的数据
  • 数据结构不合理

解决方案:

  • 优化数据结构,减少冗余数据
  • 拆分配置表,按需加载
  • 使用压缩算法减小配置表大小

8.2 配置表更新不及时

可能的原因:

  • 定时任务未执行
  • 客户端缓存未更新

解决方案:

  • 检查定时任务配置
  • 实现版本控制机制,强制客户端更新缓存

8.3 配置表数据不一致

可能的原因:

  • 多个服务器之间的配置表不同步
  • 生成配置表时数据库状态不一致

解决方案:

  • 使用中央存储服务存储配置表
  • 在事务中生成配置表,确保数据一致性

9. 参考资料

10. 更新历史

日期 版本 更新内容
2023-06-10 1.0 初始版本
2023-06-15 1.1 添加版本控制机制
2023-06-20 1.2 添加常见问题与解决方案