// 基础游戏数据操作模块 (data字段) const { getOrCreaterUser } = require('./auth'); const { validateDataStructure, mergeUserDataWithDefaults } = require('../user_init_data'); const user_db_name = "cocos_users"; /** * 获取基础游戏数据 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @returns {Object} 操作结果 */ async function getData(db, openid) { try { let user = await getOrCreaterUser(db, openid); if (!user) { return { code: -4, msg: "用户未找到" }; } return { code: 200, data: user.data, msg: "游戏数据获取成功" }; } catch (error) { console.error("获取游戏数据错误:", error); return { code: -5, msg: `获取游戏数据错误: ${error.message}` }; } } /** * 更新基础游戏数据 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @param {Object} updateData 要更新的数据 * @param {boolean} merge 是否合并更新(默认true) * @returns {Object} 操作结果 */ async function updateData(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: "无效的更新数据格式" }; } let newData; if (merge) { // 合并更新 newData = { ...user.data, ...updateData }; } else { // 完全替换 newData = updateData; } let updateRes = await db.collection(user_db_name).doc(user._id).update({ data: { data: _.set(newData), last_save_time: _.set(Date.now()) } }); if (updateRes?.stats?.updated >= 1) { return { code: 200, data: newData, msg: "游戏数据更新成功" }; } else { return { code: -1, msg: `更新失败, ${JSON.stringify(updateRes)}` }; } } catch (error) { console.error("更新游戏数据错误:", error); return { code: -5, msg: `更新游戏数据错误: ${error.message}` }; } } /** * 增加指定字段的数值 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @param {string} field 字段名 * @param {number} amount 增加的数量 * @returns {Object} 操作结果 */ async function addDataField(db, openid, field, amount) { try { const _ = db.command; let user = await getOrCreaterUser(db, openid); if (!user) { return { code: -4, msg: "用户未找到" }; } if (typeof amount !== 'number') { return { code: -3, msg: "数量必须是数字" }; } const currentValue = user.data[field] || 0; const newValue = Math.max(0, currentValue + amount); let updateRes = await db.collection(user_db_name).doc(user._id).update({ data: { [`data.${field}`]: _.set(newValue), last_save_time: _.set(Date.now()) } }); if (updateRes?.stats?.updated >= 1) { return { code: 200, data: { field: field, old_value: currentValue, new_value: newValue, change: amount }, msg: `${field} 更新成功` }; } else { return { code: -1, msg: `更新 ${field} 失败` }; } } catch (error) { console.error(`增加 ${field} 错误:`, error); return { code: -5, msg: `增加 ${field} 错误: ${error.message}` }; } } /** * 消耗指定字段的数值 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @param {string|Object[]} field 字段名或字段对象数组 [{field: 字段名, amount: 数量}] * @param {number} [amount] 消耗的数量 (当field为字符串时使用) * @returns {Object} 操作结果 */ async function spendDataField(db, openid, field, amount) { try { const _ = db.command; let user = await getOrCreaterUser(db, openid); if (!user) { return { code: -4, msg: "用户未找到" }; } // 处理单个字段的情况 if (typeof field === 'string') { if (typeof amount !== 'number' || amount < 0) { return { code: -3, msg: "数量必须是正数" }; } const currentValue = user.data[field] || 0; if (currentValue < amount) { return { code: -6, msg: `${field} 不足, 当前: ${currentValue}, 需要: ${amount}` }; } return await addDataField(db, openid, field, -amount); } // 处理多个字段的情况 if (Array.isArray(field)) { const fieldsToSpend = field; // 验证参数格式 for (const item of fieldsToSpend) { if (!item.field || typeof item.amount !== 'number' || item.amount < 0) { return { code: -3, msg: "字段参数格式错误,需要 {field, amount} 结构,且amount必须是正数" }; } } // 检查所有资源是否足够 for (const item of fieldsToSpend) { const currentValue = user.data[item.field] || 0; if (currentValue < item.amount) { return { code: -6, msg: `${item.field} 不足, 当前: ${currentValue}, 需要: ${item.amount}` }; } } // 所有资源都足够,开始扣除 const updateData = {}; const changes = []; for (const item of fieldsToSpend) { const currentValue = user.data[item.field] || 0; const newValue = Math.max(0, currentValue - item.amount); updateData[`data.${item.field}`] = _.set(newValue); changes.push({ field: item.field, old_value: currentValue, new_value: newValue, change: -item.amount }); } // 更新数据库 updateData['last_save_time'] = _.set(Date.now()); let updateRes = await db.collection(user_db_name).doc(user._id).update({ data: updateData }); if (updateRes?.stats?.updated >= 1) { return { code: 200, data: changes, msg: "资源消耗成功" }; } else { return { code: -1, msg: "资源消耗失败" }; } } return { code: -3, msg: "参数格式错误" }; } catch (error) { console.error(`消耗资源错误:`, error); return { code: -5, msg: `消耗资源错误: ${error.message}` }; } } /** * 设置指定字段的数值 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @param {string} field 字段名 * @param {any} value 新的值 * @returns {Object} 操作结果 */ async function setDataField(db, openid, field, value) { try { const _ = db.command; let user = await getOrCreaterUser(db, openid); if (!user) { return { code: -4, msg: "用户未找到" }; } const oldValue = user.data[field]; let updateRes = await db.collection(user_db_name).doc(user._id).update({ data: { [`data.${field}`]: _.set(value), last_save_time: _.set(Date.now()) } }); if (updateRes?.stats?.updated >= 1) { return { code: 200, data: { field: field, old_value: oldValue, new_value: value }, msg: `${field} 设置成功` }; } else { return { code: -1, msg: `设置 ${field} 失败` }; } } catch (error) { console.error(`设置 ${field} 错误:`, error); return { code: -5, msg: `设置 ${field} 错误: ${error.message}` }; } } /** * 重置基础游戏数据 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @returns {Object} 操作结果 */ async function resetData(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: _.set(defaultData.data), last_save_time: _.set(Date.now()), reset_time: _.set(Date.now()) } }); if (resetRes?.stats?.updated >= 1) { return { code: 200, data: defaultData.data, msg: "游戏数据重置成功" }; } else { return { code: -1, msg: `重置失败, ${JSON.stringify(resetRes)}` }; } } catch (error) { console.error("重置游戏数据错误:", error); return { code: -5, msg: `重置游戏数据错误: ${error.message}` }; } } module.exports = { getData, updateData, addDataField, spendDataField, setDataField, resetData };