mirror of
				https://github.com/yangjian102621/geekai.git
				synced 2025-11-04 08:13:43 +08:00 
			
		
		
		
	fix: markmap do not cost power in front page
This commit is contained in:
		@@ -15,6 +15,7 @@ import (
 | 
			
		||||
	"geekai/store/vo"
 | 
			
		||||
	"geekai/utils"
 | 
			
		||||
	"geekai/utils/resp"
 | 
			
		||||
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ import (
 | 
			
		||||
	"geekai/store/model"
 | 
			
		||||
	"geekai/utils"
 | 
			
		||||
	"geekai/utils/resp"
 | 
			
		||||
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"github.com/shirou/gopsutil/host"
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
@@ -128,3 +129,12 @@ func (h *ConfigHandler) GetLicense(c *gin.Context) {
 | 
			
		||||
	license := h.licenseService.GetLicense()
 | 
			
		||||
	resp.SUCCESS(c, license)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetDrawingConfig 获取AI绘画配置
 | 
			
		||||
func (h *ConfigHandler) GetDrawingConfig(c *gin.Context) {
 | 
			
		||||
	resp.SUCCESS(c, gin.H{
 | 
			
		||||
		"mj_plus":  h.App.Config.MjPlusConfigs,
 | 
			
		||||
		"mj_proxy": h.App.Config.MjProxyConfigs,
 | 
			
		||||
		"sd":       h.App.Config.SdConfigs,
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ import (
 | 
			
		||||
	"geekai/store/vo"
 | 
			
		||||
	"geekai/utils"
 | 
			
		||||
	"geekai/utils/resp"
 | 
			
		||||
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
)
 | 
			
		||||
@@ -32,7 +33,7 @@ func (h *ChatModelHandler) List(c *gin.Context) {
 | 
			
		||||
	var res *gorm.DB
 | 
			
		||||
	// 如果用户没有登录,则加载所有开放模型
 | 
			
		||||
	if !h.IsLogin(c) {
 | 
			
		||||
		res = h.DB.Where("enabled = ?", true).Where("open =?", true).Order("sort_num ASC").Find(&items)
 | 
			
		||||
		res = h.DB.Where("enabled", true).Where("open", true).Order("sort_num ASC").Find(&items)
 | 
			
		||||
	} else {
 | 
			
		||||
		user, _ := h.GetLoginUser(c)
 | 
			
		||||
		var models []int
 | 
			
		||||
@@ -43,7 +44,7 @@ func (h *ChatModelHandler) List(c *gin.Context) {
 | 
			
		||||
		}
 | 
			
		||||
		// 查询用户有权限访问的模型以及所有开放的模型
 | 
			
		||||
		res = h.DB.Where("enabled = ?", true).Where(
 | 
			
		||||
			h.DB.Where("id IN ?", models).Or("open =?", true),
 | 
			
		||||
			h.DB.Where("id IN ?", models).Or("open", true),
 | 
			
		||||
		).Order("sort_num ASC").Find(&items)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -148,7 +148,6 @@ func (h *MarkMapHandler) sendMessage(client *types.WsClient, prompt string, mode
 | 
			
		||||
	contentType := response.Header.Get("Content-Type")
 | 
			
		||||
	if strings.Contains(contentType, "text/event-stream") {
 | 
			
		||||
		// 循环读取 Chunk 消息
 | 
			
		||||
		var message = types.Message{}
 | 
			
		||||
		scanner := bufio.NewScanner(response.Body)
 | 
			
		||||
		var isNew = true
 | 
			
		||||
		for scanner.Scan() {
 | 
			
		||||
@@ -159,26 +158,26 @@ func (h *MarkMapHandler) sendMessage(client *types.WsClient, prompt string, mode
 | 
			
		||||
 | 
			
		||||
			var responseBody = types.ApiResponse{}
 | 
			
		||||
			err = json.Unmarshal([]byte(line[6:]), &responseBody)
 | 
			
		||||
			if err != nil || len(responseBody.Choices) == 0 { // 数据解析出错
 | 
			
		||||
				return fmt.Errorf("error with decode data: %v", err)
 | 
			
		||||
			if err != nil { // 数据解析出错
 | 
			
		||||
				return fmt.Errorf("error with decode data: %v", line)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// 初始化 role
 | 
			
		||||
			if responseBody.Choices[0].Delta.Role != "" && message.Role == "" {
 | 
			
		||||
				message.Role = responseBody.Choices[0].Delta.Role
 | 
			
		||||
			if len(responseBody.Choices) == 0 { // Fixed: 兼容 Azure API 第一个输出空行
 | 
			
		||||
				continue
 | 
			
		||||
			} else if responseBody.Choices[0].FinishReason != "" {
 | 
			
		||||
				break // 输出完成或者输出中断了
 | 
			
		||||
			} else {
 | 
			
		||||
				if isNew {
 | 
			
		||||
					utils.ReplyChunkMessage(client, types.WsMessage{Type: types.WsStart})
 | 
			
		||||
					isNew = false
 | 
			
		||||
				}
 | 
			
		||||
				utils.ReplyChunkMessage(client, types.WsMessage{
 | 
			
		||||
					Type:    types.WsMiddle,
 | 
			
		||||
					Content: utils.InterfaceToString(responseBody.Choices[0].Delta.Content),
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if responseBody.Choices[0].FinishReason == "stop" {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if isNew {
 | 
			
		||||
				utils.ReplyChunkMessage(client, types.WsMessage{Type: types.WsStart})
 | 
			
		||||
				isNew = false
 | 
			
		||||
			}
 | 
			
		||||
			utils.ReplyChunkMessage(client, types.WsMessage{
 | 
			
		||||
				Type:    types.WsMiddle,
 | 
			
		||||
				Content: utils.InterfaceToString(responseBody.Choices[0].Delta.Content),
 | 
			
		||||
			})
 | 
			
		||||
		} // end for
 | 
			
		||||
 | 
			
		||||
		utils.ReplyChunkMessage(client, types.WsMessage{Type: types.WsEnd})
 | 
			
		||||
 
 | 
			
		||||
@@ -302,6 +302,7 @@ func main() {
 | 
			
		||||
			group.GET("config/get", h.Get)
 | 
			
		||||
			group.POST("active", h.Active)
 | 
			
		||||
			group.GET("config/get/license", h.GetLicense)
 | 
			
		||||
			group.GET("config/get/draw", h.GetDrawingConfig)
 | 
			
		||||
		}),
 | 
			
		||||
		fx.Invoke(func(s *core.AppServer, h *admin.ManagerHandler) {
 | 
			
		||||
			group := s.Engine.Group("/api/admin/")
 | 
			
		||||
 
 | 
			
		||||
@@ -81,7 +81,7 @@
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          <div class="markdown" v-if="loading">
 | 
			
		||||
            <div :style="{ height: rightBoxHeight + 'px', overflow:'auto' }" v-html="html"></div>
 | 
			
		||||
            <div :style="{ height: rightBoxHeight + 'px', overflow:'auto',width:'80%' }" v-html="html"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="body" id="markmap" v-show="!loading">
 | 
			
		||||
            <svg ref="svgRef" :style="{ height: rightBoxHeight + 'px' }"/>
 | 
			
		||||
@@ -157,7 +157,7 @@ const initData = () => {
 | 
			
		||||
 | 
			
		||||
    httpGet("/api/model/list").then(res => {
 | 
			
		||||
      for (let v of res.data) {
 | 
			
		||||
        if (v.platform === "OpenAI") {
 | 
			
		||||
        if (v.platform === "OpenAI" && v.value.indexOf("gpt-4-gizmo") === -1) {
 | 
			
		||||
          models.value.push(v)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -171,7 +171,6 @@ const initData = () => {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const update = () => {
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    const {root} = transformer.transform(processContent(text.value))
 | 
			
		||||
    markMap.value.setData(root)
 | 
			
		||||
@@ -246,6 +245,7 @@ const connect = (userId) => {
 | 
			
		||||
    if (event.data instanceof Blob) {
 | 
			
		||||
      const reader = new FileReader();
 | 
			
		||||
      reader.readAsText(event.data, "UTF-8")
 | 
			
		||||
      const model = getModelById(modelID.value)
 | 
			
		||||
      reader.onload = () => {
 | 
			
		||||
        const data = JSON.parse(String(reader.result))
 | 
			
		||||
        switch (data.type) {
 | 
			
		||||
@@ -259,6 +259,7 @@ const connect = (userId) => {
 | 
			
		||||
          case "end":
 | 
			
		||||
            loading.value = false
 | 
			
		||||
            content.value = processContent(text.value)
 | 
			
		||||
            loginUser.value.power -= model.power
 | 
			
		||||
            nextTick(() => update())
 | 
			
		||||
            break
 | 
			
		||||
          case "error":
 | 
			
		||||
@@ -305,6 +306,14 @@ const changeModel = () => {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const getModelById = (modelId) => {
 | 
			
		||||
  for (let e of models.value) {
 | 
			
		||||
    if (e.id === modelId) {
 | 
			
		||||
      return e
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// download SVG to png file
 | 
			
		||||
const downloadImage = () => {
 | 
			
		||||
  const svgElement = document.getElementById("markmap");
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										87
									
								
								web/src/views/admin/AIDrawing.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								web/src/views/admin/AIDrawing.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <el-form label-width="150px" label-position="right">
 | 
			
		||||
    <el-tabs type="border-card">
 | 
			
		||||
      <el-tab-pane label="MJ-PLUS">
 | 
			
		||||
        <div v-if="mjPlusConfigs">
 | 
			
		||||
          <el-form-item label="网站标题">
 | 
			
		||||
            <el-input v-model="sdConfigs"/>
 | 
			
		||||
          </el-form-item>
 | 
			
		||||
        </div>
 | 
			
		||||
        <el-empty v-else></el-empty>
 | 
			
		||||
        <el-row style="justify-content: center">
 | 
			
		||||
          <el-button round>
 | 
			
		||||
            <el-icon><Plus /></el-icon>
 | 
			
		||||
            <span>新增配置</span>
 | 
			
		||||
          </el-button>
 | 
			
		||||
        </el-row>
 | 
			
		||||
 | 
			
		||||
      </el-tab-pane>
 | 
			
		||||
 | 
			
		||||
      <el-tab-pane label="MJ-PROXY">
 | 
			
		||||
        <div v-if="mjProxyConfigs">
 | 
			
		||||
          <el-form-item label="注册赠送算力">
 | 
			
		||||
            <el-input v-model.number="sdConfigs" placeholder="新用户注册赠送算力"/>
 | 
			
		||||
          </el-form-item>
 | 
			
		||||
        </div>
 | 
			
		||||
        <el-empty v-else />
 | 
			
		||||
      </el-tab-pane>
 | 
			
		||||
 | 
			
		||||
      <el-tab-pane label="Stable-Diffusion">
 | 
			
		||||
        <el-form-item label="注册赠送算力">
 | 
			
		||||
          <el-input v-model.number="sdConfigs" placeholder="新用户注册赠送算力"/>
 | 
			
		||||
        </el-form-item>
 | 
			
		||||
      </el-tab-pane>
 | 
			
		||||
    </el-tabs>
 | 
			
		||||
 | 
			
		||||
    <div style="padding: 10px;">
 | 
			
		||||
      <el-form-item>
 | 
			
		||||
        <el-button type="primary" @click="save('system')">保存</el-button>
 | 
			
		||||
      </el-form-item>
 | 
			
		||||
    </div>
 | 
			
		||||
  </el-form>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup>
 | 
			
		||||
import {ref} from "vue";
 | 
			
		||||
import {httpGet} from "@/utils/http";
 | 
			
		||||
import {ElMessage} from "element-plus";
 | 
			
		||||
import {Plus} from "@element-plus/icons-vue";
 | 
			
		||||
 | 
			
		||||
// 变量定义
 | 
			
		||||
const sdConfigs = ref([])
 | 
			
		||||
const mjPlusConfigs = ref([])
 | 
			
		||||
const mjProxyConfigs = ref([])
 | 
			
		||||
 | 
			
		||||
httpGet("/api/admin/config/get/draw").then(res => {
 | 
			
		||||
  sdConfigs.value = res.data.sd
 | 
			
		||||
  mjPlusConfigs.value = res.data.mj_plus
 | 
			
		||||
  mjProxyConfigs.value = res.data.mj_proxy
 | 
			
		||||
}).catch(e =>{
 | 
			
		||||
  ElMessage.error("获取AI绘画配置失败:"+e.message)
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.menu {
 | 
			
		||||
 | 
			
		||||
  .opt-box {
 | 
			
		||||
    padding-bottom: 10px;
 | 
			
		||||
    display flex;
 | 
			
		||||
    justify-content flex-end
 | 
			
		||||
 | 
			
		||||
    .el-icon {
 | 
			
		||||
      margin-right: 5px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .menu-icon {
 | 
			
		||||
    width 36px
 | 
			
		||||
    height 36px
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .el-select {
 | 
			
		||||
    width: 100%
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -287,6 +287,10 @@
 | 
			
		||||
        <Menu/>
 | 
			
		||||
      </el-tab-pane>
 | 
			
		||||
 | 
			
		||||
      <el-tab-pane label="AI绘图配置" name="AIDrawing">
 | 
			
		||||
        <AIDrawing/>
 | 
			
		||||
      </el-tab-pane>
 | 
			
		||||
 | 
			
		||||
      <el-tab-pane label="授权激活" name="license">
 | 
			
		||||
        <div class="container">
 | 
			
		||||
          <el-descriptions
 | 
			
		||||
@@ -347,6 +351,7 @@ import MdEditor from "md-editor-v3";
 | 
			
		||||
import 'md-editor-v3/lib/style.css';
 | 
			
		||||
import Menu from "@/views/admin/Menu.vue";
 | 
			
		||||
import {dateFormat} from "@/utils/libs";
 | 
			
		||||
import AIDrawing from "@/views/admin/AIDrawing.vue";
 | 
			
		||||
 | 
			
		||||
const activeName = ref('basic')
 | 
			
		||||
const system = ref({models: []})
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user