// 通用库存操作模块 (items, tals, equips) const { getOrCreaterUser } = require('./auth'); const user_db_name = "cocos_users"; // 支持的数据类型 const SUPPORTED_TYPES = ['items', 'tals', 'equips']; /** * 验证数据类型 * @param {string} dataType 数据类型 * @returns {boolean} 是否有效 */ function validateDataType(dataType) { return SUPPORTED_TYPES.includes(dataType); } /** * 获取库存数据 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @param {string} dataType 数据类型 ('items', 'tals', 'equips') * @returns {Object} 操作结果 */ async function getInventory(db, openid, dataType) { try { if (!validateDataType(dataType)) { return { code: -3, msg: `Invalid data type: ${dataType}` }; } let user = await getOrCreaterUser(db, openid); if (!user) { return { code: -4, msg: "User not found" }; } return { code: 200, data: user[dataType], msg: `${dataType} retrieved successfully` }; } catch (error) { console.error(`Get ${dataType} error:`, error); return { code: -5, msg: `Get ${dataType} error: ${error.message}` }; } } /** * 获取单个物品数据 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @param {string} dataType 数据类型 * @param {number} itemId 物品ID * @returns {Object} 操作结果 */ async function getInventoryItem(db, openid, dataType, itemId) { try { if (!validateDataType(dataType)) { return { code: -3, msg: `Invalid data type: ${dataType}` }; } let user = await getOrCreaterUser(db, openid); if (!user) { return { code: -4, msg: "User not found" }; } const itemCount = user[dataType][itemId]; if (itemCount === undefined) { return { code: -6, msg: `${dataType.slice(0, -1)} ${itemId} not found` }; } return { code: 200, data: { item_id: itemId, count: itemCount }, msg: `${dataType.slice(0, -1)} ${itemId} retrieved successfully` }; } catch (error) { console.error(`Get ${dataType} item error:`, error); return { code: -5, msg: `Get ${dataType} item error: ${error.message}` }; } } /** * 添加物品 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @param {string} dataType 数据类型 * @param {number} itemId 物品ID * @param {number} count 添加数量 * @returns {Object} 操作结果 */ async function addInventoryItem(db, openid, dataType, itemId, count) { try { 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 (typeof count !== 'number' || count < 0) { return { code: -3, msg: "Count must be a non-negative number" }; } 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} added successfully` }; } else { return { code: -1, msg: `Add ${dataType.slice(0, -1)} fail` }; } } catch (error) { console.error(`Add ${dataType} item error:`, error); return { code: -5, msg: `Add ${dataType} item error: ${error.message}` }; } } /** * 消耗物品 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @param {string} dataType 数据类型 * @param {number} itemId 物品ID * @param {number} count 消耗数量 * @returns {Object} 操作结果 */ async function consumeInventoryItem(db, openid, dataType, itemId, count) { try { if (!validateDataType(dataType)) { return { code: -3, msg: `Invalid data type: ${dataType}` }; } let user = await getOrCreaterUser(db, openid); if (!user) { return { code: -4, msg: "User not found" }; } if (typeof count !== 'number' || count < 0) { return { code: -3, msg: "Count must be a non-negative number" }; } const currentCount = user[dataType][itemId] || 0; if (currentCount < count) { return { code: -6, msg: `Insufficient ${dataType.slice(0, -1)} ${itemId}, current: ${currentCount}, required: ${count}` }; } return await addInventoryItem(db, openid, dataType, itemId, -count); } catch (error) { console.error(`Consume ${dataType} item error:`, error); return { code: -5, msg: `Consume ${dataType} item error: ${error.message}` }; } } /** * 设置物品数量 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @param {string} dataType 数据类型 * @param {number} itemId 物品ID * @param {number} count 新的数量 * @returns {Object} 操作结果 */ async function setInventoryItem(db, openid, dataType, itemId, count) { try { 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 (typeof count !== 'number' || count < 0) { return { code: -3, msg: "Count must be a non-negative number" }; } 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} set successfully` }; } else { return { code: -1, msg: `Set ${dataType.slice(0, -1)} fail` }; } } catch (error) { console.error(`Set ${dataType} item error:`, error); return { code: -5, msg: `Set ${dataType} item error: ${error.message}` }; } } /** * 批量更新库存 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @param {string} dataType 数据类型 * @param {Object} updateData 更新数据对象 * @param {boolean} merge 是否合并更新(默认true) * @returns {Object} 操作结果 */ async function updateInventory(db, openid, dataType, updateData, merge = true) { try { 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 { code: -5, msg: `Update ${dataType} error: ${error.message}` }; } } /** * 重置库存数据 * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @param {string} dataType 数据类型 * @returns {Object} 操作结果 */ async function resetInventory(db, openid, dataType) { try { if (!validateDataType(dataType)) { return { code: -3, msg: `Invalid data type: ${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}` }; } } /** * 获取拥有的物品列表(数量大于0的) * @param {Object} db 数据库实例 * @param {string} openid 用户openid * @param {string} dataType 数据类型 * @returns {Object} 操作结果 */ async function getOwnedItems(db, openid, dataType) { try { if (!validateDataType(dataType)) { return { code: -3, msg: `Invalid data type: ${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}` }; } } module.exports = { getInventory, getInventoryItem, addInventoryItem, consumeInventoryItem, setInventoryItem, updateInventory, resetInventory, getOwnedItems, SUPPORTED_TYPES };