返回 AiToEarn
account-group.service.ts
根目录 / project / aitoearn-backend / apps / aitoearn-server / src / core / channels / accounts / account-group.service.ts
1 import type { AccountGroup } from '@yikart/mongodb'
2 import { Injectable } from '@nestjs/common'
3 import { AppException, ResponseCode } from '@yikart/common'
4 import { AccountGroupRepository, AccountRepository, Transactional } from '@yikart/mongodb'
5 import { ChannelAccountGroupCreateDto, ChannelAccountGroupUpdateDto } from './account-group.dto'
6
7 @Injectable()
8 export class AccountGroupService {
9 constructor(
10 private readonly accountRepository: AccountRepository,
11 private readonly accountGroupRepository: AccountGroupRepository,
12 ) {}
13
14 async create(userId: string, data: ChannelAccountGroupCreateDto): Promise<AccountGroup> {
15 return this.accountGroupRepository.createAccountGroup({
16 ...data,
17 userId,
18 })
19 }
20
21 async update(userId: string, groupId: string, data: ChannelAccountGroupUpdateDto): Promise<AccountGroup> {
22 const group = await this.getOwnedGroup(userId, groupId)
23 const updated = await this.accountGroupRepository.updateAccountGroup(group.id, data)
24 if (!updated) {
25 throw new AppException(ResponseCode.AccountGroupNotFound)
26 }
27 return { ...group, ...data }
28 }
29
30 @Transactional()
31 async deleteMany(userId: string, groupIds: string[]): Promise<boolean> {
32 const groups = await this.accountGroupRepository.getAccountGorupListByIds(groupIds, userId)
33 const defaultGroup = await this.accountGroupRepository.getDefaultGroup(userId)
34 if (groups.some(group => group.isDefault || group.id === defaultGroup.id)) {
35 throw new AppException(ResponseCode.AccountGroupNotFound, {
36 reasonCode: 'default_group_delete_not_allowed',
37 })
38 }
39 for (const group of groups) {
40 await this.accountRepository.updateManyToDefaultGroup(userId, group.id, defaultGroup.id)
41 }
42 return this.accountGroupRepository.deleteAccountGroup(groupIds, userId)
43 }
44
45 async list(userId: string): Promise<AccountGroup[]> {
46 const groups = await this.accountGroupRepository.getAccountGroup(userId)
47 return groups
48 .sort((a, b) => (a.rank ?? 0) - (b.rank ?? 0))
49 }
50
51 @Transactional()
52 async sortAccounts(userId: string, groupId: string, list: { id: string, rank: number }[]): Promise<boolean> {
53 await this.getOwnedGroup(userId, groupId)
54 const ids = list.map(item => item.id)
55 if (new Set(ids).size !== ids.length) {
56 throw new AppException(ResponseCode.ValidationFailed)
57 }
58
59 const accounts = await this.accountRepository.listByUserIdAndIds(userId, ids)
60 const accountMap = new Map(accounts.map(account => [account.id, account]))
61 for (const id of ids) {
62 const account = accountMap.get(id)
63 if (!account || account.groupId !== groupId) {
64 throw new AppException(ResponseCode.AccountNotFound)
65 }
66 }
67
68 const updated = await this.accountRepository.updateManyRankByIds(userId, groupId, list)
69 if (!updated) {
70 throw new AppException(ResponseCode.AccountNotFound)
71 }
72 return true
73 }
74
75 async findOneById(id: string) {
76 return this.accountGroupRepository.getById(id)
77 }
78
79 async getDefaultGroup(userId: string): Promise<AccountGroup> {
80 return this.accountGroupRepository.getDefaultGroup(userId)
81 }
82
83 async getAccountGroup(userId: string): Promise<AccountGroup[]> {
84 return this.accountGroupRepository.getAccountGroup(userId)
85 }
86
87 async sortRank(userId: string, list: { id: string, rank: number }[]): Promise<boolean> {
88 return this.accountGroupRepository.sortRank(userId, list)
89 }
90
91 async getAccountGroupByName(userId: string, name: string): Promise<AccountGroup[]> {
92 return this.accountGroupRepository.getAccountGroupByName(userId, name)
93 }
94
95 private async getOwnedGroup(userId: string, groupId: string): Promise<AccountGroup> {
96 const groups = await this.accountGroupRepository.getAccountGorupListByIds([groupId], userId)
97 const group = groups[0]
98 if (!group) {
99 throw new AppException(ResponseCode.AccountGroupNotFound)
100 }
101 return group
102 }
103 }
104
104 lines TYPESCRIPT