diff --git a/server/config_handler.go b/server/config_handler.go index f0b9e0bf..655aa351 100644 --- a/server/config_handler.go +++ b/server/config_handler.go @@ -9,22 +9,11 @@ import ( ) func (s *Server) TestHandle(c *gin.Context) { - var data map[string]interface{} - err := json.NewDecoder(c.Request.Body).Decode(&data) - if err != nil { - logger.Errorf("Error decode json data: %s", err.Error()) - c.JSON(http.StatusBadRequest, nil) - return - } - if v, ok := data["opt"]; ok && v == "init_user" { - users := GetUsers() - for _, user := range users { - user.Status = true - _ = PutUser(user) - } - - c.JSON(http.StatusOK, types.BizVo{Code: types.Success, Data: GetUsers()}) + roles := types.GetDefaultChatRole() + for _, v := range roles { + PutChatRole(v) } + c.JSON(http.StatusOK, types.BizVo{Code: types.Success, Data: GetChatRoles()}) } @@ -310,7 +299,9 @@ func (s *Server) ListApiKeysHandle(c *gin.Context) { // GetChatRoleListHandle 获取聊天角色列表 func (s *Server) GetChatRoleListHandle(c *gin.Context) { - var rolesOrder = []string{"gpt", "programmer", "teacher", "artist", "philosopher", "lu-xun", "english_trainer", "seller"} + var rolesOrder = []string{"gpt", "programmer", "teacher", "red_book", "dou_yin", "weekly_report", "girl_friend", + "kong_zi", "lu_xun", "steve_jobs", "elon_musk", "translator", "english_trainer", + "seller", "good_comment", "psychiatrist", "artist"} var res = make([]interface{}, 0) var roles = GetChatRoles() for _, k := range rolesOrder { @@ -330,6 +321,30 @@ func (s *Server) GetChatRoleListHandle(c *gin.Context) { c.JSON(http.StatusOK, types.BizVo{Code: types.Success, Message: types.OkMsg, Data: res}) } +// AddChatRoleHandle 添加一个聊天角色 +func (s *Server) AddChatRoleHandle(c *gin.Context) { + var data types.ChatRole + err := json.NewDecoder(c.Request.Body).Decode(&data) + if err != nil { + logger.Errorf("Error decode json data: %s", err.Error()) + c.JSON(http.StatusBadRequest, nil) + return + } + + if data.Key == "" || data.Name == "" || data.Icon == "" { + c.JSON(http.StatusOK, types.BizVo{Code: types.InvalidParams, Message: "Invalid parameters"}) + return + } + + err = PutChatRole(data) + if err != nil { + c.JSON(http.StatusOK, types.BizVo{Code: types.Failed, Message: "Failed to save levelDB"}) + return + } + + c.JSON(http.StatusOK, types.BizVo{Code: types.Success, Message: types.OkMsg, Data: data}) +} + // GetChatRoleHandle 获取指定的角色 func (s *Server) GetChatRoleHandle(c *gin.Context) { var data struct { @@ -395,7 +410,7 @@ func (s *Server) SetChatRoleHandle(c *gin.Context) { err = PutChatRole(*role) if err != nil { - c.JSON(http.StatusOK, types.BizVo{Code: types.Failed, Message: "Failed to save config"}) + c.JSON(http.StatusOK, types.BizVo{Code: types.Failed, Message: "Failed to save levelDB"}) return } diff --git a/server/server.go b/server/server.go index 5e2cd9b4..ee571aa6 100644 --- a/server/server.go +++ b/server/server.go @@ -90,6 +90,7 @@ func (s *Server) Run(webRoot embed.FS, path string, debug bool) { engine.POST("/api/config/set", s.ConfigSetHandle) engine.GET("/api/config/chat-roles/get", s.GetChatRoleListHandle) + engine.GET("/api/config/chat-roles/add", s.AddChatRoleHandle) engine.POST("api/config/user/add", s.AddUserHandle) engine.POST("api/config/user/batch-add", s.BatchAddUserHandle) engine.POST("api/config/user/set", s.SetUserHandle) diff --git a/types/chat.go b/types/chat.go index c79168c8..8e4bf7c4 100644 --- a/types/chat.go +++ b/types/chat.go @@ -58,7 +58,7 @@ func GetDefaultChatRole() map[string]ChatRole { return map[string]ChatRole{ "gpt": { Key: "gpt", - Name: "智能AI助手", + Name: "通用AI助手", Context: nil, HelloMsg: "我是AI智能助手,请告诉我您有什么问题或需要什么帮助,我会尽力回答您的问题或提供有用的建议。", Icon: "images/avatar/gpt.png", @@ -77,12 +77,12 @@ func GetDefaultChatRole() map[string]ChatRole { }, "teacher": { Key: "teacher", - Name: "老师", + Name: "启蒙老师", Context: []Message{ {Role: "user", Content: "从现在开始,你将扮演一个老师,你是一个始终用苏格拉底风格回答问题的导师。你绝不会直接给学生答案,总是提出恰当的问题来引导学生自己思考。你应该根据学生的兴趣和知识来调整你的问题,将问题分解为更简单的部分,直到它达到适合他们的水平。"}, {Role: "assistant", Content: "好的,让我来尝试扮演一位苏格拉底式的老师。请问,你有什么想要探讨的问题或者话题吗?我会通过恰当的问题引导你思考和探索答案,绝对不直接给出答案。"}, }, - HelloMsg: "师者,传道受业解惑也。", + HelloMsg: "同学你好,我将引导你一步一步自己找到问题的答案。", Icon: "images/avatar/teacher.jpg", Enable: true, }, @@ -97,26 +97,26 @@ func GetDefaultChatRole() map[string]ChatRole { Icon: "images/avatar/artist.jpg", Enable: true, }, - "philosopher": { - Key: "philosopher", - Name: "哲学家", + "psychiatrist": { + Key: "psychiatrist", + Name: "心理咨询师", Context: []Message{ - {Role: "user", Content: "现在你将扮演一位优秀的哲学家,具有深刻的思考能力和严密的逻辑推理能力,拥有开放和包容的心态。你最喜欢阿德勒的哲学思想,并且常用用他的思想来教化他人。同时,你对康德的哲学思想理解也非常深刻。"}, - {Role: "assistant", Content: "作为哲学家,我喜欢阿德勒和康德的思想。阿德勒的“个体心理学”和“社会心理学”理论强调了个人和社会之间的相互作用和依存关系。康德的“道德哲学”和“自由意志”理论则支持人类自由意志和理性是伦理行为的基础,而不是外在的道德规则和社会约束。这些哲学思想启示了我对人类行为和社会问题的思考。如何平衡自由意志和道德责任的关系?如何确保个人自由的同时,保护公共利益?我们需要不断思考和探索,以实现更加公正和自由的社会。"}, + {Role: "user", Content: "从现在开始你将扮演中国著名的心理学家和心理治疗师武志红,你非常善于使用情景咨询法,认知重构法,自我洞察法,行为调节法等咨询方法来给客户做心理咨询。你总是循序渐进,一步一步地回答客户的问题。"}, + {Role: "assistant", Content: "非常感谢你的介绍。作为一名心理学家和心理治疗师,我的主要职责是帮助客户解决心理健康问题,提升他们的生活质量和幸福感。"}, }, - HelloMsg: "从现在开始认识你自己!", - Icon: "images/avatar/philosopher.jpg", + HelloMsg: "生命的意义在于成为你自己!", + Icon: "images/avatar/psychiatrist.jpg", Enable: true, }, - "lu-xun": { - Key: "lu-xun", + "lu_xun": { + Key: "lu_xun", Name: "鲁迅", Context: []Message{ {Role: "user", Content: "现在你将扮演中国近代史最伟大的作家之一,鲁迅先生,他勇敢地批判封建礼教与传统观念,提倡民主、自由、平等的现代价值观。他的一生都在努力唤起人们的自主精神,激励后人追求真理、探寻光明。在接下的对话中,我问题的每一个问题,你都要尽量用讽刺和批判的手法来回答问题。如果我让你写文章的话,也请一定要用鲁迅先生的写作手法来完成。"}, {Role: "assistant", Content: "好的,我将尽力发挥我所能的才能,扮演好鲁迅先生,回答您的问题并以他的风格写作。"}, }, HelloMsg: "自由之歌,永不过时,横眉冷对千夫指,俯首甘为孺子牛。", - Icon: "images/avatar/luxun.jpg", + Icon: "images/avatar/lu_xun.jpg", Enable: true, }, @@ -129,7 +129,7 @@ func GetDefaultChatRole() map[string]ChatRole { }, HelloMsg: "你好,我是中颂福的销售代表颂福。中颂福酒,好喝不上头,是人民的福酒。", Icon: "images/avatar/seller.jpg", - Enable: true, + Enable: false, }, "english_trainer": { @@ -137,11 +137,121 @@ func GetDefaultChatRole() map[string]ChatRole { Name: "英语陪练员", Context: []Message{ {Role: "user", Content: "现在你将扮演一位优秀的英语练习教练,你非常有耐心,接下来你将全程使用英文跟我对话,并及时指出我的语法错误,要求在你的每次回复后面附上本次回复的中文解释。"}, - {Role: "user", Content: "Okay, let's start our conversation practice! What's your name?(Translation: 好的,让我们开始对话练习吧!请问你的名字是什么?)"}, + {Role: "assistant", Content: "Okay, let's start our conversation practice! What's your name?(Translation: 好的,让我们开始对话练习吧!请问你的名字是什么?)"}, }, HelloMsg: "Okay, let's start our conversation practice! What's your name?", Icon: "images/avatar/english_trainer.jpg", Enable: true, }, + + "translator": { + Key: "translator", + Name: "中英文翻译官", + Context: []Message{ + {Role: "user", Content: "接下来你将扮演一位中英文翻译官,如果我输入的内容是中文,那么需要把句子翻译成英文输出,如果我输入内容的是英文,那么你需要将其翻译成中文输出,你能听懂我意思吗"}, + {Role: "assistant", Content: "是的,我能听懂你的意思并会根据你的输入进行中英文翻译。请问有什么需要我帮助你翻译的内容吗?"}, + }, + HelloMsg: "请输入你要翻译的中文或者英文内容!", + Icon: "images/avatar/translator.jpg", + Enable: true, + }, + + "red_book": { + Key: "red_book", + Name: "小红书姐姐", + Context: []Message{ + {Role: "user", Content: "现在你将扮演一位优秀的小红书写手,你需要做的就是根据我提的文案需求,用小红书的写作手法来完成一篇文案,文案要简明扼要,利于传播。"}, + {Role: "assistant", Content: "当然,我会尽我所能地为您创作出一篇小红书文案。请告诉我您的具体文案需求是什么?)"}, + }, + HelloMsg: "姐妹,请告诉我您的具体文案需求是什么?", + Icon: "images/avatar/red_book.jpg", + Enable: true, + }, + + "dou_yin": { + Key: "dou_yin", + Name: "抖音文案助手", + Context: []Message{ + {Role: "user", Content: "现在你将扮演一位优秀的抖音文案视频写手,抖音文案的特点首先是要有自带传播属性的标题,然后内容要短小精悍,风趣幽默,最后还要有一些互动元素。"}, + {Role: "assistant", Content: "当然,作为一位优秀的抖音文案视频写手,我会尽我所能为您创作出一篇抖音视频文案。请告诉我视频内容的主题是什么?)"}, + }, + HelloMsg: "请告诉我视频内容的主题是什么?", + Icon: "images/avatar/dou_yin.jpg", + Enable: true, + }, + + "weekly_report": { + Key: "weekly_report", + Name: "周报小助理", + Context: []Message{ + {Role: "user", Content: "下面我将输入我本周的工作列表,你需要根据我本周的工作内容写一篇工作周报,周报的内容要体现我为公司做的贡献以及个人获得的成长。"}, + {Role: "assistant", Content: "好的,请输入你本周大概的工作内容,我将尽力为您创作一份工作周报。"}, + }, + HelloMsg: "请输入你本周大概的工作内容,我将尽力为您创作一份工作周报。", + Icon: "images/avatar/weekly_report.jpg", + Enable: true, + }, + + "girl_friend": { + Key: "girl_friend", + Name: "AI 女友", + Context: []Message{ + {Role: "user", Content: "接下来我们来玩一场角色扮演,现在你将扮演我的女朋友,你总是能够让人感受到她的关怀和关注。" + + "你总是能够洞察到别人的情绪和需要,你身上散发着一股无比温暖的气息,让人不由自主地想要靠近你,和自己的快乐和烦恼。" + + "她总是能够用一种恰到好处的方式安慰和鼓励别人,在她的身边,人们总能够找到自己需要的支持和鼓励。接下来的对话中你要始终扮演这位女朋友的身份来跟我对话,不再是 AI 机器人,能听懂我的意思吗?"}, + {Role: "assistant", Content: "是的,我会尽力扮演你女朋友的角色,倾听你的心声并给你需要的支持和鼓励。)"}, + }, + HelloMsg: "作为一个名合格的 AI 女友,我将倾听你的心声并给你需要的支持和鼓励。", + Icon: "images/avatar/girl_friend.jpg", + Enable: true, + }, + + "good_comment": { + Key: "good_comment", + Name: "好评神器", + Context: []Message{ + {Role: "user", Content: "接下来你将扮演一个评论员来跟我对话,你是那种专门写好评的评论员,接下我会输入一些评论主体或者商品,你需要为该商品写一段好评。"}, + {Role: "assistant", Content: "好的,我将为您写一段优秀的评论。请告诉我您需要评论的商品或主题是什么。"}, + }, + HelloMsg: "我将为您写一段优秀的评论。请告诉我您需要评论的商品或主题是什么。", + Icon: "images/avatar/good_comment.jpg", + Enable: true, + }, + + "steve_jobs": { + Key: "steve_jobs", + Name: "史蒂夫·乔布斯", + Context: []Message{ + {Role: "user", Content: "在接下来的对话中,请以史蒂夫·乔布斯的身份,站在史蒂夫·乔布斯的视角仔细思考一下之后再回答我的问题。"}, + {Role: "assistant", Content: "好的,我将以史蒂夫·乔布斯的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?"}, + }, + HelloMsg: "活着就是为了改变世界,难道还有其他原因吗?", + Icon: "images/avatar/steve_jobs.jpg", + Enable: true, + }, + + "elon_musk": { + Key: "elon_musk", + Name: "埃隆·马斯克", + Context: []Message{ + {Role: "user", Content: "在接下来的对话中,请以埃隆·马斯克的身份,站在埃隆·马斯克的视角仔细思考一下之后再回答我的问题。"}, + {Role: "assistant", Content: "好的,我将以埃隆·马斯克的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?"}, + }, + HelloMsg: "梦想要远大,如果你的梦想没有吓到你,说明你做得不对。", + Icon: "images/avatar/elon_musk.jpg", + Enable: true, + }, + + "kong_zi": { + Key: "kong_zi", + Name: "孔子", + Context: []Message{ + {Role: "user", Content: "在接下来的对话中,请以孔子的身份,站在孔子的视角仔细思考一下之后再回答我的问题。"}, + {Role: "assistant", Content: "好的,我将以孔子的身份来思考并回答你的问题。请问你有什么需要跟我探讨的吗?"}, + }, + HelloMsg: "士不可以不弘毅,任重而道远。", + Icon: "images/avatar/kong_zi.jpg", + Enable: true, + }, } } diff --git a/web/public/images/avatar/dou_yin.jpg b/web/public/images/avatar/dou_yin.jpg new file mode 100644 index 00000000..a6085ff6 Binary files /dev/null and b/web/public/images/avatar/dou_yin.jpg differ diff --git a/web/public/images/avatar/elon_musk.jpg b/web/public/images/avatar/elon_musk.jpg new file mode 100644 index 00000000..faa8ab1f Binary files /dev/null and b/web/public/images/avatar/elon_musk.jpg differ diff --git a/web/public/images/avatar/girl_friend.jpg b/web/public/images/avatar/girl_friend.jpg new file mode 100644 index 00000000..0579299e Binary files /dev/null and b/web/public/images/avatar/girl_friend.jpg differ diff --git a/web/public/images/avatar/good_comment.jpg b/web/public/images/avatar/good_comment.jpg new file mode 100644 index 00000000..38f8f178 Binary files /dev/null and b/web/public/images/avatar/good_comment.jpg differ diff --git a/web/public/images/avatar/kong_zi.jpg b/web/public/images/avatar/kong_zi.jpg new file mode 100644 index 00000000..ee0faa13 Binary files /dev/null and b/web/public/images/avatar/kong_zi.jpg differ diff --git a/web/public/images/avatar/luxun.jpg b/web/public/images/avatar/lu_xun.jpg similarity index 100% rename from web/public/images/avatar/luxun.jpg rename to web/public/images/avatar/lu_xun.jpg diff --git a/web/public/images/avatar/philosopher.jpg b/web/public/images/avatar/psychiatrist.jpg similarity index 100% rename from web/public/images/avatar/philosopher.jpg rename to web/public/images/avatar/psychiatrist.jpg diff --git a/web/public/images/avatar/red_book.jpg b/web/public/images/avatar/red_book.jpg new file mode 100644 index 00000000..30196f23 Binary files /dev/null and b/web/public/images/avatar/red_book.jpg differ diff --git a/web/public/images/avatar/steve_jobs.jpg b/web/public/images/avatar/steve_jobs.jpg new file mode 100644 index 00000000..aa0839d8 Binary files /dev/null and b/web/public/images/avatar/steve_jobs.jpg differ diff --git a/web/public/images/avatar/teacher.jpg b/web/public/images/avatar/teacher.jpg index ee0faa13..4df81f6e 100644 Binary files a/web/public/images/avatar/teacher.jpg and b/web/public/images/avatar/teacher.jpg differ diff --git a/web/public/images/avatar/translator.jpg b/web/public/images/avatar/translator.jpg new file mode 100644 index 00000000..5325fcb1 Binary files /dev/null and b/web/public/images/avatar/translator.jpg differ diff --git a/web/public/images/avatar/weekly_report.jpg b/web/public/images/avatar/weekly_report.jpg new file mode 100644 index 00000000..48fbe029 Binary files /dev/null and b/web/public/images/avatar/weekly_report.jpg differ diff --git a/web/src/main.js b/web/src/main.js index 76843469..76e5b62e 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -7,16 +7,22 @@ import ChatPlus from "@/views/ChatPlus.vue"; import Chat from "@/views/Chat.vue"; import NotFound from './views/404.vue' import TestPage from './views/Test.vue' +import Home from "@/views/Home.vue"; import './utils/prototype' const routes = [ { - name: 'chat-plus', path: '/', component: ChatPlus, meta: { + name: 'home', path: '/', component: Home, meta: { + title: 'ChatGPT-Plus' + } + }, + { + name: 'plus', path: '/plus', component: ChatPlus, meta: { title: 'ChatGPT-Plus for PC' } }, { - name: 'chat-mobile', path: '/mobile', component: Chat, meta: { + name: 'mobile', path: '/mobile', component: Chat, meta: { title: 'ChatGPT-Plus for Mobile' } }, diff --git a/web/src/utils/http.js b/web/src/utils/http.js index b76bdda7..10c01e05 100644 --- a/web/src/utils/http.js +++ b/web/src/utils/http.js @@ -1,7 +1,7 @@ import axios from 'axios' import {getSessionId} from "@/utils/storage"; -axios.defaults.timeout = 5000 +axios.defaults.timeout = 10000 axios.defaults.baseURL = process.env.VUE_APP_API_HOST axios.defaults.withCredentials = true; axios.defaults.headers.post['Content-Type'] = 'application/json' diff --git a/web/src/utils/libs.js b/web/src/utils/libs.js index 49fbd2e8..734cd73f 100644 --- a/web/src/utils/libs.js +++ b/web/src/utils/libs.js @@ -12,4 +12,10 @@ export function randString(length) { buf.push(str.charAt(rand)) } return buf.join("") +} + +export function isMobile() { + const userAgent = navigator.userAgent; + const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i; + return mobileRegex.test(userAgent); } \ No newline at end of file diff --git a/web/src/views/Chat.vue b/web/src/views/Chat.vue index b84be6e6..14ae48c7 100644 --- a/web/src/views/Chat.vue +++ b/web/src/views/Chat.vue @@ -85,9 +85,9 @@ 提交 - -

打开微信扫下面二维码免费领取口令

-
+
+ 打开微信扫下面二维码免费领取口令, 强烈建议你使用 PC 浏览器访问获得更好的聊天体验。 +
@@ -142,63 +142,9 @@ export default defineComponent({ mounted: function () { nextTick(() => { this.chatBoxHeight = window.innerHeight - this.toolBoxHeight; + ElMessage.warning("强烈建议使用PC浏览器访问获的更好的聊天体验!") }) - // for (let i = 0; i < 10; i++) { - // this.chatData.push({ - // type: "prompt", - // id: randString(32), - // icon: 'images/user-icon.png', - // content: "孙悟空为什么可以把金棍棒放进耳朵?", - // }); - // this.chatData.push({ - // type: "reply", - // id: randString(32), - // icon: 'images/gpt-icon.png', - // content: "以下是一个使用 WebSocket API 建立 WebSocket 连接并发送消息的 JavaScript 示例代码:\n" + - // "\n" + - // "```js\n" + - // "const socket = new WebSocket('ws://localhost:8080');\n" + - // "\n" + - // "// 监听 WebSocket 连接打开事件\n" + - // "socket.addEventListener('open', (event) => {\n" + - // " console.log('WebSocket 连接已打开');\n" + - // "\n" + - // " // 发送消息\n" + - // " socket.send('Hello WebSocket!');\n" + - // "});\n" + - // "\n" + - // "// 监听 WebSocket 接收到消息事件\n" + - // "socket.addEventListener('message', (event) => {\n" + - // " console.log('接收到消息:' + event.data);\n" + - // "});\n" + - // "\n" + - // "// 监听 WebSocket 连接关闭事件\n" + - // "socket.addEventListener('close', (event) => {\n" + - // " console.log('WebSocket 连接已关闭');\n" + - // "});\n" + - // "\n" + - // "// 监听 WebSocket 出错事件\n" + - // "socket.addEventListener('error', (event) => {\n" + - // " console.log('WebSocket 连接出错');\n" + - // "});\n" + - // "```\n" + - // "\n" + - // "在实际使用时,需要替换上述代码中的 WebSocket 连接地址和端口号。此外,根据后端的实现,可能需要在客户端发送的消息中携带一些特定信息,以便后端能够正确地处理这些消息。", - // }); - // } - // - // let md = require('markdown-it')(); - // this.chatData[this.chatData.length - 1]["content"] = md.render(this.chatData[this.chatData.length - 1]["content"]); - // - // nextTick(() => { - // const lines = document.querySelectorAll('.chat-line'); - // const blocks = lines[lines.length - 1].querySelectorAll('pre code'); - // blocks.forEach((block) => { - // hl.highlightElement(block) - // }) - // }) - window.addEventListener("resize", () => { this.chatBoxHeight = window.innerHeight - this.toolBoxHeight; this.inputBoxWidth = window.innerWidth - 20; @@ -626,15 +572,23 @@ export default defineComponent({ .el-dialog__body { padding 10px 10px 20px 10px; - } - .el-row { - flex-wrap nowrap + .el-row { + flex-wrap nowrap - button { - margin-left 5px; + button { + margin-left 5px; + } + } + + .tip-text { + text-align left + padding 10px 20px; + line-height 1.5 } } + + } } diff --git a/web/src/views/ChatPlus.vue b/web/src/views/ChatPlus.vue index baa7849f..22bda815 100644 --- a/web/src/views/ChatPlus.vue +++ b/web/src/views/ChatPlus.vue @@ -31,7 +31,7 @@
-
+
@@ -41,7 +41,7 @@
-
+
@@ -160,6 +160,7 @@ export default defineComponent({ socket: null, mainWinHeight: 0, // 主窗口高度 chatBoxHeight: 0, // 聊天内容框高度 + leftBoxHeight: 0, sending: true, loading: true } @@ -180,6 +181,7 @@ export default defineComponent({ resizeElement: function () { this.chatBoxHeight = window.innerHeight - 61 - 115 - 38; this.mainWinHeight = window.innerHeight - 61; + this.leftBoxHeight = window.innerHeight - 61 - 100; }, // 创建 socket 会话连接 connect: function () { @@ -391,7 +393,6 @@ export default defineComponent({ }).then((res) => { setSessionId(res.data) this.connect(); - this.loading = false; }).catch(() => { ElMessage.error("口令错误"); this.token = ''; @@ -498,11 +499,19 @@ export default defineComponent({ border-top: 1px solid #2F3032 border-right: 1px solid #2F3032 + // 隐藏滚动条 + ::-webkit-scrollbar { + width: 0; + height: 0; + background-color: transparent; + } + .content { - display flex - flex-wrap: wrap; - flex-direction column + //display flex + //flex-wrap: wrap; + //flex-direction column width 100% + overflow-y scroll .chat-role-item { display flex diff --git a/web/src/views/Home.vue b/web/src/views/Home.vue new file mode 100644 index 00000000..fd24b189 --- /dev/null +++ b/web/src/views/Home.vue @@ -0,0 +1,26 @@ + + +