-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
1272 lines (1142 loc) · 58.4 KB
/
index.html
File metadata and controls
1272 lines (1142 loc) · 58.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>荣格八维全息测评系统 (移动端适配版)</title>
<!-- 引入 Marked.js -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<style>
:root {
--primary: #2c3e50;
--accent: #3498db;
--accent-hover: #2980b9;
--bg: #f4f6f9;
--card-bg: #ffffff;
--text: #2c3e50;
--border: #e1e4e8;
--shadow: 0 4px 20px rgba(0,0,0,0.05);
--radius: 12px;
--chat-user: #e3f2fd;
--chat-ai: #ffffff;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background-color: var(--bg);
color: var(--text);
margin: 0;
padding: 0;
height: 100vh;
overflow: hidden;
}
.app-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
/* 页面通用 */
.page {
display: none;
flex: 1;
flex-direction: column;
overflow-y: auto;
padding: 20px;
animation: fadeIn 0.3s ease;
-webkit-overflow-scrolling: touch;
}
.page.active { display: flex; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
/* 首页 */
.home-content {
max-width: 900px;
width: 100%;
margin: auto;
text-align: center;
background: var(--card-bg);
padding: 50px;
border-radius: var(--radius);
box-shadow: var(--shadow);
}
.mode-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
gap: 15px;
margin: 40px 0;
}
.mode-card {
border: 2px solid var(--border);
border-radius: 12px;
padding: 20px;
cursor: pointer;
transition: all 0.2s;
}
.mode-card:hover { border-color: var(--accent); background: #ebf5fb; }
.mode-card.selected { border-color: var(--accent); background: var(--accent); color: white; }
.mode-card.selected p { color: rgba(255,255,255,0.9); }
.btn-start {
background: var(--primary);
color: white;
border: none;
padding: 15px 60px;
font-size: 1.2rem;
border-radius: 30px;
cursor: pointer;
transition: transform 0.1s;
box-shadow: 0 4px 15px rgba(44, 62, 80, 0.3);
width: 100%;
max-width: 300px;
}
.btn-start:hover { transform: scale(1.05); background: #1a252f; }
.btn-import {
margin-top: 20px;
background: transparent;
border: 1px dashed #aaa;
padding: 10px 20px;
border-radius: 20px;
cursor: pointer;
color: #666;
font-size: 0.9rem;
}
/* 答题页 */
.quiz-container {
max-width: 800px;
width: 100%;
margin: auto;
background: var(--card-bg);
padding: 40px;
border-radius: var(--radius);
box-shadow: var(--shadow);
min-height: 60vh;
display: flex;
flex-direction: column;
}
.progress-bar { height: 8px; background: #eee; border-radius: 4px; margin-bottom: 20px; overflow: hidden; }
.progress-fill { height: 100%; background: var(--accent); width: 0%; transition: width 0.3s; }
.question-text {
font-size: 1.4rem;
font-weight: 500;
margin: 30px 0;
line-height: 1.6;
text-align: center;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.options-row { display: flex; gap: 10px; margin-bottom: 20px; }
.opt-btn {
flex: 1;
padding: 15px 5px;
border: 1px solid var(--border);
background: white;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s;
font-size: 0.95rem;
min-height: 50px;
display: flex;
align-items: center;
justify-content: center;
}
.opt-btn:active { transform: scale(0.98); }
.opt-1:hover, .opt-1:active { background: #ffebee; border-color: #ef5350; color: #c62828; }
.opt-2:hover, .opt-2:active { background: #fff3e0; border-color: #ff9800; color: #ef6c00; }
.opt-3:hover, .opt-3:active { background: #f5f5f5; border-color: #9e9e9e; color: #616161; }
.opt-4:hover, .opt-4:active { background: #e8f5e9; border-color: #66bb6a; color: #2e7d32; }
.opt-5:hover, .opt-5:active { background: #e3f2fd; border-color: #42a5f5; color: #1565c0; }
/* 结果页布局 */
.result-layout {
display: flex;
height: 100%;
gap: 20px;
max-width: 1600px;
margin: 0 auto;
width: 100%;
padding: 0 20px 20px 20px;
}
.left-panel {
width: 380px;
background: var(--card-bg);
border-radius: var(--radius);
padding: 25px;
overflow-y: auto;
box-shadow: var(--shadow);
flex-shrink: 0;
display: flex;
flex-direction: column;
}
.right-panel {
flex: 1;
background: var(--card-bg);
border-radius: var(--radius);
display: flex;
flex-direction: column;
box-shadow: var(--shadow);
overflow: hidden;
}
.chart-row { display: flex; align-items: center; margin-bottom: 15px; font-size: 0.9rem; }
.chart-label-container {
width: 40px;
position: relative;
cursor: help;
}
.chart-label { font-weight: bold; color: var(--primary); border-bottom: 1px dotted #999; }
.chart-label-container:hover::after {
content: attr(data-tooltip);
position: absolute;
left: 100%;
top: 50%;
transform: translateY(-50%);
background: #333;
color: white;
padding: 10px 15px;
border-radius: 6px;
font-size: 0.85rem;
white-space: normal;
width: 240px;
line-height: 1.4;
text-align: left;
z-index: 100;
margin-left: 10px;
box-shadow: 0 4px 10px rgba(0,0,0,0.2);
pointer-events: none;
}
.chart-label-container:hover::before {
content: '';
position: absolute;
left: 100%;
top: 50%;
transform: translateY(-50%);
border-width: 5px;
border-style: solid;
border-color: transparent #333 transparent transparent;
margin-left: 0px;
}
.chart-track { flex: 1; height: 12px; background: #f0f0f0; border-radius: 6px; margin: 0 12px; overflow: hidden; }
.chart-fill { height: 100%; background: var(--accent); border-radius: 6px; transition: width 1s ease; }
.chart-val { width: 45px; text-align: right; font-family: monospace; font-weight: bold; }
.type-badge {
font-size: 3.5rem;
font-weight: 800;
color: var(--accent);
text-align: center;
margin: 10px 0;
letter-spacing: 2px;
}
.chat-header {
padding: 15px;
border-bottom: 1px solid var(--border);
background: #fafafa;
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
}
.ai-tab {
padding: 6px 12px;
border-radius: 20px;
border: 1px solid var(--border);
background: white;
cursor: pointer;
font-size: 0.85rem;
transition: all 0.2s;
color: #666;
flex-grow: 1;
text-align: center;
}
.ai-tab.active { background: var(--accent); color: white; border-color: var(--accent); }
.chat-messages {
flex: 1;
overflow-y: auto;
padding: 15px;
display: flex;
flex-direction: column;
gap: 15px;
background: #fcfcfc;
}
.message {
max-width: 95%;
padding: 12px 16px;
border-radius: 12px;
line-height: 1.6;
font-size: 0.95rem;
position: relative;
word-wrap: break-word;
}
.msg-ai {
align-self: flex-start;
background: var(--chat-ai);
border: 1px solid #eee;
border-bottom-left-radius: 2px;
}
.msg-user {
align-self: flex-end;
background: var(--chat-user);
color: #1565c0;
border-bottom-right-radius: 2px;
}
.chat-input-area {
padding: 15px;
background: white;
border-top: 1px solid var(--border);
display: flex;
gap: 10px;
}
.chat-input {
flex: 1;
padding: 10px;
border: 1px solid var(--border);
border-radius: 8px;
font-size: 1rem;
outline: none;
}
.btn-send {
padding: 0 20px;
background: var(--accent);
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: bold;
white-space: nowrap;
}
.action-btns {
display: flex;
gap: 10px;
margin-top: 20px;
}
.btn-action {
flex: 1;
padding: 12px;
border: 1px solid #ddd;
background: white;
border-radius: 8px;
cursor: pointer;
color: #666;
font-size: 0.9rem;
}
.markdown-body h1, .markdown-body h2 { font-size: 1.2em; margin-top: 1em; }
.markdown-body p { margin-bottom: 0.8em; }
.markdown-body ul { padding-left: 20px; }
.cursor::after {
content: '▋';
display: inline-block;
animation: blink 1s infinite;
color: var(--accent);
margin-left: 2px;
}
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
@media (max-width: 900px) {
body {
height: auto;
overflow-y: auto;
overflow-x: hidden;
}
.app-container {
height: auto;
min-height: 100vh;
}
.page {
padding: 15px;
height: auto;
overflow: visible;
}
.home-content {
padding: 30px 20px;
margin-top: 20px;
}
.mode-grid {
grid-template-columns: repeat(2, 1fr);
}
.quiz-container {
padding: 20px;
min-height: auto;
}
.question-text {
font-size: 1.2rem;
margin: 20px 0;
min-height: 100px;
}
.options-row {
flex-direction: column;
gap: 12px;
}
.opt-btn {
padding: 12px;
width: 100%;
text-align: center;
font-size: 1rem;
}
.result-layout {
flex-direction: column;
padding: 0 10px 20px 10px;
height: auto;
}
.left-panel {
width: 100%;
height: auto;
margin-bottom: 20px;
padding: 20px;
}
.right-panel {
width: 100%;
height: 600px;
flex: none;
}
.chart-label-container:hover::after {
left: 0;
top: 100%;
transform: translateY(5px);
margin-left: 0;
width: 200px;
z-index: 999;
}
.chart-label-container:hover::before {
display: none;
}
.type-badge { font-size: 2.8rem; }
.chat-header span { width: 100%; margin-bottom: 5px; }
}
</style>
</head>
<body>
<div class="app-container">
<!-- 1. 首页 -->
<div id="page-home" class="page active">
<div class="home-content">
<h1 style="margin-bottom: 10px; font-size: 1.8rem;">荣格八维全息测评</h1>
<div style="color: #7f8c8d; font-size: 1rem;">基于认知功能动力学的深度人格解析</div>
<div class="mode-grid">
<div class="mode-card" onclick="selectMode(32, this)">
<h3>32题</h3><p>快速概览</p>
</div>
<div class="mode-card" onclick="selectMode(64, this)">
<h3>64题</h3><p>标准测试</p>
</div>
<div class="mode-card selected" onclick="selectMode(96, this)">
<h3>96题</h3><p>深度分析</p>
</div>
<div class="mode-card" onclick="selectMode(144, this)">
<h3>144题</h3><p>专业剖析</p>
</div>
<div class="mode-card" onclick="selectMode(256, this)">
<h3>256题</h3><p>全息扫描</p>
</div>
</div>
<button class="btn-start" onclick="startQuiz()">开始探索</button>
<br>
<button class="btn-import" onclick="document.getElementById('file-input').click()">📂 导入历史结果</button>
<input type="file" id="file-input" style="display: none;" accept=".json" onchange="importData(this)">
</div>
</div>
<!-- 2. 答题页 -->
<div id="page-quiz" class="page">
<div class="quiz-container">
<div class="progress-bar"><div class="progress-fill" id="progress"></div></div>
<div style="display:flex; justify-content:space-between; color:#999; font-size:0.9rem; margin-bottom: 10px;">
<span>进度: <span id="curr-idx">1</span> / <span id="total-count">96</span></span>
<button onclick="undo()" id="btn-undo" style="background:none; border:none; color:#999; cursor:pointer; text-decoration:underline; padding: 0;" disabled>↩ 撤回</button>
</div>
<div class="question-text" id="q-text">加载中...</div>
<div class="options-row">
<button class="opt-btn opt-1" onclick="handleAnswer(1)">完全不符</button>
<button class="opt-btn opt-2" onclick="handleAnswer(2)">不太符合</button>
<button class="opt-btn opt-3" onclick="handleAnswer(3)">中立/不确定</button>
<button class="opt-btn opt-4" onclick="handleAnswer(4)">比较符合</button>
<button class="opt-btn opt-5" onclick="handleAnswer(5)">完全符合</button>
</div>
</div>
</div>
<!-- 3. 结果页 -->
<div id="page-result" class="page" style="padding: 0; background: #eef2f5;">
<div class="result-layout">
<!-- 左侧:数据统计 -->
<div class="left-panel">
<h3 style="text-align:center; margin-top:0; color:#666;">您的核心人格</h3>
<div class="type-badge" id="res-type">INTJ</div>
<div style="margin-top: 20px;">
<h4 style="border-bottom: 2px solid #eee; padding-bottom: 10px;">八维功能强度</h4>
<div style="font-size: 0.8rem; color: #999; margin-bottom: 10px;">* 点击/悬停标签查看含义</div>
<div id="chart-container"></div>
</div>
<div style="margin-top: 30px;">
<h4 style="border-bottom: 2px solid #eee; padding-bottom: 10px;">原型匹配度 (Top 5)</h4>
<div id="match-container" style="font-size:0.9rem;"></div>
</div>
<div class="action-btns">
<button class="btn-action" onclick="exportData()">💾 保存</button>
<button class="btn-action" onclick="location.reload()">🔄 重测</button>
</div>
</div>
<!-- 右侧:AI 交互面板 -->
<div class="right-panel">
<div class="chat-header">
<span style="font-weight: bold;">AI 深度咨询:</span>
<div style="display:flex; gap:5px; width:100%;">
<button class="ai-tab active" onclick="switchAiTab('general')">🧠 解析</button>
<button class="ai-tab" onclick="switchAiTab('career')">💼 职业</button>
<button class="ai-tab" onclick="switchAiTab('love')">❤️ 情感</button>
</div>
</div>
<div class="chat-messages" id="chat-box">
<!-- 消息流 -->
</div>
<div class="chat-input-area">
<input type="text" class="chat-input" id="user-input" placeholder="输入问题..." onkeypress="if(event.keyCode==13) sendMessage()">
<button class="btn-send" onclick="sendMessage()">发送</button>
</div>
</div>
</div>
</div>
</div>
<script>
// --- 0. 基础配置与数据 ---
// 注意:API_KEY 已移除,现在通过后端 /api/chat 代理请求
if (typeof marked !== 'undefined') {
marked.setOptions({
breaks: true,
gfm: true
});
}
const funcDefinitions = {
"Te": "外倾思考:关注效率、资源调度、外部秩序、结果导向。",
"Ti": "内倾思考:关注逻辑自洽、原理解构、精确定义、独立思考。",
"Fe": "外倾情感:关注人际和谐、社会规范、情绪共鸣、群体价值。",
"Fi": "内倾情感:关注核心价值、真诚体验、个体独特性、内心评判。",
"Se": "外倾感觉:关注当下体验、感官刺激、物理互动、即兴反应。",
"Si": "内倾感觉:关注过往经验、细节记忆、身体稳态、程序规范。",
"Ne": "外倾直觉:关注可能性、发散思维、概念关联、头脑风暴。",
"Ni": "内倾直觉:关注本质规律、未来趋势、宏观愿景、直觉洞察。"
};
// 题库 (256题)
const rawText = `
1. 我认为自己是一个在混乱局面中能迅速建立指挥链条的人。
2. 我习惯通过可视化的图表、数据或KPI来衡量自己一天的成就感。
3. 我觉得自己是一个“终结者”,比起开启新项目,我更擅长推进项目直到完工。
4. 我认为客观的规则和标准比个人的特殊情况更重要,因为这样才公平。
5. 我觉得自己对他人的无能或低效率容忍度很低,容易因此感到烦躁。
6. 我倾向于直接指出问题所在,而不是为了照顾面子而委婉表达。
7. 我认为自己是一个极其重视时间表的人,延期对我来说是严重的失误。
8. 我觉得自己通过掌控外部环境(如整理房间、管理团队)来获得安全感。
9. 朋友或同事经常评价我说话“一针见血”,有时甚至显得有点不近人情。
10. 别人常说在做决定时,我显得非常果断,几乎不带犹豫。
11. 在团队合作中,大家倾向于推举我来分配任务和监督进度。
12. 别人经常向我咨询如何优化流程或提高办事效率的建议。
13. 亲近的人有时会抱怨我过于关注事情的“对错”而忽略了他们的心情。
14. 别人认为我是一个非常有野心且目标明确的人。
15. 同事们觉得我是一个非常看重层级秩序和执行力的人。
16. 别人常说我看起来很忙碌,总是处于一种“正在解决问题”的状态。
17. 相比于探索一个理论的深层含义,我更喜欢验证它在现实中是否管用。
18. 我更喜欢与那些说话简练、直奔主题的人交流,而不是铺垫很多的人。
19. 我更看重一个人的实际产出和业绩,而不是他的努力程度或初衷。
20. 我喜欢制定详细的待办事项清单(To-Do List),并享受划掉它们的快感。
21. 相比于“和谐但低效”的团队氛围,我更偏向“紧张但高效”的工作环境。
22. 我更喜欢阅读非虚构类的、能提供具体方法论的书籍,而不是纯文学。
23. 我讨厌模棱两可的指令,我喜欢清晰明确的步骤和截止日期。
24. 我更倾向于掌控资源和局面,而不是作为一个配合者。
25. 当团队讨论陷入无休止的争论时,我会打断大家并强制做出一个决定。
26. 如果发现购买的商品有质量问题,我会立即查找退换货政策并坚决维权。
27. 在制定旅行计划时,我会精确到每个时间段的交通衔接和预算控制。
28. 当面对一个复杂的任务时,我的第一反应是把它拆解成可执行的步骤分配下去。
29. 如果必须裁员以保全公司,我会依据绩效数据执行,尽量不掺杂个人情感。
30. 看到有人违反明确的规定(如插队),我会倾向于出面制止或要求管理者介入。
31. 在玩策略游戏时,我倾向于通过资源碾压或快速扩张来获胜。
32. 当我发现现有的工作流程繁琐时,我会立刻着手设计一套新流程来替代它。
33. 我觉得自己是一个必须把事情的底层原理彻底搞懂才能安心的人。
34. 我认为逻辑的一致性比达成外部目标更重要,哪怕这会拖慢进度。
35. 我经常在脑海中对自己使用的词汇进行重新定义,以确保精确无误。
36. 我觉得自己是一个独立的观察者,习惯与世界保持距离来冷静分析。
37. 我认为真理是独立的,不应该受到权威或大多数人意见的左右。
38. 我觉得自己擅长发现别人论点中的逻辑漏洞,并忍不住想指出来。
39. 我经常陷入长时间的沉思,构建复杂的思维模型,而不在乎是否实用。
40. 我认为自己是一个“极简主义者”,倾向于用最少的原则解释最多的现象。
41. 别人常说我喜欢“钻牛角尖”或在无关紧要的细节上争论不休。
42. 朋友们觉得我很难被说服,除非他们能拿出无懈可击的逻辑证据。
43. 别人经常评价我看起来很冷淡,好像总是活在自己的头脑里。
44. 大家认为我是一个很好的故障排除者,总能找到系统崩溃的根本原因。
45. 别人常说我解释问题时过于复杂,使用了太多专业术语或抽象概念。
46. 亲近的人觉得我对他人的情感需求反应迟钝,总是试图用逻辑解决情绪问题。
47. 同事们认为我适合做研发或分析工作,而不是管理或销售。
48. 别人常惊讶于我能在混乱的信息中梳理出一条清晰的逻辑线索。
49. 我更喜欢“为了知识而知识”,而不是为了应用而学习。
50. 相比于遵循既定的操作手册,我更喜欢自己摸索出一套独特的方法。
51. 我讨厌被强加的规则,除非这些规则在逻辑上能说服我。
52. 我更喜欢独自解决复杂的智力谜题,而不是在团队中通过头脑风暴解决。
53. 我倾向于保留判断,直到我收集了足够的信息并完成了内部推导。
54. 我更看重思维的准确性和严密性,而不是说话的速度或感染力。
55. 我喜欢拆解机械装置或软件代码,看看它们内部是如何运作的。
56. 相比于获得他人的赞赏,我更在乎自己的理论模型是否完美自洽。
57. 当别人在谈论一个我不认同的观点时,我会先在心里默默反驳他的逻辑谬误。
58. 如果老师或上司说了一个错误的结论,我会倾向于当场或事后纠正他。
59. 在购买电子产品时,我会花大量时间研究参数对比,而不是听导购推荐。
60. 当面对一个情绪崩溃的朋友,我的第一反应是分析他为什么会这样,并提供解决方案。
61. 如果一项任务没有合理的逻辑理由,即使有报酬,我也很难强迫自己去执行。
62. 在辩论中,如果发现自己之前的观点有逻辑漏洞,我会毫不犹豫地推翻自己。
63. 当需要学习新技能时,我会先找原理书看,而不是直接上手操作。
64. 面对社会热点新闻,我倾向于分析各方利益链条和逻辑关系,而不是站队表态。
65. 我觉得自己像一个“情绪温度计”,能瞬间感知到房间里气氛的变化。
66. 我认为维护群体的和谐与团结比坚持我个人的正确更重要。
67. 我觉得自己有责任照顾每个人的感受,确保没有人感到被冷落。
68. 我倾向于根据交谈对象的不同,自然地调整自己的语气和举止。
69. 我认为礼貌、得体和遵守社会规范是人际交往的基石。
70. 我觉得自己很容易被他人的情绪感染,看到别人哭我也想哭。
71. 我经常为了不让别人失望而答应一些我其实不想做的事情。
72. 我认为自己是一个很好的倾听者和调解者,擅长化解人际冲突。
73. 朋友们常说我是团队的“粘合剂”,有我在大家就会很开心。
74. 别人经常评价我非常贴心、温暖,总是能照顾到细节。
75. 有人可能会觉得我有点“老好人”,缺乏明确的个人界限。
76. 大家倾向于向我倾诉烦恼,因为觉得我会给予情感上的支持。
77. 别人常说我非常擅长社交辞令,能让尴尬的场面变得顺滑。
78. 亲近的人有时觉得我过于在意别人的看法,活得有点累。
79. 同事们认为我非常适合做公关、HR或教育类的工作。
80. 别人常惊讶于我能记得他们的生日、喜好等微小的个人信息。
81. 我更喜欢大家一起开心合作的氛围,而不是通过残酷竞争分出胜负。
82. 我倾向于公开表达我的感激和赞赏,也希望得到同样的反馈。
83. 我更看重人际关系的亲密度和信任感,而不是纯粹的利益交换。
84. 我喜欢组织聚会或活动,看到大家享受其中我会非常有成就感。
85. 相比于独自做决定,我更倾向于征求大家的意见,达成共识。
86. 我讨厌冲突和争吵,我会尽一切努力去平息事态。
87. 我更喜欢遵循主流的价值观和道德标准,而不是特立独行。
88. 我倾向于通过帮助他人来实现自我价值,而不是独自取得成就。
89. 在聚餐时,如果有人点的菜还没上,我会主动催促服务员并安抚那个人的情绪。
90. 当朋友送了我一个我不喜欢的礼物时,我会表现得非常开心以避免伤害他。
91. 如果团队中有人因为失误被责骂,我会私下里去安慰他并帮他分担。
92. 在做决定时,我会首先考虑“这对其他人会有什么影响”,而不是“我想怎么做”。
93. 看到有人在社交场合被孤立,我会主动走过去和他搭话。
94. 如果我和朋友发生矛盾,我会主动道歉或示好,因为我受不了冷战的氛围。
95. 在观看感人的电影或新闻时,我通常会毫不掩饰地流露情感。
96. 当面对道德困境时,我会参考社会普遍的看法或身边人的建议来做判断。
97. 我觉得自己内心深处有一套不可动摇的价值观,即使与世界为敌也要坚守。
98. 我认为“忠于自我”是人生最重要的课题,我极度反感虚伪和做作。
99. 我觉得自己情感丰富且深沉,但通常只在内心翻涌,很少表露在外。
100. 我倾向于用个人的喜恶和道德直觉来做决定,而不是逻辑利弊。
101. 我认为每个人都是独一无二的个体,不应该被标签化或强制同化。
102. 我觉得自己对他人的痛苦有很深的共情,但这种共情是内化的、静默的。
103. 我经常审视自己的动机,确保我的行为符合我的良知。
104. 我觉得自己像一个“守护者”,默默守护着那些被忽视的弱者或小众群体。
105. 别人常说我看起来很安静、神秘,让人捉摸不透我在想什么。
106. 朋友们觉得我非常有个性,穿衣打扮或兴趣爱好都很独特。
107. 别人经常评价我有点“固执”,一旦认定的事情九头牛都拉不回。
108. 大家认为我是一个非常真诚的人,从不为了迎合他人而撒谎。
109. 亲近的人觉得我情绪起伏很大,虽然我表面上可能看起来很平静。
110. 别人常说我对艺术、音乐或文学有独特的品味和深刻的理解。
111. 同事们觉得我不太合群,更喜欢独自工作或沉浸在自己的世界里。
112. 别人常惊讶于我在某些原则性问题上表现出的激烈反应。
113. 我更喜欢深入的一对一交流,而不是肤浅的群体社交。
114. 我倾向于选择能表达自我个性的工作,而不是仅仅为了赚钱。
115. 我更看重内心的平静和满足,而不是外界的地位和名声。
116. 我讨厌被告知“你应该怎么做”,我只听从内心的声音。
117. 我喜欢沉浸在悲伤、忧郁等复杂情绪中,认为这也是一种美。
118. 相比于广泛的交友,我更倾向于拥有几个灵魂契合的知己。
119. 我更喜欢支持那些有意义但冷门的项目,而不是随大流。
120. 我倾向于通过创作(写作、绘画等)来宣泄和整理我的情感。
121. 如果公司要求我做一件违背我良心的事情,我会毫不犹豫地辞职。
122. 当看到有人被霸凌时,我会因为强烈的义愤而挺身而出,哪怕我很害怕。
123. 在社交场合,如果话题我不感兴趣,我会选择沉默或神游,而不是假装投入。
124. 当朋友向我诉苦时,我会静静地陪伴他,而不是急着给他出主意。
125. 如果我不喜欢一个人,我很难对他挤出笑容,哪怕是出于礼貌。
126. 在做职业规划时,我会优先考虑“这是否是我热爱的”,而不是“这是否有前途”。
127. 当我的个人空间被侵犯时,我会表现出强烈的防御性。
128. 面对他人的误解,如果解释不清,我倾向于不解释,相信懂我的人自然懂。
129. 我觉得自己是一个活在当下的人,很少为过去后悔或为未来焦虑。
130. 我认为身体的直接体验(触觉、味觉、动感)比抽象的理论更真实。
131. 我觉得自己反应极快,擅长处理突发状况和危机公关。
132. 我倾向于通过行动来解决问题,而不是坐下来讨论方案。
133. 我认为生活就应该充满刺激和变化,平淡无奇的日子让我窒息。
134. 我觉得自己对周围环境的物理细节(颜色、声音、光线)非常敏感。
135. 我喜欢展示自己,享受成为众人目光焦点的感觉。
136. 我觉得自己是一个机会主义者,能敏锐地捕捉到眼前的利益。
137. 朋友们常说我精力充沛,总是拉着他们去尝试各种新奇好玩的活动。
138. 别人经常评价我胆子大,敢于冒险,甚至有点鲁莽。
139. 大家认为我是一个时尚达人,对穿搭、美食或潮流非常有研究。
140. 别人常说我做事“三分钟热度”,很难长期坚持枯燥的任务。
141. 亲近的人觉得我有点冲动,经常不计后果地行事。
142. 同事们认为我非常适合做现场执行、销售或表演类的工作。
143. 别人常惊讶于我的动手能力,能很快学会操作复杂的器械。
144. 大家觉得我是一个很现实的人,只相信眼见为实。
145. 我更喜欢户外运动或竞技游戏,而不是宅在家里看书。
146. 我倾向于购买高品质、高颜值的实物,享受物质带来的快乐。
147. 我更看重即时的满足感,而不是延迟满足。
148. 我喜欢与人进行直接的身体接触(如拥抱、击掌)或眼神交流。
149. 相比于制定长远的计划,我更喜欢“走一步看一步”。
150. 我讨厌抽象的哲学讨论,觉得那是浪费时间,不如去干点实事。
151. 我更喜欢快节奏、高强度的生活方式,而不是慢节奏的隐居。
152. 我倾向于通过感官冲击(如大声的音乐、辛辣的食物)来释放压力。
153. 在游乐场,我会毫不犹豫地选择最刺激的过山车或跳楼机。
154. 当发生紧急事故(如火灾)时,我会本能地冲上去救人或灭火,而不是惊慌失措。
155. 如果手里有一笔闲钱,我会倾向于去旅行或买奢侈品,而不是存起来。
156. 在聚会上,我会主动炒热气氛,唱歌跳舞或讲笑话。
157. 当面对复杂的说明书时,我会直接扔到一边,自己动手试错。
158. 如果有人挑衅我,我会倾向于直接回击(语言或肢体),而不是忍气吞声。
159. 在做决定时,我会依据当前的形势迅速拍板,而不是反复权衡。
160. 看到美丽的风景,我会立刻拿出手机拍照打卡,并分享到社交媒体。
161. 我觉得自己是一个非常念旧的人,珍视传统、回忆和老物件。
162. 我认为“按部就班”是最高效的,因为这样可以避免不必要的风险。
163. 我觉得自己对身体的内部感觉(如饥饿、疲劳、疼痛)非常敏感。
164. 我倾向于通过对比过去和现在来判断事物是否正常。
165. 我认为细节决定成败,我无法容忍数据或事实上的微小偏差。
166. 我觉得自己需要稳定的日常惯例(Routine)来维持内心的平静。
167. 我经常在脑海中像放电影一样回放过去的场景,细节清晰可见。
168. 我觉得自己是一个守成者,比起创新,我更擅长维护和优化现有体系。
169. 朋友们常说我记性好得可怕,能记得几年前发生的琐事。
170. 别人经常评价我做事稳重、靠谱,把事情交给我很放心。
171. 大家认为我有点墨守成规,不喜欢改变现状或尝试新事物。
172. 别人常说我非常节俭,懂得未雨绸缪,总是有备用方案。
173. 亲近的人觉得我有点唠叨,总是重复提起过去的经验教训。
174. 同事们认为我非常适合做财务、档案管理或质检类的工作。
175. 别人常惊讶于我对流程和规则的熟悉程度,简直是活字典。
176. 大家觉得我是一个很恋家的人,喜欢舒适熟悉的环境。
177. 我更喜欢去熟悉的餐厅点同样的菜,而不是去新开的店踩雷。
178. 我倾向于遵循前辈总结出来的经验方法,而不是自己瞎折腾。
179. 我更看重生活的稳定性和安全感,而不是刺激和挑战。
180. 我喜欢收集和整理具有纪念意义的物品(如票根、照片)。
181. 相比于宏大的愿景,我更关注具体的执行细节和步骤。
182. 我讨厌突如其来的变故或计划被打乱,这会让我很焦虑。
183. 我更喜欢阅读历史、传记或纪实文学,而不是科幻小说。
184. 我倾向于一步一个脚印地积累财富,而不是进行高风险投资。
185. 在整理房间时,我会把每样东西都放回它固定的位置,并且很难容忍别人乱放。
186. 当接手一个新项目时,我会先查阅以前的档案,看看以前是怎么做的。
187. 如果身体感到一点不适,我会立刻休息或吃药,防止病情恶化。
188. 在做预算时,我会详细记录每一笔开支,精确到小数点后两位。
189. 面对他人的画饼,我会要求他提供具体的数据和过往的成功案例。
190. 如果必须去一个陌生的地方,我会提前查好路线图和攻略,不做无准备之行。
191. 在节日里,我会坚持按照传统的习俗来庆祝,觉得这样才有仪式感。
192. 当别人提出一个激进的改革方案时,我会列举过去失败的例子来反驳。
193. 我觉得自己脑子里总是充满了各种天马行空的想法,停都停不下来。
194. 我认为世界充满了无限的可能性,我不愿意过一眼望到头的生活。
195. 我觉得自己擅长发现看似无关的事物之间的潜在联系。
196. 我倾向于跳跃性思维,说话时经常从一个话题跳到另一个话题。
197. 我认为“开始”比“结束”更有趣,我经常挖坑不填。
198. 我觉得自己是一个改革者,总是想打破常规,尝试新的方法。
199. 我经常对未来的各种“如果”感到兴奋,哪怕它们很不切实际。
200. 我觉得自己很难长时间集中注意力在枯燥的细节上,容易走神。
201. 朋友们常说我脑洞很大,总是能提出一些意想不到的点子。
202. 别人经常评价我幽默风趣,说话充满了梗和比喻。
203. 大家认为我有点不靠谱,想法变来变去,缺乏定性。
204. 别人常说我热情洋溢,总能感染身边的人一起做梦。
205. 亲近的人觉得我有点“多动症”,很难安安静静地坐着。
206. 同事们认为我非常适合做创意、策划或市场类的工作。
207. 别人常惊讶于我能从一个微小的线索推导出无数种可能性。
208. 大家觉得我是一个很好奇的人,对什么都感兴趣,但都不精通。
209. 我更喜欢头脑风暴的环节,而不是具体的执行环节。
210. 我倾向于探索抽象的概念和理论,而不是关注现实的琐事。
211. 我更看重灵感和创意,而不是严谨和秩序。
212. 我喜欢与不同背景的人交流,碰撞出思维的火花。
213. 相比于专注于一个领域,我更喜欢跨界学习,成为通才。
214. 我讨厌重复性的工作,那会让我感到灵魂枯竭。
215. 我更喜欢开放式的结局,而不是确定的答案。
216. 我倾向于通过辩论来探索真理,享受思维交锋的快感。
217. 在讨论问题时,我会不断提出“如果……会怎样”,引导大家发散思维。
218. 当看到一个新奇的小玩意,我会忍不住买回来研究它有什么新玩法。
219. 如果原来的计划行不通,我会立刻想出方案B、方案C甚至方案D。
220. 在写作或创作时,我经常写着写着就偏离了最初的大纲,发现了新大陆。
221. 面对死板的规定,我会尝试寻找漏洞或用创新的方式绕过它。
222. 当别人在谈论现实的困难时,我会描绘未来的美好蓝图来激励他们。
223. 如果让我选择,我宁愿做一个失败的创新者,也不做一个成功的模仿者。
224. 在闲暇时,我会浏览各种不相关的资讯,期待从中获得灵感。
225. 我觉得自己经常会有强烈的预感,并且事后证明通常是正确的。
226. 我认为透过现象看本质是我的本能,我不喜欢停留在表面。
227. 我觉得自己是一个长期主义者,为了一个宏大的目标可以忍受当下的寂寞。
228. 我倾向于收敛性思维,把各种信息整合成一个唯一的结论或愿景。
229. 我认为万事万物之间都存在着某种神秘的内在联系或宿命。
230. 我觉得自己经常用隐喻、象征或图像来思考问题,而不是语言。
231. 我经常感到一种“顿悟”时刻,答案突然出现在脑海里,却说不清推导过程。
232. 我觉得自己与现实世界有一种疏离感,更像是一个旁观者。
233. 朋友们常说我说话深奥难懂,像个哲学家或预言家。
234. 别人经常评价我眼神深邃,好像能看穿他们的心思。
235. 大家认为我有点固执己见,对自己认定的未来方向绝不妥协。
236. 别人常说我过于理想化,不接地气,忽略了现实的阻碍。
237. 亲近的人觉得我很难放松,脑子里总是在思考沉重的问题。
238. 同事们认为我非常适合做战略规划、顾问或研究类的工作。
239. 别人常惊讶于我对局势发展的预测能力,简直神准。
240. 大家觉得我是一个很有深度的人,但很难真正走进我的内心。
241. 我更喜欢深入钻研一个领域直到极致,而不是广泛涉猎。
242. 我倾向于思考“为什么”和“将会怎样”,而不是“是什么”和“现在怎样”。
243. 我更看重思想的深度和原创性,而不是信息的广度。
244. 我喜欢独处,给自己留出时间来冥想或整理思绪。
245. 相比于热闹的聚会,我更喜欢和一两个有思想的人进行深度对谈。
246. 我讨厌琐碎的日常事务,觉得它们在消耗我的生命。
247. 我更喜欢策划长远的战略,而不是处理眼前的战术问题。
248. 我倾向于相信直觉指引,哪怕没有足够的数据支持。
249. 在看电影时,我经常在开头就能猜到结局和导演想表达的深层隐喻。
250. 当面对一个复杂的问题时,我会先退后一步,寻找其背后的核心模式。
251. 如果我觉得某件事注定会失败,无论别人怎么劝说,我都不会参与。
252. 在制定计划时,我会倒推法,先确定终局画面,再规划路径。
253. 当别人都在关注热点新闻的细节时,我在思考这背后反映了什么社会趋势。
254. 如果我的直觉告诉我某人不可信,我会对他保持警惕,即使他表现得很友善。
255. 在学习新知识时,我会试图建立一个框架体系,把所有知识点串联起来。
256. 面对人生的重大选择,我会听从内心的召唤,而不是社会的期待。
`;
const lines = rawText.trim().split('\n').filter(l => l.trim() !== '');
const fullQuestionBank = [];
const funcMap = ["Te", "Ti", "Fe", "Fi", "Se", "Si", "Ne", "Ni"];
lines.forEach((line, idx) => {
const groupIdx = Math.floor(idx / 32);
if (groupIdx < 8) {
fullQuestionBank.push({
id: idx + 1,
text: line.replace(/^\d+\.\s*/, ''),
func: funcMap[groupIdx]
});
}
});
// --- 1. 状态管理 ---
let targetCount = 96;
let quizList = [];
let currentIdx = 0;
let answers = [];
let scores = {};
let normalizedScores = {};
let finalType = "";
let chatHistory = {
general: [],
career: [],
love: []
};
let currentAiTab = 'general';
let isGenerating = false;
const isDebug = true;
// --- 2. 逻辑控制 ---
function selectMode(count, el) {
targetCount = count;
document.querySelectorAll('.mode-card').forEach(c => c.classList.remove('selected'));
el.classList.add('selected');
}
function startQuiz() {
quizList = [];
if (targetCount === 256) {
quizList = [...fullQuestionBank];
} else {
const countPerFunc = targetCount / 8;
funcMap.forEach(f => {
const funcQuestions = fullQuestionBank.filter(q => q.func === f);
const shuffled = funcQuestions.sort(() => 0.5 - Math.random());
quizList.push(...shuffled.slice(0, countPerFunc));
});
}
quizList.sort(() => 0.5 - Math.random());
currentIdx = 0;
answers = [];
document.getElementById('page-home').classList.remove('active');
document.getElementById('page-quiz').classList.add('active');
renderQuestion();
}
function renderQuestion() {
const q = quizList[currentIdx];
document.getElementById('q-text').innerText = q.text;
document.getElementById('curr-idx').innerText = currentIdx + 1;
document.getElementById('total-count').innerText = targetCount;
const pct = (currentIdx / targetCount) * 100;
document.getElementById('progress').style.width = pct + "%";
document.getElementById('btn-undo').disabled = (currentIdx === 0);
document.getElementById('btn-undo').style.opacity = (currentIdx === 0) ? 0.3 : 1;
}
function handleAnswer(val) {
const q = quizList[currentIdx];
answers.push({ func: q.func, score: val });
currentIdx++;
if (currentIdx < targetCount) {
renderQuestion();
} else {
finishQuiz();
}
}
function undo() {
if (currentIdx > 0) {
answers.pop();
currentIdx--;
renderQuestion();
}
}
// --- 3. 结果计算与归一化 ---
const types = {
"ESTJ": ["Te", "Si", "Ne", "Fi"], "ENTJ": ["Te", "Ni", "Se", "Fi"],
"ESFJ": ["Fe", "Si", "Ne", "Ti"], "ENFJ": ["Fe", "Ni", "Se", "Ti"],
"ESTP": ["Se", "Ti", "Fe", "Ni"], "ESFP": ["Se", "Fi", "Te", "Ni"],
"ENTP": ["Ne", "Ti", "Fe", "Si"], "ENFP": ["Ne", "Fi", "Te", "Si"],
"ISTJ": ["Si", "Te", "Fi", "Ne"], "ISFJ": ["Si", "Fe", "Ti", "Ne"],
"INTJ": ["Ni", "Te", "Fi", "Se"], "INFJ": ["Ni", "Fe", "Ti", "Se"],
"ISTP": ["Ti", "Se", "Ni", "Fe"], "ISFP": ["Fi", "Se", "Ni", "Te"],
"INTP": ["Ti", "Ne", "Si", "Fe"], "INFP": ["Fi", "Ne", "Si", "Te"]
};
function finishQuiz() {
scores = { "Te":0, "Ti":0, "Fe":0, "Fi":0, "Se":0, "Si":0, "Ne":0, "Ni":0 };
answers.forEach(a => scores[a.func] += a.score);
const maxPossibleScore = (targetCount / 8) * 5;
normalizedScores = {};
for(let f in scores) {
normalizedScores[f] = Math.round((scores[f] / maxPossibleScore) * 100);
}
let matchScores = [];
for (let t in types) {
const stack = types[t];
let s = (normalizedScores[stack[0]]*4) +
(normalizedScores[stack[1]]*3) +
(normalizedScores[stack[2]]*2) +
(normalizedScores[stack[3]]*1);
let matchPct = (s / 1000) * 100;
matchScores.push({ type: t, score: matchPct.toFixed(1) });
}
matchScores.sort((a, b) => b.score - a.score);
finalType = matchScores[0].type;
showResultPage(matchScores);
}
function showResultPage(matchScores) {
document.getElementById('page-quiz').classList.remove('active');
document.getElementById('page-home').classList.remove('active');
document.getElementById('page-result').classList.add('active');
document.getElementById('res-type').innerText = finalType;
renderCharts();
renderMatchList(matchScores);
if (chatHistory['general'].length === 0) {
switchAiTab('general');
} else {
switchAiTab(currentAiTab);
}
}
function renderCharts() {
const container = document.getElementById('chart-container');
container.innerHTML = '';
const order = ["Te", "Ti", "Fe", "Fi", "Se", "Si", "Ne", "Ni"];
order.forEach(f => {
const pct = normalizedScores[f];
const desc = funcDefinitions[f];
container.innerHTML += `
<div class="chart-row">
<div class="chart-label-container" data-tooltip="${desc}">
<div class="chart-label">${f}</div>
</div>
<div class="chart-track"><div class="chart-fill" style="width:${pct}%"></div></div>
<div class="chart-val">${pct}%</div>
</div>
`;
});
}
function renderMatchList(list) {
const container = document.getElementById('match-container');
container.innerHTML = '';
list.slice(0, 5).forEach(item => {