| 1 | import { Injectable } from '@nestjs/common' |
| 2 | import { InjectModel } from '@nestjs/mongoose' |
| 3 | import { UserType } from '@yikart/common' |
| 4 | import { FilterQuery, Model, RootFilterQuery, Types } from 'mongoose' |
| 5 | import { Media, MediaType } from '../schemas/media.schema' |
| 6 | import { BaseRepository } from './base.repository' |
| 7 | |
| 8 | @Injectable() |
| 9 | export class MediaRepository extends BaseRepository<Media> { |
| 10 | constructor( |
| 11 | @InjectModel(Media.name) |
| 12 | private readonly mediaModel: Model<Media>, |
| 13 | ) { |
| 14 | super(mediaModel) |
| 15 | } |
| 16 | |
| 17 | override async create(newData: Omit<Media, 'id' | 'updatedAt' | 'useCount' | 'createdAt'>) { |
| 18 | return await this.mediaModel.create(newData) |
| 19 | } |
| 20 | |
| 21 | async getListByIds(ids: string[]) { |
| 22 | const mediaList = await this.mediaModel.find({ _id: { $in: ids } }).lean({ virtuals: true }) |
| 23 | return mediaList |
| 24 | } |
| 25 | |
| 26 | async updateGroupIdByIds(ids: string[], targetGroupId: string, userId: string): Promise<number> { |
| 27 | const res = await this.mediaModel.updateMany( |
| 28 | { _id: { $in: ids }, userId }, |
| 29 | { $set: { groupId: targetGroupId } }, |
| 30 | ) |
| 31 | return res.modifiedCount |
| 32 | } |
| 33 | |
| 34 | async updateMaterialGroupByIds(ids: string[], targetGroupId: string, userId: string): Promise<number> { |
| 35 | const res = await this.mediaModel.updateMany( |
| 36 | { _id: { $in: ids }, userId }, |
| 37 | { $set: { materialGroupId: targetGroupId } }, |
| 38 | ) |
| 39 | return res.modifiedCount |
| 40 | } |
| 41 | |
| 42 | async listByIdsAndUserId(ids: string[], userId: string): Promise<Media[]> { |
| 43 | return this.mediaModel.find({ _id: { $in: ids }, userId }).lean({ virtuals: true }) |
| 44 | } |
| 45 | |
| 46 | // 批量删除素材 |
| 47 | async deleteManyByIds(ids: string[], filter?: FilterQuery<Media>): Promise<boolean> { |
| 48 | const res = await this.mediaModel.deleteMany({ _id: { $in: ids }, ...filter }) |
| 49 | return res.deletedCount > 0 |
| 50 | } |
| 51 | |
| 52 | // 批量删除素材 |
| 53 | async getListByFilter(filter: FilterQuery<Media>) { |
| 54 | const mediaList = await this.mediaModel.find(filter).lean({ virtuals: true }) |
| 55 | return mediaList |
| 56 | } |
| 57 | |
| 58 | // 批量删除素材 |
| 59 | async deleteByFilter(filter: FilterQuery<Media>): Promise<boolean> { |
| 60 | const res = await this.mediaModel.deleteMany(filter) |
| 61 | return res.deletedCount > 0 |
| 62 | } |
| 63 | |
| 64 | // 更新 |
| 65 | async updateInfo(id: string, newData: Partial<Media>): Promise<boolean> { |
| 66 | const res = await this.mediaModel.updateOne({ _id: id }, { $set: newData }) |
| 67 | return res.modifiedCount > 0 |
| 68 | } |
| 69 | |
| 70 | async getInfo(id: string) { |
| 71 | return await this.mediaModel.findOne({ _id: id }).lean({ virtuals: true }) |
| 72 | } |
| 73 | |
| 74 | /** |
| 75 | * 获取指定分组下的媒体 |
| 76 | * @param groupId |
| 77 | * @returns |
| 78 | */ |
| 79 | async getListByGroup(groupId: string) { |
| 80 | return await this.mediaModel.find({ groupId }).lean({ virtuals: true }) |
| 81 | } |
| 82 | |
| 83 | // 获取列表 |
| 84 | async getList(inFilter: { |
| 85 | userId?: string |
| 86 | groupId?: string |
| 87 | materialGroupId?: string |
| 88 | type?: MediaType |
| 89 | userType?: UserType |
| 90 | useCount?: number |
| 91 | }, pageInfo: { |
| 92 | pageNo: number |
| 93 | pageSize: number |
| 94 | }) { |
| 95 | const { pageNo, pageSize } = pageInfo |
| 96 | |
| 97 | const filter: RootFilterQuery<Media> = { |
| 98 | ...(inFilter.userId && { userId: inFilter.userId }), |
| 99 | ...(inFilter.groupId && { groupId: inFilter.groupId }), |
| 100 | ...(inFilter.materialGroupId && { materialGroupId: inFilter.materialGroupId }), |
| 101 | ...(inFilter.userType && { userType: inFilter.userType }), |
| 102 | ...(inFilter.type && { type: inFilter.type }), |
| 103 | ...(inFilter.useCount !== undefined && { useCount: { $gte: inFilter.useCount } }), |
| 104 | } |
| 105 | |
| 106 | const total = await this.mediaModel.countDocuments(filter) |
| 107 | const list = await this.mediaModel |
| 108 | .find(filter) |
| 109 | .sort({ createdAt: -1 }) |
| 110 | .skip((pageNo! - 1) * pageSize) |
| 111 | .limit(pageSize) |
| 112 | .lean({ virtuals: true }) |
| 113 | .exec() |
| 114 | |
| 115 | return { |
| 116 | total, |
| 117 | list, |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | /** |
| 122 | * 检查指定组是否为空(不包含任何媒体文件) |
| 123 | * @param groupId 组ID |
| 124 | * @returns 如果组为空返回true,否则返回false |
| 125 | */ |
| 126 | async getIsEmptyByGroup(groupId: string): Promise<boolean> { |
| 127 | const exists = await this.mediaModel.exists({ groupId }) |
| 128 | return !exists |
| 129 | } |
| 130 | |
| 131 | // 使用次数增加 |
| 132 | async updateUseCountById(id: string): Promise<boolean> { |
| 133 | const res = await this.mediaModel.updateOne({ _id: id }, { $inc: { useCount: 1 } }) |
| 134 | return res.modifiedCount > 0 |
| 135 | } |
| 136 | |
| 137 | async updateManyUseCountByIds(ids: string[], filter?: FilterQuery<Media>): Promise<boolean> { |
| 138 | const idList = ids.map(id => new Types.ObjectId(id)) |
| 139 | const res = await this.mediaModel.updateMany({ _id: { $in: idList }, ...filter }, { $inc: { useCount: 1 } }) |
| 140 | return res.modifiedCount > 0 |
| 141 | } |
| 142 | } |
| 143 |