金币经验掉落
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { oops } from "db://oops-framework/core/Oops";
|
import { oops } from "db://oops-framework/core/Oops";
|
||||||
import { WxCloudApi ,UserGameData} from "../wx_clound_client_api/WxCloudApi";
|
import { WxCloudApi ,UserGameData} from "../wx_clound_client_api/WxCloudApi";
|
||||||
import { smc } from "./SingletonModuleComp";
|
import { smc } from "./SingletonModuleComp";
|
||||||
|
import { GameData } from "../wx_clound_client_api/WxCloudApi";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 游戏数据同步管理器
|
* 游戏数据同步管理器
|
||||||
@@ -351,33 +352,6 @@ export class GameDataSyncManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置天赋点数量
|
|
||||||
* @param talId 天赋ID
|
|
||||||
* @param count 数量
|
|
||||||
* @returns 是否成功
|
|
||||||
*/
|
|
||||||
async setTalent(talId: number, count: number): Promise<boolean> {
|
|
||||||
try {
|
|
||||||
console.log(`[GameDataSyncManager]: 设置天赋点数量 ID:${talId}, 数量:${count}`);
|
|
||||||
|
|
||||||
const result = await WxCloudApi.setInventoryItem('tals', talId, count);
|
|
||||||
|
|
||||||
if (result.result.code === 200) {
|
|
||||||
// 远程修改成功,同步本地数据
|
|
||||||
smc.tals[talId] = count;
|
|
||||||
console.log(`[GameDataSyncManager]: 天赋点数量设置成功,本地数据已同步`);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
console.warn(`[GameDataSyncManager]: 天赋点数量设置失败: ${result.result.msg}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`[GameDataSyncManager]: 设置天赋点数量异常:`, error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增加装备
|
* 增加装备
|
||||||
* @param equipId 装备ID
|
* @param equipId 装备ID
|
||||||
@@ -432,34 +406,37 @@ export class GameDataSyncManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置装备数量
|
async addGameProperty(property: string, value: any): Promise<boolean> {
|
||||||
* @param equipId 装备ID
|
|
||||||
* @param count 数量
|
|
||||||
* @returns 是否成功
|
|
||||||
*/
|
|
||||||
async setEquipment(equipId: number, count: number): Promise<boolean> {
|
|
||||||
try {
|
try {
|
||||||
console.log(`[GameDataSyncManager]: 设置装备数量 ID:${equipId}, 数量:${count}`);
|
console.log(`[GameDataSyncManager]: 增加游戏数据 ${property} = ${value}`);
|
||||||
|
const result = await WxCloudApi.addGameDataField(property, value);
|
||||||
const result = await WxCloudApi.setInventoryItem('equips', equipId, count);
|
|
||||||
|
|
||||||
if (result.result.code === 200) {
|
if (result.result.code === 200) {
|
||||||
// 远程修改成功,同步本地数据
|
console.log(`[GameDataSyncManager]: 游戏数据增加成功`);
|
||||||
smc.equips[equipId] = count;
|
|
||||||
console.log(`[GameDataSyncManager]: 装备数量设置成功,本地数据已同步`);
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
console.warn(`[GameDataSyncManager]: 装备数量设置失败: ${result.result.msg}`);
|
console.warn(`[GameDataSyncManager]: 游戏数据增加失败: ${result.result.msg}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`[GameDataSyncManager]: 设置装备数量异常:`, error);
|
console.error(`[GameDataSyncManager]: 增加游戏数据异常:`, error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async spendGameProperty(property: string, value: any): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
console.log(`[GameDataSyncManager]: 消耗游戏数据 ${property} = ${value}`);
|
||||||
|
const result = await WxCloudApi.spendGameDataField(property, value);
|
||||||
|
if (result.result.code === 200) {
|
||||||
|
console.log(`[GameDataSyncManager]: 游戏数据消耗成功`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[GameDataSyncManager]: 消耗游戏数据异常:`, error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从云端加载所有游戏数据并同步到本地
|
* 从云端加载所有游戏数据并同步到本地
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Initialize } from "../initialize/Initialize";
|
|||||||
import { GameMap } from "../map/GameMap";
|
import { GameMap } from "../map/GameMap";
|
||||||
import { HeroUI, VmInfo } from "./config/Mission";
|
import { HeroUI, VmInfo } from "./config/Mission";
|
||||||
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||||
import { WxCloudApi } from "../wx_clound_client_api/WxCloudApi";
|
import { GameData, WxCloudApi } from "../wx_clound_client_api/WxCloudApi";
|
||||||
import { gameDataSyncManager } from "./GameDataSyncManager";
|
import { gameDataSyncManager } from "./GameDataSyncManager";
|
||||||
import { GameSet } from "./config/BoxSet";
|
import { GameSet } from "./config/BoxSet";
|
||||||
import { Test } from "./Test";
|
import { Test } from "./Test";
|
||||||
@@ -166,15 +166,61 @@ export class SingletonModuleComp extends ecs.Comp {
|
|||||||
* @param autoSave 是否自动保存 (默认true)
|
* @param autoSave 是否自动保存 (默认true)
|
||||||
* @returns 操作结果
|
* @returns 操作结果
|
||||||
*/
|
*/
|
||||||
async addGameProperty(property: string, value: any, autoSave: boolean = true): Promise<any> {
|
addExp(exp:number,autoSave:boolean=true){
|
||||||
const currentValue = this.data[property] || 0;
|
this.data.exp+=exp
|
||||||
const newValue = currentValue + value;
|
this.vmdata.data.exp+=exp
|
||||||
|
if(this.isWxClient()){
|
||||||
this.data[property] = newValue;
|
this.gameDataSyncManager.addGameProperty("exp",exp)
|
||||||
this.vmdata.data[property] = newValue;
|
}
|
||||||
|
}
|
||||||
console.log(`[SMC]: 增加游戏数据 ${property} = ${value}, 当前值: ${newValue}`);
|
addGold(gold:number,autoSave:boolean=true){
|
||||||
return newValue;
|
this.data.gold+=gold
|
||||||
|
this.vmdata.data.gold+=gold
|
||||||
|
if(this.isWxClient()){
|
||||||
|
this.gameDataSyncManager.addGameProperty("gold",gold)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addDiamond(diamond:number,autoSave:boolean=true){
|
||||||
|
this.data.diamond+=diamond
|
||||||
|
this.vmdata.data.diamond+=diamond
|
||||||
|
if(this.isWxClient()){
|
||||||
|
this.gameDataSyncManager.addGameProperty("diamond",diamond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addMission(mission:number,autoSave:boolean=true){
|
||||||
|
this.data.mission+=mission
|
||||||
|
this.vmdata.data.mission+=mission
|
||||||
|
if(this.isWxClient()){
|
||||||
|
this.gameDataSyncManager.addGameProperty("mission",mission)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spendMission(mission:number,autoSave:boolean=true){
|
||||||
|
this.data.mission-=mission
|
||||||
|
this.vmdata.data.mission-=mission
|
||||||
|
if(this.isWxClient()){
|
||||||
|
this.gameDataSyncManager.spendGameProperty("mission",mission)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spendExp(exp:number,autoSave:boolean=true){
|
||||||
|
this.data.exp-=exp
|
||||||
|
this.vmdata.data.exp-=exp
|
||||||
|
if(this.isWxClient()){
|
||||||
|
this.gameDataSyncManager.spendGameProperty("exp",exp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spendGold(gold:number,autoSave:boolean=true){
|
||||||
|
this.data.gold-=gold
|
||||||
|
this.vmdata.data.gold-=gold
|
||||||
|
if(this.isWxClient()){
|
||||||
|
this.gameDataSyncManager.spendGameProperty("gold",gold)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spendDiamond(diamond:number,autoSave:boolean=true){
|
||||||
|
this.data.diamond-=diamond
|
||||||
|
this.vmdata.data.diamond-=diamond
|
||||||
|
if(this.isWxClient()){
|
||||||
|
this.gameDataSyncManager.spendGameProperty("diamond",diamond)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -228,6 +274,7 @@ export class SingletonModuleComp extends ecs.Comp {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
addItem(item_uuid:number,count:number,autoSave:boolean=true){
|
addItem(item_uuid:number,count:number,autoSave:boolean=true){
|
||||||
if(this.isWxClient()){
|
if(this.isWxClient()){
|
||||||
this.gameDataSyncManager.addItem(item_uuid,count);
|
this.gameDataSyncManager.addItem(item_uuid,count);
|
||||||
|
|||||||
@@ -116,6 +116,93 @@ export const MonsterDropTable: { [monsterId: number]: [number, number, number, n
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 基础资源掉落配置表 - 以普通怪为基础值
|
||||||
|
export const BaseResourceDropConfig = {
|
||||||
|
// 经验值配置
|
||||||
|
exp: {
|
||||||
|
baseValue: 100, // 普通怪基础经验值
|
||||||
|
stageMultiplier: 1.15, // 关卡倍数 (降低增长)
|
||||||
|
randomRange: 0.2, // 随机范围 (±20%)
|
||||||
|
baseProbability: 1.0 // 基础掉落概率 (100%)
|
||||||
|
},
|
||||||
|
// 金币配置
|
||||||
|
gold: {
|
||||||
|
baseValue: 50, // 普通怪基础金币值
|
||||||
|
stageMultiplier: 1.12, // 关卡倍数 (降低增长)
|
||||||
|
randomRange: 0.25, // 随机范围 (±25%)
|
||||||
|
baseProbability: 0.7 // 基础掉落概率 (70%)
|
||||||
|
},
|
||||||
|
// 钻石配置
|
||||||
|
diamond: {
|
||||||
|
baseValue: 2, // 基础钻石值
|
||||||
|
stageMultiplier: 1.05, // 关卡倍数 (大幅降低增长)
|
||||||
|
randomRange: 0.2, // 随机范围 (±20%)
|
||||||
|
baseProbability: 0.0 // 基础掉落概率 (0%,需要品质加成)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 怪物品质加成配置表 - 使用加法权重
|
||||||
|
export const QualityBonusConfig = {
|
||||||
|
[QualitySet.GREEN]: {
|
||||||
|
// 绿色品质:基础值 + 加成
|
||||||
|
expBonus: 0, // 经验值加成
|
||||||
|
goldBonus: 0, // 金币加成
|
||||||
|
diamondBonus: 0, // 钻石加成
|
||||||
|
expProbabilityBonus: 0, // 经验掉落概率加成
|
||||||
|
goldProbabilityBonus: 0, // 金币掉落概率加成
|
||||||
|
diamondProbabilityBonus: 0 // 钻石掉落概率加成
|
||||||
|
},
|
||||||
|
[QualitySet.BLUE]: {
|
||||||
|
// 蓝色品质:基础值 + 加成
|
||||||
|
expBonus: 50, // 经验值 +50
|
||||||
|
goldBonus: 25, // 金币 +25
|
||||||
|
diamondBonus: 0, // 钻石加成 0
|
||||||
|
expProbabilityBonus: 0, // 经验掉落概率加成
|
||||||
|
goldProbabilityBonus: 0.1, // 金币掉落概率 +10%
|
||||||
|
diamondProbabilityBonus: 0.2 // 钻石掉落概率 +20%
|
||||||
|
},
|
||||||
|
[QualitySet.PURPLE]: {
|
||||||
|
// 紫色品质:基础值 + 加成
|
||||||
|
expBonus: 100, // 经验值 +100
|
||||||
|
goldBonus: 50, // 金币 +50
|
||||||
|
diamondBonus: 1, // 钻石 +1
|
||||||
|
expProbabilityBonus: 0, // 经验掉落概率加成
|
||||||
|
goldProbabilityBonus: 0.2, // 金币掉落概率 +20%
|
||||||
|
diamondProbabilityBonus: 0.1 // 钻石掉落概率 +10%(精英10%)
|
||||||
|
},
|
||||||
|
[QualitySet.ORANGE]: {
|
||||||
|
// 橙色品质:基础值 + 加成
|
||||||
|
expBonus: 200, // 经验值 +200
|
||||||
|
goldBonus: 100, // 金币 +100
|
||||||
|
diamondBonus: 3, // 钻石 +3
|
||||||
|
expProbabilityBonus: 0, // 经验掉落概率加成
|
||||||
|
goldProbabilityBonus: 0.3, // 金币掉落概率 +30%
|
||||||
|
diamondProbabilityBonus: 1.0 // 钻石掉落概率 +100%(BOSS必掉)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 关卡和buff加成配置表 - 使用加法权重
|
||||||
|
export const StageBuffBonusConfig = {
|
||||||
|
// 关卡加成配置
|
||||||
|
stage: {
|
||||||
|
expBonusPerStage: 5, // 每关经验值加成
|
||||||
|
goldBonusPerStage: 2, // 每关金币加成
|
||||||
|
diamondBonusPerStage: 0.1, // 每关钻石加成
|
||||||
|
expProbabilityBonusPerStage: 0, // 每关经验掉落概率加成
|
||||||
|
goldProbabilityBonusPerStage: 0, // 每关金币掉落概率加成
|
||||||
|
diamondProbabilityBonusPerStage: 0 // 每关钻石掉落概率加成
|
||||||
|
},
|
||||||
|
// buff数量加成配置
|
||||||
|
buff: {
|
||||||
|
expBonusPerBuff: 10, // 每个buff经验值加成
|
||||||
|
goldBonusPerBuff: 5, // 每个buff金币加成
|
||||||
|
diamondBonusPerBuff: 0.5, // 每个buff钻石加成
|
||||||
|
expProbabilityBonusPerBuff: 0, // 每个buff经验掉落概率加成
|
||||||
|
goldProbabilityBonusPerBuff: 0.01, // 每个buff金币掉落概率加成
|
||||||
|
diamondProbabilityBonusPerBuff: 0.005 // 每个buff钻石掉落概率加成
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 怪物掉落管理器
|
// 怪物掉落管理器
|
||||||
export class MonsterDropManager {
|
export class MonsterDropManager {
|
||||||
|
|
||||||
@@ -213,5 +300,68 @@ export class MonsterDropManager {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算怪物基础资源掉落(经验、金币、钻石)
|
||||||
|
* @param monsterQuality 怪物品质
|
||||||
|
* @param stageNumber 关卡数
|
||||||
|
* @param buffCount buff数量
|
||||||
|
* @returns 基础资源掉落结果
|
||||||
|
*/
|
||||||
|
static calculateBaseResourceDrops(monsterQuality: QualitySet, stageNumber: number, buffCount: number = 0): {exp: number, gold?: number, diamond?: number} {
|
||||||
|
const result: {exp: number, gold?: number, diamond?: number} = {exp: 0};
|
||||||
|
|
||||||
|
// 获取品质加成
|
||||||
|
const qualityBonus = QualityBonusConfig[monsterQuality];
|
||||||
|
|
||||||
|
// 计算经验值(必出)
|
||||||
|
const expConfig = BaseResourceDropConfig.exp;
|
||||||
|
const expValue = (expConfig.baseValue +
|
||||||
|
qualityBonus.expBonus +
|
||||||
|
StageBuffBonusConfig.stage.expBonusPerStage * stageNumber +
|
||||||
|
StageBuffBonusConfig.buff.expBonusPerBuff * buffCount) *
|
||||||
|
Math.pow(expConfig.stageMultiplier, stageNumber - 1);
|
||||||
|
|
||||||
|
// 添加随机范围
|
||||||
|
const expRandomFactor = 1 + (Math.random() - 0.5) * 2 * expConfig.randomRange;
|
||||||
|
result.exp = Math.floor(expValue * expRandomFactor);
|
||||||
|
|
||||||
|
// 金币与钻石独立判定,可同时掉落:
|
||||||
|
// 使用加法权重系统:基础值 + 品质加成 + 关卡加成 + buff加成 + 关卡增长
|
||||||
|
|
||||||
|
// 金币判定
|
||||||
|
const goldProbability = BaseResourceDropConfig.gold.baseProbability +
|
||||||
|
qualityBonus.goldProbabilityBonus +
|
||||||
|
StageBuffBonusConfig.stage.goldProbabilityBonusPerStage * stageNumber +
|
||||||
|
StageBuffBonusConfig.buff.goldProbabilityBonusPerBuff * buffCount;
|
||||||
|
if (Math.random() < goldProbability) {
|
||||||
|
const goldConfig = BaseResourceDropConfig.gold;
|
||||||
|
const goldValue = (goldConfig.baseValue +
|
||||||
|
qualityBonus.goldBonus +
|
||||||
|
StageBuffBonusConfig.stage.goldBonusPerStage * stageNumber +
|
||||||
|
StageBuffBonusConfig.buff.goldBonusPerBuff * buffCount) *
|
||||||
|
Math.pow(goldConfig.stageMultiplier, stageNumber - 1);
|
||||||
|
const goldRandomFactor = 1 + (Math.random() - 0.5) * 2 * goldConfig.randomRange;
|
||||||
|
result.gold = Math.floor(goldValue * goldRandomFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 钻石判定
|
||||||
|
const diamondProbability = BaseResourceDropConfig.diamond.baseProbability +
|
||||||
|
qualityBonus.diamondProbabilityBonus +
|
||||||
|
StageBuffBonusConfig.stage.diamondProbabilityBonusPerStage * stageNumber +
|
||||||
|
StageBuffBonusConfig.buff.diamondProbabilityBonusPerBuff * buffCount;
|
||||||
|
if (Math.random() < diamondProbability) {
|
||||||
|
const diamondConfig = BaseResourceDropConfig.diamond;
|
||||||
|
const diamondValue = (diamondConfig.baseValue +
|
||||||
|
qualityBonus.diamondBonus +
|
||||||
|
StageBuffBonusConfig.stage.diamondBonusPerStage * stageNumber +
|
||||||
|
StageBuffBonusConfig.buff.diamondBonusPerBuff * buffCount) *
|
||||||
|
Math.pow(diamondConfig.stageMultiplier, stageNumber - 1);
|
||||||
|
const diamondRandomFactor = 1 + (Math.random() - 0.5) * 2 * diamondConfig.randomRange;
|
||||||
|
result.diamond = Math.floor(diamondValue * diamondRandomFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { FightSet, getExpDrops, getStoneDrops, TooltipTypes } from "../common/co
|
|||||||
import { RandomManager } from "db://oops-framework/core/common/random/RandomManager";
|
import { RandomManager } from "db://oops-framework/core/common/random/RandomManager";
|
||||||
import { EnhancementType } from "../common/config/LevelUp";
|
import { EnhancementType } from "../common/config/LevelUp";
|
||||||
import { MonsterDropManager } from "../common/config/Items";
|
import { MonsterDropManager } from "../common/config/Items";
|
||||||
|
import { HeroInfo } from "../common/config/heroSet";
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
|
|
||||||
@@ -255,10 +256,7 @@ export class HeroViewComp extends CCComp {
|
|||||||
this.is_count_dead=true
|
this.is_count_dead=true
|
||||||
if(this.fac==FacSet.MON){
|
if(this.fac==FacSet.MON){
|
||||||
this.scheduleOnce(()=>{
|
this.scheduleOnce(()=>{
|
||||||
let drop_item=this.do_drop()
|
this.do_drop()
|
||||||
if(drop_item.length>0){
|
|
||||||
oops.message.dispatchEvent(GameEvent.MonDead,{mon_uuid:this.hero_uuid,drops:drop_item})
|
|
||||||
}
|
|
||||||
},0.1)
|
},0.1)
|
||||||
}
|
}
|
||||||
if(this.fac==FacSet.HERO){
|
if(this.fac==FacSet.HERO){
|
||||||
@@ -276,8 +274,24 @@ export class HeroViewComp extends CCComp {
|
|||||||
}
|
}
|
||||||
do_drop(){
|
do_drop(){
|
||||||
let drop_item=MonsterDropManager.calculateMonsterDrops(this.hero_uuid,smc.data.mission,1)
|
let drop_item=MonsterDropManager.calculateMonsterDrops(this.hero_uuid,smc.data.mission,1)
|
||||||
console.log("[HeroViewComp]:do_drop",this.hero_uuid,drop_item)
|
let {exp,gold,diamond}=MonsterDropManager.calculateBaseResourceDrops(HeroInfo[this.hero_uuid].quality,smc.data.mission,this.BUFFS.length)
|
||||||
return drop_item
|
oops.message.dispatchEvent(GameEvent.MonDead,{mon_uuid:this.hero_uuid,drops:drop_item,game_data:{exp:exp, gold:gold, diamond:diamond}})
|
||||||
|
if(drop_item.length>0){
|
||||||
|
for(let i=0;i<drop_item.length;i++){
|
||||||
|
let d_item=drop_item[i]
|
||||||
|
smc.addItem(d_item.item_uuid,d_item.count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(exp>0){
|
||||||
|
smc.addExp(exp)
|
||||||
|
}
|
||||||
|
if(gold>0){
|
||||||
|
smc.addGold(gold)
|
||||||
|
}
|
||||||
|
if(diamond>0){
|
||||||
|
smc.addDiamond(diamond)
|
||||||
|
}
|
||||||
|
console.log("[HeroViewComp]:do_drop",this.hero_uuid,drop_item,exp,gold,diamond)
|
||||||
}
|
}
|
||||||
add_debuff(type:number,deV:number,deC:number,deR:number){
|
add_debuff(type:number,deV:number,deC:number,deR:number){
|
||||||
let n_deR=deR-this.Attrs[BuffAttr.DEBUFF_DOWN]
|
let n_deR=deR-this.Attrs[BuffAttr.DEBUFF_DOWN]
|
||||||
|
|||||||
@@ -65,8 +65,8 @@ export class HInfoComp extends Component {
|
|||||||
smc.spendGameProperty({exp:experience,gold:gold},false)
|
smc.spendGameProperty({exp:experience,gold:gold},false)
|
||||||
let result=smc.levelUpHero(this.h_uuid,experience,gold)
|
let result=smc.levelUpHero(this.h_uuid,experience,gold)
|
||||||
if(!result){
|
if(!result){
|
||||||
smc.addGameProperty("exp",experience,false)
|
smc.addExp(experience,false)
|
||||||
smc.addGameProperty("gold",gold,false)
|
smc.addGold(gold,false)
|
||||||
oops.gui.toast("网络出错了,升级失败,请重试")
|
oops.gui.toast("网络出错了,升级失败,请重试")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ export class MissionComp extends CCComp {
|
|||||||
if(d_item.item_uuid==hitem.item_uuid){
|
if(d_item.item_uuid==hitem.item_uuid){
|
||||||
hitem.addItemCount(d_item.count)
|
hitem.addItemCount(d_item.count)
|
||||||
drop_item.splice(j,1)
|
drop_item.splice(j,1)
|
||||||
smc.addItem(d_item.item_uuid,d_item.count)
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,7 +88,6 @@ export class MissionComp extends CCComp {
|
|||||||
const node = instantiate(prefab) as unknown as Node;
|
const node = instantiate(prefab) as unknown as Node;
|
||||||
node.parent=parent
|
node.parent=parent
|
||||||
node.getComponent(ItemComp)!.update_data(d_item.item_uuid,d_item.count)
|
node.getComponent(ItemComp)!.update_data(d_item.item_uuid,d_item.count)
|
||||||
smc.addItem(d_item.item_uuid,d_item.count)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +105,7 @@ export class MissionComp extends CCComp {
|
|||||||
oops.message.dispatchEvent(GameEvent.NewWave)
|
oops.message.dispatchEvent(GameEvent.NewWave)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
smc.addGameProperty("mission",1)
|
smc.addMission(1)
|
||||||
oops.message.dispatchEvent(GameEvent.FightEnd,{victory:true})
|
oops.message.dispatchEvent(GameEvent.FightEnd,{victory:true})
|
||||||
oops.gui.open(UIID.Victory,{victory:true,rewards:this.rewards})
|
oops.gui.open(UIID.Victory,{victory:true,rewards:this.rewards})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,14 +36,6 @@ export type GameData = {
|
|||||||
diamond: number,
|
diamond: number,
|
||||||
meat: number,
|
meat: number,
|
||||||
exp: number,
|
exp: number,
|
||||||
ghstone: number, // 绿色英雄石
|
|
||||||
bhstone: number, // 蓝色英雄石
|
|
||||||
phlestone: number, // 紫色英雄石
|
|
||||||
rhstone: number, // 红色英雄石
|
|
||||||
herocard: number, // 英雄卡
|
|
||||||
ckey: number, // 铜钥匙
|
|
||||||
skey: number, // 银钥匙
|
|
||||||
gkey: number // 金钥匙
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 出战英雄类型
|
// 出战英雄类型
|
||||||
@@ -209,7 +201,7 @@ export class WxCloudApi{
|
|||||||
* @param amount 增加的数量
|
* @param amount 增加的数量
|
||||||
* @return Promise<CloudCallFunctionResult<CloudReturnType<{field: string, old_value: number, new_value: number, change: number}>>>
|
* @return Promise<CloudCallFunctionResult<CloudReturnType<{field: string, old_value: number, new_value: number, change: number}>>>
|
||||||
*/
|
*/
|
||||||
public static async addGameDataField(field: keyof GameData, amount: number): Promise<CloudCallFunctionResult<CloudReturnType<{
|
public static async addGameDataField(field:string, amount: number): Promise<CloudCallFunctionResult<CloudReturnType<{
|
||||||
field: string,
|
field: string,
|
||||||
old_value: number,
|
old_value: number,
|
||||||
new_value: number,
|
new_value: number,
|
||||||
@@ -232,7 +224,7 @@ export class WxCloudApi{
|
|||||||
* @param amount 消耗的数量
|
* @param amount 消耗的数量
|
||||||
* @return Promise<CloudCallFunctionResult<CloudReturnType<{field: string, old_value: number, new_value: number, change: number}>>>
|
* @return Promise<CloudCallFunctionResult<CloudReturnType<{field: string, old_value: number, new_value: number, change: number}>>>
|
||||||
*/
|
*/
|
||||||
public static async spendGameDataField(field: keyof GameData, amount: number): Promise<CloudCallFunctionResult<CloudReturnType<{
|
public static async spendGameDataField(field:string, amount: number): Promise<CloudCallFunctionResult<CloudReturnType<{
|
||||||
field: string,
|
field: string,
|
||||||
old_value: number,
|
old_value: number,
|
||||||
new_value: number,
|
new_value: number,
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ const gameDataModule = require('./modules/gameData');
|
|||||||
const fightHerosModule = require('./modules/fightHeros');
|
const fightHerosModule = require('./modules/fightHeros');
|
||||||
const herosModule = require('./modules/heros');
|
const herosModule = require('./modules/heros');
|
||||||
const inventoryModule = require('./modules/inventory');
|
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 responseModule = require('./modules/response');
|
||||||
|
|
||||||
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }); // 使用当前云环境
|
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }); // 使用当前云环境
|
||||||
@@ -73,12 +76,6 @@ exports.main = async (event, context) => {
|
|||||||
result = await gameDataModule.spendDataField(db, wxContext.OPENID, params.field, params.amount);
|
result = await gameDataModule.spendDataField(db, wxContext.OPENID, params.field, params.amount);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'data_set':
|
|
||||||
const setValidation = responseModule.validateRequiredParams(params, ['field', 'value']);
|
|
||||||
if (setValidation) return setValidation;
|
|
||||||
result = await gameDataModule.setDataField(db, wxContext.OPENID, params.field, params.value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'data_reset':
|
case 'data_reset':
|
||||||
result = await gameDataModule.resetData(db, wxContext.OPENID);
|
result = await gameDataModule.resetData(db, wxContext.OPENID);
|
||||||
break;
|
break;
|
||||||
@@ -159,7 +156,7 @@ exports.main = async (event, context) => {
|
|||||||
result = await herosModule.getOwnedHeroIds(db, wxContext.OPENID);
|
result = await herosModule.getOwnedHeroIds(db, wxContext.OPENID);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ==================== 库存管理 (items, tals, equips) ====================
|
// ==================== 库存管理 (通用接口) ====================
|
||||||
case 'inventory_get':
|
case 'inventory_get':
|
||||||
const invGetValidation = responseModule.validateRequiredParams(params, ['type']);
|
const invGetValidation = responseModule.validateRequiredParams(params, ['type']);
|
||||||
if (invGetValidation) return invGetValidation;
|
if (invGetValidation) return invGetValidation;
|
||||||
@@ -209,40 +206,139 @@ exports.main = async (event, context) => {
|
|||||||
result = await inventoryModule.getOwnedItems(db, wxContext.OPENID, params.type);
|
result = await inventoryModule.getOwnedItems(db, wxContext.OPENID, params.type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ==================== 兼容旧接口 ====================
|
// ==================== 物品管理 (items) ====================
|
||||||
case 'load':
|
case 'items_get':
|
||||||
result = await authModule.login(db, wxContext);
|
result = await itemsModule.getItems(db, wxContext.OPENID);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'save':
|
case 'item_get':
|
||||||
// 兼容旧的保存接口
|
const itemIdValidation = responseModule.validateRequiredParams(params, ['item_id']);
|
||||||
if (params.data) {
|
if (itemIdValidation) return itemIdValidation;
|
||||||
const tasks = [];
|
result = await itemsModule.getItem(db, wxContext.OPENID, params.item_id);
|
||||||
if (params.data.data) tasks.push(gameDataModule.updateData(db, wxContext.OPENID, params.data.data));
|
|
||||||
if (params.data.fight_heros) tasks.push(fightHerosModule.updateFightHeros(db, wxContext.OPENID, params.data.fight_heros));
|
|
||||||
if (params.data.heros) {
|
|
||||||
// 批量更新英雄
|
|
||||||
for (const heroId in params.data.heros) {
|
|
||||||
tasks.push(herosModule.updateHero(db, wxContext.OPENID, parseInt(heroId), params.data.heros[heroId]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (params.data.items) tasks.push(inventoryModule.updateInventory(db, wxContext.OPENID, 'items', params.data.items));
|
|
||||||
if (params.data.tals) tasks.push(inventoryModule.updateInventory(db, wxContext.OPENID, 'tals', params.data.tals));
|
|
||||||
if (params.data.equips) tasks.push(inventoryModule.updateInventory(db, wxContext.OPENID, 'equips', params.data.equips));
|
|
||||||
|
|
||||||
const results = await Promise.all(tasks);
|
|
||||||
const hasError = results.some(r => r.code !== 200);
|
|
||||||
|
|
||||||
if (hasError) {
|
|
||||||
result = responseModule.error(-1, "Partial save failed", { results });
|
|
||||||
} else {
|
|
||||||
result = responseModule.success({ results }, "All data saved successfully");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result = responseModule.badRequest("No data to save");
|
|
||||||
}
|
|
||||||
break;
|
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:
|
default:
|
||||||
const availableCommands = [
|
const availableCommands = [
|
||||||
'login', 'user_info', 'version', 'upgrade',
|
'login', 'user_info', 'version', 'upgrade',
|
||||||
@@ -250,6 +346,9 @@ exports.main = async (event, context) => {
|
|||||||
'fight_heros_get', 'fight_hero_set', 'fight_heros_update', 'fight_heros_active', 'fight_heros_swap', 'fight_heros_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',
|
'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',
|
'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'
|
'load', 'save'
|
||||||
];
|
];
|
||||||
result = responseModule.unknownCommand(cmd, availableCommands);
|
result = responseModule.unknownCommand(cmd, availableCommands);
|
||||||
|
|||||||
@@ -0,0 +1,421 @@
|
|||||||
|
// 装备库存操作模块 (equips)
|
||||||
|
const { getOrCreaterUser } = require('./auth');
|
||||||
|
|
||||||
|
const user_db_name = "cocos_users";
|
||||||
|
const DATA_TYPE = 'equips';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取装备库存数据
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function getEquips(db, openid) {
|
||||||
|
try {
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: user[DATA_TYPE],
|
||||||
|
msg: `${DATA_TYPE}获取成功`
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`获取${DATA_TYPE}错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `获取${DATA_TYPE}错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个装备数据
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {number} equipId 装备ID
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function getEquip(db, openid, equipId) {
|
||||||
|
try {
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const equipCount = user[DATA_TYPE][equipId];
|
||||||
|
if (equipCount === undefined) {
|
||||||
|
return {
|
||||||
|
code: -6,
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${equipId} 未找到`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
item_id: equipId,
|
||||||
|
count: equipCount
|
||||||
|
},
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${equipId} 获取成功`
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`获取${DATA_TYPE}物品错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `获取${DATA_TYPE}物品错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加装备
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {number} equipId 装备ID
|
||||||
|
* @param {number} count 添加数量
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function addEquip(db, openid, equipId, count) {
|
||||||
|
try {
|
||||||
|
const _ = db.command;
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof count !== 'number' || count < 0) {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: "数量必须是非负数"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentCount = user[DATA_TYPE][equipId] || 0;
|
||||||
|
const newCount = currentCount + count;
|
||||||
|
|
||||||
|
let updateRes = await db.collection(user_db_name).doc(user._id).update({
|
||||||
|
data: {
|
||||||
|
[`${DATA_TYPE}.${equipId}`]: _.set(newCount),
|
||||||
|
last_save_time: _.set(Date.now())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updateRes?.stats?.updated >= 1) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
item_id: equipId,
|
||||||
|
old_count: currentCount,
|
||||||
|
new_count: newCount,
|
||||||
|
added: count
|
||||||
|
},
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${equipId} 添加成功`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
msg: `添加 ${DATA_TYPE.slice(0, -1)} 失败`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`添加${DATA_TYPE}物品错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `添加${DATA_TYPE}物品错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消耗装备
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {number} equipId 装备ID
|
||||||
|
* @param {number} count 消耗数量
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function consumeEquip(db, openid, equipId, count) {
|
||||||
|
try {
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof count !== 'number' || count < 0) {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: "数量必须是非负数"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentCount = user[DATA_TYPE][equipId] || 0;
|
||||||
|
if (currentCount < count) {
|
||||||
|
return {
|
||||||
|
code: -6,
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${equipId}不足, 当前: ${currentCount}, 需要: ${count}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return await addEquip(db, openid, equipId, -count);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`消耗${DATA_TYPE}物品错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `消耗${DATA_TYPE}物品错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置装备数量
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {number} equipId 装备ID
|
||||||
|
* @param {number} count 新的数量
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function setEquip(db, openid, equipId, count) {
|
||||||
|
try {
|
||||||
|
const _ = db.command;
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof count !== 'number' || count < 0) {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: "数量必须是非负数"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldCount = user[DATA_TYPE][equipId] || 0;
|
||||||
|
|
||||||
|
let updateRes = await db.collection(user_db_name).doc(user._id).update({
|
||||||
|
data: {
|
||||||
|
[`${DATA_TYPE}.${equipId}`]: _.set(count),
|
||||||
|
last_save_time: _.set(Date.now())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updateRes?.stats?.updated >= 1) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
item_id: equipId,
|
||||||
|
old_count: oldCount,
|
||||||
|
new_count: count
|
||||||
|
},
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${equipId} 设置成功`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
msg: `设置 ${DATA_TYPE.slice(0, -1)} 失败`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`设置${DATA_TYPE}物品错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `设置${DATA_TYPE}物品错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量更新装备库存
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {Object} updateData 更新数据对象
|
||||||
|
* @param {boolean} merge 是否合并更新(默认true)
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function updateEquips(db, openid, updateData, merge = true) {
|
||||||
|
try {
|
||||||
|
const _ = db.command;
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证更新数据
|
||||||
|
if (!updateData || typeof updateData !== 'object') {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: "无效的更新数据格式"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证所有值都是非负数
|
||||||
|
for (const equipId in updateData) {
|
||||||
|
const count = updateData[equipId];
|
||||||
|
if (typeof count !== 'number' || count < 0) {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: `装备 ${equipId} 的数量无效: ${count}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let newData;
|
||||||
|
if (merge) {
|
||||||
|
// 合并更新
|
||||||
|
newData = { ...user[DATA_TYPE], ...updateData };
|
||||||
|
} else {
|
||||||
|
// 完全替换
|
||||||
|
newData = updateData;
|
||||||
|
}
|
||||||
|
|
||||||
|
let updateRes = await db.collection(user_db_name).doc(user._id).update({
|
||||||
|
data: {
|
||||||
|
[DATA_TYPE]: _.set(newData),
|
||||||
|
last_save_time: _.set(Date.now())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updateRes?.stats?.updated >= 1) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: newData,
|
||||||
|
msg: `${DATA_TYPE} 更新成功`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
msg: `更新 ${DATA_TYPE} 失败`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`更新${DATA_TYPE}错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `更新${DATA_TYPE}错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置装备库存数据
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function resetEquips(db, openid) {
|
||||||
|
try {
|
||||||
|
const _ = db.command;
|
||||||
|
const { getNewUserInitData } = require('../user_init_data');
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultData = getNewUserInitData();
|
||||||
|
|
||||||
|
let resetRes = await db.collection(user_db_name).doc(user._id).update({
|
||||||
|
data: {
|
||||||
|
[DATA_TYPE]: _.set(defaultData[DATA_TYPE]),
|
||||||
|
last_save_time: _.set(Date.now()),
|
||||||
|
reset_time: _.set(Date.now())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (resetRes?.stats?.updated >= 1) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: defaultData[DATA_TYPE],
|
||||||
|
msg: `${DATA_TYPE} 重置成功`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
msg: `重置 ${DATA_TYPE} 失败`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`重置${DATA_TYPE}错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `重置${DATA_TYPE}错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取拥有的装备列表(数量大于0的)
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function getOwnedEquips(db, openid) {
|
||||||
|
try {
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const ownedEquips = [];
|
||||||
|
for (const equipId in user[DATA_TYPE]) {
|
||||||
|
const count = user[DATA_TYPE][equipId];
|
||||||
|
if (count > 0) {
|
||||||
|
ownedEquips.push({
|
||||||
|
item_id: parseInt(equipId),
|
||||||
|
count: count
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
owned_items: ownedEquips,
|
||||||
|
total_types: ownedEquips.length
|
||||||
|
},
|
||||||
|
msg: `拥有的${DATA_TYPE}获取成功`
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`获取拥有的${DATA_TYPE}错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `获取拥有的${DATA_TYPE}错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getEquips,
|
||||||
|
getEquip,
|
||||||
|
addEquip,
|
||||||
|
consumeEquip,
|
||||||
|
setEquip,
|
||||||
|
updateEquips,
|
||||||
|
resetEquips,
|
||||||
|
getOwnedEquips
|
||||||
|
};
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
// 通用库存操作模块 (items, tals, equips)
|
// 通用库存操作模块 (items, tals, equips)
|
||||||
const { getOrCreaterUser } = require('./auth');
|
// 现在作为统一接口,调用各个独立模块
|
||||||
|
const itemsModule = require('./items');
|
||||||
const user_db_name = "cocos_users";
|
const talsModule = require('./tals');
|
||||||
|
const equipsModule = require('./equips');
|
||||||
|
|
||||||
// 支持的数据类型
|
// 支持的数据类型
|
||||||
const SUPPORTED_TYPES = ['items', 'tals', 'equips'];
|
const SUPPORTED_TYPES = ['items', 'tals', 'equips'];
|
||||||
@@ -15,6 +16,24 @@ function validateDataType(dataType) {
|
|||||||
return SUPPORTED_TYPES.includes(dataType);
|
return SUPPORTED_TYPES.includes(dataType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据数据类型获取对应的模块
|
||||||
|
* @param {string} dataType 数据类型
|
||||||
|
* @returns {Object} 对应的模块
|
||||||
|
*/
|
||||||
|
function getModuleByType(dataType) {
|
||||||
|
switch(dataType) {
|
||||||
|
case 'items':
|
||||||
|
return itemsModule;
|
||||||
|
case 'tals':
|
||||||
|
return talsModule;
|
||||||
|
case 'equips':
|
||||||
|
return equipsModule;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取库存数据
|
* 获取库存数据
|
||||||
* @param {Object} db 数据库实例
|
* @param {Object} db 数据库实例
|
||||||
@@ -23,33 +42,26 @@ function validateDataType(dataType) {
|
|||||||
* @returns {Object} 操作结果
|
* @returns {Object} 操作结果
|
||||||
*/
|
*/
|
||||||
async function getInventory(db, openid, dataType) {
|
async function getInventory(db, openid, dataType) {
|
||||||
try {
|
if (!validateDataType(dataType)) {
|
||||||
if (!validateDataType(dataType)) {
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: `无效的数据类型: ${dataType}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const module = getModuleByType(dataType);
|
||||||
|
switch(dataType) {
|
||||||
|
case 'items':
|
||||||
|
return await module.getItems(db, openid);
|
||||||
|
case 'tals':
|
||||||
|
return await module.getTals(db, openid);
|
||||||
|
case 'equips':
|
||||||
|
return await module.getEquips(db, openid);
|
||||||
|
default:
|
||||||
return {
|
return {
|
||||||
code: -3,
|
code: -3,
|
||||||
msg: `无效的数据类型: ${dataType}`
|
msg: `无效的数据类型: ${dataType}`
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
let user = await getOrCreaterUser(db, openid);
|
|
||||||
if (!user) {
|
|
||||||
return {
|
|
||||||
code: -4,
|
|
||||||
msg: "未找到用户"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
code: 200,
|
|
||||||
data: user[dataType],
|
|
||||||
msg: `${dataType}获取成功`
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`获取${dataType}错误:`, error);
|
|
||||||
return {
|
|
||||||
code: -5,
|
|
||||||
msg: `获取${dataType}错误: ${error.message}`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,44 +74,26 @@ async function getInventory(db, openid, dataType) {
|
|||||||
* @returns {Object} 操作结果
|
* @returns {Object} 操作结果
|
||||||
*/
|
*/
|
||||||
async function getInventoryItem(db, openid, dataType, itemId) {
|
async function getInventoryItem(db, openid, dataType, itemId) {
|
||||||
try {
|
if (!validateDataType(dataType)) {
|
||||||
if (!validateDataType(dataType)) {
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: `无效的数据类型: ${dataType}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const module = getModuleByType(dataType);
|
||||||
|
switch(dataType) {
|
||||||
|
case 'items':
|
||||||
|
return await module.getItem(db, openid, itemId);
|
||||||
|
case 'tals':
|
||||||
|
return await module.getTal(db, openid, itemId);
|
||||||
|
case 'equips':
|
||||||
|
return await module.getEquip(db, openid, itemId);
|
||||||
|
default:
|
||||||
return {
|
return {
|
||||||
code: -3,
|
code: -3,
|
||||||
msg: `无效的数据类型: ${dataType}`
|
msg: `无效的数据类型: ${dataType}`
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
let user = await getOrCreaterUser(db, openid);
|
|
||||||
if (!user) {
|
|
||||||
return {
|
|
||||||
code: -4,
|
|
||||||
msg: "未找到用户"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const itemCount = user[dataType][itemId];
|
|
||||||
if (itemCount === undefined) {
|
|
||||||
return {
|
|
||||||
code: -6,
|
|
||||||
msg: `${dataType.slice(0, -1)} ${itemId} 未找到`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
code: 200,
|
|
||||||
data: {
|
|
||||||
item_id: itemId,
|
|
||||||
count: itemCount
|
|
||||||
},
|
|
||||||
msg: `${dataType.slice(0, -1)} ${itemId} 获取成功`
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`获取${dataType}物品错误:`, error);
|
|
||||||
return {
|
|
||||||
code: -5,
|
|
||||||
msg: `获取${dataType}物品错误: ${error.message}`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,63 +107,26 @@ async function getInventoryItem(db, openid, dataType, itemId) {
|
|||||||
* @returns {Object} 操作结果
|
* @returns {Object} 操作结果
|
||||||
*/
|
*/
|
||||||
async function addInventoryItem(db, openid, dataType, itemId, count) {
|
async function addInventoryItem(db, openid, dataType, itemId, count) {
|
||||||
try {
|
if (!validateDataType(dataType)) {
|
||||||
if (!validateDataType(dataType)) {
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: `无效的数据类型: ${dataType}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const module = getModuleByType(dataType);
|
||||||
|
switch(dataType) {
|
||||||
|
case 'items':
|
||||||
|
return await module.addItem(db, openid, itemId, count);
|
||||||
|
case 'tals':
|
||||||
|
return await module.addTal(db, openid, itemId, count);
|
||||||
|
case 'equips':
|
||||||
|
return await module.addEquip(db, openid, itemId, count);
|
||||||
|
default:
|
||||||
return {
|
return {
|
||||||
code: -3,
|
code: -3,
|
||||||
msg: `无效的数据类型: ${dataType}`
|
msg: `无效的数据类型: ${dataType}`
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
const _ = db.command;
|
|
||||||
let user = await getOrCreaterUser(db, openid);
|
|
||||||
if (!user) {
|
|
||||||
return {
|
|
||||||
code: -4,
|
|
||||||
msg: "未找到用户"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof count !== 'number' || count < 0) {
|
|
||||||
return {
|
|
||||||
code: -3,
|
|
||||||
msg: "数量必须是非负数"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentCount = user[dataType][itemId] || 0;
|
|
||||||
const newCount = currentCount + count;
|
|
||||||
|
|
||||||
let updateRes = await db.collection(user_db_name).doc(user._id).update({
|
|
||||||
data: {
|
|
||||||
[`${dataType}.${itemId}`]: _.set(newCount),
|
|
||||||
last_save_time: _.set(Date.now())
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (updateRes?.stats?.updated >= 1) {
|
|
||||||
return {
|
|
||||||
code: 200,
|
|
||||||
data: {
|
|
||||||
item_id: itemId,
|
|
||||||
old_count: currentCount,
|
|
||||||
new_count: newCount,
|
|
||||||
added: count
|
|
||||||
},
|
|
||||||
msg: `${dataType.slice(0, -1)} ${itemId} 添加成功`
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
code: -1,
|
|
||||||
msg: `添加 ${dataType.slice(0, -1)} 失败`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`添加${dataType}物品错误:`, error);
|
|
||||||
return {
|
|
||||||
code: -5,
|
|
||||||
msg: `添加${dataType}物品错误: ${error.message}`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,44 +140,26 @@ async function addInventoryItem(db, openid, dataType, itemId, count) {
|
|||||||
* @returns {Object} 操作结果
|
* @returns {Object} 操作结果
|
||||||
*/
|
*/
|
||||||
async function consumeInventoryItem(db, openid, dataType, itemId, count) {
|
async function consumeInventoryItem(db, openid, dataType, itemId, count) {
|
||||||
try {
|
if (!validateDataType(dataType)) {
|
||||||
if (!validateDataType(dataType)) {
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: `无效的数据类型: ${dataType}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const module = getModuleByType(dataType);
|
||||||
|
switch(dataType) {
|
||||||
|
case 'items':
|
||||||
|
return await module.consumeItem(db, openid, itemId, count);
|
||||||
|
case 'tals':
|
||||||
|
return await module.consumeTal(db, openid, itemId, count);
|
||||||
|
case 'equips':
|
||||||
|
return await module.consumeEquip(db, openid, itemId, count);
|
||||||
|
default:
|
||||||
return {
|
return {
|
||||||
code: -3,
|
code: -3,
|
||||||
msg: `无效的数据类型: ${dataType}`
|
msg: `无效的数据类型: ${dataType}`
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
let user = await getOrCreaterUser(db, openid);
|
|
||||||
if (!user) {
|
|
||||||
return {
|
|
||||||
code: -4,
|
|
||||||
msg: "未找到用户"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof count !== 'number' || count < 0) {
|
|
||||||
return {
|
|
||||||
code: -3,
|
|
||||||
msg: "数量必须是非负数"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentCount = user[dataType][itemId] || 0;
|
|
||||||
if (currentCount < count) {
|
|
||||||
return {
|
|
||||||
code: -6,
|
|
||||||
msg: `${dataType.slice(0, -1)} ${itemId}不足, 当前: ${currentCount}, 需要: ${count}`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return await addInventoryItem(db, openid, dataType, itemId, -count);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`消耗${dataType}物品错误:`, error);
|
|
||||||
return {
|
|
||||||
code: -5,
|
|
||||||
msg: `消耗${dataType}物品错误: ${error.message}`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,61 +173,26 @@ async function consumeInventoryItem(db, openid, dataType, itemId, count) {
|
|||||||
* @returns {Object} 操作结果
|
* @returns {Object} 操作结果
|
||||||
*/
|
*/
|
||||||
async function setInventoryItem(db, openid, dataType, itemId, count) {
|
async function setInventoryItem(db, openid, dataType, itemId, count) {
|
||||||
try {
|
if (!validateDataType(dataType)) {
|
||||||
if (!validateDataType(dataType)) {
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: `无效的数据类型: ${dataType}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const module = getModuleByType(dataType);
|
||||||
|
switch(dataType) {
|
||||||
|
case 'items':
|
||||||
|
return await module.setItem(db, openid, itemId, count);
|
||||||
|
case 'tals':
|
||||||
|
return await module.setTal(db, openid, itemId, count);
|
||||||
|
case 'equips':
|
||||||
|
return await module.setEquip(db, openid, itemId, count);
|
||||||
|
default:
|
||||||
return {
|
return {
|
||||||
code: -3,
|
code: -3,
|
||||||
msg: `无效的数据类型: ${dataType}`
|
msg: `无效的数据类型: ${dataType}`
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
const _ = db.command;
|
|
||||||
let user = await getOrCreaterUser(db, openid);
|
|
||||||
if (!user) {
|
|
||||||
return {
|
|
||||||
code: -4,
|
|
||||||
msg: "未找到用户"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof count !== 'number' || count < 0) {
|
|
||||||
return {
|
|
||||||
code: -3,
|
|
||||||
msg: "数量必须是非负数"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const oldCount = user[dataType][itemId] || 0;
|
|
||||||
|
|
||||||
let updateRes = await db.collection(user_db_name).doc(user._id).update({
|
|
||||||
data: {
|
|
||||||
[`${dataType}.${itemId}`]: _.set(count),
|
|
||||||
last_save_time: _.set(Date.now())
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (updateRes?.stats?.updated >= 1) {
|
|
||||||
return {
|
|
||||||
code: 200,
|
|
||||||
data: {
|
|
||||||
item_id: itemId,
|
|
||||||
old_count: oldCount,
|
|
||||||
new_count: count
|
|
||||||
},
|
|
||||||
msg: `${dataType.slice(0, -1)} ${itemId} 设置成功`
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
code: -1,
|
|
||||||
msg: `设置 ${dataType.slice(0, -1)} 失败`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`设置${dataType}物品错误:`, error);
|
|
||||||
return {
|
|
||||||
code: -5,
|
|
||||||
msg: `设置${dataType}物品错误: ${error.message}`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,77 +206,27 @@ async function setInventoryItem(db, openid, dataType, itemId, count) {
|
|||||||
* @returns {Object} 操作结果
|
* @returns {Object} 操作结果
|
||||||
*/
|
*/
|
||||||
async function updateInventory(db, openid, dataType, updateData, merge = true) {
|
async function updateInventory(db, openid, dataType, updateData, merge = true) {
|
||||||
try {
|
if (!validateDataType(dataType)) {
|
||||||
if (!validateDataType(dataType)) {
|
|
||||||
return {
|
|
||||||
code: -3,
|
|
||||||
msg: `Invalid data type: ${dataType}`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const _ = db.command;
|
|
||||||
let user = await getOrCreaterUser(db, openid);
|
|
||||||
if (!user) {
|
|
||||||
return {
|
|
||||||
code: -4,
|
|
||||||
msg: "User not found"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证更新数据
|
|
||||||
if (!updateData || typeof updateData !== 'object') {
|
|
||||||
return {
|
|
||||||
code: -3,
|
|
||||||
msg: "Invalid update data format"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证所有值都是非负数
|
|
||||||
for (const itemId in updateData) {
|
|
||||||
const count = updateData[itemId];
|
|
||||||
if (typeof count !== 'number' || count < 0) {
|
|
||||||
return {
|
|
||||||
code: -3,
|
|
||||||
msg: `Invalid count for item ${itemId}: ${count}`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let newData;
|
|
||||||
if (merge) {
|
|
||||||
// 合并更新
|
|
||||||
newData = { ...user[dataType], ...updateData };
|
|
||||||
} else {
|
|
||||||
// 完全替换
|
|
||||||
newData = updateData;
|
|
||||||
}
|
|
||||||
|
|
||||||
let updateRes = await db.collection(user_db_name).doc(user._id).update({
|
|
||||||
data: {
|
|
||||||
[dataType]: _.set(newData),
|
|
||||||
last_save_time: _.set(Date.now())
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (updateRes?.stats?.updated >= 1) {
|
|
||||||
return {
|
|
||||||
code: 200,
|
|
||||||
data: newData,
|
|
||||||
msg: `${dataType} updated successfully`
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
code: -1,
|
|
||||||
msg: `Update ${dataType} fail`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Update ${dataType} error:`, error);
|
|
||||||
return {
|
return {
|
||||||
code: -5,
|
code: -3,
|
||||||
msg: `Update ${dataType} error: ${error.message}`
|
msg: `无效的数据类型: ${dataType}`
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const module = getModuleByType(dataType);
|
||||||
|
switch(dataType) {
|
||||||
|
case 'items':
|
||||||
|
return await module.updateItems(db, openid, updateData, merge);
|
||||||
|
case 'tals':
|
||||||
|
return await module.updateTals(db, openid, updateData, merge);
|
||||||
|
case 'equips':
|
||||||
|
return await module.updateEquips(db, openid, updateData, merge);
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: `无效的数据类型: ${dataType}`
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -383,52 +237,26 @@ async function updateInventory(db, openid, dataType, updateData, merge = true) {
|
|||||||
* @returns {Object} 操作结果
|
* @returns {Object} 操作结果
|
||||||
*/
|
*/
|
||||||
async function resetInventory(db, openid, dataType) {
|
async function resetInventory(db, openid, dataType) {
|
||||||
try {
|
if (!validateDataType(dataType)) {
|
||||||
if (!validateDataType(dataType)) {
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: `无效的数据类型: ${dataType}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const module = getModuleByType(dataType);
|
||||||
|
switch(dataType) {
|
||||||
|
case 'items':
|
||||||
|
return await module.resetItems(db, openid);
|
||||||
|
case 'tals':
|
||||||
|
return await module.resetTals(db, openid);
|
||||||
|
case 'equips':
|
||||||
|
return await module.resetEquips(db, openid);
|
||||||
|
default:
|
||||||
return {
|
return {
|
||||||
code: -3,
|
code: -3,
|
||||||
msg: `Invalid data type: ${dataType}`
|
msg: `无效的数据类型: ${dataType}`
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
const _ = db.command;
|
|
||||||
const { getNewUserInitData } = require('../user_init_data');
|
|
||||||
let user = await getOrCreaterUser(db, openid);
|
|
||||||
if (!user) {
|
|
||||||
return {
|
|
||||||
code: -4,
|
|
||||||
msg: "User not found"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultData = getNewUserInitData();
|
|
||||||
|
|
||||||
let resetRes = await db.collection(user_db_name).doc(user._id).update({
|
|
||||||
data: {
|
|
||||||
[dataType]: _.set(defaultData[dataType]),
|
|
||||||
last_save_time: _.set(Date.now()),
|
|
||||||
reset_time: _.set(Date.now())
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (resetRes?.stats?.updated >= 1) {
|
|
||||||
return {
|
|
||||||
code: 200,
|
|
||||||
data: defaultData[dataType],
|
|
||||||
msg: `${dataType} reset successfully`
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
code: -1,
|
|
||||||
msg: `Reset ${dataType} fail`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Reset ${dataType} error:`, error);
|
|
||||||
return {
|
|
||||||
code: -5,
|
|
||||||
msg: `Reset ${dataType} error: ${error.message}`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,47 +268,26 @@ async function resetInventory(db, openid, dataType) {
|
|||||||
* @returns {Object} 操作结果
|
* @returns {Object} 操作结果
|
||||||
*/
|
*/
|
||||||
async function getOwnedItems(db, openid, dataType) {
|
async function getOwnedItems(db, openid, dataType) {
|
||||||
try {
|
if (!validateDataType(dataType)) {
|
||||||
if (!validateDataType(dataType)) {
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: `无效的数据类型: ${dataType}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const module = getModuleByType(dataType);
|
||||||
|
switch(dataType) {
|
||||||
|
case 'items':
|
||||||
|
return await module.getOwnedItems(db, openid);
|
||||||
|
case 'tals':
|
||||||
|
return await module.getOwnedTals(db, openid);
|
||||||
|
case 'equips':
|
||||||
|
return await module.getOwnedEquips(db, openid);
|
||||||
|
default:
|
||||||
return {
|
return {
|
||||||
code: -3,
|
code: -3,
|
||||||
msg: `Invalid data type: ${dataType}`
|
msg: `无效的数据类型: ${dataType}`
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
let user = await getOrCreaterUser(db, openid);
|
|
||||||
if (!user) {
|
|
||||||
return {
|
|
||||||
code: -4,
|
|
||||||
msg: "User not found"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const ownedItems = [];
|
|
||||||
for (const itemId in user[dataType]) {
|
|
||||||
const count = user[dataType][itemId];
|
|
||||||
if (count > 0) {
|
|
||||||
ownedItems.push({
|
|
||||||
item_id: parseInt(itemId),
|
|
||||||
count: count
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
code: 200,
|
|
||||||
data: {
|
|
||||||
owned_items: ownedItems,
|
|
||||||
total_types: ownedItems.length
|
|
||||||
},
|
|
||||||
msg: `Owned ${dataType} retrieved successfully`
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Get owned ${dataType} error:`, error);
|
|
||||||
return {
|
|
||||||
code: -5,
|
|
||||||
msg: `Get owned ${dataType} error: ${error.message}`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,421 @@
|
|||||||
|
// 物品库存操作模块 (items)
|
||||||
|
const { getOrCreaterUser } = require('./auth');
|
||||||
|
|
||||||
|
const user_db_name = "cocos_users";
|
||||||
|
const DATA_TYPE = 'items';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取物品库存数据
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function getItems(db, openid) {
|
||||||
|
try {
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: user[DATA_TYPE],
|
||||||
|
msg: `${DATA_TYPE}获取成功`
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`获取${DATA_TYPE}错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `获取${DATA_TYPE}错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个物品数据
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {number} itemId 物品ID
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function getItem(db, openid, itemId) {
|
||||||
|
try {
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const itemCount = user[DATA_TYPE][itemId];
|
||||||
|
if (itemCount === undefined) {
|
||||||
|
return {
|
||||||
|
code: -6,
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${itemId} 未找到`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
item_id: itemId,
|
||||||
|
count: itemCount
|
||||||
|
},
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${itemId} 获取成功`
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`获取${DATA_TYPE}物品错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `获取${DATA_TYPE}物品错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加物品
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {number} itemId 物品ID
|
||||||
|
* @param {number} count 添加数量
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function addItem(db, openid, itemId, count) {
|
||||||
|
try {
|
||||||
|
const _ = db.command;
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof count !== 'number' || count < 0) {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: "数量必须是非负数"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentCount = user[DATA_TYPE][itemId] || 0;
|
||||||
|
const newCount = currentCount + count;
|
||||||
|
|
||||||
|
let updateRes = await db.collection(user_db_name).doc(user._id).update({
|
||||||
|
data: {
|
||||||
|
[`${DATA_TYPE}.${itemId}`]: _.set(newCount),
|
||||||
|
last_save_time: _.set(Date.now())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updateRes?.stats?.updated >= 1) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
item_id: itemId,
|
||||||
|
old_count: currentCount,
|
||||||
|
new_count: newCount,
|
||||||
|
added: count
|
||||||
|
},
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${itemId} 添加成功`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
msg: `添加 ${DATA_TYPE.slice(0, -1)} 失败`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`添加${DATA_TYPE}物品错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `添加${DATA_TYPE}物品错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消耗物品
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {number} itemId 物品ID
|
||||||
|
* @param {number} count 消耗数量
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function consumeItem(db, openid, itemId, count) {
|
||||||
|
try {
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof count !== 'number' || count < 0) {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: "数量必须是非负数"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentCount = user[DATA_TYPE][itemId] || 0;
|
||||||
|
if (currentCount < count) {
|
||||||
|
return {
|
||||||
|
code: -6,
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${itemId}不足, 当前: ${currentCount}, 需要: ${count}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return await addItem(db, openid, itemId, -count);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`消耗${DATA_TYPE}物品错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `消耗${DATA_TYPE}物品错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置物品数量
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {number} itemId 物品ID
|
||||||
|
* @param {number} count 新的数量
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function setItem(db, openid, itemId, count) {
|
||||||
|
try {
|
||||||
|
const _ = db.command;
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof count !== 'number' || count < 0) {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: "数量必须是非负数"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldCount = user[DATA_TYPE][itemId] || 0;
|
||||||
|
|
||||||
|
let updateRes = await db.collection(user_db_name).doc(user._id).update({
|
||||||
|
data: {
|
||||||
|
[`${DATA_TYPE}.${itemId}`]: _.set(count),
|
||||||
|
last_save_time: _.set(Date.now())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updateRes?.stats?.updated >= 1) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
item_id: itemId,
|
||||||
|
old_count: oldCount,
|
||||||
|
new_count: count
|
||||||
|
},
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${itemId} 设置成功`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
msg: `设置 ${DATA_TYPE.slice(0, -1)} 失败`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`设置${DATA_TYPE}物品错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `设置${DATA_TYPE}物品错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量更新物品库存
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {Object} updateData 更新数据对象
|
||||||
|
* @param {boolean} merge 是否合并更新(默认true)
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function updateItems(db, openid, updateData, merge = true) {
|
||||||
|
try {
|
||||||
|
const _ = db.command;
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证更新数据
|
||||||
|
if (!updateData || typeof updateData !== 'object') {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: "无效的更新数据格式"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证所有值都是非负数
|
||||||
|
for (const itemId in updateData) {
|
||||||
|
const count = updateData[itemId];
|
||||||
|
if (typeof count !== 'number' || count < 0) {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: `物品 ${itemId} 的数量无效: ${count}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let newData;
|
||||||
|
if (merge) {
|
||||||
|
// 合并更新
|
||||||
|
newData = { ...user[DATA_TYPE], ...updateData };
|
||||||
|
} else {
|
||||||
|
// 完全替换
|
||||||
|
newData = updateData;
|
||||||
|
}
|
||||||
|
|
||||||
|
let updateRes = await db.collection(user_db_name).doc(user._id).update({
|
||||||
|
data: {
|
||||||
|
[DATA_TYPE]: _.set(newData),
|
||||||
|
last_save_time: _.set(Date.now())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updateRes?.stats?.updated >= 1) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: newData,
|
||||||
|
msg: `${DATA_TYPE} 更新成功`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
msg: `更新 ${DATA_TYPE} 失败`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`更新${DATA_TYPE}错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `更新${DATA_TYPE}错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置物品库存数据
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function resetItems(db, openid) {
|
||||||
|
try {
|
||||||
|
const _ = db.command;
|
||||||
|
const { getNewUserInitData } = require('../user_init_data');
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultData = getNewUserInitData();
|
||||||
|
|
||||||
|
let resetRes = await db.collection(user_db_name).doc(user._id).update({
|
||||||
|
data: {
|
||||||
|
[DATA_TYPE]: _.set(defaultData[DATA_TYPE]),
|
||||||
|
last_save_time: _.set(Date.now()),
|
||||||
|
reset_time: _.set(Date.now())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (resetRes?.stats?.updated >= 1) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: defaultData[DATA_TYPE],
|
||||||
|
msg: `${DATA_TYPE} 重置成功`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
msg: `重置 ${DATA_TYPE} 失败`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`重置${DATA_TYPE}错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `重置${DATA_TYPE}错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取拥有的物品列表(数量大于0的)
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function getOwnedItems(db, openid) {
|
||||||
|
try {
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const ownedItems = [];
|
||||||
|
for (const itemId in user[DATA_TYPE]) {
|
||||||
|
const count = user[DATA_TYPE][itemId];
|
||||||
|
if (count > 0) {
|
||||||
|
ownedItems.push({
|
||||||
|
item_id: parseInt(itemId),
|
||||||
|
count: count
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
owned_items: ownedItems,
|
||||||
|
total_types: ownedItems.length
|
||||||
|
},
|
||||||
|
msg: `拥有的${DATA_TYPE}获取成功`
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`获取拥有的${DATA_TYPE}错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `获取拥有的${DATA_TYPE}错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getItems,
|
||||||
|
getItem,
|
||||||
|
addItem,
|
||||||
|
consumeItem,
|
||||||
|
setItem,
|
||||||
|
updateItems,
|
||||||
|
resetItems,
|
||||||
|
getOwnedItems
|
||||||
|
};
|
||||||
@@ -0,0 +1,421 @@
|
|||||||
|
// 天赋库存操作模块 (tals)
|
||||||
|
const { getOrCreaterUser } = require('./auth');
|
||||||
|
|
||||||
|
const user_db_name = "cocos_users";
|
||||||
|
const DATA_TYPE = 'tals';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取天赋库存数据
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function getTals(db, openid) {
|
||||||
|
try {
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: user[DATA_TYPE],
|
||||||
|
msg: `${DATA_TYPE}获取成功`
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`获取${DATA_TYPE}错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `获取${DATA_TYPE}错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个天赋数据
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {number} talId 天赋ID
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function getTal(db, openid, talId) {
|
||||||
|
try {
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const talCount = user[DATA_TYPE][talId];
|
||||||
|
if (talCount === undefined) {
|
||||||
|
return {
|
||||||
|
code: -6,
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${talId} 未找到`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
item_id: talId,
|
||||||
|
count: talCount
|
||||||
|
},
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${talId} 获取成功`
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`获取${DATA_TYPE}物品错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `获取${DATA_TYPE}物品错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加天赋
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {number} talId 天赋ID
|
||||||
|
* @param {number} count 添加数量
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function addTal(db, openid, talId, count) {
|
||||||
|
try {
|
||||||
|
const _ = db.command;
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof count !== 'number' || count < 0) {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: "数量必须是非负数"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentCount = user[DATA_TYPE][talId] || 0;
|
||||||
|
const newCount = currentCount + count;
|
||||||
|
|
||||||
|
let updateRes = await db.collection(user_db_name).doc(user._id).update({
|
||||||
|
data: {
|
||||||
|
[`${DATA_TYPE}.${talId}`]: _.set(newCount),
|
||||||
|
last_save_time: _.set(Date.now())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updateRes?.stats?.updated >= 1) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
item_id: talId,
|
||||||
|
old_count: currentCount,
|
||||||
|
new_count: newCount,
|
||||||
|
added: count
|
||||||
|
},
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${talId} 添加成功`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
msg: `添加 ${DATA_TYPE.slice(0, -1)} 失败`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`添加${DATA_TYPE}物品错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `添加${DATA_TYPE}物品错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消耗天赋
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {number} talId 天赋ID
|
||||||
|
* @param {number} count 消耗数量
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function consumeTal(db, openid, talId, count) {
|
||||||
|
try {
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof count !== 'number' || count < 0) {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: "数量必须是非负数"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentCount = user[DATA_TYPE][talId] || 0;
|
||||||
|
if (currentCount < count) {
|
||||||
|
return {
|
||||||
|
code: -6,
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${talId}不足, 当前: ${currentCount}, 需要: ${count}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return await addTal(db, openid, talId, -count);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`消耗${DATA_TYPE}物品错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `消耗${DATA_TYPE}物品错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置天赋数量
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {number} talId 天赋ID
|
||||||
|
* @param {number} count 新的数量
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function setTal(db, openid, talId, count) {
|
||||||
|
try {
|
||||||
|
const _ = db.command;
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof count !== 'number' || count < 0) {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: "数量必须是非负数"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldCount = user[DATA_TYPE][talId] || 0;
|
||||||
|
|
||||||
|
let updateRes = await db.collection(user_db_name).doc(user._id).update({
|
||||||
|
data: {
|
||||||
|
[`${DATA_TYPE}.${talId}`]: _.set(count),
|
||||||
|
last_save_time: _.set(Date.now())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updateRes?.stats?.updated >= 1) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
item_id: talId,
|
||||||
|
old_count: oldCount,
|
||||||
|
new_count: count
|
||||||
|
},
|
||||||
|
msg: `${DATA_TYPE.slice(0, -1)} ${talId} 设置成功`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
msg: `设置 ${DATA_TYPE.slice(0, -1)} 失败`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`设置${DATA_TYPE}物品错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `设置${DATA_TYPE}物品错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量更新天赋库存
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @param {Object} updateData 更新数据对象
|
||||||
|
* @param {boolean} merge 是否合并更新(默认true)
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function updateTals(db, openid, updateData, merge = true) {
|
||||||
|
try {
|
||||||
|
const _ = db.command;
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证更新数据
|
||||||
|
if (!updateData || typeof updateData !== 'object') {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: "无效的更新数据格式"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证所有值都是非负数
|
||||||
|
for (const talId in updateData) {
|
||||||
|
const count = updateData[talId];
|
||||||
|
if (typeof count !== 'number' || count < 0) {
|
||||||
|
return {
|
||||||
|
code: -3,
|
||||||
|
msg: `天赋 ${talId} 的数量无效: ${count}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let newData;
|
||||||
|
if (merge) {
|
||||||
|
// 合并更新
|
||||||
|
newData = { ...user[DATA_TYPE], ...updateData };
|
||||||
|
} else {
|
||||||
|
// 完全替换
|
||||||
|
newData = updateData;
|
||||||
|
}
|
||||||
|
|
||||||
|
let updateRes = await db.collection(user_db_name).doc(user._id).update({
|
||||||
|
data: {
|
||||||
|
[DATA_TYPE]: _.set(newData),
|
||||||
|
last_save_time: _.set(Date.now())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updateRes?.stats?.updated >= 1) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: newData,
|
||||||
|
msg: `${DATA_TYPE} 更新成功`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
msg: `更新 ${DATA_TYPE} 失败`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`更新${DATA_TYPE}错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `更新${DATA_TYPE}错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置天赋库存数据
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function resetTals(db, openid) {
|
||||||
|
try {
|
||||||
|
const _ = db.command;
|
||||||
|
const { getNewUserInitData } = require('../user_init_data');
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultData = getNewUserInitData();
|
||||||
|
|
||||||
|
let resetRes = await db.collection(user_db_name).doc(user._id).update({
|
||||||
|
data: {
|
||||||
|
[DATA_TYPE]: _.set(defaultData[DATA_TYPE]),
|
||||||
|
last_save_time: _.set(Date.now()),
|
||||||
|
reset_time: _.set(Date.now())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (resetRes?.stats?.updated >= 1) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: defaultData[DATA_TYPE],
|
||||||
|
msg: `${DATA_TYPE} 重置成功`
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
msg: `重置 ${DATA_TYPE} 失败`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`重置${DATA_TYPE}错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `重置${DATA_TYPE}错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取拥有的天赋列表(数量大于0的)
|
||||||
|
* @param {Object} db 数据库实例
|
||||||
|
* @param {string} openid 用户openid
|
||||||
|
* @returns {Object} 操作结果
|
||||||
|
*/
|
||||||
|
async function getOwnedTals(db, openid) {
|
||||||
|
try {
|
||||||
|
let user = await getOrCreaterUser(db, openid);
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
code: -4,
|
||||||
|
msg: "未找到用户"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const ownedTals = [];
|
||||||
|
for (const talId in user[DATA_TYPE]) {
|
||||||
|
const count = user[DATA_TYPE][talId];
|
||||||
|
if (count > 0) {
|
||||||
|
ownedTals.push({
|
||||||
|
item_id: parseInt(talId),
|
||||||
|
count: count
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
owned_items: ownedTals,
|
||||||
|
total_types: ownedTals.length
|
||||||
|
},
|
||||||
|
msg: `拥有的${DATA_TYPE}获取成功`
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`获取拥有的${DATA_TYPE}错误:`, error);
|
||||||
|
return {
|
||||||
|
code: -5,
|
||||||
|
msg: `获取拥有的${DATA_TYPE}错误: ${error.message}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getTals,
|
||||||
|
getTal,
|
||||||
|
addTal,
|
||||||
|
consumeTal,
|
||||||
|
setTal,
|
||||||
|
updateTals,
|
||||||
|
resetTals,
|
||||||
|
getOwnedTals
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user