diff --git a/api/handle_tts.go b/api/handle_tts.go new file mode 100644 index 00000000..d14ff03d --- /dev/null +++ b/api/handle_tts.go @@ -0,0 +1,52 @@ +package main + +import ( + "fmt" + "io" + "net/http" + "os" +) + +func handleTTSRequest(w http.ResponseWriter, r *http.Request) { + // Create a new HTTP request with the same method, URL, and body as the original request + targetURL := r.URL + hostEnvVarName := "TTS_HOST" + portEnvVarName := "TTS_PORT" + realHost := fmt.Sprintf("http://%s:%s/api", os.Getenv(hostEnvVarName), os.Getenv(portEnvVarName)) + fullURL := realHost + targetURL.String() + print(fullURL) + proxyReq, err := http.NewRequest(r.Method, fullURL, r.Body) + if err != nil { + http.Error(w, "Error creating proxy request", http.StatusInternalServerError) + return + } + + // Copy the headers from the original request to the proxy request + for name, values := range r.Header { + for _, value := range values { + proxyReq.Header.Add(name, value) + } + } + var customTransport = http.DefaultTransport + + // Send the proxy request using the custom transport + resp, err := customTransport.RoundTrip(proxyReq) + if err != nil { + http.Error(w, "Error sending proxy request", http.StatusInternalServerError) + return + } + defer resp.Body.Close() + + // Copy the headers from the proxy response to the original response + for name, values := range resp.Header { + for _, value := range values { + w.Header().Add(name, value) + } + } + + // Set the status code of the original response to the status code of the proxy response + w.WriteHeader(resp.StatusCode) + + // Copy the body of the proxy response to the original response + io.Copy(w, resp.Body) +} diff --git a/api/main.go b/api/main.go index 45d8009e..4ed69a6f 100644 --- a/api/main.go +++ b/api/main.go @@ -147,7 +147,6 @@ func main() { if err != nil { log.Fatal(err) } - ChatModelHandler := NewChatModelHandler(sqlc_q) ChatModelHandler.Register(router) @@ -211,6 +210,8 @@ func main() { user_model_privilege_handler := NewUserChatModelPrivilegeHandler(sqlc_q) user_model_privilege_handler.Register(router) + router.HandleFunc("/tts", handleTTSRequest) + router.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error { tpl, err1 := route.GetPathTemplate() met, err2 := route.GetMethods() @@ -239,8 +240,10 @@ func main() { http.Redirect(w, r, "/static/", http.StatusMovedPermanently) }) + router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", makeGzipHandler(cacheHandler))) + // fly.io if os.Getenv("FLY_APP_NAME") != "" { router.Use(UpdateLastRequestTime) diff --git a/api/middleware_authenticate.go b/api/middleware_authenticate.go index dd1fd626..066b33de 100644 --- a/api/middleware_authenticate.go +++ b/api/middleware_authenticate.go @@ -96,6 +96,7 @@ func IsAuthorizedMiddleware(handler http.Handler) http.Handler { "/": true, "/login": true, "/signup": true, + "/tts": true, } jwtSigningKey := []byte(jwtSecretAndAud.Secret) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/web/src/locales/zh-CN.json b/web/src/locales/zh-CN.json index 6916d188..008b618c 100644 --- a/web/src/locales/zh-CN.json +++ b/web/src/locales/zh-CN.json @@ -77,7 +77,8 @@ "sessionConfig": "会话设置", "enable_debug": "启用", "disable_debug": "关闭", - "completionsCount": "结果数量: {contextCount}" + "completionsCount": "结果数量: {contextCount}", + "playAudio": "语音" }, "chat_snapshot": { "title": "对话集", diff --git a/web/src/views/chat/components/AudioPlayer/index.vue b/web/src/views/chat/components/AudioPlayer/index.vue new file mode 100644 index 00000000..c0cda715 --- /dev/null +++ b/web/src/views/chat/components/AudioPlayer/index.vue @@ -0,0 +1,57 @@ + + + + + \ No newline at end of file diff --git a/web/src/views/chat/components/Message/index.vue b/web/src/views/chat/components/Message/index.vue index 3ea52af8..0dd34a90 100644 --- a/web/src/views/chat/components/Message/index.vue +++ b/web/src/views/chat/components/Message/index.vue @@ -8,6 +8,7 @@ import { copyText } from '@/utils/format' import { useIconRender } from '@/hooks/useIconRender' import { t } from '@/locales' import { displayLocaleDate } from '@/utils/date' +import AudioPlayer from "../AudioPlayer/index.vue" interface Props { index: number @@ -119,6 +120,7 @@ function handleRegenerate() { + diff --git a/web/src/views/chat/index.vue b/web/src/views/chat/index.vue index 0c4b8fd0..0afe6821 100644 --- a/web/src/views/chat/index.vue +++ b/web/src/views/chat/index.vue @@ -542,6 +542,7 @@ function getDataFromResponseText(responseText: string): string { :is-prompt="item.isPrompt" :is-pin="item.isPin" :loading="item.loading" :pining="pining" :index="index" @regenerate="onRegenerate(index)" @delete="handleDelete(index)" @toggle-pin="handleTogglePin(index)" @after-edit="handleAfterEdit" /> +