personalac 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +249 -0
- package/bin/personalac.js +215 -0
- package/dist/agent/context.d.ts +39 -0
- package/dist/agent/context.d.ts.map +1 -0
- package/dist/agent/context.js +163 -0
- package/dist/agent/context.js.map +1 -0
- package/dist/agent/executors.d.ts +40 -0
- package/dist/agent/executors.d.ts.map +1 -0
- package/dist/agent/executors.js +177 -0
- package/dist/agent/executors.js.map +1 -0
- package/dist/agent/index.d.ts +61 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +907 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/planner.d.ts +15 -0
- package/dist/agent/planner.d.ts.map +1 -0
- package/dist/agent/planner.js +81 -0
- package/dist/agent/planner.js.map +1 -0
- package/dist/agent/scheduler.d.ts +22 -0
- package/dist/agent/scheduler.d.ts.map +1 -0
- package/dist/agent/scheduler.js +178 -0
- package/dist/agent/scheduler.js.map +1 -0
- package/dist/database/index.d.ts +5 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +283 -0
- package/dist/database/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +141 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.middleware.d.ts +6 -0
- package/dist/middleware/auth.middleware.d.ts.map +1 -0
- package/dist/middleware/auth.middleware.js +19 -0
- package/dist/middleware/auth.middleware.js.map +1 -0
- package/dist/routes/agent.routes.d.ts +3 -0
- package/dist/routes/agent.routes.d.ts.map +1 -0
- package/dist/routes/agent.routes.js +101 -0
- package/dist/routes/agent.routes.js.map +1 -0
- package/dist/routes/auth.routes.d.ts +3 -0
- package/dist/routes/auth.routes.d.ts.map +1 -0
- package/dist/routes/auth.routes.js +66 -0
- package/dist/routes/auth.routes.js.map +1 -0
- package/dist/routes/chat.routes.d.ts +3 -0
- package/dist/routes/chat.routes.d.ts.map +1 -0
- package/dist/routes/chat.routes.js +80 -0
- package/dist/routes/chat.routes.js.map +1 -0
- package/dist/routes/data.routes.d.ts +3 -0
- package/dist/routes/data.routes.d.ts.map +1 -0
- package/dist/routes/data.routes.js +16 -0
- package/dist/routes/data.routes.js.map +1 -0
- package/dist/routes/email.routes.d.ts +3 -0
- package/dist/routes/email.routes.d.ts.map +1 -0
- package/dist/routes/email.routes.js +18 -0
- package/dist/routes/email.routes.js.map +1 -0
- package/dist/routes/goals.routes.d.ts +3 -0
- package/dist/routes/goals.routes.d.ts.map +1 -0
- package/dist/routes/goals.routes.js +45 -0
- package/dist/routes/goals.routes.js.map +1 -0
- package/dist/routes/plans.routes.d.ts +3 -0
- package/dist/routes/plans.routes.d.ts.map +1 -0
- package/dist/routes/plans.routes.js +19 -0
- package/dist/routes/plans.routes.js.map +1 -0
- package/dist/routes/settings.routes.d.ts +3 -0
- package/dist/routes/settings.routes.d.ts.map +1 -0
- package/dist/routes/settings.routes.js +29 -0
- package/dist/routes/settings.routes.js.map +1 -0
- package/dist/routes/workspace.routes.d.ts +3 -0
- package/dist/routes/workspace.routes.d.ts.map +1 -0
- package/dist/routes/workspace.routes.js +28 -0
- package/dist/routes/workspace.routes.js.map +1 -0
- package/dist/services/auth.service.d.ts +32 -0
- package/dist/services/auth.service.d.ts.map +1 -0
- package/dist/services/auth.service.js +110 -0
- package/dist/services/auth.service.js.map +1 -0
- package/dist/services/data.service.d.ts +47 -0
- package/dist/services/data.service.d.ts.map +1 -0
- package/dist/services/data.service.js +139 -0
- package/dist/services/data.service.js.map +1 -0
- package/dist/services/email.service.d.ts +23 -0
- package/dist/services/email.service.d.ts.map +1 -0
- package/dist/services/email.service.js +316 -0
- package/dist/services/email.service.js.map +1 -0
- package/dist/services/notify.service.d.ts +2 -0
- package/dist/services/notify.service.d.ts.map +1 -0
- package/dist/services/notify.service.js +21 -0
- package/dist/services/notify.service.js.map +1 -0
- package/dist/services/plan.service.d.ts +21 -0
- package/dist/services/plan.service.d.ts.map +1 -0
- package/dist/services/plan.service.js +96 -0
- package/dist/services/plan.service.js.map +1 -0
- package/dist/services/resource.service.d.ts +27 -0
- package/dist/services/resource.service.d.ts.map +1 -0
- package/dist/services/resource.service.js +150 -0
- package/dist/services/resource.service.js.map +1 -0
- package/dist/services/settings.service.d.ts +41 -0
- package/dist/services/settings.service.d.ts.map +1 -0
- package/dist/services/settings.service.js +254 -0
- package/dist/services/settings.service.js.map +1 -0
- package/dist/services/sobriety.service.d.ts +41 -0
- package/dist/services/sobriety.service.d.ts.map +1 -0
- package/dist/services/sobriety.service.js +243 -0
- package/dist/services/sobriety.service.js.map +1 -0
- package/dist/services/workspace.service.d.ts +71 -0
- package/dist/services/workspace.service.d.ts.map +1 -0
- package/dist/services/workspace.service.js +265 -0
- package/dist/services/workspace.service.js.map +1 -0
- package/dist/tools/chat-tools.d.ts +2 -0
- package/dist/tools/chat-tools.d.ts.map +1 -0
- package/dist/tools/chat-tools.js +419 -0
- package/dist/tools/chat-tools.js.map +1 -0
- package/dist/tools/index.d.ts +19 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +27 -0
- package/dist/tools/index.js.map +1 -0
- package/package.json +38 -0
- package/public/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/public/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/public/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/public/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/public/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/public/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/public/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/public/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/public/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/public/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/public/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/public/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/public/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/public/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/public/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/public/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/public/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/public/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/public/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/public/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/public/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/public/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/public/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/public/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/public/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/public/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/public/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/public/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/public/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/public/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/public/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/public/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/public/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/public/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/public/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/public/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/public/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/public/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/public/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/public/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/public/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/public/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/public/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/public/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/public/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/public/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/public/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/public/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/public/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/public/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/public/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/public/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/public/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/public/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/public/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/public/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/public/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/public/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/public/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/public/assets/_baseUniq-DiHtXYsr.js +1 -0
- package/public/assets/arc-Bv1zbXf7.js +1 -0
- package/public/assets/architectureDiagram-Q4EWVU46-EbiUvXBr.js +36 -0
- package/public/assets/blockDiagram-DXYQGD6D-B-4wwQNT.js +132 -0
- package/public/assets/c4Diagram-AHTNJAMY-brLyKMPJ.js +10 -0
- package/public/assets/channel-Me4d6Y1x.js +1 -0
- package/public/assets/chunk-4BX2VUAB-DMh-4Nye.js +1 -0
- package/public/assets/chunk-4TB4RGXK-CSr1z2CQ.js +206 -0
- package/public/assets/chunk-55IACEB6-xN0xmcvD.js +1 -0
- package/public/assets/chunk-EDXVE4YY-CkCM3j5E.js +1 -0
- package/public/assets/chunk-FMBD7UC4-B-mDgsjM.js +15 -0
- package/public/assets/chunk-OYMX7WX6-DK8dg9K4.js +231 -0
- package/public/assets/chunk-QZHKN3VN-BZGbFOdK.js +1 -0
- package/public/assets/chunk-YZCP3GAM-BTmFmMer.js +1 -0
- package/public/assets/classDiagram-6PBFFD2Q-BXgAb5m4.js +1 -0
- package/public/assets/classDiagram-v2-HSJHXN6E-BXgAb5m4.js +1 -0
- package/public/assets/clone-rnECnpTI.js +1 -0
- package/public/assets/cose-bilkent-S5V4N54A-BBqCwo63.js +1 -0
- package/public/assets/cytoscape.esm-BQk4lpUV.js +331 -0
- package/public/assets/dagre-KV5264BT-DLeQYvAA.js +4 -0
- package/public/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/public/assets/diagram-5BDNPKRD-D85z2LaM.js +10 -0
- package/public/assets/diagram-G4DWMVQ6-4AvBmvcP.js +24 -0
- package/public/assets/diagram-MMDJMWI5-DRNEGNZA.js +43 -0
- package/public/assets/diagram-TYMM5635-C_oGwrmX.js +24 -0
- package/public/assets/erDiagram-SMLLAGMA-DDSp8ANa.js +85 -0
- package/public/assets/flowDiagram-DWJPFMVM-B1Wy36da.js +162 -0
- package/public/assets/ganttDiagram-T4ZO3ILL-CQ7VWheo.js +292 -0
- package/public/assets/gitGraphDiagram-UUTBAWPF-BhvM7s41.js +106 -0
- package/public/assets/graph-fatjTp1h.js +1 -0
- package/public/assets/index-1PrEnCZL.js +677 -0
- package/public/assets/index-DcsnItNp.css +1 -0
- package/public/assets/infoDiagram-42DDH7IO-4eawOC2G.js +2 -0
- package/public/assets/init-Gi6I4Gst.js +1 -0
- package/public/assets/ishikawaDiagram-UXIWVN3A-CJWfG1fv.js +70 -0
- package/public/assets/journeyDiagram-VCZTEJTY-C4Zx3dpF.js +139 -0
- package/public/assets/kanban-definition-6JOO6SKY-CV1vDcC8.js +89 -0
- package/public/assets/layout-CX0IDv3q.js +1 -0
- package/public/assets/linear-C8hMcu9f.js +1 -0
- package/public/assets/min-BaxMGW9J.js +1 -0
- package/public/assets/mindmap-definition-QFDTVHPH-KzGyX4Em.js +96 -0
- package/public/assets/ordinal-Cboi1Yqb.js +1 -0
- package/public/assets/pieDiagram-DEJITSTG-Dp2x5kvP.js +30 -0
- package/public/assets/quadrantDiagram-34T5L4WZ-B4yqA6XF.js +7 -0
- package/public/assets/requirementDiagram-MS252O5E-DEjN_2tG.js +84 -0
- package/public/assets/sankeyDiagram-XADWPNL6-BKm_F5FA.js +10 -0
- package/public/assets/sequenceDiagram-FGHM5R23-07BCMKjW.js +157 -0
- package/public/assets/stateDiagram-FHFEXIEX-DVz6GtR8.js +1 -0
- package/public/assets/stateDiagram-v2-QKLJ7IA2-DYiYr0PB.js +1 -0
- package/public/assets/timeline-definition-GMOUNBTQ-C0u67FqY.js +120 -0
- package/public/assets/vennDiagram-DHZGUBPP-BiAlMVLe.js +34 -0
- package/public/assets/wardley-RL74JXVD-BnWyuHzf.js +162 -0
- package/public/assets/wardleyDiagram-NUSXRM2D-DEL2Lx6S.js +20 -0
- package/public/assets/xychartDiagram-5P7HB3ND-ILdmj7ok.js +7 -0
- package/public/index.html +17 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.recordLearning = recordLearning;
|
|
4
|
+
exports.getSummary = getSummary;
|
|
5
|
+
const uuid_1 = require("uuid");
|
|
6
|
+
const database_1 = require("../database");
|
|
7
|
+
const SUPERADMIN_ID = 'superadmin';
|
|
8
|
+
function recordLearning(data) {
|
|
9
|
+
try {
|
|
10
|
+
const db = (0, database_1.getDB)();
|
|
11
|
+
const now = Date.now();
|
|
12
|
+
const sid = data.studentId || SUPERADMIN_ID;
|
|
13
|
+
const recordId = (0, uuid_1.v4)();
|
|
14
|
+
const recordDate = data.recordDate || now;
|
|
15
|
+
db.prepare(`
|
|
16
|
+
INSERT INTO LearningRecord (id, student_id, subject, topic, score, duration_minutes, note, record_date, create_user, update_user, create_time, update_time, delete_flag)
|
|
17
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)
|
|
18
|
+
`).run(recordId, sid, data.subject, data.topic, data.score ?? null, data.durationMinutes ?? 0, data.note ?? null, recordDate, SUPERADMIN_ID, SUPERADMIN_ID, now, now);
|
|
19
|
+
// Update KnowledgePoint weakness score
|
|
20
|
+
updateWeaknessScore(sid, data.subject, data.topic, data.score);
|
|
21
|
+
console.log(`Learning recorded for student ${sid}: ${data.subject}/${data.topic}`);
|
|
22
|
+
// Notify agent
|
|
23
|
+
try {
|
|
24
|
+
const { getAgentEngine } = require('../agent');
|
|
25
|
+
const engine = getAgentEngine();
|
|
26
|
+
if (engine) {
|
|
27
|
+
engine.handleEvent({
|
|
28
|
+
type: 'new_learning_data',
|
|
29
|
+
studentId: sid,
|
|
30
|
+
recordId,
|
|
31
|
+
subject: data.subject,
|
|
32
|
+
topic: data.topic,
|
|
33
|
+
score: data.score
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Agent not ready
|
|
39
|
+
}
|
|
40
|
+
const record = {
|
|
41
|
+
id: recordId,
|
|
42
|
+
student_id: sid,
|
|
43
|
+
subject: data.subject,
|
|
44
|
+
topic: data.topic,
|
|
45
|
+
score: data.score,
|
|
46
|
+
duration_minutes: data.durationMinutes ?? 0,
|
|
47
|
+
note: data.note,
|
|
48
|
+
record_date: recordDate,
|
|
49
|
+
create_time: now
|
|
50
|
+
};
|
|
51
|
+
return { success: true, data: record };
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
55
|
+
console.error('RecordLearning error:', error);
|
|
56
|
+
return { success: false, error };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function updateWeaknessScore(studentId, subject, topic, score) {
|
|
60
|
+
try {
|
|
61
|
+
const db = (0, database_1.getDB)();
|
|
62
|
+
const now = Date.now();
|
|
63
|
+
const existing = db
|
|
64
|
+
.prepare('SELECT id, weakness_score, attempt_count FROM KnowledgePoint WHERE student_id = ? AND subject = ? AND topic = ? AND delete_flag = 0')
|
|
65
|
+
.get(studentId, subject, topic);
|
|
66
|
+
let weaknessAdjustment = 0;
|
|
67
|
+
if (score === undefined) {
|
|
68
|
+
weaknessAdjustment = 0.05;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
const normalizedScore = Math.max(0, Math.min(100, score)) / 100;
|
|
72
|
+
weaknessAdjustment = (0.5 - normalizedScore) * 0.3;
|
|
73
|
+
}
|
|
74
|
+
if (existing) {
|
|
75
|
+
const newWeakness = Math.max(0, Math.min(1, existing.weakness_score + weaknessAdjustment));
|
|
76
|
+
db.prepare(`
|
|
77
|
+
UPDATE KnowledgePoint
|
|
78
|
+
SET weakness_score = ?, attempt_count = ?, last_practiced = ?, update_user = ?, update_time = ?
|
|
79
|
+
WHERE id = ?
|
|
80
|
+
`).run(newWeakness, existing.attempt_count + 1, now, SUPERADMIN_ID, now, existing.id);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const initialWeakness = score === undefined ? 0.5 : Math.max(0, 1 - score / 100);
|
|
84
|
+
db.prepare(`
|
|
85
|
+
INSERT INTO KnowledgePoint (id, student_id, subject, topic, weakness_score, attempt_count, last_practiced, create_user, update_user, create_time, update_time, delete_flag)
|
|
86
|
+
VALUES (?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, 0)
|
|
87
|
+
`).run((0, uuid_1.v4)(), studentId, subject, topic, initialWeakness, now, SUPERADMIN_ID, SUPERADMIN_ID, now, now);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
console.warn('updateWeaknessScore error:', err);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function getSummary(studentId, dateFrom, dateTo, subject) {
|
|
95
|
+
try {
|
|
96
|
+
const db = (0, database_1.getDB)();
|
|
97
|
+
const sid = studentId || SUPERADMIN_ID;
|
|
98
|
+
const subjectFilter = subject ? 'AND subject = ?' : '';
|
|
99
|
+
const subjectParams = subject ? [subject] : [];
|
|
100
|
+
const overall = db
|
|
101
|
+
.prepare(`SELECT COUNT(*) as totalSessions,
|
|
102
|
+
COALESCE(SUM(duration_minutes), 0) as totalMinutes,
|
|
103
|
+
AVG(CASE WHEN score IS NOT NULL THEN score END) as avgScore
|
|
104
|
+
FROM LearningRecord
|
|
105
|
+
WHERE student_id = ? AND record_date >= ? AND record_date <= ? AND delete_flag = 0 ${subjectFilter}`)
|
|
106
|
+
.get(sid, dateFrom, dateTo, ...subjectParams);
|
|
107
|
+
const bySubjectRows = db
|
|
108
|
+
.prepare(`SELECT subject,
|
|
109
|
+
COUNT(*) as sessions,
|
|
110
|
+
COALESCE(SUM(duration_minutes), 0) as totalMinutes,
|
|
111
|
+
AVG(CASE WHEN score IS NOT NULL THEN score END) as avgScore
|
|
112
|
+
FROM LearningRecord
|
|
113
|
+
WHERE student_id = ? AND record_date >= ? AND record_date <= ? AND delete_flag = 0 ${subjectFilter}
|
|
114
|
+
GROUP BY subject
|
|
115
|
+
ORDER BY sessions DESC`)
|
|
116
|
+
.all(sid, dateFrom, dateTo, ...subjectParams);
|
|
117
|
+
const weakPoints = db
|
|
118
|
+
.prepare(`SELECT subject, topic, weakness_score, attempt_count
|
|
119
|
+
FROM KnowledgePoint
|
|
120
|
+
WHERE student_id = ? AND delete_flag = 0 ${subject ? 'AND subject = ?' : ''}
|
|
121
|
+
ORDER BY weakness_score DESC
|
|
122
|
+
LIMIT 10`)
|
|
123
|
+
.all(sid, ...subjectParams);
|
|
124
|
+
const summary = {
|
|
125
|
+
totalSessions: overall.totalSessions,
|
|
126
|
+
totalMinutes: overall.totalMinutes,
|
|
127
|
+
avgScore: overall.avgScore,
|
|
128
|
+
bySubject: bySubjectRows,
|
|
129
|
+
weakPoints
|
|
130
|
+
};
|
|
131
|
+
return { success: true, data: summary };
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
135
|
+
console.error('getSummary error:', error);
|
|
136
|
+
return { success: false, error };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=data.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.service.js","sourceRoot":"","sources":["../../src/services/data.service.ts"],"names":[],"mappings":";;AAmDA,wCAoEC;AA+CD,gCA0EC;AAhPD,+BAAmC;AACnC,0CAAmC;AAEnC,MAAM,aAAa,GAAG,YAAY,CAAA;AAgDlC,SAAgB,cAAc,CAAC,IAAyB;IACtD,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,IAAA,gBAAK,GAAE,CAAA;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,IAAI,aAAa,CAAA;QAE3C,MAAM,QAAQ,GAAG,IAAA,SAAM,GAAE,CAAA;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,GAAG,CAAA;QAEzC,EAAE,CAAC,OAAO,CAAC;;;KAGV,CAAC,CAAC,GAAG,CACJ,QAAQ,EACR,GAAG,EACH,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,KAAK,IAAI,IAAI,EAClB,IAAI,CAAC,eAAe,IAAI,CAAC,EACzB,IAAI,CAAC,IAAI,IAAI,IAAI,EACjB,UAAU,EACV,aAAa,EACb,aAAa,EACb,GAAG,EACH,GAAG,CACJ,CAAA;QAED,uCAAuC;QACvC,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;QAE9D,OAAO,CAAC,GAAG,CAAC,iCAAiC,GAAG,KAAK,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;QAElF,eAAe;QACf,IAAI,CAAC;YACH,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;YAC9C,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;YAC/B,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,WAAW,CAAC;oBACjB,IAAI,EAAE,mBAAmB;oBACzB,SAAS,EAAE,GAAG;oBACd,QAAQ;oBACR,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;iBAClB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;QAED,MAAM,MAAM,GAAmB;YAC7B,EAAE,EAAE,QAAQ;YACZ,UAAU,EAAE,GAAG;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,gBAAgB,EAAE,IAAI,CAAC,eAAe,IAAI,CAAC;YAC3C,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,UAAU;YACvB,WAAW,EAAE,GAAG;SACjB,CAAA;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IACxC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC9D,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAA;QAC7C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IAClC,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAC1B,SAAiB,EACjB,OAAe,EACf,KAAa,EACb,KAAyB;IAEzB,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,IAAA,gBAAK,GAAE,CAAA;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAEtB,MAAM,QAAQ,GAAG,EAAE;aAChB,OAAO,CACN,qIAAqI,CACtI;aACA,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAEnB,CAAA;QAEb,IAAI,kBAAkB,GAAG,CAAC,CAAA;QAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,kBAAkB,GAAG,IAAI,CAAA;QAC3B,CAAC;aAAM,CAAC;YACN,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,GAAG,GAAG,CAAA;YAC/D,kBAAkB,GAAG,CAAC,GAAG,GAAG,eAAe,CAAC,GAAG,GAAG,CAAA;QACpD,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,cAAc,GAAG,kBAAkB,CAAC,CAAC,CAAA;YAC1F,EAAE,CAAC,OAAO,CAAC;;;;OAIV,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,aAAa,GAAG,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAA;QACvF,CAAC;aAAM,CAAC;YACN,MAAM,eAAe,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC,CAAA;YAChF,EAAE,CAAC,OAAO,CAAC;;;OAGV,CAAC,CAAC,GAAG,CAAC,IAAA,SAAM,GAAE,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;QAC3G,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAA;IACjD,CAAC;AACH,CAAC;AAED,SAAgB,UAAU,CACxB,SAAiB,EACjB,QAAgB,EAChB,MAAc,EACd,OAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,IAAA,gBAAK,GAAE,CAAA;QAClB,MAAM,GAAG,GAAG,SAAS,IAAI,aAAa,CAAA;QAEtC,MAAM,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAA;QACtD,MAAM,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAE9C,MAAM,OAAO,GAAG,EAAE;aACf,OAAO,CACN;;;;8FAIsF,aAAa,EAAE,CACtG;aACA,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,aAAa,CAI7C,CAAA;QAED,MAAM,aAAa,GAAG,EAAE;aACrB,OAAO,CACN;;;;;8FAKsF,aAAa;;gCAE3E,CACzB;aACA,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,aAAa,CAK5C,CAAA;QAEF,MAAM,UAAU,GAAG,EAAE;aAClB,OAAO,CACN;;oDAE4C,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE;;kBAElE,CACX;aACA,GAAG,CAAC,GAAG,EAAE,GAAG,aAAa,CAK1B,CAAA;QAEF,MAAM,OAAO,GAAgB;YAC3B,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,SAAS,EAAE,aAAa;YACxB,UAAU;SACX,CAAA;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IACzC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC9D,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAA;QACzC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;IAClC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
interface EmailServiceStatus {
|
|
2
|
+
polling: boolean;
|
|
3
|
+
lastCheck: Date | null;
|
|
4
|
+
error: string | null;
|
|
5
|
+
}
|
|
6
|
+
declare class EmailService {
|
|
7
|
+
private polling;
|
|
8
|
+
private intervalId;
|
|
9
|
+
private lastCheck;
|
|
10
|
+
private lastError;
|
|
11
|
+
init(): Promise<void>;
|
|
12
|
+
startPolling(): void;
|
|
13
|
+
stopPolling(): void;
|
|
14
|
+
checkNewEmails(): Promise<void>;
|
|
15
|
+
private processEmailSource;
|
|
16
|
+
private registerFileIndex;
|
|
17
|
+
private registerResource;
|
|
18
|
+
private notifyAgent;
|
|
19
|
+
getStatus(): EmailServiceStatus;
|
|
20
|
+
}
|
|
21
|
+
export declare const emailService: EmailService;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=email.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.service.d.ts","sourceRoot":"","sources":["../../src/services/email.service.ts"],"names":[],"mappings":"AAMA,UAAU,kBAAkB;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,IAAI,GAAG,IAAI,CAAA;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,cAAM,YAAY;IAChB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,SAAS,CAAsB;IAMjC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAa3B,YAAY,IAAI,IAAI;IAwBpB,WAAW,IAAI,IAAI;IAab,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;YAuFvB,kBAAkB;IAwFhC,OAAO,CAAC,iBAAiB;IAyCzB,OAAO,CAAC,gBAAgB;IAkDxB,OAAO,CAAC,WAAW;IAqBnB,SAAS,IAAI,kBAAkB;CAOhC;AAED,eAAO,MAAM,YAAY,cAAqB,CAAA"}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.emailService = void 0;
|
|
40
|
+
const path_1 = __importDefault(require("path"));
|
|
41
|
+
const fs_1 = __importDefault(require("fs"));
|
|
42
|
+
const uuid_1 = require("uuid");
|
|
43
|
+
const database_1 = require("../database");
|
|
44
|
+
const settings_service_1 = require("./settings.service");
|
|
45
|
+
class EmailService {
|
|
46
|
+
constructor() {
|
|
47
|
+
this.polling = false;
|
|
48
|
+
this.intervalId = null;
|
|
49
|
+
this.lastCheck = null;
|
|
50
|
+
this.lastError = null;
|
|
51
|
+
}
|
|
52
|
+
// -------------------------------------------------------------------------
|
|
53
|
+
// init — read config and verify connectivity (called once on startup)
|
|
54
|
+
// -------------------------------------------------------------------------
|
|
55
|
+
async init() {
|
|
56
|
+
const config = (0, settings_service_1.getRawEmailConfig)();
|
|
57
|
+
if (!config) {
|
|
58
|
+
console.log('EmailService: no config found, skipping init');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
console.log(`EmailService initialized for ${config.email}`);
|
|
62
|
+
}
|
|
63
|
+
// -------------------------------------------------------------------------
|
|
64
|
+
// startPolling — check every 5 minutes
|
|
65
|
+
// -------------------------------------------------------------------------
|
|
66
|
+
startPolling() {
|
|
67
|
+
if (this.polling) {
|
|
68
|
+
console.log('EmailService: already polling');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
this.polling = true;
|
|
72
|
+
console.log('EmailService: starting polling (every 5 minutes)');
|
|
73
|
+
// Run immediately
|
|
74
|
+
this.checkNewEmails().catch((err) => {
|
|
75
|
+
console.error('EmailService: initial check failed:', err);
|
|
76
|
+
});
|
|
77
|
+
this.intervalId = setInterval(() => {
|
|
78
|
+
this.checkNewEmails().catch((err) => {
|
|
79
|
+
console.error('EmailService: scheduled check failed:', err);
|
|
80
|
+
});
|
|
81
|
+
}, 5 * 60 * 1000);
|
|
82
|
+
}
|
|
83
|
+
// -------------------------------------------------------------------------
|
|
84
|
+
// stopPolling
|
|
85
|
+
// -------------------------------------------------------------------------
|
|
86
|
+
stopPolling() {
|
|
87
|
+
if (this.intervalId !== null) {
|
|
88
|
+
clearInterval(this.intervalId);
|
|
89
|
+
this.intervalId = null;
|
|
90
|
+
}
|
|
91
|
+
this.polling = false;
|
|
92
|
+
console.log('EmailService: polling stopped');
|
|
93
|
+
}
|
|
94
|
+
// -------------------------------------------------------------------------
|
|
95
|
+
// checkNewEmails — connect via IMAP, fetch unread, save attachments
|
|
96
|
+
// -------------------------------------------------------------------------
|
|
97
|
+
async checkNewEmails() {
|
|
98
|
+
const config = (0, settings_service_1.getRawEmailConfig)();
|
|
99
|
+
if (!config) {
|
|
100
|
+
this.lastError = '邮件未配置';
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
let client = null;
|
|
104
|
+
try {
|
|
105
|
+
const { ImapFlow } = await Promise.resolve().then(() => __importStar(require('imapflow')));
|
|
106
|
+
client = new ImapFlow({
|
|
107
|
+
host: config.imapHost,
|
|
108
|
+
port: config.imapPort,
|
|
109
|
+
secure: config.imapPort === 993,
|
|
110
|
+
auth: { user: config.email, pass: config.authCode },
|
|
111
|
+
logger: false
|
|
112
|
+
});
|
|
113
|
+
await client.connect();
|
|
114
|
+
console.log('EmailService: connected to IMAP');
|
|
115
|
+
const lock = await client.getMailboxLock('INBOX');
|
|
116
|
+
try {
|
|
117
|
+
// Search for unseen messages
|
|
118
|
+
const seenUids = [];
|
|
119
|
+
for await (const message of client.fetch('1:*', {
|
|
120
|
+
flags: true,
|
|
121
|
+
envelope: true,
|
|
122
|
+
bodyStructure: true,
|
|
123
|
+
source: true
|
|
124
|
+
})) {
|
|
125
|
+
// Only process unseen
|
|
126
|
+
if (message.flags?.has('\\Seen'))
|
|
127
|
+
continue;
|
|
128
|
+
const uid = message.uid;
|
|
129
|
+
const envelope = message.envelope;
|
|
130
|
+
const senderEmail = envelope?.from?.[0]?.address || envelope?.sender?.[0]?.address || 'unknown';
|
|
131
|
+
const subject = envelope?.subject || '(无主题)';
|
|
132
|
+
console.log(`EmailService: processing message uid=${uid} from=${senderEmail} subject=${subject}`);
|
|
133
|
+
// Parse body and attachments from source
|
|
134
|
+
const source = message.source;
|
|
135
|
+
if (source) {
|
|
136
|
+
await this.processEmailSource(source, senderEmail, subject);
|
|
137
|
+
}
|
|
138
|
+
seenUids.push(uid);
|
|
139
|
+
}
|
|
140
|
+
// Mark processed emails as read
|
|
141
|
+
if (seenUids.length > 0) {
|
|
142
|
+
for (const uid of seenUids) {
|
|
143
|
+
await client.messageFlagsAdd({ uid }, ['\\Seen']);
|
|
144
|
+
}
|
|
145
|
+
console.log(`EmailService: marked ${seenUids.length} emails as read`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
lock.release();
|
|
150
|
+
}
|
|
151
|
+
await client.logout();
|
|
152
|
+
this.lastCheck = new Date();
|
|
153
|
+
this.lastError = null;
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
157
|
+
this.lastError = error;
|
|
158
|
+
console.error('EmailService: checkNewEmails error:', error);
|
|
159
|
+
try {
|
|
160
|
+
await client?.logout();
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// ignore logout error
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// -------------------------------------------------------------------------
|
|
168
|
+
// processEmailSource — parse raw email, extract text and attachments
|
|
169
|
+
// -------------------------------------------------------------------------
|
|
170
|
+
async processEmailSource(source, senderEmail, subject) {
|
|
171
|
+
try {
|
|
172
|
+
// Use mailparser for parsing if available, otherwise do basic text extraction
|
|
173
|
+
let plainText = '';
|
|
174
|
+
const attachments = [];
|
|
175
|
+
try {
|
|
176
|
+
const { simpleParser } = await Promise.resolve().then(() => __importStar(require('mailparser')));
|
|
177
|
+
const parsed = await simpleParser(source);
|
|
178
|
+
plainText = parsed.text || (typeof parsed.html === 'string' ? parsed.html.replace(/<[^>]+>/g, ' ') : '') || '';
|
|
179
|
+
if (parsed.attachments) {
|
|
180
|
+
for (const att of parsed.attachments) {
|
|
181
|
+
if (att.content && att.filename) {
|
|
182
|
+
attachments.push({
|
|
183
|
+
filename: att.filename,
|
|
184
|
+
content: att.content,
|
|
185
|
+
contentType: att.contentType || 'application/octet-stream'
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// mailparser not available, do basic extraction
|
|
193
|
+
plainText = source.toString('utf-8').slice(0, 5000);
|
|
194
|
+
}
|
|
195
|
+
// Save attachments to workspace
|
|
196
|
+
const workspaceRoot = path_1.default.join(process.env.DATA_DIR || path_1.default.join(process.cwd(), 'data'), 'workspace');
|
|
197
|
+
const uploadDir = path_1.default.join(workspaceRoot, 'uploads', 'email');
|
|
198
|
+
if (!fs_1.default.existsSync(uploadDir)) {
|
|
199
|
+
fs_1.default.mkdirSync(uploadDir, { recursive: true });
|
|
200
|
+
}
|
|
201
|
+
for (const att of attachments) {
|
|
202
|
+
const timestamp = Date.now();
|
|
203
|
+
const safeFilename = att.filename.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
204
|
+
const savedFilename = `${timestamp}_${safeFilename}`;
|
|
205
|
+
const savedPath = path_1.default.join(uploadDir, savedFilename);
|
|
206
|
+
const relativePath = `uploads/email/${savedFilename}`;
|
|
207
|
+
fs_1.default.writeFileSync(savedPath, att.content);
|
|
208
|
+
console.log(`EmailService: saved attachment ${savedFilename}`);
|
|
209
|
+
const ext = path_1.default.extname(att.filename).replace('.', '').toLowerCase();
|
|
210
|
+
// Register in FileIndex
|
|
211
|
+
this.registerFileIndex({
|
|
212
|
+
filePath: savedPath,
|
|
213
|
+
fileName: att.filename,
|
|
214
|
+
fileType: ext || 'bin',
|
|
215
|
+
fileSize: att.content.length,
|
|
216
|
+
category: 'uploads',
|
|
217
|
+
sourceEmail: senderEmail,
|
|
218
|
+
description: `来自邮件: ${subject}`
|
|
219
|
+
});
|
|
220
|
+
// Register in Resource table
|
|
221
|
+
this.registerResource({
|
|
222
|
+
filePath: savedPath,
|
|
223
|
+
fileName: att.filename,
|
|
224
|
+
fileType: ext || 'bin',
|
|
225
|
+
fileSize: att.content.length,
|
|
226
|
+
sourceEmail: senderEmail,
|
|
227
|
+
parsedText: plainText.slice(0, 10000)
|
|
228
|
+
});
|
|
229
|
+
// Notify agent
|
|
230
|
+
this.notifyAgent(senderEmail, att.filename, relativePath);
|
|
231
|
+
}
|
|
232
|
+
// If there are no attachments but there is text content, still notify agent
|
|
233
|
+
if (attachments.length === 0 && plainText.trim().length > 0) {
|
|
234
|
+
console.log(`EmailService: email from ${senderEmail} has no attachments, text only`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
console.error('EmailService: processEmailSource error:', err);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// -------------------------------------------------------------------------
|
|
242
|
+
// registerFileIndex — writes a record to FileIndex table
|
|
243
|
+
// -------------------------------------------------------------------------
|
|
244
|
+
registerFileIndex(params) {
|
|
245
|
+
try {
|
|
246
|
+
const db = (0, database_1.getDB)();
|
|
247
|
+
const now = new Date().toISOString();
|
|
248
|
+
db.prepare(`
|
|
249
|
+
INSERT INTO FileIndex
|
|
250
|
+
(file_path, file_name, file_type, file_size, category, student_id, source_email, description, tags, created_at, create_time, update_time, delete_flag)
|
|
251
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)
|
|
252
|
+
`).run(params.filePath, params.fileName, params.fileType, params.fileSize, params.category, params.studentId || null, params.sourceEmail || null, params.description || null, params.tags ? JSON.stringify(params.tags) : null, now, now, now);
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
console.error('EmailService: registerFileIndex error:', err);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// -------------------------------------------------------------------------
|
|
259
|
+
// registerResource — writes a record to Resource table
|
|
260
|
+
// -------------------------------------------------------------------------
|
|
261
|
+
registerResource(params) {
|
|
262
|
+
try {
|
|
263
|
+
const db = (0, database_1.getDB)();
|
|
264
|
+
const now = Date.now();
|
|
265
|
+
// Use a system/admin uploader id — find the admin user
|
|
266
|
+
const admin = db
|
|
267
|
+
.prepare("SELECT id FROM User WHERE role = 'admin' AND delete_flag = 0 LIMIT 1")
|
|
268
|
+
.get();
|
|
269
|
+
if (!admin) {
|
|
270
|
+
console.warn('EmailService: no admin user found, cannot register resource');
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const resourceId = (0, uuid_1.v4)();
|
|
274
|
+
db.prepare(`
|
|
275
|
+
INSERT INTO Resource
|
|
276
|
+
(id, uploader_id, file_name, file_path, file_type, file_size, source_email, parsed_text, create_user, update_user, create_time, update_time, delete_flag)
|
|
277
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)
|
|
278
|
+
`).run(resourceId, admin.id, params.fileName, params.filePath, params.fileType, params.fileSize, params.sourceEmail, params.parsedText || null, admin.id, admin.id, now, now);
|
|
279
|
+
}
|
|
280
|
+
catch (err) {
|
|
281
|
+
console.error('EmailService: registerResource error:', err);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// -------------------------------------------------------------------------
|
|
285
|
+
// notifyAgent — triggers agent new_resource event
|
|
286
|
+
// -------------------------------------------------------------------------
|
|
287
|
+
notifyAgent(senderEmail, fileName, relativePath) {
|
|
288
|
+
try {
|
|
289
|
+
const { getAgentEngine } = require('../agent');
|
|
290
|
+
const engine = getAgentEngine();
|
|
291
|
+
if (engine) {
|
|
292
|
+
engine.handleEvent({
|
|
293
|
+
type: 'new_resource',
|
|
294
|
+
sourceEmail: senderEmail,
|
|
295
|
+
fileName,
|
|
296
|
+
relativePath
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch (err) {
|
|
301
|
+
console.warn('EmailService: failed to notify agent:', err);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
// -------------------------------------------------------------------------
|
|
305
|
+
// getStatus
|
|
306
|
+
// -------------------------------------------------------------------------
|
|
307
|
+
getStatus() {
|
|
308
|
+
return {
|
|
309
|
+
polling: this.polling,
|
|
310
|
+
lastCheck: this.lastCheck,
|
|
311
|
+
error: this.lastError
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
exports.emailService = new EmailService();
|
|
316
|
+
//# sourceMappingURL=email.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.service.js","sourceRoot":"","sources":["../../src/services/email.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify.service.d.ts","sourceRoot":"","sources":["../../src/services/notify.service.ts"],"names":[],"mappings":"AAIA,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sendMessage = sendMessage;
|
|
4
|
+
const uuid_1 = require("uuid");
|
|
5
|
+
const database_1 = require("../database");
|
|
6
|
+
// 1.3 无 bot,消息记录到 MessageLog 表,后续可扩展 WebSocket 推送
|
|
7
|
+
async function sendMessage(userId, content) {
|
|
8
|
+
try {
|
|
9
|
+
const db = (0, database_1.getDB)();
|
|
10
|
+
const now = Date.now();
|
|
11
|
+
db.prepare(`
|
|
12
|
+
INSERT INTO MessageLog (id, user_id, direction, message_type, content, status, create_time, update_time, delete_flag)
|
|
13
|
+
VALUES (?, ?, 'outbound', 'text', ?, 'sent', ?, ?, 0)
|
|
14
|
+
`).run((0, uuid_1.v4)(), userId, content, now, now);
|
|
15
|
+
console.log(`[Notify] → ${userId}: ${content.slice(0, 60)}...`);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
console.error('[Notify] sendMessage error:', err);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=notify.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notify.service.js","sourceRoot":"","sources":["../../src/services/notify.service.ts"],"names":[],"mappings":";;AAIA,kCAYC;AAhBD,+BAAmC;AACnC,0CAAmC;AAEnC,kDAAkD;AAC3C,KAAK,UAAU,WAAW,CAAC,MAAc,EAAE,OAAe;IAC/D,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,IAAA,gBAAK,GAAE,CAAA;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,EAAE,CAAC,OAAO,CAAC;;;KAGV,CAAC,CAAC,GAAG,CAAC,IAAA,SAAM,GAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;QAC3C,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAA;IACjE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAA;IACnD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface Plan {
|
|
2
|
+
id: string;
|
|
3
|
+
student_id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
description: string;
|
|
6
|
+
subjects: string[];
|
|
7
|
+
status: 'active' | 'archived';
|
|
8
|
+
create_time: number;
|
|
9
|
+
update_time: number;
|
|
10
|
+
}
|
|
11
|
+
export interface PlanResult {
|
|
12
|
+
success: boolean;
|
|
13
|
+
data?: Plan | Plan[] | {
|
|
14
|
+
message: string;
|
|
15
|
+
};
|
|
16
|
+
error?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function create(studentId: string, title: string, description: string, subjects: string[]): PlanResult;
|
|
19
|
+
export declare function getActive(studentId: string): PlanResult;
|
|
20
|
+
export declare function listPlans(studentId: string): PlanResult;
|
|
21
|
+
//# sourceMappingURL=plan.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.service.d.ts","sourceRoot":"","sources":["../../src/services/plan.service.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,MAAM,CACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAAE,GACjB,UAAU,CAkDZ;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAqCvD;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CA+BvD"}
|