mirror of
				https://github.com/yangjian102621/geekai.git
				synced 2025-11-04 16:23:42 +08:00 
			
		
		
		
	feat: markmap page view is ready
This commit is contained in:
		
							
								
								
									
										1825
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1825
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -22,6 +22,9 @@
 | 
			
		||||
    "markdown-it": "^13.0.1",
 | 
			
		||||
    "markdown-it-latex2img": "^0.0.6",
 | 
			
		||||
    "markdown-it-mathjax": "^2.0.0",
 | 
			
		||||
    "markmap-common": "^0.16.0",
 | 
			
		||||
    "markmap-lib": "^0.16.1",
 | 
			
		||||
    "markmap-view": "^0.16.0",
 | 
			
		||||
    "md-editor-v3": "^2.2.1",
 | 
			
		||||
    "pinia": "^2.1.4",
 | 
			
		||||
    "qrcode": "^1.5.3",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								web/public/images/menu/xmind.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								web/public/images/menu/xmind.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 1.6 KiB  | 
							
								
								
									
										87
									
								
								web/src/assets/css/mark-map.styl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								web/src/assets/css/mark-map.styl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
.page-mark-map {
 | 
			
		||||
  background-color: #282c34;
 | 
			
		||||
  height 100vh
 | 
			
		||||
 | 
			
		||||
  .inner {
 | 
			
		||||
    display: flex;
 | 
			
		||||
 | 
			
		||||
    .mark-map-box {
 | 
			
		||||
      margin 10px
 | 
			
		||||
      background-color #262626
 | 
			
		||||
      border 1px solid #454545
 | 
			
		||||
      min-width 300px
 | 
			
		||||
      max-width 300px
 | 
			
		||||
      padding 10px
 | 
			
		||||
      border-radius 10px
 | 
			
		||||
      color #ffffff;
 | 
			
		||||
      font-size 14px
 | 
			
		||||
 | 
			
		||||
      h2 {
 | 
			
		||||
        font-weight: bold;
 | 
			
		||||
        font-size 20px
 | 
			
		||||
        text-align center
 | 
			
		||||
        color #47fff1
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 隐藏滚动条
 | 
			
		||||
      ::-webkit-scrollbar {
 | 
			
		||||
        width: 0;
 | 
			
		||||
        height: 0;
 | 
			
		||||
        background-color: transparent;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .mark-map-params {
 | 
			
		||||
        margin-top 10px
 | 
			
		||||
        overflow auto
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        .param-line {
 | 
			
		||||
          padding 10px
 | 
			
		||||
 | 
			
		||||
          .el-button {
 | 
			
		||||
            width 100%
 | 
			
		||||
 | 
			
		||||
            span {
 | 
			
		||||
              color #2D3A4B
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .text-info {
 | 
			
		||||
          padding 10px
 | 
			
		||||
 | 
			
		||||
          .el-tag {
 | 
			
		||||
            margin-right 10px
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .el-form {
 | 
			
		||||
      .el-form-item__label {
 | 
			
		||||
        color #ffffff
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .right-box {
 | 
			
		||||
      width 100%
 | 
			
		||||
      h2 {
 | 
			
		||||
        color #ffffff
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      .body {
 | 
			
		||||
        display flex
 | 
			
		||||
        justify-content center
 | 
			
		||||
        align-items center
 | 
			
		||||
 | 
			
		||||
        .markmap {
 | 
			
		||||
          width 100%
 | 
			
		||||
          color #ffffff
 | 
			
		||||
          font-size 12px
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -62,6 +62,12 @@ const routes = [
 | 
			
		||||
                meta: {title: '消费日志'},
 | 
			
		||||
                component: () => import('@/views/PowerLog.vue'),
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                name: 'xmind',
 | 
			
		||||
                path: '/xmind',
 | 
			
		||||
                meta: {title: '思维导图'},
 | 
			
		||||
                component: () => import('@/views/MarkMap.vue'),
 | 
			
		||||
            },
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										128
									
								
								web/src/views/MarkMap.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								web/src/views/MarkMap.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,128 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
    <div class="page-mark-map">
 | 
			
		||||
      <div class="inner custom-scroll">
 | 
			
		||||
        <div class="mark-map-box">
 | 
			
		||||
          <h2>思维导图创作中心</h2>
 | 
			
		||||
 | 
			
		||||
          <div class="mark-map-params" :style="{ height: leftBoxHeight + 'px' }">
 | 
			
		||||
            <el-form :model="params" label-width="80px" label-position="left">
 | 
			
		||||
              <div class="param-line">
 | 
			
		||||
                你的需求?
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="param-line">
 | 
			
		||||
                <el-input
 | 
			
		||||
                    v-model="prompt"
 | 
			
		||||
                    :autosize="{ minRows: 4, maxRows: 6 }"
 | 
			
		||||
                    type="textarea"
 | 
			
		||||
                    placeholder="请给AI输入提示词,让AI帮你完善"
 | 
			
		||||
                />
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
              <div class="param-line">
 | 
			
		||||
                <el-button color="#47fff1" :dark="false" round @click="generate">智能生成思维导图</el-button>
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
              <div class="param-line">
 | 
			
		||||
                使用已有内容生成?
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="param-line">
 | 
			
		||||
                <el-input
 | 
			
		||||
                    v-model="prompt"
 | 
			
		||||
                    :autosize="{ minRows: 4, maxRows: 6 }"
 | 
			
		||||
                    type="textarea"
 | 
			
		||||
                    placeholder="请用markdown语法输入您想要生成思维导图的内容!"
 | 
			
		||||
                />
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
              <div class="param-line">
 | 
			
		||||
                <el-button color="#47fff1" :dark="false" round @click="generate">直接生成(免费)</el-button>
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
              <div class="text-info">
 | 
			
		||||
               <el-row :gutter="10">
 | 
			
		||||
                 <el-col :span="12">
 | 
			
		||||
                   <el-tag>每次生成消耗1算力</el-tag>
 | 
			
		||||
                 </el-col>
 | 
			
		||||
                 <el-col :span="12">
 | 
			
		||||
                   <el-tag type="success">当前可用算力:{{ power }}</el-tag>
 | 
			
		||||
                 </el-col>
 | 
			
		||||
               </el-row>
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
            </el-form>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="right-box">
 | 
			
		||||
          <h2>思维导图</h2>
 | 
			
		||||
          <div class="body">
 | 
			
		||||
            <svg ref="svgRef" :style="{ height: leftBoxHeight + 'px' }"/>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div><!-- end task list box -->
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <login-dialog :show="showLoginDialog" @hide="showLoginDialog =  false" @success="initData"/>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup>
 | 
			
		||||
import LoginDialog from "@/components/LoginDialog.vue";
 | 
			
		||||
import {ref, onMounted, onUpdated} from 'vue';
 | 
			
		||||
import {Markmap} from 'markmap-view';
 | 
			
		||||
import {loadJS, loadCSS} from 'markmap-common';
 | 
			
		||||
import {Transformer} from 'markmap-lib';
 | 
			
		||||
 | 
			
		||||
const leftBoxHeight = ref(window.innerHeight - 105)
 | 
			
		||||
const rightBoxHeight = ref(window.innerHeight - 105)
 | 
			
		||||
 | 
			
		||||
const prompt = ref("")
 | 
			
		||||
const text = ref(`# Geek-AI 助手
 | 
			
		||||
 | 
			
		||||
* 完整的开源系统,前端应用和后台管理系统皆可开箱即用。
 | 
			
		||||
* 基于 Websocket 实现,完美的打字机体验。
 | 
			
		||||
* 内置了各种预训练好的角色应用,轻松满足你的各种聊天和应用需求。
 | 
			
		||||
* 支持 OPenAI,Azure,文心一言,讯飞星火,清华 ChatGLM等多个大语言模型。
 | 
			
		||||
* 支持 MidJourney / Stable Diffusion AI 绘画集成,开箱即用。
 | 
			
		||||
* 支持使用个人微信二维码作为充值收费的支付渠道,无需企业支付通道。
 | 
			
		||||
* 已集成支付宝支付功能,微信支付,支持多种会员套餐和点卡购买功能。
 | 
			
		||||
* 集成插件 API 功能,可结合大语言模型的 function 功能开发各种强大的插件。
 | 
			
		||||
`)
 | 
			
		||||
const showLoginDialog = ref(false)
 | 
			
		||||
const isLogin = ref(false)
 | 
			
		||||
const power = ref(0)
 | 
			
		||||
const transformer = new Transformer();
 | 
			
		||||
const {scripts, styles} = transformer.getAssets()
 | 
			
		||||
loadCSS(styles);
 | 
			
		||||
loadJS(scripts);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const svgRef = ref(null)
 | 
			
		||||
const markMap = ref(null)
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  markMap.value = Markmap.create(svgRef.value)
 | 
			
		||||
  update()
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const update = () => {
 | 
			
		||||
  const {root} = transformer.transform(text.value)
 | 
			
		||||
  markMap.value.setData(root)
 | 
			
		||||
  markMap.value.fit()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
onUpdated(update)
 | 
			
		||||
 | 
			
		||||
window.onresize = () => {
 | 
			
		||||
  leftBoxHeight.value = window.innerHeight - 145
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus">
 | 
			
		||||
@import "@/assets/css/mark-map.styl"
 | 
			
		||||
@import "@/assets/css/custom-scroll.styl"
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,16 +1,43 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
    {{ title }}
 | 
			
		||||
    <textarea v-model="value"/>
 | 
			
		||||
  </div>
 | 
			
		||||
  <svg ref="svgRef"/>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup>
 | 
			
		||||
import {ref, onMounted, onUpdated} from 'vue';
 | 
			
		||||
import {Markmap} from 'markmap-view';
 | 
			
		||||
import {loadJS, loadCSS} from 'markmap-common';
 | 
			
		||||
import {Transformer} from 'markmap-lib';
 | 
			
		||||
 | 
			
		||||
import {ref} from "vue";
 | 
			
		||||
const transformer = new Transformer();
 | 
			
		||||
const {scripts, styles} = transformer.getAssets();
 | 
			
		||||
loadCSS(styles);
 | 
			
		||||
loadJS(scripts);
 | 
			
		||||
 | 
			
		||||
const title = ref('Test Page')
 | 
			
		||||
const initValue = `# markmap
 | 
			
		||||
 | 
			
		||||
- beautiful
 | 
			
		||||
- useful
 | 
			
		||||
- easy
 | 
			
		||||
- interactive
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
const value = ref(initValue);
 | 
			
		||||
const svgRef = ref(null);
 | 
			
		||||
let mm;
 | 
			
		||||
 | 
			
		||||
const update = () => {
 | 
			
		||||
  const {root} = transformer.transform(value.value);
 | 
			
		||||
  mm.setData(root);
 | 
			
		||||
  mm.fit();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  mm = Markmap.create(svgRef.value);
 | 
			
		||||
  update();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
onUpdated(update);
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
</style>
 | 
			
		||||
		Reference in New Issue
	
	Block a user