feat: update menu icons, add version in site titles
@@ -478,7 +478,7 @@ func (h *ChatHandler) doRequest(ctx context.Context, req types.ApiRequest, platf
 | 
			
		||||
	request = request.WithContext(ctx)
 | 
			
		||||
	request.Header.Set("Content-Type", "application/json")
 | 
			
		||||
	var proxyURL string
 | 
			
		||||
	if apiKey.ProxyURL != "" { // 使用代理
 | 
			
		||||
	if len(apiKey.ProxyURL) > 5 { // 使用代理
 | 
			
		||||
		proxy, _ := url.Parse(apiKey.ProxyURL)
 | 
			
		||||
		client = &http.Client{
 | 
			
		||||
			Transport: &http.Transport{
 | 
			
		||||
 
 | 
			
		||||
@@ -220,7 +220,7 @@ func (h *FunctionHandler) Dall3(c *gin.Context) {
 | 
			
		||||
	var res imgRes
 | 
			
		||||
	var errRes ErrRes
 | 
			
		||||
	var request *req.Request
 | 
			
		||||
	if apiKey.ProxyURL != "" {
 | 
			
		||||
	if len(apiKey.ProxyURL) > 5 {
 | 
			
		||||
		request = req.C().SetProxyURL(apiKey.ProxyURL).R()
 | 
			
		||||
	} else {
 | 
			
		||||
		request = req.C().R()
 | 
			
		||||
 
 | 
			
		||||
@@ -61,7 +61,7 @@ func OpenAIRequest(db *gorm.DB, prompt string) (string, error) {
 | 
			
		||||
	var response apiRes
 | 
			
		||||
	var errRes apiErrRes
 | 
			
		||||
	client := req.C()
 | 
			
		||||
	if apiKey.ProxyURL != "" {
 | 
			
		||||
	if len(apiKey.ProxyURL) > 5 {
 | 
			
		||||
		client.SetProxyURL(apiKey.ApiURL)
 | 
			
		||||
	}
 | 
			
		||||
	r, err := client.R().SetHeader("Content-Type", "application/json").
 | 
			
		||||
 
 | 
			
		||||
@@ -6,3 +6,4 @@ VUE_APP_ADMIN_USER=admin
 | 
			
		||||
VUE_APP_ADMIN_PASS=admin123
 | 
			
		||||
VUE_APP_KEY_PREFIX=ChatPLUS_DEV_
 | 
			
		||||
VUE_APP_TITLE="Geek-AI 创作系统"
 | 
			
		||||
VUE_APP_VERSION=v4.0.2
 | 
			
		||||
 
 | 
			
		||||
@@ -2,3 +2,4 @@ VUE_APP_API_HOST=
 | 
			
		||||
VUE_APP_WS_HOST=
 | 
			
		||||
VUE_APP_KEY_PREFIX=ChatPLUS_
 | 
			
		||||
VUE_APP_TITLE="Geek-AI 创作系统"
 | 
			
		||||
VUE_APP_VERSION=v4.0.2
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 741 B After Width: | Height: | Size: 1.5 KiB  | 
| 
		 Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 1.1 KiB  | 
| 
		 Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 2.6 KiB  | 
| 
		 Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 2.1 KiB  | 
@@ -275,6 +275,13 @@
 | 
			
		||||
  width: 20px;
 | 
			
		||||
  height: 20px;
 | 
			
		||||
}
 | 
			
		||||
.page-mj .inner .task-list-box .task-list-inner .el-row.text-info {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  padding: 10px 0;
 | 
			
		||||
}
 | 
			
		||||
.page-mj .inner .task-list-box .task-list-inner .el-row.text-info .el-tag {
 | 
			
		||||
  margin-right: 10px;
 | 
			
		||||
}
 | 
			
		||||
.page-mj .inner .task-list-box .task-list-inner .submit-btn {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  margin: 20px 0;
 | 
			
		||||
@@ -282,12 +289,6 @@
 | 
			
		||||
.page-mj .inner .task-list-box .task-list-inner .submit-btn .el-button {
 | 
			
		||||
  width: 200px;
 | 
			
		||||
}
 | 
			
		||||
.page-mj .inner .task-list-box .task-list-inner .submit-btn .text-info {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: right;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
}
 | 
			
		||||
.page-mj .inner .task-list-box .task-list-inner .job-list-box .running-job-list .job-item {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  padding: 2px;
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,12 @@
 | 
			
		||||
  padding-top: 5px;
 | 
			
		||||
  padding-bottom: 5px;
 | 
			
		||||
}
 | 
			
		||||
.page-sd .inner .sd-box .sd-params .text-info {
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
}
 | 
			
		||||
.page-sd .inner .sd-box .sd-params .text-info .el-tag {
 | 
			
		||||
  margin-right: 10px;
 | 
			
		||||
}
 | 
			
		||||
.page-sd .inner .sd-box .submit-btn {
 | 
			
		||||
  padding: 10px 15px 0 15px;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
@@ -159,6 +165,13 @@
 | 
			
		||||
  width: 20px;
 | 
			
		||||
  height: 20px;
 | 
			
		||||
}
 | 
			
		||||
.page-sd .inner .task-list-box .task-list-inner .el-row.text-info {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  padding: 10px 0;
 | 
			
		||||
}
 | 
			
		||||
.page-sd .inner .task-list-box .task-list-inner .el-row.text-info .el-tag {
 | 
			
		||||
  margin-right: 10px;
 | 
			
		||||
}
 | 
			
		||||
.page-sd .inner .task-list-box .task-list-inner .submit-btn {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  margin: 20px 0;
 | 
			
		||||
@@ -166,12 +179,6 @@
 | 
			
		||||
.page-sd .inner .task-list-box .task-list-inner .submit-btn .el-button {
 | 
			
		||||
  width: 200px;
 | 
			
		||||
}
 | 
			
		||||
.page-sd .inner .task-list-box .task-list-inner .submit-btn .text-info {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: right;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
}
 | 
			
		||||
.page-sd .inner .task-list-box .task-list-inner .job-list-box .running-job-list .job-item {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  padding: 2px;
 | 
			
		||||
 
 | 
			
		||||
@@ -120,6 +120,10 @@ const removeFile = (file) => {
 | 
			
		||||
 | 
			
		||||
const insertURL = (url) => {
 | 
			
		||||
  show.value = false
 | 
			
		||||
  // 如果是相对路径,处理成绝对路径
 | 
			
		||||
  if (url.indexOf("http") === -1) {
 | 
			
		||||
    url = location.protocol + "//" + location.host + url
 | 
			
		||||
  }
 | 
			
		||||
  emits('selected', url)
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,9 @@
 | 
			
		||||
  <div class="container">
 | 
			
		||||
    <div class="footer">
 | 
			
		||||
      Powered by {{ author }} @
 | 
			
		||||
      <el-link type="primary" href="https://github.com/yangjian102621/chatgpt-plus" target="_blank">{{ title }}
 | 
			
		||||
      <el-link type="primary" href="https://github.com/yangjian102621/chatgpt-plus" target="_blank">
 | 
			
		||||
        {{ title }} -
 | 
			
		||||
        {{ version }}
 | 
			
		||||
      </el-link>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
@@ -12,6 +14,7 @@
 | 
			
		||||
import {ref} from "vue";
 | 
			
		||||
 | 
			
		||||
const title = ref(process.env.VUE_APP_TITLE)
 | 
			
		||||
const version = ref(process.env.VUE_APP_VERSION)
 | 
			
		||||
const author = ref('极客学长')
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="welcome">
 | 
			
		||||
    <div class="container">
 | 
			
		||||
      <h1 class="title">{{ title }}</h1>
 | 
			
		||||
      <h1 class="title">{{ title }}-{{ version }}</h1>
 | 
			
		||||
 | 
			
		||||
      <el-row :gutter="20">
 | 
			
		||||
        <el-col :span="8">
 | 
			
		||||
@@ -60,6 +60,7 @@ import {httpGet} from "@/utils/http";
 | 
			
		||||
import {ElMessage} from "element-plus";
 | 
			
		||||
 | 
			
		||||
const title = ref(process.env.VUE_APP_TITLE)
 | 
			
		||||
const version = ref(process.env.VUE_APP_VERSION)
 | 
			
		||||
 | 
			
		||||
const samples = ref([
 | 
			
		||||
  "用小学生都能听懂的术语解释什么是量子纠缠",
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
  <div class="sidebar">
 | 
			
		||||
    <div class="logo">
 | 
			
		||||
      <el-image :src="logo"/>
 | 
			
		||||
      <span class="text" v-show="!sidebar.collapse">{{ title }}</span>
 | 
			
		||||
      <span class="text" v-show="!sidebar.collapse">{{ title }} - {{ version }}</span>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <el-menu
 | 
			
		||||
@@ -60,6 +60,7 @@ import {ElMessage} from "element-plus";
 | 
			
		||||
 | 
			
		||||
const title = ref('Chat-Plus-Admin')
 | 
			
		||||
const logo = ref('/images/logo.png')
 | 
			
		||||
const version = ref(process.env.VUE_APP_VERSION)
 | 
			
		||||
 | 
			
		||||
// 加载系统配置
 | 
			
		||||
httpGet('/api/admin/config/get?key=system').then(res => {
 | 
			
		||||
 
 | 
			
		||||
@@ -451,6 +451,12 @@ const newChat = () => {
 | 
			
		||||
    showLoginDialog.value = true
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  const role = getRoleById(roleId.value)
 | 
			
		||||
  if (role.key === 'gpt') {
 | 
			
		||||
    showHello.value = true
 | 
			
		||||
  } else {
 | 
			
		||||
    showHello.value = false
 | 
			
		||||
  }
 | 
			
		||||
  // 已有新开的会话
 | 
			
		||||
  if (newChatItem.value !== null && newChatItem.value['role_id'] === roles.value[0]['role_id']) {
 | 
			
		||||
    return;
 | 
			
		||||
 
 | 
			
		||||
@@ -6,9 +6,9 @@
 | 
			
		||||
        <div class="divider"></div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <ul class="nav-items">
 | 
			
		||||
        <li v-for="item in navs" :key="item.path">
 | 
			
		||||
          <a @click="changeNav(item)" :class="item.path === curPath ? 'active' : ''">
 | 
			
		||||
            <el-image :src="item.icon" :width="20"/>
 | 
			
		||||
        <li v-for="item in navs" :key="item.url">
 | 
			
		||||
          <a @click="changeNav(item)" :class="item.url === curPath ? 'active' : ''">
 | 
			
		||||
            <el-image :src="item.icon" style="width: 30px;height: 30px"/>
 | 
			
		||||
          </a>
 | 
			
		||||
          <div :class="item.url === curPath ? 'title active' : 'title'">{{ item.name }}</div>
 | 
			
		||||
        </li>
 | 
			
		||||
@@ -66,7 +66,7 @@ onMounted(() => {
 | 
			
		||||
  .navigator {
 | 
			
		||||
    display flex
 | 
			
		||||
    flex-flow column
 | 
			
		||||
    width 70px
 | 
			
		||||
    width 60px
 | 
			
		||||
    padding 10px 6px
 | 
			
		||||
    border-right: 1px solid #3c3c3c
 | 
			
		||||
    background-color: #25272D
 | 
			
		||||
@@ -76,6 +76,10 @@ onMounted(() => {
 | 
			
		||||
      flex-flow column
 | 
			
		||||
      align-items center
 | 
			
		||||
 | 
			
		||||
      .el-image {
 | 
			
		||||
        width 50px
 | 
			
		||||
        height 50px
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .divider {
 | 
			
		||||
        border-bottom 1px solid #4A4A4A
 | 
			
		||||
@@ -86,15 +90,13 @@ onMounted(() => {
 | 
			
		||||
 | 
			
		||||
    .nav-items {
 | 
			
		||||
      margin-top: 20px;
 | 
			
		||||
      padding-left: 10px;
 | 
			
		||||
      padding-right: 10px;
 | 
			
		||||
      padding 0 5px
 | 
			
		||||
 | 
			
		||||
      li {
 | 
			
		||||
        margin-bottom 15px
 | 
			
		||||
 | 
			
		||||
        a {
 | 
			
		||||
          color #DADBDC
 | 
			
		||||
          background-color #40444A
 | 
			
		||||
          border-radius 10px
 | 
			
		||||
          width 48px
 | 
			
		||||
          height 48px
 | 
			
		||||
@@ -114,6 +116,7 @@ onMounted(() => {
 | 
			
		||||
 | 
			
		||||
        a:hover, a.active {
 | 
			
		||||
          color #47fff1
 | 
			
		||||
          background-color #0F7A71
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .title {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
    <div class="main">
 | 
			
		||||
      <div class="contain">
 | 
			
		||||
        <div class="logo">
 | 
			
		||||
          <el-image src="images/logo.png" fit="cover"/>
 | 
			
		||||
          <el-image :src="logo" fit="cover"/>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="header">{{ title }}</div>
 | 
			
		||||
        <div class="content">
 | 
			
		||||
@@ -54,7 +54,7 @@
 | 
			
		||||
 | 
			
		||||
import {ref} from "vue";
 | 
			
		||||
import {Lock, UserFilled} from "@element-plus/icons-vue";
 | 
			
		||||
import {httpPost} from "@/utils/http";
 | 
			
		||||
import {httpGet, httpPost} from "@/utils/http";
 | 
			
		||||
import {ElMessage} from "element-plus";
 | 
			
		||||
import {useRouter} from "vue-router";
 | 
			
		||||
import FooterBar from "@/components/FooterBar.vue";
 | 
			
		||||
@@ -69,6 +69,15 @@ const title = ref('ChatPlus 用户登录');
 | 
			
		||||
const username = ref(process.env.VUE_APP_USER);
 | 
			
		||||
const password = ref(process.env.VUE_APP_PASS);
 | 
			
		||||
const showResetPass = ref(false)
 | 
			
		||||
const logo = ref("/images/logo.png")
 | 
			
		||||
 | 
			
		||||
// 获取系统配置
 | 
			
		||||
httpGet("/api/config/get?key=system").then(res => {
 | 
			
		||||
  logo.value = res.data.logo
 | 
			
		||||
}).catch(e => {
 | 
			
		||||
  ElMessage.error("获取系统配置失败:" + e.message)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
checkSession().then(() => {
 | 
			
		||||
  if (isMobile()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
      <div class="page-inner">
 | 
			
		||||
        <div class="contain" v-if="enableRegister">
 | 
			
		||||
          <div class="logo">
 | 
			
		||||
            <el-image src="images/logo.png" fit="cover"/>
 | 
			
		||||
            <el-image :src="logo" fit="cover"/>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          <div class="header">{{ title }}</div>
 | 
			
		||||
@@ -141,6 +141,7 @@ const enableRegister = ref(true)
 | 
			
		||||
const wxImg = ref("/images/wx.png")
 | 
			
		||||
const ways = []
 | 
			
		||||
const placeholder = ref("用户名:")
 | 
			
		||||
const logo = ref("/images/logo.png")
 | 
			
		||||
 | 
			
		||||
httpGet("/api/config/get?key=system").then(res => {
 | 
			
		||||
  if (res.data) {
 | 
			
		||||
@@ -160,6 +161,7 @@ httpGet("/api/config/get?key=system").then(res => {
 | 
			
		||||
    if (res.data['wechat_card_url'] !== '') {
 | 
			
		||||
      wxImg.value = res.data['wechat_card_url']
 | 
			
		||||
    }
 | 
			
		||||
    logo.value = res.data.logo
 | 
			
		||||
  }
 | 
			
		||||
}).catch(e => {
 | 
			
		||||
  ElMessage.error("获取系统配置失败:" + e.message)
 | 
			
		||||
 
 | 
			
		||||