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