| | |
| | | taskServiceDepartment: TaskServiceDepartment; |
| | | |
| | | async execute() { |
| | | // 捞出所有待处理任务 |
| | | |
| | | const pendingSiteJobs = await this.reportJoblogEntity.find({ |
| | | where: { |
| | | status: In(['INIT', 'FAILED']), |
| | | jobName: In(['SITE_DAILY', 'DEPT_DAILY']), |
| | | }, |
| | | order: { |
| | | dataDate: 'ASC', // 先算历史,后算今天 |
| | | // 确保在同一天内,SITE_DAILY 先跑,DEPT_DAILY 后跑 |
| | | // 在 JS 数组中我们可以进一步控制排序,或者由业务逻辑严格控制依赖 |
| | | }, |
| | | where: { status: In(['INIT', 'FAILED']), jobName: In(['SITE_DAILY', 'DEPT_DAILY']) }, |
| | | order: { dataDate: 'ASC' }, |
| | | }); |
| | | // 显式排序:同日期内 SITE_DAILY 必须排在 DEPT_DAILY 前面 |
| | | pendingSiteJobs.sort((a, b) => { |
| | | const d = String(a.dataDate).localeCompare(String(b.dataDate)); |
| | | if (d !== 0) return d; |
| | | return a.jobName === 'SITE_DAILY' ? -1 : 1; |
| | | }); |
| | | |
| | | for (const job of pendingSiteJobs) { |
| | | // 严格依赖检查:如果是部门日表任务,必须确保同天的站点日表任务已经是 SUCCESS |
| | |
| | | |
| | | } catch (error) { |
| | | // 失败:记录堆栈,等待下一小时重试 |
| | | |
| | | var errorMessage = ''; |
| | | let errorMessage = ''; |
| | | if (error instanceof Error) { |
| | | errorMessage = error.stack ?? error.message; |
| | | } |
| | | if (typeof error === 'string') { |
| | | console.error('[JOB-FAILED]', job.jobName, job.dataDate, error?.message ?? error); |
| | | console.error(error.stack); |
| | | } else if (typeof error === 'string') { |
| | | errorMessage = error; |
| | | } |
| | | try { |
| | | errorMessage = JSON.stringify(error); |
| | | } catch { |
| | | errorMessage = String(error); |
| | | } |
| | | |
| | | } else { |
| | | try { errorMessage = JSON.stringify(error); } |
| | | catch { errorMessage = String(error); } |
| | | } |
| | | await this.reportJoblogEntity.update(job.id, { |
| | | status: 'FAILED', |
| | | endTime: new Date(), |