refactor(common): 重构游戏数据同步与单例模块代码
- 移除 GameDataSyncManager 类及相关依赖,简化数据同步管理逻辑 - 在 SingletonModuleComp 中集成数据管理功能,使用本地数组替代字典结构存储英雄数据 - 优化本地与云端数据同步方法,适配云函数接口改动 - 修改英雄判断逻辑,支持基于数组的查询方式 - 修正金币数据的增减接口,增加异步云调用与本地更新的统一处理 - 删除冗余注释及无用代码,提升代码可读性和维护性 - 调整数据结构定义和类型声明,保障类型安全与代码健壮性
This commit is contained in:
@@ -1,371 +1,80 @@
|
||||
// 云函数路由入口文件
|
||||
// 云函数入口文件
|
||||
const cloud = require('wx-server-sdk');
|
||||
|
||||
// 导入各个模块
|
||||
const authModule = require('./modules/auth');
|
||||
const gameDataModule = require('./modules/gameData');
|
||||
const fightHerosModule = require('./modules/fightHeros');
|
||||
const herosModule = require('./modules/heros');
|
||||
const inventoryModule = require('./modules/inventory');
|
||||
const itemsModule = require('./modules/items');
|
||||
const talsModule = require('./modules/tals');
|
||||
const equipsModule = require('./modules/equips');
|
||||
const responseModule = require('./modules/response');
|
||||
|
||||
const user_db_name = "cocos_users";
|
||||
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }); // 使用当前云环境
|
||||
|
||||
// 云函数入口函数
|
||||
exports.main = async (event, context) => {
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
// 验证命令参数
|
||||
const validation = responseModule.validateRequiredParams(event, ['cmd']);
|
||||
if (validation) {
|
||||
return validation;
|
||||
}
|
||||
|
||||
const { cmd, ...params } = event;
|
||||
let cmd = event.cmd;
|
||||
if (cmd == null) {
|
||||
return {
|
||||
code: -1,
|
||||
msg: "no cmd!"
|
||||
};
|
||||
}
|
||||
|
||||
const wxContext = cloud.getWXContext();
|
||||
const db = cloud.database({
|
||||
env: cloud.DYNAMIC_CURRENT_ENV,
|
||||
throwOnNotFound: false
|
||||
});
|
||||
|
||||
console.log(`[${cmd}] Request from ${wxContext.OPENID}:`, params);
|
||||
|
||||
// 路由分发
|
||||
let result;
|
||||
switch (cmd) {
|
||||
// ==================== 认证相关 ====================
|
||||
case 'login':
|
||||
result = await authModule.login(db, wxContext);
|
||||
break;
|
||||
|
||||
case 'user_info':
|
||||
result = await authModule.getUserInfo(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
case 'version':
|
||||
result = await authModule.checkVersion(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
case 'upgrade':
|
||||
result = await authModule.upgradeUserData(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
// ==================== 基础游戏数据 ====================
|
||||
case 'data_get':
|
||||
result = await gameDataModule.getData(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
case 'data_update':
|
||||
const merge = params.merge !== false; // 默认合并
|
||||
result = await gameDataModule.updateData(db, wxContext.OPENID, params.data, merge);
|
||||
break;
|
||||
|
||||
case 'data_add':
|
||||
const fieldValidation = responseModule.validateRequiredParams(params, ['field', 'amount']);
|
||||
if (fieldValidation) return fieldValidation;
|
||||
result = await gameDataModule.addDataField(db, wxContext.OPENID, params.field, params.amount);
|
||||
break;
|
||||
|
||||
case 'data_spend':
|
||||
const spendValidation = responseModule.validateRequiredParams(params, ['field', 'amount']);
|
||||
if (spendValidation) return spendValidation;
|
||||
result = await gameDataModule.spendDataField(db, wxContext.OPENID, params.field, params.amount);
|
||||
break;
|
||||
const _ = db.command;
|
||||
|
||||
case 'data_reset':
|
||||
result = await gameDataModule.resetData(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
// ==================== 出战英雄 ====================
|
||||
case 'fight_heros_get':
|
||||
result = await fightHerosModule.getFightHeros(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
case 'fight_hero_set':
|
||||
const heroSetValidation = responseModule.validateRequiredParams(params, ['position', 'hero_id']);
|
||||
if (heroSetValidation) return heroSetValidation;
|
||||
result = await fightHerosModule.setFightHero(db, wxContext.OPENID, params.position, params.hero_id);
|
||||
break;
|
||||
|
||||
case 'fight_heros_update':
|
||||
const herosUpdateValidation = responseModule.validateRequiredParams(params, ['fight_heros']);
|
||||
if (herosUpdateValidation) return herosUpdateValidation;
|
||||
result = await fightHerosModule.updateFightHeros(db, wxContext.OPENID, params.fight_heros);
|
||||
break;
|
||||
|
||||
case 'fight_heros_active':
|
||||
result = await fightHerosModule.getActiveFightHeros(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
case 'fight_heros_swap':
|
||||
const swapValidation = responseModule.validateRequiredParams(params, ['position1', 'position2']);
|
||||
if (swapValidation) return swapValidation;
|
||||
result = await fightHerosModule.swapFightHeros(db, wxContext.OPENID, params.position1, params.position2);
|
||||
break;
|
||||
|
||||
case 'fight_heros_reset':
|
||||
result = await fightHerosModule.resetFightHeros(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
// ==================== 英雄管理 ====================
|
||||
case 'heros_get':
|
||||
result = await herosModule.getHeros(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
case 'hero_get':
|
||||
const heroGetValidation = responseModule.validateRequiredParams(params, ['hero_id']);
|
||||
if (heroGetValidation) return heroGetValidation;
|
||||
result = await herosModule.getHero(db, wxContext.OPENID, params.hero_id);
|
||||
break;
|
||||
|
||||
case 'hero_add':
|
||||
const heroAddValidation = responseModule.validateRequiredParams(params, ['hero_id']);
|
||||
if (heroAddValidation) return heroAddValidation;
|
||||
result = await herosModule.addHero(db, wxContext.OPENID, params.hero_id, params.hero_data);
|
||||
break;
|
||||
|
||||
case 'hero_update':
|
||||
const heroUpdateValidation = responseModule.validateRequiredParams(params, ['hero_id', 'update_data']);
|
||||
if (heroUpdateValidation) return heroUpdateValidation;
|
||||
result = await herosModule.updateHero(db, wxContext.OPENID, params.hero_id, params.update_data);
|
||||
break;
|
||||
|
||||
case 'hero_property_set':
|
||||
const propValidation = responseModule.validateRequiredParams(params, ['hero_id', 'property', 'value']);
|
||||
if (propValidation) return propValidation;
|
||||
result = await herosModule.setHeroProperty(db, wxContext.OPENID, params.hero_id, params.property, params.value);
|
||||
break;
|
||||
|
||||
case 'hero_levelup':
|
||||
const levelValidation = responseModule.validateRequiredParams(params, ['hero_id']);
|
||||
if (levelValidation) return levelValidation;
|
||||
result = await herosModule.levelUpHero(db, wxContext.OPENID, params.hero_id, params.levels);
|
||||
break;
|
||||
|
||||
case 'hero_delete':
|
||||
const deleteValidation = responseModule.validateRequiredParams(params, ['hero_id']);
|
||||
if (deleteValidation) return deleteValidation;
|
||||
result = await herosModule.deleteHero(db, wxContext.OPENID, params.hero_id);
|
||||
break;
|
||||
|
||||
case 'heros_owned':
|
||||
result = await herosModule.getOwnedHeroIds(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
// ==================== 库存管理 (通用接口) ====================
|
||||
case 'inventory_get':
|
||||
const invGetValidation = responseModule.validateRequiredParams(params, ['type']);
|
||||
if (invGetValidation) return invGetValidation;
|
||||
result = await inventoryModule.getInventory(db, wxContext.OPENID, params.type);
|
||||
break;
|
||||
|
||||
case 'inventory_item_get':
|
||||
const itemGetValidation = responseModule.validateRequiredParams(params, ['type', 'item_id']);
|
||||
if (itemGetValidation) return itemGetValidation;
|
||||
result = await inventoryModule.getInventoryItem(db, wxContext.OPENID, params.type, params.item_id);
|
||||
break;
|
||||
|
||||
case 'inventory_item_add':
|
||||
const itemAddValidation = responseModule.validateRequiredParams(params, ['type', 'item_id', 'count']);
|
||||
if (itemAddValidation) return itemAddValidation;
|
||||
result = await inventoryModule.addInventoryItem(db, wxContext.OPENID, params.type, params.item_id, params.count);
|
||||
break;
|
||||
|
||||
case 'inventory_item_consume':
|
||||
const itemConsumeValidation = responseModule.validateRequiredParams(params, ['type', 'item_id', 'count']);
|
||||
if (itemConsumeValidation) return itemConsumeValidation;
|
||||
result = await inventoryModule.consumeInventoryItem(db, wxContext.OPENID, params.type, params.item_id, params.count);
|
||||
break;
|
||||
|
||||
case 'inventory_item_set':
|
||||
const itemSetValidation = responseModule.validateRequiredParams(params, ['type', 'item_id', 'count']);
|
||||
if (itemSetValidation) return itemSetValidation;
|
||||
result = await inventoryModule.setInventoryItem(db, wxContext.OPENID, params.type, params.item_id, params.count);
|
||||
break;
|
||||
|
||||
case 'inventory_update':
|
||||
const invUpdateValidation = responseModule.validateRequiredParams(params, ['type', 'data']);
|
||||
if (invUpdateValidation) return invUpdateValidation;
|
||||
const invMerge = params.merge !== false;
|
||||
result = await inventoryModule.updateInventory(db, wxContext.OPENID, params.type, params.data, invMerge);
|
||||
break;
|
||||
|
||||
case 'inventory_reset':
|
||||
const invResetValidation = responseModule.validateRequiredParams(params, ['type']);
|
||||
if (invResetValidation) return invResetValidation;
|
||||
result = await inventoryModule.resetInventory(db, wxContext.OPENID, params.type);
|
||||
break;
|
||||
|
||||
case 'inventory_owned':
|
||||
const invOwnedValidation = responseModule.validateRequiredParams(params, ['type']);
|
||||
if (invOwnedValidation) return invOwnedValidation;
|
||||
result = await inventoryModule.getOwnedItems(db, wxContext.OPENID, params.type);
|
||||
break;
|
||||
|
||||
// ==================== 物品管理 (items) ====================
|
||||
case 'items_get':
|
||||
result = await itemsModule.getItems(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
case 'item_get':
|
||||
const itemIdValidation = responseModule.validateRequiredParams(params, ['item_id']);
|
||||
if (itemIdValidation) return itemIdValidation;
|
||||
result = await itemsModule.getItem(db, wxContext.OPENID, params.item_id);
|
||||
break;
|
||||
|
||||
case 'item_add':
|
||||
const addItemValidation = responseModule.validateRequiredParams(params, ['item_id', 'count']);
|
||||
if (addItemValidation) return addItemValidation;
|
||||
result = await itemsModule.addItem(db, wxContext.OPENID, params.item_id, params.count);
|
||||
break;
|
||||
|
||||
case 'item_consume':
|
||||
const consumeItemValidation = responseModule.validateRequiredParams(params, ['item_id', 'count']);
|
||||
if (consumeItemValidation) return consumeItemValidation;
|
||||
result = await itemsModule.consumeItem(db, wxContext.OPENID, params.item_id, params.count);
|
||||
break;
|
||||
|
||||
case 'item_set':
|
||||
const setItemValidation = responseModule.validateRequiredParams(params, ['item_id', 'count']);
|
||||
if (setItemValidation) return setItemValidation;
|
||||
result = await itemsModule.setItem(db, wxContext.OPENID, params.item_id, params.count);
|
||||
break;
|
||||
|
||||
case 'items_update':
|
||||
const updateItemsValidation = responseModule.validateRequiredParams(params, ['data']);
|
||||
if (updateItemsValidation) return updateItemsValidation;
|
||||
const itemsMerge = params.merge !== false;
|
||||
result = await itemsModule.updateItems(db, wxContext.OPENID, params.data, itemsMerge);
|
||||
break;
|
||||
|
||||
case 'items_reset':
|
||||
result = await itemsModule.resetItems(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
case 'items_owned':
|
||||
result = await itemsModule.getOwnedItems(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
// ==================== 天赋管理 (tals) ====================
|
||||
case 'tals_get':
|
||||
result = await talsModule.getTals(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
case 'tal_get':
|
||||
const talIdValidation = responseModule.validateRequiredParams(params, ['tal_id']);
|
||||
if (talIdValidation) return talIdValidation;
|
||||
result = await talsModule.getTal(db, wxContext.OPENID, params.tal_id);
|
||||
break;
|
||||
|
||||
case 'tal_add':
|
||||
const addTalValidation = responseModule.validateRequiredParams(params, ['tal_id', 'count']);
|
||||
if (addTalValidation) return addTalValidation;
|
||||
result = await talsModule.addTal(db, wxContext.OPENID, params.tal_id, params.count);
|
||||
break;
|
||||
|
||||
case 'tal_consume':
|
||||
const consumeTalValidation = responseModule.validateRequiredParams(params, ['tal_id', 'count']);
|
||||
if (consumeTalValidation) return consumeTalValidation;
|
||||
result = await talsModule.consumeTal(db, wxContext.OPENID, params.tal_id, params.count);
|
||||
break;
|
||||
|
||||
case 'tal_set':
|
||||
const setTalValidation = responseModule.validateRequiredParams(params, ['tal_id', 'count']);
|
||||
if (setTalValidation) return setTalValidation;
|
||||
result = await talsModule.setTal(db, wxContext.OPENID, params.tal_id, params.count);
|
||||
break;
|
||||
|
||||
case 'tals_update':
|
||||
const updateTalsValidation = responseModule.validateRequiredParams(params, ['data']);
|
||||
if (updateTalsValidation) return updateTalsValidation;
|
||||
const talsMerge = params.merge !== false;
|
||||
result = await talsModule.updateTals(db, wxContext.OPENID, params.data, talsMerge);
|
||||
break;
|
||||
|
||||
case 'tals_reset':
|
||||
result = await talsModule.resetTals(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
case 'tals_owned':
|
||||
result = await talsModule.getOwnedTals(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
// ==================== 装备管理 (equips) ====================
|
||||
case 'equips_get':
|
||||
result = await equipsModule.getEquips(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
case 'equip_get':
|
||||
const equipIdValidation = responseModule.validateRequiredParams(params, ['equip_id']);
|
||||
if (equipIdValidation) return equipIdValidation;
|
||||
result = await equipsModule.getEquip(db, wxContext.OPENID, params.equip_id);
|
||||
break;
|
||||
|
||||
case 'equip_add':
|
||||
const addEquipValidation = responseModule.validateRequiredParams(params, ['equip_id', 'count']);
|
||||
if (addEquipValidation) return addEquipValidation;
|
||||
result = await equipsModule.addEquip(db, wxContext.OPENID, params.equip_id, params.count);
|
||||
break;
|
||||
|
||||
case 'equip_consume':
|
||||
const consumeEquipValidation = responseModule.validateRequiredParams(params, ['equip_id', 'count']);
|
||||
if (consumeEquipValidation) return consumeEquipValidation;
|
||||
result = await equipsModule.consumeEquip(db, wxContext.OPENID, params.equip_id, params.count);
|
||||
break;
|
||||
|
||||
case 'equip_set':
|
||||
const setEquipValidation = responseModule.validateRequiredParams(params, ['equip_id', 'count']);
|
||||
if (setEquipValidation) return setEquipValidation;
|
||||
result = await equipsModule.setEquip(db, wxContext.OPENID, params.equip_id, params.count);
|
||||
break;
|
||||
|
||||
case 'equips_update':
|
||||
const updateEquipsValidation = responseModule.validateRequiredParams(params, ['data']);
|
||||
if (updateEquipsValidation) return updateEquipsValidation;
|
||||
const equipsMerge = params.merge !== false;
|
||||
result = await equipsModule.updateEquips(db, wxContext.OPENID, params.data, equipsMerge);
|
||||
break;
|
||||
|
||||
case 'equips_reset':
|
||||
result = await equipsModule.resetEquips(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
case 'equips_owned':
|
||||
result = await equipsModule.getOwnedEquips(db, wxContext.OPENID);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
const availableCommands = [
|
||||
'login', 'user_info', 'version', 'upgrade',
|
||||
'data_get', 'data_update', 'data_add', 'data_spend', 'data_set', 'data_reset',
|
||||
'fight_heros_get', 'fight_hero_set', 'fight_heros_update', 'fight_heros_active', 'fight_heros_swap', 'fight_heros_reset',
|
||||
'heros_get', 'hero_get', 'hero_add', 'hero_update', 'hero_property_set', 'hero_levelup', 'hero_delete', 'heros_owned',
|
||||
'inventory_get', 'inventory_item_get', 'inventory_item_add', 'inventory_item_consume', 'inventory_item_set', 'inventory_update', 'inventory_reset', 'inventory_owned',
|
||||
'items_get', 'item_get', 'item_add', 'item_consume', 'item_set', 'items_update', 'items_reset', 'items_owned',
|
||||
'tals_get', 'tal_get', 'tal_add', 'tal_consume', 'tal_set', 'tals_update', 'tals_reset', 'tals_owned',
|
||||
'equips_get', 'equip_get', 'equip_add', 'equip_consume', 'equip_set', 'equips_update', 'equips_reset', 'equips_owned',
|
||||
'load', 'save'
|
||||
];
|
||||
result = responseModule.unknownCommand(cmd, availableCommands);
|
||||
break;
|
||||
if (cmd === "login") {
|
||||
let user = await getOrCreaterUser(db, wxContext.OPENID);
|
||||
return {
|
||||
code: 200,
|
||||
data: user,
|
||||
};
|
||||
} else if (cmd === "save") {
|
||||
let data = event.data;
|
||||
let user = await getOrCreaterUser(db, wxContext.OPENID);
|
||||
let saveDataRes = await db.collection(user_db_name).doc(user._id).update({
|
||||
data: {
|
||||
game_data: _.set(data)
|
||||
}
|
||||
});
|
||||
|
||||
console.log("Save data:", saveDataRes, data);
|
||||
if (saveDataRes?.stats?.updated >= 1) {
|
||||
return {
|
||||
code: 200,
|
||||
data: saveDataRes
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
code: -1,
|
||||
msg: `Save fail, ${JSON.stringify(saveDataRes)}`
|
||||
};
|
||||
}
|
||||
|
||||
// 添加执行时间
|
||||
const executionTime = Date.now() - startTime;
|
||||
if (result && typeof result === 'object') {
|
||||
result.execution_time = executionTime;
|
||||
}
|
||||
|
||||
console.log(`[${cmd}] Response (${executionTime}ms):`, result.code, result.msg);
|
||||
return result;
|
||||
|
||||
} catch (error) {
|
||||
console.error("Cloud function error:", error);
|
||||
return responseModule.systemError("Cloud function execution failed", error);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
code: -2,
|
||||
msg: `Unknow cmd: ${event?.cmd}`,
|
||||
};
|
||||
};
|
||||
|
||||
async function getOrCreaterUser(db, openid) {
|
||||
try {
|
||||
let res = await db.collection(user_db_name).where({ _openid: openid }).get();
|
||||
let userData = null;
|
||||
if (res == null || res.data == null || res.data.length <= 0) {
|
||||
userData = {
|
||||
_openid: openid,
|
||||
regist_time: Date.now(),
|
||||
};
|
||||
let addResult = await db.collection(user_db_name).add({
|
||||
data: userData
|
||||
});
|
||||
userData._id = addResult._id;
|
||||
} else {
|
||||
userData = res.data[0];
|
||||
}
|
||||
return userData;
|
||||
} catch (err) {
|
||||
console.error(`Get or create user err`, err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user