import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose'; import { BAG } from '../pubUtils/dicParam'; import { SearchItemParam } from '../domain/backEndField/search'; // const Transaction = require("mongoose-transactions"); @index({ roleId: 1, id: 1 }) @index({ seqId: 1 }) @modelOptions({ schemaOptions: { id: false } }) export default class Item extends BaseModel { @prop({ required: true, default: '' }) roleId: string; // 角色 id @prop({ required: true, default: '' }) roleName: string; // 角色名称 @prop({ required: true, default: '' }) id: number; // 道具 id @prop({ required: true, default: '' }) type: number; // 道具类型 @prop({ required: true, default: '' }) itemName: string; // 道具名称 @prop({ required: true, default: 0 }) hid: number; // 将魂:武将id,其他:0 @prop({ required: true }) count: number; // 道具数量 public static async findbyRole(roleId: string, select = '') { const items: ItemType[] = await ItemModel.find({ roleId, count: {$gte: 0} }).select(select).lean(); return items; } public static async findbyRoleAndIds(roleId: string, ids: Array, lean = true) { const items: ItemType[] = await ItemModel.find({ roleId, id: { $in: ids }, count: {$gte: 0} }).select('id count type').lean(lean); return items; } public static async findByRoleAndType(roleId: string, type: number, lean = true) { const items: ItemType[] = await ItemModel.find({ roleId, type }).select('id count type').sort({ id: 1 }).lean(lean); return items; } public static async findbyRoleAndGidAndCount(roleId: string, id: number, count: number, lean = true) { const items: ItemType = await ItemModel.findOne({ roleId, id, count: { $gte: count } }).select('id count type').lean(lean); return items; } public static async findbyRoleAndGid(roleId: string, id: number, lean = true) { const items: ItemType = await ItemModel.findOne({ roleId, id }).select('id count type').lean(lean); return items; } public static async increaseItem(roleId: string, id: number, count: number, itemInfo: { roleId: string, roleName: string, id: number, itemName: string, type: number, hid?: number }) { const doc = new ItemModel(); const setOnInsert = Object.assign(doc.toJSON(), itemInfo); let items: ItemType = await ItemModel.findOneAndUpdate({ roleId, id }, { $setOnInsert: setOnInsert, $inc: { count } }, { new: true, upsert: true }).lean(); if(items.count > BAG.BAG_GOODS_UPLIMITED) { items = await ItemModel.findOneAndUpdate({ roleId, id, count: { $gte: BAG.BAG_GOODS_UPLIMITED } }, { $set: { count: BAG.BAG_GOODS_UPLIMITED } }, { new: true }).lean(); } return items; } public static async decreaseItems(roleId: string, items: Array<{ id: number, count: number, ratio?: number }>, lean = true) { let updateItems = new Array<{ id: number, count: number, ratio?: number }>(), hasError: boolean = false, result = new Array(); for (let { id, count, ratio } of items) { let rec: ItemType; if (!ratio) { rec = await ItemModel.findOneAndUpdate({ roleId, id, count: { $gte: count } }, { $inc: { count: -1 * count } }, { new: true }).lean(lean); } else { rec = await ItemModel.findOneAndUpdate({ roleId, id }, { $inc: { count: ratio * count } }, { new: true, upsert: true }).lean(lean); } if (!!rec) { let index = result.findIndex(cur => cur.id == rec.id); if (index != -1) { result[index].count = rec.count; result[index].inc += -count; } else { result.push({ id: rec.id, count: rec.count, inc: -count }); } updateItems.push({ id, count, ratio }); } else { hasError = true; break; } } if (hasError) { // 数量不足 for (let { id, count, ratio } of updateItems) { if (!ratio) ratio = -1; await ItemModel.findOneAndUpdate({ roleId, id }, { $inc: { count: -ratio * count } }, { new: true }).lean(lean); } return { hasError: true } } else { return { hasError: false, result } } } public static async deleteAccount(roleId: string) { let result = await ItemModel.deleteMany({ roleId }); return result; } public static async deletebyRoleAndIds(roleId: string, ids: Array) { const result = await ItemModel.deleteMany({ roleId, id: { $in: ids } }); return result; } public static async updateCountByRoleAndIds(roleId: string, ids: Array, count: number) { const result: ItemType = await ItemModel.findOneAndUpdate({ roleId, id: { $in: ids } }, {$set: {count}}, {new: true, upsert: true}).lean(); return result; } private static getSearchObj(form: SearchItemParam) { let searchObj = {}; if (form.roleId) searchObj['roleId'] = form.roleId; if (form.roleName) searchObj['roleName'] = { $regex: new RegExp(form.roleName.toString(), 'i') }; if (form.id) searchObj['id'] = form.id; return searchObj } public static async findByCondition(page: number, pageSize: number, sortField: string = 'updatedAt', sortOrder: string = 'descend', form: SearchItemParam = {}) { let searchObj = this.getSearchObj(form); let sort = {}; if (sortField && sortOrder) { if (sortOrder == 'ascend') { sort[sortField] = 1; } else if (sortOrder == 'descend') { sort[sortField] = -1; } } const result: ItemType[] = await ItemModel.find(searchObj).limit(pageSize).skip((page - 1) * pageSize).sort(sort).select('-_id -__v -createdAt -updatedAt').lean({ getters: true, virtuals: true }); return result; } public static async countByCondition(form: SearchItemParam = {}) { let searchObj = this.getSearchObj(form); const result = await ItemModel.count(searchObj); return result; } } export const ItemModel = getModelForClass(Item); export interface ItemType extends Pick, keyof Item> { id: number; };