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.