diff --git a/WATCHDOG.yml b/WATCHDOG.yml new file mode 100644 index 0000000..a641236 --- /dev/null +++ b/WATCHDOG.yml @@ -0,0 +1,3 @@ +advisors: + - name: default + model: deepseek/deepseek-v4-flash:xhigh diff --git a/apps/admin/src/pages/Classrooms/index.tsx b/apps/admin/src/pages/Classrooms/index.tsx index 515ebf7..bd8485c 100644 --- a/apps/admin/src/pages/Classrooms/index.tsx +++ b/apps/admin/src/pages/Classrooms/index.tsx @@ -226,29 +226,27 @@ const ClassroomsPage: React.FC = () => { > 添加教室 - - { - const formData = new FormData(); - formData.append('file', file); - try { - const res: any = await api.post('/classrooms/import', formData, { - headers: { 'Content-Type': 'multipart/form-data' }, - }); - message.success(res.message); - onSuccess?.(res); - fetchData(); - } catch (e: any) { - message.error(e?.message || '导入失败'); - onError?.(e); - } - }} - > - - - + { + const formData = new FormData(); + formData.append('file', file); + try { + const res: any = await api.post('/classrooms/import', formData, { + headers: { 'Content-Type': 'multipart/form-data' }, + }); + message.success(res.message); + onSuccess?.(res); + fetchData(); + } catch (e: any) { + message.error(e?.message || '导入失败'); + onError?.(e); + } + }} + > + + } diff --git a/apps/admin/src/pages/Expenses/index.tsx b/apps/admin/src/pages/Expenses/index.tsx index 849c63f..1bce84b 100644 --- a/apps/admin/src/pages/Expenses/index.tsx +++ b/apps/admin/src/pages/Expenses/index.tsx @@ -349,37 +349,35 @@ const ExpensesPage: React.FC = () => { onChange={(v) => setRoomTypeFilter(v)} options={expenseTypeOptions} /> - - { - const formData = new FormData(); - formData.append('file', file); - try { - const res: any = await api.post('/expenses/utility/import', formData, { - headers: { 'Content-Type': 'multipart/form-data' }, + { + const formData = new FormData(); + formData.append('file', file); + try { + const res: any = await api.post('/expenses/utility/import', formData, { + headers: { 'Content-Type': 'multipart/form-data' }, + }); + if (res.errors?.length > 0) { + Modal.warning({ + title: res.message, + content: res.errors.join('\n'), + width: 500, }); - if (res.errors?.length > 0) { - Modal.warning({ - title: res.message, - content: res.errors.join('\n'), - width: 500, - }); - } else { - message.success(res.message); - } - onSuccess?.(res); - fetchData(); - } catch (e: any) { - message.error(e?.message || '导入失败'); - onError?.(e); + } else { + message.success(res.message); } - }} - > - - - + onSuccess?.(res); + fetchData(); + } catch (e: any) { + message.error(e?.message || '导入失败'); + onError?.(e); + } + }} + > + + } @@ -484,29 +482,27 @@ const ExpensesPage: React.FC = () => { onChange={(v) => setPersonalTypeFilter(v)} options={personalExpenseTypeOptions} /> - - { - try { - const formData = new FormData(); - formData.append('file', file); - const res: any = await api.post('/expenses/personal/import', formData); - message.success(res.message || '导入完成'); - if (res.errors?.length) - res.errors.forEach((e: string) => message.warning(e)); - fetchData(); - onSuccess?.(res); - } catch (e: any) { - message.error(e?.message || '导入失败'); - onError?.(e); - } - }} - > - - - + { + try { + const formData = new FormData(); + formData.append('file', file); + const res: any = await api.post('/expenses/personal/import', formData); + message.success(res.message || '导入完成'); + if (res.errors?.length) + res.errors.forEach((e: string) => message.warning(e)); + fetchData(); + onSuccess?.(res); + } catch (e: any) { + message.error(e?.message || '导入失败'); + onError?.(e); + } + }} + > + + } diff --git a/apps/admin/src/pages/Occupancies/index.tsx b/apps/admin/src/pages/Occupancies/index.tsx index 9e9bb42..6bbd2c9 100644 --- a/apps/admin/src/pages/Occupancies/index.tsx +++ b/apps/admin/src/pages/Occupancies/index.tsx @@ -287,48 +287,46 @@ const OccupanciesPage: React.FC = () => { > 入住登记 - - { - const formData = new FormData(); - formData.append('file', file); - const params = new URLSearchParams(); - if (autoDeposit) { - params.set('autoDeposit', 'true'); - params.set('depositAmount', String(depositAmount)); + { + const formData = new FormData(); + formData.append('file', file); + const params = new URLSearchParams(); + if (autoDeposit) { + params.set('autoDeposit', 'true'); + params.set('depositAmount', String(depositAmount)); + } + try { + const res: any = await api.post( + `/occupancies/import?${params.toString()}`, + formData, + { headers: { 'Content-Type': 'multipart/form-data' } }, + ); + if (res.errors?.length > 0) { + Modal.warning({ + title: res.message, + content: res.errors.join('\n'), + width: 500, + }); + } else { + message.success(res.message); } - try { - const res: any = await api.post( - `/occupancies/import?${params.toString()}`, - formData, - { headers: { 'Content-Type': 'multipart/form-data' } }, - ); - if (res.errors?.length > 0) { - Modal.warning({ - title: res.message, - content: res.errors.join('\n'), - width: 500, - }); - } else { - message.success(res.message); - } - onSuccess?.(res); - fetchData(); - } catch (e: any) { - message.error(e?.message || '导入失败'); - onError?.(e); - } - }} - > - - - - - + onSuccess?.(res); + fetchData(); + } catch (e: any) { + message.error(e?.message || '导入失败'); + onError?.(e); + } + }} + > + + + + } diff --git a/apps/admin/src/pages/Rooms/index.tsx b/apps/admin/src/pages/Rooms/index.tsx index 30ba5af..e35a3c0 100644 --- a/apps/admin/src/pages/Rooms/index.tsx +++ b/apps/admin/src/pages/Rooms/index.tsx @@ -330,27 +330,25 @@ const RoomsPage: React.FC = () => { > 添加宿舍 - - { - try { - const res: any = await api.post('/rooms/import', formData, { - headers: { 'Content-Type': 'multipart/form-data' }, - }); - message.success(res.message); - onSuccess?.(res); - fetchData(); - } catch (e: any) { - message.error(e?.message || '导入失败'); - onError?.(e); - } - }} - > - - - + { + try { + const res: any = await api.post('/rooms/import', formData, { + headers: { 'Content-Type': 'multipart/form-data' }, + }); + message.success(res.message); + onSuccess?.(res); + fetchData(); + } catch (e: any) { + message.error(e?.message || '导入失败'); + onError?.(e); + } + }} + > + + } diff --git a/apps/admin/src/pages/Students/index.tsx b/apps/admin/src/pages/Students/index.tsx index f7fb748..8d84422 100644 --- a/apps/admin/src/pages/Students/index.tsx +++ b/apps/admin/src/pages/Students/index.tsx @@ -275,29 +275,27 @@ const StudentsPage: React.FC = () => { > 添加学生 - - { - const formData = new FormData(); - formData.append('file', file); - try { - const res: any = await api.post('/students/import', formData, { - headers: { 'Content-Type': 'multipart/form-data' }, - }); - message.success(res.message); - onSuccess?.(res); - fetchData(); - } catch (e: any) { - message.error(e?.message || '导入失败'); - onError?.(e); - } - }} - > - - - + { + const formData = new FormData(); + formData.append('file', file); + try { + const res: any = await api.post('/students/import', formData, { + headers: { 'Content-Type': 'multipart/form-data' }, + }); + message.success(res.message); + onSuccess?.(res); + fetchData(); + } catch (e: any) { + message.error(e?.message || '导入失败'); + onError?.(e); + } + }} + > + + } diff --git a/package-lock.json b/package-lock.json index e2542f0..f0d8509 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,6 +54,7 @@ "@nestjs/jwt": "^11.0.2", "@nestjs/passport": "^11.0.5", "@nestjs/platform-express": "^11.1.19", + "@nestjs/schedule": "^6.1.3", "@nestjs/throttler": "^6.5.0", "@nestjs/typeorm": "^11.0.1", "@types/multer": "^2.1.0", @@ -3086,6 +3087,19 @@ "node": ">= 0.6" } }, + "node_modules/@nestjs/schedule": { + "version": "6.1.3", + "resolved": "https://registry.npmmirror.com/@nestjs/schedule/-/schedule-6.1.3.tgz", + "integrity": "sha512-RflMFOpR16Dwd1jAUbeB4mfGTCh65fvEdL4mSjQPJChpkRGRjIXjb+6YQcK2faQrVT60c9DmLmoVR7/ONCtuYQ==", + "license": "MIT", + "dependencies": { + "cron": "4.4.0" + }, + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "@nestjs/core": "^10.0.0 || ^11.0.0" + } + }, "node_modules/@nestjs/schematics": { "version": "11.1.0", "resolved": "https://registry.npmmirror.com/@nestjs/schematics/-/schematics-11.1.0.tgz", @@ -3605,9 +3619,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3625,9 +3636,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3645,9 +3653,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3665,9 +3670,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3685,9 +3687,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3705,9 +3704,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3725,9 +3721,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3745,9 +3738,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3952,9 +3942,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3972,9 +3959,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3992,9 +3976,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4012,9 +3993,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4032,9 +4010,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -4052,9 +4027,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4072,9 +4044,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4092,9 +4061,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5010,9 +4976,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5030,9 +4993,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5050,9 +5010,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5070,9 +5027,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5090,9 +5044,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5110,9 +5061,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5622,6 +5570,12 @@ "@types/node": "*" } }, + "node_modules/@types/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmmirror.com/@types/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-gW+Oib+vUtGJBtNC8V9Reww0oIpusw+4m81uncg9REGZAJfqOQHfo/nkabnc7w0QReXyPqjrbWMJk6NuAkiX3Q==", + "license": "MIT" + }, "node_modules/@types/methods": { "version": "1.1.4", "resolved": "https://registry.npmmirror.com/@types/methods/-/methods-1.1.4.tgz", @@ -6210,9 +6164,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6227,9 +6178,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -6244,9 +6192,6 @@ "loong64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6261,9 +6206,6 @@ "loong64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -6278,9 +6220,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6295,9 +6234,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6312,9 +6248,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -6329,9 +6262,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6346,9 +6276,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -6363,9 +6290,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -8205,6 +8129,23 @@ "devOptional": true, "license": "MIT" }, + "node_modules/cron": { + "version": "4.4.0", + "resolved": "https://registry.npmmirror.com/cron/-/cron-4.4.0.tgz", + "integrity": "sha512-fkdfq+b+AHI4cKdhZlppHveI/mgz2qpiYxcm+t5E5TsxX7QrLS1VE0+7GENEk9z0EeGPcpSciGv6ez24duWhwQ==", + "license": "MIT", + "dependencies": { + "@types/luxon": "~3.7.0", + "luxon": "~3.7.0" + }, + "engines": { + "node": ">=18.x" + }, + "funding": { + "type": "ko-fi", + "url": "https://ko-fi.com/intcreator" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -11791,9 +11732,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11815,9 +11753,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11839,9 +11774,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -11863,9 +11795,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -12190,6 +12119,15 @@ "url": "https://github.com/sponsors/wellwelwel" } }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmmirror.com/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/magic-string": { "version": "0.30.17", "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz",