125 lines
5.4 KiB
TypeScript
125 lines
5.4 KiB
TypeScript
import BaseModel from './BaseModel';
|
||
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
|
||
import { findIndex } from 'underscore';
|
||
import { BAG } from '../pubUtils/dicParam';
|
||
// 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, lean = true) {
|
||
const items: ItemType[] = await ItemModel.find({ roleId, count: {$gte: 0} }).select('id count type').lean(lean);
|
||
return items;
|
||
}
|
||
|
||
public static async findbyRoleAndIds(roleId: string, ids: Array<number>, 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 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 = findIndex(result,{id})
|
||
if (!!result[index]) {
|
||
result[index] = { id: rec.id, count: rec.count, 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<number>) {
|
||
const result = await ItemModel.deleteMany({ roleId, id: { $in: ids } });
|
||
return result;
|
||
}
|
||
|
||
public static async updateCountByRoleAndIds(roleId: string, ids: Array<number>, count: number) {
|
||
const result: ItemType = await ItemModel.findOneAndUpdate({ roleId, id: { $in: ids } }, {$set: {count}}, {new: true, upsert: true}).lean();
|
||
return result;
|
||
}
|
||
|
||
public static async findByField(field: string, value?: number|string, lean = true) {
|
||
let searchObj = {};
|
||
if(field != 'all') {
|
||
if(field == 'roleName') {
|
||
searchObj['roleName'] = { $regex: new RegExp(value.toString(), 'i') }
|
||
} else {
|
||
searchObj[field] = value;
|
||
}
|
||
}
|
||
//.select('uid tel username')
|
||
const user: ItemType[] = await ItemModel.find(searchObj).lean(lean);
|
||
return user;
|
||
}
|
||
}
|
||
|
||
|
||
export const ItemModel = getModelForClass(Item);
|
||
|
||
export interface ItemType extends Pick<DocumentType<Item>, keyof Item> {
|
||
id: number;
|
||
};
|