collabdocchat 2.4.4 → 2.4.5
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/package.json +2 -2
- package/scripts/add-button-hover.js +2 -0
- package/scripts/add-missing-braces.js +27 -0
- package/scripts/add-missing-functions.js +2 -0
- package/scripts/add-more-features.js +2 -0
- package/scripts/add-user-functions.js +2 -0
- package/scripts/auto-publish.js +2 -0
- package/scripts/beautify-buttons.js +2 -0
- package/scripts/beautify-ui.js +2 -0
- package/scripts/check-brackets.js +50 -0
- package/scripts/check-encoding.js +2 -0
- package/scripts/check-syntax.js +2 -0
- package/scripts/delete-orphan-block.js +27 -0
- package/scripts/find-buttons.js +2 -0
- package/scripts/find-duplicate.js +2 -0
- package/scripts/find-extra-brace.js +63 -0
- package/scripts/find-sidebar-buttons.js +2 -0
- package/scripts/fix-file-end.js +46 -0
- package/scripts/fix-help.js +2 -0
- package/scripts/fix-issues-step1.js +2 -0
- package/scripts/fix-issues-step2.js +2 -0
- package/scripts/fix-issues-step3.js +2 -0
- package/scripts/fix-issues-step4.js +2 -0
- package/scripts/fix-optimized-views.js +2 -0
- package/scripts/fix-settings.js +2 -0
- package/scripts/fix-syntax-error.js +38 -0
- package/scripts/fix-workflow.js +2 -0
- package/scripts/refactor-step1.js +2 -0
- package/scripts/refactor-step2.js +2 -0
- package/scripts/refactor-step3.js +2 -0
- package/scripts/refactor-step4.js +2 -0
- package/scripts/refactor-step5.js +2 -0
- package/scripts/refactor-step6.js +2 -0
- package/scripts/refactor-step7.js +2 -0
- package/scripts/remove-orphan-code.js +57 -0
- package/scripts/update-port-user.js +2 -0
- package/scripts/update-port.js +2 -0
- package/server/index.js +4 -0
- package/server/index.js.bak +97 -0
- package/server/models/Document.js +5 -0
- package/server/models/KnowledgeBase.js +259 -254
- package/server/models/Poll.js +97 -0
- package/server/routes/ai.js +391 -327
- package/server/routes/audit.js +61 -0
- package/server/routes/documents.js +74 -5
- package/server/routes/export.js +171 -10
- package/server/routes/files.js +27 -4
- package/server/routes/knowledge.js +31 -22
- package/server/routes/messages.js +142 -0
- package/server/routes/polls.js +241 -0
- package/server/routes/tasks.js +1 -0
- package/server/routes/workflows.js +27 -0
- package/server/utils/auditLogger.js +268 -238
- package/src/pages/admin-dashboard.js +1431 -335
- package/src/pages/admin-dashboard.js.audit-optimize.bak +4134 -0
- package/src/pages/admin-dashboard.js.bak +4041 -0
- package/src/pages/admin-dashboard.js.broken.bak +4099 -0
- package/src/pages/admin-dashboard.js.comprehensive.bak +4099 -0
- package/src/pages/admin-dashboard.js.escape.bak +4099 -0
- package/src/pages/admin-dashboard.js.final-final-fix.bak +4099 -0
- package/src/pages/admin-dashboard.js.final-fix.bak +4099 -0
- package/src/pages/admin-dashboard.js.final.bak +4099 -0
- package/src/pages/admin-dashboard.js.indent-fix.bak +4099 -0
- package/src/pages/admin-dashboard.js.last-fix.bak +4099 -0
- package/src/pages/admin-dashboard.js.line595-fix.bak +4099 -0
- package/src/pages/admin-dashboard.js.pre-manual-fix.bak +4099 -0
- package/src/pages/admin-dashboard.js.syntax.bak +4099 -0
- package/src/pages/admin-dashboard.js.test.bak +4099 -0
- package/src/pages/optimized-task-detail-original.js +838 -0
- package/src/pages/optimized-task-detail.js +324 -22
- package/src/pages/optimized-task-detail.js.bak +1162 -0
- package/src/pages/poll-detail-enhanced.js +394 -0
- package/src/pages/update-poll-display.js +380 -0
- package/src/pages/user-dashboard.js +1860 -1006
- package/src/services/api.js +326 -265
- package/src/services/auth.js +54 -54
- package/src/services/websocket.js +88 -80
- package/src/pages/simplified-workflows.js +0 -652
- package/src/utils/ai-assistant.js +0 -1384
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "collabdocchat",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.5",
|
|
4
4
|
"description": "开源的实时协作文档聊天平台 - 集成任务管理、多人文档编辑、智能点名功能",
|
|
5
5
|
"main": "./server/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -91,4 +91,4 @@
|
|
|
91
91
|
"open": "^11.0.0",
|
|
92
92
|
"vite": "^5.0.8"
|
|
93
93
|
}
|
|
94
|
-
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
|
|
8
|
+
const filePath = path.join(__dirname, '../src/pages/admin-dashboard.js');
|
|
9
|
+
|
|
10
|
+
console.log('添加缺失的闭合括号...');
|
|
11
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
12
|
+
|
|
13
|
+
// 在文件末尾添加缺失的 }
|
|
14
|
+
content = content.trimEnd();
|
|
15
|
+
if (!content.endsWith('}')) {
|
|
16
|
+
content += '\n}\n';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 再添加一个
|
|
20
|
+
content += '\n';
|
|
21
|
+
|
|
22
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
23
|
+
|
|
24
|
+
console.log('✅ 已添加缺失的闭合括号');
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
package/scripts/auto-publish.js
CHANGED
package/scripts/beautify-ui.js
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
|
|
8
|
+
const filePath = path.join(__dirname, '../src/pages/admin-dashboard.js');
|
|
9
|
+
|
|
10
|
+
console.log('检查 JavaScript 语法...');
|
|
11
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
12
|
+
|
|
13
|
+
// 检查括号匹配
|
|
14
|
+
let braceCount = 0;
|
|
15
|
+
let parenCount = 0;
|
|
16
|
+
let bracketCount = 0;
|
|
17
|
+
const lines = content.split('\n');
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i < lines.length; i++) {
|
|
20
|
+
const line = lines[i];
|
|
21
|
+
|
|
22
|
+
// 跳过注释和字符串
|
|
23
|
+
const cleanLine = line.replace(/\/\/.*$/, '').replace(/'[^']*'/g, '').replace(/"[^"]*"/g, '').replace(/`[^`]*`/g, '');
|
|
24
|
+
|
|
25
|
+
for (const char of cleanLine) {
|
|
26
|
+
if (char === '{') braceCount++;
|
|
27
|
+
if (char === '}') braceCount--;
|
|
28
|
+
if (char === '(') parenCount++;
|
|
29
|
+
if (char === ')') parenCount--;
|
|
30
|
+
if (char === '[') bracketCount++;
|
|
31
|
+
if (char === ']') bracketCount--;
|
|
32
|
+
|
|
33
|
+
if (braceCount < 0 || parenCount < 0 || bracketCount < 0) {
|
|
34
|
+
console.log(`\n❌ 第 ${i + 1} 行发现不匹配的括号:`);
|
|
35
|
+
console.log(` ${line.trim()}`);
|
|
36
|
+
console.log(` 大括号: ${braceCount}, 圆括号: ${parenCount}, 方括号: ${bracketCount}`);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (braceCount < 0 || parenCount < 0 || bracketCount < 0) break;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.log(`\n最终统计:`);
|
|
45
|
+
console.log(`大括号 {}: ${braceCount > 0 ? '缺少 ' + braceCount + ' 个 }' : braceCount < 0 ? '多了 ' + Math.abs(braceCount) + ' 个 }' : '匹配'}`);
|
|
46
|
+
console.log(`圆括号 (): ${parenCount > 0 ? '缺少 ' + parenCount + ' 个 )' : parenCount < 0 ? '多了 ' + Math.abs(parenCount) + ' 个 )' : '匹配'}`);
|
|
47
|
+
console.log(`方括号 []: ${bracketCount > 0 ? '缺少 ' + bracketCount + ' 个 ]' : bracketCount < 0 ? '多了 ' + Math.abs(bracketCount) + ' 个 ]' : '匹配'}`);
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
package/scripts/check-syntax.js
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
|
|
8
|
+
const filePath = path.join(__dirname, '../src/pages/admin-dashboard.js');
|
|
9
|
+
|
|
10
|
+
console.log('删除第 1339-1531 行的孤立代码...');
|
|
11
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
12
|
+
const lines = content.split('\n');
|
|
13
|
+
|
|
14
|
+
// 删除第 1339 行(索引 1338)到第 1531 行(索引 1530)之前的内容
|
|
15
|
+
const newLines = [
|
|
16
|
+
...lines.slice(0, 1338), // 保留前 1338 行
|
|
17
|
+
'', // 保留空行
|
|
18
|
+
...lines.slice(1531) // 从第 1532 行开始保留
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
content = newLines.join('\n');
|
|
22
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
23
|
+
|
|
24
|
+
console.log('✅ 已删除 ' + (1531 - 1338) + ' 行孤立代码');
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
package/scripts/find-buttons.js
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
|
|
8
|
+
const filePath = path.join(__dirname, '../src/pages/admin-dashboard.js');
|
|
9
|
+
|
|
10
|
+
console.log('查找多余的大括号...');
|
|
11
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
12
|
+
const lines = content.split('\n');
|
|
13
|
+
|
|
14
|
+
let braceCount = 0;
|
|
15
|
+
let functionStack = [];
|
|
16
|
+
|
|
17
|
+
for (let i = 0; i < lines.length; i++) {
|
|
18
|
+
const line = lines[i];
|
|
19
|
+
const trimmed = line.trim();
|
|
20
|
+
|
|
21
|
+
// 检测函数定义
|
|
22
|
+
if (trimmed.match(/(?:async\s+)?function\s+\w+|(?:const|let|var)\s+\w+\s*=\s*(?:async\s+)?\(/)) {
|
|
23
|
+
const match = trimmed.match(/function\s+(\w+)|(?:const|let|var)\s+(\w+)/);
|
|
24
|
+
if (match) {
|
|
25
|
+
functionStack.push({ name: match[1] || match[2], line: i + 1, braceCount });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 计算括号
|
|
30
|
+
for (const char of line) {
|
|
31
|
+
if (char === '{') braceCount++;
|
|
32
|
+
if (char === '}') {
|
|
33
|
+
braceCount--;
|
|
34
|
+
if (braceCount < 0) {
|
|
35
|
+
console.log(`\n❌ 第 ${i + 1} 行有多余的 }:`);
|
|
36
|
+
console.log(` ${line.trim()}`);
|
|
37
|
+
console.log(`\n当前函数栈:`);
|
|
38
|
+
functionStack.forEach(f => console.log(` - ${f.name} (第 ${f.line} 行)`));
|
|
39
|
+
process.exit(0);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 检测函数结束
|
|
45
|
+
if (trimmed === '}' && functionStack.length > 0) {
|
|
46
|
+
const lastFunc = functionStack[functionStack.length - 1];
|
|
47
|
+
if (braceCount <= lastFunc.braceCount) {
|
|
48
|
+
functionStack.pop();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
console.log(`\n最终大括号计数: ${braceCount}`);
|
|
54
|
+
if (braceCount > 0) {
|
|
55
|
+
console.log(`\n❌ 缺少 ${braceCount} 个 }`);
|
|
56
|
+
console.log(`\n未闭合的函数:`);
|
|
57
|
+
functionStack.forEach(f => console.log(` - ${f.name} (第 ${f.line} 行)`));
|
|
58
|
+
} else if (braceCount < 0) {
|
|
59
|
+
console.log(`\n❌ 多了 ${Math.abs(braceCount)} 个 }`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
|
|
8
|
+
const filePath = path.join(__dirname, '../src/pages/admin-dashboard.js');
|
|
9
|
+
|
|
10
|
+
console.log('修复文件末尾的括号...');
|
|
11
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
12
|
+
|
|
13
|
+
// 移除文件末尾的空行
|
|
14
|
+
content = content.trimEnd();
|
|
15
|
+
|
|
16
|
+
// 检查最后几行
|
|
17
|
+
const lines = content.split('\n');
|
|
18
|
+
const lastLine = lines[lines.length - 1].trim();
|
|
19
|
+
|
|
20
|
+
console.log('最后一行:', lastLine);
|
|
21
|
+
|
|
22
|
+
// 如果最后一行是 },我们需要确保有正确数量的闭合括号
|
|
23
|
+
// 根据之前的分析,renderAdminDashboard 函数没有闭合
|
|
24
|
+
// renderView('groups'); 后面应该有一个 } 来闭合 renderAdminDashboard
|
|
25
|
+
|
|
26
|
+
// 替换文件末尾
|
|
27
|
+
if (content.includes("renderView('groups');")) {
|
|
28
|
+
// 找到 renderView('groups'); 的位置
|
|
29
|
+
const renderViewIndex = content.lastIndexOf("renderView('groups');");
|
|
30
|
+
const beforeRenderView = content.substring(0, renderViewIndex);
|
|
31
|
+
const afterRenderView = content.substring(renderViewIndex);
|
|
32
|
+
|
|
33
|
+
// 确保 renderView 后面有正确的闭合
|
|
34
|
+
const newEnding = `renderView('groups');
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
content = beforeRenderView + newEnding;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
42
|
+
|
|
43
|
+
console.log('✅ 文件末尾已修复');
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
package/scripts/fix-help.js
CHANGED
package/scripts/fix-settings.js
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
|
|
8
|
+
const filePath = path.join(__dirname, '../src/pages/admin-dashboard.js');
|
|
9
|
+
|
|
10
|
+
console.log('修复语法错误...');
|
|
11
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
12
|
+
|
|
13
|
+
// 删除孤立的 aiInputText 相关代码
|
|
14
|
+
const linesToRemove = [
|
|
15
|
+
` const input = document.getElementById('aiInputText');`,
|
|
16
|
+
` if (input) {`,
|
|
17
|
+
` input.addEventListener('keypress', (e) => {`,
|
|
18
|
+
` if (e.key === 'Enter' && !e.shiftKey) {`,
|
|
19
|
+
` e.preventDefault();`,
|
|
20
|
+
` document.getElementById('aiSendBtn').click();`,
|
|
21
|
+
` }`,
|
|
22
|
+
` });`,
|
|
23
|
+
` }`
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
linesToRemove.forEach(line => {
|
|
27
|
+
content = content.replace(line, '');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// 删除多余的空行
|
|
31
|
+
content = content.replace(/\n\n\n+/g, '\n\n');
|
|
32
|
+
|
|
33
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
34
|
+
|
|
35
|
+
console.log('✅ 语法错误已修复');
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
package/scripts/fix-workflow.js
CHANGED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
|
|
8
|
+
const filePath = path.join(__dirname, '../src/pages/admin-dashboard.js');
|
|
9
|
+
|
|
10
|
+
console.log('删除孤立的旧代码...');
|
|
11
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
12
|
+
const lines = content.split('\n');
|
|
13
|
+
|
|
14
|
+
// 找到并删除从第 1339 行开始的孤立代码块
|
|
15
|
+
// 这些代码在快捷问题按钮的 forEach 之后,但没有被包含在任何函数中
|
|
16
|
+
let newLines = [];
|
|
17
|
+
let skipMode = false;
|
|
18
|
+
let skipStart = 0;
|
|
19
|
+
|
|
20
|
+
for (let i = 0; i < lines.length; i++) {
|
|
21
|
+
const line = lines[i];
|
|
22
|
+
const trimmed = line.trim();
|
|
23
|
+
|
|
24
|
+
// 检测孤立代码的开始(第 1338 行之后)
|
|
25
|
+
if (i === 1338 && trimmed === '') {
|
|
26
|
+
// 检查下一行是否是孤立的代码
|
|
27
|
+
if (i + 1 < lines.length && lines[i + 1].trim().startsWith('const question')) {
|
|
28
|
+
skipMode = true;
|
|
29
|
+
skipStart = i + 1;
|
|
30
|
+
newLines.push(line); // 保留空行
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 如果在跳过模式,查找代码块的结束
|
|
36
|
+
if (skipMode) {
|
|
37
|
+
// 查找 renderCallView 函数的开始
|
|
38
|
+
if (trimmed.startsWith('async function renderCallView')) {
|
|
39
|
+
skipMode = false;
|
|
40
|
+
console.log(`✅ 删除了第 ${skipStart + 1} 到 ${i} 行的孤立代码`);
|
|
41
|
+
newLines.push(line);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
// 跳过这一行
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
newLines.push(line);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
content = newLines.join('\n');
|
|
52
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
53
|
+
|
|
54
|
+
console.log('✅ 孤立代码已删除');
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
package/scripts/update-port.js
CHANGED
package/server/index.js
CHANGED
|
@@ -16,6 +16,8 @@ import knowledgeRoutes from './routes/knowledge.js';
|
|
|
16
16
|
import workflowRoutes from './routes/workflows.js';
|
|
17
17
|
import exportRoutes from './routes/export.js';
|
|
18
18
|
import backupRoutes from './routes/backup.js';
|
|
19
|
+
import pollRoutes from './routes/polls.js';
|
|
20
|
+
import messageRoutes from './routes/messages.js';
|
|
19
21
|
import { setupWebSocket } from './websocket/index.js';
|
|
20
22
|
import { initDefaultAdmin } from './utils/initAdmin.js';
|
|
21
23
|
import { errorHandler, notFoundHandler } from './middleware/errorHandler.js';
|
|
@@ -61,6 +63,8 @@ app.use('/api/knowledge', knowledgeRoutes);
|
|
|
61
63
|
app.use('/api/workflows', workflowRoutes);
|
|
62
64
|
app.use('/api/export', exportRoutes);
|
|
63
65
|
app.use('/api/backup', backupRoutes);
|
|
66
|
+
app.use('/api/polls', pollRoutes);
|
|
67
|
+
app.use('/api/messages', messageRoutes);
|
|
64
68
|
|
|
65
69
|
// WebSocket 设置
|
|
66
70
|
setupWebSocket(wss);
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { createServer } from 'http';
|
|
3
|
+
import { WebSocketServer } from 'ws';
|
|
4
|
+
import cors from 'cors';
|
|
5
|
+
import dotenv from 'dotenv';
|
|
6
|
+
import mongoose from 'mongoose';
|
|
7
|
+
import authRoutes from './routes/auth.js';
|
|
8
|
+
import taskRoutes from './routes/tasks.js';
|
|
9
|
+
import documentRoutes from './routes/documents.js';
|
|
10
|
+
import groupRoutes from './routes/groups.js';
|
|
11
|
+
import auditRoutes from './routes/audit.js';
|
|
12
|
+
import fileRoutes from './routes/files.js';
|
|
13
|
+
import chunkedUploadRoutes from './routes/chunked-upload.js';
|
|
14
|
+
import aiRoutes from './routes/ai.js';
|
|
15
|
+
import knowledgeRoutes from './routes/knowledge.js';
|
|
16
|
+
import workflowRoutes from './routes/workflows.js';
|
|
17
|
+
import exportRoutes from './routes/export.js';
|
|
18
|
+
import backupRoutes from './routes/backup.js';
|
|
19
|
+
import pollRoutes from './routes/polls.js';
|
|
20
|
+
import { setupWebSocket } from './websocket/index.js';
|
|
21
|
+
import { initDefaultAdmin } from './utils/initAdmin.js';
|
|
22
|
+
import { errorHandler, notFoundHandler } from './middleware/errorHandler.js';
|
|
23
|
+
import backupService from './utils/backup.js';
|
|
24
|
+
|
|
25
|
+
dotenv.config();
|
|
26
|
+
|
|
27
|
+
const app = express();
|
|
28
|
+
const server = createServer(app);
|
|
29
|
+
const wss = new WebSocketServer({ server });
|
|
30
|
+
|
|
31
|
+
// 中间件
|
|
32
|
+
app.use(cors({
|
|
33
|
+
origin: ['http://localhost:5173', 'http://localhost:5174'],
|
|
34
|
+
credentials: true
|
|
35
|
+
}));
|
|
36
|
+
app.use(express.json());
|
|
37
|
+
|
|
38
|
+
// 数据库连接
|
|
39
|
+
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/collabdocchat')
|
|
40
|
+
.then(async () => {
|
|
41
|
+
console.log('✅ MongoDB 连接成功');
|
|
42
|
+
// 初始化默认管理员账户
|
|
43
|
+
await initDefaultAdmin();
|
|
44
|
+
// 初始化自动备份
|
|
45
|
+
backupService.initAutoBackup();
|
|
46
|
+
})
|
|
47
|
+
.catch(err => console.error('❌ MongoDB 连接失败:', err));
|
|
48
|
+
|
|
49
|
+
// 静态文件服务(用于文件下载)
|
|
50
|
+
app.use('/uploads', express.static('uploads'));
|
|
51
|
+
|
|
52
|
+
// API 路由
|
|
53
|
+
app.use('/api/auth', authRoutes);
|
|
54
|
+
app.use('/api/tasks', taskRoutes);
|
|
55
|
+
app.use('/api/documents', documentRoutes);
|
|
56
|
+
app.use('/api/groups', groupRoutes);
|
|
57
|
+
app.use('/api/audit', auditRoutes);
|
|
58
|
+
app.use('/api/files', fileRoutes);
|
|
59
|
+
app.use('/api/files/chunked', chunkedUploadRoutes);
|
|
60
|
+
app.use('/api/ai', aiRoutes);
|
|
61
|
+
app.use('/api/knowledge', knowledgeRoutes);
|
|
62
|
+
app.use('/api/workflows', workflowRoutes);
|
|
63
|
+
app.use('/api/export', exportRoutes);
|
|
64
|
+
app.use('/api/backup', backupRoutes);
|
|
65
|
+
app.use('/api/polls', pollRoutes);
|
|
66
|
+
|
|
67
|
+
// WebSocket 设置
|
|
68
|
+
setupWebSocket(wss);
|
|
69
|
+
|
|
70
|
+
// 健康检查
|
|
71
|
+
app.get('/health', (req, res) => {
|
|
72
|
+
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// 404 处理
|
|
76
|
+
app.use(notFoundHandler);
|
|
77
|
+
|
|
78
|
+
// 错误处理中间件(必须在所有路由之后)
|
|
79
|
+
app.use(errorHandler);
|
|
80
|
+
|
|
81
|
+
const PORT = process.env.PORT || 8765;
|
|
82
|
+
server.listen(PORT, () => {
|
|
83
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
84
|
+
console.log(`🚀 CollabDocChat 服务器启动成功!`);
|
|
85
|
+
console.log(`${'='.repeat(60)}`);
|
|
86
|
+
console.log(`📍 服务器地址: http://localhost:${PORT}`);
|
|
87
|
+
console.log(`🔌 WebSocket: ws://localhost:${PORT}`);
|
|
88
|
+
console.log(`\n✅ 已启用功能:`);
|
|
89
|
+
console.log(` - 错误处理中间件`);
|
|
90
|
+
console.log(` - 分片上传功能`);
|
|
91
|
+
console.log(` - AI助手API`);
|
|
92
|
+
console.log(` - 知识库系统`);
|
|
93
|
+
console.log(` - 工作流引擎`);
|
|
94
|
+
console.log(` - 数据导出功能`);
|
|
95
|
+
console.log(` - 自动备份系统`);
|
|
96
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
97
|
+
});
|
|
@@ -25,6 +25,11 @@ const documentSchema = new mongoose.Schema({
|
|
|
25
25
|
enum: ['readonly', 'editable'],
|
|
26
26
|
default: 'editable'
|
|
27
27
|
},
|
|
28
|
+
// 可编辑成员列表(共享文档功能)
|
|
29
|
+
editableMembers: [{
|
|
30
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
31
|
+
ref: 'User'
|
|
32
|
+
}],
|
|
28
33
|
editors: [{
|
|
29
34
|
user: {
|
|
30
35
|
type: mongoose.Schema.Types.ObjectId,
|