Files
ZYZ/shared/db/Item.ts
2021-01-08 18:19:13 +08:00

119 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
const _ = require('underscore');
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 }).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 } }).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 }, lean = true) {
const doc = new ItemModel();
const setOnInsert = Object.assign(doc.toJSON(), itemInfo);
const items: ItemType = await ItemModel.findOneAndUpdate({ roleId, id }, { $setOnInsert: setOnInsert, $inc: { count } }, { new: true, upsert: true }).lean(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 }
// } else {
// result.push({ id: rec.id, count: rec.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 decreaseItems(roleId: string, items: Array<{ id: number, count: number, ratio?: number}>, lean = true) {
const transaction = new Transaction();
let hasError: boolean = false, result = new Array();
try {
for (let { id, count, ratio } of items) {
if (ratio) ratio = -1;
await transaction.update({ roleId, id, count: { $gte: count } }, { $inc: { count: ratio * count } }, { new: true});
const rec: ItemType = await transaction.findOneAndUpdate({ roleId, id, count: { $gte: count } }, { $inc: { count: ratio * count } }, { new: true}).lean(lean);
if (!!rec) {
result.push({ id: rec.id, count: rec.count });
} else {
hasError = true; break;
}
}
await transaction.run();
return {hasError, result};
} catch (error) {
await transaction.rollback().catch(console.error);
transaction.clean();
return {error};
}
}
public static async deleteAccount(roleId: string) {
let result = await ItemModel.deleteMany({ roleId });
return result;
}
}
export const ItemModel = getModelForClass(Item);
export interface ItemType extends Pick<DocumentType<Item>, keyof Item> {
id: number;
};