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) {