collabdocchat 2.4.4 → 2.4.6
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/bin/cli.js +1 -1
- package/package.json +4 -2
- package/scripts/cleanup-scripts.js +140 -0
- package/scripts/fix-startup-issues.js +136 -0
- package/scripts/start-app.js +11 -5
- package/scripts/start-simple.js +96 -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/scripts/add-button-hover.js +0 -56
- package/scripts/add-missing-functions.js +0 -66
- package/scripts/add-more-features.js +0 -427
- package/scripts/add-user-functions.js +0 -201
- package/scripts/auto-publish.js +0 -63
- package/scripts/beautify-buttons.js +0 -45
- package/scripts/beautify-ui.js +0 -267
- package/scripts/check-encoding.js +0 -41
- package/scripts/check-syntax.js +0 -54
- package/scripts/find-buttons.js +0 -20
- package/scripts/find-duplicate.js +0 -35
- package/scripts/find-sidebar-buttons.js +0 -21
- package/scripts/fix-help.js +0 -274
- package/scripts/fix-issues-step1.js +0 -73
- package/scripts/fix-issues-step2.js +0 -93
- package/scripts/fix-issues-step3.js +0 -155
- package/scripts/fix-issues-step4.js +0 -150
- package/scripts/fix-optimized-views.js +0 -37
- package/scripts/fix-ports.js +0 -77
- package/scripts/fix-settings.js +0 -258
- package/scripts/fix-user-dashboard.js +0 -62
- package/scripts/fix-workflow.js +0 -110
- package/scripts/refactor-step1.js +0 -32
- package/scripts/refactor-step2.js +0 -255
- package/scripts/refactor-step3.js +0 -137
- package/scripts/refactor-step4.js +0 -183
- package/scripts/refactor-step5.js +0 -181
- package/scripts/refactor-step6.js +0 -254
- package/scripts/refactor-step7.js +0 -291
- package/scripts/remove-bom.js +0 -69
- package/scripts/remove-quill-from-user-dashboard.js +0 -49
- package/scripts/remove-quill-imports-only.js +0 -32
- package/scripts/update-port-user.js +0 -21
- package/scripts/update-port.js +0 -22
- package/src/pages/simplified-workflows.js +0 -652
- package/src/utils/ai-assistant.js +0 -1384
package/bin/cli.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "collabdocchat",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.6",
|
|
4
4
|
"description": "开源的实时协作文档聊天平台 - 集成任务管理、多人文档编辑、智能点名功能",
|
|
5
5
|
"main": "./server/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"postinstall": "node scripts/postinstall.js",
|
|
58
58
|
"dev": "concurrently \"npm run server\" \"npm run client\" \"npm run open-browser\"",
|
|
59
59
|
"start": "node scripts/start-app.js",
|
|
60
|
+
"start:simple": "node scripts/start-simple.js",
|
|
60
61
|
"quick-start": "node scripts/quick-start.js",
|
|
61
62
|
"stop": "node scripts/stop-app.js",
|
|
62
63
|
"server": "nodemon server/index.js",
|
|
@@ -65,6 +66,7 @@
|
|
|
65
66
|
"build": "vite build",
|
|
66
67
|
"preview": "vite preview",
|
|
67
68
|
"serve": "node server/index.js",
|
|
69
|
+
"fix": "node scripts/fix-startup-issues.js",
|
|
68
70
|
"prepack": "node scripts/pre-publish-check.js",
|
|
69
71
|
"prepublishOnly": "node scripts/pre-publish-check.js"
|
|
70
72
|
},
|
|
@@ -91,4 +93,4 @@
|
|
|
91
93
|
"open": "^11.0.0",
|
|
92
94
|
"vite": "^5.0.8"
|
|
93
95
|
}
|
|
94
|
-
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 清理不需要的开发脚本
|
|
5
|
+
* 保留生产环境必需的脚本
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { unlinkSync, existsSync } from 'fs';
|
|
9
|
+
import { join, dirname } from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = dirname(__filename);
|
|
14
|
+
const scriptsDir = __dirname;
|
|
15
|
+
|
|
16
|
+
console.log('🗑️ 开始清理不需要的脚本...\n');
|
|
17
|
+
|
|
18
|
+
// 需要保留的脚本(生产环境必需)
|
|
19
|
+
const keepScripts = [
|
|
20
|
+
'postinstall.js', // npm 安装后执行
|
|
21
|
+
'pre-publish-check.js', // 发布前检查
|
|
22
|
+
'start-app.js', // 标准启动脚本
|
|
23
|
+
'start-simple.js', // 简化启动脚本
|
|
24
|
+
'quick-start.js', // 快速启动
|
|
25
|
+
'stop-app.js', // 停止应用
|
|
26
|
+
'open-browser.js', // 打开浏览器
|
|
27
|
+
'fix-startup-issues.js', // 修复启动问题
|
|
28
|
+
'generate-docs.js', // 生成文档
|
|
29
|
+
'cleanup-scripts.js' // 本脚本
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
// 需要删除的脚本(开发调试用的临时脚本)
|
|
33
|
+
const scriptsToDelete = [
|
|
34
|
+
// 添加功能的临时脚本
|
|
35
|
+
'add-button-hover.js',
|
|
36
|
+
'add-missing-braces.js',
|
|
37
|
+
'add-missing-functions.js',
|
|
38
|
+
'add-more-features.js',
|
|
39
|
+
'add-user-functions.js',
|
|
40
|
+
|
|
41
|
+
// 美化相关的临时脚本
|
|
42
|
+
'beautify-buttons.js',
|
|
43
|
+
'beautify-ui.js',
|
|
44
|
+
|
|
45
|
+
// 检查相关的临时脚本
|
|
46
|
+
'check-brackets.js',
|
|
47
|
+
'check-encoding.js',
|
|
48
|
+
'check-syntax.js',
|
|
49
|
+
|
|
50
|
+
// 查找相关的临时脚本
|
|
51
|
+
'find-buttons.js',
|
|
52
|
+
'find-duplicate.js',
|
|
53
|
+
'find-extra-brace.js',
|
|
54
|
+
'find-sidebar-buttons.js',
|
|
55
|
+
|
|
56
|
+
// 修复相关的临时脚本
|
|
57
|
+
'fix-file-end.js',
|
|
58
|
+
'fix-help.js',
|
|
59
|
+
'fix-issues-step1.js',
|
|
60
|
+
'fix-issues-step2.js',
|
|
61
|
+
'fix-issues-step3.js',
|
|
62
|
+
'fix-issues-step4.js',
|
|
63
|
+
'fix-optimized-views.js',
|
|
64
|
+
'fix-ports.js',
|
|
65
|
+
'fix-settings.js',
|
|
66
|
+
'fix-syntax-error.js',
|
|
67
|
+
'fix-user-dashboard.js',
|
|
68
|
+
'fix-workflow.js',
|
|
69
|
+
|
|
70
|
+
// 重构相关的临时脚本
|
|
71
|
+
'refactor-step1.js',
|
|
72
|
+
'refactor-step2.js',
|
|
73
|
+
'refactor-step3.js',
|
|
74
|
+
'refactor-step4.js',
|
|
75
|
+
'refactor-step5.js',
|
|
76
|
+
'refactor-step6.js',
|
|
77
|
+
'refactor-step7.js',
|
|
78
|
+
|
|
79
|
+
// 删除相关的临时脚本
|
|
80
|
+
'delete-orphan-block.js',
|
|
81
|
+
'remove-bom.js',
|
|
82
|
+
'remove-orphan-code.js',
|
|
83
|
+
'remove-quill-from-user-dashboard.js',
|
|
84
|
+
'remove-quill-imports-only.js',
|
|
85
|
+
|
|
86
|
+
// 更新相关的临时脚本
|
|
87
|
+
'update-port-user.js',
|
|
88
|
+
'update-port.js',
|
|
89
|
+
|
|
90
|
+
// 自动发布脚本(已不需要)
|
|
91
|
+
'auto-publish.js'
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
let deletedCount = 0;
|
|
95
|
+
let failedCount = 0;
|
|
96
|
+
|
|
97
|
+
console.log('📋 将要删除的脚本:\n');
|
|
98
|
+
|
|
99
|
+
scriptsToDelete.forEach((script, index) => {
|
|
100
|
+
const scriptPath = join(scriptsDir, script);
|
|
101
|
+
|
|
102
|
+
if (existsSync(scriptPath)) {
|
|
103
|
+
try {
|
|
104
|
+
unlinkSync(scriptPath);
|
|
105
|
+
console.log(` ${index + 1}. ✅ ${script}`);
|
|
106
|
+
deletedCount++;
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.log(` ${index + 1}. ❌ ${script} - 删除失败: ${error.message}`);
|
|
109
|
+
failedCount++;
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
console.log(` ${index + 1}. ⚠️ ${script} - 文件不存在`);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
console.log('\n' + '='.repeat(60));
|
|
117
|
+
console.log('📊 清理统计:\n');
|
|
118
|
+
console.log(` ✅ 成功删除: ${deletedCount} 个脚本`);
|
|
119
|
+
console.log(` ❌ 删除失败: ${failedCount} 个脚本`);
|
|
120
|
+
console.log(` 📦 保留脚本: ${keepScripts.length} 个\n`);
|
|
121
|
+
|
|
122
|
+
console.log('📝 保留的脚本:\n');
|
|
123
|
+
keepScripts.forEach((script, index) => {
|
|
124
|
+
console.log(` ${index + 1}. ${script}`);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
console.log('\n' + '='.repeat(60));
|
|
128
|
+
console.log('✅ 清理完成!\n');
|
|
129
|
+
console.log('💡 保留的脚本说明:');
|
|
130
|
+
console.log(' • postinstall.js - npm 安装后自动执行');
|
|
131
|
+
console.log(' • pre-publish-check.js - 发布前检查');
|
|
132
|
+
console.log(' • start-app.js - 标准启动(带端口检测)');
|
|
133
|
+
console.log(' • start-simple.js - 简化启动(推荐)');
|
|
134
|
+
console.log(' • quick-start.js - 快速启动');
|
|
135
|
+
console.log(' • stop-app.js - 停止所有进程');
|
|
136
|
+
console.log(' • open-browser.js - 自动打开浏览器');
|
|
137
|
+
console.log(' • fix-startup-issues.js - 修复启动问题');
|
|
138
|
+
console.log(' • generate-docs.js - 生成文档');
|
|
139
|
+
console.log('\n');
|
|
140
|
+
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 修复启动问题脚本
|
|
5
|
+
* 解决:
|
|
6
|
+
* 1. 端口配置不一致
|
|
7
|
+
* 2. 安全警告(shell: true)
|
|
8
|
+
* 3. Mongoose 重复索引警告
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
12
|
+
import { join, dirname } from 'path';
|
|
13
|
+
import { fileURLToPath } from 'url';
|
|
14
|
+
|
|
15
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
16
|
+
const __dirname = dirname(__filename);
|
|
17
|
+
const rootDir = join(__dirname, '..');
|
|
18
|
+
|
|
19
|
+
console.log('🔧 开始修复启动问题...\n');
|
|
20
|
+
|
|
21
|
+
let fixCount = 0;
|
|
22
|
+
|
|
23
|
+
// 1. 修复 start-app.js 中的安全警告
|
|
24
|
+
console.log('1️⃣ 修复 start-app.js 安全警告...');
|
|
25
|
+
try {
|
|
26
|
+
const startAppPath = join(rootDir, 'scripts', 'start-app.js');
|
|
27
|
+
let content = readFileSync(startAppPath, 'utf-8');
|
|
28
|
+
|
|
29
|
+
// 移除 shell: true 选项
|
|
30
|
+
content = content.replace(/shell: true/g, 'shell: false');
|
|
31
|
+
|
|
32
|
+
// 修复 Windows 命令
|
|
33
|
+
content = content.replace(
|
|
34
|
+
/const npmCmd = isWindows \? 'npm\.cmd' : 'npm';/g,
|
|
35
|
+
"const npmCmd = isWindows ? 'npm.cmd' : 'npm';"
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
writeFileSync(startAppPath, content, 'utf-8');
|
|
39
|
+
console.log(' ✅ start-app.js 已修复\n');
|
|
40
|
+
fixCount++;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.log(' ⚠️ start-app.js 修复失败:', error.message, '\n');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 2. 修复 bin/cli.js 中的安全警告
|
|
46
|
+
console.log('2️⃣ 修复 bin/cli.js 安全警告...');
|
|
47
|
+
try {
|
|
48
|
+
const cliPath = join(rootDir, 'bin', 'cli.js');
|
|
49
|
+
let content = readFileSync(cliPath, 'utf-8');
|
|
50
|
+
|
|
51
|
+
// 移除 shell: true 选项
|
|
52
|
+
content = content.replace(/shell: true/g, 'shell: false');
|
|
53
|
+
|
|
54
|
+
writeFileSync(cliPath, content, 'utf-8');
|
|
55
|
+
console.log(' ✅ bin/cli.js 已修复\n');
|
|
56
|
+
fixCount++;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.log(' ⚠️ bin/cli.js 修复失败:', error.message, '\n');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 3. 修复 User.js 中的重复索引
|
|
62
|
+
console.log('3️⃣ 修复 User.js 重复索引警告...');
|
|
63
|
+
try {
|
|
64
|
+
const userModelPath = join(rootDir, 'server', 'models', 'User.js');
|
|
65
|
+
let content = readFileSync(userModelPath, 'utf-8');
|
|
66
|
+
|
|
67
|
+
// 移除 index: true,只保留 unique: true
|
|
68
|
+
content = content.replace(
|
|
69
|
+
/username: \{ type: String, required: true, unique: true, index: true \}/g,
|
|
70
|
+
'username: { type: String, required: true, unique: true }'
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
content = content.replace(
|
|
74
|
+
/email: \{ type: String, required: true, unique: true, index: true \}/g,
|
|
75
|
+
'email: { type: String, required: true, unique: true }'
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
writeFileSync(userModelPath, content, 'utf-8');
|
|
79
|
+
console.log(' ✅ User.js 已修复\n');
|
|
80
|
+
fixCount++;
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.log(' ⚠️ User.js 修复失败:', error.message, '\n');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 4. 创建 .env 文件(如果不存在)
|
|
86
|
+
console.log('4️⃣ 检查 .env 配置...');
|
|
87
|
+
try {
|
|
88
|
+
const envPath = join(rootDir, '.env');
|
|
89
|
+
const envExamplePath = join(rootDir, '.env.example');
|
|
90
|
+
|
|
91
|
+
let envContent = '';
|
|
92
|
+
try {
|
|
93
|
+
envContent = readFileSync(envPath, 'utf-8');
|
|
94
|
+
} catch {
|
|
95
|
+
// .env 不存在,创建默认配置
|
|
96
|
+
envContent = `# MongoDB 配置
|
|
97
|
+
MONGODB_URI=mongodb://localhost:27017/collabdocchat
|
|
98
|
+
|
|
99
|
+
# JWT 密钥
|
|
100
|
+
JWT_SECRET=your_jwt_secret_key_change_this_in_production
|
|
101
|
+
|
|
102
|
+
# 服务器端口
|
|
103
|
+
PORT=3000
|
|
104
|
+
|
|
105
|
+
# Node 环境
|
|
106
|
+
NODE_ENV=development
|
|
107
|
+
`;
|
|
108
|
+
writeFileSync(envPath, envContent, 'utf-8');
|
|
109
|
+
console.log(' ✅ 已创建 .env 文件\n');
|
|
110
|
+
fixCount++;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// 检查端口配置
|
|
114
|
+
if (!envContent.includes('PORT=')) {
|
|
115
|
+
envContent += '\n# 服务器端口\nPORT=3000\n';
|
|
116
|
+
writeFileSync(envPath, envContent, 'utf-8');
|
|
117
|
+
console.log(' ✅ 已添加 PORT 配置\n');
|
|
118
|
+
fixCount++;
|
|
119
|
+
} else {
|
|
120
|
+
console.log(' ✅ .env 配置正常\n');
|
|
121
|
+
}
|
|
122
|
+
} catch (error) {
|
|
123
|
+
console.log(' ⚠️ .env 配置失败:', error.message, '\n');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 总结
|
|
127
|
+
console.log('='.repeat(50));
|
|
128
|
+
console.log(`✅ 修复完成!共修复 ${fixCount} 个问题\n`);
|
|
129
|
+
console.log('📝 修复内容:');
|
|
130
|
+
console.log(' 1. 移除不安全的 shell: true 选项');
|
|
131
|
+
console.log(' 2. 修复 Mongoose 重复索引警告');
|
|
132
|
+
console.log(' 3. 确保 .env 配置正确\n');
|
|
133
|
+
console.log('🚀 现在可以重新启动应用:');
|
|
134
|
+
console.log(' collabdocchat');
|
|
135
|
+
console.log(' 或: npm start\n');
|
|
136
|
+
|
package/scripts/start-app.js
CHANGED
|
@@ -3,12 +3,16 @@ import { platform } from 'os';
|
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { dirname, join } from 'path';
|
|
5
5
|
import http from 'http';
|
|
6
|
-
import { existsSync } from 'fs';
|
|
6
|
+
import { existsSync, readFileSync } from 'fs';
|
|
7
|
+
import dotenv from 'dotenv';
|
|
7
8
|
|
|
8
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
10
|
const __dirname = dirname(__filename);
|
|
10
11
|
const rootDir = join(__dirname, '..');
|
|
11
12
|
|
|
13
|
+
// 加载 .env 文件
|
|
14
|
+
dotenv.config({ path: join(rootDir, '.env') });
|
|
15
|
+
|
|
12
16
|
const PORT = process.env.PORT || 8765;
|
|
13
17
|
const CLIENT_PORT = 5173;
|
|
14
18
|
const CLIENT_URL = `http://localhost:${CLIENT_PORT}`;
|
|
@@ -29,7 +33,7 @@ function installDevDependencies() {
|
|
|
29
33
|
const install = spawn(npmCmd, ['install'], {
|
|
30
34
|
cwd: rootDir,
|
|
31
35
|
stdio: 'inherit',
|
|
32
|
-
shell:
|
|
36
|
+
shell: false
|
|
33
37
|
});
|
|
34
38
|
|
|
35
39
|
install.on('close', (code) => {
|
|
@@ -92,7 +96,7 @@ function openBrowser(url) {
|
|
|
92
96
|
const browser = spawn(command, args, {
|
|
93
97
|
stdio: 'ignore',
|
|
94
98
|
detached: true,
|
|
95
|
-
shell:
|
|
99
|
+
shell: false
|
|
96
100
|
});
|
|
97
101
|
browser.unref();
|
|
98
102
|
} catch (error) {
|
|
@@ -146,7 +150,8 @@ function startServer() {
|
|
|
146
150
|
const server = spawn('node', ['server/index.js'], {
|
|
147
151
|
cwd: rootDir,
|
|
148
152
|
stdio: 'inherit',
|
|
149
|
-
shell:
|
|
153
|
+
shell: false,
|
|
154
|
+
env: { ...process.env }
|
|
150
155
|
});
|
|
151
156
|
|
|
152
157
|
return server;
|
|
@@ -159,7 +164,8 @@ function startClient() {
|
|
|
159
164
|
const client = spawn(npmCmd, ['run', 'client'], {
|
|
160
165
|
cwd: rootDir,
|
|
161
166
|
stdio: 'inherit',
|
|
162
|
-
shell:
|
|
167
|
+
shell: false,
|
|
168
|
+
env: { ...process.env }
|
|
163
169
|
});
|
|
164
170
|
|
|
165
171
|
return client;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 简化的启动脚本 - 避免超时问题
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { spawn } from 'child_process';
|
|
8
|
+
import { platform } from 'os';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import { dirname, join } from 'path';
|
|
11
|
+
import dotenv from 'dotenv';
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = dirname(__filename);
|
|
15
|
+
const rootDir = join(__dirname, '..');
|
|
16
|
+
const isWindows = platform() === 'win32';
|
|
17
|
+
|
|
18
|
+
// 加载环境变量
|
|
19
|
+
dotenv.config({ path: join(rootDir, '.env') });
|
|
20
|
+
|
|
21
|
+
const PORT = process.env.PORT || 8765;
|
|
22
|
+
|
|
23
|
+
console.log('📦 CollabDocChat 正在启动...\n');
|
|
24
|
+
|
|
25
|
+
// 启动服务器
|
|
26
|
+
console.log('🚀 正在启动服务器...');
|
|
27
|
+
const server = spawn('node', ['server/index.js'], {
|
|
28
|
+
cwd: rootDir,
|
|
29
|
+
stdio: 'inherit',
|
|
30
|
+
env: { ...process.env }
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
server.on('error', (error) => {
|
|
34
|
+
console.error('❌ 服务器启动失败:', error.message);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// 等待3秒后启动客户端
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
console.log('\n🎨 正在启动客户端...\n');
|
|
41
|
+
const npmCmd = isWindows ? 'npm.cmd' : 'npm';
|
|
42
|
+
const client = spawn(npmCmd, ['run', 'client'], {
|
|
43
|
+
cwd: rootDir,
|
|
44
|
+
stdio: 'inherit',
|
|
45
|
+
env: { ...process.env }
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
client.on('error', (error) => {
|
|
49
|
+
console.error('❌ 客户端启动失败:', error.message);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// 再等待5秒后打开浏览器
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
console.log('\n✅ 应用启动成功!');
|
|
55
|
+
console.log('\n💡 访问地址:');
|
|
56
|
+
console.log(` • 服务器: http://localhost:${PORT}`);
|
|
57
|
+
console.log(' • 客户端: http://localhost:5173');
|
|
58
|
+
console.log(' • 默认账号: admin / admin123');
|
|
59
|
+
console.log('\n⚠️ 按 Ctrl+C 停止服务\n');
|
|
60
|
+
|
|
61
|
+
// 打开浏览器
|
|
62
|
+
try {
|
|
63
|
+
const openCmd = isWindows ? 'start' : (platform() === 'darwin' ? 'open' : 'xdg-open');
|
|
64
|
+
const url = 'http://localhost:5173';
|
|
65
|
+
|
|
66
|
+
if (isWindows) {
|
|
67
|
+
spawn('cmd', ['/c', 'start', '', url], {
|
|
68
|
+
stdio: 'ignore',
|
|
69
|
+
detached: true
|
|
70
|
+
}).unref();
|
|
71
|
+
} else {
|
|
72
|
+
spawn(openCmd, [url], {
|
|
73
|
+
stdio: 'ignore',
|
|
74
|
+
detached: true
|
|
75
|
+
}).unref();
|
|
76
|
+
}
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.log('⚠️ 无法自动打开浏览器,请手动访问: http://localhost:5173');
|
|
79
|
+
}
|
|
80
|
+
}, 5000);
|
|
81
|
+
|
|
82
|
+
// 处理退出信号
|
|
83
|
+
process.on('SIGINT', () => {
|
|
84
|
+
console.log('\n\n🛑 正在关闭服务器...');
|
|
85
|
+
server.kill();
|
|
86
|
+
client.kill();
|
|
87
|
+
process.exit(0);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
process.on('SIGTERM', () => {
|
|
91
|
+
server.kill();
|
|
92
|
+
client.kill();
|
|
93
|
+
process.exit(0);
|
|
94
|
+
});
|
|
95
|
+
}, 3000);
|
|
96
|
+
|
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,
|