返回 AiToEarn
service.ts
1 /*
2 * @Author: nevin
3 * @Date: 2025-01-24 17:10:35
4 * @LastEditors: nevin
5 * @Description: autoRun AutoRun
6 */
7 import { Injectable } from '../core/decorators';
8 import {
9 AutoRunModel,
10 AutoRunStatus,
11 AutoRunType,
12 } from '../../db/models/autoRun';
13 import {
14 AutoRunRecordModel,
15 AutoRunRecordStatus,
16 } from '../../db/models/autoRunRecord';
17 import { FindOptionsWhere, MoreThan, Not, Repository } from 'typeorm';
18 import { AppDataSource } from '../../db';
19 import windowOperate from '../../util/windowOperate';
20 import { SendChannelEnum } from '../../../commont/UtilsEnum';
21 import { hasTriggered, parseCycleType } from './comment';
22
23 @Injectable()
24 export class AutoRunService {
25 private autoRunRepository: Repository<AutoRunModel>;
26 private autoRunRecordRepository: Repository<AutoRunRecordModel>;
27
28 constructor() {
29 this.autoRunRepository = AppDataSource.getRepository(AutoRunModel);
30 this.autoRunRecordRepository =
31 AppDataSource.getRepository(AutoRunRecordModel);
32 }
33
34 // 限制处于启动状态的任务数量
35 private async chectAutoRunCount(userId: string): Promise<boolean> {
36 const count = await this.autoRunRepository.count({
37 where: {
38 userId,
39 status: AutoRunStatus.DOING,
40 },
41 });
42
43 if (count >= 100) return false;
44
45 return true;
46 }
47
48 // 创建进程
49 async createAutoRun(info: Partial<AutoRunModel>, data: Record<string, any>) {
50 if (!(await this.chectAutoRunCount(data.userId!))) return null;
51
52 info.data = JSON.stringify(data);
53 return await this.autoRunRepository.save(info);
54 }
55
56 // 根据ID查询进程信息
57 async findAutoRunById(id: number) {
58 const info = await this.autoRunRepository.findOne({
59 where: {
60 id,
61 },
62 });
63
64 if (info) info.dataInfo = JSON.parse(info.data);
65
66 return info;
67 }
68
69 // 查询进程列表
70 async findAutoRunList(
71 pageInfo: {
72 page: number;
73 pageSize: number;
74 },
75 query: {
76 type?: AutoRunType;
77 status?: AutoRunStatus;
78 cycleType?: string;
79 accountId?: number;
80 dataId?: string;
81 },
82 ): Promise<{
83 list: AutoRunModel[];
84 total: number;
85 }> {
86 const { page, pageSize } = pageInfo;
87 const whereClause: FindOptionsWhere<AutoRunModel> = {
88 status: Not(AutoRunStatus.DELETE),
89 ...(query.type !== undefined && { type: query.type }),
90 ...(query.status !== undefined && { status: query.status }),
91 ...(query.cycleType !== undefined && { cycleType: query.cycleType }),
92 ...(query.accountId !== undefined && { accountId: query.accountId }),
93 ...(query.dataId !== undefined && { dataId: query.dataId }),
94 };
95
96 const list = await this.autoRunRepository.find({
97 where: whereClause,
98 skip: (page - 1) * pageSize,
99 take: pageSize,
100 });
101
102 const total = await this.autoRunRepository.count({
103 where: whereClause,
104 });
105
106 return {
107 list,
108 total,
109 };
110 }
111
112 // 查询需要运行的进程列表
113 async findAutoRunListOfNeedRun(userId: string) {
114 return await this.autoRunRepository.find({
115 where: {
116 userId,
117 status: AutoRunStatus.DOING,
118 },
119 });
120 }
121
122 // 更新进程状态
123 async updateAutoRunStatus(id: number, status: AutoRunStatus) {
124 return await this.autoRunRepository.update(id, {
125 status,
126 });
127 }
128
129 // 创建进程记录
130 async createAutoRunRecord(autoRun: AutoRunModel) {
131 const data = {
132 autoRunId: autoRun.id,
133 userId: autoRun.userId,
134 type: autoRun.type,
135 cycleType: autoRun.cycleType,
136 status: AutoRunRecordStatus.DOING,
137 };
138 return await this.autoRunRecordRepository.save(data);
139 }
140
141 // 查询进程记录列表
142 async findAutoRunRecordList(
143 pageInfo: {
144 page: number;
145 pageSize: number;
146 },
147 query: {
148 autoRunId: number;
149 type?: AutoRunType;
150 status?: AutoRunRecordStatus;
151 cycleType?: string;
152 },
153 ) {
154 const { page, pageSize } = pageInfo;
155 const whereClause: FindOptionsWhere<AutoRunRecordModel> = {
156 ...(query.autoRunId !== undefined && { autoRunId: query.autoRunId }),
157 ...(query.type !== undefined && { type: query.type }),
158 ...(query.status !== undefined && { status: query.status }),
159 ...(query.cycleType !== undefined && { cycleType: query.cycleType }),
160 };
161
162 const list = await this.autoRunRecordRepository.find({
163 where: whereClause,
164 skip: (page - 1) * pageSize,
165 take: pageSize,
166 });
167
168 const total = await this.autoRunRecordRepository.count({
169 where: whereClause,
170 });
171
172 return {
173 list,
174 total,
175 };
176 }
177
178 // 更新进程记录状态
179 async updateAutoRunRecordStatus(id: number, status: AutoRunRecordStatus) {
180 return await this.autoRunRecordRepository.update(id, {
181 status,
182 });
183 }
184
185 // 发送自动任务进度通知
186 async sendAutoRunProgress(id: number, status: -1 | 0 | 1 | 2, error?: any) {
187 const autoRunInfo = await this.findAutoRunById(id);
188 if (!autoRunInfo) return;
189
190 windowOperate.sendRenderMsg(
191 SendChannelEnum.AutoRun,
192 status,
193 autoRunInfo,
194 error,
195 );
196 }
197
198 // 查找周期内的最近一条记录
199 async findLastAutoRunRecord(
200 autoRun: AutoRunModel,
201 cycleType: 'day' | 'week' | 'month',
202 ) {
203 const where: FindOptionsWhere<AutoRunRecordModel> = {
204 autoRunId: autoRun.id,
205 };
206
207 if (cycleType === 'day') {
208 where.createTime = MoreThan(new Date(new Date().setHours(0, 0, 0, 0)));
209 } else if (cycleType === 'week') {
210 where.createTime = MoreThan(
211 new Date(new Date().setDate(new Date().getDate() - 7)),
212 );
213 } else if (cycleType === 'month') {
214 where.createTime = MoreThan(
215 new Date(new Date().setDate(new Date().getDate() - 30)),
216 );
217 }
218
219 const lastRecord = await this.autoRunRecordRepository.findOne({
220 where,
221 order: {
222 createTime: 'DESC',
223 },
224 });
225
226 return lastRecord;
227 }
228
229 // 判断是否需要触发运行
230 async isNeedAutoRunToRun(autoRun: AutoRunModel): Promise<boolean> {
231 const { cycleType } = autoRun;
232
233 const isHasTriggered = hasTriggered(cycleType);
234 if (!isHasTriggered) return false;
235
236 const { type } = parseCycleType(cycleType);
237 if (!type) return false;
238
239 const record = await this.findLastAutoRunRecord(autoRun, type);
240
241 return !record;
242 }
243 }
244
244 lines TYPESCRIPT