mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-21 02:36:39 +08:00
fix: markmap do not cost power in front page
This commit is contained in:
parent
4edf2ea02a
commit
8251c6589b
@ -15,6 +15,7 @@ import (
|
|||||||
"geekai/store/vo"
|
"geekai/store/vo"
|
||||||
"geekai/utils"
|
"geekai/utils"
|
||||||
"geekai/utils/resp"
|
"geekai/utils/resp"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"geekai/store/model"
|
"geekai/store/model"
|
||||||
"geekai/utils"
|
"geekai/utils"
|
||||||
"geekai/utils/resp"
|
"geekai/utils/resp"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/shirou/gopsutil/host"
|
"github.com/shirou/gopsutil/host"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -128,3 +129,12 @@ func (h *ConfigHandler) GetLicense(c *gin.Context) {
|
|||||||
license := h.licenseService.GetLicense()
|
license := h.licenseService.GetLicense()
|
||||||
resp.SUCCESS(c, license)
|
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/store/vo"
|
||||||
"geekai/utils"
|
"geekai/utils"
|
||||||
"geekai/utils/resp"
|
"geekai/utils/resp"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
@ -32,7 +33,7 @@ func (h *ChatModelHandler) List(c *gin.Context) {
|
|||||||
var res *gorm.DB
|
var res *gorm.DB
|
||||||
// 如果用户没有登录,则加载所有开放模型
|
// 如果用户没有登录,则加载所有开放模型
|
||||||
if !h.IsLogin(c) {
|
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 {
|
} else {
|
||||||
user, _ := h.GetLoginUser(c)
|
user, _ := h.GetLoginUser(c)
|
||||||
var models []int
|
var models []int
|
||||||
@ -43,7 +44,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("id 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,6 @@ func (h *MarkMapHandler) sendMessage(client *types.WsClient, prompt string, mode
|
|||||||
contentType := response.Header.Get("Content-Type")
|
contentType := response.Header.Get("Content-Type")
|
||||||
if strings.Contains(contentType, "text/event-stream") {
|
if strings.Contains(contentType, "text/event-stream") {
|
||||||
// 循环读取 Chunk 消息
|
// 循环读取 Chunk 消息
|
||||||
var message = types.Message{}
|
|
||||||
scanner := bufio.NewScanner(response.Body)
|
scanner := bufio.NewScanner(response.Body)
|
||||||
var isNew = true
|
var isNew = true
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
@ -159,26 +158,26 @@ func (h *MarkMapHandler) sendMessage(client *types.WsClient, prompt string, mode
|
|||||||
|
|
||||||
var responseBody = types.ApiResponse{}
|
var responseBody = types.ApiResponse{}
|
||||||
err = json.Unmarshal([]byte(line[6:]), &responseBody)
|
err = json.Unmarshal([]byte(line[6:]), &responseBody)
|
||||||
if err != nil || len(responseBody.Choices) == 0 { // 数据解析出错
|
if err != nil { // 数据解析出错
|
||||||
return fmt.Errorf("error with decode data: %v", err)
|
return fmt.Errorf("error with decode data: %v", line)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化 role
|
if len(responseBody.Choices) == 0 { // Fixed: 兼容 Azure API 第一个输出空行
|
||||||
if responseBody.Choices[0].Delta.Role != "" && message.Role == "" {
|
|
||||||
message.Role = responseBody.Choices[0].Delta.Role
|
|
||||||
continue
|
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
|
} // end for
|
||||||
|
|
||||||
utils.ReplyChunkMessage(client, types.WsMessage{Type: types.WsEnd})
|
utils.ReplyChunkMessage(client, types.WsMessage{Type: types.WsEnd})
|
||||||
|
@ -302,6 +302,7 @@ func main() {
|
|||||||
group.GET("config/get", h.Get)
|
group.GET("config/get", h.Get)
|
||||||
group.POST("active", h.Active)
|
group.POST("active", h.Active)
|
||||||
group.GET("config/get/license", h.GetLicense)
|
group.GET("config/get/license", h.GetLicense)
|
||||||
|
group.GET("config/get/draw", h.GetDrawingConfig)
|
||||||
}),
|
}),
|
||||||
fx.Invoke(func(s *core.AppServer, h *admin.ManagerHandler) {
|
fx.Invoke(func(s *core.AppServer, h *admin.ManagerHandler) {
|
||||||
group := s.Engine.Group("/api/admin/")
|
group := s.Engine.Group("/api/admin/")
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="markdown" v-if="loading">
|
<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>
|
||||||
<div class="body" id="markmap" v-show="!loading">
|
<div class="body" id="markmap" v-show="!loading">
|
||||||
<svg ref="svgRef" :style="{ height: rightBoxHeight + 'px' }"/>
|
<svg ref="svgRef" :style="{ height: rightBoxHeight + 'px' }"/>
|
||||||
@ -157,7 +157,7 @@ const initData = () => {
|
|||||||
|
|
||||||
httpGet("/api/model/list").then(res => {
|
httpGet("/api/model/list").then(res => {
|
||||||
for (let v of res.data) {
|
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)
|
models.value.push(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,7 +171,6 @@ const initData = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const update = () => {
|
const update = () => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const {root} = transformer.transform(processContent(text.value))
|
const {root} = transformer.transform(processContent(text.value))
|
||||||
markMap.value.setData(root)
|
markMap.value.setData(root)
|
||||||
@ -246,6 +245,7 @@ const connect = (userId) => {
|
|||||||
if (event.data instanceof Blob) {
|
if (event.data instanceof Blob) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.readAsText(event.data, "UTF-8")
|
reader.readAsText(event.data, "UTF-8")
|
||||||
|
const model = getModelById(modelID.value)
|
||||||
reader.onload = () => {
|
reader.onload = () => {
|
||||||
const data = JSON.parse(String(reader.result))
|
const data = JSON.parse(String(reader.result))
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
@ -259,6 +259,7 @@ const connect = (userId) => {
|
|||||||
case "end":
|
case "end":
|
||||||
loading.value = false
|
loading.value = false
|
||||||
content.value = processContent(text.value)
|
content.value = processContent(text.value)
|
||||||
|
loginUser.value.power -= model.power
|
||||||
nextTick(() => update())
|
nextTick(() => update())
|
||||||
break
|
break
|
||||||
case "error":
|
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
|
// download SVG to png file
|
||||||
const downloadImage = () => {
|
const downloadImage = () => {
|
||||||
const svgElement = document.getElementById("markmap");
|
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/>
|
<Menu/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane label="AI绘图配置" name="AIDrawing">
|
||||||
|
<AIDrawing/>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane label="授权激活" name="license">
|
<el-tab-pane label="授权激活" name="license">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<el-descriptions
|
<el-descriptions
|
||||||
@ -347,6 +351,7 @@ import MdEditor from "md-editor-v3";
|
|||||||
import 'md-editor-v3/lib/style.css';
|
import 'md-editor-v3/lib/style.css';
|
||||||
import Menu from "@/views/admin/Menu.vue";
|
import Menu from "@/views/admin/Menu.vue";
|
||||||
import {dateFormat} from "@/utils/libs";
|
import {dateFormat} from "@/utils/libs";
|
||||||
|
import AIDrawing from "@/views/admin/AIDrawing.vue";
|
||||||
|
|
||||||
const activeName = ref('basic')
|
const activeName = ref('basic')
|
||||||
const system = ref({models: []})
|
const system = ref({models: []})
|
||||||
|
Loading…
Reference in New Issue
Block a user