mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-19 01:36:38 +08:00
feat: vue-mobile => 完成移动端聊天配置功能
This commit is contained in:
parent
6a733de556
commit
5187a43543
1
api/go/.gitignore
vendored
1
api/go/.gitignore
vendored
@ -16,3 +16,4 @@ tmp
|
|||||||
bin
|
bin
|
||||||
data
|
data
|
||||||
config.toml
|
config.toml
|
||||||
|
static/upload
|
||||||
|
@ -51,6 +51,9 @@ func (s *AppServer) Init(debug bool) {
|
|||||||
s.Engine.Use(authorizeMiddleware(s))
|
s.Engine.Use(authorizeMiddleware(s))
|
||||||
s.Engine.Use(errorHandler)
|
s.Engine.Use(errorHandler)
|
||||||
//gob.Register(model.User{})
|
//gob.Register(model.User{})
|
||||||
|
|
||||||
|
// 添加静态资源访问
|
||||||
|
s.Engine.Static("/static", s.AppConfig.StaticDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AppServer) Run(db *gorm.DB) error {
|
func (s *AppServer) Run(db *gorm.DB) error {
|
||||||
|
@ -18,6 +18,7 @@ func NewDefaultConfig() *types.AppConfig {
|
|||||||
Listen: "0.0.0.0:5678",
|
Listen: "0.0.0.0:5678",
|
||||||
ProxyURL: "",
|
ProxyURL: "",
|
||||||
Manager: types.Manager{Username: "admin", Password: "admin123"},
|
Manager: types.Manager{Username: "admin", Password: "admin123"},
|
||||||
|
StaticDir: "./static",
|
||||||
|
|
||||||
Session: types.Session{
|
Session: types.Session{
|
||||||
SecretKey: utils.RandString(64),
|
SecretKey: utils.RandString(64),
|
||||||
|
@ -11,6 +11,7 @@ type AppConfig struct {
|
|||||||
ProxyURL string
|
ProxyURL string
|
||||||
MysqlDns string // mysql 连接地址
|
MysqlDns string // mysql 连接地址
|
||||||
Manager Manager // 后台管理员账户信息
|
Manager Manager // 后台管理员账户信息
|
||||||
|
StaticDir string // 静态资源目录
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manager 管理员
|
// Manager 管理员
|
||||||
|
@ -289,8 +289,6 @@ func (h *UserHandler) Profile(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
userVo.Id = user.Id
|
userVo.Id = user.Id
|
||||||
userVo.CreatedAt = user.CreatedAt.Unix()
|
|
||||||
userVo.UpdatedAt = user.UpdatedAt.Unix()
|
|
||||||
resp.SUCCESS(c, userVo)
|
resp.SUCCESS(c, userVo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
api/go/static/hello.txt
Normal file
1
api/go/static/hello.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
hello, world!
|
@ -4,16 +4,16 @@ import "chatplus/core/types"
|
|||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
BaseVo
|
BaseVo
|
||||||
Username string `json:"username"`
|
Username string `json:"username,omitempty"`
|
||||||
Nickname string `json:"nickname"`
|
Nickname string `json:"nickname,omitempty"`
|
||||||
Avatar string `json:"avatar"`
|
Avatar string `json:"avatar,omitempty"`
|
||||||
Salt string `json:"salt"` // 密码盐
|
Salt string `json:"salt,omitempty"` // 密码盐
|
||||||
Tokens int64 `json:"tokens"` // 剩余tokens
|
Tokens int64 `json:"tokens,omitempty"` // 剩余tokens
|
||||||
Calls int `json:"calls"` // 剩余对话次数
|
Calls int `json:"calls,omitempty"` // 剩余对话次数
|
||||||
ChatConfig types.ChatConfig `json:"chat_config"` // 聊天配置
|
ChatConfig types.ChatConfig `json:"chat_config,omitempty"` // 聊天配置
|
||||||
ChatRoles []string `json:"chat_roles"` // 聊天角色集合
|
ChatRoles []string `json:"chat_roles,omitempty"` // 聊天角色集合
|
||||||
ExpiredTime int64 `json:"expired_time"` // 账户到期时间
|
ExpiredTime int64 `json:"expired_time,omitempty"` // 账户到期时间
|
||||||
Status bool `json:"status"` // 当前状态
|
Status bool `json:"status,omitempty"` // 当前状态
|
||||||
LastLoginAt int64 `json:"last_login_at"` // 最后登录时间
|
LastLoginAt int64 `json:"last_login_at,omitempty"` // 最后登录时间
|
||||||
LastLoginIp string `json:"last_login_ip"` // 最后登录 IP
|
LastLoginIp string `json:"last_login_ip,omitempty"` // 最后登录 IP
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ onMounted(() => {
|
|||||||
margin-left 5px
|
margin-left 5px
|
||||||
|
|
||||||
.van-image {
|
.van-image {
|
||||||
width 25px
|
width 32px
|
||||||
|
|
||||||
img {
|
img {
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
@ -73,7 +73,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
word-break break-word;
|
word-break break-word;
|
||||||
padding: 6px 10px;
|
padding: 5px 10px;
|
||||||
background-color: #98E165;
|
background-color: #98E165;
|
||||||
color #444444
|
color #444444
|
||||||
font-size: 16px
|
font-size: 16px
|
||||||
|
@ -56,7 +56,7 @@ onMounted(() => {
|
|||||||
margin-right 5px
|
margin-right 5px
|
||||||
|
|
||||||
.van-image {
|
.van-image {
|
||||||
width 25px
|
width 32px
|
||||||
|
|
||||||
img {
|
img {
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
@ -92,7 +92,7 @@ onMounted(() => {
|
|||||||
overflow-x auto
|
overflow-x auto
|
||||||
min-height 20px;
|
min-height 20px;
|
||||||
word-break break-word;
|
word-break break-word;
|
||||||
padding: 6px 10px;
|
padding: 5px 10px;
|
||||||
color #444444
|
color #444444
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
font-size: 16px
|
font-size: 16px
|
||||||
|
@ -25,6 +25,7 @@ import {
|
|||||||
ShareSheet,
|
ShareSheet,
|
||||||
Sticky,
|
Sticky,
|
||||||
SwipeCell,
|
SwipeCell,
|
||||||
|
Switch,
|
||||||
Tabbar,
|
Tabbar,
|
||||||
TabbarItem,
|
TabbarItem,
|
||||||
TextEllipsis
|
TextEllipsis
|
||||||
@ -56,6 +57,7 @@ app.use(Sticky);
|
|||||||
app.use(SwipeCell);
|
app.use(SwipeCell);
|
||||||
app.use(Dialog);
|
app.use(Dialog);
|
||||||
app.use(ShareSheet);
|
app.use(ShareSheet);
|
||||||
|
app.use(Switch);
|
||||||
app.use(router).use(ElementPlus).mount('#app')
|
app.use(router).use(ElementPlus).mount('#app')
|
||||||
|
|
||||||
|
|
||||||
|
@ -227,20 +227,22 @@ const removeChat = (item) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
|
$fontSize = 16px;
|
||||||
.mobile-chat-list {
|
.mobile-chat-list {
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
.van-cell__value {
|
.van-cell__value {
|
||||||
.chat-list-item {
|
.chat-list-item {
|
||||||
display flex
|
display flex
|
||||||
|
font-size $fontSize
|
||||||
|
|
||||||
.van-image {
|
.van-image {
|
||||||
width 30px
|
width 32px
|
||||||
height 30px
|
height 32px
|
||||||
}
|
}
|
||||||
|
|
||||||
.van-ellipsis {
|
.van-ellipsis {
|
||||||
margin-top 4px;
|
margin-top 5px;
|
||||||
margin-left 10px;
|
margin-left 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="mobile-user-profile container">
|
||||||
<van-nav-bar :title="title"/>
|
<van-nav-bar :title="title"/>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<van-form @submit="onSubmit">
|
||||||
|
<van-cell-group inset>
|
||||||
|
<van-field
|
||||||
|
v-model="username"
|
||||||
|
name="用户名"
|
||||||
|
label="用户名"
|
||||||
|
placeholder="用户名"
|
||||||
|
:rules="[{ required: true, message: '请填写用户名' }]"
|
||||||
|
/>
|
||||||
|
<van-field
|
||||||
|
v-model="password"
|
||||||
|
type="password"
|
||||||
|
name="密码"
|
||||||
|
label="密码"
|
||||||
|
placeholder="密码"
|
||||||
|
:rules="[{ required: true, message: '请填写密码' }]"
|
||||||
|
/>
|
||||||
|
</van-cell-group>
|
||||||
|
<div style="margin: 16px;">
|
||||||
|
<van-button round block type="primary" native-type="submit">
|
||||||
|
提交
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</van-form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -1,15 +1,132 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="mobile-setting container">
|
||||||
<van-nav-bar :title="title"/>
|
<van-nav-bar :title="title"/>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<van-form @submit="save" v-model="form">
|
||||||
|
<van-cell-group inset>
|
||||||
|
<van-field
|
||||||
|
v-model="form.chat_config.model"
|
||||||
|
is-link
|
||||||
|
readonly
|
||||||
|
label="默认模型"
|
||||||
|
placeholder=""
|
||||||
|
@click="showPicker = true"
|
||||||
|
/>
|
||||||
|
<van-field
|
||||||
|
v-model.number="form.chat_config.max_tokens"
|
||||||
|
name="MaxTokens"
|
||||||
|
type="number"
|
||||||
|
label="MaxTokens"
|
||||||
|
placeholder="每次请求最大 token 数量"
|
||||||
|
:rules="[{ required: true, message: '请填写 MaxTokens' }]"
|
||||||
|
/>
|
||||||
|
<van-field
|
||||||
|
v-model.number="form.chat_config.temperature"
|
||||||
|
type="number"
|
||||||
|
name="Temperature"
|
||||||
|
label="Temperature"
|
||||||
|
placeholder="模型温度"
|
||||||
|
:rules="[{ required: true, message: '请填写 Temperature' }]"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<van-field name="switch" label="聊天记录">
|
||||||
|
<template #input>
|
||||||
|
<van-switch v-model="form.chat_config.enable_history"/>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
|
||||||
|
<van-field name="switch" label="聊天上下文">
|
||||||
|
<template #input>
|
||||||
|
<van-switch v-model="form.chat_config.enable_context"/>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
<van-field
|
||||||
|
v-model="form.chat_config.api_key"
|
||||||
|
name="API KEY"
|
||||||
|
label="API KEY"
|
||||||
|
placeholder="配置自己的 api key"
|
||||||
|
:rules="[{ required: true, message: '请填写 API KEY' }]"
|
||||||
|
/>
|
||||||
|
</van-cell-group>
|
||||||
|
<div style="margin: 16px;">
|
||||||
|
<van-button round block type="primary" native-type="submit">
|
||||||
|
保存
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</van-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<van-popup v-model:show="showPicker" round position="bottom">
|
||||||
|
<van-picker
|
||||||
|
:columns="models"
|
||||||
|
@cancel="showPicker = false"
|
||||||
|
@confirm="selectModel"
|
||||||
|
/>
|
||||||
|
</van-popup>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {ref} from "vue";
|
import {onMounted, ref} from "vue";
|
||||||
|
import {httpGet, httpPost} from "@/utils/http";
|
||||||
|
import {showFailToast, showSuccessToast} from "vant";
|
||||||
|
import {ElMessage} from "element-plus";
|
||||||
|
|
||||||
const title = ref('聊天设置')
|
const title = ref('聊天设置')
|
||||||
|
const form = ref({
|
||||||
|
chat_config: {
|
||||||
|
model: '',
|
||||||
|
max_tokens: 0,
|
||||||
|
enable_context: false,
|
||||||
|
enable_history: false,
|
||||||
|
temperature: false,
|
||||||
|
api_key: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const showPicker = ref(false)
|
||||||
|
const models = ref([])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 获取最新用户信息
|
||||||
|
httpGet('/api/user/profile').then(res => {
|
||||||
|
console.log(res.data)
|
||||||
|
form.value = res.data
|
||||||
|
}).catch(() => {
|
||||||
|
showFailToast('获取用户信息失败')
|
||||||
|
});
|
||||||
|
|
||||||
|
// 加载系统配置
|
||||||
|
httpGet('/api/admin/config/get?key=system').then(res => {
|
||||||
|
const mds = res.data.models;
|
||||||
|
console.log(mds)
|
||||||
|
mds.forEach(item => {
|
||||||
|
models.value.push({text: item, value: item})
|
||||||
|
})
|
||||||
|
}).catch(e => {
|
||||||
|
ElMessage.error("加载系统配置失败: " + e.message)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const selectModel = (item) => {
|
||||||
|
showPicker.value = false
|
||||||
|
form.value.chat_config.model = item.selectedValues[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
const save = () => {
|
||||||
|
httpPost('/api/user/profile/update', form.value).then(() => {
|
||||||
|
showSuccessToast('保存成功')
|
||||||
|
}).catch(() => {
|
||||||
|
showFailToast('保存失败')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="stylus">
|
||||||
|
.mobile-setting {
|
||||||
|
.content {
|
||||||
|
padding-top 60px
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
Loading…
Reference in New Issue
Block a user