collabdocchat 2.4.7 → 2.4.9

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "collabdocchat",
3
- "version": "2.4.7",
3
+ "version": "2.4.9",
4
4
  "description": "开源的实时协作文档聊天平台 - 集成任务管理、多人文档编辑、智能点名功能",
5
5
  "main": "./server/index.js",
6
6
  "type": "module",
@@ -33,7 +33,7 @@ function installDevDependencies() {
33
33
  const install = spawn(npmCmd, ['install'], {
34
34
  cwd: rootDir,
35
35
  stdio: 'inherit',
36
- shell: false
36
+ shell: isWindows // Windows 需要 shell
37
37
  });
38
38
 
39
39
  install.on('close', (code) => {
@@ -187,16 +187,16 @@ async function main() {
187
187
  process.exit(1);
188
188
  }
189
189
 
190
- // 检查并安装 devDependencies
191
- if (!checkDevDependencies()) {
192
- console.log('⚠️ 检测到缺少开发依赖\n');
193
- try {
194
- await installDevDependencies();
195
- } catch (error) {
196
- console.error(' 依赖安装失败:', error.message);
197
- console.error('\n💡 请手动运行: npm install\n');
198
- process.exit(1);
199
- }
190
+ // 检查是否有开发依赖(全局安装时可能没有)
191
+ const hasDevDeps = checkDevDependencies();
192
+
193
+ if (!hasDevDeps) {
194
+ console.log('⚠️ 检测到全局安装模式(无开发依赖)');
195
+ console.log('💡 将只启动服务器,不启动客户端\n');
196
+ console.log('📝 如需完整开发环境,请:');
197
+ console.log(' 1. 克隆项目到本地目录');
198
+ console.log(' 2. 运行 npm install');
199
+ console.log(' 3. 运行 npm run dev\n');
200
200
  }
201
201
 
202
202
  // 启动服务器
@@ -211,38 +211,60 @@ async function main() {
211
211
  process.exit(1);
212
212
  }
213
213
 
214
- // 启动客户端
215
- const client = startClient();
216
-
217
- // 等待客户端就绪后打开浏览器
218
- setTimeout(async () => {
219
- try {
220
- await waitForServer(CLIENT_URL, 20, 500);
221
- console.log(`\n🌐 正在打开浏览器: ${CLIENT_URL}`);
222
- openBrowser(CLIENT_URL);
223
- console.log('\n✅ 应用启动成功!');
224
- console.log('\n💡 提示:');
225
- console.log(` • 服务器: http://localhost:${PORT}`);
226
- console.log(' • 客户端: http://localhost:5173');
227
- console.log(' 默认账号: admin / admin123');
228
- console.log('\n⚠️ 按 Ctrl+C 停止服务\n');
229
- } catch (error) {
230
- console.log(`\n⚠️ 客户端可能还在启动中,请手动访问: ${CLIENT_URL}`);
231
- openBrowser(CLIENT_URL);
232
- }
233
- }, 3000);
214
+ let client = null;
215
+
216
+ // 只有在有开发依赖时才启动客户端
217
+ if (hasDevDeps) {
218
+ // 启动客户端
219
+ client = startClient();
220
+
221
+ // 等待客户端就绪后打开浏览器
222
+ setTimeout(async () => {
223
+ try {
224
+ await waitForServer(CLIENT_URL, 20, 500);
225
+ console.log(`\n🌐 正在打开浏览器: ${CLIENT_URL}`);
226
+ openBrowser(CLIENT_URL);
227
+ console.log('\n✅ 应用启动成功!');
228
+ console.log('\n💡 提示:');
229
+ console.log(` • 服务器: http://localhost:${PORT}`);
230
+ console.log(' • 客户端: http://localhost:5173');
231
+ console.log(' • 默认账号: admin / admin123');
232
+ console.log('\n⚠️ 按 Ctrl+C 停止服务\n');
233
+ } catch (error) {
234
+ console.log(`\n⚠️ 客户端可能还在启动中,请手动访问: ${CLIENT_URL}`);
235
+ openBrowser(CLIENT_URL);
236
+ }
237
+ }, 3000);
238
+ } else {
239
+ // 全局安装模式,只有服务器,自动打开浏览器
240
+ console.log('\n✅ 服务器启动成功!');
241
+ console.log('\n💡 提示:');
242
+ console.log(` • API 服务器: http://localhost:${PORT}`);
243
+ console.log(' • 默认账号: admin / admin123');
244
+ console.log('\n📝 注意:');
245
+ console.log(' 全局安装模式仅提供 API 服务器');
246
+ console.log(' 如需完整的前端界面,请在本地项目中运行');
247
+ console.log('\n🌐 正在打开浏览器...\n');
248
+
249
+ // 延迟1秒后打开浏览器
250
+ setTimeout(() => {
251
+ openBrowser(`http://localhost:${PORT}`);
252
+ }, 1000);
253
+
254
+ console.log('⚠️ 按 Ctrl+C 停止服务\n');
255
+ }
234
256
 
235
257
  // 处理退出信号
236
258
  process.on('SIGINT', () => {
237
259
  console.log('\n\n🛑 正在关闭服务器...');
238
260
  server.kill();
239
- client.kill();
261
+ if (client) client.kill();
240
262
  process.exit(0);
241
263
  });
242
264
 
243
265
  process.on('SIGTERM', () => {
244
266
  server.kill();
245
- client.kill();
267
+ if (client) client.kill();
246
268
  process.exit(0);
247
269
  });
248
270
  }
package/server/index.js CHANGED
@@ -4,6 +4,8 @@ import { WebSocketServer } from 'ws';
4
4
  import cors from 'cors';
5
5
  import dotenv from 'dotenv';
6
6
  import mongoose from 'mongoose';
7
+ import { fileURLToPath } from 'url';
8
+ import { dirname, join } from 'path';
7
9
  import authRoutes from './routes/auth.js';
8
10
  import taskRoutes from './routes/tasks.js';
9
11
  import documentRoutes from './routes/documents.js';
@@ -23,6 +25,9 @@ import { initDefaultAdmin } from './utils/initAdmin.js';
23
25
  import { errorHandler, notFoundHandler } from './middleware/errorHandler.js';
24
26
  import backupService from './utils/backup.js';
25
27
 
28
+ const __filename = fileURLToPath(import.meta.url);
29
+ const __dirname = dirname(__filename);
30
+
26
31
  dotenv.config();
27
32
 
28
33
  const app = express();
@@ -50,6 +55,9 @@ mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/collabdoc
50
55
  // 静态文件服务(用于文件下载)
51
56
  app.use('/uploads', express.static('uploads'));
52
57
 
58
+ // 静态页面服务(全局安装模式的欢迎页面)
59
+ app.use(express.static(join(__dirname, 'public')));
60
+
53
61
  // API 路由
54
62
  app.use('/api/auth', authRoutes);
55
63
  app.use('/api/tasks', taskRoutes);
@@ -74,6 +82,11 @@ app.get('/health', (req, res) => {
74
82
  res.json({ status: 'ok', timestamp: new Date().toISOString() });
75
83
  });
76
84
 
85
+ // 根路径 - 返回欢迎页面
86
+ app.get('/', (req, res) => {
87
+ res.sendFile(join(__dirname, 'public', 'index.html'));
88
+ });
89
+
77
90
  // 404 处理
78
91
  app.use(notFoundHandler);
79
92
 
@@ -0,0 +1,246 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>CollabDocChat - API 服务器</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
16
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
17
+ min-height: 100vh;
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ padding: 20px;
22
+ }
23
+
24
+ .container {
25
+ background: white;
26
+ border-radius: 20px;
27
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
28
+ max-width: 800px;
29
+ width: 100%;
30
+ padding: 40px;
31
+ }
32
+
33
+ .header {
34
+ text-align: center;
35
+ margin-bottom: 40px;
36
+ }
37
+
38
+ .logo {
39
+ font-size: 48px;
40
+ margin-bottom: 10px;
41
+ }
42
+
43
+ h1 {
44
+ color: #333;
45
+ font-size: 32px;
46
+ margin-bottom: 10px;
47
+ }
48
+
49
+ .subtitle {
50
+ color: #666;
51
+ font-size: 16px;
52
+ }
53
+
54
+ .status {
55
+ background: #f0fdf4;
56
+ border: 2px solid #86efac;
57
+ border-radius: 12px;
58
+ padding: 20px;
59
+ margin-bottom: 30px;
60
+ }
61
+
62
+ .status-title {
63
+ color: #16a34a;
64
+ font-weight: bold;
65
+ font-size: 18px;
66
+ margin-bottom: 10px;
67
+ }
68
+
69
+ .status-item {
70
+ color: #166534;
71
+ margin: 8px 0;
72
+ padding-left: 20px;
73
+ position: relative;
74
+ }
75
+
76
+ .status-item::before {
77
+ content: "✓";
78
+ position: absolute;
79
+ left: 0;
80
+ color: #16a34a;
81
+ font-weight: bold;
82
+ }
83
+
84
+ .info-box {
85
+ background: #f8fafc;
86
+ border-radius: 12px;
87
+ padding: 20px;
88
+ margin-bottom: 20px;
89
+ }
90
+
91
+ .info-title {
92
+ font-weight: bold;
93
+ color: #334155;
94
+ margin-bottom: 15px;
95
+ font-size: 18px;
96
+ }
97
+
98
+ .info-item {
99
+ display: flex;
100
+ justify-content: space-between;
101
+ padding: 10px 0;
102
+ border-bottom: 1px solid #e2e8f0;
103
+ }
104
+
105
+ .info-item:last-child {
106
+ border-bottom: none;
107
+ }
108
+
109
+ .info-label {
110
+ color: #64748b;
111
+ }
112
+
113
+ .info-value {
114
+ color: #0f172a;
115
+ font-weight: 500;
116
+ }
117
+
118
+ .api-link {
119
+ color: #667eea;
120
+ text-decoration: none;
121
+ font-weight: 500;
122
+ }
123
+
124
+ .api-link:hover {
125
+ text-decoration: underline;
126
+ }
127
+
128
+ .warning-box {
129
+ background: #fef3c7;
130
+ border: 2px solid #fbbf24;
131
+ border-radius: 12px;
132
+ padding: 20px;
133
+ margin-bottom: 20px;
134
+ }
135
+
136
+ .warning-title {
137
+ color: #92400e;
138
+ font-weight: bold;
139
+ margin-bottom: 10px;
140
+ }
141
+
142
+ .warning-text {
143
+ color: #78350f;
144
+ line-height: 1.6;
145
+ }
146
+
147
+ .action-box {
148
+ background: #eff6ff;
149
+ border-radius: 12px;
150
+ padding: 20px;
151
+ }
152
+
153
+ .action-title {
154
+ color: #1e40af;
155
+ font-weight: bold;
156
+ margin-bottom: 15px;
157
+ }
158
+
159
+ .action-steps {
160
+ color: #1e3a8a;
161
+ line-height: 1.8;
162
+ }
163
+
164
+ .action-steps li {
165
+ margin: 8px 0;
166
+ }
167
+
168
+ code {
169
+ background: #1e293b;
170
+ color: #e2e8f0;
171
+ padding: 2px 8px;
172
+ border-radius: 4px;
173
+ font-family: 'Courier New', monospace;
174
+ font-size: 14px;
175
+ }
176
+
177
+ .footer {
178
+ text-align: center;
179
+ margin-top: 30px;
180
+ color: #64748b;
181
+ font-size: 14px;
182
+ }
183
+ </style>
184
+ </head>
185
+ <body>
186
+ <div class="container">
187
+ <div class="header">
188
+ <div class="logo">🎉</div>
189
+ <h1>CollabDocChat</h1>
190
+ <p class="subtitle">开源的实时协作文档聊天平台</p>
191
+ </div>
192
+
193
+ <div class="status">
194
+ <div class="status-title">✅ API 服务器运行中</div>
195
+ <div class="status-item">MongoDB 已连接</div>
196
+ <div class="status-item">WebSocket 服务已启动</div>
197
+ <div class="status-item">所有 API 端点可用</div>
198
+ </div>
199
+
200
+ <div class="info-box">
201
+ <div class="info-title">📍 服务器信息</div>
202
+ <div class="info-item">
203
+ <span class="info-label">API 地址</span>
204
+ <span class="info-value"><a href="/api" class="api-link" target="_blank">http://localhost:3000/api</a></span>
205
+ </div>
206
+ <div class="info-item">
207
+ <span class="info-label">健康检查</span>
208
+ <span class="info-value"><a href="/health" class="api-link" target="_blank">http://localhost:3000/health</a></span>
209
+ </div>
210
+ <div class="info-item">
211
+ <span class="info-label">WebSocket</span>
212
+ <span class="info-value">ws://localhost:3000</span>
213
+ </div>
214
+ <div class="info-item">
215
+ <span class="info-label">默认账号</span>
216
+ <span class="info-value">admin / admin123</span>
217
+ </div>
218
+ </div>
219
+
220
+ <div class="warning-box">
221
+ <div class="warning-title">⚠️ 全局安装模式</div>
222
+ <p class="warning-text">
223
+ 当前运行在全局安装模式下,仅提供 API 服务器。
224
+ 如需完整的前端界面和开发环境,请按照下方步骤操作。
225
+ </p>
226
+ </div>
227
+
228
+ <div class="action-box">
229
+ <div class="action-title">🚀 获取完整功能</div>
230
+ <ol class="action-steps">
231
+ <li>克隆或下载项目到本地目录</li>
232
+ <li>运行 <code>npm install</code> 安装所有依赖</li>
233
+ <li>运行 <code>npm run dev</code> 启动完整应用</li>
234
+ <li>访问 <code>http://localhost:5173</code> 使用前端界面</li>
235
+ </ol>
236
+ </div>
237
+
238
+ <div class="footer">
239
+ <p>CollabDocChat v2.4.8 | MIT License</p>
240
+ <p><a href="https://github.com/shijinghao/collabdocchat" class="api-link" target="_blank">GitHub</a> |
241
+ <a href="https://www.npmjs.com/package/collabdocchat" class="api-link" target="_blank">NPM</a></p>
242
+ </div>
243
+ </div>
244
+ </body>
245
+ </html>
246
+