mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-20 02:06:38 +08:00
feat: The 'chat_models' field of user table, holds the model IDS in place of the model values
This commit is contained in:
parent
172d498618
commit
c72d963f45
@ -131,30 +131,30 @@ const XunFei = Platform("XunFei")
|
|||||||
const QWen = Platform("QWen")
|
const QWen = Platform("QWen")
|
||||||
|
|
||||||
type SystemConfig struct {
|
type SystemConfig struct {
|
||||||
Title string `json:"title"`
|
Title string `json:"title,omitempty"`
|
||||||
AdminTitle string `json:"admin_title"`
|
AdminTitle string `json:"admin_title,omitempty"`
|
||||||
Logo string `json:"logo"`
|
Logo string `json:"logo,omitempty"`
|
||||||
InitPower int `json:"init_power"` // 新用户注册赠送算力值
|
InitPower int `json:"init_power,omitempty"` // 新用户注册赠送算力值
|
||||||
DailyPower int `json:"daily_power"` // 每日赠送算力
|
DailyPower int `json:"daily_power,omitempty"` // 每日赠送算力
|
||||||
InvitePower int `json:"invite_power"` // 邀请新用户赠送算力值
|
InvitePower int `json:"invite_power,omitempty"` // 邀请新用户赠送算力值
|
||||||
VipMonthPower int `json:"vip_month_power"` // VIP 会员每月赠送的算力值
|
VipMonthPower int `json:"vip_month_power,omitempty"` // VIP 会员每月赠送的算力值
|
||||||
|
|
||||||
RegisterWays []string `json:"register_ways"` // 注册方式:支持手机,邮箱注册
|
RegisterWays []string `json:"register_ways,omitempty"` // 注册方式:支持手机,邮箱注册
|
||||||
EnabledRegister bool `json:"enabled_register"` // 是否开放注册
|
EnabledRegister bool `json:"enabled_register,omitempty"` // 是否开放注册
|
||||||
|
|
||||||
RewardImg string `json:"reward_img"` // 众筹收款二维码地址
|
RewardImg string `json:"reward_img,omitempty"` // 众筹收款二维码地址
|
||||||
EnabledReward bool `json:"enabled_reward"` // 启用众筹功能
|
EnabledReward bool `json:"enabled_reward,omitempty"` // 启用众筹功能
|
||||||
PowerPrice float64 `json:"power_price"` // 算力单价
|
PowerPrice float64 `json:"power_price,omitempty"` // 算力单价
|
||||||
|
|
||||||
OrderPayTimeout int `json:"order_pay_timeout"` //订单支付超时时间
|
OrderPayTimeout int `json:"order_pay_timeout,omitempty"` //订单支付超时时间
|
||||||
DefaultModels []string `json:"default_models"` // 默认开通的 AI 模型
|
DefaultModels []int `json:"default_models,omitempty"` // 默认开通的 AI 模型
|
||||||
|
|
||||||
MjPower int `json:"mj_power"` // MJ 绘画消耗算力
|
MjPower int `json:"mj_power,omitempty"` // MJ 绘画消耗算力
|
||||||
SdPower int `json:"sd_power"` // SD 绘画消耗算力
|
SdPower int `json:"sd_power,omitempty"` // SD 绘画消耗算力
|
||||||
DallPower int `json:"dall_power"` // DALLE3 绘图消耗算力
|
DallPower int `json:"dall_power,omitempty"` // DALLE3 绘图消耗算力
|
||||||
|
|
||||||
WechatCardURL string `json:"wechat_card_url"` // 微信客服地址
|
WechatCardURL string `json:"wechat_card_url,omitempty"` // 微信客服地址
|
||||||
|
|
||||||
EnableContext bool `json:"enable_context"`
|
EnableContext bool `json:"enable_context,omitempty"`
|
||||||
ContextDeep int `json:"context_deep"`
|
ContextDeep int `json:"context_deep,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -26,18 +26,18 @@ func NewChatModelHandler(app *core.AppServer, db *gorm.DB) *ChatModelHandler {
|
|||||||
|
|
||||||
func (h *ChatModelHandler) Save(c *gin.Context) {
|
func (h *ChatModelHandler) Save(c *gin.Context) {
|
||||||
var data struct {
|
var data struct {
|
||||||
Id uint `json:"id"`
|
Id uint `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
SortNum int `json:"sort_num"`
|
SortNum int `json:"sort_num"`
|
||||||
Open bool `json:"open"`
|
Open bool `json:"open"`
|
||||||
Platform string `json:"platform"`
|
Platform string `json:"platform"`
|
||||||
Power int `json:"power"`
|
Power int `json:"power"`
|
||||||
MaxTokens int `json:"max_tokens"` // 最大响应长度
|
MaxTokens int `json:"max_tokens"` // 最大响应长度
|
||||||
MaxContext int `json:"max_context"` // 最大上下文长度
|
MaxContext int `json:"max_context"` // 最大上下文长度
|
||||||
Temperature string `json:"temperature"` // 模型温度
|
Temperature float32 `json:"temperature"` // 模型温度
|
||||||
CreatedAt int64 `json:"created_at"`
|
CreatedAt int64 `json:"created_at"`
|
||||||
}
|
}
|
||||||
if err := c.ShouldBindJSON(&data); err != nil {
|
if err := c.ShouldBindJSON(&data); err != nil {
|
||||||
resp.ERROR(c, types.InvalidArgs)
|
resp.ERROR(c, types.InvalidArgs)
|
||||||
@ -53,7 +53,7 @@ func (h *ChatModelHandler) Save(c *gin.Context) {
|
|||||||
Open: data.Open,
|
Open: data.Open,
|
||||||
MaxTokens: data.MaxTokens,
|
MaxTokens: data.MaxTokens,
|
||||||
MaxContext: data.MaxContext,
|
MaxContext: data.MaxContext,
|
||||||
Temperature: float32(utils.Str2Float(data.Temperature)),
|
Temperature: data.Temperature,
|
||||||
Power: data.Power}
|
Power: data.Power}
|
||||||
item.Id = data.Id
|
item.Id = data.Id
|
||||||
if item.Id > 0 {
|
if item.Id > 0 {
|
||||||
|
@ -25,8 +25,12 @@ func NewConfigHandler(app *core.AppServer, db *gorm.DB) *ConfigHandler {
|
|||||||
|
|
||||||
func (h *ConfigHandler) Update(c *gin.Context) {
|
func (h *ConfigHandler) Update(c *gin.Context) {
|
||||||
var data struct {
|
var data struct {
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Config map[string]interface{} `json:"config"`
|
Config struct {
|
||||||
|
types.SystemConfig
|
||||||
|
Content string `json:"content,omitempty"`
|
||||||
|
Updated bool `json:"updated,omitempty"`
|
||||||
|
} `json:"config"`
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.ShouldBindJSON(&data); err != nil {
|
if err := c.ShouldBindJSON(&data); err != nil {
|
||||||
|
@ -72,7 +72,7 @@ func (h *UserHandler) Save(c *gin.Context) {
|
|||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
ChatRoles []string `json:"chat_roles"`
|
ChatRoles []string `json:"chat_roles"`
|
||||||
ChatModels []string `json:"chat_models"`
|
ChatModels []int `json:"chat_models"`
|
||||||
ExpiredTime string `json:"expired_time"`
|
ExpiredTime string `json:"expired_time"`
|
||||||
Status bool `json:"status"`
|
Status bool `json:"status"`
|
||||||
Vip bool `json:"vip"`
|
Vip bool `json:"vip"`
|
||||||
|
@ -32,7 +32,7 @@ func (h *ChatModelHandler) List(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var models []string
|
var models []int
|
||||||
err = utils.JsonDecode(user.ChatModels, &models)
|
err = utils.JsonDecode(user.ChatModels, &models)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.ERROR(c, "当前用户没有订阅任何模型")
|
resp.ERROR(c, "当前用户没有订阅任何模型")
|
||||||
@ -41,7 +41,7 @@ func (h *ChatModelHandler) List(c *gin.Context) {
|
|||||||
|
|
||||||
// 查询用户有权限访问的模型以及所有开放的模型
|
// 查询用户有权限访问的模型以及所有开放的模型
|
||||||
res := h.db.Where("enabled = ?", true).Where(
|
res := h.db.Where("enabled = ?", true).Where(
|
||||||
h.db.Where("value IN ?", models).Or("open =?", true),
|
h.db.Where("id IN ?", models).Or("open =?", true),
|
||||||
).Order("sort_num ASC").Find(&items)
|
).Order("sort_num ASC").Find(&items)
|
||||||
if res.Error == nil {
|
if res.Error == nil {
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
|
@ -8,7 +8,7 @@ type User struct {
|
|||||||
Salt string `json:"salt"` // 密码盐
|
Salt string `json:"salt"` // 密码盐
|
||||||
Power int `json:"power"` // 剩余算力
|
Power int `json:"power"` // 剩余算力
|
||||||
ChatRoles []string `json:"chat_roles"` // 聊天角色集合
|
ChatRoles []string `json:"chat_roles"` // 聊天角色集合
|
||||||
ChatModels []string `json:"chat_models"` // AI模型集合
|
ChatModels []int `json:"chat_models"` // AI模型集合
|
||||||
ExpiredTime int64 `json:"expired_time"` // 账户到期时间
|
ExpiredTime int64 `json:"expired_time"` // 账户到期时间
|
||||||
Status bool `json:"status"` // 当前状态
|
Status bool `json:"status"` // 当前状态
|
||||||
LastLoginAt int64 `json:"last_login_at"` // 最后登录时间
|
LastLoginAt int64 `json:"last_login_at"` // 最后登录时间
|
||||||
|
@ -30,7 +30,7 @@ DROP `total_tokens`,
|
|||||||
DROP `img_calls`;
|
DROP `img_calls`;
|
||||||
|
|
||||||
ALTER TABLE `chatgpt_chat_models` CHANGE `weight` `power` TINYINT NOT NULL COMMENT '消耗算力点数';
|
ALTER TABLE `chatgpt_chat_models` CHANGE `weight` `power` TINYINT NOT NULL COMMENT '消耗算力点数';
|
||||||
ALTER TABLE `chatgpt_chat_models` ADD `temperature` FLOAT(3,2) NOT NULL DEFAULT '1' COMMENT '模型创意度' AFTER `power`, ADD `max_tokens` INT(11) NOT NULL DEFAULT '1024' COMMENT '最大响应长度' AFTER `temperature`, ADD `max_context` INT(11) NOT NULL DEFAULT '4096' COMMENT '最大上下文长度' AFTER `max_tokens`;
|
ALTER TABLE `chatgpt_chat_models` ADD `temperature` FLOAT(3,1) NOT NULL DEFAULT '1' COMMENT '模型创意度' AFTER `power`, ADD `max_tokens` INT(11) NOT NULL DEFAULT '1024' COMMENT '最大响应长度' AFTER `temperature`, ADD `max_context` INT(11) NOT NULL DEFAULT '4096' COMMENT '最大上下文长度' AFTER `max_tokens`;
|
||||||
|
|
||||||
CREATE TABLE `chatgpt_plus`.`chatgpt_power_logs` ( `id` INT(11) NOT NULL AUTO_INCREMENT , `user_id` INT(11) NOT NULL COMMENT '用户ID' , `username` VARCHAR(30) NOT NULL COMMENT '用户名' , `type` TINYINT(1) NOT NULL COMMENT '类型(1:充值,2:消费,3:退费)' , `amount` SMALLINT(3) NOT NULL COMMENT '算力花费' , `balance` INT(11) NOT NULL COMMENT '余额' , `model` VARCHAR(30) NOT NULL COMMENT '模型' , `remark` VARCHAR(255) NOT NULL COMMENT '备注' , `created_at` DATETIME NOT NULL COMMENT '创建时间' , PRIMARY KEY (`id`)) ENGINE = InnoDB COMMENT = '用户算力消费日志';
|
CREATE TABLE `chatgpt_plus`.`chatgpt_power_logs` ( `id` INT(11) NOT NULL AUTO_INCREMENT , `user_id` INT(11) NOT NULL COMMENT '用户ID' , `username` VARCHAR(30) NOT NULL COMMENT '用户名' , `type` TINYINT(1) NOT NULL COMMENT '类型(1:充值,2:消费,3:退费)' , `amount` SMALLINT(3) NOT NULL COMMENT '算力花费' , `balance` INT(11) NOT NULL COMMENT '余额' , `model` VARCHAR(30) NOT NULL COMMENT '模型' , `remark` VARCHAR(255) NOT NULL COMMENT '备注' , `created_at` DATETIME NOT NULL COMMENT '创建时间' , PRIMARY KEY (`id`)) ENGINE = InnoDB COMMENT = '用户算力消费日志';
|
||||||
|
|
||||||
|
@ -142,6 +142,7 @@
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
#app .common-layout .el-main .chat-head .chat-config .el-select {
|
#app .common-layout .el-main .chat-head .chat-config .el-select {
|
||||||
|
max-width: 150px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
#app .common-layout .el-main .chat-head .chat-config .role-select {
|
#app .common-layout .el-main .chat-head .chat-config .role-select {
|
||||||
|
@ -181,7 +181,7 @@ $borderColor = #4676d0;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.el-select {
|
.el-select {
|
||||||
//max-width 150px;
|
max-width 150px;
|
||||||
margin-right 10px;
|
margin-right 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,6 +202,7 @@ $borderColor = #4676d0;
|
|||||||
|
|
||||||
.is-circle {
|
.is-circle {
|
||||||
margin-left 5px
|
margin-left 5px
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
margin-right 0
|
margin-right 0
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@
|
|||||||
<el-main v-loading="loading" element-loading-background="rgba(122, 122, 122, 0.3)">
|
<el-main v-loading="loading" element-loading-background="rgba(122, 122, 122, 0.3)">
|
||||||
<div class="chat-head">
|
<div class="chat-head">
|
||||||
<div class="chat-config">
|
<div class="chat-config">
|
||||||
<span class="role-select-label">聊天角色:</span>
|
<!-- <span class="role-select-label">聊天角色:</span>-->
|
||||||
<el-select v-model="roleId" filterable placeholder="角色" class="role-select" @change="newChat">
|
<el-select v-model="roleId" filterable placeholder="角色" class="role-select" @change="newChat">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in roles"
|
v-for="item in roles"
|
||||||
|
@ -266,6 +266,7 @@ const edit = function (row) {
|
|||||||
|
|
||||||
const save = function () {
|
const save = function () {
|
||||||
formRef.value.validate((valid) => {
|
formRef.value.validate((valid) => {
|
||||||
|
item.value.temperature = parseFloat(item.value.temperature)
|
||||||
if (valid) {
|
if (valid) {
|
||||||
showDialog.value = false
|
showDialog.value = false
|
||||||
httpPost('/api/admin/model/save', item.value).then((res) => {
|
httpPost('/api/admin/model/save', item.value).then((res) => {
|
||||||
|
@ -36,7 +36,14 @@
|
|||||||
<el-form-item label="VIP每月赠送算力" prop="vip_month_power">
|
<el-form-item label="VIP每月赠送算力" prop="vip_month_power">
|
||||||
<el-input v-model.number="system['vip_month_power']" placeholder="VIP用户每月赠送算力"/>
|
<el-input v-model.number="system['vip_month_power']" placeholder="VIP用户每月赠送算力"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="每日赠送算力" prop="daily_power">
|
||||||
|
<div class="tip-input-line">
|
||||||
|
<el-input v-model.number="system['daily_power']" placeholder="默认值0"/>
|
||||||
|
<div class="tip">
|
||||||
|
如果设置0表示不赠送,用户享受完免费算力额度之后就不能再发起对话了。如果设置为N,则系统每天将算力值小于N的用户自动补充到N。注意,此功能要配合XXL-JOB启用。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="开放注册" prop="enabled_register">
|
<el-form-item label="开放注册" prop="enabled_register">
|
||||||
<el-switch v-model="system['enabled_register']"/>
|
<el-switch v-model="system['enabled_register']"/>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
@ -144,7 +151,7 @@
|
|||||||
v-for="item in models"
|
v-for="item in models"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
:value="item.value"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
@ -167,12 +174,12 @@
|
|||||||
<el-switch v-model="system['enable_context']"/>
|
<el-switch v-model="system['enable_context']"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="会话上下文深度">
|
<el-form-item label="会话上下文深度">
|
||||||
<div style="width:100%">
|
<div class="tip-input-line">
|
||||||
<el-input-number v-model="system['context_deep']" :min="0" :max="10"/>
|
<el-input-number v-model="system['context_deep']" :min="0" :max="10"/>
|
||||||
</div>
|
<div class="tip">会话上下文深度:在老会话中继续会话,默认加载多少条聊天记录作为上下文。如果设置为
|
||||||
<div class="tip" style="margin-top: 10px; ">会话上下文深度:在老会话中继续会话,默认加载多少条聊天记录作为上下文。如果设置为
|
0
|
||||||
0
|
则不加载聊天记录,仅仅使用当前角色的上下文。该配置参数最好设置需要为偶数,否则将无法兼容百度的 API。
|
||||||
则不加载聊天记录,仅仅使用当前角色的上下文。该配置参数最好设置需要为偶数,否则将无法兼容百度的 API。
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@ -202,17 +209,6 @@ import 'md-editor-v3/lib/style.css';
|
|||||||
|
|
||||||
const activeName = ref('basic')
|
const activeName = ref('basic')
|
||||||
const system = ref({models: []})
|
const system = ref({models: []})
|
||||||
const chat = ref({
|
|
||||||
open_ai: {temperature: 1, max_tokens: 1024},
|
|
||||||
azure: {temperature: 1, max_tokens: 1024},
|
|
||||||
chat_gml: {temperature: 0.95, max_tokens: 1024},
|
|
||||||
baidu: {temperature: 0.95, max_tokens: 1024},
|
|
||||||
xun_fei: {temperature: 0.5, max_tokens: 1024},
|
|
||||||
context_deep: 0,
|
|
||||||
enable_context: true,
|
|
||||||
enable_history: true,
|
|
||||||
dall_api_url: "",
|
|
||||||
})
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const systemFormRef = ref(null)
|
const systemFormRef = ref(null)
|
||||||
const chatFormRef = ref(null)
|
const chatFormRef = ref(null)
|
||||||
@ -226,14 +222,6 @@ onMounted(() => {
|
|||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
ElMessage.error("加载系统配置失败: " + e.message)
|
ElMessage.error("加载系统配置失败: " + e.message)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 加载聊天配置
|
|
||||||
httpGet('/api/admin/config/get?key=chat').then(res => {
|
|
||||||
chat.value = res.data
|
|
||||||
}).catch(e => {
|
|
||||||
ElMessage.error("加载聊天配置失败: " + e.message)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 加载聊天配置
|
// 加载聊天配置
|
||||||
httpGet('/api/admin/config/get?key=notice').then(res => {
|
httpGet('/api/admin/config/get?key=notice').then(res => {
|
||||||
notice.value = res.data['content']
|
notice.value = res.data['content']
|
||||||
@ -361,12 +349,6 @@ const onUploadImg = (files, callback) => {
|
|||||||
padding-left 10px;
|
padding-left 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tip {
|
|
||||||
color #c1c1c1
|
|
||||||
font-size 12px;
|
|
||||||
line-height 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-icon {
|
.el-icon {
|
||||||
font-size 16px
|
font-size 16px
|
||||||
margin-left 10px
|
margin-left 10px
|
||||||
@ -378,6 +360,15 @@ const onUploadImg = (files, callback) => {
|
|||||||
position relative
|
position relative
|
||||||
top 3px
|
top 3px
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tip-input-line {
|
||||||
|
.tip {
|
||||||
|
margin-top 10px
|
||||||
|
color #c1c1c1
|
||||||
|
font-size 12px;
|
||||||
|
line-height 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@
|
|||||||
v-for="item in models"
|
v-for="item in models"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
:value="item.value"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -297,7 +297,6 @@ const saveUser = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleSelectionChange = function (rows) {
|
const handleSelectionChange = function (rows) {
|
||||||
// TODO: 批量删除操作
|
|
||||||
console.log(rows)
|
console.log(rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user