PageSourceSearch

https://qy.hw99.com/scanner/index.html

html hw99.com collected 2026-10-02 06:17:04 UTC 52,004 bytes, 1,620 lines download raw bytes

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>汉王扫描仪驱动下载中心</title>
7 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
8 <style>
9   * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; }
10   
11   :root {
12     --primary: #4361ee;
13     --primary-dark: #3a56d4;
14     --success: #4cc9a7;
15     --warning: #f9c74f;
16     --text-primary: #1a1a2e;
17     --text-secondary: #4a4a6a;
18     --text-tertiary: #7a7a9d;
19     --border: #e2e8f0;
20     --bg-primary: #fff;
21     --bg-secondary: #f8fafc;
22     --bg-tertiary: #f1f5f9;
23     --shadow: 0 4px 12px rgba(0,0,0,0.08);
24     --radius: 10px;
25   }
26
27   body {
28     background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
29     min-height: 100vh;
30     padding: 24px;
31     line-height: 1.6;
32     padding-bottom: 100px;
33   }
34
35   .mobile-notice {
36     display: none;
37     background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
38     color: white;
39     padding: 16px 20px;
40     border-radius: 12px;
41     margin-bottom: 20px;
42     box-shadow: 0 4px 15px rgba(245, 158, 11, 0.3);
43     position: relative;
44     overflow: hidden;
45   }
46
47   .mobile-notice::before {
48     content: "";
49     position: absolute;
50     top: 0; left: 0; right: 0; bottom: 0;
51     background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.1'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
52     opacity: 0.3;
53   }
54
55   .mobile-notice.show {
56     display: block;
57     animation: slideDown 0.4s ease-out;
58   }
59
60   @keyframes slideDown {
61     from { opacity: 0; transform: translateY(-20px); }
62     to { opacity: 1; transform: translateY(0); }
63   }
64
65   .mobile-notice-content {
66     display: flex;
67     flex-wrap: wrap;
68     align-items: center;
69     position: relative;
70     z-index: 1;
71   }
72
73   .mobile-notice-icon {
74     font-size: 28px;
75     flex-shrink: 0;
76     margin-right: 16px;
77     animation: pulse 2s infinite;
78   }
79
80   @keyframes pulse {
81     0%, 100% { transform: scale(1); }
82     50% { transform: scale(1.1); }
83   }
84
85   .mobile-notice-text { flex: 1; min-width: 200px; }
86
87   .mobile-notice-title {
88     font-weight: 700;
89     font-size: 1.1rem;
90     margin-bottom: 4px;
91     display: flex;
92     align-items: center;
93   }
94
95   .mobile-notice-title i { margin-right: 8px; }
96
97   .mobile-notice-desc {
98     font-size: 0.9rem;
99     opacity: 0.95;
100     line-height: 1.5;
101   }
102
103   .mobile-notice-close {
104     background: rgba(255,255,255,0.2);
105     border: none;
106     color: white;
107     width: 32px;
108     height: 32px;
109     border-radius: 50%;
110     cursor: pointer;
111     display: flex;
112     align-items: center;
113     justify-content: center;
114     transition: all 0.2s;
115     flex-shrink: 0;
116     margin-left: 8px;
117   }
118
119   .mobile-notice-close:hover {
120     background: rgba(255,255,255,0.3);
121     transform: rotate(90deg);
122   }
123
124   .container {
125     max-width: 1200px;
126     margin: 0 auto;
127     background: rgba(255,255,255,0.95);
128     border-radius: 24px;
129     box-shadow: 0 20px 50px rgba(0,0,0,0.15);
130     padding: 48px;
131     position: relative;
132   }
133
134   .container::before {
135     content: "";
136     position: absolute;
137     top: 0; left: 0; right: 0;
138     height: 6px;
139     background: linear-gradient(135deg, #4361ee 0%, #3a56d4 100%);
140     border-radius: 24px 24px 0 0;
141   }
142
143   .header {
144     text-align: center;
145     margin-bottom: 48px;
146   }
147
148   .main-title {
149     font-size: 2.5rem;
150     font-weight: 800;
151     background: linear-gradient(135deg, #4361ee 0%, #3a56d4 100%);
152     -webkit-background-clip: text;
153     -webkit-text-fill-color: transparent;
154     margin-bottom: 8px;
155   }
156
157   .title-sub {
158     color: var(--text-secondary);
159     max-width: 600px;
160     margin: 0 auto;
161   }
162
163   .search-section {
164     background: var(--bg-primary);
165     border-radius: 16px;
166     padding: 32px;
167     margin-bottom: 32px;
168     box-shadow: var(--shadow);
169     border: 1px solid rgba(255,255,255,0.8);
170   }
171
172   .search-box {
173     display: flex;
174     flex-wrap: wrap;
175     align-items: center;
176     margin: -8px;
177   }
178
179   .search-box > * { margin: 8px; }
180
181   #model-input {
182     flex: 1;
183     min-width: 280px;
184     padding: 16px 24px;
185     border: 1px solid var(--border);
186     border-radius: var(--radius);
187     font-size: 1rem;
188     background: var(--bg-secondary);
189     transition: 0.2s;
190   }
191
192   #model-input:focus {
193     outline: none;
194     border-color: var(--primary);
195     box-shadow: 0 0 0 3px rgba(67,97,238,0.1);
196   }
197
198   #search-btn {
199     padding: 16px 32px;
200     background: linear-gradient(135deg, #4361ee 0%, #3a56d4 100%);
201     color: white;
202     border: none;
203     border-radius: var(--radius);
204     cursor: pointer;
205     font-size: 1rem;
206     font-weight: 600;
207     display: flex;
208     align-items: center;
209     transition: 0.2s;
210   }
211
212   #search-btn i { margin-right: 8px; }
213
214   #search-btn:hover {
215     transform: translateY(-2px);
216     box-shadow: 0 6px 20px rgba(67,97,238,0.3);
217   }
218
219   .filter-bar {
220     display: none;
221     margin-bottom: 24px;
222     padding: 16px;
223     background: var(--bg-tertiary);
224     border-radius: var(--radius);
225     flex-wrap: wrap;
226   }
227
228   .filter-bar.active { display: flex; }
229
230   .filter-group {
231     display: flex;
232     align-items: center;
233     margin-right: 16px;
234     margin-bottom: 8px;
235   }
236
237   .filter-label {
238     font-size: 0.9rem;
239     color: var(--text-secondary);
240     font-weight: 600;
241     margin-right: 8px;
242   }
243
244   .filter-select {
245     padding: 8px 16px;
246     border: 1px solid var(--border);
247     border-radius: 6px;
248     font-size: 0.9rem;
249     background: var(--bg-primary);
250     min-width: 160px;
251     cursor: pointer;
252   }
253
254   .filter-reset {
255     padding: 8px 16px;
256     background: var(--bg-primary);
257     color: var(--primary);
258     border: 1px solid var(--primary);
259     border-radius: 6px;
260     cursor: pointer;
261     font-weight: 600;
262     margin-bottom: 8px;
263   }
264
265   .filter-reset i { margin-right: 4px; }
266
267   .table-container {
268     width: 100%;
269     overflow-x: auto;
270     border-radius: var(--radius);
271     box-shadow: var(--shadow);
272     margin-bottom: 24px;
273   }
274
275   .common-table {
276     width: 100%;
277     border-collapse: collapse;
278     background: var(--bg-primary);
279     min-width: 800px;
280   }
281
282   .common-table th { display: none; }
283
284   .common-table td {
285     padding: 24px;
286     border-bottom: 1px solid var(--border);
287   }
288
289   .model-group-row {
290     cursor: pointer;
291     background: rgba(67,97,238,0.08);
292     font-weight: 600;
293   }
294
295   .model-group-row:hover { background: rgba(67,97,238,0.15); }
296
297   .model-group-row td {
298     font-size: 1.1rem;
299     font-weight: 600;
300     border-bottom: 3px solid #fff;
301   }
302
303   .os-group-row {
304     cursor: pointer;
305     background: rgba(76,201,167,0.08);
306   }
307
308   .os-group-row:hover { background: rgba(76,201,167,0.15); }
309
310   .os-group-row td {
311     font-weight: 600;
312     font-size: 1rem;
313     border-bottom: 2px solid #fff;
314     padding-left: 40px;
315   }
316
317   .driver-detail-row td { 
318     padding-left: 60px; 
319     border-bottom: 1px solid var(--border);
320   }
321
322   .driver-detail-row.last-in-group td { border-bottom: none; }
323
324   .software-detail-row td { padding-left: 60px; }
325
326   .expand-icon {
327     display: inline-flex;
328     align-items: center;
329     justify-content: center;
330     width: 28px;
331     height: 28px;
332     margin-right: 8px;
333     border-radius: 50%;
334     background: var(--bg-primary);
335     color: var(--text-secondary);
336     font-size: 14px;
337     transition: 0.2s;
338   }
339
340   .model-group-row:hover .expand-icon,
341   .os-group-row:hover .expand-icon {
342     background: var(--primary);
343     color: white;
344   }
345
346   .download-btn {
347     padding: 8px 16px;
348     background: var(--success);
349     color: white;
350     border: none;
351     border-radius: 6px;
352     cursor: pointer;
353     font-size: 0.85rem;
354     font-weight: 600;
355     display: inline-flex;
356     align-items: center;
357     transition: 0.2s;
358   }
359
360   .download-btn i { margin-right: 6px; }
361
362   .download-btn:hover {
363     background: #3db895;
364     transform: translateY(-2px);
365   }
366
367   .software-section {
368     background: rgba(67,97,238,0.1);
369     border-radius: 16px;
370     padding: 32px;
371     margin-top: 32px;
372   }
373
374   .software-title {
375     font-size: 1.5rem;
376     font-weight: 700;
377     margin-bottom: 16px;
378     display: flex;
379     align-items: center;
380   }
381
382   .software-title i { color: var(--primary); margin-right: 8px; }
383
384   .software-desc {
385     font-size: 0.85rem;
386     color: var(--text-tertiary);
387     margin-left: 16px;
388     padding-left: 16px;
389     border-left: 2px solid var(--border);
390     font-weight: normal;
391     word-break: break-all;
392   }
393
394   .software-section .model-group-row td { border-bottom: 2px solid #fff; }
395
396   .detail-header-row td {
397     padding: 12px 24px;
398     background: var(--bg-tertiary);
399     font-weight: 600;
400     font-size: 0.85rem;
401     color: var(--text-secondary);
402   }
403
404   .os-group-row + .detail-header-row td,
405   .model-group-row + .detail-header-row td { padding-left: 60px; }
406
407   .version-info {
408     color: var(--primary);
409     margin-left: 8px;
410     font-size: 0.9rem;
411   }
412
413   .no-driver-cell {
414     text-align: center;
415     color: var(--text-tertiary);
416     padding: 24px;
417     border-bottom: none;
418   }
419
420   .highlight {
421     background: rgba(67,97,238,0.2);
422     color: var(--primary-dark);
423     padding: 2px 4px;
424     border-radius: 4px;
425     font-weight: 600;
426   }
427
428   .result-count {
429     color: var(--text-secondary);
430     margin-bottom: 16px;
431     display: flex;
432     align-items: center;
433   }
434
435   .result-count i { margin-right: 8px; }
436
437   .loading, .empty {
438     text-align: center;
439     padding: 48px;
440     display: none;
441   }
442
443   .loading.active, .empty.active { display: block; }
444
445   .loading::before {
446     content: "";
447     display: inline-block;
448     width: 32px;
449     height: 32px;
450     border: 3px solid rgba(67,97,238,0.2);
451     border-top: 3px solid var(--primary);
452     border-radius: 50%;
453     animation: spin 1s linear infinite;
454   }
455
456   .empty::before {
457     content: "\1F50D";
458     font-size: 48px;
459     opacity: 0.5;
460   }
461
462   @keyframes spin {
463     0% { transform: rotate(0deg); }
464     100% { transform: rotate(360deg); }
465   }
466
467   /* 桌面端:右下角悬浮按钮 */
468   .hotline-fab {
469     position: fixed;
470     right: 24px;
471     bottom: 24px;
472     z-index: 1000;
473   }
474
475   .hotline-fab-btn {
476     width: 56px;
477     height: 56px;
478     border-radius: 50%;
479     background: linear-gradient(135deg, #4361ee 0%, #3a56d4 100%);
480     color: white;
481     border: none;
482     cursor: pointer;
483     box-shadow: 0 4px 15px rgba(67,97,238,0.4);
484     display: flex;
485     align-items: center;
486     justify-content: center;
487     font-size: 24px;
488     transition: all 0.3s ease;
489     position: relative;
490   }
491
492   .hotline-fab-btn:hover {
493     transform: scale(1.1);
494     box-shadow: 0 6px 20px rgba(67,97,238,0.5);
495   }
496
497   .hotline-fab-btn.pulse::after {
498     content: '';
499     position: absolute;
500     width: 100%;
501     height: 100%;
502     border-radius: 50%;
503     background: rgba(67,97,238,0.4);
504     animation: fabPulse 2s infinite;
505     z-index: -1;
506   }
507
508   @keyframes fabPulse {
509     0% { transform: scale(1); opacity: 1; }
510     100% { transform: scale(1.5); opacity: 0; }
511   }
512
513   .hotline-fab-panel {
514     position: absolute;
515     bottom: 70px;
516     right: 0;
517     width: 280px;
518     background: white;
519     border-radius: 16px;
520     box-shadow: 0 10px 40px rgba(0,0,0,0.15);
521     padding: 24px;
522     opacity: 0;
523     visibility: hidden;
524     transform: translateY(10px) scale(0.95);
525     transition: all 0.3s ease;
526     transform-origin: bottom right;
527   }
528
529   .hotline-fab-panel.show {
530     opacity: 1;
531     visibility: visible;
532     transform: translateY(0) scale(1);
533   }
534
535   .hotline-fab-panel::after {
536     content: '';
537     position: absolute;
538     bottom: -8px;
539     right: 20px;
540     width: 16px;
541     height: 16px;
542     background: white;
543     transform: rotate(45deg);
544   }
545
546   .hotline-fab-header {
547     display: flex;
548     align-items: center;
549     margin-bottom: 16px;
550     padding-bottom: 16px;
551     border-bottom: 1px solid var(--border);
552   }
553
554   .hotline-fab-icon {
555     width: 40px;
556     height: 40px;
557     background: rgba(67,97,238,0.1);
558     border-radius: 50%;
559     display: flex;
560     align-items: center;
561     justify-content: center;
562     color: var(--primary);
563     font-size: 18px;
564     margin-right: 12px;
565     flex-shrink: 0;
566   }
567
568   .hotline-fab-title {
569     font-weight: 700;
570     color: var(--text-primary);
571     font-size: 1rem;
572   }
573
574   .hotline-fab-subtitle {
575     font-size: 0.8rem;
576     color: var(--text-tertiary);
577   }
578
579   .hotline-fab-number {
580     font-size: 1.5rem;
581     font-weight: 800;
582     color: var(--primary);
583     display: block;
584     margin: 12px 0;
585     text-decoration: none;
586     transition: color 0.2s;
587   }
588
589   .hotline-fab-number i { margin-right: 8px; }
590
591   .hotline-fab-number:hover { color: var(--primary-dark); }
592
593   .hotline-fab-time {
594     font-size: 0.85rem;
595     color: var(--text-secondary);
596     display: flex;
597     align-items: center;
598   }
599
600   .hotline-fab-time i { margin-right: 6px; }
601
602   .hotline-fab-close {
603     position: absolute;
604     top: 12px;
605     right: 12px;
606     width: 28px;
607     height: 28px;
608     border-radius: 50%;
609     border: none;
610     background: var(--bg-tertiary);
611     color: var(--text-secondary);
612     cursor: pointer;
613     display: flex;
614     align-items: center;
615     justify-content: center;
616     font-size: 14px;
617     transition: all 0.2s;
618   }
619
620   .hotline-fab-close:hover {
621     background: var(--border);
622     color: var(--text-primary);
623   }
624
625   /* 移动端:底部固定栏 */
626   .hotline-mobile-bar {
627     display: none;
628     position: fixed;
629     bottom: 0;
630     left: 0;
631     right: 0;
632     background: white;
633     box-shadow: 0 -4px 20px rgba(0,0,0,0.1);
634     z-index: 1000;
635     padding: 12px 16px;
636     transform: translateY(0);
637     transition: transform 0.3s ease;
638   }
639
640   .hotline-mobile-bar.hidden { transform: translateY(100%); }
641
642   .hotline-mobile-content {
643     display: flex;
644     align-items: center;
645     justify-content: space-between;
646     max-width: 600px;
647     margin: 0 auto;
648   }
649
650   .hotline-mobile-info {
651     display: flex;
652     align-items: center;
653   }
654
655   .hotline-mobile-icon {
656     width: 40px;
657     height: 40px;
658     background: linear-gradient(135deg, #4361ee 0%, #3a56d4 100%);
659     border-radius: 50%;
660     display: flex;
661     align-items: center;
662     justify-content: center;
663     color: white;
664     font-size: 18px;
665     margin-right: 12px;
666     flex-shrink: 0;
667   }
668
669   .hotline-mobile-text {
670     display: flex;
671     flex-direction: column;
672   }
673
674   .hotline-mobile-label {
675     font-size: 0.75rem;
676     color: var(--text-tertiary);
677   }
678
679   .hotline-mobile-number {
680     font-size: 1.2rem;
681     font-weight: 700;
682     color: var(--primary);
683     text-decoration: none;
684   }
685
686   .hotline-mobile-actions {
687     display: flex;
688   }
689
690   .hotline-mobile-btn {
691     padding: 10px 20px;
692     border-radius: 20px;
693     border: none;
694     font-weight: 600;
695     font-size: 0.9rem;
696     cursor: pointer;
697     display: flex;
698     align-items: center;
699     transition: all 0.2s;
700   }
701
702   .hotline-mobile-btn i { margin-right: 6px; }
703
704   .hotline-mobile-btn.call {
705     background: linear-gradient(135deg, #4361ee 0%, #3a56d4 100%);
706     color: white;
707   }
708
709   .hotline-mobile-btn.call:hover {
710     transform: translateY(-2px);
711     box-shadow: 0 4px 12px rgba(67,97,238,0.3);
712   }
713
714   .hotline-mobile-btn.close {
715     background: var(--bg-tertiary);
716     color: var(--text-secondary);
717     width: 36px;
718     height: 36px;
719     padding: 0;
720     border-radius: 50%;
721     justify-content: center;
722     margin-left: 8px;
723   }
724
725   .hotline-mobile-btn.close i { margin-right: 0; }
726
727   .hotline-mobile-btn.close:hover { background: var(--border); }
728
729   /* 展开的热线详情(移动端) */
730   .hotline-mobile-detail {
731     display: none;
732     position: fixed;
733     bottom: 70px;
734     left: 16px;
735     right: 16px;
736     background: white;
737     border-radius: 16px;
738     box-shadow: 0 -4px 30px rgba(0,0,0,0.15);
739     padding: 20px;
740     z-index: 999;
741     animation: slideUp 0.3s ease;
742   }
743
744   .hotline-mobile-detail.show { display: block; }
745
746   @keyframes slideUp {
747     from { transform: translateY(20px); opacity: 0; }
748     to { transform: translateY(0); opacity: 1; }
749   }
750
751   .hotline-mobile-detail-header {
752     display: flex;
753     align-items: center;
754     justify-content: space-between;
755     margin-bottom: 16px;
756   }
757
758   .hotline-mobile-detail-title {
759     font-weight: 700;
760     color: var(--text-primary);
761   }
762
763   .hotline-mobile-detail-close {
764     width: 32px;
765     height: 32px;
766     border-radius: 50%;
767     border: none;
768     background: var(--bg-tertiary);
769     color: var(--text-secondary);
770     cursor: pointer;
771   }
772
773   .hotline-mobile-detail-time {
774     background: var(--bg-secondary);
775     padding: 12px;
776     border-radius: 10px;
777     font-size: 0.85rem;
778     color: var(--text-secondary);
779     display: flex;
780     align-items: center;
781     margin-bottom: 12px;
782   }
783
784   .hotline-mobile-detail-time i { margin-right: 8px; }
785
786   .hotline-mobile-detail-tip {
787     font-size: 0.8rem;
788     color: var(--text-tertiary);
789     line-height: 1.5;
790   }
791
792   /* Toast */
793   .toast {
794     position: fixed;
795     top: 24px;
796     right: 24px;
797     padding: 16px 24px;
798     border-radius: var(--radius);
799     z-index: 1100;
800     opacity: 0;
801     transform: translateY(-20px);
802     transition: 0.3s;
803     display: flex;
804     align-items: center;
805     font-weight: 500;
806     box-shadow: 0 4px 15px rgba(0,0,0,0.15);
807     min-width: 200px;
808   }
809
810   .toast i { margin-right: 8px; }
811
812   .toast.show { opacity: 1; transform: translateY(0); }
813   .toast.success { background: #10b981; color: white; }
814   .toast.error { background: #ef4444; color: white; }
815   .toast.info { background: #3b82f6; color: white; }
816   .toast.warning { background: #f59e0b; color: white; }
817
818   /* 视频区域 */
819   .video-section {
820     background: rgba(67,97,238,0.08);
821     border-radius: 16px;
822     padding: 32px;
823     margin-top: 32px;
824   }
825
826   .video-title {
827     font-size: 1.5rem;
828     font-weight: 700;
829     margin-bottom: 20px;
830     display: flex;
831     align-items: center;
832     color: var(--text-primary);
833   }
834
835   .video-title i { color: var(--primary); margin-right: 10px; }
836
837   .video-grid {
838     display: grid;
839     grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
840     grid-gap: 20px;
841   }
842
843   .video-card {
844     background: var(--bg-primary);
845     border-radius: 12px;
846     overflow: hidden;
847     border: 1px solid var(--border);
848     transition: all 0.3s ease;
849     cursor: pointer;
850   }
851
852   .video-card:hover {
853     transform: translateY(-4px);
854     box-shadow: 0 12px 24px rgba(0,0,0,0.1);
855     border-color: var(--primary);
856   }
857
858   .video-thumbnail {
859     position: relative;
860     width: 100%;
861     padding-top: 56.25%;
862     background: #1a1a2e;
863     overflow: hidden;
864   }
865
866   .video-thumbnail img {
867     position: absolute;
868     top: 0; left: 0;
869     width: 100%; height: 100%;
870     object-fit: cover;
871   }
872
873   .video-play-overlay {
874     position: absolute;
875     top: 0; left: 0; right: 0; bottom: 0;
876     background: rgba(0,0,0,0.3);
877     display: flex;
878     align-items: flex-end;
879     justify-content: flex-end;
880     padding: 16px;
881     transition: background 0.3s;
882   }
883
884   .video-card:hover .video-play-overlay { background: rgba(0,0,0,0.5); }
885
886   .video-play-btn {
887     width: 56px;
888     height: 56px;
889     background: rgba(255,255,255,0.95);
890     border-radius: 50%;
891     display: flex;
892     align-items: center;
893     justify-content: center;
894     color: var(--primary);
895     font-size: 18px;
896     transition: all 0.3s ease;
897   }
898
899   .video-card:hover .video-play-btn {
900     background: var(--primary);
901     color: white;
902     transform: scale(1.1);
903   }
904
905   .video-info { padding: 16px; }
906
907   .video-name {
908     font-weight: 600;
909     color: var(--text-primary);
910     font-size: 0.95rem;
911     line-height: 1.4;
912     display: -webkit-box;
913     -webkit-line-clamp: 2;
914     -webkit-box-orient: vertical;
915     overflow: hidden;
916   }
917
918   .video-empty {
919     text-align: center;
920     padding: 48px 24px;
921     color: var(--text-tertiary);
922     background: var(--bg-primary);
923     border-radius: 12px;
924     border: 1px dashed var(--border);
925     grid-column: 1 / -1;
926   }
927
928   .video-empty i { font-size: 48px; margin-bottom: 16px; display: block; opacity: 0.5; }
929
930   /* 视频播放器弹窗 */
931   .video-modal {
932     display: none;
933     position: fixed;
934     top: 0; left: 0; right: 0; bottom: 0;
935     background: rgba(0,0,0,0.9);
936     z-index: 2000;
937     align-items: center;
938     justify-content: center;
939     padding: 20px;
940   }
941
942   .video-modal.show { display: flex; }
943
944   .video-modal-content {
945     width: 100%;
946     max-width: 960px;
947     background: #000;
948     border-radius: 12px;
949     overflow: hidden;
950     position: relative;
951   }
952
953   .video-modal-header {
954     display: flex;
955     align-items: center;
956     justify-content: space-between;
957     padding: 16px 20px;
958     background: #1a1a2e;
959     color: white;
960   }
961
962   .video-modal-close {
963     width: 36px; height: 36px;
964     border-radius: 50%;
965     border: none;
966     background: rgba(255,255,255,0.1);
967     color: white;
968     cursor: pointer;
969     display: flex;
970     align-items: center;
971     justify-content: center;
972     font-size: 16px;
973   }
974
975   .video-modal-close:hover { background: rgba(255,255,255,0.2); }
976
977   .video-modal-player {
978     position: relative;
979     padding-top: 56.25%;
980     background: #000;
981   }
982
983   .video-modal-player iframe {
984     position: absolute;
985     top: 0; left: 0;
986     width: 100%; height: 100%;
987     border: none;
988   }
989
990   /* 响应式 */
991   @media (max-width: 768px) {
992     body { padding: 16px; padding-bottom: 100px; }
993     .container { padding: 24px; }
994     .main-title { font-size: 1.8rem; }
995     .search-box { flex-direction: column; margin: 0; }
996     .search-box > * { margin: 8px 0; }
997     #model-input, #search-btn { width: 100%; }
998     .hotline-fab { display: none; }
999     .hotline-mobile-bar { display: block; }
1000     .mobile-notice { margin: -8px -8px 16px -8px; border-radius: 0; }
1001     .os-group-row td { padding-left: 20px; }
1002     .driver-detail-row td,
1003     .software-detail-row td,
1004     .detail-header-row td { padding-left: 30px !important; }
1005     .toast { top: auto; bottom: 100px; right: 16px; left: 16px; min-width: auto; }
1006     .video-section { padding: 24px 20px; margin: 24px -8px -8px -8px; border-radius: 0; }
1007     .video-grid { grid-template-columns: 1fr; }
1008     .video-modal-content { border-radius: 0; max-height: 100vh; }
1009   }
1010
1011   @media (min-width: 769px) {
1012     .hotline-mobile-bar,
1013     .hotline-mobile-detail,
1014     .hotline-mini-fab { display: none !important; }
1015     body { padding-bottom: 24px; }
1016   }
1017
1018   .hotline-mini-fab {
1019     display: none;
1020     position: fixed;
1021     right: 16px; bottom: 16px;
1022     width: 48px; height: 48px;
1023     border-radius: 50%;
1024     background: linear-gradient(135deg, #4361ee 0%, #3a56d4 100%);
1025     color: white;
1026     border: none;
1027     cursor: pointer;
1028     box-shadow: 0 4px 15px rgba(67,97,238,0.4);
1029     font-size: 20px;
1030     z-index: 999;
1031     animation: bounceIn 0.5s ease;
1032   }
1033
1034   .hotline-mini-fab.show {
1035     display: flex;
1036     align-items: center;
1037     justify-content: center;
1038   }
1039
1040   @keyframes bounceIn {
1041     0% { transform: scale(0); }
1042     50% { transform: scale(1.2); }
1043     100% { transform: scale(1); }
1044   }
1045
1046   @media (max-width: 768px) {
1047     .hotline-mini-fab.show { display: flex; }
1048   }
1049 </style>
1050<base target="_blank">
1051</head>
1052<body>
1053 <div class="mobile-notice" id="mobile-notice">
1054   <div class="mobile-notice-content">
1055     <span class="mobile-notice-icon"><i class="fas fa-mobile-alt"></i></span>
1056     <div class="mobile-notice-text">
1057       <div class="mobile-notice-title">
1058         <i class="fas fa-exclamation-triangle"></i>
1059         检测到您正在使用移动设备
1060       </div>
1061       <div class="mobile-notice-desc">
1062         本网站提供的是PC端驱动程序,下载后需要在电脑上安装使用。建议您使用电脑访问本网站,或下载后通过数据线/微信/QQ等方式传输到电脑上进行安装。
1063       </div>
1064     </div>
1065     <button class="mobile-notice-close" onclick="closeMobileNotice()" title="关闭提示">
1066       <i class="fas fa-times"></i>
1067     </button>
1068   </div>
1069 </div>
1070
1071 <div class="hotline-fab" id="hotline-fab">
1072   <div class="hotline-fab-panel show" id="hotline-fab-panel">
1073     <button class="hotline-fab-close" onclick="toggleHotlinePanel()" title="收起">
1074       <i class="fas fa-times"></i>
1075     </button>
1076     <div class="hotline-fab-header">
1077       <div class="hotline-fab-icon">
1078         <i class="fas fa-headset"></i>
1079       </div>
1080       <div>
1081         <div class="hotline-fab-title">客服热线</div>
1082         <div class="hotline-fab-subtitle">汉王技术支持</div>
1083       </div>
1084     </div>
1085     <a href="tel:400-810-8816" class="hotline-fab-number">
1086       <i class="fas fa-phone-alt"></i> 400-810-8816
1087     </a>
1088     <div class="hotline-fab-time">
1089       <i class="far fa-clock"></i>
1090       <span>工作日 9:00-18:00</span>
1091     </div>
1092   </div>
1093   <button class="hotline-fab-btn" id="hotline-fab-btn" onclick="toggleHotlinePanel()" title="客服热线">
1094     <i class="fas fa-phone-alt"></i>
1095   </button>
1096 </div>
1097
1098 <div class="hotline-mobile-bar" id="hotline-mobile-bar">
1099   <div class="hotline-mobile-content">
1100     <div class="hotline-mobile-info">
1101       <div class="hotline-mobile-icon">
1102         <i class="fas fa-headset"></i>
1103       </div>
1104       <div class="hotline-mobile-text">
1105         <span class="hotline-mobile-label">客服热线</span>
1106         <a href="tel:400-810-8816" class="hotline-mobile-number">400-810-8816</a>
1107       </div>
1108     </div>
1109     <div class="hotline-mobile-actions">
1110       <button class="hotline-mobile-btn call" onclick="callHotline()">
1111         <i class="fas fa-phone"></i> 拨打
1112       </button>
1113       <button class="hotline-mobile-btn close" onclick="hideMobileHotline()" title="收起">
1114         <i class="fas fa-chevron-down"></i>
1115       </button>
1116     </div>
1117   </div>
1118 </div>
1119
1120 <div class="hotline-mobile-detail" id="hotline-mobile-detail">
1121   <div class="hotline-mobile-detail-header">
1122     <span class="hotline-mobile-detail-title">客服热线详情</span>
1123     <button class="video-modal-close" onclick="hideMobileDetail()">
1124       <i class="fas fa-times"></i>
1125     </button>
1126   </div>
1127   <div class="hotline-mobile-detail-time">
1128     <i class="far fa-clock"></i>
1129     <span>服务时间:工作日 9:00-18:00</span>
1130   </div>
1131   <div class="hotline-mobile-detail-tip">
1132     <i class="fas fa-info-circle"></i> 如遇占线请稍后再拨,或通过汉王官网在线客服咨询
1133   </div>
1134 </div>
1135
1136 <button class="hotline-mini-fab" id="hotline-mini-fab" onclick="showMobileHotline()" title="客服热线">
1137   <i class="fas fa-phone-alt"></i>
1138 </button>
1139
1140 <div class="video-modal" id="video-modal" onclick="closeVideoModal(event)">
1141   <div class="video-modal-content" onclick="event.stopPropagation()">
1142     <div class="video-modal-header">
1143       <span class="video-modal-title" id="video-modal-title">视频播放</span>
1144       <button class="video-modal-close" onclick="closeVideoModal()">
1145         <i class="fas fa-times"></i>
1146       </button>
1147     </div>
1148     <div class="video-modal-player" id="video-modal-player"></div>
1149   </div>
1150 </div>
1151
1152 <div class="container">
1153   <div class="header">
1154     <h1 class="main-title">汉王扫描仪驱动下载中心</h1>
1155     <p class="title-sub">请输入扫描仪型号搜索对应的驱动程序</p>
1156   </div>
1157   
1158   <section class="search-section">
1159     <div class="search-box">
1160       <input type="text" id="model-input" placeholder="请输入扫描仪型号,如HW-3130、HW6040、H25A">
1161       <button id="search-btn"><i class="fas fa-search"></i> 搜索驱动</button>
1162     </div>
1163   </section>
1164
1165   <div class="filter-bar" id="filter-bar">
1166     <div class="filter-group">
1167       <span class="filter-label">操作系统</span>
1168       <select class="filter-select" id="os-filter"><option value="all">全部系统</option></select>
1169     </div>
1170     <div class="filter-group">
1171       <span class="filter-label">系统架构</span>
1172       <select class="filter-select" id="arch-filter"><option value="all">全部架构</option></select>
1173     </div>
1174     <button class="filter-reset" id="filter-reset"><i class="fas fa-redo"></i> 重置</button>
1175   </div>
1176
1177   <div class="loading" id="loading"><p>正在搜索...</p></div>
1178   <div class="empty" id="empty"></div>
1179
1180   <section id="result-area"></section>
1181
1182   <section class="software-section">
1183     <h2 class="software-title"><i class="fas fa-download"></i> 扫描仪配套软件</h2>
1184     <div id="software-area"></div>
1185   </section>
1186
1187   <section class="video-section">
1188     <h2 class="video-title">
1189       <i class="fas fa-play-circle"></i>
1190       产品相关视频
1191     </h2>
1192     <div class="video-grid" id="video-area"></div>
1193   </section>
1194 </div>
1195
1196 <div class="toast" id="toast"></div>
1197
1198<script>
1199  var CFG = {
1200    API: 'https://scannerdrive.hw99.com/api/drivers',
1201    searchMode: 0,
1202    expand: 0,
1203    software: [
1204  {
1205    name: '驱动自动检测下载工具',
1206    desc: '自动检测您的扫描仪型号提供相应驱动程序下载',
1207    versions: [
1208      { rowName:"驱动自动检测下载工具", os: 'Windows7/10/11', arch: 'X64', url: 'http://download.hw99.com/scanner/drivers/Software/扫描仪驱动自动检测下载工具/汉王扫描仪驱动自动检测工具 202607070949.zip' }
1209    ]
1210  },
1211  {
1212    name: '汉王文本王🚀2026 新版|Win首发(升级OCR核心)',
1213    desc: '汉王全系扫描仪配套软件,离线高速 OCR 识别、多格式输出、智能图像优化',
1214    versions: [
1215      { rowName:"汉王文本王2024", os: 'Win 7/10/11 64位', arch: 'X64', url: 'https://download.hw99.com/scanner/drivers/Software/wenbenwang/%E6%B1%89%E7%8E%8B%E6%96%87%E6%9C%AC%E7%8E%8B2024(V1.0.15.3)_20260316.zip' },
1216      { rowName:"汉王文本王2026(新版首发)", os: 'Win 10/11 64位', arch: 'X64', url: 'http://download.hw99.com/scanner/drivers/Software/wenbenwang/汉王文本王2026(v3.1.2)_20260903.zip' },
1217      { rowName:"汉王文本王2024", os: '麒麟Kylin', arch: 'AMD64(兆芯/海光)', url: 'https://download.hw99.com/scanner/drivers/Software/wenbenwang/HanvonTextApp_amd64_2.0.8.deb' },
1218      { rowName:"汉王文本王2024", os: '麒麟Kylin', arch: 'ARM(飞腾/海思)', url: 'https://download.hw99.com/scanner/drivers/Software/wenbenwang/HanvonTextApp_2.0.9_arm64.deb' },
1219      { rowName:"汉王文本王2024", os: '统信UOS', arch: 'AMD64(兆芯/海光)', url: 'https://download.hw99.com/scanner/drivers/Software/wenbenwang/signed_HanvonTextApp_amd64_2.0.8.deb' },
1220      { rowName:"汉王文本王2024", os: '统信UOS', arch: 'ARM(飞腾/海思)', url: 'https://download.hw99.com/scanner/drivers/Software/wenbenwang/signed_HanvonTextApp_2.0.9_arm64-uos.deb' }
1221    ]
1222  }
1223],
1224    videos: [
1225  { bvid: 'BV1fKQ2BxEW4', title: '汉王扫描仪驱动搜索及下载', cover: 'https://i1.hdslb.com/bfs/archive/bf7cbfc06c4e13c4c3bfb929bc6f1d5bd2e7b422.jpg' },
1226  { bvid: 'BV1azXhBrEB1', title: '国产操作系统CPU架构判断', cover: 'http://i2.hdslb.com/bfs/archive/abd0e83f414a758079735e45662ab7d56e0bfdac.jpg' },
1227  { bvid: 'BV1pRXbBXE3y', title: '汉王扫描仪驱动安装(Windows)', cover: 'https://i1.hdslb.com/bfs/archive/554b9898a1111879e21f8be89c66dcb95dd1552b.jpg' },
1228  { bvid: 'BV1pRXbBXEz2', title: '汉王扫描仪驱动安装(国产操作系统)', cover: 'https://i1.hdslb.com/bfs/archive/268f6831ffa3d906b2715766b7cee59f04d38d50.jpg' },
1229  { bvid: 'BV1NSXKBZEcB', title: '汉王扫描仪连接及放纸', cover: 'http://i1.hdslb.com/bfs/archive/2c706b1ec101d75dbb161f466a25c7702ed9068b.jpg' },
1230  { bvid: 'BV1skXoBvE3r', title: '汉王扫描仪基础扫描(国产操作系统)', cover: 'http://i1.hdslb.com/bfs/archive/559273e3f0423de216b6fe1a4e6272c72b6bab88.jpg' },
1231  { bvid: 'BV1CyXoBPEmp', title: '汉王扫描仪日常清洁维护', cover: 'http://i0.hdslb.com/bfs/archive/ba8a79cfff2e34bb17c0ba2e1b298922f816be19.jpg' }
1232]
1233  };
1234  function $(id) { return document.getElementById(id); }
1235  var els = {
1236    input: $('model-input'), btn: $('search-btn'), loading: $('loading'),
1237    empty: $('empty'), result: $('result-area'), software: $('software-area'),
1238    filter: $('filter-bar'), os: $('os-filter'), arch: $('arch-filter'),
1239    reset: $('filter-reset'), toast: $('toast'), mobileNotice: $('mobile-notice'),
1240    hotlineFab: $('hotline-fab'), hotlinePanel: $('hotline-fab-panel'),
1241    hotlineBtn: $('hotline-fab-btn'), mobileBar: $('hotline-mobile-bar'),
1242    miniFab: $('hotline-mini-fab'), mobileDetail: $('hotline-mobile-detail'),
1243    video: $('video-area'), videoModal: $('video-modal'),
1244    videoModalTitle: $('video-modal-title'), videoModalPlayer: $('video-modal-player')
1245  };
1246  var state = { keyword: '', drivers: [], filters: { os: 'all', arch: 'all' } };
1247  function valid(a) { return Array.isArray(a) && a.length > 0; }
1248  function osName(t) {
1249    var map = { Windows: 'Windows', Kylin: '麒麟Kylin', UOS: '统信UOS' };
1250    return map[t] || t || '未知';
1251  }
1252  // 热线控制
1253  window.toggleHotlinePanel = function() {
1254    var isOpen = els.hotlinePanel.classList.contains('show');
1255    if (isOpen) {
1256      els.hotlinePanel.classList.remove('show');
1257      els.hotlineBtn.classList.add('pulse');
1258    } else {
1259      els.hotlinePanel.classList.add('show');
1260      els.hotlineBtn.classList.remove('pulse');
1261    }
1262  };
1263  window.hideMobileHotline = function() {
1264    els.mobileBar.classList.add('hidden');
1265    setTimeout(function() { els.miniFab.classList.add('show'); }, 300);
1266  };
1267  window.showMobileHotline = function() {
1268    els.miniFab.classList.remove('show');
1269    els.mobileBar.classList.remove('hidden');
1270  };
1271  window.callHotline = function() { window.location.href = 'tel:400-810-8816'; };
1272  window.showMobileDetail = function() { els.mobileDetail.classList.add('show'); };
1273  window.hideMobileDetail = function() { els.mobileDetail.classList.remove('show'); };
1274  document.addEventListener('click', function(e) {
1275    if (window.innerWidth <= 768) {
1276      if (!els.mobileBar.contains(e.target) && !els.miniFab.contains(e.target)) {
1277        els.mobileDetail.classList.remove('show');
1278      }
1279    }
1280  });
1281  function isMobileDevice() {
1282    return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
1283      || window.matchMedia("(max-width: 768px)").matches;
1284  }
1285  function showMobileNotice() {
1286    if (isMobileDevice()) { els.mobileNotice.classList.add('show'); }
1287  }
1288  window.closeMobileNotice = function() {
1289    els.mobileNotice.classList.remove('show');
1290    localStorage.setItem('mobileNoticeClosed', 'true');
1291    localStorage.setItem('mobileNoticeClosedTime', Date.now().toString());
1292  };
1293  function shouldShowMobileNotice() {
1294    var closedTime = localStorage.getItem('mobileNoticeClosedTime');
1295    if (closedTime) {
1296      var hoursPassed = (Date.now() - parseInt(closedTime, 10)) / (1000 * 60 * 60);
1297      if (hoursPassed < 24) return false;
1298    }
1299    return true;
1300  }
1301  // 视频播放
1302  window.playVideo = function(bvid, title) {
1303    els.videoModalTitle.textContent = title;
1304    els.videoModalPlayer.innerHTML =
1305      '<iframe src="https://player.bilibili.com/player.html?bvid=' + bvid + '&autoplay=1&high_quality=1" ' +
1306      'scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe>';
1307    els.videoModal.classList.add('show');
1308    document.body.style.overflow = 'hidden';
1309  };
1310  window.closeVideoModal = function(event) {
1311    if (event && event.target !== els.videoModal && !event.target.closest('.video-modal-close')) return;
1312    els.videoModal.classList.remove('show');
1313    els.videoModalPlayer.innerHTML = '';
1314    document.body.style.overflow = '';
1315  };
1316  els.videoModal.querySelector('.video-modal-content').addEventListener('click', function(e) {
1317    e.stopPropagation();
1318  });
1319  document.addEventListener('keydown', function(e) {
1320    if (e.key === 'Escape' && els.videoModal.classList.contains('show')) { closeVideoModal(); }
1321  });
1322  // 视频渲染
1323  function renderVideos() {
1324    if (!valid(CFG.videos)) {
1325      els.video.innerHTML =
1326        '<div class="video-empty"><i class="fas fa-film"></i><p>暂无演示视频</p></div>';
1327      return;
1328    }
1329    var html = '';
1330    for (var i = 0; i < CFG.videos.length; i++) {
1331      var v = CFG.videos[i];
1332      var safeTitle = v.title.replace(/'/g, "\\'");
1333      html +=
1334        '<div class="video-card" onclick="playVideo(\'' + v.bvid + '\', \'' + safeTitle + '\')" title="点击播放:' + v.title + '">' +
1335        '<div class="video-thumbnail">' +
1336        '<img src="' + (v.cover || ('https://i0.hdslb.com/bfs/archive/' + v.bvid + '.jpg')) + '" alt="' + v.title + '" referrerpolicy="no-referrer" ' +
1337        'onerror="this.src=\'https://via.placeholder.com/320x180/1a1a2e/4361ee?text=\u25B6\'">' +
1338        '<div class="video-play-overlay"><div class="video-play-btn"><i class="fas fa-play"></i></div></div>' +
1339        '</div><div class="video-info"><div class="video-name">' + v.title + '</div></div></div>';
1340    }
1341    els.video.innerHTML = html;
1342  }
1343  // 配套软件渲染
1344  function renderSoftware() {
1345    var icon = CFG.expand ? '\u2212' : '+';
1346    var display = CFG.expand ? '' : 'none';
1347    var html = '<div class="table-container"><table class="common-table"><tbody>';
1348    for (var i = 0; i < CFG.software.length; i++) {
1349      var sw = CFG.software[i];
1350      var gid = 'sw-' + i;
1351      var desc = sw.desc ? '<span class="software-desc">' + sw.desc + '</span>' : '';
1352      html +=
1353        '<tr class="model-group-row os-group-row" data-group="' + gid + '">' +
1354        '<td colspan="4"><span class="expand-icon">' + icon + '</span><i class="fas fa-box"></i> ' + sw.name + desc + '</td></tr>';
1355      for (var j = 0; j < sw.versions.length; j++) {
1356        var v = sw.versions[j];
1357        // 优先本行rowName,无则回退外层软件名称
1358        var currentRowName = v.rowName || sw.name;
1359        if (j === 0) {
1360          html +=
1361            '<tr class="detail-header-row" data-parent="' + gid + '" style="display:' + display + '">' +
1362            '<td>软件名称</td><td>操作系统</td><td>系统架构</td><td>下载操作</td></tr>';
1363        }
1364        html +=
1365          '<tr class="software-detail-row" data-parent="' + gid + '" style="display:' + display + '">' +
1366          '<td>' + currentRowName + '</td><td>' + v.os + '</td><td>' + v.arch + '</td>' +
1367          '<td><button class="download-btn" data-url="' + v.url + '" data-model="' + currentRowName + '"><i class="fas fa-download"></i> 下载</button></td></tr>';
1368      }
1369    }
1370    html += '</tbody></table></div>';
1371    els.software.innerHTML = html;
1372  }
1373  // 搜索
1374  function search() {
1375    var kw = els.input.value.trim();
1376    if (!kw) { toast('请输入扫描仪型号', 'warning'); return; }
1377    state.keyword = kw;
1378    updateUrl('keyword', kw);
1379    els.loading.classList.add('active');
1380    els.result.innerHTML = '';
1381    els.empty.classList.remove('active');
1382    els.filter.classList.remove('active');
1383    fetch(CFG.API + '/search?keyword=' + encodeURIComponent(kw)).then(function(res) {
1384      return res.json();
1385    }).then(function(json) {
1386      var success = json.success, data = json.data || [], message = json.message;
1387      if (!success) throw new Error(message);
1388      var lower = kw.toLowerCase();
1389      var matched;
1390      if (CFG.searchMode === 1) {
1391        matched = data.filter(function(d) { return d.model === kw || d.modelRemark === kw; });
1392      } else {
1393        matched = data.filter(function(d) {
1394          return ((d.model || '').toLowerCase().indexOf(lower) !== -1) || ((d.modelRemark || '').toLowerCase().indexOf(lower) !== -1);
1395        });
1396      }
1397      state.drivers = matched;
1398      if (!matched.length) {
1399        els.empty.innerHTML = '<p>' + (CFG.searchMode === 1 ? '未找到精确匹配的型号' : '未找到相关驱动,请尝试其他关键词') + '</p>';
1400        els.empty.classList.add('active');
1401      } else {
1402        initFilters(matched);
1403        els.filter.classList.add('active');
1404        renderDrivers(matched);
1405      }
1406    }).catch(function(e) {
1407      els.empty.innerHTML = '<p>搜索出错:' + e.message + '</p>';
1408      els.empty.classList.add('active');
1409      toast(e.message, 'error');
1410    }).finally(function() {
1411      els.loading.classList.remove('active');
1412    });
1413  }
1414  // 初始化筛选器
1415  function initFilters(data) {
1416    var osSet = {};
1417    var archSet = {};
1418    for (var i = 0; i < data.length; i++) {
1419      var d = data[i];
1420      var groups = d.osGroups || [];
1421      for (var j = 0; j < groups.length; j++) {
1422        var g = groups[j];
1423        osSet[osName(g.type)] = true;
1424        var osType = g.osType;
1425        if (osType) {
1426          var archs = osType.architectures || [];
1427          for (var k = 0; k < archs.length; k++) {
1428            if (archs[k].name) archSet[archs[k].name] = true;
1429          }
1430        }
1431      }
1432    }
1433    var osKeys = Object.keys(osSet).sort();
1434    var archKeys = Object.keys(archSet).sort();
1435    var osHtml = '<option value="all">全部操作系统</option>';
1436    for (var a = 0; a < osKeys.length; a++) { osHtml += '<option>' + osKeys[a] + '</option>'; }
1437    var archHtml = '<option value="all">全部系统架构</option>';
1438    for (var b = 0; b < archKeys.length; b++) { archHtml += '<option>' + archKeys[b] + '</option>'; }
1439    els.os.innerHTML = osHtml;
1440    els.arch.innerHTML = archHtml;
1441  }
1442  // 渲染驱动列表
1443  function renderDrivers(data, filterInfo) {
1444    filterInfo = filterInfo || '';
1445    var icon = CFG.expand ? '\u2212' : '+';
1446    var display = CFG.expand ? '' : 'none';
1447    var kw = state.keyword;
1448    function hl(text) {
1449      if (!kw || !text) return text;
1450      var escaped = kw.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1451      return text.replace(new RegExp('(' + escaped + ')', 'gi'), '<span class="highlight">$1</span>');
1452    }
1453    var html = '<div class="result-count"><i class="fas fa-list"></i> 找到 ' + data.length + ' 个型号' + filterInfo + '</div>' +
1454      '<div class="table-container"><table class="common-table"><tbody>';
1455    for (var mi = 0; mi < data.length; mi++) {
1456      var driver = data[mi];
1457      var rawModel = driver.model || '未知型号';
1458      var model = hl(rawModel);
1459      var desc = driver.modelRemark ? '<span class="software-desc">' + hl(driver.modelRemark) + '</span>' : '';
1460      var gid = 'm-' + mi;
1461      html +=
1462        '<tr class="model-group-row" data-group="' + gid + '">' +
1463        '<td colspan="5"><span class="expand-icon">' + icon + '</span><i class="fas fa-scanner"></i> ' + model + desc + '</td></tr>';
1464      var groups = driver.osGroups || [];
1465      if (!valid(groups)) {
1466        html +=
1467          '<tr class="detail-header-row" data-parent="' + gid + '" style="display:' + display + '">' +
1468          '<td>扫描仪型号</td><td>操作系统</td><td>系统架构</td><td>文件说明</td><td>下载操作</td></tr>' +
1469          '<tr class="driver-detail-row" data-parent="' + gid + '" style="display:' + display + '">' +
1470          '<td>' + model + '</td><td colspan="4" class="no-driver-cell"><i class="fas fa-exclamation-circle"></i> 暂无该型号驱动</td></tr>';
1471        continue;
1472      }
1473      for (var gi = 0; gi < groups.length; gi++) {
1474        var g = groups[gi];
1475        var os = osName(g.type);
1476        var osType = g.osType;
1477        var ver = (osType && osType.version) ? '<span class="version-info">' + osType.version + '</span>' : '';
1478        var sgid = gid + '-' + gi;
1479        html +=
1480          '<tr class="os-group-row" data-group="' + sgid + '" data-parent="' + gid + '" style="display:' + display + '">' +
1481          '<td colspan="5"><span class="expand-icon">' + icon + '</span><i class="fas fa-desktop"></i> ' + os + ver + '</td></tr>';
1482        var archs = (osType && osType.architectures) || [];
1483        for (var ai = 0; ai < archs.length; ai++) {
1484          var a = archs[ai];
1485          if (ai === 0) {
1486            html +=
1487              '<tr class="detail-header-row" data-parent="' + sgid + '" style="display:' + display + '">' +
1488              '<td>扫描仪型号</td><td>操作系统</td><td>系统架构</td><td>文件说明</td><td>下载操作</td></tr>';
1489          }
1490          var lastClass = (ai === archs.length - 1) ? 'last-in-group' : '';
1491          html +=
1492            '<tr class="driver-detail-row ' + lastClass + '" data-parent="' + sgid + '" style="display:' + display + '">' +
1493            '<td>' + model + '</td><td>' + os + '</td><td>' + (a.name || '未知架构') + '</td><td>' + (a.version || '') + '</td>' +
1494            '<td><button class="download-btn" data-url="' + a.url + '" data-model="' + rawModel + '"><i class="fas fa-download"></i> 下载</button></td></tr>';
1495        }
1496      }
1497    }
1498    html += '</tbody></table></div>';
1499    els.result.innerHTML = html;
1500  }
1501  // 筛选
1502  function applyFilter() {
1503    state.filters = { os: els.os.value, arch: els.arch.value };
1504    var filtered = JSON.parse(JSON.stringify(state.drivers));
1505    if (state.filters.os !== 'all') {
1506      for (var i = 0; i < filtered.length; i++) {
1507        var groups = filtered[i].osGroups || [];
1508        filtered[i].osGroups = groups.filter(function(g) { return osName(g.type) === state.filters.os; });
1509      }
1510    }
1511    if (state.filters.arch !== 'all') {
1512      for (var j = 0; j < filtered.length; j++) {
1513        var gs = filtered[j].osGroups || [];
1514        filtered[j].osGroups = gs.map(function(g) {
1515          var osType = g.osType;
1516          var archs = (osType && osType.architectures) || [];
1517          var newArchs = archs.filter(function(a) { return a.name === state.filters.arch; });
1518          var newOsType = Object.assign({}, osType, { architectures: newArchs });
1519          return Object.assign({}, g, { osType: newOsType });
1520        }).filter(function(g) { return valid(g.osType && g.osType.architectures); });
1521      }
1522    }
1523    filtered = filtered.filter(function(d) { return valid(d.osGroups); });
1524    var info = '';
1525    if (state.filters.os !== 'all' || state.filters.arch !== 'all') {
1526      var parts = [];
1527      if (state.filters.os !== 'all') parts.push('操作系统:' + state.filters.os);
1528      if (state.filters.arch !== 'all') parts.push('系统架构:' + state.filters.arch);
1529      info = '(筛选条件:' + parts.join(',') + ')';
1530    }
1531    if (valid(filtered)) {
1532      renderDrivers(filtered, info);
1533    } else {
1534      els.result.innerHTML = '<div class="empty active" style="display:block"><p>没有符合筛选条件的驱动</p></div>';
1535    }
1536  }
1537  function resetFilter() {
1538    els.os.value = els.arch.value = 'all';
1539    state.filters = { os: 'all', arch: 'all' };
1540    renderDrivers(state.drivers);
1541    toast('筛选已重置', 'info');
1542  }
1543  // 展开/收起(修复 NodeList.forEach 问题)
1544  function toggleExpand(row) {
1545    var id = row.getAttribute('data-group');
1546    var icon = row.querySelector('.expand-icon');
1547    if (!icon) return;
1548    var expanded = icon.textContent === '\u2212';
1549    if (expanded) {
1550      var children = document.querySelectorAll('[data-parent="' + id + '"]');
1551      for (var i = 0; i < children.length; i++) {
1552        var child = children[i];
1553        if (child.classList.contains('model-group-row') || child.classList.contains('os-group-row')) {
1554          var childIcon = child.querySelector('.expand-icon');
1555          if (childIcon && childIcon.textContent === '\u2212') { toggleExpand(child); }
1556        }
1557      }
1558    }
1559    icon.textContent = expanded ? '+' : '\u2212';
1560    var children2 = document.querySelectorAll('[data-parent="' + id + '"]');
1561    for (var j = 0; j < children2.length; j++) {
1562      children2[j].style.display = expanded ? 'none' : '';
1563    }
1564  }
1565  function download(btn) {
1566    var url = btn.getAttribute('data-url');
1567    var model = btn.getAttribute('data-model');
1568    try {
1569      if (!url || !(new URL(url)).href.indexOf('http') === 0) throw new Error();
1570      toast('开始下载 ' + model, 'success');
1571      window.location.href = url;
1572    } catch(e) {
1573      toast('下载链接无效', 'error');
1574    }
1575  }
1576  function toast(msg, type) {
1577    type = type || 'info';
1578    els.toast.textContent = msg;
1579    els.toast.className = 'toast ' + type + ' show';
1580    setTimeout(function() { els.toast.classList.remove('show'); }, 3000);
1581  }
1582  function updateUrl(k, v) {
1583    var p = new URLSearchParams(location.search);
1584    if (v) { p.set(k, v); } else { p.delete(k); }
1585    history.replaceState({}, '', location.pathname + (p.toString() ? '?' + p.toString() : ''));
1586  }
1587  // 事件监听
1588  document.addEventListener('click', function(e) {
1589    var row = e.target.closest('.model-group-row, .os-group-row');
1590    if (row) toggleExpand(row);
1591    var btn = e.target.closest('.download-btn');
1592    if (btn) { e.stopPropagation(); download(btn); }
1593  });
1594  els.btn.addEventListener('click', search);
1595  els.input.addEventListener('keypress', function(e) { if (e.key === 'Enter') search(); });
1596  els.input.addEventListener('focus', function() { els.input.select(); });
1597  els.os.addEventListener('change', applyFilter);
1598  els.arch.addEventListener('change', applyFilter);
1599  els.reset.addEventListener('click', resetFilter);
1600  // 初始化
1601  renderSoftware();
1602  renderVideos();
1603  if (shouldShowMobileNotice()) { showMobileNotice(); }
1604  var urlKw = new URLSearchParams(location.search).get('keyword');
1605  if (urlKw) { els.input.value = decodeURIComponent(urlKw); search(); }
1606  window.addEventListener('resize', function() {
1607    if (window.innerWidth > 768) {
1608      els.hotlinePanel.classList.add('show');
1609      els.hotlineBtn.classList.remove('pulse');
1610      els.mobileBar.classList.remove('hidden');
1611      els.miniFab.classList.remove('show');
1612      els.mobileDetail.classList.remove('show');
1613    } else {
1614      els.hotlinePanel.classList.remove('show');
1615      els.hotlineBtn.classList.add('pulse');
1616    }
1617  });
1618 </script>
1618
1619</body>
1620</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.