1package zh_tw 2 3import ( 4 "fmt" 5 "log" 6 "reflect" 7 "strconv" 8 "strings" 9 "time" 10 11 "github.com/go-playground/locales" 12 ut "github.com/go-playground/universal-translator" 13 "github.com/go-playground/validator/v10" 14) 15 16// RegisterDefaultTranslations registers a set of default translations 17// for all built in tag's in validator; you may add your own as desired. 18func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) { 19 20 translations := []struct { 21 tag string 22 translation string 23 override bool 24 customRegisFunc validator.RegisterTranslationsFunc 25 customTransFunc validator.TranslationFunc 26 }{ 27 { 28 tag: "required", 29 translation: "{0}為必填欄位", 30 override: false, 31 }, 32 { 33 tag: "len", 34 customRegisFunc: func(ut ut.Translator) (err error) { 35 36 if err = ut.Add("len-string", "{0}長度必須為{1}", false); err != nil { 37 return 38 } 39 40 //if err = ut.AddCardinal("len-string-character", "{0}字元", locales.PluralRuleOne, false); err != nil { 41 // return 42 //} 43 44 if err = ut.AddCardinal("len-string-character", "{0}個字元", locales.PluralRuleOther, false); err != nil { 45 return 46 } 47 48 if err = ut.Add("len-number", "{0}必須等於{1}", false); err != nil { 49 return 50 } 51 52 if err = ut.Add("len-items", "{0}必須包含{1}", false); err != nil { 53 return 54 } 55 //if err = ut.AddCardinal("len-items-item", "{0}項", locales.PluralRuleOne, false); err != nil { 56 // return 57 //} 58 59 if err = ut.AddCardinal("len-items-item", "{0}項", locales.PluralRuleOther, false); err != nil { 60 return 61 } 62 63 return 64 65 }, 66 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 67 68 var err error 69 var t string 70 71 var digits uint64 72 var kind reflect.Kind 73 74 if idx := strings.Index(fe.Param(), "."); idx != -1 { 75 digits = uint64(len(fe.Param()[idx+1:])) 76 } 77 78 f64, err := strconv.ParseFloat(fe.Param(), 64) 79 if err != nil { 80 goto END 81 } 82 83 kind = fe.Kind() 84 if kind == reflect.Ptr { 85 kind = fe.Type().Elem().Kind() 86 } 87 88 switch kind { 89 case reflect.String: 90 91 var c string 92 93 c, err = ut.C("len-string-character", f64, digits, ut.FmtNumber(f64, digits)) 94 if err != nil { 95 goto END 96 } 97 98 t, err = ut.T("len-string", fe.Field(), c) 99 100 case reflect.Slice, reflect.Map, reflect.Array: 101 var c string 102 103 c, err = ut.C("len-items-item", f64, digits, ut.FmtNumber(f64, digits)) 104 if err != nil { 105 goto END 106 } 107 108 t, err = ut.T("len-items", fe.Field(), c) 109 110 default: 111 t, err = ut.T("len-number", fe.Field(), ut.FmtNumber(f64, digits)) 112 } 113 114 END: 115 if err != nil { 116 fmt.Printf("警告: 翻譯欄位錯誤: %s", err) 117 return fe.(error).Error() 118 } 119 120 return t 121 }, 122 }, 123 { 124 tag: "min", 125 customRegisFunc: func(ut ut.Translator) (err error) { 126 127 if err = ut.Add("min-string", "{0}長度必須至少為{1}", false); err != nil { 128 return 129 } 130 131 //if err = ut.AddCardinal("min-string-character", "{0}個字元", locales.PluralRuleOne, false); err != nil { 132 // return 133 //} 134 135 if err = ut.AddCardinal("min-string-character", "{0}個字元", locales.PluralRuleOther, false); err != nil { 136 return 137 } 138 139 if err = ut.Add("min-number", "{0}最小只能為{1}", false); err != nil { 140 return 141 } 142 143 if err = ut.Add("min-items", "{0}必須至少包含{1}", false); err != nil { 144 return 145 } 146 //if err = ut.AddCardinal("min-items-item", "{0}項", locales.PluralRuleOne, false); err != nil { 147 // return 148 //} 149 150 if err = ut.AddCardinal("min-items-item", "{0}項", locales.PluralRuleOther, false); err != nil { 151 return 152 } 153 154 return 155 156 }, 157 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 158 159 var err error 160 var t string 161 162 var digits uint64 163 var kind reflect.Kind 164 165 if idx := strings.Index(fe.Param(), "."); idx != -1 { 166 digits = uint64(len(fe.Param()[idx+1:])) 167 } 168 169 f64, err := strconv.ParseFloat(fe.Param(), 64) 170 if err != nil { 171 goto END 172 } 173 174 kind = fe.Kind() 175 if kind == reflect.Ptr { 176 kind = fe.Type().Elem().Kind() 177 } 178 179 switch kind { 180 case reflect.String: 181 182 var c string 183 184 c, err = ut.C("min-string-character", f64, digits, ut.FmtNumber(f64, digits)) 185 if err != nil { 186 goto END 187 } 188 189 t, err = ut.T("min-string", fe.Field(), c) 190 191 case reflect.Slice, reflect.Map, reflect.Array: 192 var c string 193 194 c, err = ut.C("min-items-item", f64, digits, ut.FmtNumber(f64, digits)) 195 if err != nil { 196 goto END 197 } 198 199 t, err = ut.T("min-items", fe.Field(), c) 200 201 default: 202 t, err = ut.T("min-number", fe.Field(), ut.FmtNumber(f64, digits)) 203 } 204 205 END: 206 if err != nil { 207 fmt.Printf("警告: 翻譯欄位錯誤: %s", err) 208 return fe.(error).Error() 209 } 210 211 return t 212 }, 213 }, 214 { 215 tag: "max", 216 customRegisFunc: func(ut ut.Translator) (err error) { 217 218 if err = ut.Add("max-string", "{0}長度不能超過{1}", false); err != nil { 219 return 220 } 221 222 //if err = ut.AddCardinal("max-string-character", "{0}個字元", locales.PluralRuleOne, false); err != nil { 223 // return 224 //} 225 226 if err = ut.AddCardinal("max-string-character", "{0}個字元", locales.PluralRuleOther, false); err != nil { 227 return 228 } 229 230 if err = ut.Add("max-number", "{0}必須小於或等於{1}", false); err != nil { 231 return 232 } 233 234 if err = ut.Add("max-items", "{0}最多只能包含{1}", false); err != nil { 235 return 236 } 237 //if err = ut.AddCardinal("max-items-item", "{0}項", locales.PluralRuleOne, false); err != nil { 238 // return 239 //} 240 241 if err = ut.AddCardinal("max-items-item", "{0}項", locales.PluralRuleOther, false); err != nil { 242 return 243 } 244 245 return 246 247 }, 248 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 249 250 var err error 251 var t string 252 253 var digits uint64 254 var kind reflect.Kind 255 256 if idx := strings.Index(fe.Param(), "."); idx != -1 { 257 digits = uint64(len(fe.Param()[idx+1:])) 258 } 259 260 f64, err := strconv.ParseFloat(fe.Param(), 64) 261 if err != nil { 262 goto END 263 } 264 265 kind = fe.Kind() 266 if kind == reflect.Ptr { 267 kind = fe.Type().Elem().Kind() 268 } 269 270 switch kind { 271 case reflect.String: 272 273 var c string 274 275 c, err = ut.C("max-string-character", f64, digits, ut.FmtNumber(f64, digits)) 276 if err != nil { 277 goto END 278 } 279 280 t, err = ut.T("max-string", fe.Field(), c) 281 282 case reflect.Slice, reflect.Map, reflect.Array: 283 var c string 284 285 c, err = ut.C("max-items-item", f64, digits, ut.FmtNumber(f64, digits)) 286 if err != nil { 287 goto END 288 } 289 290 t, err = ut.T("max-items", fe.Field(), c) 291 292 default: 293 t, err = ut.T("max-number", fe.Field(), ut.FmtNumber(f64, digits)) 294 } 295 296 END: 297 if err != nil { 298 fmt.Printf("警告: 翻譯欄位錯誤: %s", err) 299 return fe.(error).Error() 300 } 301 302 return t 303 }, 304 }, 305 { 306 tag: "eq", 307 translation: "{0}不等於{1}", 308 override: false, 309 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 310 311 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 312 if err != nil { 313 fmt.Printf("警告: 翻譯欄位錯誤: %#v", fe) 314 return fe.(error).Error() 315 } 316 317 return t 318 }, 319 }, 320 { 321 tag: "ne", 322 translation: "{0}不能等於{1}", 323 override: false, 324 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 325 326 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 327 if err != nil { 328 fmt.Printf("警告: 翻譯欄位錯誤: %#v", fe) 329 return fe.(error).Error() 330 } 331 332 return t 333 }, 334 }, 335 { 336 tag: "lt", 337 customRegisFunc: func(ut ut.Translator) (err error) { 338 339 if err = ut.Add("lt-string", "{0}長度必須小於{1}", false); err != nil { 340 return 341 } 342 343 //if err = ut.AddCardinal("lt-string-character", "{0}個字元", locales.PluralRuleOne, false); err != nil { 344 // return 345 //} 346 347 if err = ut.AddCardinal("lt-string-character", "{0}個字元", locales.PluralRuleOther, false); err != nil { 348 return 349 } 350 351 if err = ut.Add("lt-number", "{0}必須小於{1}", false); err != nil { 352 return 353 } 354 355 if err = ut.Add("lt-items", "{0}必須包含少於{1}", false); err != nil { 356 return 357 } 358 359 //if err = ut.AddCardinal("lt-items-item", "{0}項", locales.PluralRuleOne, false); err != nil { 360 // return 361 //} 362 363 if err = ut.AddCardinal("lt-items-item", "{0}項", locales.PluralRuleOther, false); err != nil { 364 return 365 } 366 367 if err = ut.Add("lt-datetime", "{0}必須小於目前日期和時間", false); err != nil { 368 return 369 } 370 371 return 372 373 }, 374 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 375 376 var err error 377 var t string 378 var f64 float64 379 var digits uint64 380 var kind reflect.Kind 381 382 fn := func() (err error) { 383 384 if idx := strings.Index(fe.Param(), "."); idx != -1 { 385 digits = uint64(len(fe.Param()[idx+1:])) 386 } 387 388 f64, err = strconv.ParseFloat(fe.Param(), 64) 389 390 return 391 } 392 393 kind = fe.Kind() 394 if kind == reflect.Ptr { 395 kind = fe.Type().Elem().Kind() 396 } 397 398 switch kind { 399 case reflect.String: 400 401 var c string 402 403 err = fn() 404 if err != nil { 405 goto END 406 } 407 408 c, err = ut.C("lt-string-character", f64, digits, ut.FmtNumber(f64, digits)) 409 if err != nil { 410 goto END 411 } 412 413 t, err = ut.T("lt-string", fe.Field(), c) 414 415 case reflect.Slice, reflect.Map, reflect.Array: 416 var c string 417 418 err = fn() 419 if err != nil { 420 goto END 421 } 422 423 c, err = ut.C("lt-items-item", f64, digits, ut.FmtNumber(f64, digits)) 424 if err != nil { 425 goto END 426 } 427 428 t, err = ut.T("lt-items", fe.Field(), c) 429 430 case reflect.Struct: 431 if fe.Type() != reflect.TypeOf(time.Time{}) { 432 err = fmt.Errorf("tag '%s'不能用於struct類型.", fe.Tag()) 433 } else { 434 t, err = ut.T("lt-datetime", fe.Field()) 435 } 436 437 default: 438 err = fn() 439 if err != nil { 440 goto END 441 } 442 443 t, err = ut.T("lt-number", fe.Field(), ut.FmtNumber(f64, digits)) 444 } 445 446 END: 447 if err != nil { 448 fmt.Printf("警告: 翻譯欄位錯誤: %s", err) 449 return fe.(error).Error() 450 } 451 452 return t 453 }, 454 }, 455 { 456 tag: "lte", 457 customRegisFunc: func(ut ut.Translator) (err error) { 458 459 if err = ut.Add("lte-string", "{0}長度不能超過{1}", false); err != nil { 460 return 461 } 462 463 //if err = ut.AddCardinal("lte-string-character", "{0} character", locales.PluralRuleOne, false); err != nil { 464 // return 465 //} 466 467 if err = ut.AddCardinal("lte-string-character", "{0}個字元", locales.PluralRuleOther, false); err != nil { 468 return 469 } 470 471 if err = ut.Add("lte-number", "{0}必須小於或等於{1}", false); err != nil { 472 return 473 } 474 475 if err = ut.Add("lte-items", "{0}最多只能包含{1}", false); err != nil { 476 return 477 } 478 479 //if err = ut.AddCardinal("lte-items-item", "{0} item", locales.PluralRuleOne, false); err != nil { 480 // return 481 //} 482 483 if err = ut.AddCardinal("lte-items-item", "{0}項", locales.PluralRuleOther, false); err != nil { 484 return 485 } 486 487 if err = ut.Add("lte-datetime", "{0}必須小於或等於目前日期和時間", false); err != nil { 488 return 489 } 490 491 return 492 }, 493 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 494 495 var err error 496 var t string 497 var f64 float64 498 var digits uint64 499 var kind reflect.Kind 500 501 fn := func() (err error) { 502 503 if idx := strings.Index(fe.Param(), "."); idx != -1 { 504 digits = uint64(len(fe.Param()[idx+1:])) 505 } 506 507 f64, err = strconv.ParseFloat(fe.Param(), 64) 508 509 return 510 } 511 512 kind = fe.Kind() 513 if kind == reflect.Ptr { 514 kind = fe.Type().Elem().Kind() 515 } 516 517 switch kind { 518 case reflect.String: 519 520 var c string 521 522 err = fn() 523 if err != nil { 524 goto END 525 } 526 527 c, err = ut.C("lte-string-character", f64, digits, ut.FmtNumber(f64, digits)) 528 if err != nil { 529 goto END 530 } 531 532 t, err = ut.T("lte-string", fe.Field(), c) 533 534 case reflect.Slice, reflect.Map, reflect.Array: 535 var c string 536 537 err = fn() 538 if err != nil { 539 goto END 540 } 541 542 c, err = ut.C("lte-items-item", f64, digits, ut.FmtNumber(f64, digits)) 543 if err != nil { 544 goto END 545 } 546 547 t, err = ut.T("lte-items", fe.Field(), c) 548 549 case reflect.Struct: 550 if fe.Type() != reflect.TypeOf(time.Time{}) { 551 err = fmt.Errorf("tag '%s'不能用於struct類型.", fe.Tag()) 552 } else { 553 t, err = ut.T("lte-datetime", fe.Field()) 554 } 555 556 default: 557 err = fn() 558 if err != nil { 559 goto END 560 } 561 562 t, err = ut.T("lte-number", fe.Field(), ut.FmtNumber(f64, digits)) 563 } 564 565 END: 566 if err != nil { 567 fmt.Printf("警告: 翻譯欄位錯誤: %s", err) 568 return fe.(error).Error() 569 } 570 571 return t 572 }, 573 }, 574 { 575 tag: "gt", 576 customRegisFunc: func(ut ut.Translator) (err error) { 577 578 if err = ut.Add("gt-string", "{0}長度必須大於{1}", false); err != nil { 579 return 580 } 581 582 //if err = ut.AddCardinal("gt-string-character", "{0}個字元", locales.PluralRuleOne, false); err != nil { 583 // return 584 //} 585 586 if err = ut.AddCardinal("gt-string-character", "{0}個字元", locales.PluralRuleOther, false); err != nil { 587 return 588 } 589 590 if err = ut.Add("gt-number", "{0}必須大於{1}", false); err != nil { 591 return 592 } 593 594 if err = ut.Add("gt-items", "{0}必須大於{1}", false); err != nil { 595 return 596 } 597 598 //if err = ut.AddCardinal("gt-items-item", "{0}項", locales.PluralRuleOne, false); err != nil { 599 // return 600 //} 601 602 if err = ut.AddCardinal("gt-items-item", "{0}項", locales.PluralRuleOther, false); err != nil { 603 return 604 } 605 606 if err = ut.Add("gt-datetime", "{0}必須大於目前日期和時間", false); err != nil { 607 return 608 } 609 610 return 611 }, 612 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 613 614 var err error 615 var t string 616 var f64 float64 617 var digits uint64 618 var kind reflect.Kind 619 620 fn := func() (err error) { 621 if idx := strings.Index(fe.Param(), "."); idx != -1 { 622 digits = uint64(len(fe.Param()[idx+1:])) 623 } 624 f64, err = strconv.ParseFloat(fe.Param(), 64) 625 return 626 } 627 628 kind = fe.Kind() 629 if kind == reflect.Ptr { 630 kind = fe.Type().Elem().Kind() 631 } 632 633 switch kind { 634 case reflect.String: 635 636 var c string 637 638 err = fn() 639 if err != nil { 640 goto END 641 } 642 643 c, err = ut.C("gt-string-character", f64, digits, ut.FmtNumber(f64, digits)) 644 if err != nil { 645 goto END 646 } 647 648 t, err = ut.T("gt-string", fe.Field(), c) 649 650 case reflect.Slice, reflect.Map, reflect.Array: 651 var c string 652 653 err = fn() 654 if err != nil { 655 goto END 656 } 657 658 c, err = ut.C("gt-items-item", f64, digits, ut.FmtNumber(f64, digits)) 659 if err != nil { 660 goto END 661 } 662 663 t, err = ut.T("gt-items", fe.Field(), c) 664 665 case reflect.Struct: 666 if fe.Type() != reflect.TypeOf(time.Time{}) { 667 err = fmt.Errorf("tag '%s'不能用於struct類型.", fe.Tag()) 668 } else { 669 t, err = ut.T("gt-datetime", fe.Field()) 670 } 671 672 default: 673 err = fn() 674 if err != nil { 675 goto END 676 } 677 678 t, err = ut.T("gt-number", fe.Field(), ut.FmtNumber(f64, digits)) 679 } 680 681 END: 682 if err != nil { 683 fmt.Printf("警告: 翻譯欄位錯誤: %s", err) 684 return fe.(error).Error() 685 } 686 687 return t 688 }, 689 }, 690 { 691 tag: "gte", 692 customRegisFunc: func(ut ut.Translator) (err error) { 693 694 if err = ut.Add("gte-string", "{0}長度必須至少為{1}", false); err != nil { 695 return 696 } 697 698 //if err = ut.AddCardinal("gte-string-character", "{0}個字元", locales.PluralRuleOne, false); err != nil { 699 // return 700 //} 701 702 if err = ut.AddCardinal("gte-string-character", "{0}個字元", locales.PluralRuleOther, false); err != nil { 703 return 704 } 705 706 if err = ut.Add("gte-number", "{0}必須大於或等於{1}", false); err != nil { 707 return 708 } 709 710 if err = ut.Add("gte-items", "{0}必須至少包含{1}", false); err != nil { 711 return 712 } 713 714 //if err = ut.AddCardinal("gte-items-item", "{0}項", locales.PluralRuleOne, false); err != nil { 715 // return 716 //} 717 718 if err = ut.AddCardinal("gte-items-item", "{0}項", locales.PluralRuleOther, false); err != nil { 719 return 720 } 721 722 if err = ut.Add("gte-datetime", "{0}必須大於或等於目前日期和時間", false); err != nil { 723 return 724 } 725 726 return 727 }, 728 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 729 730 var err error 731 var t string 732 var f64 float64 733 var digits uint64 734 var kind reflect.Kind 735 736 fn := func() (err error) { 737 738 if idx := strings.Index(fe.Param(), "."); idx != -1 { 739 digits = uint64(len(fe.Param()[idx+1:])) 740 } 741 742 f64, err = strconv.ParseFloat(fe.Param(), 64) 743 744 return 745 } 746 747 kind = fe.Kind() 748 if kind == reflect.Ptr { 749 kind = fe.Type().Elem().Kind() 750 } 751 752 switch kind { 753 case reflect.String: 754 755 var c string 756 757 err = fn() 758 if err != nil { 759 goto END 760 } 761 762 c, err = ut.C("gte-string-character", f64, digits, ut.FmtNumber(f64, digits)) 763 if err != nil { 764 goto END 765 } 766 767 t, err = ut.T("gte-string", fe.Field(), c) 768 769 case reflect.Slice, reflect.Map, reflect.Array: 770 var c string 771 772 err = fn() 773 if err != nil { 774 goto END 775 } 776 777 c, err = ut.C("gte-items-item", f64, digits, ut.FmtNumber(f64, digits)) 778 if err != nil { 779 goto END 780 } 781 782 t, err = ut.T("gte-items", fe.Field(), c) 783 784 case reflect.Struct: 785 if fe.Type() != reflect.TypeOf(time.Time{}) { 786 err = fmt.Errorf("tag '%s'不能用於struct類型.", fe.Tag()) 787 } else { 788 t, err = ut.T("gte-datetime", fe.Field()) 789 } 790 791 default: 792 err = fn() 793 if err != nil { 794 goto END 795 } 796 797 t, err = ut.T("gte-number", fe.Field(), ut.FmtNumber(f64, digits)) 798 } 799 800 END: 801 if err != nil { 802 fmt.Printf("警告: 翻譯欄位錯誤: %s", err) 803 return fe.(error).Error() 804 } 805 806 return t 807 }, 808 }, 809 { 810 tag: "eqfield", 811 translation: "{0}必須等於{1}", 812 override: false, 813 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 814 815 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 816 if err != nil { 817 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 818 return fe.(error).Error() 819 } 820 821 return t 822 }, 823 }, 824 { 825 tag: "eqcsfield", 826 translation: "{0}必須等於{1}", 827 override: false, 828 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 829 830 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 831 if err != nil { 832 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 833 return fe.(error).Error() 834 } 835 836 return t 837 }, 838 }, 839 { 840 tag: "necsfield", 841 translation: "{0}不能等於{1}", 842 override: false, 843 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 844 845 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 846 if err != nil { 847 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 848 return fe.(error).Error() 849 } 850 851 return t 852 }, 853 }, 854 { 855 tag: "gtcsfield", 856 translation: "{0}必須大於{1}", 857 override: false, 858 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 859 860 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 861 if err != nil { 862 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 863 return fe.(error).Error() 864 } 865 866 return t 867 }, 868 }, 869 { 870 tag: "gtecsfield", 871 translation: "{0}必須大於或等於{1}", 872 override: false, 873 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 874 875 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 876 if err != nil { 877 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 878 return fe.(error).Error() 879 } 880 881 return t 882 }, 883 }, 884 { 885 tag: "ltcsfield", 886 translation: "{0}必須小於{1}", 887 override: false, 888 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 889 890 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 891 if err != nil { 892 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 893 return fe.(error).Error() 894 } 895 896 return t 897 }, 898 }, 899 { 900 tag: "ltecsfield", 901 translation: "{0}必須小於或等於{1}", 902 override: false, 903 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 904 905 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 906 if err != nil { 907 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 908 return fe.(error).Error() 909 } 910 911 return t 912 }, 913 }, 914 { 915 tag: "nefield", 916 translation: "{0}不能等於{1}", 917 override: false, 918 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 919 920 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 921 if err != nil { 922 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 923 return fe.(error).Error() 924 } 925 926 return t 927 }, 928 }, 929 { 930 tag: "gtfield", 931 translation: "{0}必須大於{1}", 932 override: false, 933 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 934 935 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 936 if err != nil { 937 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 938 return fe.(error).Error() 939 } 940 941 return t 942 }, 943 }, 944 { 945 tag: "gtefield", 946 translation: "{0}必須大於或等於{1}", 947 override: false, 948 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 949 950 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 951 if err != nil { 952 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 953 return fe.(error).Error() 954 } 955 956 return t 957 }, 958 }, 959 { 960 tag: "ltfield", 961 translation: "{0}必須小於{1}", 962 override: false, 963 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 964 965 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 966 if err != nil { 967 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 968 return fe.(error).Error() 969 } 970 971 return t 972 }, 973 }, 974 { 975 tag: "ltefield", 976 translation: "{0}必須小於或等於{1}", 977 override: false, 978 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 979 980 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 981 if err != nil { 982 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 983 return fe.(error).Error() 984 } 985 986 return t 987 }, 988 }, 989 { 990 tag: "alpha", 991 translation: "{0}只能包含字母", 992 override: false, 993 }, 994 { 995 tag: "alphanum", 996 translation: "{0}只能包含字母和數字", 997 override: false, 998 }, 999 { 1000 tag: "numeric", 1001 translation: "{0}必須是一個有效的數值", 1002 override: false, 1003 }, 1004 { 1005 tag: "number", 1006 translation: "{0}必須是一個有效的數字", 1007 override: false, 1008 }, 1009 { 1010 tag: "hexadecimal", 1011 translation: "{0}必須是一個有效的十六進制", 1012 override: false, 1013 }, 1014 { 1015 tag: "hexcolor", 1016 translation: "{0}必須是一個有效的十六進制顏色", 1017 override: false, 1018 }, 1019 { 1020 tag: "rgb", 1021 translation: "{0}必須是一個有效的RGB顏色", 1022 override: false, 1023 }, 1024 { 1025 tag: "rgba", 1026 translation: "{0}必須是一個有效的RGBA顏色", 1027 override: false, 1028 }, 1029 { 1030 tag: "hsl", 1031 translation: "{0}必須是一個有效的HSL顏色", 1032 override: false, 1033 }, 1034 { 1035 tag: "hsla", 1036 translation: "{0}必須是一個有效的HSLA顏色", 1037 override: false, 1038 }, 1039 { 1040 tag: "email", 1041 translation: "{0}必須是一個有效的信箱", 1042 override: false, 1043 }, 1044 { 1045 tag: "url", 1046 translation: "{0}必須是一個有效的URL", 1047 override: false, 1048 }, 1049 { 1050 tag: "uri", 1051 translation: "{0}必須是一個有效的URI", 1052 override: false, 1053 }, 1054 { 1055 tag: "base64", 1056 translation: "{0}必須是一個有效的Base64字元串", 1057 override: false, 1058 }, 1059 { 1060 tag: "contains", 1061 translation: "{0}必須包含文字'{1}'", 1062 override: false, 1063 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 1064 1065 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 1066 if err != nil { 1067 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 1068 return fe.(error).Error() 1069 } 1070 1071 return t 1072 }, 1073 }, 1074 { 1075 tag: "containsany", 1076 translation: "{0}必須包含至少一個以下字元'{1}'", 1077 override: false, 1078 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 1079 1080 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 1081 if err != nil { 1082 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 1083 return fe.(error).Error() 1084 } 1085 1086 return t 1087 }, 1088 }, 1089 { 1090 tag: "excludes", 1091 translation: "{0}不能包含文字'{1}'", 1092 override: false, 1093 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 1094 1095 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 1096 if err != nil { 1097 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 1098 return fe.(error).Error() 1099 } 1100 1101 return t 1102 }, 1103 }, 1104 { 1105 tag: "excludesall", 1106 translation: "{0}不能包含以下任何字元'{1}'", 1107 override: false, 1108 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 1109 1110 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 1111 if err != nil { 1112 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 1113 return fe.(error).Error() 1114 } 1115 1116 return t 1117 }, 1118 }, 1119 { 1120 tag: "excludesrune", 1121 translation: "{0}不能包含'{1}'", 1122 override: false, 1123 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 1124 1125 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 1126 if err != nil { 1127 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 1128 return fe.(error).Error() 1129 } 1130 1131 return t 1132 }, 1133 }, 1134 { 1135 tag: "isbn", 1136 translation: "{0}必須是一個有效的ISBN編號", 1137 override: false, 1138 }, 1139 { 1140 tag: "isbn10", 1141 translation: "{0}必須是一個有效的ISBN-10編號", 1142 override: false, 1143 }, 1144 { 1145 tag: "isbn13", 1146 translation: "{0}必須是一個有效的ISBN-13編號", 1147 override: false, 1148 }, 1149 { 1150 tag: "uuid", 1151 translation: "{0}必須是一個有效的UUID", 1152 override: false, 1153 }, 1154 { 1155 tag: "uuid3", 1156 translation: "{0}必須是一個有效的V3 UUID", 1157 override: false, 1158 }, 1159 { 1160 tag: "uuid4", 1161 translation: "{0}必須是一個有效的V4 UUID", 1162 override: false, 1163 }, 1164 { 1165 tag: "uuid5", 1166 translation: "{0}必須是一個有效的V5 UUID", 1167 override: false, 1168 }, 1169 { 1170 tag: "ascii", 1171 translation: "{0}必須只包含ascii字元", 1172 override: false, 1173 }, 1174 { 1175 tag: "printascii", 1176 translation: "{0}必須只包含可輸出的ascii字元", 1177 override: false, 1178 }, 1179 { 1180 tag: "multibyte", 1181 translation: "{0}必須包含多個字元", 1182 override: false, 1183 }, 1184 { 1185 tag: "datauri", 1186 translation: "{0}必須包含有效的數據URI", 1187 override: false, 1188 }, 1189 { 1190 tag: "latitude", 1191 translation: "{0}必須包含有效的緯度座標", 1192 override: false, 1193 }, 1194 { 1195 tag: "longitude", 1196 translation: "{0}必須包含有效的經度座標", 1197 override: false, 1198 }, 1199 { 1200 tag: "ssn", 1201 translation: "{0}必須是一個有效的社會安全編號(SSN)", 1202 override: false, 1203 }, 1204 { 1205 tag: "ipv4", 1206 translation: "{0}必須是一個有效的IPv4地址", 1207 override: false, 1208 }, 1209 { 1210 tag: "ipv6", 1211 translation: "{0}必須是一個有效的IPv6地址", 1212 override: false, 1213 }, 1214 { 1215 tag: "ip", 1216 translation: "{0}必須是一個有效的IP地址", 1217 override: false, 1218 }, 1219 { 1220 tag: "cidr", 1221 translation: "{0}必須是一個有效的無類別域間路由(CIDR)", 1222 override: false, 1223 }, 1224 { 1225 tag: "cidrv4", 1226 translation: "{0}必須是一个包含IPv4地址的有效無類別域間路由(CIDR)", 1227 override: false, 1228 }, 1229 { 1230 tag: "cidrv6", 1231 translation: "{0}必須是一个包含IPv6地址的有效無類別域間路由(CIDR)", 1232 override: false, 1233 }, 1234 { 1235 tag: "tcp_addr", 1236 translation: "{0}必須是一個有效的TCP地址", 1237 override: false, 1238 }, 1239 { 1240 tag: "tcp4_addr", 1241 translation: "{0}必須是一個有效的IPv4 TCP地址", 1242 override: false, 1243 }, 1244 { 1245 tag: "tcp6_addr", 1246 translation: "{0}必須是一個有效的IPv6 TCP地址", 1247 override: false, 1248 }, 1249 { 1250 tag: "udp_addr", 1251 translation: "{0}必須是一個有效的UDP地址", 1252 override: false, 1253 }, 1254 { 1255 tag: "udp4_addr", 1256 translation: "{0}必須是一個有效的IPv4 UDP地址", 1257 override: false, 1258 }, 1259 { 1260 tag: "udp6_addr", 1261 translation: "{0}必須是一個有效的IPv6 UDP地址", 1262 override: false, 1263 }, 1264 { 1265 tag: "ip_addr", 1266 translation: "{0}必須是一個有效的IP地址", 1267 override: false, 1268 }, 1269 { 1270 tag: "ip4_addr", 1271 translation: "{0}必須是一個有效的IPv4地址", 1272 override: false, 1273 }, 1274 { 1275 tag: "ip6_addr", 1276 translation: "{0}必須是一個有效的IPv6地址", 1277 override: false, 1278 }, 1279 { 1280 tag: "unix_addr", 1281 translation: "{0}必須是一個有效的UNIX地址", 1282 override: false, 1283 }, 1284 { 1285 tag: "mac", 1286 translation: "{0}必須是一個有效的MAC地址", 1287 override: false, 1288 }, 1289 { 1290 tag: "iscolor", 1291 translation: "{0}必須是一個有效的顏色", 1292 override: false, 1293 }, 1294 { 1295 tag: "oneof", 1296 translation: "{0}必須是[{1}]中的一個", 1297 override: false, 1298 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { 1299 s, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) 1300 if err != nil { 1301 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 1302 return fe.(error).Error() 1303 } 1304 return s 1305 }, 1306 }, 1307 } 1308 1309 for _, t := range translations { 1310 1311 if t.customTransFunc != nil && t.customRegisFunc != nil { 1312 1313 err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc) 1314 1315 } else if t.customTransFunc != nil && t.customRegisFunc == nil { 1316 1317 err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc) 1318 1319 } else if t.customTransFunc == nil && t.customRegisFunc != nil { 1320 1321 err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc) 1322 1323 } else { 1324 err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc) 1325 } 1326 1327 if err != nil { 1328 return 1329 } 1330 } 1331 1332 return 1333} 1334 1335func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc { 1336 1337 return func(ut ut.Translator) (err error) { 1338 1339 if err = ut.Add(tag, translation, override); err != nil { 1340 return 1341 } 1342 1343 return 1344 1345 } 1346 1347} 1348 1349func translateFunc(ut ut.Translator, fe validator.FieldError) string { 1350 1351 t, err := ut.T(fe.Tag(), fe.Field()) 1352 if err != nil { 1353 log.Printf("警告: 翻譯欄位錯誤: %#v", fe) 1354 return fe.(error).Error() 1355 } 1356 1357 return t 1358} 1359