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
|
@@ -151,10 +151,22 @@ function renderOptimizedTaskDetail(task, container) {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
// 渲染投票结果
|
|
154
|
+
// 渲染投票结果(增强版 - 显示投票成员详情)
|
|
154
155
|
function renderPollResults(poll) {
|
|
155
156
|
if (!poll || !poll.options) return '';
|
|
156
157
|
|
|
157
158
|
const totalVotes = poll.options.reduce((sum, opt) => sum + (opt.votes || 0), 0);
|
|
159
|
+
|
|
160
|
+
// 获取所有已投票成员
|
|
161
|
+
const votedMembers = new Set();
|
|
162
|
+
poll.options.forEach(option => {
|
|
163
|
+
if (option.voters) {
|
|
164
|
+
option.voters.forEach(voter => {
|
|
165
|
+
const voterName = typeof voter === 'string' ? voter : voter.username;
|
|
166
|
+
votedMembers.add(voterName);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
});
|
|
158
170
|
|
|
159
171
|
return `
|
|
160
172
|
<div class="task-poll-card-modern">
|
|
@@ -162,52 +174,116 @@ function renderPollResults(poll) {
|
|
|
162
174
|
<span class="card-icon">📊</span> 投票结果
|
|
163
175
|
</h3>
|
|
164
176
|
<div class="poll-question-modern">${poll.question || '投票'}</div>
|
|
177
|
+
|
|
178
|
+
<!-- 投票统计摘要 -->
|
|
179
|
+
<div class="poll-stats-summary">
|
|
180
|
+
<div class="poll-stat-item">
|
|
181
|
+
<span class="poll-stat-icon">✅</span>
|
|
182
|
+
<span class="poll-stat-label">已投票:</span>
|
|
183
|
+
<span class="poll-stat-value">${votedMembers.size}人</span>
|
|
184
|
+
</div>
|
|
185
|
+
<div class="poll-stat-item">
|
|
186
|
+
<span class="poll-stat-icon">⏳</span>
|
|
187
|
+
<span class="poll-stat-label">未投票:</span>
|
|
188
|
+
<span class="poll-stat-value">${(poll.totalMembers || 0) - votedMembers.size}人</span>
|
|
189
|
+
</div>
|
|
190
|
+
<div class="poll-stat-item">
|
|
191
|
+
<span class="poll-stat-icon">📊</span>
|
|
192
|
+
<span class="poll-stat-label">总票数:</span>
|
|
193
|
+
<span class="poll-stat-value">${totalVotes}票</span>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<!-- 投票选项列表 -->
|
|
165
198
|
<div class="poll-options-modern">
|
|
166
|
-
${poll.options.map(option => {
|
|
199
|
+
${poll.options.map((option, index) => {
|
|
167
200
|
const percentage = totalVotes > 0 ? Math.round((option.votes || 0) / totalVotes * 100) : 0;
|
|
201
|
+
const voters = option.voters || [];
|
|
168
202
|
return `
|
|
169
203
|
<div class="poll-option-modern">
|
|
170
204
|
<div class="poll-option-header-modern">
|
|
171
205
|
<span class="poll-option-text-modern">${option.text}</span>
|
|
172
|
-
<span class="poll-option-count-modern">${option.votes || 0}
|
|
206
|
+
<span class="poll-option-count-modern">${option.votes || 0} 票 (${percentage}%)</span>
|
|
173
207
|
</div>
|
|
174
208
|
<div class="poll-option-bar-modern">
|
|
175
209
|
<div class="poll-option-fill-modern" style="width: ${percentage}%"></div>
|
|
176
210
|
</div>
|
|
211
|
+
${voters.length > 0 ? `
|
|
212
|
+
<div class="poll-voters-list">
|
|
213
|
+
<div class="poll-voters-header">
|
|
214
|
+
<span class="poll-voters-icon">👥</span>
|
|
215
|
+
<span class="poll-voters-title">投票成员 (${voters.length}人):</span>
|
|
216
|
+
</div>
|
|
217
|
+
<div class="poll-voters-tags">
|
|
218
|
+
${voters.map(voter => {
|
|
219
|
+
const voterName = typeof voter === 'string' ? voter : voter.username;
|
|
220
|
+
return `
|
|
221
|
+
<span class="poll-voter-tag">
|
|
222
|
+
<span class="voter-avatar">${voterName ? voterName[0].toUpperCase() : '?'}</span>
|
|
223
|
+
<span class="voter-name">${voterName || '未知用户'}</span>
|
|
224
|
+
</span>
|
|
225
|
+
`;
|
|
226
|
+
}).join('')}
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
` : `
|
|
230
|
+
<div class="poll-voters-empty">
|
|
231
|
+
<span class="empty-icon">📭</span>
|
|
232
|
+
<span class="empty-text">暂无人投票</span>
|
|
233
|
+
</div>
|
|
234
|
+
`}
|
|
177
235
|
</div>
|
|
178
236
|
`;
|
|
179
237
|
}).join('')}
|
|
180
238
|
</div>
|
|
181
|
-
|
|
239
|
+
|
|
240
|
+
<!-- 未投票成员列表 -->
|
|
241
|
+
${renderUnvotedMembers(poll, votedMembers)}
|
|
182
242
|
</div>
|
|
183
243
|
`;
|
|
184
244
|
}
|
|
185
245
|
|
|
186
|
-
//
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
246
|
+
// 渲染未投票成员列表
|
|
247
|
+
function renderUnvotedMembers(poll, votedMembers) {
|
|
248
|
+
if (!poll.allMembers || poll.allMembers.length === 0) return '';
|
|
249
|
+
|
|
250
|
+
const unvotedMembers = poll.allMembers.filter(member => {
|
|
251
|
+
const memberName = typeof member === 'string' ? member : member.username;
|
|
252
|
+
return !votedMembers.has(memberName);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
if (unvotedMembers.length === 0) {
|
|
256
|
+
return `
|
|
257
|
+
<div class="poll-unvoted-section all-voted">
|
|
258
|
+
<div class="poll-unvoted-header">
|
|
259
|
+
<span class="unvoted-icon">✅</span>
|
|
260
|
+
<span class="unvoted-title">所有成员已完成投票</span>
|
|
199
261
|
</div>
|
|
200
262
|
</div>
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
263
|
+
`;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return `
|
|
267
|
+
<div class="poll-unvoted-section">
|
|
268
|
+
<div class="poll-unvoted-header">
|
|
269
|
+
<span class="unvoted-icon">⚠️</span>
|
|
270
|
+
<span class="unvoted-title">未投票成员 (${unvotedMembers.length}人):</span>
|
|
271
|
+
</div>
|
|
272
|
+
<div class="poll-unvoted-list">
|
|
273
|
+
${unvotedMembers.map(member => {
|
|
274
|
+
const memberName = typeof member === 'string' ? member : member.username;
|
|
275
|
+
return `
|
|
276
|
+
<span class="poll-unvoted-tag">
|
|
277
|
+
<span class="unvoted-avatar">${memberName ? memberName[0].toUpperCase() : '?'}</span>
|
|
278
|
+
<span class="unvoted-name">${memberName || '未知用户'}</span>
|
|
279
|
+
<span class="unvoted-status">未投票</span>
|
|
280
|
+
</span>
|
|
281
|
+
`;
|
|
282
|
+
}).join('')}
|
|
205
283
|
</div>
|
|
206
284
|
</div>
|
|
207
285
|
`;
|
|
208
286
|
}
|
|
209
|
-
|
|
210
|
-
// 计算完成进度
|
|
211
287
|
function calculateProgress(task) {
|
|
212
288
|
if (!task.members || task.members.length === 0) return 0;
|
|
213
289
|
const completed = task.completedCount || 0;
|
|
@@ -776,6 +852,232 @@ function addTaskDetailStyles() {
|
|
|
776
852
|
font-size: 15px;
|
|
777
853
|
}
|
|
778
854
|
|
|
855
|
+
|
|
856
|
+
/* ========== 投票详情增强样式 ========== */
|
|
857
|
+
|
|
858
|
+
/* 投票统计摘要 */
|
|
859
|
+
.poll-stats-summary {
|
|
860
|
+
display: grid;
|
|
861
|
+
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
862
|
+
gap: 12px;
|
|
863
|
+
margin-bottom: 24px;
|
|
864
|
+
padding: 16px;
|
|
865
|
+
background: linear-gradient(135deg, rgba(99,102,241,0.05) 0%, rgba(139,92,246,0.05) 100%);
|
|
866
|
+
border-radius: 12px;
|
|
867
|
+
border: 1px solid var(--border);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
.poll-stat-item {
|
|
871
|
+
display: flex;
|
|
872
|
+
align-items: center;
|
|
873
|
+
gap: 8px;
|
|
874
|
+
padding: 12px;
|
|
875
|
+
background: var(--bg-dark);
|
|
876
|
+
border-radius: 8px;
|
|
877
|
+
border: 1px solid var(--border);
|
|
878
|
+
transition: all 0.3s ease;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
.poll-stat-item:hover {
|
|
882
|
+
transform: translateY(-2px);
|
|
883
|
+
box-shadow: 0 4px 12px rgba(99,102,241,0.2);
|
|
884
|
+
border-color: var(--primary);
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
.poll-stat-icon {
|
|
888
|
+
font-size: 20px;
|
|
889
|
+
flex-shrink: 0;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
.poll-stat-label {
|
|
893
|
+
font-size: 13px;
|
|
894
|
+
color: var(--text-secondary);
|
|
895
|
+
font-weight: 600;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
.poll-stat-value {
|
|
899
|
+
font-size: 16px;
|
|
900
|
+
color: var(--text-primary);
|
|
901
|
+
font-weight: 700;
|
|
902
|
+
margin-left: auto;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
/* 投票成员列表 */
|
|
906
|
+
.poll-voters-list {
|
|
907
|
+
margin-top: 16px;
|
|
908
|
+
padding-top: 16px;
|
|
909
|
+
border-top: 1px solid var(--border);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
.poll-voters-header {
|
|
913
|
+
display: flex;
|
|
914
|
+
align-items: center;
|
|
915
|
+
gap: 8px;
|
|
916
|
+
margin-bottom: 12px;
|
|
917
|
+
font-size: 13px;
|
|
918
|
+
color: var(--text-secondary);
|
|
919
|
+
font-weight: 600;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
.poll-voters-icon {
|
|
923
|
+
font-size: 16px;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
.poll-voters-title {
|
|
927
|
+
flex: 1;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
.poll-voters-tags {
|
|
931
|
+
display: flex;
|
|
932
|
+
flex-wrap: wrap;
|
|
933
|
+
gap: 8px;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
.poll-voter-tag {
|
|
937
|
+
display: inline-flex;
|
|
938
|
+
align-items: center;
|
|
939
|
+
gap: 8px;
|
|
940
|
+
padding: 6px 12px;
|
|
941
|
+
background: linear-gradient(135deg, rgba(99,102,241,0.1) 0%, rgba(139,92,246,0.1) 100%);
|
|
942
|
+
border: 1px solid rgba(99,102,241,0.3);
|
|
943
|
+
border-radius: 20px;
|
|
944
|
+
transition: all 0.3s ease;
|
|
945
|
+
cursor: default;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
.poll-voter-tag:hover {
|
|
949
|
+
background: linear-gradient(135deg, rgba(99,102,241,0.2) 0%, rgba(139,92,246,0.2) 100%);
|
|
950
|
+
border-color: var(--primary);
|
|
951
|
+
transform: scale(1.05);
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
.voter-avatar {
|
|
955
|
+
width: 24px;
|
|
956
|
+
height: 24px;
|
|
957
|
+
border-radius: 50%;
|
|
958
|
+
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
|
|
959
|
+
display: flex;
|
|
960
|
+
align-items: center;
|
|
961
|
+
justify-content: center;
|
|
962
|
+
font-size: 12px;
|
|
963
|
+
font-weight: 700;
|
|
964
|
+
color: white;
|
|
965
|
+
flex-shrink: 0;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
.voter-name {
|
|
969
|
+
font-size: 13px;
|
|
970
|
+
font-weight: 600;
|
|
971
|
+
color: var(--text-primary);
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
/* 空状态 */
|
|
975
|
+
.poll-voters-empty {
|
|
976
|
+
display: flex;
|
|
977
|
+
align-items: center;
|
|
978
|
+
justify-content: center;
|
|
979
|
+
gap: 8px;
|
|
980
|
+
padding: 16px;
|
|
981
|
+
margin-top: 12px;
|
|
982
|
+
background: rgba(239,68,68,0.05);
|
|
983
|
+
border: 1px dashed rgba(239,68,68,0.3);
|
|
984
|
+
border-radius: 8px;
|
|
985
|
+
color: var(--text-secondary);
|
|
986
|
+
font-size: 13px;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
.empty-icon {
|
|
990
|
+
font-size: 18px;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
.empty-text {
|
|
994
|
+
font-weight: 500;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
/* 未投票成员区域 */
|
|
998
|
+
.poll-unvoted-section {
|
|
999
|
+
margin-top: 24px;
|
|
1000
|
+
padding: 20px;
|
|
1001
|
+
background: linear-gradient(135deg, rgba(239,68,68,0.05) 0%, rgba(220,38,38,0.05) 100%);
|
|
1002
|
+
border: 1px solid rgba(239,68,68,0.2);
|
|
1003
|
+
border-radius: 12px;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
.poll-unvoted-section.all-voted {
|
|
1007
|
+
background: linear-gradient(135deg, rgba(16,185,129,0.05) 0%, rgba(5,150,105,0.05) 100%);
|
|
1008
|
+
border-color: rgba(16,185,129,0.3);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
.poll-unvoted-header {
|
|
1012
|
+
display: flex;
|
|
1013
|
+
align-items: center;
|
|
1014
|
+
gap: 10px;
|
|
1015
|
+
margin-bottom: 16px;
|
|
1016
|
+
font-size: 15px;
|
|
1017
|
+
font-weight: 700;
|
|
1018
|
+
color: var(--text-primary);
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
.unvoted-icon {
|
|
1022
|
+
font-size: 20px;
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
.unvoted-title {
|
|
1026
|
+
flex: 1;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
.poll-unvoted-list {
|
|
1030
|
+
display: flex;
|
|
1031
|
+
flex-wrap: wrap;
|
|
1032
|
+
gap: 10px;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
.poll-unvoted-tag {
|
|
1036
|
+
display: inline-flex;
|
|
1037
|
+
align-items: center;
|
|
1038
|
+
gap: 8px;
|
|
1039
|
+
padding: 8px 14px;
|
|
1040
|
+
background: var(--bg-dark);
|
|
1041
|
+
border: 2px solid rgba(239,68,68,0.3);
|
|
1042
|
+
border-radius: 20px;
|
|
1043
|
+
transition: all 0.3s ease;
|
|
1044
|
+
cursor: default;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
.poll-unvoted-tag:hover {
|
|
1048
|
+
background: rgba(239,68,68,0.1);
|
|
1049
|
+
border-color: var(--danger);
|
|
1050
|
+
transform: scale(1.05);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
.unvoted-avatar {
|
|
1054
|
+
width: 28px;
|
|
1055
|
+
height: 28px;
|
|
1056
|
+
border-radius: 50%;
|
|
1057
|
+
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
|
1058
|
+
display: flex;
|
|
1059
|
+
align-items: center;
|
|
1060
|
+
justify-content: center;
|
|
1061
|
+
font-size: 13px;
|
|
1062
|
+
font-weight: 700;
|
|
1063
|
+
color: white;
|
|
1064
|
+
flex-shrink: 0;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
.unvoted-name {
|
|
1068
|
+
font-size: 14px;
|
|
1069
|
+
font-weight: 600;
|
|
1070
|
+
color: var(--text-primary);
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
.unvoted-status {
|
|
1074
|
+
font-size: 11px;
|
|
1075
|
+
font-weight: 600;
|
|
1076
|
+
color: var(--danger);
|
|
1077
|
+
background: rgba(239,68,68,0.1);
|
|
1078
|
+
padding: 2px 8px;
|
|
1079
|
+
border-radius: 10px;
|
|
1080
|
+
}
|
|
779
1081
|
@media (max-width: 768px) {
|
|
780
1082
|
.task-detail-header-modern {
|
|
781
1083
|
flex-direction: column;
|