diff --git a/api/go/handler/user_handler.go b/api/go/handler/user_handler.go index 625d8f46..b6d5208e 100644 --- a/api/go/handler/user_handler.go +++ b/api/go/handler/user_handler.go @@ -318,3 +318,43 @@ func (h *UserHandler) Profile(c *gin.Context) { userVo.UpdatedAt = user.UpdatedAt.Unix() resp.SUCCESS(c, userVo) } + +// Password 更新密码 +func (h *UserHandler) Password(c *gin.Context) { + var data struct { + OldPass string `json:"old_pass"` + Password string `json:"password"` + } + if err := c.ShouldBindJSON(&data); err != nil { + resp.ERROR(c, types.InvalidArgs) + return + } + + if len(data.Password) < 8 { + resp.ERROR(c, "密码长度不能少于8个字符") + return + } + + user, err := utils.GetLoginUser(c, h.db) + if err != nil { + resp.NotAuth(c) + return + } + + password := utils.GenPassword(data.OldPass, user.Salt) + logger.Info(user.Salt, ",", user.Password, ",", password, ",", data.OldPass) + if password != user.Password { + resp.ERROR(c, "原密码错误") + return + } + + newPass := utils.GenPassword(data.Password, user.Salt) + res := h.db.Model(&user).UpdateColumn("password", newPass) + if res.Error != nil { + logger.Error("更新数据库失败: ", res.Error) + resp.ERROR(c, "更新数据库失败") + return + } + + resp.SUCCESS(c) +} diff --git a/api/go/main.go b/api/go/main.go index c0fca3b8..43e849c0 100644 --- a/api/go/main.go +++ b/api/go/main.go @@ -106,6 +106,7 @@ func main() { group.GET("session", h.Session) group.GET("profile", h.Profile) group.POST("profile/update", h.ProfileUpdate) + group.POST("password", h.Password) }), fx.Invoke(func(s *core.AppServer, h *handler.ChatHandler) { group := s.Engine.Group("/api/chat/") diff --git a/web/public/favicon.ico b/web/public/favicon.ico index 9af616ce..32b5cf3e 100644 Binary files a/web/public/favicon.ico and b/web/public/favicon.ico differ diff --git a/web/public/images/logo.png b/web/public/images/logo.png index 8d010414..43e5d544 100644 Binary files a/web/public/images/logo.png and b/web/public/images/logo.png differ diff --git a/web/src/assets/iconfont/iconfont.css b/web/src/assets/iconfont/iconfont.css new file mode 100644 index 00000000..f4eec58e --- /dev/null +++ b/web/src/assets/iconfont/iconfont.css @@ -0,0 +1,31 @@ +@font-face { + font-family: "iconfont"; /* Project id 4125778 */ + src: url('iconfont.woff2?t=1686901862117') format('woff2'), + url('iconfont.woff?t=1686901862117') format('woff'), + url('iconfont.ttf?t=1686901862117') format('truetype'); +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-password:before { + content: "\e62a"; +} + +.icon-send:before { + content: "\e604"; +} + +.icon-logout:before { + content: "\e62e"; +} + +.icon-github:before { + content: "\e66f"; +} + diff --git a/web/src/assets/iconfont/iconfont.js b/web/src/assets/iconfont/iconfont.js new file mode 100644 index 00000000..10e33f86 --- /dev/null +++ b/web/src/assets/iconfont/iconfont.js @@ -0,0 +1 @@ +window._iconfont_svg_string_4125778='',function(n){var t=(t=document.getElementsByTagName("script"))[t.length-1],e=t.getAttribute("data-injectcss"),t=t.getAttribute("data-disable-injectsvg");if(!t){var o,i,c,l,d,a=function(t,e){e.parentNode.insertBefore(t,e)};if(e&&!n.__iconfont__svg__cssinject__){n.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(t){console&&console.log(t)}}o=function(){var t,e=document.createElement("div");e.innerHTML=n._iconfont_svg_string_4125778,(e=e.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",e=e,(t=document.body).firstChild?a(e,t.firstChild):t.appendChild(e))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(o,0):(i=function(){document.removeEventListener("DOMContentLoaded",i,!1),o()},document.addEventListener("DOMContentLoaded",i,!1)):document.attachEvent&&(c=o,l=n.document,d=!1,r(),l.onreadystatechange=function(){"complete"==l.readyState&&(l.onreadystatechange=null,s())})}function s(){d||(d=!0,c())}function r(){try{l.documentElement.doScroll("left")}catch(t){return void setTimeout(r,50)}s()}}(window); \ No newline at end of file diff --git a/web/src/assets/iconfont/iconfont.js:Zone.Identifier b/web/src/assets/iconfont/iconfont.js:Zone.Identifier new file mode 100644 index 00000000..df2640e1 --- /dev/null +++ b/web/src/assets/iconfont/iconfont.js:Zone.Identifier @@ -0,0 +1,4 @@ +[ZoneTransfer] +ZoneId=3 +ReferrerUrl=https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=4125778 +HostUrl=https://www.iconfont.cn/api/project/download.zip?spm=a313x.7781069.1998910419.d7543c303&pid=4125778&ctoken=SHhMU2NkC6BavrZsXJmrL-LS diff --git a/web/src/assets/iconfont/iconfont.json b/web/src/assets/iconfont/iconfont.json new file mode 100644 index 00000000..e3d0c29c --- /dev/null +++ b/web/src/assets/iconfont/iconfont.json @@ -0,0 +1,37 @@ +{ + "id": "4125778", + "name": "chatgpt", + "font_family": "iconfont", + "css_prefix_text": "icon-", + "description": "", + "glyphs": [ + { + "icon_id": "611345", + "name": "密码", + "font_class": "password", + "unicode": "e62a", + "unicode_decimal": 58922 + }, + { + "icon_id": "1418205", + "name": "发送", + "font_class": "send", + "unicode": "e604", + "unicode_decimal": 58884 + }, + { + "icon_id": "1048893", + "name": "注销", + "font_class": "logout", + "unicode": "e62e", + "unicode_decimal": 58926 + }, + { + "icon_id": "14401714", + "name": "github", + "font_class": "github", + "unicode": "e66f", + "unicode_decimal": 58991 + } + ] +} diff --git a/web/src/assets/iconfont/iconfont.ttf b/web/src/assets/iconfont/iconfont.ttf new file mode 100644 index 00000000..6b860991 Binary files /dev/null and b/web/src/assets/iconfont/iconfont.ttf differ diff --git a/web/src/assets/iconfont/iconfont.woff b/web/src/assets/iconfont/iconfont.woff new file mode 100644 index 00000000..9988cbfd Binary files /dev/null and b/web/src/assets/iconfont/iconfont.woff differ diff --git a/web/src/assets/iconfont/iconfont.woff2 b/web/src/assets/iconfont/iconfont.woff2 new file mode 100644 index 00000000..cfd18dab Binary files /dev/null and b/web/src/assets/iconfont/iconfont.woff2 differ diff --git a/web/src/components/PasswordDialog.vue b/web/src/components/PasswordDialog.vue new file mode 100644 index 00000000..be647634 --- /dev/null +++ b/web/src/components/PasswordDialog.vue @@ -0,0 +1,96 @@ + + + + + \ No newline at end of file diff --git a/web/src/views/ChatPlus.vue b/web/src/views/ChatPlus.vue index c53df95a..4d15102b 100644 --- a/web/src/views/ChatPlus.vue +++ b/web/src/views/ChatPlus.vue @@ -55,6 +55,11 @@ 聊天设置 + + + 修改密码 + + @@ -63,18 +68,17 @@ - - - + 注销 - - - - - - + + + + powered by + chatgpt-plus-v3 + + @@ -180,6 +184,7 @@ + @@ -210,6 +215,7 @@ import {httpGet, httpPost} from "@/utils/http"; import {useRouter} from "vue-router"; import Clipboard from "clipboard"; import ConfigDialog from "@/components/ConfigDialog.vue"; +import PasswordDialog from "@/components/PasswordDialog.vue"; const title = ref('ChatGPT-智能助手'); const logo = 'images/logo.png'; @@ -229,6 +235,7 @@ const roleId = ref(0) const newChatItem = ref(null); const router = useRouter(); const showConfigDialog = ref(false); +const showPasswordDialog = ref(false); if (!user.value) { router.push("login"); @@ -712,6 +719,7 @@ const updateUser = function (data) {