import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, mongoose, Ref } from '@typegoose/typegoose'; import Role, { RoleType } from './Role'; import FriendShip, { FriendShipType } from './FriendShip'; import { ROLE_SELECT, POPULATE_TYPE } from '../consts'; export class Relation { @prop({ required: true, default: '' }) roleId: string; // 对方玩家id @prop({ required: true, ref: 'Role', type: mongoose.Schema.Types.ObjectId }) role: Ref; @prop({ required: true, ref: 'FriendRelation', type: mongoose.Schema.Types.ObjectId }) friendShip: Ref; } /** * 好友系统关系表 */ @index({ roleId: 1, createdAt: -1 }) export default class FriendRelation extends BaseModel { @prop({ required: true, default: '' }) roleId: string; // 操作玩家本人id @prop({ required: true, default: [], type: Relation, _id: false }) friends: Relation[]; // 好友列表 @prop({ required: true, default: [], type: Relation, _id: false }) blacklist: Relation[]; // 黑名单列表 // 创建 public static async addFriend(roleId: string, friend: RoleType, friendShip: FriendShipType) { const result: FriendRelationType = await FriendRelationModel.findOneAndUpdate( { roleId }, { $setOnInsert: { blacklist: [] }, $push: { friends: { roleId: friend.roleId, role: friend._id, friendShip: friendShip._id } } }, { upsert: true, new: true }).lean(); return result; } // 获取列表 public static async findFriendByRole(roleId: string, populateType: number) { let document = FriendRelationModel.findOne({ roleId }) .lean({ getters: true, virtuals: true }); if (populateType == POPULATE_TYPE.FRIEND) { document .populate('friends.role', ROLE_SELECT.SHOW_SIMPLE, 'Role') .populate('friends.friendShip', null, 'FriendShip'); } else if (populateType == POPULATE_TYPE.BLACKLIST) { document .populate('blacklist.role', ROLE_SELECT.SHOW_SIMPLE, 'Role') } else if (populateType == POPULATE_TYPE.FRIENDSHIP) { document.populate('friends.friendShip', null, 'FriendShip'); } else if (populateType == POPULATE_TYPE.FRIEND_NAME_ONLY) { document .populate('friends.role', 'roleName', 'Role') } let result: FriendRelationType = await document.lean({ getters: true, virtuals: true });; // console.log(JSON.stringify(result)); return result; } public static async moveFromFriend(roleId: string, friend: RoleType, friendShip: FriendShipType, toBlack: boolean, hasFriend: boolean ) { let update = {} let setOnInsert = {}; if(hasFriend) { update['$pull'] = { friends: { roleId: friend.roleId } }; } else { setOnInsert['friends'] = []; } if(toBlack) { update['$push'] = { blacklist: { roleId: friend.roleId, role: friend._id, friendShip: friendShip? friendShip._id: null } }; } else { setOnInsert['blacklist'] = []; } update['$setOnInsert'] = setOnInsert; let result: FriendRelationType = await FriendRelationModel.findOneAndUpdate({ roleId }, update, { upsert: true, new: true }); return result } public static async removeFromBlack(roleId: string, frdRoleId: string ) { let result: FriendRelationType = await FriendRelationModel.findOneAndUpdate({ roleId }, { $pull: { blacklist: { roleId: frdRoleId } }, $setOnInsert: { friends: [] } }, { upsert: true, new: true }); return result } public static async isInBlackList(roleId: string, hisRoleId: string) { let result = await FriendRelationModel.find({ $or: [{ roleId, 'blacklist.roleId': hisRoleId}, { hisRoleId, 'blacklist.roleId': roleId}] }).lean(); return result.length > 0; } public static async updateInfo(roleId: string, update: friendShipUpdate) { const result = await FriendRelationModel.findOneAndUpdate({ roleId }, {$set: update}, { new: true }).lean(); return result; } public static async deleteAccount(roleId: string) { let result = await FriendRelationModel.deleteMany({ roleId }); await FriendRelationModel.updateMany({}, { $pull: { friends: { roleId }, blacklist: { roleId } }}); return result; } } export const FriendRelationModel = getModelForClass(FriendRelation); export interface FriendRelationType extends Pick, keyof FriendRelation> { }; type friendShipUpdate = Partial; // 将所有字段变成可选项