正在显示
10 个修改的文件
包含
288 行增加
和
0 行删除
@@ -7,6 +7,10 @@ | @@ -7,6 +7,10 @@ | ||
7 | @doc "日志查询" | 7 | @doc "日志查询" |
8 | @handler commonGetLog | 8 | @handler commonGetLog |
9 | get /log/:module | 9 | get /log/:module |
10 | + | ||
11 | + @doc "文件服务" | ||
12 | + @handler commonGetFile | ||
13 | + get /file/:module | ||
10 | } | 14 | } |
11 | 15 | ||
12 | // 通用接口 | 16 | // 通用接口 |
@@ -20,6 +24,10 @@ | @@ -20,6 +24,10 @@ | ||
20 | @handler commonSmsCode | 24 | @handler commonSmsCode |
21 | post /common/sms/code (CommonSmsCodeRequest) returns (CommonSmsCodeResposne) | 25 | post /common/sms/code (CommonSmsCodeRequest) returns (CommonSmsCodeResposne) |
22 | 26 | ||
27 | + @doc "短信验证码" | ||
28 | + @handler commonTextToSpeech | ||
29 | + post /common/tts (TextToSpeechRequest) returns (TextToSpeechResponse) | ||
30 | + | ||
23 | @doc "微信二维码" | 31 | @doc "微信二维码" |
24 | @handler miniQrcodeInvite | 32 | @handler miniQrcodeInvite |
25 | post /mini/qrcode (MiniQrCodeRequest) | 33 | post /mini/qrcode (MiniQrCodeRequest) |
@@ -45,3 +53,12 @@ | @@ -45,3 +53,12 @@ | ||
45 | Scene string `json:"scene"` // 参数 | 53 | Scene string `json:"scene"` // 参数 |
46 | } | 54 | } |
47 | ) | 55 | ) |
56 | + | ||
57 | + type( | ||
58 | + TextToSpeechRequest{ | ||
59 | + Text string `json:"text"` // 文本信息 | ||
60 | + } | ||
61 | + TextToSpeechResponse{ | ||
62 | + AudioUrl string `json:"audioUrl"` // 音频文件地址 | ||
63 | + } | ||
64 | + ) |
@@ -41,3 +41,14 @@ Wechat: | @@ -41,3 +41,14 @@ Wechat: | ||
41 | AppID: wxae5b305849343ec8 | 41 | AppID: wxae5b305849343ec8 |
42 | AppSecret: f584adb68f7d784425b60e1ebb2ffd4b | 42 | AppSecret: f584adb68f7d784425b60e1ebb2ffd4b |
43 | QrcodeEnv: trial | 43 | QrcodeEnv: trial |
44 | + | ||
45 | +TTS: | ||
46 | + ReginID: cn-shanghai #ap-southeast-1 | ||
47 | + AccessKeyID: LTAI4Fz1LUBW2fXp6QWaJHRS | ||
48 | + AccessKeySecret: aLZXwK8pgrs10Ws03qcN7NsrSXFVsg | ||
49 | + Domain: nls-meta.cn-shanghai.aliyuncs.com #nlsmeta.cn-shenzhen.aliyuncs.com # | ||
50 | + AppKey: hRAovF4pNBhKJdFG | ||
51 | + Voice: xiaoyun | ||
52 | + Volume: 50 | ||
53 | + SpeechRate: 0 | ||
54 | + PitchRate: 0 |
@@ -18,6 +18,7 @@ type Config struct { | @@ -18,6 +18,7 @@ type Config struct { | ||
18 | DebugSmsCode string `json:",optional,default=999512"` | 18 | DebugSmsCode string `json:",optional,default=999512"` |
19 | LogRequest bool `json:",optional,default=true"` | 19 | LogRequest bool `json:",optional,default=true"` |
20 | ContentSecurityCheck bool `json:",optional,default=false"` | 20 | ContentSecurityCheck bool `json:",optional,default=false"` |
21 | + TTS TTS `json:",optional"` | ||
21 | } | 22 | } |
22 | 23 | ||
23 | type ApiService struct { | 24 | type ApiService struct { |
@@ -25,3 +26,16 @@ type ApiService struct { | @@ -25,3 +26,16 @@ type ApiService struct { | ||
25 | Host string | 26 | Host string |
26 | Timeout time.Duration | 27 | Timeout time.Duration |
27 | } | 28 | } |
29 | + | ||
30 | +// TTS text to speech | ||
31 | +type TTS struct { | ||
32 | + ReginID string | ||
33 | + AccessKeyID string | ||
34 | + AccessKeySecret string | ||
35 | + Domain string | ||
36 | + AppKey string | ||
37 | + Voice string `json:",default=xiaoyun"` //发音人 | ||
38 | + Volume int `json:",default=50"` // 音量,范围是0~100,可选,默认50。 | ||
39 | + SpeechRate int `json:",default=0"` //语速,范围是-500~500,可选,默认是0 | ||
40 | + PitchRate int `json:",default=0"` //语调,范围是-500~500,可选,默认是0 | ||
41 | +} |
1 | +package common | ||
2 | + | ||
3 | +import ( | ||
4 | + "github.com/zeromicro/go-zero/rest/httpx" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc/cmd/bsi/api/internal/svc" | ||
6 | + "net/http" | ||
7 | + "path/filepath" | ||
8 | +) | ||
9 | + | ||
10 | +func CommonGetFileHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | ||
11 | + return func(w http.ResponseWriter, r *http.Request) { | ||
12 | + var req struct { | ||
13 | + Module string `path:"module"` | ||
14 | + } | ||
15 | + if err := httpx.Parse(r, &req); err != nil { | ||
16 | + httpx.ErrorCtx(r.Context(), w, err) | ||
17 | + return | ||
18 | + } | ||
19 | + path := "public" | ||
20 | + handler := http.FileServer(http.Dir(path)) | ||
21 | + r.URL.Path = filepath.Join(req.Module) | ||
22 | + handler.ServeHTTP(w, r) | ||
23 | + } | ||
24 | +} |
1 | +package common | ||
2 | + | ||
3 | +import ( | ||
4 | + "net/http" | ||
5 | + | ||
6 | + "github.com/zeromicro/go-zero/rest/httpx" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc/cmd/bsi/api/internal/logic/common" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc/cmd/bsi/api/internal/svc" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc/cmd/bsi/api/internal/types" | ||
10 | +) | ||
11 | + | ||
12 | +func CommonTextToSpeechHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | ||
13 | + return func(w http.ResponseWriter, r *http.Request) { | ||
14 | + var req types.TextToSpeechRequest | ||
15 | + if err := httpx.Parse(r, &req); err != nil { | ||
16 | + httpx.ErrorCtx(r.Context(), w, err) | ||
17 | + return | ||
18 | + } | ||
19 | + | ||
20 | + l := common.NewCommonTextToSpeechLogic(r.Context(), svcCtx) | ||
21 | + resp, err := l.CommonTextToSpeech(&req) | ||
22 | + if err != nil { | ||
23 | + httpx.ErrorCtx(r.Context(), w, err) | ||
24 | + } else { | ||
25 | + httpx.OkJsonCtx(r.Context(), w, resp) | ||
26 | + } | ||
27 | + } | ||
28 | +} |
@@ -19,6 +19,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -19,6 +19,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
19 | Path: "/log/:module", | 19 | Path: "/log/:module", |
20 | Handler: common.CommonGetLogHandler(serverCtx), | 20 | Handler: common.CommonGetLogHandler(serverCtx), |
21 | }, | 21 | }, |
22 | + { | ||
23 | + Method: http.MethodGet, | ||
24 | + Path: "/file/:module", | ||
25 | + Handler: common.CommonGetFileHandler(serverCtx), | ||
26 | + }, | ||
22 | }, | 27 | }, |
23 | rest.WithPrefix("/v1"), | 28 | rest.WithPrefix("/v1"), |
24 | ) | 29 | ) |
@@ -34,6 +39,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -34,6 +39,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
34 | }, | 39 | }, |
35 | { | 40 | { |
36 | Method: http.MethodPost, | 41 | Method: http.MethodPost, |
42 | + Path: "/common/tts", | ||
43 | + Handler: common.CommonTextToSpeechHandler(serverCtx), | ||
44 | + }, | ||
45 | + { | ||
46 | + Method: http.MethodPost, | ||
37 | Path: "/mini/qrcode", | 47 | Path: "/mini/qrcode", |
38 | Handler: common.MiniQrcodeInviteHandler(serverCtx), | 48 | Handler: common.MiniQrcodeInviteHandler(serverCtx), |
39 | }, | 49 | }, |
1 | +package common | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + | ||
6 | + "github.com/zeromicro/go-zero/core/logx" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc/cmd/bsi/api/internal/svc" | ||
8 | +) | ||
9 | + | ||
10 | +type CommonGetFileLogic struct { | ||
11 | + logx.Logger | ||
12 | + ctx context.Context | ||
13 | + svcCtx *svc.ServiceContext | ||
14 | +} | ||
15 | + | ||
16 | +func NewCommonGetFileLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CommonGetFileLogic { | ||
17 | + return &CommonGetFileLogic{ | ||
18 | + Logger: logx.WithContext(ctx), | ||
19 | + ctx: ctx, | ||
20 | + svcCtx: svcCtx, | ||
21 | + } | ||
22 | +} | ||
23 | + | ||
24 | +func (l *CommonGetFileLogic) CommonGetFile() error { | ||
25 | + // todo: add your logic here and delete this line | ||
26 | + | ||
27 | + return nil | ||
28 | +} |
1 | +package common | ||
2 | + | ||
3 | +import ( | ||
4 | + "bytes" | ||
5 | + "context" | ||
6 | + "encoding/json" | ||
7 | + "fmt" | ||
8 | + "github.com/aliyun/alibaba-cloud-sdk-go/sdk" | ||
9 | + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" | ||
10 | + nls "github.com/aliyun/alibabacloud-nls-go-sdk" | ||
11 | + "github.com/google/uuid" | ||
12 | + "github.com/zeromicro/go-zero/core/logx" | ||
13 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc/cmd/bsi/api/internal/svc" | ||
14 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc/cmd/bsi/api/internal/types" | ||
15 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc/pkg/xerr" | ||
16 | + "io/ioutil" | ||
17 | + "net/http" | ||
18 | + "os" | ||
19 | + "path" | ||
20 | + "strconv" | ||
21 | +) | ||
22 | + | ||
23 | +type CommonTextToSpeechLogic struct { | ||
24 | + logx.Logger | ||
25 | + ctx context.Context | ||
26 | + svcCtx *svc.ServiceContext | ||
27 | +} | ||
28 | + | ||
29 | +func NewCommonTextToSpeechLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CommonTextToSpeechLogic { | ||
30 | + return &CommonTextToSpeechLogic{ | ||
31 | + Logger: logx.WithContext(ctx), | ||
32 | + ctx: ctx, | ||
33 | + svcCtx: svcCtx, | ||
34 | + } | ||
35 | +} | ||
36 | + | ||
37 | +func (l *CommonTextToSpeechLogic) CommonTextToSpeech(req *types.TextToSpeechRequest) (resp *types.TextToSpeechResponse, err error) { | ||
38 | + token, err := l.getToken1() | ||
39 | + if err != nil { | ||
40 | + return nil, xerr.NewErrMsgErr("授权失败", err) | ||
41 | + } | ||
42 | + id, _ := uuid.NewUUID() | ||
43 | + file := fmt.Sprintf("%s.wav", id.String()) | ||
44 | + filename := path.Join("public", file) | ||
45 | + if err = l.processPOSTRequest(token, req.Text, filename, "wav", 16000); err != nil { | ||
46 | + return nil, xerr.NewErrMsgErr("TTS转换失败", err) | ||
47 | + } | ||
48 | + url := path.Join("file", file) | ||
49 | + resp = &types.TextToSpeechResponse{ | ||
50 | + AudioUrl: url, | ||
51 | + } | ||
52 | + return | ||
53 | +} | ||
54 | + | ||
55 | +func (l *CommonTextToSpeechLogic) getToken() (string, error) { | ||
56 | + client, err := sdk.NewClientWithAccessKey(l.svcCtx.Config.TTS.ReginID, l.svcCtx.Config.TTS.AccessKeyID, l.svcCtx.Config.TTS.AccessKeySecret) | ||
57 | + if err != nil { | ||
58 | + return "", xerr.NewErrMsgErr("授权失败", err) | ||
59 | + } | ||
60 | + request := requests.NewCommonRequest() | ||
61 | + request.Method = "POST" | ||
62 | + request.Domain = l.svcCtx.Config.TTS.Domain //"nlsmeta.ap-southeast-1.aliyuncs.com" | ||
63 | + request.ApiName = "CreateToken" | ||
64 | + request.Version = "2019-02-28" | ||
65 | + response, err := client.ProcessCommonRequest(request) | ||
66 | + | ||
67 | + if err != nil { | ||
68 | + return "", xerr.NewErrMsgErr("授权失败", err) | ||
69 | + } | ||
70 | + token := response.GetHttpContentString() | ||
71 | + return token, nil | ||
72 | +} | ||
73 | + | ||
74 | +func (l *CommonTextToSpeechLogic) getToken1() (string, error) { | ||
75 | + tts := l.svcCtx.Config.TTS | ||
76 | + client, err := nls.GetToken(tts.ReginID, tts.Domain, tts.AccessKeyID, tts.AccessKeySecret, "2019-02-28") | ||
77 | + if err != nil { | ||
78 | + return "", xerr.NewErrMsgErr("授权失败", err) | ||
79 | + } | ||
80 | + token := client.TokenResult.Id | ||
81 | + return token, nil | ||
82 | +} | ||
83 | + | ||
84 | +func (l *CommonTextToSpeechLogic) processPOSTRequest(token string, text string, audioSaveFile string, format string, sampleRate int) error { | ||
85 | + /** | ||
86 | + * 设置HTTPS POST请求: | ||
87 | + * 1.使用HTTPS协议 | ||
88 | + * 2.语音合成服务域名:nls-gateway-ap-southeast-1.aliyuncs.com | ||
89 | + * 3.语音合成接口请求路径:/stream/v1/tts | ||
90 | + * 4.设置必须请求参数:appkey、token、text、format、sample_rate | ||
91 | + * 5.设置可选请求参数:voice、volume、speech_rate、pitch_rate | ||
92 | + */ | ||
93 | + ttsConfig := l.svcCtx.Config.TTS | ||
94 | + var url string = fmt.Sprintf("https://%s/stream/v1/tts", "nls-gateway-ap-southeast-1.aliyuncs.com") | ||
95 | + bodyContent := make(map[string]interface{}) | ||
96 | + bodyContent["appkey"] = ttsConfig.AppKey | ||
97 | + bodyContent["text"] = text | ||
98 | + bodyContent["token"] = token | ||
99 | + bodyContent["format"] = format | ||
100 | + bodyContent["sample_rate"] = sampleRate | ||
101 | + // voice 发音人,可选,默认是xiaoyun。 | ||
102 | + bodyContent["voice"] = ttsConfig.Voice | ||
103 | + // volume 音量,范围是0~100,可选,默认50。 | ||
104 | + bodyContent["volume"] = ttsConfig.Volume | ||
105 | + // speech_rate 语速,范围是-500~500,可选,默认是0。 | ||
106 | + bodyContent["speech_rate"] = ttsConfig.SpeechRate | ||
107 | + // pitch_rate 语调,范围是-500~500,可选,默认是0。 | ||
108 | + bodyContent["pitch_rate"] = ttsConfig.PitchRate | ||
109 | + bodyJson, err := json.Marshal(bodyContent) | ||
110 | + if err != nil { | ||
111 | + panic(nil) | ||
112 | + } | ||
113 | + fmt.Println(string(bodyJson)) | ||
114 | + /** | ||
115 | + * 发送HTTPS POST请求,处理服务端的响应。 | ||
116 | + */ | ||
117 | + response, err := http.Post(url, "application/json;charset=utf-8", bytes.NewBuffer([]byte(bodyJson))) | ||
118 | + if err != nil { | ||
119 | + return err | ||
120 | + } | ||
121 | + defer response.Body.Close() | ||
122 | + contentType := response.Header.Get("Content-Type") | ||
123 | + body, _ := ioutil.ReadAll(response.Body) | ||
124 | + var file *os.File | ||
125 | + if "audio/mpeg" == contentType { | ||
126 | + file, err = os.Create(audioSaveFile) | ||
127 | + if err != nil { | ||
128 | + return err | ||
129 | + } | ||
130 | + defer file.Close() | ||
131 | + file.Write([]byte(body)) | ||
132 | + //fmt.Println("The POST request succeed!") | ||
133 | + } else { | ||
134 | + // ContentType 为 null 或者为 "application/json" | ||
135 | + statusCode := response.StatusCode | ||
136 | + fmt.Println("The HTTP statusCode: " + strconv.Itoa(statusCode)) | ||
137 | + fmt.Println("The POST request failed: " + string(body)) | ||
138 | + return xerr.NewErrMsgErr("The POST request failed: "+string(body), nil) | ||
139 | + } | ||
140 | + return nil | ||
141 | +} |
@@ -13,6 +13,14 @@ type MiniQrCodeRequest struct { | @@ -13,6 +13,14 @@ type MiniQrCodeRequest struct { | ||
13 | Scene string `json:"scene"` // 参数 | 13 | Scene string `json:"scene"` // 参数 |
14 | } | 14 | } |
15 | 15 | ||
16 | +type TextToSpeechRequest struct { | ||
17 | + Text string `json:"text"` // 文本信息 | ||
18 | +} | ||
19 | + | ||
20 | +type TextToSpeechResponse struct { | ||
21 | + AudioUrl string `json:"audioUrl"` // 音频文件地址 | ||
22 | +} | ||
23 | + | ||
16 | type ActivityOpenRequest struct { | 24 | type ActivityOpenRequest struct { |
17 | Id int64 `json:"id"` // 唯一标识 | 25 | Id int64 `json:"id"` // 唯一标识 |
18 | } | 26 | } |
@@ -20,6 +20,8 @@ require ( | @@ -20,6 +20,8 @@ require ( | ||
20 | 20 | ||
21 | require ( | 21 | require ( |
22 | github.com/Shopify/sarama v1.37.2 // indirect | 22 | github.com/Shopify/sarama v1.37.2 // indirect |
23 | + github.com/aliyun/alibaba-cloud-sdk-go v1.62.708 // indirect | ||
24 | + github.com/aliyun/alibabacloud-nls-go-sdk v1.1.1 // indirect | ||
23 | github.com/beego/beego/v2 v2.0.1 // indirect | 25 | github.com/beego/beego/v2 v2.0.1 // indirect |
24 | github.com/beorn7/perks v1.0.1 // indirect | 26 | github.com/beorn7/perks v1.0.1 // indirect |
25 | github.com/cenkalti/backoff/v4 v4.2.0 // indirect | 27 | github.com/cenkalti/backoff/v4 v4.2.0 // indirect |
@@ -46,6 +48,7 @@ require ( | @@ -46,6 +48,7 @@ require ( | ||
46 | github.com/golang/protobuf v1.5.3 // indirect | 48 | github.com/golang/protobuf v1.5.3 // indirect |
47 | github.com/golang/snappy v0.0.4 // indirect | 49 | github.com/golang/snappy v0.0.4 // indirect |
48 | github.com/google/uuid v1.3.0 // indirect | 50 | github.com/google/uuid v1.3.0 // indirect |
51 | + github.com/gorilla/websocket v1.4.2 // indirect | ||
49 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 // indirect | 52 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 // indirect |
50 | github.com/hashicorp/errwrap v1.1.0 // indirect | 53 | github.com/hashicorp/errwrap v1.1.0 // indirect |
51 | github.com/hashicorp/go-multierror v1.1.1 // indirect | 54 | github.com/hashicorp/go-multierror v1.1.1 // indirect |
@@ -60,6 +63,7 @@ require ( | @@ -60,6 +63,7 @@ require ( | ||
60 | github.com/jcmturner/gokrb5/v8 v8.4.3 // indirect | 63 | github.com/jcmturner/gokrb5/v8 v8.4.3 // indirect |
61 | github.com/jcmturner/rpc/v2 v2.0.3 // indirect | 64 | github.com/jcmturner/rpc/v2 v2.0.3 // indirect |
62 | github.com/jinzhu/inflection v1.0.0 // indirect | 65 | github.com/jinzhu/inflection v1.0.0 // indirect |
66 | + github.com/jmespath/go-jmespath v0.4.0 // indirect | ||
63 | github.com/json-iterator/go v1.1.12 // indirect | 67 | github.com/json-iterator/go v1.1.12 // indirect |
64 | github.com/klauspost/compress v1.15.15 // indirect | 68 | github.com/klauspost/compress v1.15.15 // indirect |
65 | github.com/leodido/go-urn v1.1.0 // indirect | 69 | github.com/leodido/go-urn v1.1.0 // indirect |
@@ -72,6 +76,7 @@ require ( | @@ -72,6 +76,7 @@ require ( | ||
72 | github.com/modern-go/reflect2 v1.0.2 // indirect | 76 | github.com/modern-go/reflect2 v1.0.2 // indirect |
73 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect | 77 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect |
74 | github.com/onsi/gomega v1.26.0 // indirect | 78 | github.com/onsi/gomega v1.26.0 // indirect |
79 | + github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect | ||
75 | github.com/openzipkin/zipkin-go v0.4.1 // indirect | 80 | github.com/openzipkin/zipkin-go v0.4.1 // indirect |
76 | github.com/pelletier/go-toml v1.8.1 // indirect | 81 | github.com/pelletier/go-toml v1.8.1 // indirect |
77 | github.com/pelletier/go-toml/v2 v2.0.9 // indirect | 82 | github.com/pelletier/go-toml/v2 v2.0.9 // indirect |
@@ -85,6 +90,7 @@ require ( | @@ -85,6 +90,7 @@ require ( | ||
85 | github.com/richardlehane/mscfb v1.0.4 // indirect | 90 | github.com/richardlehane/mscfb v1.0.4 // indirect |
86 | github.com/richardlehane/msoleps v1.0.1 // indirect | 91 | github.com/richardlehane/msoleps v1.0.1 // indirect |
87 | github.com/samber/lo v1.39.0 // indirect | 92 | github.com/samber/lo v1.39.0 // indirect |
93 | + github.com/satori/go.uuid v1.2.0 // indirect | ||
88 | github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect | 94 | github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect |
89 | github.com/spaolacci/murmur3 v1.1.0 // indirect | 95 | github.com/spaolacci/murmur3 v1.1.0 // indirect |
90 | github.com/spf13/afero v1.2.2 // indirect | 96 | github.com/spf13/afero v1.2.2 // indirect |
@@ -119,6 +125,7 @@ require ( | @@ -119,6 +125,7 @@ require ( | ||
119 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect | 125 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect |
120 | google.golang.org/protobuf v1.31.0 // indirect | 126 | google.golang.org/protobuf v1.31.0 // indirect |
121 | gopkg.in/go-playground/validator.v9 v9.29.1 // indirect | 127 | gopkg.in/go-playground/validator.v9 v9.29.1 // indirect |
128 | + gopkg.in/ini.v1 v1.67.0 // indirect | ||
122 | gopkg.in/yaml.v2 v2.4.0 // indirect | 129 | gopkg.in/yaml.v2 v2.4.0 // indirect |
123 | gopkg.in/yaml.v3 v3.0.1 // indirect | 130 | gopkg.in/yaml.v3 v3.0.1 // indirect |
124 | ) | 131 | ) |
-
请 注册 或 登录 后发表评论