collabdocchat 2.5.10 → 2.5.13
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/dist/assets/index-1ylqJADA.js +2456 -0
- package/dist/index.html +1 -1
- package/package.json +5 -1
- package/scripts/cleanup-scripts.js +3 -0
- package/scripts/fix-startup-issues.js +3 -0
- package/scripts/start-simple.js +3 -0
- package/server/public/index.html +3 -0
- package/server/routes/polls.js +50 -12
- package/src/main.js +3 -0
- package/src/pages/admin-dashboard.js +20 -8
- package/src/polyfills.js +11 -0
- package/vite.config.js +29 -0
- package/dist/assets/index-9XAJPSRa.js +0 -2451
package/dist/index.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>CollabDocChat - 协作文档聊天平台</title>
|
|
7
7
|
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
|
|
8
8
|
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
|
|
9
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-1ylqJADA.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/assets/index-D8ZqeoaM.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "collabdocchat",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.13",
|
|
4
4
|
"description": "开源的实时协作文档聊天平台 - 集成任务管理、多人文档编辑、智能点名功能",
|
|
5
5
|
"main": "./server/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -89,9 +89,13 @@
|
|
|
89
89
|
"yjs": "^13.6.10"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
|
+
"buffer": "^6.0.3",
|
|
92
93
|
"concurrently": "^8.2.2",
|
|
94
|
+
"crypto-browserify": "^3.12.0",
|
|
93
95
|
"nodemon": "^3.0.2",
|
|
94
96
|
"open": "^11.0.0",
|
|
97
|
+
"process": "^0.11.10",
|
|
98
|
+
"stream-browserify": "^3.0.0",
|
|
95
99
|
"vite": "^5.0.8"
|
|
96
100
|
}
|
|
97
101
|
}
|
package/scripts/start-simple.js
CHANGED
package/server/public/index.html
CHANGED
package/server/routes/polls.js
CHANGED
|
@@ -93,29 +93,44 @@ router.get('/:pollId', authenticate, async (req, res) => {
|
|
|
93
93
|
return res.status(404).json({ error: '投票不存在' });
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
// 确保创建者信息正确
|
|
97
|
+
if (!poll.creatorName && poll.creator && poll.creator.username) {
|
|
98
|
+
poll.creatorName = poll.creator.username;
|
|
99
|
+
}
|
|
100
|
+
|
|
96
101
|
// 验证用户是群组成员
|
|
97
102
|
const group = await Group.findById(poll.group);
|
|
98
103
|
if (!group.members.includes(req.user.userId)) {
|
|
99
104
|
return res.status(403).json({ error: '您不是该群组成员' });
|
|
100
105
|
}
|
|
101
106
|
|
|
102
|
-
//
|
|
107
|
+
// 确保投票者信息正确返回
|
|
103
108
|
if (!poll.anonymous) {
|
|
109
|
+
// 对于非匿名投票,确保每个 vote 都有 username
|
|
104
110
|
for (let option of poll.options) {
|
|
105
111
|
for (let vote of option.votes) {
|
|
106
|
-
// 如果
|
|
107
|
-
if (vote.user &&
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
// 如果 vote 有 user 字段但没有 username,尝试从 user 对象获取或 populate
|
|
113
|
+
if (vote.user && !vote.username) {
|
|
114
|
+
// 如果 user 已经被 populate(有 username 属性)
|
|
115
|
+
if (vote.user.username) {
|
|
116
|
+
vote.username = vote.user.username;
|
|
117
|
+
} else {
|
|
118
|
+
// 如果 user 是 ObjectId,尝试 populate
|
|
119
|
+
try {
|
|
120
|
+
const userId = vote.user.toString ? vote.user.toString() : vote.user;
|
|
121
|
+
const user = await User.findById(userId).select('username');
|
|
122
|
+
if (user) {
|
|
123
|
+
vote.username = user.username;
|
|
124
|
+
}
|
|
125
|
+
} catch (err) {
|
|
126
|
+
console.error('Populate vote user failed:', err);
|
|
113
127
|
}
|
|
114
|
-
} catch (err) {
|
|
115
|
-
// 如果 populate 失败,使用已保存的 username
|
|
116
|
-
console.error('Populate vote user failed:', err);
|
|
117
128
|
}
|
|
118
129
|
}
|
|
130
|
+
// 确保 username 字段存在(投票时应该已经保存了)
|
|
131
|
+
if (!vote.username) {
|
|
132
|
+
console.warn('投票记录缺少 username 字段:', vote);
|
|
133
|
+
}
|
|
119
134
|
}
|
|
120
135
|
}
|
|
121
136
|
} else {
|
|
@@ -127,7 +142,30 @@ router.get('/:pollId', authenticate, async (req, res) => {
|
|
|
127
142
|
});
|
|
128
143
|
}
|
|
129
144
|
|
|
130
|
-
|
|
145
|
+
// 转换为普通对象,确保所有字段都被包含
|
|
146
|
+
const pollData = poll.toObject ? poll.toObject({ virtuals: true }) : JSON.parse(JSON.stringify(poll));
|
|
147
|
+
|
|
148
|
+
// 确保创建者名称存在
|
|
149
|
+
if (!pollData.creatorName && pollData.creator) {
|
|
150
|
+
pollData.creatorName = pollData.creator.username || '未知用户';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 确保每个投票都有 username(再次检查)
|
|
154
|
+
if (!poll.anonymous && pollData.options) {
|
|
155
|
+
pollData.options.forEach(option => {
|
|
156
|
+
if (option.votes) {
|
|
157
|
+
option.votes.forEach(vote => {
|
|
158
|
+
if (vote.user && !vote.username) {
|
|
159
|
+
if (vote.user.username) {
|
|
160
|
+
vote.username = vote.user.username;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
res.json({ poll: pollData });
|
|
131
169
|
} catch (error) {
|
|
132
170
|
console.error('获取投票详情失败:', error);
|
|
133
171
|
res.status(500).json({ error: '获取投票详情失败' });
|
package/src/main.js
CHANGED
|
@@ -1299,6 +1299,14 @@ export function renderAdminDashboard(user, wsService) {
|
|
|
1299
1299
|
|
|
1300
1300
|
const result = await response.json();
|
|
1301
1301
|
const poll = result.poll;
|
|
1302
|
+
|
|
1303
|
+
// 调试:打印投票数据
|
|
1304
|
+
console.log('投票详情数据:', poll);
|
|
1305
|
+
console.log('创建者信息:', poll.creatorName, poll.creator);
|
|
1306
|
+
poll.options.forEach((opt, idx) => {
|
|
1307
|
+
console.log(`选项 ${idx} (${opt.text}) 的投票记录:`, opt.votes);
|
|
1308
|
+
});
|
|
1309
|
+
|
|
1302
1310
|
const totalVotes = poll.options.reduce((sum, opt) => sum + opt.votes.length, 0);
|
|
1303
1311
|
const isEnded = poll.status === 'ended' || (poll.endTime && new Date(poll.endTime) < new Date());
|
|
1304
1312
|
|
|
@@ -1356,19 +1364,20 @@ export function renderAdminDashboard(user, wsService) {
|
|
|
1356
1364
|
let votersList = '';
|
|
1357
1365
|
if (!poll.anonymous && option.votes.length > 0) {
|
|
1358
1366
|
const voters = option.votes.map(v => {
|
|
1359
|
-
//
|
|
1367
|
+
// 优先使用直接保存的 username 字段
|
|
1360
1368
|
if (v && typeof v === 'object') {
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
return v.user.username;
|
|
1369
|
+
if (v.username && typeof v.username === 'string' && v.username.trim()) {
|
|
1370
|
+
return v.username.trim();
|
|
1364
1371
|
}
|
|
1365
|
-
// 如果 user
|
|
1366
|
-
if (v.
|
|
1367
|
-
|
|
1372
|
+
// 如果 user 被 populate 了,使用 user.username
|
|
1373
|
+
if (v.user && typeof v.user === 'object') {
|
|
1374
|
+
if (v.user.username && typeof v.user.username === 'string') {
|
|
1375
|
+
return v.user.username.trim();
|
|
1376
|
+
}
|
|
1368
1377
|
}
|
|
1369
1378
|
}
|
|
1370
1379
|
return null;
|
|
1371
|
-
}).filter(name => name !== null && name !== '未知用户');
|
|
1380
|
+
}).filter(name => name !== null && name !== '未知用户' && name.trim() !== '');
|
|
1372
1381
|
|
|
1373
1382
|
if (voters.length > 0) {
|
|
1374
1383
|
votersList = `
|
|
@@ -1376,6 +1385,9 @@ export function renderAdminDashboard(user, wsService) {
|
|
|
1376
1385
|
<strong style="color: var(--text-primary);">👥 投票者:</strong> ${voters.join(', ')}
|
|
1377
1386
|
</div>
|
|
1378
1387
|
`;
|
|
1388
|
+
} else {
|
|
1389
|
+
// 如果没有找到投票者,显示调试信息(开发时使用)
|
|
1390
|
+
console.warn('投票者信息缺失:', option.votes);
|
|
1379
1391
|
}
|
|
1380
1392
|
}
|
|
1381
1393
|
|
package/src/polyfills.js
ADDED
package/vite.config.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { defineConfig } from 'vite';
|
|
2
|
+
import { Buffer } from 'buffer';
|
|
2
3
|
|
|
3
4
|
export default defineConfig({
|
|
4
5
|
server: {
|
|
@@ -14,7 +15,35 @@ export default defineConfig({
|
|
|
14
15
|
build: {
|
|
15
16
|
rollupOptions: {
|
|
16
17
|
// 移除 external 配置,让 Vite 打包所有依赖
|
|
18
|
+
},
|
|
19
|
+
commonjsOptions: {
|
|
20
|
+
transformMixedEsModules: true
|
|
17
21
|
}
|
|
22
|
+
},
|
|
23
|
+
define: {
|
|
24
|
+
// 修复 crypto 模块在构建时的问题
|
|
25
|
+
'process.env': {},
|
|
26
|
+
'global': 'globalThis',
|
|
27
|
+
'Buffer': ['buffer', 'Buffer']
|
|
28
|
+
},
|
|
29
|
+
resolve: {
|
|
30
|
+
alias: {
|
|
31
|
+
// 确保使用浏览器兼容的模块
|
|
32
|
+
'crypto': 'crypto-browserify',
|
|
33
|
+
'stream': 'stream-browserify',
|
|
34
|
+
'buffer': 'buffer',
|
|
35
|
+
'process': 'process/browser'
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
optimizeDeps: {
|
|
39
|
+
esbuildOptions: {
|
|
40
|
+
// Node.js 全局变量注入
|
|
41
|
+
define: {
|
|
42
|
+
global: 'globalThis'
|
|
43
|
+
},
|
|
44
|
+
plugins: []
|
|
45
|
+
},
|
|
46
|
+
include: ['buffer', 'process']
|
|
18
47
|
}
|
|
19
48
|
});
|
|
20
49
|
|