diff --git a/CHANGELOG.md b/CHANGELOG.md index 3437735f..f916b18b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,9 @@ * 功能优化:恢复关闭注册系统配置项,管理员可以在后台关闭用户注册,只允许内部添加账号 * 功能优化:兼用旧版本微信收款消息解析 * 功能优化:优化订单扫码支付状态轮询功能,当关闭二维码时取消轮询,节约网络资源 -* +* 功能新增:后台新增配置微信客服二维码,可以上传自己的微信客服二维码 +* 功能新增:新增网站公告,可以在管理后台自定义配置 +* 功能新增:新增阿里通义千问大模型支持 ## v3.2.5 diff --git a/api/core/types/config.go b/api/core/types/config.go index dd2c3484..bd248db9 100644 --- a/api/core/types/config.go +++ b/api/core/types/config.go @@ -195,5 +195,6 @@ type SystemConfig struct { InviteChatCalls int `json:"invite_chat_calls"` // 邀请用户注册奖励对话次数 InviteImgCalls int `json:"invite_img_calls"` // 邀请用户注册奖励绘图次数 - ShowDemoNotice bool `json:"show_demo_notice"` // 显示演示站公告 + ShowDemoNotice bool `json:"show_demo_notice"` // 显示演示站公告 + WechatCardURL string `json:"wechat_card_url"` // 微信客服地址 } diff --git a/api/handler/chatimpl/chat_handler.go b/api/handler/chatimpl/chat_handler.go index 53dc543d..0b19b238 100644 --- a/api/handler/chatimpl/chat_handler.go +++ b/api/handler/chatimpl/chat_handler.go @@ -26,7 +26,8 @@ import ( ) const ErrorMsg = "抱歉,AI 助手开小差了,请稍后再试。" -const ErrImg = "![](/images/wx.png)" + +var ErrImg = "![](/images/wx.png)" var logger = logger2.GetLogger() @@ -45,6 +46,13 @@ func NewChatHandler(app *core.AppServer, db *gorm.DB, redis *redis.Client) *Chat return &h } +func (h *ChatHandler) Init() { + // 如果后台有上传微信客服微信二维码,则覆盖 + if h.App.SysConfig.WechatCardURL != "" { + ErrImg = fmt.Sprintf("![](%s)", h.App.SysConfig.WechatCardURL) + } +} + var chatConfig types.ChatConfig // ChatHandle 处理聊天 WebSocket 请求 diff --git a/api/main.go b/api/main.go index 514d3e19..8a0708ff 100644 --- a/api/main.go +++ b/api/main.go @@ -59,11 +59,13 @@ func main() { } debug, _ := strconv.ParseBool(os.Getenv("APP_DEBUG")) logger.Info("Loading config file: ", configFile) - defer func() { - if err := recover(); err != nil { - logger.Error("Panic Error:", err) - } - }() + if !debug { + defer func() { + if err := recover(); err != nil { + logger.Error("Panic Error:", err) + } + }() + } app := fx.New( // 初始化配置应用配置 @@ -378,7 +380,9 @@ func main() { log.Fatal(err) } }), - + fx.Invoke(func(h *chatimpl.ChatHandler) { + h.Init() + }), // 注册生命周期回调函数 fx.Invoke(func(lifecycle fx.Lifecycle, lc *AppLifecycle) { lifecycle.Append(fx.Hook{ diff --git a/web/src/views/ChatPlus.vue b/web/src/views/ChatPlus.vue index bc1c268e..0cfab75b 100644 --- a/web/src/views/ChatPlus.vue +++ b/web/src/views/ChatPlus.vue @@ -222,7 +222,7 @@
- +
@@ -325,6 +325,7 @@ const textInput = ref(null) const showFeedbackDialog = ref(false) const showDemoNotice = ref(false) const showNoticeKey = ref("SHOW_DEMO_NOTICE_") +const wechatCardURL = ref("/images/wx.png") if (isMobile()) { router.replace("/mobile") @@ -377,6 +378,7 @@ onMounted(() => { if (!show) { showDemoNotice.value = res.data['show_demo_notice'] } + wechatCardURL.value = res.data['wechat_card_url'] }).catch(e => { ElMessage.error("获取系统配置失败:" + e.message) }) diff --git a/web/src/views/Register.vue b/web/src/views/Register.vue index 65e81a0f..00742286 100644 --- a/web/src/views/Register.vue +++ b/web/src/views/Register.vue @@ -156,6 +156,10 @@ httpGet("/api/admin/config/get?key=system").then(res => { placeholder.value += ways.join("/") // 是否启用注册 enableRegister.value = res.data['enabled_register'] + // 覆盖微信二维码 + if (res.data['wechat_card_url'] !== '') { + wxImg.value = res.data['wechat_card_url'] + } } }).catch(e => { ElMessage.error("获取系统配置失败:" + e.message) diff --git a/web/src/views/admin/SysConfig.vue b/web/src/views/admin/SysConfig.vue index 90a5c705..9449cad0 100644 --- a/web/src/views/admin/SysConfig.vue +++ b/web/src/views/admin/SysConfig.vue @@ -1,113 +1,40 @@ @@ -244,7 +272,10 @@ import {httpGet, httpPost} from "@/utils/http"; import Compressor from "compressorjs"; import {ElMessage} from "element-plus"; import {InfoFilled, UploadFilled} from "@element-plus/icons-vue"; +import MdEditor from "md-editor-v3"; +import 'md-editor-v3/lib/style.css'; +const activeName = ref('basic') const system = ref({models: []}) const chat = ref({ open_ai: {temperature: 1, max_tokens: 1024}, @@ -261,6 +292,7 @@ const loading = ref(true) const systemFormRef = ref(null) const chatFormRef = ref(null) const models = ref([]) +const notice = ref("") onMounted(() => { // 加载系统配置 @@ -321,8 +353,13 @@ const save = function (key) { } } +const configKey = ref("") +const beforeUpload = (key) => { + configKey.value = key +} + // 图片上传 -const uploadRewardImg = (file) => { +const uploadImg = (file) => { // 压缩图片并上传 new Compressor(file.file, { quality: 0.6, @@ -331,17 +368,20 @@ const uploadRewardImg = (file) => { formData.append('file', result, result.name); // 执行上传操作 httpPost('/api/upload', formData).then((res) => { - system.value['reward_img'] = res.data.url + system.value[configKey.value] = res.data.url ElMessage.success('上传成功') }).catch((e) => { ElMessage.error('上传失败:' + e.message) }) }, - error(err) { - console.log(err.message); + error(e) { + ElMessage.error('上传失败:' + e.message) }, }); }; +const onUploadImg = (files) => { + console.log(files); +}; @@ -351,41 +391,46 @@ const uploadRewardImg = (file) => { display flex justify-content center - .container { + .el-tabs { width 100% - max-width 800px; + background-color #ffffff + padding 10px 20px 40px 20px + border: 1px solid #ddd; + border-radius: 5px - .el-form { - .el-form-item__content { + .container { + .el-form { + .el-form-item__content { - .tip-text { - padding-left 10px; + .tip-text { + padding-left 10px; + } + + .tip { + color #c1c1c1 + font-size 12px; + line-height 1.5; + } + + .el-icon { + font-size 16px + margin-left 10px + cursor pointer + } + + .uploader-icon { + font-size 24px + position relative + top 3px + } } + } - .tip { - color #c1c1c1 - font-size 12px; - line-height 1.5; - } - - .el-icon { - font-size 16px - margin-left 10px - cursor pointer - } - - .uploader-icon { - font-size 24px - position relative - top 3px - } + .el-alert { + margin-bottom 15px; } } - .el-alert { - margin-bottom 15px; - } } - } \ No newline at end of file