Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c5a243c2f | ||
|
|
3541b7df40 | ||
|
|
9eab537b2e | ||
|
|
31d71db611 | ||
|
|
cfe07aa32e | ||
|
|
b8ac079009 | ||
|
|
040ce6601b | ||
|
|
77dd62477e | ||
|
|
b831d95063 | ||
|
|
bff6024e2e | ||
|
|
919b1517d9 | ||
|
|
2cbd08c532 | ||
|
|
c26cc5af83 | ||
|
|
5e300c0320 | ||
|
|
714567a733 | ||
|
|
28d6bb7d90 | ||
|
|
ecb2fbab48 | ||
|
|
a8c13b8f9a | ||
|
|
475dd4754a | ||
|
|
8a59185156 | ||
|
|
80ca74e477 | ||
|
|
c67bebb384 | ||
|
|
3a9002821c | ||
|
|
d0b289ed28 | ||
|
|
84782f924b | ||
|
|
2dd3db4c9d | ||
|
|
eb61e24746 | ||
|
|
abb332fd46 | ||
|
|
0c4fadb211 | ||
|
|
cd361c1f6e | ||
|
|
e0dc13c9f8 | ||
|
|
670114d8d8 | ||
|
|
c5b5fd86de | ||
|
|
493e0da7ae | ||
|
|
896121f6b6 | ||
|
|
b79076baa3 | ||
|
|
715627727e | ||
|
|
5ed5f0ff0d | ||
|
|
c12189ca87 | ||
|
|
be38eb2ca6 | ||
|
|
e80890aa7e | ||
|
|
e0ca3a5d12 | ||
|
|
30404721fa |
84
README_EN.md
Normal file
@ -0,0 +1,84 @@
|
||||
<h1 align="center">Simple mind map</h1>
|
||||
|
||||
[](https://www.npmjs.com/package/simple-mind-map)
|
||||

|
||||
[](https://github.com/wanglin2/mind-map/issues)
|
||||

|
||||
[](https://github.com/wanglin2/mind-map/stargazers)
|
||||
[](https://github.com/wanglin2/mind-map/network/members)
|
||||
|
||||
English | [中文](./README.md)
|
||||
|
||||
> Chinese name: 思绪思维导图. A simple & powerful web mind map library and mind map software.
|
||||
|
||||
This project consists of two parts: an open-source JavaScript library and closed-source client software.
|
||||
|
||||
# Library, Web
|
||||
|
||||
> Refers to the code in this repository, currently in low-maintenance status.
|
||||
|
||||
- A `js` mind map library, independent of any framework, which can be used to quickly develop web-based mind map products.
|
||||
|
||||
> Documentation: [https://wanglin2.github.io/mind-map-docs/](https://wanglin2.github.io/mind-map-docs/)
|
||||
|
||||
- A web-based mind map application, developed using the mind map library, `Vue2.x`, and `ElementUI`. It supports operations on local computer files, can be used as an online mind map application, and is open for self-deployment and secondary development.
|
||||
|
||||
> Online address: [https://wanglin2.github.io/mind-map/](https://wanglin2.github.io/mind-map/)
|
||||
|
||||
Learn more: [README](./README_MORE_EN.md).
|
||||
|
||||
# Client, Plugins
|
||||
|
||||
> The client and plugin code are not open source and are under active development and maintenance.
|
||||
|
||||
- 思绪思维导图 Client
|
||||
|
||||
Local storage, privacy-first, data security. The software can be used without an internet connection!
|
||||
|
||||
- [x] 1. Supports creating unlimited files and nodes (free nodes); supports creating and using templates.
|
||||
- [x] 2. Offers rich settings: basic settings, custom fonts/shortcuts/right-click menus/icons, image hosting configuration, AI configuration, WebDAV cloud sync configuration, etc., highly customizable.
|
||||
- [x] 3. Supports various structure types: mind maps, logical structure diagrams, directory organization charts, organizational charts, timelines, fishbone diagrams, tables, etc.
|
||||
- [x] 4. Built-in hundreds of rich and beautiful themes, also supports custom themes and AI-generated themes.
|
||||
- [x] 5. Nodes support adding rich content: text, images, links, icons, notes, attachments, tags, summary nodes, association lines, borders, markers, to-dos, descriptions, numbering, mathematical formulas, etc.
|
||||
- [x] 6. Supports importing files in XMind, FreeMind, Markdown, Txt, Xlsx, etc.; supports exporting to PNG, XMind, SVG, PDF, Markdown, Txt, Xlsx, FreeMind, Mermaid, Html, etc.
|
||||
- [x] 7. Rich style settings: text, borders, background, shape, lines, inner/outer margins, image tag layout, etc.
|
||||
- [x] 8. Supports practical and interesting features: historical version management, presentation mode, AI generation, hand-drawn style, outline editing, watermark, scrollbars, sibling node alignment, minimap, entering specific nodes, rainbow lines, bidirectional node linking, search and replace, etc.
|
||||
|
||||
Supports Windows, Mac, and Linux systems; supports Chinese, English, Traditional Chinese, Vietnamese, and Russian languages.
|
||||
|
||||
Download links: [Github](https://github.com/wanglin2/mind-map/releases), [Baidu Netdisk](https://pan.baidu.com/s/1C8phEJ5pagAAa-o1tU42Uw?pwd=jqfb), [Quark Netdisk](https://pan.quark.cn/s/2733982f1976)
|
||||
|
||||
> If the software fails to open after installation on macOS, showing an error like **untrusted** or **moved to trash**, execute the following command and then restart:
|
||||
> ``` shell
|
||||
> sudo xattr -d com.apple.quarantine /Applications/思绪思维导图.app
|
||||
> ```
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
- Obsidian Plugin
|
||||
|
||||
Download link: [Github](https://github.com/wanglin2/obsidian-simplemindmap/releases)
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
- UTools Plugin
|
||||
|
||||
Available in the [uTools](https://www.u.tools/) plugin market. You can search for `思绪` directly in the uTools plugin market to install it, or visit this address directly: [Homepage](https://www.u-tools.cn/plugins/detail/%E6%80%9D%E7%BB%AA%E6%80%9D%E7%BB%B4%E5%AF%BC%E5%9B%BE/), and click the 【Launch】 button on the right to install.
|
||||
91
README_MORE_EN.md
Normal file
@ -0,0 +1,91 @@
|
||||
# Features
|
||||
|
||||
- [x] Plugin-based architecture. Apart from core functionalities, other features are provided as plugins, allowing on-demand use to reduce bundle size.
|
||||
- [x] Supports various structures: Logical Structure Diagrams (left, right), Mind Maps, Organizational Charts, Directory Organization Charts, Timelines (horizontal, vertical), Fishbone Diagrams, etc.
|
||||
- [x] Built-in multiple themes, allows high customization of styles, supports registering new themes.
|
||||
- [x] Node content supports text (plain text, rich text), images, icons, hyperlinks, notes, tags, summaries, mathematical formulas.
|
||||
- [x] Nodes support drag-and-drop (move, free resize), multiple node shapes; supports extending node content, supports using DDM for fully custom node content.
|
||||
- [x] Supports canvas dragging and zooming.
|
||||
- [x] Supports two methods for multi-selecting nodes: mouse button drag selection and Ctrl+left click.
|
||||
- [x] Supports export to `json`, `png`, `svg`, `pdf`, `markdown`, `xmind`, `txt`; supports import from `json`, `xmind`, `markdown`.
|
||||
- [x] Supports shortcuts, undo/redo, associative lines, search/replace, mini-map, watermark, scrollbars, hand-drawn style, rainbow lines, markers, outer frames.
|
||||
- [x] Provides rich configuration options to meet various scenarios and usage habits.
|
||||
- [x] Supports collaborative editing.
|
||||
- [x] Supports presentation mode.
|
||||
- [x] More features await your discovery.
|
||||
|
||||
The following plugins are officially provided and can be imported as needed (if a feature doesn't work, it's likely because the corresponding plugin hasn't been imported). Please refer to the documentation for specific usage:
|
||||
|
||||
| RichText (Node Rich Text Plugin) | Select (Mouse Multi-Select Node Plugin) | Drag (Node Drag Plugin) | AssociativeLine (Associative Line Plugin) |
|
||||
| ------------------------------------- | ----------------------------------------- | ------------------------------------- | ----------------------------------------- |
|
||||
| Export (Export Plugin) | KeyboardNavigation (Keyboard Navigation Plugin) | MiniMap (Mini-Map Plugin) | Watermark (Watermark Plugin) |
|
||||
| TouchEvent (Mobile Touch Event Support Plugin) | NodeImgAdjust (Drag to Adjust Node Image Size Plugin) | Search (Search Plugin) | Painter (Node Format Painter Plugin) |
|
||||
| Scrollbar (Scrollbar Plugin) | Formula (Mathematical Formula Plugin) | Cooperate (Collaborative Editing Plugin) | RainbowLines (Rainbow Lines Plugin) |
|
||||
| Demonstrate (Presentation Mode Plugin) | OuterFrame (Outer Frame Plugin) | MindMapLayoutPro (Mind Map Layout Plugin) | |
|
||||
|
||||
Features that will **not** be implemented in this project:
|
||||
|
||||
> 1. Free nodes, i.e., multiple root nodes.
|
||||
>
|
||||
> 2. Adding nodes after a summary node.
|
||||
>
|
||||
> If you need the above features, this library may not meet your requirements.
|
||||
|
||||
# Installation
|
||||
|
||||
```bash
|
||||
npm i simple-mind-map
|
||||
```
|
||||
|
||||
# Usage
|
||||
|
||||
Provide a container element with non-zero width and height:
|
||||
|
||||
```html
|
||||
<div id="mindMapContainer"></div>
|
||||
```
|
||||
|
||||
Also, set the following CSS styles:
|
||||
|
||||
```css
|
||||
#mindMapContainer * {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
```
|
||||
|
||||
Then create an instance:
|
||||
|
||||
```js
|
||||
import MindMap from "simple-mind-map";
|
||||
|
||||
const mindMap = new MindMap({
|
||||
el: document.getElementById("mindMapContainer"),
|
||||
data: {
|
||||
data: {
|
||||
text: "Root Node",
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You will get a mind map. Want to implement more features? Check the [Development Documentation](https://wanglin2.github.io/mind-map-docs/).
|
||||
|
||||
# License
|
||||
|
||||
[MIT](./LICENSE). Commercial use is permitted freely as long as the `simple-mind-map` copyright notice and attribution are retained. If you have questions or wish to remove these requirements, please contact the author (WeChat: wanglinguanfang) for a paid option to remove them.
|
||||
|
||||
> Example: You can add the following content on any page of your application, such as the About page, Help page, Documentation page, Open Source Notice, etc.:
|
||||
>
|
||||
> The mind map feature of this product is developed based on the SimpleMindMap project. The copyright belongs to the original project. [Open Source License](https://github.com/wanglin2/mind-map/blob/main/LICENSE).
|
||||
|
||||
# Development Help / Technical Support / Consulting
|
||||
|
||||
Due to limited time and a shift in focus, we currently do not provide any development support (including paid support). Thank you for your understanding!
|
||||
|
||||
# Star
|
||||
|
||||
If you like this project, welcome to give it a star. It means a lot to us.
|
||||
|
||||
[](https://star-history.com/#wanglin2/mind-map&Date)
|
||||
986
README_MORE_ZH.md
Normal file
@ -0,0 +1,986 @@
|
||||
# 特性
|
||||
|
||||
- [x] 插件化架构,除核心功能外,其他功能作为插件提供,按需使用,减小打包体积
|
||||
- [x] 支持逻辑结构图(向左、向右逻辑结构图)、思维导图、组织结构图、目录组织图、时间轴(横向、竖向)、鱼骨图等结构
|
||||
- [x] 内置多种主题,允许高度自定义样式,支持注册新主题
|
||||
- [x] 节点内容支持文本(普通文本、富文本)、图片、图标、超链接、备注、标签、概要、数学公式
|
||||
- [x] 节点支持拖拽(拖拽移动、自由调整)、多种节点形状;支持扩展节点内容、支持使用 DDM 完全自定义节点内容
|
||||
- [x] 支持画布拖动、缩放
|
||||
- [x] 支持鼠标按键拖动选择和 Ctrl+左键两种多选节点方式
|
||||
- [x] 支持导出为`json`、`png`、`svg`、`pdf`、`markdown`、`xmind`、`txt`,支持从`json`、`xmind`、`markdown`导入
|
||||
- [x] 支持快捷键、前进后退、关联线、搜索替换、小地图、水印、滚动条、手绘风格、彩虹线条、标记、外框
|
||||
- [x] 提供丰富的配置,满足各种场景各种使用习惯
|
||||
- [x] 支持协同编辑
|
||||
- [x] 支持演示模式
|
||||
- [x] 更多功能等你来发现
|
||||
|
||||
官方提供了如下插件,可根据需求按需引入(某个功能不生效大概率是因为你没有引入对应的插件),具体使用方式请查看文档:
|
||||
|
||||
| RichText(节点富文本插件) | Select(鼠标多选节点插件) | Drag(节点拖拽插件) | AssociativeLine(关联线插件) |
|
||||
| ------------------------------------ | ----------------------------------------- | ------------------------------------ | ------------------------------------ |
|
||||
| Export(导出插件) | KeyboardNavigation(键盘导航插件) | MiniMap(小地图插件) | Watermark(水印插件) |
|
||||
| TouchEvent(移动端触摸事件支持插件) | NodeImgAdjust(拖拽调整节点图片大小插件) | Search(搜索插件) | Painter(节点格式刷插件) |
|
||||
| Scrollbar(滚动条插件) | Formula(数学公式插件) | Cooperate(协同编辑插件) | RainbowLines(彩虹线条插件) |
|
||||
| Demonstrate(演示模式插件) | OuterFrame(外框插件) | MindMapLayoutPro(思维导图布局插件) | |
|
||||
|
||||
|
||||
本项目不会实现的特性:
|
||||
|
||||
> 1.自由节点,即多个根节点;
|
||||
>
|
||||
> 2.概要节点后面继续添加节点;
|
||||
>
|
||||
> 如果你需要以上特性,那么本库可能无法满足你的需求。
|
||||
|
||||
# 安装
|
||||
|
||||
```bash
|
||||
npm i simple-mind-map
|
||||
```
|
||||
|
||||
# 使用
|
||||
|
||||
提供一个宽高不为 0 的容器元素:
|
||||
|
||||
```html
|
||||
<div id="mindMapContainer"></div>
|
||||
```
|
||||
|
||||
另外再设置一下`css`样式:
|
||||
|
||||
```css
|
||||
#mindMapContainer * {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
```
|
||||
|
||||
然后创建一个实例:
|
||||
|
||||
```js
|
||||
import MindMap from "simple-mind-map";
|
||||
|
||||
const mindMap = new MindMap({
|
||||
el: document.getElementById("mindMapContainer"),
|
||||
data: {
|
||||
data: {
|
||||
text: "根节点",
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
即可得到一个思维导图。想要实现更多功能?可以查看[开发文档](https://wanglin2.github.io/mind-map-docs/)。
|
||||
|
||||
# License
|
||||
|
||||
[MIT](./LICENSE)。保留`simple-mind-map`版权声明和注明来源的情况下可随意商用,如有疑问或不想保留可联系作者(微信:wanglinguanfang)通过付费的方式去除。
|
||||
|
||||
> 示例:可以在你应用中的关于页面、帮助页面、文档页面、开源声明等任何页面添加以下内容:
|
||||
>
|
||||
> 本产品思维导图基于SimpleMindMap项目开发,版权归源项目所有,[开源协议](https://github.com/wanglin2/mind-map/blob/main/LICENSE)。
|
||||
|
||||
# 开发帮助/技术支持/咨询等
|
||||
|
||||
因精力有限,及重心转变,暂不提供任何开发支持(包括有偿),请见谅!
|
||||
|
||||
# star
|
||||
|
||||
如果喜欢本项目,欢迎点个 star,这对我们很重要。
|
||||
|
||||
[](https://star-history.com/#wanglin2/mind-map&Date)
|
||||
|
||||
# 关于定制
|
||||
|
||||
如果你有个性化的商用定制需求,可以联系我们,我们提供付费开发服务,无论前端、后端、还是部署,都可以帮你一站式搞定。
|
||||
|
||||
# 谁在使用
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="http://drawon.cn/">
|
||||
<img src="./web/src/assets/avatar/桌案.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>drawon.cn(桌案)</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
# 感谢赞赏过本项目的人
|
||||
|
||||
## 最强王者
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/hi.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>hi</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## 钻石赞助
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/黄智彪@一米一栗科技.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>黄智彪@一米一栗科技</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/沨沄.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>沨沄</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/行.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>行</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## 黄金赞助
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/小土渣的宇宙.jpeg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>小土渣的宇宙</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/Chris.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Chris</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/仓鼠.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>仓鼠</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/风格.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>风格</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>LiuJL</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/Kyle.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Kyle</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/秀树因馨雨.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>秀树因馨雨</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>黄泳</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/ccccs.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>ccccs</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/炫.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>炫</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>晏江</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/梁辉.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>梁辉</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/千帆.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>千帆</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/布林.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>布林</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/达仁科技.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>达仁科技</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/沐风牧草.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>沐风牧草</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/俊奇.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>俊奇</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/庆国.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>庆国</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Matt</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/雨馨.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>雨馨</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/峰.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>峰</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/御风.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>御风</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/兔子快跑.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>兔子快跑</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>LSHM</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>newplayer</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## 青铜赞助
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/Think.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Think</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/志斌.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>志斌</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/qp.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>qp</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/ZXR.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>ZXR</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/花儿朵朵.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>花儿朵朵</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/suka.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>suka</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/水车.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>水车</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/才镇.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>才镇</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/小米.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>小米bbᯤ²ᴳ</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/棐.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>*棐</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/南风.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>南风</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/蜉蝣撼大叔.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>蜉蝣撼大叔</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/乙.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>乙</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/敏.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>敏</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/有希.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>有希</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/樊笼.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>樊笼</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/小逗比.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>小逗比</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/天清如愿.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>天清如愿</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/敬明朗.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>敬明朗</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>飞箭</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/戚永峰.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>戚永峰</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/moom.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>moom</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/张扬.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>张扬</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/长沙利奥软件.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>长沙利奥软件</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/HaHN.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>HaHN</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/继龙.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>继龙</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/欣.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>欣</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>易空小易</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/国发.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>国发</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>建明</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/汪津合.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>汪津合</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>博文</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/慕智打印-兰兰.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>慕智打印-兰兰</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>锦冰</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/旭东.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>旭东</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/橘半.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>橘半</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/pluvet.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>pluvet</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/皇登攀.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>皇登攀</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>SR</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/逆水行舟.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>逆水行舟</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/L.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>L</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>sunniberg</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/在下青铜五.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>sunniberg</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/在下青铜五.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>在下青铜五</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/木星二号.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>木星二号</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/阿晨.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>阿晨</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>铁</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/Alex.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Alex</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/子豪.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>子豪</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/宏涛.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>宏涛</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/最多5个字.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>最多5个字</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/ZX.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>ZX</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>协成</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/木木.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>木木</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/好名字.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>好名字</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/lsytyrt.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>lsytyrt</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/buddy.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>buddy</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>小川</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/Tobin.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Tobin</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/夏虫不语冰.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>夏虫不语冰</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/晴空.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>晴空</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/。.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>。</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/Jeffrey.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Jeffrey</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/张文建.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>张文建</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/Lawliet.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Lawliet</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/一叶孤舟.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>一叶孤舟</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Eric</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/Joe.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Joe</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>中文网字计划-江夏尧</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/海云.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>海云</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/皮老板.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>皮老板</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/h.r.w.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>h.r.w</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/时光匆匆.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>时光匆匆</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/广兴.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>广兴</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/一亩三.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>一亩三</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/xbkkjbs0246658.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>xbkkjbs0246658</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/4399行星元帅.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>4399行星元帅</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/Xavier.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Xavier</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/冒号括号.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>:)</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/可米阳光.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>可米阳光</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/MrFujing.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>MrFujing</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/Sword.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Sword</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/好好先生Ervin.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>好好先生Ervin</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/胡永刚.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>胡永刚</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/旋风.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>旋风</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/星夜寒.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>星夜寒</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/神话.jpg" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>神话</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>Towards the future</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" style="word-wrap: break-word; width: 75.0; height: 75.0">
|
||||
<a href="#">
|
||||
<img src="./web/src/assets/avatar/default.png" width="50;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px"/>
|
||||
<br />
|
||||
<sub style="font-size:14px"><b>安嘉</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
BIN
assets/client/client1.png
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
assets/client/client2.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
assets/client/client3.png
Normal file
|
After Width: | Height: | Size: 143 KiB |
BIN
assets/client/client4.png
Normal file
|
After Width: | Height: | Size: 152 KiB |
BIN
assets/client/client5.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
assets/client/client6.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
assets/client/clienten1.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
assets/client/clienten2.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
assets/client/clienten3.png
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
assets/client/clienten4.png
Normal file
|
After Width: | Height: | Size: 202 KiB |
BIN
assets/client/clienten5.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
assets/client/clienten6.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
assets/ob/ob1.png
Normal file
|
After Width: | Height: | Size: 153 KiB |
BIN
assets/ob/ob2.png
Normal file
|
After Width: | Height: | Size: 161 KiB |
BIN
assets/ob/ob3.png
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
assets/ob/ob4.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
BIN
assets/ob/ob5.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
assets/ob/oben1.png
Normal file
|
After Width: | Height: | Size: 178 KiB |
BIN
assets/ob/oben2.png
Normal file
|
After Width: | Height: | Size: 149 KiB |
BIN
assets/ob/oben3.png
Normal file
|
After Width: | Height: | Size: 112 KiB |
BIN
assets/ob/oben4.png
Normal file
|
After Width: | Height: | Size: 125 KiB |
BIN
assets/ob/oben5.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
2
dist/css/app.css
vendored
@ -1 +1 @@
|
||||
*{margin:0;padding:0;box-sizing:border-box}#app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#2c3e50}.customScrollbar{&::-webkit-scrollbar{width:7px;height:7px}&::-webkit-scrollbar-thumb{border-radius:7px;background-color:rgba(0,0,0,.3);cursor:pointer}&::-webkit-scrollbar-track{box-shadow:none;background:transparent;display:none}}@font-face{font-family:iconfont;src:url(../fonts/iconfont.woff2) format("woff2"),url(../fonts/iconfont.woff) format("woff"),url(../fonts/iconfont.ttf) format("truetype")}.iconfont{font-family:iconfont!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.iconAIshengcheng:before{content:"\e6b5"}.iconprinting:before{content:"\ea28"}.iconwenjianjia:before{content:"\e614"}.iconcontentleft:before{content:"\e8c9"}.iconjuzhongduiqi:before{content:"\ec80"}.iconfile-excel:before{content:"\e7b7"}.iconfreemind:before{content:"\e97d"}.iconwaikuang:before{content:"\e640"}.iconhighlight:before{content:"\e6b8"}.iconyanshibofang:before{content:"\e648"}.iconfujian:before{content:"\e88a"}.icongeshihua:before{content:"\e7a3"}.iconyuanma:before{content:"\e658"}.icongundongtiao:before{content:"\e670"}.iconxietongwendang:before{content:"\e60d"}.iconTXT:before{content:"\e6e1"}.iconwenjian1:before{content:"\e69f"}.icondodeparent:before{content:"\e70f"}.icongongshi:before{content:"\e617"}.icontouming:before{content:"\e60c"}.iconlieri:before{content:"\e60b"}.iconmoon_line:before{content:"\e745"}.iconsousuo:before{content:"\e693"}.iconjiantouyou:before{content:"\e62d"}.iconbianji1:before{content:"\e60a"}.icondaohang1:before{content:"\e632"}.iconyanjing:before{content:"\e8bf"}.iconwangzhan:before{content:"\e628"}.iconcsdn:before{content:"\e608"}.iconshejiaotubiao-10:before{content:"\e644"}.iconstar:before{content:"\e7df"}.iconfork:before{content:"\e641"}.iconxiazai:before{content:"\e613"}.iconteamwork:before{content:"\e870"}.iconshuiyin:before{content:"\e67a"}.iconxmind:before{content:"\ea57"}.iconmouseR:before{content:"\e6bd"}.iconmouseL:before{content:"\e6c0"}.iconwenjian:before{content:"\e607"}.iconpdf:before{content:"\e740"}.iconPNG:before{content:"\ec18"}.iconSVG:before{content:"\e621"}.iconmarkdown:before{content:"\ec04"}.iconjson:before{content:"\ea42"}.iconlianjiexian:before{content:"\e75b"}.iconbangzhu:before{content:"\e620"}.iconshezhi:before{content:"\e8b7"}.iconwushuju:before{content:"\e643"}.iconzuijinliulan:before{content:"\e62f"}.icon3zuidahua-3:before{content:"\e692"}.iconzuixiaohua:before{content:"\e650"}.iconzuidahua:before{content:"\e651"}.iconguanbi:before{content:"\e652"}.icondiannao:before{content:"\eac0"}.iconzhuye:before{content:"\e65c"}.iconbendi1x:before{content:"\e606"}.iconbeijingyanse:before{content:"\e6f8"}.iconqingchu:before{content:"\e605"}.iconcase:before{content:"\e6c6"}.iconxingzhuang-wenzi:before{content:"\eb99"}.iconzitijiacu:before{content:"\ec83"}.iconzitixiahuaxian:before{content:"\ec85"}.iconzitixieti:before{content:"\ec86"}.iconshanchuxian:before{content:"\e612"}.iconzitiyanse:before{content:"\e854"}.icongithub:before{content:"\e64f"}.iconchoose1:before{content:"\e6c5"}.iconzhuti:before{content:"\e7aa"}.icondaochu1:before{content:"\e63e"}.iconlingcunwei:before{content:"\e657"}.iconexport:before{content:"\e642"}.icondakai:before{content:"\ebdf"}.iconxinjian:before{content:"\e64e"}.iconjianqie:before{content:"\e601"}.iconzhengli:before{content:"\e83b"}.iconfuzhi:before{content:"\e604"}.iconniantie:before{content:"\e63f"}.iconshangyi:before{content:"\e6be"}.iconxiayi:before{content:"\e6bf"}.icongaikuozonglan:before{content:"\e609"}.iconquanxuan:before{content:"\f199"}.icondaoru:before{content:"\e6a3"}.iconhoutui-shi:before{content:"\e656"}.iconqianjin1:before{content:"\e654"}.iconwithdraw:before{content:"\e603"}.iconqianjin:before{content:"\e600"}.iconhuifumoren:before{content:"\e60e"}.iconhuanhang:before{content:"\e61e"}.iconsuoxiao:before{content:"\ec13"}.iconbianji:before{content:"\e626"}.iconfangda:before{content:"\e663"}.iconquanping1:before{content:"\e664"}.icondingwei:before{content:"\e616"}.icondaohang:before{content:"\e611"}.iconjianpan:before{content:"\e64d"}.iconquanping:before{content:"\e602"}.icondaochu:before{content:"\e63d"}.iconbiaoqian:before{content:"\e63c"}.iconflow-Mark:before{content:"\e65b"}.iconchaolianjie:before{content:"\e6f4"}.iconjingzi:before{content:"\e610"}.iconxiaolian:before{content:"\e60f"}.iconimage:before{content:"\e629"}.iconjiegou:before{content:"\e61d"}.iconyangshi:before{content:"\e631"}.iconfuhao-dagangshu:before{content:"\e71f"}.icontianjiazijiedian:before{content:"\e622"}.iconjiedian:before{content:"\e655"}.iconshanchu:before{content:"\e696"}.iconzhankai:before{content:"\e64c"}.iconzhankai1:before{content:"\e673"}
|
||||
*{margin:0;padding:0;box-sizing:border-box}#app{font-family:Avenir,Helvetica,Arial,sans-serif;color:#2c3e50}.customScrollbar::-webkit-scrollbar{width:7px;height:7px}.customScrollbar::-webkit-scrollbar-thumb{border-radius:7px;background-color:rgba(0,0,0,.3);cursor:pointer}.customScrollbar::-webkit-scrollbar-track{box-shadow:none;background:transparent;display:none}.el-dialog{border-radius:10px}@font-face{font-family:iconfont;src:url(../fonts/iconfont.woff2) format("woff2"),url(../fonts/iconfont.woff) format("woff"),url(../fonts/iconfont.ttf) format("truetype")}.iconfont{font-family:iconfont!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.iconAIshengcheng:before{content:"\e6b5"}.iconprinting:before{content:"\ea28"}.iconwenjianjia:before{content:"\e614"}.iconcontentleft:before{content:"\e8c9"}.iconjuzhongduiqi:before{content:"\ec80"}.iconfile-excel:before{content:"\e7b7"}.iconfreemind:before{content:"\e97d"}.iconwaikuang:before{content:"\e640"}.iconhighlight:before{content:"\e6b8"}.iconyanshibofang:before{content:"\e648"}.iconfujian:before{content:"\e88a"}.icongeshihua:before{content:"\e7a3"}.iconyuanma:before{content:"\e658"}.icongundongtiao:before{content:"\e670"}.iconxietongwendang:before{content:"\e60d"}.iconTXT:before{content:"\e6e1"}.iconwenjian1:before{content:"\e69f"}.icondodeparent:before{content:"\e70f"}.icongongshi:before{content:"\e617"}.icontouming:before{content:"\e60c"}.iconlieri:before{content:"\e60b"}.iconmoon_line:before{content:"\e745"}.iconsousuo:before{content:"\e693"}.iconjiantouyou:before{content:"\e62d"}.iconbianji1:before{content:"\e60a"}.icondaohang1:before{content:"\e632"}.iconyanjing:before{content:"\e8bf"}.iconwangzhan:before{content:"\e628"}.iconcsdn:before{content:"\e608"}.iconshejiaotubiao-10:before{content:"\e644"}.iconstar:before{content:"\e7df"}.iconfork:before{content:"\e641"}.iconxiazai:before{content:"\e613"}.iconteamwork:before{content:"\e870"}.iconshuiyin:before{content:"\e67a"}.iconxmind:before{content:"\ea57"}.iconmouseR:before{content:"\e6bd"}.iconmouseL:before{content:"\e6c0"}.iconwenjian:before{content:"\e607"}.iconpdf:before{content:"\e740"}.iconPNG:before{content:"\ec18"}.iconSVG:before{content:"\e621"}.iconmarkdown:before{content:"\ec04"}.iconjson:before{content:"\ea42"}.iconlianjiexian:before{content:"\e75b"}.iconbangzhu:before{content:"\e620"}.iconshezhi:before{content:"\e8b7"}.iconwushuju:before{content:"\e643"}.iconzuijinliulan:before{content:"\e62f"}.icon3zuidahua-3:before{content:"\e692"}.iconzuixiaohua:before{content:"\e650"}.iconzuidahua:before{content:"\e651"}.iconguanbi:before{content:"\e652"}.icondiannao:before{content:"\eac0"}.iconzhuye:before{content:"\e65c"}.iconbendi1x:before{content:"\e606"}.iconbeijingyanse:before{content:"\e6f8"}.iconqingchu:before{content:"\e605"}.iconcase:before{content:"\e6c6"}.iconxingzhuang-wenzi:before{content:"\eb99"}.iconzitijiacu:before{content:"\ec83"}.iconzitixiahuaxian:before{content:"\ec85"}.iconzitixieti:before{content:"\ec86"}.iconshanchuxian:before{content:"\e612"}.iconzitiyanse:before{content:"\e854"}.icongithub:before{content:"\e64f"}.iconchoose1:before{content:"\e6c5"}.iconzhuti:before{content:"\e7aa"}.icondaochu1:before{content:"\e63e"}.iconlingcunwei:before{content:"\e657"}.iconexport:before{content:"\e642"}.icondakai:before{content:"\ebdf"}.iconxinjian:before{content:"\e64e"}.iconjianqie:before{content:"\e601"}.iconzhengli:before{content:"\e83b"}.iconfuzhi:before{content:"\e604"}.iconniantie:before{content:"\e63f"}.iconshangyi:before{content:"\e6be"}.iconxiayi:before{content:"\e6bf"}.icongaikuozonglan:before{content:"\e609"}.iconquanxuan:before{content:"\f199"}.icondaoru:before{content:"\e6a3"}.iconhoutui-shi:before{content:"\e656"}.iconqianjin1:before{content:"\e654"}.iconwithdraw:before{content:"\e603"}.iconqianjin:before{content:"\e600"}.iconhuifumoren:before{content:"\e60e"}.iconhuanhang:before{content:"\e61e"}.iconsuoxiao:before{content:"\ec13"}.iconbianji:before{content:"\e626"}.iconfangda:before{content:"\e663"}.iconquanping1:before{content:"\e664"}.icondingwei:before{content:"\e616"}.icondaohang:before{content:"\e611"}.iconjianpan:before{content:"\e64d"}.iconquanping:before{content:"\e602"}.icondaochu:before{content:"\e63d"}.iconbiaoqian:before{content:"\e63c"}.iconflow-Mark:before{content:"\e65b"}.iconchaolianjie:before{content:"\e6f4"}.iconjingzi:before{content:"\e610"}.iconxiaolian:before{content:"\e60f"}.iconimage:before{content:"\e629"}.iconjiegou:before{content:"\e61d"}.iconyangshi:before{content:"\e631"}.iconfuhao-dagangshu:before{content:"\e71f"}.icontianjiazijiedian:before{content:"\e622"}.iconjiedian:before{content:"\e655"}.iconshanchu:before{content:"\e696"}.iconzhankai:before{content:"\e64c"}.iconzhankai1:before{content:"\e673"}
|
||||
BIN
dist/img/withBg1.jpg
vendored
|
Before Width: | Height: | Size: 51 KiB |
BIN
dist/img/withBg2.jpg
vendored
|
Before Width: | Height: | Size: 28 KiB |
BIN
dist/img/withBg3.jpg
vendored
|
Before Width: | Height: | Size: 48 KiB |
BIN
dist/img/withBg4.jpg
vendored
|
Before Width: | Height: | Size: 23 KiB |
BIN
dist/img/withBg5.jpg
vendored
|
Before Width: | Height: | Size: 20 KiB |
2
dist/js/app.js
vendored
65
dist/js/chunk-183b683c.js
vendored
Normal file
69
dist/js/chunk-27a8e520.js
vendored
8
dist/js/chunk-vendors.js
vendored
@ -9,7 +9,7 @@
|
||||
})
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}</script><link href="dist/css/chunk-vendors.css?b70e90f1bbbbeb12fd74" rel="stylesheet"><link href="dist/css/app.css?b70e90f1bbbbeb12fd74" rel="stylesheet"></head><body><noscript><strong>We're sorry but thoughts doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script>const getDataFromBackend = () => {
|
||||
}</script><link href="dist/css/chunk-vendors.css?227f61428db154a5d9bc" rel="stylesheet"><link href="dist/css/app.css?227f61428db154a5d9bc" rel="stylesheet"></head><body><noscript><strong>We're sorry but thoughts doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script>const getDataFromBackend = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
@ -83,4 +83,4 @@
|
||||
// 可以通过window.$bus.$on()来监听应用的一些事件
|
||||
// 实例化页面
|
||||
window.initApp()
|
||||
}</script><script src="dist/js/chunk-vendors.js?b70e90f1bbbbeb12fd74"></script><script src="dist/js/app.js?b70e90f1bbbbeb12fd74"></script></body></html>
|
||||
}</script><script src="dist/js/chunk-vendors.js?227f61428db154a5d9bc"></script><script src="dist/js/app.js?227f61428db154a5d9bc"></script></body></html>
|
||||
BIN
qrcode.jpg
|
Before Width: | Height: | Size: 41 KiB |
@ -31,7 +31,7 @@ MindMap.markdown = markdown
|
||||
MindMap.iconList = icons.nodeIconList
|
||||
MindMap.constants = constants
|
||||
MindMap.defaultTheme = defaultTheme
|
||||
MindMap.version = '0.14.0'
|
||||
MindMap.version = '0.14.0-fix.1'
|
||||
|
||||
MindMap.usePlugin(MiniMap)
|
||||
.usePlugin(Watermark)
|
||||
|
||||
4
simple-mind-map/package-lock.json
generated
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "simple-mind-map",
|
||||
"version": "0.12.1",
|
||||
"version": "0.14.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "0.12.1",
|
||||
"version": "0.14.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@svgdotjs/svg.js": "3.2.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "simple-mind-map",
|
||||
"version": "0.14.0",
|
||||
"version": "0.14.0-fix.1",
|
||||
"description": "一个简单的web在线思维导图",
|
||||
"authors": [
|
||||
{
|
||||
|
||||
@ -613,6 +613,13 @@ class Render {
|
||||
this.emitNodeActiveEvent()
|
||||
}
|
||||
|
||||
// 当某个自定义节点内容改变后,可以调用该方法实时更新该节点大小和整体节点的定位
|
||||
renderByCustomNodeContentNode(node) {
|
||||
node.getSize()
|
||||
node.customNodeContentRealtimeLayout()
|
||||
this.mindMap.render()
|
||||
}
|
||||
|
||||
// 给当前被收起来的节点数据添加更新标志
|
||||
resetUnExpandNodeStyle() {
|
||||
if (!this.renderTree) return
|
||||
|
||||
@ -32,9 +32,16 @@ const defaultTagStyle = {
|
||||
//width: 30 // 标签矩形的宽度,如果不设置,默认以文字的宽度+paddingX*2为宽度
|
||||
}
|
||||
|
||||
// 获取图片的真实url
|
||||
// 因为如果注册了NodeBase64ImageStorage插件,那么节点图片字段保存的实际是一个id,所以如果要获取图片真实的url可以通过该方法
|
||||
function getImageUrl() {
|
||||
const img = this.getData('image')
|
||||
return (this.mindMap.renderer.renderTree.data.imgMap || {})[img] || img
|
||||
}
|
||||
|
||||
// 创建图片节点
|
||||
function createImgNode() {
|
||||
let img = this.getData('image')
|
||||
const img = this.getImageUrl()
|
||||
if (!img) {
|
||||
return
|
||||
}
|
||||
@ -570,6 +577,7 @@ function isUseCustomNodeContent() {
|
||||
}
|
||||
|
||||
export default {
|
||||
getImageUrl,
|
||||
createImgNode,
|
||||
getImgShowSize,
|
||||
createIconNode,
|
||||
|
||||
@ -33,7 +33,9 @@ function getTagContentSize(space) {
|
||||
function getNodeRect() {
|
||||
// 自定义节点内容
|
||||
if (this.isUseCustomNodeContent()) {
|
||||
const rect = this.measureCustomNodeContentSize(this._customNodeContent)
|
||||
const rect = this.measureCustomNodeContentSize(
|
||||
this._customNodeContent.cloneNode(true)
|
||||
)
|
||||
return {
|
||||
width: this.hasCustomWidth() ? this.customTextWidth : rect.width,
|
||||
height: rect.height
|
||||
@ -178,13 +180,54 @@ function getNodeRect() {
|
||||
}
|
||||
}
|
||||
|
||||
// 激活hover和激活边框
|
||||
function addHoverNode(width, height) {
|
||||
const { hoverRectPadding } = this.mindMap.opt
|
||||
this.hoverNode = new Rect()
|
||||
.size(width + hoverRectPadding * 2, height + hoverRectPadding * 2)
|
||||
.x(-hoverRectPadding)
|
||||
.y(-hoverRectPadding)
|
||||
this.hoverNode.addClass('smm-hover-node')
|
||||
this.style.hoverNode(this.hoverNode, width, height)
|
||||
this.group.add(this.hoverNode)
|
||||
}
|
||||
|
||||
// 当使用了完全自定义节点内容后,可以通过该方法实时更新节点大小
|
||||
function customNodeContentRealtimeLayout() {
|
||||
if (!this.group) return
|
||||
if (!this.isUseCustomNodeContent()) return
|
||||
// 删除除foreignObject外的其他元素
|
||||
if (this.shapeNode) this.shapeNode.remove()
|
||||
if (this._unVisibleRectRegionNode) this._unVisibleRectRegionNode.remove()
|
||||
if (this.hoverNode) this.hoverNode.remove()
|
||||
const { width, height } = this
|
||||
const halfBorderWidth = this.getBorderWidth() / 2
|
||||
// 节点形状
|
||||
this.shapeNode = this.shapeInstance.createShape()
|
||||
this.shapeNode.addClass('smm-node-shape')
|
||||
this.shapeNode.translate(halfBorderWidth, halfBorderWidth)
|
||||
this.style.shape(this.shapeNode)
|
||||
this.group.add(this.shapeNode)
|
||||
// 渲染一个隐藏的矩形区域,用来触发展开收起按钮的显示
|
||||
this.renderExpandBtnPlaceholderRect()
|
||||
// 概要节点添加一个带所属节点id的类名
|
||||
if (this.isGeneralization && this.generalizationBelongNode) {
|
||||
this.group.addClass('generalization_' + this.generalizationBelongNode.uid)
|
||||
}
|
||||
// 激活hover和激活边框
|
||||
this.addHoverNode(width, height)
|
||||
// 将形状元素移至底层,避免遮挡foreignObject
|
||||
this.shapeNode.back()
|
||||
// 更新foreignObject元素大小
|
||||
this.group.findOne('foreignObject').size(width, height)
|
||||
}
|
||||
|
||||
// 定位节点内容
|
||||
function layout() {
|
||||
if (!this.group) return
|
||||
// 清除之前的内容
|
||||
this.group.clear()
|
||||
const {
|
||||
hoverRectPadding,
|
||||
openRealtimeRenderOnNodeTextEdit,
|
||||
textContentMargin,
|
||||
addCustomContentToNode
|
||||
@ -217,16 +260,6 @@ function layout() {
|
||||
if (this.isGeneralization && this.generalizationBelongNode) {
|
||||
this.group.addClass('generalization_' + this.generalizationBelongNode.uid)
|
||||
}
|
||||
// 激活hover和激活边框
|
||||
const addHoverNode = () => {
|
||||
this.hoverNode = new Rect()
|
||||
.size(width + hoverRectPadding * 2, height + hoverRectPadding * 2)
|
||||
.x(-hoverRectPadding)
|
||||
.y(-hoverRectPadding)
|
||||
this.hoverNode.addClass('smm-hover-node')
|
||||
this.style.hoverNode(this.hoverNode, width, height)
|
||||
this.group.add(this.hoverNode)
|
||||
}
|
||||
// 如果存在自定义节点内容,那么使用自定义节点内容
|
||||
if (this.isUseCustomNodeContent()) {
|
||||
const foreignObject = createForeignObjectNode({
|
||||
@ -235,7 +268,7 @@ function layout() {
|
||||
height
|
||||
})
|
||||
this.group.add(foreignObject)
|
||||
addHoverNode()
|
||||
this.addHoverNode(width, height)
|
||||
return
|
||||
}
|
||||
const { IMG_PLACEMENT, TAG_PLACEMENT } = CONSTANTS
|
||||
@ -453,7 +486,7 @@ function layout() {
|
||||
break
|
||||
}
|
||||
textContentNested.translate(translateX, translateY)
|
||||
addHoverNode()
|
||||
this.addHoverNode(width, height)
|
||||
if (this._customContentAddToNodeAdd && this._customContentAddToNodeAdd.el) {
|
||||
const foreignObject = createForeignObjectNode(
|
||||
this._customContentAddToNodeAdd
|
||||
@ -477,5 +510,7 @@ export default {
|
||||
getImgTextMarin,
|
||||
getTagContentSize,
|
||||
getNodeRect,
|
||||
layout
|
||||
addHoverNode,
|
||||
layout,
|
||||
customNodeContentRealtimeLayout
|
||||
}
|
||||
|
||||
@ -174,7 +174,8 @@ class Base {
|
||||
isResizeSource ||
|
||||
isNodeDataChange ||
|
||||
isLayerTypeChange ||
|
||||
newNode.getData('resetRichText') ||
|
||||
(newNode.getData('resetRichText') && // 自定义节点内容可以直接忽略resetRichText
|
||||
!newNode.isUseCustomNodeContent()) ||
|
||||
newNode.getData('needUpdate') ||
|
||||
isNodeInnerFixChange
|
||||
) {
|
||||
@ -224,7 +225,8 @@ class Base {
|
||||
isResizeSource ||
|
||||
isNodeDataChange ||
|
||||
isLayerTypeChange ||
|
||||
newNode.getData('resetRichText') ||
|
||||
(newNode.getData('resetRichText') &&
|
||||
!newNode.isUseCustomNodeContent()) ||
|
||||
newNode.getData('needUpdate') ||
|
||||
isNodeInnerFixChange
|
||||
) {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { fromMarkdown } from 'mdast-util-from-markdown'
|
||||
|
||||
const getNodeText = node => {
|
||||
if (node.type === 'list') return ''
|
||||
let textStr = ''
|
||||
|
||||
;(node.children || []).forEach(item => {
|
||||
|
||||
@ -43,6 +43,18 @@ class Demonstrate {
|
||||
this.mindMap.opt.demonstrateConfig || {}
|
||||
)
|
||||
this.needRestorePerformanceMode = false
|
||||
this.onConfigUpdate = this.onConfigUpdate.bind(this)
|
||||
this.mindMap.on('after_update_config', this.onConfigUpdate)
|
||||
}
|
||||
|
||||
// 监听配置更新
|
||||
onConfigUpdate(opt) {
|
||||
if (typeof opt.demonstrateConfig !== 'undefined') {
|
||||
this.config = {
|
||||
...this.config,
|
||||
...opt.demonstrateConfig
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 进入演示模式
|
||||
@ -417,11 +429,13 @@ class Demonstrate {
|
||||
// 插件被移除前做的事情
|
||||
beforePluginRemove() {
|
||||
this.unBindEvent()
|
||||
this.mindMap.off('after_update_config', this.onConfigUpdate)
|
||||
}
|
||||
|
||||
// 插件被卸载前做的事情
|
||||
beforePluginDestroy() {
|
||||
this.unBindEvent()
|
||||
this.mindMap.off('after_update_config', this.onConfigUpdate)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -144,6 +144,7 @@ class Export {
|
||||
try {
|
||||
const canvas = document.createElement('canvas')
|
||||
const dpr = Math.max(window.devicePixelRatio, minExportImgCanvasScale)
|
||||
// 图片原始大小
|
||||
let imgWidth = img.width
|
||||
let imgHeight = img.height
|
||||
// 如果是裁减操作的话,那么需要手动添加内边距,及调整图片大小为实际的裁减区域的大小,不要忘了内边距哦
|
||||
@ -184,6 +185,8 @@ class Export {
|
||||
}
|
||||
// 检查是否超出canvas支持的像素上限
|
||||
// canvas大小需要乘以dpr
|
||||
let scaleX = 1
|
||||
let scaleY = 1
|
||||
let canvasWidth = (fitBgImgWidth || imgWidth) * dpr
|
||||
let canvasHeight = (fitBgImgHeight || imgHeight) * dpr
|
||||
if (canvasWidth > maxCanvasSize || canvasHeight > maxCanvasSize) {
|
||||
@ -203,6 +206,8 @@ class Export {
|
||||
newWidth,
|
||||
newHeight
|
||||
)
|
||||
scaleX = res[0] / canvasWidth
|
||||
scaleY = res[1] / canvasHeight
|
||||
canvasWidth = res[0]
|
||||
canvasHeight = res[1]
|
||||
}
|
||||
@ -210,6 +215,7 @@ class Export {
|
||||
canvas.height = canvasHeight
|
||||
const styleWidth = canvasWidth / dpr
|
||||
const styleHeight = canvasHeight / dpr
|
||||
// canvas元素实际上的大小
|
||||
canvas.style.width = styleWidth + 'px'
|
||||
canvas.style.height = styleHeight + 'px'
|
||||
const ctx = canvas.getContext('2d')
|
||||
@ -221,9 +227,9 @@ class Export {
|
||||
// 图片绘制到canvas里
|
||||
// 如果有裁减数据,那么需要进行裁减
|
||||
const fitBgLeft =
|
||||
fitBgImgWidth > 0 ? (fitBgImgWidth - imgWidth) / 2 : 0
|
||||
(fitBgImgWidth > 0 ? (fitBgImgWidth - imgWidth) / 2 : 0) * scaleX
|
||||
const fitBgTop =
|
||||
fitBgImgHeight > 0 ? (fitBgImgHeight - imgHeight) / 2 : 0
|
||||
(fitBgImgHeight > 0 ? (fitBgImgHeight - imgHeight) / 2 : 0) * scaleY
|
||||
if (clipData) {
|
||||
ctx.drawImage(
|
||||
img,
|
||||
@ -231,13 +237,19 @@ class Export {
|
||||
clipData.top,
|
||||
clipData.width,
|
||||
clipData.height,
|
||||
paddingX + fitBgLeft,
|
||||
paddingY + fitBgTop,
|
||||
clipData.width,
|
||||
clipData.height
|
||||
paddingX * scaleX + fitBgLeft,
|
||||
paddingY * scaleY + fitBgTop,
|
||||
clipData.width * scaleX,
|
||||
clipData.height * scaleY
|
||||
)
|
||||
} else {
|
||||
ctx.drawImage(img, fitBgLeft, fitBgTop, imgWidth, imgHeight)
|
||||
ctx.drawImage(
|
||||
img,
|
||||
fitBgLeft,
|
||||
fitBgTop,
|
||||
imgWidth * scaleX,
|
||||
imgHeight * scaleY
|
||||
)
|
||||
}
|
||||
resolve(canvas.toDataURL(format))
|
||||
} catch (error) {
|
||||
|
||||
@ -491,7 +491,10 @@ class RichText {
|
||||
})
|
||||
this.quill.on('selection-change', range => {
|
||||
// 刚创建的节点全选不需要显示操作条
|
||||
if (this.isInserting) return
|
||||
if (this.isInserting) {
|
||||
this.isInserting = false
|
||||
return
|
||||
}
|
||||
this.lastRange = this.range
|
||||
this.range = null
|
||||
if (range) {
|
||||
|
||||
11
web/package-lock.json
generated
@ -15699,8 +15699,7 @@
|
||||
"node_modules/viewerjs": {
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/viewerjs/-/viewerjs-1.11.6.tgz",
|
||||
"integrity": "sha512-TlhdSp2oEOLFXvEp4psKaeTjR5zBjTRcM/sHUN8PkV1UWuY8HKC8n7GaVdW5Xqnwdr/F1OmzLik1QwDjI4w/nw==",
|
||||
"peer": true
|
||||
"integrity": "sha512-TlhdSp2oEOLFXvEp4psKaeTjR5zBjTRcM/sHUN8PkV1UWuY8HKC8n7GaVdW5Xqnwdr/F1OmzLik1QwDjI4w/nw=="
|
||||
},
|
||||
"node_modules/vm-browserify": {
|
||||
"version": "1.1.2",
|
||||
@ -19258,6 +19257,7 @@
|
||||
"integrity": "sha512-VCNRiAt2P/bLo09rYt3DLe6xXUMlhJwrvU18Ddd/lYJgC7s8+wvhgYs+MTx4OiAXdu58drGwSBO9SPx7C6J82Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/core": "^7.11.0",
|
||||
"@babel/helper-compilation-targets": "^7.9.6",
|
||||
"@babel/helper-module-imports": "^7.8.3",
|
||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||
@ -19270,6 +19270,7 @@
|
||||
"@vue/babel-plugin-jsx": "^1.0.3",
|
||||
"@vue/babel-preset-jsx": "^1.2.4",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||
"core-js": "^3.6.5",
|
||||
"core-js-compat": "^3.6.5",
|
||||
"semver": "^6.1.0"
|
||||
}
|
||||
@ -29565,7 +29566,8 @@
|
||||
"resolved": "https://registry.npmjs.org/v-viewer/-/v-viewer-1.7.4.tgz",
|
||||
"integrity": "sha512-K3PQ8utnVXXBCa5IRXRAhk/m83fNIsK77gTSXqAmPJe8eDTaSY1nifAOWPUmQDjzuCxYfa14UjGftHR9MFV70Q==",
|
||||
"requires": {
|
||||
"lodash-es": "^4.17.21"
|
||||
"lodash-es": "^4.17.21",
|
||||
"viewerjs": "^1.11.6"
|
||||
}
|
||||
},
|
||||
"v8-compile-cache": {
|
||||
@ -29630,8 +29632,7 @@
|
||||
"viewerjs": {
|
||||
"version": "1.11.6",
|
||||
"resolved": "https://registry.npmjs.org/viewerjs/-/viewerjs-1.11.6.tgz",
|
||||
"integrity": "sha512-TlhdSp2oEOLFXvEp4psKaeTjR5zBjTRcM/sHUN8PkV1UWuY8HKC8n7GaVdW5Xqnwdr/F1OmzLik1QwDjI4w/nw==",
|
||||
"peer": true
|
||||
"integrity": "sha512-TlhdSp2oEOLFXvEp4psKaeTjR5zBjTRcM/sHUN8PkV1UWuY8HKC8n7GaVdW5Xqnwdr/F1OmzLik1QwDjI4w/nw=="
|
||||
},
|
||||
"vm-browserify": {
|
||||
"version": "1.1.2",
|
||||
|
||||
@ -1,53 +1,81 @@
|
||||
const express = require('express')
|
||||
const axios = require('axios')
|
||||
const net = require('net')
|
||||
|
||||
const port = 3456
|
||||
|
||||
// 起个服务
|
||||
const app = express()
|
||||
app.use(express.json())
|
||||
app.use(express.urlencoded({ extended: true }))
|
||||
|
||||
// 允许跨域
|
||||
app.use((req, res, next) => {
|
||||
res.header('Access-Control-Allow-Origin', '*') // 允许所有来源的跨域请求,或者指定一个域名
|
||||
res.header('Access-Control-Allow-Methods', '*') // 允许的方法
|
||||
res.header('Access-Control-Allow-Headers', '*') // 允许的头部信息
|
||||
next()
|
||||
})
|
||||
|
||||
// 监听对话请求
|
||||
app.get('/ai/test', (req, res) => {
|
||||
res
|
||||
.json({
|
||||
code: 0,
|
||||
data: null,
|
||||
msg: '连接成功'
|
||||
const isPortUsed = port => {
|
||||
return new Promise(resolve => {
|
||||
const server = net.createServer()
|
||||
server.once('error', err => {
|
||||
if (err.code === 'EADDRINUSE') {
|
||||
resolve(true) // 端口被占用
|
||||
} else {
|
||||
resolve(false) // 其他错误
|
||||
}
|
||||
})
|
||||
.end()
|
||||
})
|
||||
app.post('/ai/chat', async (req, res, next) => {
|
||||
// 设置SSE响应头
|
||||
res.setHeader('Content-Type', 'text/event-stream')
|
||||
res.setHeader('Cache-Control', 'no-cache')
|
||||
res.setHeader('Connection', 'keep-alive')
|
||||
|
||||
const { api, method = 'POST', headers = {}, data } = req.body
|
||||
|
||||
try {
|
||||
const response = await axios({
|
||||
url: api,
|
||||
method,
|
||||
headers,
|
||||
data,
|
||||
responseType: 'stream'
|
||||
server.once('listening', () => {
|
||||
server.close(() => resolve(false)) // 端口可用
|
||||
})
|
||||
response.data.pipe(res)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
server.listen(port) // 尝试监听端口
|
||||
})
|
||||
}
|
||||
|
||||
const createServe = () => {
|
||||
// 起个服务
|
||||
const app = express()
|
||||
app.use(express.json())
|
||||
app.use(express.urlencoded({ extended: true }))
|
||||
|
||||
// 允许跨域
|
||||
app.use((req, res, next) => {
|
||||
res.header('Access-Control-Allow-Origin', '*') // 允许所有来源的跨域请求,或者指定一个域名
|
||||
res.header('Access-Control-Allow-Methods', '*') // 允许的方法
|
||||
res.header('Access-Control-Allow-Headers', '*') // 允许的头部信息
|
||||
next()
|
||||
})
|
||||
|
||||
// 监听对话请求
|
||||
app.get('/ai/test', (req, res) => {
|
||||
res
|
||||
.json({
|
||||
code: 0,
|
||||
data: null,
|
||||
msg: '连接成功'
|
||||
})
|
||||
.end()
|
||||
})
|
||||
app.post('/ai/chat', async (req, res, next) => {
|
||||
// 设置SSE响应头
|
||||
res.setHeader('Content-Type', 'text/event-stream')
|
||||
res.setHeader('Cache-Control', 'no-cache')
|
||||
res.setHeader('Connection', 'keep-alive')
|
||||
|
||||
const { api, method = 'POST', headers = {}, data } = req.body
|
||||
|
||||
try {
|
||||
const response = await axios({
|
||||
url: api,
|
||||
method,
|
||||
headers,
|
||||
data,
|
||||
responseType: 'stream'
|
||||
})
|
||||
response.data.pipe(res)
|
||||
} catch (error) {
|
||||
next(error)
|
||||
}
|
||||
})
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`app listening on port ${port}`)
|
||||
})
|
||||
}
|
||||
|
||||
isPortUsed(port).then(isUsed => {
|
||||
if (isUsed) {
|
||||
console.error('端口被占用')
|
||||
} else {
|
||||
createServe()
|
||||
}
|
||||
})
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`app listening on port ${port}`)
|
||||
})
|
||||
|
||||
@ -10,7 +10,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<style lang="less">
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@ -18,8 +18,6 @@ export default {
|
||||
}
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
@ -41,4 +39,8 @@ export default {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.el-dialog{
|
||||
border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
BIN
web/src/assets/avatar/行.jpg
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
web/src/assets/img/foramt/1.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
web/src/assets/img/foramt/10.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
web/src/assets/img/foramt/2.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
web/src/assets/img/foramt/3.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
web/src/assets/img/foramt/4.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
web/src/assets/img/foramt/5.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
web/src/assets/img/foramt/6.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
web/src/assets/img/foramt/7.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
web/src/assets/img/foramt/8.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
web/src/assets/img/foramt/9.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
web/src/assets/img/gzh.jpeg
Normal file
|
After Width: | Height: | Size: 39 KiB |
@ -439,38 +439,32 @@ export const sidebarTriggerList = [
|
||||
value: 'outline',
|
||||
icon: 'iconfuhao-dagangshu'
|
||||
},
|
||||
// {
|
||||
// name: 'AI',
|
||||
// value: 'ai',
|
||||
// icon: 'iconAIshengcheng'
|
||||
// },
|
||||
{
|
||||
name: 'Setting',
|
||||
value: 'setting',
|
||||
icon: 'iconshezhi'
|
||||
},
|
||||
{
|
||||
name: 'AI',
|
||||
value: 'ai',
|
||||
icon: 'iconAIshengcheng'
|
||||
},
|
||||
{
|
||||
name: 'ShortcutKey',
|
||||
value: 'shortcutKey',
|
||||
icon: 'iconjianpan'
|
||||
}
|
||||
// {
|
||||
// name: 'ShortcutKey',
|
||||
// value: 'shortcutKey',
|
||||
// icon: 'iconjianpan'
|
||||
// }
|
||||
]
|
||||
|
||||
// 下载类型列表
|
||||
export const downTypeList = [
|
||||
{
|
||||
name: 'Dedicated file',
|
||||
name: '思绪 file',
|
||||
type: 'smm',
|
||||
icon: 'iconwenjian',
|
||||
desc:
|
||||
'SimpleMindMap private format, can be used for re import, and the client can directly edit it'
|
||||
},
|
||||
{
|
||||
name: 'JSON',
|
||||
type: 'json',
|
||||
icon: 'iconjson',
|
||||
desc: 'Popular data exchange format that can be used for re importing'
|
||||
},
|
||||
{
|
||||
name: 'Image',
|
||||
type: 'png',
|
||||
@ -507,6 +501,12 @@ export const downTypeList = [
|
||||
icon: 'iconTXT',
|
||||
desc: 'Plain text file'
|
||||
},
|
||||
{
|
||||
name: 'Excel',
|
||||
type: 'xlsx',
|
||||
icon: 'iconfile-excel',
|
||||
desc: 'Table text format, editable with Excel software'
|
||||
},
|
||||
{
|
||||
name: 'FreeMind',
|
||||
type: 'mm',
|
||||
@ -514,11 +514,11 @@ export const downTypeList = [
|
||||
desc: 'FreeMind software format'
|
||||
},
|
||||
{
|
||||
name: 'Excel',
|
||||
type: 'xlsx',
|
||||
icon: 'iconfile-excel',
|
||||
desc: 'Table text format, editable with Excel software'
|
||||
}
|
||||
name: 'JSON',
|
||||
type: 'json',
|
||||
icon: 'iconjson',
|
||||
desc: 'Popular data exchange format that can be used for re importing'
|
||||
},
|
||||
]
|
||||
|
||||
// 编号类型列表
|
||||
@ -672,13 +672,11 @@ export const layoutGroupList = [
|
||||
list: [
|
||||
'timeline',
|
||||
'timeline2',
|
||||
'verticalTimeline2',
|
||||
'verticalTimeline3',
|
||||
'verticalTimeline'
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Fishbone',
|
||||
list: ['fishbone', 'fishbone2', 'rightFishbone', 'rightFishbone2']
|
||||
list: ['fishbone']
|
||||
}
|
||||
]
|
||||
|
||||
@ -7,6 +7,8 @@ import {
|
||||
lineHeightList,
|
||||
store,
|
||||
langList,
|
||||
shapeListMap,
|
||||
lineStyleMap,
|
||||
fontFamilyList as fontFamilyListZh,
|
||||
borderDasharrayList as borderDasharrayListZh,
|
||||
lineStyleList as lineStyleListZh,
|
||||
@ -18,8 +20,6 @@ import {
|
||||
sidebarTriggerList as sidebarTriggerListZh,
|
||||
backgroundSizeList as backgroundSizeListZh,
|
||||
downTypeList as downTypeListZh,
|
||||
shapeListMap as shapeListMapZh,
|
||||
lineStyleMap as lineStyleMapZh,
|
||||
numberTypeList as numberTypeListZh,
|
||||
numberLevelList as numberLevelListZh,
|
||||
linearGradientDirList as linearGradientDirListZh,
|
||||
@ -62,113 +62,135 @@ import {
|
||||
alignList as alignListZhtw,
|
||||
layoutGroupList as layoutGroupListZhtw
|
||||
} from './zhtw'
|
||||
import {
|
||||
fontFamilyList as fontFamilyListVi,
|
||||
borderDasharrayList as borderDasharrayListVi,
|
||||
lineStyleList as lineStyleListVi,
|
||||
rootLineKeepSameInCurveList as rootLineKeepSameInCurveListVi,
|
||||
backgroundRepeatList as backgroundRepeatListVi,
|
||||
backgroundPositionList as backgroundPositionListVi,
|
||||
shortcutKeyList as shortcutKeyListVi,
|
||||
shapeList as shapeListVi,
|
||||
sidebarTriggerList as sidebarTriggerListVi,
|
||||
backgroundSizeList as backgroundSizeListVi,
|
||||
downTypeList as downTypeListVi,
|
||||
numberTypeList as numberTypeListVi,
|
||||
numberLevelList as numberLevelListVi,
|
||||
linearGradientDirList as linearGradientDirListVi,
|
||||
alignList as alignListVi,
|
||||
layoutGroupList as layoutGroupListVi
|
||||
} from './vi'
|
||||
|
||||
const fontFamilyList = {
|
||||
zh: fontFamilyListZh,
|
||||
en: fontFamilyListEn,
|
||||
zhtw: fontFamilyListZhtw
|
||||
zhtw: fontFamilyListZhtw,
|
||||
vi: fontFamilyListVi
|
||||
}
|
||||
|
||||
const borderDasharrayList = {
|
||||
zh: borderDasharrayListZh,
|
||||
en: borderDasharrayListEn,
|
||||
zhtw: borderDasharrayListZhtw
|
||||
zhtw: borderDasharrayListZhtw,
|
||||
vi: borderDasharrayListVi
|
||||
}
|
||||
|
||||
const lineStyleList = {
|
||||
zh: lineStyleListZh,
|
||||
en: lineStyleListEn,
|
||||
zhtw: lineStyleListZhtw
|
||||
}
|
||||
|
||||
const lineStyleMap = {
|
||||
zh: lineStyleMapZh,
|
||||
en: lineStyleMapZh,
|
||||
zhtw: lineStyleMapZh
|
||||
zhtw: lineStyleListZhtw,
|
||||
vi: lineStyleListVi
|
||||
}
|
||||
|
||||
const rootLineKeepSameInCurveList = {
|
||||
zh: rootLineKeepSameInCurveListZh,
|
||||
en: rootLineKeepSameInCurveListEn,
|
||||
zhtw: rootLineKeepSameInCurveListZhtw
|
||||
zhtw: rootLineKeepSameInCurveListZhtw,
|
||||
vi: rootLineKeepSameInCurveListVi
|
||||
}
|
||||
|
||||
const backgroundRepeatList = {
|
||||
zh: backgroundRepeatListZh,
|
||||
en: backgroundRepeatListEn,
|
||||
zhtw: backgroundRepeatListZhtw
|
||||
zhtw: backgroundRepeatListZhtw,
|
||||
vi: backgroundRepeatListVi
|
||||
}
|
||||
|
||||
const backgroundPositionList = {
|
||||
zh: backgroundPositionListZh,
|
||||
en: backgroundPositionListEn,
|
||||
zhtw: backgroundPositionListZhtw
|
||||
zhtw: backgroundPositionListZhtw,
|
||||
vi: backgroundPositionListVi
|
||||
}
|
||||
|
||||
const backgroundSizeList = {
|
||||
zh: backgroundSizeListZh,
|
||||
en: backgroundSizeListEn,
|
||||
zhtw: backgroundSizeListZhtw
|
||||
zhtw: backgroundSizeListZhtw,
|
||||
vi: backgroundSizeListVi
|
||||
}
|
||||
|
||||
const shortcutKeyList = {
|
||||
zh: shortcutKeyListZh,
|
||||
en: shortcutKeyListEn,
|
||||
zhtw: shortcutKeyListZhtw
|
||||
zhtw: shortcutKeyListZhtw,
|
||||
vi: shortcutKeyListVi
|
||||
}
|
||||
|
||||
const shapeList = {
|
||||
zh: shapeListZh,
|
||||
en: shapeListEn,
|
||||
zhtw: shapeListZhtw
|
||||
}
|
||||
|
||||
const shapeListMap = {
|
||||
zh: shapeListMapZh,
|
||||
en: shapeListMapZh,
|
||||
zhtw: shapeListMapZh
|
||||
zhtw: shapeListZhtw,
|
||||
vi: shapeListVi
|
||||
}
|
||||
|
||||
const sidebarTriggerList = {
|
||||
zh: sidebarTriggerListZh,
|
||||
en: sidebarTriggerListEn,
|
||||
zhtw: sidebarTriggerListZhtw
|
||||
zhtw: sidebarTriggerListZhtw,
|
||||
vi: sidebarTriggerListVi
|
||||
}
|
||||
|
||||
const downTypeList = {
|
||||
zh: downTypeListZh,
|
||||
en: downTypeListEn,
|
||||
zhtw: downTypeListZhtw
|
||||
zhtw: downTypeListZhtw,
|
||||
vi: downTypeListVi
|
||||
}
|
||||
|
||||
const numberTypeList = {
|
||||
zh: numberTypeListZh,
|
||||
en: numberTypeListEn,
|
||||
zhtw: numberTypeListZhtw
|
||||
zhtw: numberTypeListZhtw,
|
||||
vi: numberTypeListVi
|
||||
}
|
||||
|
||||
const numberLevelList = {
|
||||
zh: numberLevelListZh,
|
||||
en: numberLevelListEn,
|
||||
zhtw: numberLevelListZhtw
|
||||
zhtw: numberLevelListZhtw,
|
||||
vi: numberLevelListVi
|
||||
}
|
||||
|
||||
const linearGradientDirList = {
|
||||
zh: linearGradientDirListZh,
|
||||
en: linearGradientDirListEn,
|
||||
zhtw: linearGradientDirListZhtw
|
||||
zhtw: linearGradientDirListZhtw,
|
||||
vi: linearGradientDirListVi
|
||||
}
|
||||
|
||||
const alignList = {
|
||||
zh: alignListZh,
|
||||
en: alignListEn,
|
||||
zhtw: alignListZhtw
|
||||
zhtw: alignListZhtw,
|
||||
vi: alignListVi
|
||||
}
|
||||
|
||||
const layoutGroupList = {
|
||||
zh: layoutGroupListZh,
|
||||
en: layoutGroupListEn,
|
||||
zhtw: layoutGroupListZhtw
|
||||
zhtw: layoutGroupListZhtw,
|
||||
vi: layoutGroupListVi
|
||||
}
|
||||
|
||||
export {
|
||||
|
||||
705
web/src/config/vi.js
Normal file
@ -0,0 +1,705 @@
|
||||
// Danh sách phông chữ
|
||||
export const fontFamilyList = [
|
||||
{
|
||||
name: 'Song Thân',
|
||||
value: '宋体, SimSun, Songti SC'
|
||||
},
|
||||
{
|
||||
name: 'Microsoft và Yahoo',
|
||||
value: '微软雅黑, Microsoft YaHei'
|
||||
},
|
||||
{
|
||||
name: 'Chữ Khải',
|
||||
value: '楷体, 楷体_GB2312, SimKai, STKaiti'
|
||||
},
|
||||
{
|
||||
name: 'Da đen',
|
||||
value: '黑体, SimHei, Heiti SC'
|
||||
},
|
||||
{
|
||||
name: 'Lệ Thư',
|
||||
value: '隶书, SimLi'
|
||||
},
|
||||
{
|
||||
name: 'Andale Mono',
|
||||
value: 'andale mono'
|
||||
},
|
||||
{
|
||||
name: 'Arial',
|
||||
value: 'arial, helvetica, sans-serif'
|
||||
},
|
||||
{
|
||||
name: 'arialBlack',
|
||||
value: 'arial black, avant garde'
|
||||
},
|
||||
{
|
||||
name: 'Comic Sans Ms',
|
||||
value: 'comic sans ms'
|
||||
},
|
||||
{
|
||||
name: 'Impact',
|
||||
value: 'impact, chicago'
|
||||
},
|
||||
{
|
||||
name: 'Times New Roman',
|
||||
value: 'times new roman'
|
||||
},
|
||||
{
|
||||
name: 'Sans-Serif',
|
||||
value: 'sans-serif'
|
||||
},
|
||||
{
|
||||
name: 'serif',
|
||||
value: 'serif'
|
||||
}
|
||||
]
|
||||
|
||||
// Kiểu viền
|
||||
export const borderDasharrayList = [
|
||||
{
|
||||
name: 'Dòng rắn',
|
||||
value: 'none'
|
||||
},
|
||||
{
|
||||
name: 'Đường chấm 1',
|
||||
value: '5,5'
|
||||
},
|
||||
{
|
||||
name: 'Đường chấm 2',
|
||||
value: '10,10'
|
||||
},
|
||||
{
|
||||
name: 'Đường chấm 3',
|
||||
value: '20,10,5,5,5,10'
|
||||
},
|
||||
{
|
||||
name: 'Đường chấm 4',
|
||||
value: '5,5,1,5'
|
||||
},
|
||||
{
|
||||
name: 'Đường chấm 5',
|
||||
value: '15,10,5,10,15'
|
||||
},
|
||||
{
|
||||
name: 'Đường chấm 6',
|
||||
value: '1,5'
|
||||
},
|
||||
{
|
||||
name: 'Đường chấm 7',
|
||||
value: '6,4'
|
||||
}
|
||||
]
|
||||
|
||||
// Kiểu kết nối
|
||||
export const lineStyleList = [
|
||||
{
|
||||
name: 'Đường thẳng',
|
||||
value: 'straight'
|
||||
},
|
||||
{
|
||||
name: 'Đường cong',
|
||||
value: 'curve'
|
||||
},
|
||||
{
|
||||
name: 'Trực tiếp',
|
||||
value: 'direct'
|
||||
}
|
||||
]
|
||||
|
||||
// Trong một kiểu đường cong, kiểu nút gốc có giống với các nút khác hay không
|
||||
export const rootLineKeepSameInCurveList = [
|
||||
{
|
||||
name: 'ngoặc đơn',
|
||||
value: false
|
||||
},
|
||||
{
|
||||
name: 'ngoặc nhọn',
|
||||
value: true
|
||||
}
|
||||
]
|
||||
|
||||
// Cách lặp lại hình ảnh
|
||||
export const backgroundRepeatList = [
|
||||
{
|
||||
name: 'Không lặp lại',
|
||||
value: 'no-repeat'
|
||||
},
|
||||
{
|
||||
name: 'Lặp lại',
|
||||
value: 'repeat'
|
||||
},
|
||||
{
|
||||
name: 'Lặp lại hướng ngang',
|
||||
value: 'repeat-x'
|
||||
},
|
||||
{
|
||||
name: 'Lặp lại theo chiều dọc',
|
||||
value: 'repeat-y'
|
||||
}
|
||||
]
|
||||
|
||||
// Định vị ảnh nền
|
||||
export const backgroundPositionList = [
|
||||
{
|
||||
name: 'Mặc định',
|
||||
value: '0% 0%'
|
||||
},
|
||||
{
|
||||
name: 'Trái trên',
|
||||
value: 'left top'
|
||||
},
|
||||
{
|
||||
name: 'Trái giữa',
|
||||
value: 'left center'
|
||||
},
|
||||
{
|
||||
name: 'Trái dưới',
|
||||
value: 'left bottom'
|
||||
},
|
||||
{
|
||||
name: 'Phải trên',
|
||||
value: 'right top'
|
||||
},
|
||||
{
|
||||
name: 'Phải giữa',
|
||||
value: 'right center'
|
||||
},
|
||||
{
|
||||
name: 'Dưới bên phải',
|
||||
value: 'right bottom'
|
||||
},
|
||||
{
|
||||
name: 'Giữa trên',
|
||||
value: 'center top'
|
||||
},
|
||||
{
|
||||
name: 'Ở giữa',
|
||||
value: 'center center'
|
||||
},
|
||||
{
|
||||
name: 'Dưới',
|
||||
value: 'center bottom'
|
||||
}
|
||||
]
|
||||
|
||||
// Cỡ ảnh nền
|
||||
export const backgroundSizeList = [
|
||||
{
|
||||
name: 'Tự động',
|
||||
value: 'auto'
|
||||
},
|
||||
{
|
||||
name: 'Ghi đè',
|
||||
value: 'cover'
|
||||
},
|
||||
{
|
||||
name: 'Giữ',
|
||||
value: 'contain'
|
||||
}
|
||||
]
|
||||
|
||||
// Lưu trữ dữ liệu
|
||||
export const store = {
|
||||
sidebarZIndex: 1 //Thanh bên zIndex
|
||||
}
|
||||
const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0
|
||||
const ctrl = isMac ? '⌘' : 'Ctrl'
|
||||
const enter = isMac ? 'Return' : 'Enter'
|
||||
const macFn = isMac ? 'fn + ' : ''
|
||||
|
||||
// Danh sách phím tắt
|
||||
export const shortcutKeyList = [
|
||||
{
|
||||
type: 'Hoạt động nút',
|
||||
list: [
|
||||
{
|
||||
icon: 'icontianjiazijiedian',
|
||||
name: 'Chèn nút thấp hơn',
|
||||
value: 'Tab | Insert'
|
||||
},
|
||||
{
|
||||
icon: 'iconjiedian',
|
||||
name: 'Chèn nút ngang hàng',
|
||||
value: enter
|
||||
},
|
||||
{
|
||||
icon: 'icondodeparent',
|
||||
name: 'Chèn nút cha',
|
||||
value: 'Shift + Tab'
|
||||
},
|
||||
{
|
||||
icon: 'iconshangyi',
|
||||
name: 'Chuyển nút lên',
|
||||
value: `${ctrl} + ↑`
|
||||
},
|
||||
{
|
||||
icon: 'iconxiayi',
|
||||
name: 'Di chuyển nút xuống',
|
||||
value: `${ctrl} + ↓`
|
||||
},
|
||||
{
|
||||
icon: 'icongaikuozonglan',
|
||||
name: 'Chèn tóm tắt',
|
||||
value: `${ctrl} + G`
|
||||
},
|
||||
{
|
||||
icon: 'iconzhankai',
|
||||
name: 'Mở rộng/thu gọn các nút',
|
||||
value: '/'
|
||||
},
|
||||
{
|
||||
icon: 'iconshanchu',
|
||||
name: 'Xóa nút',
|
||||
value: 'Delete | Backspace'
|
||||
},
|
||||
{
|
||||
icon: 'iconshanchu',
|
||||
name: 'Chỉ xóa nút hiện tại',
|
||||
value: 'Shift + Backspace'
|
||||
},
|
||||
{
|
||||
icon: 'iconfuzhi',
|
||||
name: 'Sao chép nút',
|
||||
value: `${ctrl} + C`
|
||||
},
|
||||
{
|
||||
icon: 'iconjianqie',
|
||||
name: 'Cắt nút',
|
||||
value: `${ctrl} + X`
|
||||
},
|
||||
{
|
||||
icon: 'iconniantie',
|
||||
name: 'Dán nút',
|
||||
value: `${ctrl} + V`
|
||||
},
|
||||
{
|
||||
icon: 'iconbianji',
|
||||
name: 'Sửa nút',
|
||||
value: macFn + 'F2'
|
||||
},
|
||||
{
|
||||
icon: 'iconhuanhang',
|
||||
name: 'Dòng mới',
|
||||
value: `Shift + ${enter}`
|
||||
},
|
||||
{
|
||||
icon: 'iconhoutui-shi',
|
||||
name: 'Lùi lại',
|
||||
value: `${ctrl} + Z`
|
||||
},
|
||||
{
|
||||
icon: 'iconqianjin1',
|
||||
name: 'Tiến lên!',
|
||||
value: `${ctrl} + Y`
|
||||
},
|
||||
{
|
||||
icon: 'iconquanxuan',
|
||||
name: 'Chọn tất cả',
|
||||
value: `${ctrl} + A`
|
||||
},
|
||||
{
|
||||
icon: 'iconquanxuan',
|
||||
name: 'Nhiều lựa chọn',
|
||||
value: `Phải / ${ctrl} + Trái`
|
||||
},
|
||||
{
|
||||
icon: 'iconzhengli',
|
||||
name: 'Name',
|
||||
value: `${ctrl} + L`
|
||||
},
|
||||
{
|
||||
icon: 'iconsousuo',
|
||||
name: 'Tìm kiếm và thay thế',
|
||||
value: `${ctrl} + F`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'Hoạt động Canvas',
|
||||
list: [
|
||||
{
|
||||
icon: 'iconfangda',
|
||||
name: 'Phóng to',
|
||||
value: `${ctrl} + +`
|
||||
},
|
||||
{
|
||||
icon: 'iconsuoxiao',
|
||||
name: 'Thu nhỏ',
|
||||
value: `${ctrl} + -`
|
||||
},
|
||||
{
|
||||
icon: 'iconfangda',
|
||||
name: 'Phóng to/Thu nhỏ',
|
||||
value: `${ctrl} + Cuộn chuột`
|
||||
},
|
||||
{
|
||||
icon: 'icondingwei',
|
||||
name: 'Trở lại Root Node',
|
||||
value: `${ctrl} + ${enter}`
|
||||
},
|
||||
{
|
||||
icon: 'iconquanping1',
|
||||
name: 'Thích nghi với Canvas',
|
||||
value: `${ctrl} + i`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'Hoạt động phác thảo',
|
||||
list: [
|
||||
{
|
||||
icon: 'iconhuanhang',
|
||||
name: 'Dòng mới',
|
||||
value: `Shift + ${enter}`
|
||||
},
|
||||
{
|
||||
icon: 'iconshanchu',
|
||||
name: 'Xóa nút',
|
||||
value: 'Delete'
|
||||
},
|
||||
{
|
||||
icon: 'icontianjiazijiedian',
|
||||
name: 'Chèn nút thấp hơn',
|
||||
value: 'Tab'
|
||||
},
|
||||
{
|
||||
icon: 'iconjiedian',
|
||||
name: 'Chèn nút ngang hàng',
|
||||
value: enter
|
||||
},
|
||||
{
|
||||
icon: 'icondodeparent',
|
||||
name: 'Di chuyển lên một cấp',
|
||||
value: 'Shift + Tab'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// Danh sách hình dạng
|
||||
export const shapeList = [
|
||||
{
|
||||
name: 'Hình chữ nhật',
|
||||
value: 'rectangle'
|
||||
},
|
||||
{
|
||||
name: 'Kim cương',
|
||||
value: 'diamond'
|
||||
},
|
||||
{
|
||||
name: 'Tứ giác song song',
|
||||
value: 'parallelogram'
|
||||
},
|
||||
{
|
||||
name: 'Hình chữ nhật tròn',
|
||||
value: 'roundedRectangle'
|
||||
},
|
||||
{
|
||||
name: 'Hình chữ nhật bát giác',
|
||||
value: 'octagonalRectangle'
|
||||
},
|
||||
{
|
||||
name: 'Hình chữ nhật tam giác ngoài',
|
||||
value: 'outerTriangularRectangle'
|
||||
},
|
||||
{
|
||||
name: 'Hình chữ nhật tam giác bên trong',
|
||||
value: 'innerTriangularRectangle'
|
||||
},
|
||||
{
|
||||
name: 'Hình elip',
|
||||
value: 'ellipse'
|
||||
},
|
||||
{
|
||||
name: 'Vòng tròn',
|
||||
value: 'circle'
|
||||
}
|
||||
]
|
||||
|
||||
// Danh sách đa ngôn ngữ
|
||||
export const langList = [
|
||||
{
|
||||
value: 'zh',
|
||||
name: '简体中文'
|
||||
},
|
||||
{
|
||||
value: 'zhtw',
|
||||
name: '繁體中文'
|
||||
},
|
||||
{
|
||||
value: 'en',
|
||||
name: 'English'
|
||||
},
|
||||
{
|
||||
value: 'vi',
|
||||
name: 'Tiếng Việt'
|
||||
}
|
||||
]
|
||||
|
||||
// Danh sách thanh bên
|
||||
export const sidebarTriggerList = [
|
||||
{
|
||||
name: 'Kiểu nút',
|
||||
value: 'nodeStyle',
|
||||
icon: 'iconzhuti'
|
||||
},
|
||||
{
|
||||
name: 'Kiểu nền tảng',
|
||||
value: 'baseStyle',
|
||||
icon: 'iconyangshi'
|
||||
},
|
||||
{
|
||||
name: 'Chủ đề',
|
||||
value: 'theme',
|
||||
icon: 'iconjingzi'
|
||||
},
|
||||
{
|
||||
name: 'Cấu trúc',
|
||||
value: 'structure',
|
||||
icon: 'iconjiegou'
|
||||
},
|
||||
{
|
||||
name: 'Trang chủ',
|
||||
value: 'outline',
|
||||
icon: 'iconfuhao-dagangshu'
|
||||
},
|
||||
// {
|
||||
// name: 'AI',
|
||||
// value: 'ai',
|
||||
// icon: 'iconAIshengcheng'
|
||||
// },
|
||||
{
|
||||
name: 'Thiết lập',
|
||||
value: 'setting',
|
||||
icon: 'iconshezhi'
|
||||
}
|
||||
// {
|
||||
// name: 'Phím tắt',
|
||||
// value: 'shortcutKey',
|
||||
// icon: 'iconjianpan'
|
||||
// }
|
||||
]
|
||||
|
||||
// Danh sách các loại tải xuống
|
||||
export const downTypeList = [
|
||||
{
|
||||
name: '思绪Tài liệu',
|
||||
type: 'smm',
|
||||
icon: 'iconwenjian',
|
||||
desc: 'SimpleMindMap Định dạng riêng tư, có thể được sử dụng để nhập lại, có thể được chỉnh sửa trực tiếp bởi khách hàng'
|
||||
},
|
||||
{
|
||||
name: 'Hình ảnh',
|
||||
type: 'png',
|
||||
icon: 'iconPNG',
|
||||
desc: 'Định dạng ảnh phổ biến, phù hợp để xem chia sẻ'
|
||||
},
|
||||
{
|
||||
name: 'SVG',
|
||||
type: 'svg',
|
||||
icon: 'iconSVG',
|
||||
desc: 'Thu phóng đồ họa vector'
|
||||
},
|
||||
{
|
||||
name: 'PDF',
|
||||
type: 'pdf',
|
||||
icon: 'iconpdf',
|
||||
desc: 'Thích hợp để xem trình duyệt và in'
|
||||
},
|
||||
{
|
||||
name: 'Markdown',
|
||||
type: 'md',
|
||||
icon: 'iconmarkdown',
|
||||
desc: 'Định dạng văn bản md để dễ dàng mở phần mềm khác'
|
||||
},
|
||||
{
|
||||
name: 'XMind',
|
||||
type: 'xmind',
|
||||
icon: 'iconxmind',
|
||||
desc: 'Định dạng phần mềm XMind'
|
||||
},
|
||||
{
|
||||
name: 'Txt',
|
||||
type: 'txt',
|
||||
icon: 'iconTXT',
|
||||
desc: 'Tập tin văn bản thuần túy'
|
||||
},
|
||||
{
|
||||
name: 'Excel',
|
||||
type: 'xlsx',
|
||||
icon: 'iconfile-excel',
|
||||
desc: 'Dạng văn bản bảng, có thể chỉnh sửa bằng phần mềm Excel'
|
||||
},
|
||||
{
|
||||
name: 'FreeMind',
|
||||
type: 'mm',
|
||||
icon: 'iconfreemind',
|
||||
desc: 'Định dạng phần mềm FreeMind'
|
||||
},
|
||||
{
|
||||
name: 'JSON',
|
||||
type: 'json',
|
||||
icon: 'iconjson',
|
||||
desc: 'Các định dạng trao đổi dữ liệu phổ biến có thể được sử dụng để nhập lại'
|
||||
}
|
||||
]
|
||||
|
||||
// Danh sách các loại số
|
||||
export const numberTypeList = [
|
||||
{
|
||||
name: 'Không có số',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
name: '1, 2, 3',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: '1., 2., 3.',
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
name: '(1), (2), (3)',
|
||||
value: 3
|
||||
},
|
||||
{
|
||||
name: 'a., b., c.',
|
||||
value: 4
|
||||
},
|
||||
{
|
||||
name: 'A., B., C.',
|
||||
value: 5
|
||||
},
|
||||
{
|
||||
name: 'i., ii., iii.',
|
||||
value: 6
|
||||
},
|
||||
{
|
||||
name: 'I., II., III.',
|
||||
value: 7
|
||||
},
|
||||
{
|
||||
name: '一、, 二、, 三、',
|
||||
value: 8
|
||||
}
|
||||
]
|
||||
|
||||
// Không. Danh sách phân cấp
|
||||
export const numberLevelList = [
|
||||
{
|
||||
name: 'Không. Tầng đầu tiên',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: 'Không. Hai tầng đầu tiên',
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
name: 'Không. Ba tầng đầu tiên',
|
||||
value: 3
|
||||
},
|
||||
{
|
||||
name: 'Không. Tất cả các lớp',
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
|
||||
// Hướng gradient nền
|
||||
export const linearGradientDirList = [
|
||||
{
|
||||
name: 'Từ trái sang phải',
|
||||
value: '1',
|
||||
start: [0, 0],
|
||||
end: [1, 0]
|
||||
},
|
||||
{
|
||||
name: 'Từ phải sang trái',
|
||||
value: '2',
|
||||
start: [1, 0],
|
||||
end: [0, 0]
|
||||
},
|
||||
{
|
||||
name: 'Từ trên xuống dưới',
|
||||
value: '3',
|
||||
start: [0, 0],
|
||||
end: [0, 1]
|
||||
},
|
||||
{
|
||||
name: 'Từ dưới lên trên',
|
||||
value: '4',
|
||||
start: [0, 1],
|
||||
end: [0, 0]
|
||||
},
|
||||
{
|
||||
name: 'Từ trái lên phải xuống',
|
||||
value: '5',
|
||||
start: [0, 0],
|
||||
end: [1, 1]
|
||||
},
|
||||
{
|
||||
name: 'Từ trái xuống phải',
|
||||
value: '6',
|
||||
start: [0, 1],
|
||||
end: [1, 0]
|
||||
},
|
||||
{
|
||||
name: 'Từ trên xuống dưới',
|
||||
value: '7',
|
||||
start: [1, 0],
|
||||
end: [0, 1]
|
||||
},
|
||||
{
|
||||
name: 'Từ phải xuống trái',
|
||||
value: '8',
|
||||
start: [1, 1],
|
||||
end: [0, 0]
|
||||
}
|
||||
]
|
||||
|
||||
// Căn lề văn bản
|
||||
export const alignList = [
|
||||
{
|
||||
name: 'Trái:',
|
||||
value: 'left'
|
||||
},
|
||||
{
|
||||
name: 'Căn giữa',
|
||||
value: 'center'
|
||||
},
|
||||
{
|
||||
name: 'Phải',
|
||||
value: 'right'
|
||||
}
|
||||
]
|
||||
|
||||
// Danh sách cấu trúc
|
||||
export const layoutGroupList = [
|
||||
{
|
||||
name: 'Sơ đồ cấu trúc logic',
|
||||
list: ['logicalStructure', 'logicalStructureLeft']
|
||||
},
|
||||
{
|
||||
name: 'Bản đồ tư duy',
|
||||
list: ['mindMap']
|
||||
},
|
||||
{
|
||||
name: 'Sơ đồ tổ chức',
|
||||
list: ['organizationStructure']
|
||||
},
|
||||
{
|
||||
name: 'Sơ đồ tổ chức thư mục',
|
||||
list: ['catalogOrganization']
|
||||
},
|
||||
{
|
||||
name: 'Dòng thời gian',
|
||||
list: [
|
||||
'timeline',
|
||||
'timeline2',
|
||||
'verticalTimeline'
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Bản đồ Fishbone',
|
||||
list: ['fishbone']
|
||||
}
|
||||
]
|
||||
@ -507,6 +507,10 @@ export const langList = [
|
||||
{
|
||||
value: 'en',
|
||||
name: 'English'
|
||||
},
|
||||
{
|
||||
value: 'vi',
|
||||
name: 'Tiếng Việt'
|
||||
}
|
||||
]
|
||||
|
||||
@ -537,37 +541,31 @@ export const sidebarTriggerList = [
|
||||
value: 'outline',
|
||||
icon: 'iconfuhao-dagangshu'
|
||||
},
|
||||
{
|
||||
name: 'AI',
|
||||
value: 'ai',
|
||||
icon: 'iconAIshengcheng'
|
||||
},
|
||||
// {
|
||||
// name: 'AI',
|
||||
// value: 'ai',
|
||||
// icon: 'iconAIshengcheng'
|
||||
// },
|
||||
{
|
||||
name: '设置',
|
||||
value: 'setting',
|
||||
icon: 'iconshezhi'
|
||||
},
|
||||
{
|
||||
name: '快捷键',
|
||||
value: 'shortcutKey',
|
||||
icon: 'iconjianpan'
|
||||
}
|
||||
// {
|
||||
// name: '快捷键',
|
||||
// value: 'shortcutKey',
|
||||
// icon: 'iconjianpan'
|
||||
// }
|
||||
]
|
||||
|
||||
// 下载类型列表
|
||||
export const downTypeList = [
|
||||
{
|
||||
name: '专有文件',
|
||||
name: '思绪文件',
|
||||
type: 'smm',
|
||||
icon: 'iconwenjian',
|
||||
desc: 'SimpleMindMap私有格式,可用于再次导入,客户端可直接编辑'
|
||||
},
|
||||
{
|
||||
name: 'JSON',
|
||||
type: 'json',
|
||||
icon: 'iconjson',
|
||||
desc: '流行的数据交换格式,可用于再次导入'
|
||||
},
|
||||
{
|
||||
name: '图片',
|
||||
type: 'png',
|
||||
@ -604,6 +602,12 @@ export const downTypeList = [
|
||||
icon: 'iconTXT',
|
||||
desc: '纯文本文件'
|
||||
},
|
||||
{
|
||||
name: 'Excel',
|
||||
type: 'xlsx',
|
||||
icon: 'iconfile-excel',
|
||||
desc: '表格文本形式,可用Excel软件编辑'
|
||||
},
|
||||
{
|
||||
name: 'FreeMind',
|
||||
type: 'mm',
|
||||
@ -611,11 +615,11 @@ export const downTypeList = [
|
||||
desc: 'FreeMind软件格式'
|
||||
},
|
||||
{
|
||||
name: 'Excel',
|
||||
type: 'xlsx',
|
||||
icon: 'iconfile-excel',
|
||||
desc: '表格文本形式,可用Excel软件编辑'
|
||||
}
|
||||
name: 'JSON',
|
||||
type: 'json',
|
||||
icon: 'iconjson',
|
||||
desc: '流行的数据交换格式,可用于再次导入'
|
||||
},
|
||||
]
|
||||
|
||||
// 编号类型列表
|
||||
@ -769,13 +773,11 @@ export const layoutGroupList = [
|
||||
list: [
|
||||
'timeline',
|
||||
'timeline2',
|
||||
'verticalTimeline2',
|
||||
'verticalTimeline3',
|
||||
'verticalTimeline'
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '鱼骨图',
|
||||
list: ['fishbone', 'fishbone2', 'rightFishbone', 'rightFishbone2']
|
||||
list: ['fishbone']
|
||||
}
|
||||
]
|
||||
|
||||
@ -439,37 +439,31 @@ export const sidebarTriggerList = [
|
||||
value: 'outline',
|
||||
icon: 'iconfuhao-dagangshu'
|
||||
},
|
||||
{
|
||||
name: 'AI',
|
||||
value: 'ai',
|
||||
icon: 'iconAIshengcheng'
|
||||
},
|
||||
// {
|
||||
// name: 'AI',
|
||||
// value: 'ai',
|
||||
// icon: 'iconAIshengcheng'
|
||||
// },
|
||||
{
|
||||
name: '設置',
|
||||
value: 'setting',
|
||||
icon: 'iconshezhi'
|
||||
},
|
||||
{
|
||||
name: '快捷鍵',
|
||||
value: 'shortcutKey',
|
||||
icon: 'iconjianpan'
|
||||
}
|
||||
// {
|
||||
// name: '快捷鍵',
|
||||
// value: 'shortcutKey',
|
||||
// icon: 'iconjianpan'
|
||||
// }
|
||||
]
|
||||
|
||||
// 下載類型列表
|
||||
export const downTypeList = [
|
||||
{
|
||||
name: '專用檔案',
|
||||
name: '思緒檔案',
|
||||
type: 'smm',
|
||||
icon: 'iconwenjian',
|
||||
desc: 'SimpleMindMap私有格式,可用于再次導入,客戶端可直接編輯'
|
||||
},
|
||||
{
|
||||
name: 'JSON',
|
||||
type: 'json',
|
||||
icon: 'iconjson',
|
||||
desc: '流行的數據交換格式,可用于再次導入'
|
||||
},
|
||||
{
|
||||
name: '圖片',
|
||||
type: 'png',
|
||||
@ -506,6 +500,12 @@ export const downTypeList = [
|
||||
icon: 'iconTXT',
|
||||
desc: '純文本文件'
|
||||
},
|
||||
{
|
||||
name: 'Excel',
|
||||
type: 'xlsx',
|
||||
icon: 'iconfile-excel',
|
||||
desc: '表格文本形式,可用Excel軟件編輯'
|
||||
},
|
||||
{
|
||||
name: 'FreeMind',
|
||||
type: 'mm',
|
||||
@ -513,11 +513,11 @@ export const downTypeList = [
|
||||
desc: 'FreeMind軟件格式'
|
||||
},
|
||||
{
|
||||
name: 'Excel',
|
||||
type: 'xlsx',
|
||||
icon: 'iconfile-excel',
|
||||
desc: '表格文本形式,可用Excel軟件編輯'
|
||||
}
|
||||
name: 'JSON',
|
||||
type: 'json',
|
||||
icon: 'iconjson',
|
||||
desc: '流行的數據交換格式,可用于再次導入'
|
||||
},
|
||||
]
|
||||
|
||||
// 編號類型列表
|
||||
@ -671,13 +671,11 @@ export const layoutGroupList = [
|
||||
list: [
|
||||
'timeline',
|
||||
'timeline2',
|
||||
'verticalTimeline2',
|
||||
'verticalTimeline3',
|
||||
'verticalTimeline'
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '魚骨圖',
|
||||
list: ['fishbone', 'fishbone2', 'rightFishbone', 'rightFishbone2']
|
||||
list: ['fishbone']
|
||||
}
|
||||
]
|
||||
|
||||
@ -5,7 +5,8 @@ import messages from './lang'
|
||||
Vue.use(VueI18n)
|
||||
|
||||
const i18n = new VueI18n({
|
||||
messages
|
||||
messages,
|
||||
fallbackLocale: 'zh'
|
||||
})
|
||||
|
||||
export default i18n
|
||||
|
||||
@ -64,6 +64,7 @@ export default {
|
||||
isShowScrollbar: 'Is show scrollbar',
|
||||
isUseHandDrawnLikeStyle: 'Is use hand drawn like style',
|
||||
isUseMomentum: 'Is open drag momentum',
|
||||
openBlankMode: 'Is open blank mode of the demonstrate',
|
||||
watermark: 'Watermark',
|
||||
showWatermark: 'Is show watermark',
|
||||
onlyExport: 'Only export',
|
||||
@ -177,7 +178,8 @@ export default {
|
||||
options: 'Options',
|
||||
isFitBg:
|
||||
'Whether to display the complete background image (effective when a background image is used)',
|
||||
format: 'Format'
|
||||
format: 'Format',
|
||||
confirm: 'Export'
|
||||
},
|
||||
fullscreen: {
|
||||
fullscreenShow: 'Full screen show',
|
||||
@ -197,7 +199,10 @@ export default {
|
||||
fileContentError: 'The file content is incorrect',
|
||||
importSuccess: 'Import success',
|
||||
fileParsingFailed: 'File parsing failed',
|
||||
xmindCanvasSelectDialogTitle: 'Select the canvas to import'
|
||||
xmindCanvasSelectDialogTitle: 'Select the canvas to import',
|
||||
mdImportDialogTitle: 'Paste Markdown content to import',
|
||||
mdPlaceholder: 'Please enter the content in Markdown format',
|
||||
mdEmptyTip: 'The content cannot be empty'
|
||||
},
|
||||
navigatorToolbar: {
|
||||
openMiniMap: 'Open mini map',
|
||||
@ -205,7 +210,13 @@ export default {
|
||||
readonly: 'Change to Readonly',
|
||||
edit: 'Change to edit',
|
||||
backToRoot: 'Back to root node',
|
||||
changeSourceCodeEdit: 'Switch to source code editing mode'
|
||||
changeSourceCodeEdit: 'Switch to source code editing mode',
|
||||
shortcutKeys: 'Shortcut keys',
|
||||
ai: 'AI dialogue',
|
||||
downloadClient: 'Download client',
|
||||
site: 'Official website',
|
||||
current: 'Current:',
|
||||
downloadDesc: 'You can download it from the following address:'
|
||||
},
|
||||
nodeHyperlink: {
|
||||
title: 'Link',
|
||||
@ -358,7 +369,13 @@ export default {
|
||||
autoOpenNodeRichTextTip:
|
||||
'Detected imported rich text content, automatically enabled rich text mode',
|
||||
localStorageExceededTip:
|
||||
'The volume of the mind map you created has exceeded the maximum storage limit allowed by the browser. Please export it immediately, otherwise the data will be lost! It is recommended to download the client for use, as there is no size limit for the client.'
|
||||
'The volume of the mind map you created has exceeded the maximum storage limit allowed by the browser. Please export it immediately, otherwise the data will be lost! It is recommended to download the client for use, as there is no size limit for the client.',
|
||||
withBg: 'With background image',
|
||||
tryTipTitle: 'Function trial prompt',
|
||||
tryTipDesc:
|
||||
'This feature is a trial feature in the web version. Please download the client to use it:',
|
||||
downBaidu: 'Go to Baidu Netdisk to download',
|
||||
downGithub: 'Download from Github'
|
||||
},
|
||||
mouseAction: {
|
||||
tip1:
|
||||
@ -510,8 +527,7 @@ export default {
|
||||
aiCreatePartMsgPrefix: 'I have a theme for【',
|
||||
aiCreatePartMsgCenter:
|
||||
'】Can you help me continue writing one of the contents of the mind map【',
|
||||
aiCreatePartMsgPostfix:
|
||||
'】The subordinate content of the node',
|
||||
aiCreatePartMsgPostfix: '】The subordinate content of the node',
|
||||
aiCreatePartMsgHelp:
|
||||
'. Needs to be returned in Markdown format and can only use two syntax: Markdown title and unordered list. It can support multi-level nesting. Just return the content.',
|
||||
aiCreatePart: 'AI Continuation'
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import en from './en_us'
|
||||
import zh from './zh_cn'
|
||||
import zhtw from './zh_tw'
|
||||
import vi from './vi_vn'
|
||||
|
||||
export default {
|
||||
zh,
|
||||
zhtw,
|
||||
en
|
||||
en,
|
||||
vi
|
||||
}
|
||||
|
||||
545
web/src/lang/vi_vn.js
Normal file
@ -0,0 +1,545 @@
|
||||
export default {
|
||||
baseStyle: {
|
||||
title: 'Kiểu cơ bản',
|
||||
background: 'Nền',
|
||||
color: 'Màu sắc',
|
||||
image: 'Hình ảnh',
|
||||
imageRepeat: 'Lặp lại hình ảnh',
|
||||
imagePosition: 'Vị trí hình ảnh',
|
||||
imageSize: 'Kích thước hình ảnh',
|
||||
line: 'Đường kẻ',
|
||||
width: 'Độ rộng',
|
||||
style: 'Kiểu dáng',
|
||||
lineRadius: 'Độ cong',
|
||||
lineOfOutline: 'Đường viền ngoài',
|
||||
showArrow: 'Hiển thị mũi tên',
|
||||
nodePadding: 'Đệm nút',
|
||||
nodeMargin: 'Lề nút',
|
||||
horizontal: 'Ngang',
|
||||
vertical: 'Dọc',
|
||||
maximumWidth: 'Độ rộng tối đa',
|
||||
maximumHeight: 'Độ cao tối đa',
|
||||
icon: 'Biểu tượng',
|
||||
size: 'Kích thước',
|
||||
level2Node: 'Nút cấp 2',
|
||||
belowLevel2Node: 'Nút dưới cấp 2',
|
||||
nodeBorderType: 'Kiểu viền nút',
|
||||
nodeUseLineStyle: 'Chỉ sử dụng kiểu viền dưới',
|
||||
otherConfig: 'Cấu hình khác',
|
||||
associativeLine: 'Đường liên kết',
|
||||
associativeLineWidth: 'Độ rộng',
|
||||
associativeLineColor: 'Màu sắc',
|
||||
associativeLineActiveWidth: 'Độ rộng khi kích hoạt',
|
||||
associativeLineActiveColor: 'Màu sắc khi kích hoạt',
|
||||
rootStyle: 'Nút gốc',
|
||||
associativeLineText: 'Văn bản đường liên kết',
|
||||
fontFamily: 'Phông chữ',
|
||||
fontSize: 'Cỡ chữ',
|
||||
rootLineStartPos: 'Vị trí bắt đầu đường nút gốc',
|
||||
center: 'Trung tâm',
|
||||
edge: 'Cạnh',
|
||||
rainbowLines: 'Đường cầu vồng',
|
||||
notUseRainbowLines: 'Không sử dụng đường cầu vồng',
|
||||
outerFramePadding: 'Đệm khung ngoài',
|
||||
associativeLineStyle: 'Kiểu đường liên kết',
|
||||
builtInBackgroundImage: 'Hình nền tích hợp'
|
||||
},
|
||||
setting: {
|
||||
title: 'Cài đặt',
|
||||
openPerformance: 'Bật chế độ hiệu suất',
|
||||
enableFreeDrag: 'Cho phép kéo thả tự do nút (Beta)',
|
||||
isEnableNodeRichText: 'Cho phép chỉnh sửa văn bản phong phú của nút',
|
||||
mousewheelAction: 'Hành vi của con lăn chuột',
|
||||
zoomView: 'Thu phóng',
|
||||
moveViewUpDown: 'Di chuyển lên xuống',
|
||||
mousewheelZoomActionReverse: 'Thu phóng con lăn chuột',
|
||||
mousewheelZoomActionReverse1: 'Thu nhỏ tiến tới và phóng to lùi lại',
|
||||
mousewheelZoomActionReverse2: 'Phóng to tiến tới và thu nhỏ lùi lại',
|
||||
createNewNodeBehavior: 'Hành vi tạo nút mới',
|
||||
default: 'Kích hoạt nút mới và chỉnh sửa',
|
||||
notActive: 'Không kích hoạt nút mới',
|
||||
activeOnly: 'Chỉ kích hoạt nút mới mà không chỉnh sửa',
|
||||
openRealtimeRenderOnNodeTextEdit:
|
||||
'Bật hiệu ứng kết xuất thời gian thực cho chỉnh sửa văn bản',
|
||||
isShowScrollbar: 'Hiển thị thanh cuộn',
|
||||
isUseHandDrawnLikeStyle: 'Sử dụng kiểu vẽ tay',
|
||||
isUseMomentum: 'Mở động lượng kéo',
|
||||
openBlankMode: 'Mở chế độ trống cho trình diễn',
|
||||
watermark: 'Hình mờ',
|
||||
showWatermark: 'Hiển thị hình mờ',
|
||||
onlyExport: 'Chỉ xuất',
|
||||
watermarkDefaultText: 'Văn bản hình mờ',
|
||||
watermarkText: 'Văn bản hình mờ',
|
||||
watermarkTextColor: 'Màu văn bản',
|
||||
watermarkLineSpacing: 'Khoảng cách dòng',
|
||||
watermarkTextSpacing: 'Khoảng cách văn bản',
|
||||
watermarkAngle: 'Góc',
|
||||
watermarkTextOpacity: 'Độ mờ văn bản',
|
||||
watermarkTextFontSize: 'Cỡ chữ',
|
||||
belowNode: 'Hiển thị nút bên dưới',
|
||||
alwaysShowExpandBtn: 'Luôn hiển thị nút mở rộng',
|
||||
enableAutoEnterTextEditWhenKeydown:
|
||||
'Tự động vào chế độ chỉnh sửa văn bản khi nhấn phím',
|
||||
confirm: 'Xác nhận',
|
||||
cancel: 'Hủy',
|
||||
changeRichTextTip:
|
||||
'Thao tác này sẽ xóa tất cả lịch sử chỉnh sửa và sửa đổi dữ liệu sơ đồ tư duy. Bạn có muốn tiếp tục?',
|
||||
changeRichTextTip2: 'Bạn có muốn chuyển sang chế độ văn bản phong phú?',
|
||||
changeRichTextTip3:
|
||||
'Bạn có muốn chuyển sang chế độ không phải văn bản phong phú?',
|
||||
enableDragImport: 'Cho phép kéo và thả tệp trực tiếp vào trang để nhập',
|
||||
imgTextMargin: 'Khoảng cách giữa hình ảnh và văn bản nút',
|
||||
textContentMargin: 'Khoảng cách nội dung nút',
|
||||
enableInheritAncestorLineStyle:
|
||||
'Kiểu kết nối nút kế thừa kiểu của nút tổ tiên',
|
||||
enableAi: 'Bật chức năng AI'
|
||||
},
|
||||
color: {
|
||||
moreColor: 'Thêm màu'
|
||||
},
|
||||
contextmenu: {
|
||||
insertSiblingNode: 'Chèn nút cùng cấp',
|
||||
insertChildNode: 'Chèn nút con',
|
||||
insertParentNode: 'Chèn nút cha',
|
||||
insertSummary: 'Chèn tóm tắt',
|
||||
moveUpNode: 'Di chuyển nút lên',
|
||||
moveDownNode: 'Di chuyển nút xuống',
|
||||
deleteNode: 'Xóa nút',
|
||||
deleteCurrentNode: 'Chỉ xóa nút hiện tại',
|
||||
copyNode: 'Sao chép nút',
|
||||
cutNode: 'Cắt nút',
|
||||
pasteNode: 'Dán nút',
|
||||
backCenter: 'Quay lại nút gốc',
|
||||
expandAll: 'Mở rộng tất cả',
|
||||
unExpandAll: 'Thu gọn tất cả',
|
||||
expandTo: 'Mở rộng đến',
|
||||
arrangeLayout: 'Sắp xếp bố cục',
|
||||
level1: 'Cấp 1',
|
||||
level2: 'Cấp 2',
|
||||
level3: 'Cấp 3',
|
||||
level4: 'Cấp 4',
|
||||
level5: 'Cấp 5',
|
||||
level6: 'Cấp 6',
|
||||
zenMode: 'Chế độ zen',
|
||||
fitCanvas: 'Vừa với khung vẽ',
|
||||
removeImage: 'Xóa hình ảnh',
|
||||
removeHyperlink: 'Xóa liên kết',
|
||||
removeNote: 'Xóa ghi chú',
|
||||
removeCustomStyles: 'Xóa kiểu tùy chỉnh',
|
||||
removeAllNodeCustomStyles: 'Xóa tất cả kiểu tùy chỉnh của nút',
|
||||
exportNodeToPng: 'Xuất nút thành png',
|
||||
copyToClipboard: 'Sao chép vào clipboard',
|
||||
copyToSmm: 'SMM',
|
||||
copyToJson: 'JSON',
|
||||
copyToMarkdown: 'Markdown',
|
||||
copyToTxt: 'Txt',
|
||||
copyToPng: 'Png',
|
||||
copySuccess: 'Sao chép thành công',
|
||||
copyFail: 'Sao chép thất bại',
|
||||
number: 'Đánh số các nút con',
|
||||
expandNodeChild: 'Mở rộng tất cả nút con',
|
||||
unExpandNodeChild: 'Thu gọn tất cả nút con',
|
||||
addToDo: 'Thêm việc cần làm',
|
||||
removeToDo: 'Xóa việc cần làm',
|
||||
aiCreate: 'AI Tiếp tục',
|
||||
modifyNodeLink: 'Sửa liên kết nút',
|
||||
linkToNode: 'Liên kết đến nút',
|
||||
removeNodeLink: 'Xóa liên kết nút'
|
||||
},
|
||||
count: {
|
||||
words: 'Từ',
|
||||
nodes: 'Nút'
|
||||
},
|
||||
dialog: {
|
||||
cancel: 'Hủy',
|
||||
confirm: 'Xác nhận'
|
||||
},
|
||||
export: {
|
||||
title: 'Xuất',
|
||||
filename: 'Tên tệp',
|
||||
include: 'Bao gồm cấu hình như chủ đề và cấu trúc',
|
||||
dedicatedFile: 'Tệp chuyên dụng',
|
||||
jsonFile: 'Tệp json',
|
||||
imageFile: 'Tệp hình ảnh',
|
||||
svgFile: 'Tệp svg',
|
||||
pdfFile: 'Tệp pdf',
|
||||
markdownFile: 'Tệp markdown',
|
||||
isTransparent: 'Nền là trong suốt',
|
||||
transformingDomToImages: 'Đang chuyển đổi nút: ',
|
||||
notifyTitle: 'Thông tin',
|
||||
notifyMessage:
|
||||
'Nếu tải xuống không được kích hoạt, hãy kiểm tra xem có bị chặn bởi trình duyệt hay không',
|
||||
paddingX: 'Đệm x',
|
||||
paddingY: 'Đệm y',
|
||||
useMultiPageExport: 'Xuất nhiều trang',
|
||||
defaultFileName: 'Sơ đồ tư duy',
|
||||
addFooterTextPlaceholder: 'Ví dụ: Từ simple-mind-map',
|
||||
addFooterText: 'Thêm văn bản ở chân trang',
|
||||
desc: 'Mô tả',
|
||||
options: 'Tùy chọn',
|
||||
isFitBg: 'Hiển thị đầy đủ hình nền (có hiệu lực khi dùng hình nền)',
|
||||
format: 'Định dạng'
|
||||
},
|
||||
fullscreen: {
|
||||
fullscreenShow: 'Hiển thị toàn màn hình',
|
||||
fullscreenEdit: 'Chỉnh sửa toàn màn hình'
|
||||
},
|
||||
demonstrate: {
|
||||
demonstrate: 'Vào chế độ trình diễn'
|
||||
},
|
||||
import: {
|
||||
title: 'Nhập',
|
||||
selectFile: 'Chọn tệp',
|
||||
support: 'Hỗ trợ',
|
||||
file: 'tệp',
|
||||
pleaseSelect: 'Vui lòng chọn',
|
||||
maxFileNum: 'Nhiều nhất chọn một tệp',
|
||||
notSelectTip: 'Vui lòng chọn tệp để nhập',
|
||||
fileContentError: 'Nội dung tệp không chính xác',
|
||||
importSuccess: 'Nhập thành công',
|
||||
fileParsingFailed: 'Phân tích tệp thất bại',
|
||||
xmindCanvasSelectDialogTitle: 'Chọn canvas để nhập',
|
||||
mdImportDialogTitle: 'Dán nội dung Markdown để nhập',
|
||||
mdPlaceholder: 'Vui lòng nhập nội dung ở định dạng Markdown',
|
||||
mdEmptyTip: 'Nội dung không được trống'
|
||||
},
|
||||
navigatorToolbar: {
|
||||
openMiniMap: 'Mở bản đồ thu nhỏ',
|
||||
closeMiniMap: 'Đóng bản đồ thu nhỏ',
|
||||
readonly: 'Chuyển sang chế độ chỉ đọc',
|
||||
edit: 'Chuyển sang chế độ chỉnh sửa',
|
||||
backToRoot: 'Quay lại nút gốc',
|
||||
changeSourceCodeEdit: 'Chuyển sang chế độ chỉnh sửa mã nguồn',
|
||||
shortcutKeys: 'Phím tắt',
|
||||
ai: 'Đối thoại AI',
|
||||
downloadClient: 'Tải về khách hàng',
|
||||
site: 'Trang web chính thức',
|
||||
current: 'Hiện tại:',
|
||||
downloadDesc: 'Có thể download từ địa chỉ sau:'
|
||||
},
|
||||
nodeHyperlink: {
|
||||
title: 'Liên kết',
|
||||
link: 'Href',
|
||||
name: 'Tên'
|
||||
},
|
||||
nodeIcon: {
|
||||
title: 'Biểu tượng'
|
||||
},
|
||||
nodeImage: {
|
||||
title: 'Hình ảnh',
|
||||
imgTitle: 'Tiêu đề'
|
||||
},
|
||||
nodeNote: {
|
||||
title: 'Ghi chú'
|
||||
},
|
||||
nodeTag: {
|
||||
title: 'Thẻ',
|
||||
addTip: 'Nhấn Enter để thêm'
|
||||
},
|
||||
outline: {
|
||||
title: 'Dàn bài',
|
||||
nodeDefaultText: 'Nhánh nút',
|
||||
print: 'In',
|
||||
fullscreen: 'Toàn màn hình'
|
||||
},
|
||||
scale: {
|
||||
zoomIn: 'Phóng to',
|
||||
zoomOut: 'Thu nhỏ'
|
||||
},
|
||||
shortcutKey: {
|
||||
title: 'Phím tắt'
|
||||
},
|
||||
strusture: {
|
||||
title: 'Cấu trúc'
|
||||
},
|
||||
style: {
|
||||
title: 'Kiểu nút',
|
||||
normal: 'Bình thường',
|
||||
active: 'Kích hoạt',
|
||||
text: 'Văn bản',
|
||||
fontFamily: 'Phông chữ',
|
||||
fontSize: 'Cỡ chữ',
|
||||
color: 'Màu sắc',
|
||||
addFontWeight: 'Thêm độ đậm chữ',
|
||||
italic: 'Nghiêng',
|
||||
textDecoration: 'Trang trí văn bản',
|
||||
underline: 'Gạch dưới',
|
||||
none: 'Không',
|
||||
lineThrough: 'Gạch ngang',
|
||||
overline: 'Gạch trên',
|
||||
border: 'Viền',
|
||||
style: 'Kiểu dáng',
|
||||
width: 'Độ rộng',
|
||||
borderRadius: 'Độ cong viền',
|
||||
background: 'Nền',
|
||||
shape: 'Hình dạng',
|
||||
line: 'Đường kẻ',
|
||||
nodePadding: 'Đệm nút',
|
||||
horizontal: 'Ngang',
|
||||
vertical: 'Dọc',
|
||||
gradientStyle: 'Gradient',
|
||||
startColor: 'Bắt đầu',
|
||||
endColor: 'Kết thúc',
|
||||
arrowDir: 'Hướng mũi tên',
|
||||
arrowDirStart: 'Bắt đầu',
|
||||
arrowDirEnd: 'Kết thúc',
|
||||
direction: 'Hướng',
|
||||
selectNodeTip: 'Vui lòng chọn một nút',
|
||||
openLineFlow: 'Mở luồng đường kẻ',
|
||||
lineFlowDuration: 'Thời lượng luồng đường kẻ',
|
||||
forward: 'Tiến tới',
|
||||
reverse: 'Đảo ngược',
|
||||
img: 'Hình ảnh',
|
||||
placement: 'Vị trí',
|
||||
top: 'Trên',
|
||||
bottom: 'Dưới',
|
||||
left: 'Trái',
|
||||
right: 'Phải',
|
||||
tag: 'Thẻ'
|
||||
},
|
||||
theme: {
|
||||
title: 'Chủ đề',
|
||||
classics: 'Cổ điển',
|
||||
dark: 'Tối',
|
||||
simple: 'Đơn giản',
|
||||
coverTip: 'Bạn hiện đã tùy chỉnh kiểu cơ bản, bạn có muốn ghi đè không?',
|
||||
tip: 'Mẹo',
|
||||
cover: 'Ghi đè',
|
||||
reserve: 'Giữ lại'
|
||||
},
|
||||
toolbar: {
|
||||
undo: 'Hoàn tác',
|
||||
redo: 'Làm lại',
|
||||
insertSiblingNode: 'Nút cùng cấp',
|
||||
insertChildNode: 'Nút con',
|
||||
deleteNode: 'Xóa nút',
|
||||
image: 'Hình ảnh',
|
||||
icon: 'Biểu tượng',
|
||||
link: 'Liên kết',
|
||||
note: 'Ghi chú',
|
||||
tag: 'Thẻ',
|
||||
summary: 'Tóm tắt',
|
||||
displayOutline: 'Hiển thị dàn bài',
|
||||
baseStyle: 'Kiểu cơ bản',
|
||||
theme: 'Chủ đề',
|
||||
strusture: 'Cấu trúc',
|
||||
newFile: 'Tệp mới',
|
||||
openFile: 'Mở tệp',
|
||||
saveAs: 'Lưu thành',
|
||||
import: 'Nhập',
|
||||
export: 'Xuất',
|
||||
shortcutKey: 'Phím tắt',
|
||||
associativeLine: 'Đường liên kết',
|
||||
painter: 'Bút vẽ',
|
||||
formula: 'Công thức',
|
||||
attachment: 'Đính kèm',
|
||||
outerFrame: 'Khung ngoài',
|
||||
more: 'Thêm',
|
||||
selectFileTip: 'Vui lòng chọn một tệp',
|
||||
notSupportTip:
|
||||
'Trình duyệt của bạn không hỗ trợ tính năng này, hoặc trang hiện tại không sử dụng giao thức HTTPS',
|
||||
tip: 'Mẹo',
|
||||
editingLocalFileTipFront: 'Hiện đang chỉnh sửa tệp cục bộ【',
|
||||
editingLocalFileTipEnd: '】của bạn',
|
||||
fileContentError: 'Lỗi nội dung tệp',
|
||||
fileOpenFailed: 'Mở tệp thất bại',
|
||||
defaultFileName: 'Sơ đồ tư duy',
|
||||
creatingTip: 'Đang tạo tệp',
|
||||
directory: 'Thư mục',
|
||||
newFileTip:
|
||||
'Vui lòng xuất tệp đang chỉnh sửa trước khi tạo mới, Cẩn thận mất nội dung',
|
||||
openFileTip:
|
||||
'Vui lòng xuất tệp đang chỉnh sửa trước khi mở tệp, Cẩn thận mất nội dung',
|
||||
ai: 'AI'
|
||||
},
|
||||
edit: {
|
||||
newFeatureNoticeTitle: 'Nhắc nhở tính năng mới',
|
||||
newFeatureNoticeMessage:
|
||||
'Cập nhật này hỗ trợ chỉnh sửa văn bản phong phú cho nút, Nhưng có một số thiếu sót, Tác động quan trọng nhất là thời gian xuất hình ảnh tỷ lệ thuận với số lượng nút, Do đó, nếu bạn phụ thuộc nhiều vào yêu cầu xuất, bạn có thể sử dụng【Kiểu cơ bản】-【Cấu hình khác】-【Cho phép chỉnh sửa văn bản phong phú của nút】Đặt để tắt chế độ chỉnh sửa văn bản phong phú.',
|
||||
root: 'Nút gốc',
|
||||
splitByWrap: 'Tự động tách nút dựa trên ngắt dòng?',
|
||||
tip: 'Mẹo',
|
||||
yes: 'Có',
|
||||
no: 'Không',
|
||||
exportError: 'Xuất thất bại',
|
||||
dragTip: 'Thả ở đây để nhập tệp',
|
||||
deleteNodeImgTip: 'Bạn có chắc xóa hình ảnh nút?',
|
||||
autoOpenNodeRichTextTip:
|
||||
'Phát hiện nội dung văn bản phong phú nhập vào, tự động bật chế độ văn bản phong phú',
|
||||
localStorageExceededTip:
|
||||
'Dung lượng sơ đồ tư duy bạn tạo đã vượt quá giới hạn lưu trữ tối đa cho phép của trình duyệt. Vui lòng xuất ngay lập tức, nếu không dữ liệu sẽ bị mất! Nên tải xuống ứng dụng khách để sử dụng, vì không có giới hạn kích thước khi sử dụng ứng dụng khách.',
|
||||
withBg: 'Với Background',
|
||||
tryTipTitle: 'Mẹo dùng thử chức năng',
|
||||
tryTipDesc:
|
||||
'Chức năng này là chức năng dùng thử trong phiên bản web, xin vui lòng tải xuống để khách hàng sử dụng:',
|
||||
downBaidu: 'Tải xuống Baidu',
|
||||
downGithub: 'Tải xuống Github'
|
||||
},
|
||||
mouseAction: {
|
||||
tip1:
|
||||
'Hiện tại: Nhấp chuột trái để kéo canvas, nhấp chuột phải để chọn nút theo hộp',
|
||||
tip2:
|
||||
'Hiện tại: Nhấp chuột trái để chọn nút theo hộp, nhấp chuột phải để kéo canvas'
|
||||
},
|
||||
search: {
|
||||
searchPlaceholder: 'Nhập nội dung tìm kiếm và nhấn Enter',
|
||||
replacePlaceholder: 'Vui lòng nhập nội dung thay thế',
|
||||
replace: 'Thay thế',
|
||||
replaceAll: 'Thay thế tất cả',
|
||||
cancel: 'Hủy',
|
||||
noResult: 'Không có kết quả'
|
||||
},
|
||||
nodeIconSidebar: {
|
||||
title: 'Biểu tượng/Sticker',
|
||||
icon: 'Biểu tượng',
|
||||
sticker: 'Sticker'
|
||||
},
|
||||
formulaSidebar: {
|
||||
title: 'Công thức',
|
||||
placeholder: 'Vui lòng nhập cú pháp LaTeX',
|
||||
confirm: 'Xác nhận',
|
||||
common: 'Công thức phổ biến',
|
||||
tip: 'Không hỗ trợ chèn công thức trong chế độ không phải văn bản phong phú'
|
||||
},
|
||||
richTextToolbar: {
|
||||
bold: 'Đậm',
|
||||
italic: 'Nghiêng',
|
||||
underline: 'Gạch dưới',
|
||||
strike: 'Gạch ngang',
|
||||
fontFamily: 'Phông chữ',
|
||||
fontSize: 'Cỡ chữ',
|
||||
color: 'Màu sắc',
|
||||
backgroundColor: 'Màu nền',
|
||||
removeFormat: 'Xóa định dạng',
|
||||
textAlign: 'Căn chỉnh văn bản'
|
||||
},
|
||||
other: {
|
||||
loading: 'Đang tải, vui lòng đợi...'
|
||||
},
|
||||
sourceCodeEdit: {
|
||||
sourceCodeTip:
|
||||
'Không nên sửa kiểu trong chế độ văn bản phong phú vì cần phải đồng bộ sửa đổi dữ liệu và cấu trúc HTML.',
|
||||
format: 'Định dạng',
|
||||
copy: 'Sao chép',
|
||||
confirm: 'Hoàn thành',
|
||||
close: 'Đóng',
|
||||
formatErrorTip:
|
||||
'Định dạng JSON không chính xác. Vui lòng kiểm tra và thử lại',
|
||||
copyTip: 'Đã sao chép vào clipboard',
|
||||
formatTip: 'Định dạng hoàn thành'
|
||||
},
|
||||
attachment: {
|
||||
deleteAttachment: 'Xóa đính kèm',
|
||||
tip: 'Chức năng đính kèm chỉ có sẵn ở phía máy khách'
|
||||
},
|
||||
annotation: {
|
||||
mark: 'Đánh dấu',
|
||||
show: 'Hiển thị đánh dấu',
|
||||
type: 'Loại',
|
||||
color: 'Màu sắc',
|
||||
lineWidth: 'Độ rộng đường kẻ',
|
||||
padding: 'Đệm',
|
||||
animate: 'Hoạt ảnh'
|
||||
},
|
||||
nodeOuterFrame: {
|
||||
outerFrameSetting: 'Cài đặt khung ngoài',
|
||||
deleteOuterFrame: 'Xóa khung ngoài',
|
||||
boxStyle: 'Kiểu hộp',
|
||||
boxColor: 'Màu hộp',
|
||||
fillColor: 'Màu lấp đầy',
|
||||
nodeOuterFrameStyle: 'Kiểu khung ngoài',
|
||||
outerFrameText: 'Văn bản khung ngoài',
|
||||
deleteOuterFrameText: 'Xóa văn bản khung ngoài',
|
||||
fontFamily: 'Phông chữ',
|
||||
color: 'Màu sắc',
|
||||
fontSize: 'Cỡ chữ',
|
||||
radius: 'Độ cong',
|
||||
fontBold: 'Đậm chữ',
|
||||
italic: 'Nghiêng',
|
||||
lineHeight: 'Chiều cao dòng',
|
||||
textFillRadius: 'Độ cong lấp đầy văn bản',
|
||||
textFill: 'Màu lấp đầy văn bản',
|
||||
textAlign: 'Căn chỉnh văn bản',
|
||||
left: 'Trái',
|
||||
center: 'Giữa',
|
||||
right: 'Phải',
|
||||
paddingX: 'Đệm x',
|
||||
paddingY: 'Đệm y'
|
||||
},
|
||||
nodeTagStyle: {
|
||||
placeholder: 'Vui lòng nhập nội dung thẻ',
|
||||
delete: 'Xóa thẻ này'
|
||||
},
|
||||
ai: {
|
||||
chatTitle: 'Đối thoại AI',
|
||||
clearRecords: 'Xóa lịch sử',
|
||||
connectFailedTitle: 'Thông báo lỗi kết nối máy khách',
|
||||
connectFailedTip: 'Kết nối máy khách thất bại, vui lòng kiểm tra:',
|
||||
connectFailedCheckTip1:
|
||||
'1. Bạn đã cài đặt ứng dụng khách sơ đồ tư duy chưa? Nếu chưa, vui lòng nhấp vào đây để cài đặt:',
|
||||
connectFailedCheckTip2:
|
||||
'2. Nếu đã cài đặt ứng dụng khách, vui lòng xác nhận xem ứng dụng khách đã được mở chưa.',
|
||||
connectFailedCheckTip3:
|
||||
'Nếu đã được cài đặt và khởi động, bạn có thể thử đóng và khởi động lại nó.',
|
||||
connectFailedCheckTip4:
|
||||
'Sau khi hoàn thành các bước trên, bạn có thể nhấp vào:',
|
||||
baiduNetdisk: 'Baidu Netdisk',
|
||||
createMindMapTitle: 'Tạo sơ đồ tư duy một nhấp',
|
||||
createTip:
|
||||
'Vui lòng nhập chủ đề, và AI sẽ tạo sơ đồ tư duy dựa trên chủ đề của bạn, chẳng hạn như: Kế hoạch du lịch cuối tuần Hà Nội.',
|
||||
importantTip:
|
||||
'Lưu ý quan trọng: Tạo một nhấp sẽ ghi đè dữ liệu hiện có. Nên xuất dữ liệu hiện tại trước.',
|
||||
wantModifyAiConfigTip: 'Bạn muốn sửa đổi cấu hình AI? Vui lòng nhấp vào:',
|
||||
modifyAIConfiguration: 'Sửa đổi cấu hình AI',
|
||||
chatInputPlaceholder: 'Nhấn Enter để gửi, Shift+Enter để xuống dòng.',
|
||||
send: 'Gửi',
|
||||
stopGenerating: 'Dừng tạo',
|
||||
generationFailed: 'Tạo thất bại',
|
||||
aiGenerationSuccess: 'Tạo AI hoàn thành',
|
||||
stoppedGenerating: 'Đã dừng tạo',
|
||||
AIConfiguration: 'Cấu hình AI',
|
||||
VolcanoArkLargeModelConfiguration: 'Cấu hình mô hình lớn Volcano Ark:',
|
||||
configTip:
|
||||
'Hiện tại, chỉ hỗ trợ mô hình Volcano Ark, và bạn cần tự mình lấy khóa. Để biết các bước thực hiện chi tiết, vui lòng tham khảo:',
|
||||
course: 'Khóa học',
|
||||
inferenceAccessPoint: 'Điểm truy cập suy luận',
|
||||
mindMappingClientConfiguration: 'Cấu hình ứng dụng khách sơ đồ tư duy:',
|
||||
port: 'Cổng',
|
||||
cancel: 'Hủy',
|
||||
confirm: 'Xác nhận',
|
||||
close: 'Đóng',
|
||||
configSaveSuccessTip: 'Lưu cấu hình thành công',
|
||||
apiValidateTip: 'Vui lòng nhập giao diện',
|
||||
keyValidateTip: 'Vui lòng nhập API Key',
|
||||
modelValidateTip: 'Vui lòng nhập điểm truy cập suy luận',
|
||||
portValidateTip: 'Vui lòng nhập cổng',
|
||||
methodValidateTip: 'Vui lòng chọn phương thức yêu cầu',
|
||||
noInputTip: 'Vui lòng nhập nội dung',
|
||||
connectSuccessful: 'Kết nối thành công',
|
||||
connectFailed: 'Kết nối thất bại',
|
||||
connectionDetection: 'Phát hiện kết nối',
|
||||
configurationMissing: 'Thiếu cấu hình',
|
||||
aiCreateMsgPrefix: 'Giúp tôi viết một【',
|
||||
aiCreateMsgPostfix:
|
||||
'】. Nó cần được trả về ở định dạng Markdown và chỉ có thể sử dụng hai cú pháp: tiêu đề Markdown và danh sách không có thứ tự. Nó có thể hỗ trợ nhiều lớp lồng nhau. Chỉ cần trả về nội dung.',
|
||||
aiCreatePartMsgPrefix: 'Tôi có một chủ đề là【',
|
||||
aiCreatePartMsgCenter:
|
||||
'】Bạn có thể giúp tôi tiếp tục viết một trong những nội dung của sơ đồ tư duy【',
|
||||
aiCreatePartMsgPostfix: '】Nội dung phụ thuộc của nút',
|
||||
aiCreatePartMsgHelp:
|
||||
'. Cần được trả về ở định dạng Markdown và chỉ có thể sử dụng hai cú pháp: tiêu đề Markdown và danh sách không có thứ tự. Nó có thể hỗ trợ lồng ghép nhiều cấp độ. Chỉ cần trả về nội dung.',
|
||||
aiCreatePart: 'AI Tiếp tục'
|
||||
},
|
||||
note: {
|
||||
title: 'Ghi chú'
|
||||
},
|
||||
nodeLink: {
|
||||
linkToNode: 'Liên kết đến nút',
|
||||
addReturn: 'Thêm liên kết trở lại',
|
||||
tip1: 'Vui lòng chọn nút để liên kết đến',
|
||||
tip2: 'Không thể liên kết đến chính mình',
|
||||
tip3: 'Liên kết thành công',
|
||||
tip4: 'Xóa thành công',
|
||||
tip5: 'Nút liên kết không tồn tại. Có nên xóa liên kết không?'
|
||||
}
|
||||
}
|
||||
@ -62,6 +62,7 @@ export default {
|
||||
isShowScrollbar: '是否显示滚动条',
|
||||
isUseHandDrawnLikeStyle: '是否开启手绘风格',
|
||||
isUseMomentum: '是否开启拖动画布的动量效果',
|
||||
openBlankMode: '是否开启演示模式的填空功能',
|
||||
watermark: '水印',
|
||||
showWatermark: '是否显示水印',
|
||||
watermarkDefaultText: '水印文字',
|
||||
@ -145,8 +146,8 @@ export default {
|
||||
nodes: '节点'
|
||||
},
|
||||
dialog: {
|
||||
cancel: '取 消',
|
||||
confirm: '确 定'
|
||||
cancel: '取消',
|
||||
confirm: '确定'
|
||||
},
|
||||
export: {
|
||||
title: '导出',
|
||||
@ -171,7 +172,8 @@ export default {
|
||||
desc: '说明',
|
||||
options: '选项',
|
||||
isFitBg: '是否显示完整背景图片(使用了背景图片时生效)',
|
||||
format: '格式'
|
||||
format: '格式',
|
||||
confirm: '导出'
|
||||
},
|
||||
fullscreen: {
|
||||
fullscreenShow: '全屏查看',
|
||||
@ -191,7 +193,10 @@ export default {
|
||||
fileContentError: '文件内容有误',
|
||||
importSuccess: '导入成功',
|
||||
fileParsingFailed: '文件解析失败',
|
||||
xmindCanvasSelectDialogTitle: '选择要导入的画布'
|
||||
xmindCanvasSelectDialogTitle: '选择要导入的画布',
|
||||
mdImportDialogTitle: '粘贴Markdown内容导入',
|
||||
mdPlaceholder: '请输入Markdown格式的内容',
|
||||
mdEmptyTip: '内容不能为空'
|
||||
},
|
||||
navigatorToolbar: {
|
||||
openMiniMap: '开启小地图',
|
||||
@ -199,7 +204,13 @@ export default {
|
||||
readonly: '切换为只读模式',
|
||||
edit: '切换为编辑模式',
|
||||
backToRoot: '回到根节点',
|
||||
changeSourceCodeEdit: '切换为源码编辑模式'
|
||||
changeSourceCodeEdit: '切换为源码编辑模式',
|
||||
shortcutKeys: '快捷键',
|
||||
ai: 'AI对话',
|
||||
downloadClient: '下载客户端',
|
||||
site: '官方网站',
|
||||
current: '当前:',
|
||||
downloadDesc: '可从如下地址下载:'
|
||||
},
|
||||
nodeHyperlink: {
|
||||
title: '超链接',
|
||||
@ -347,7 +358,12 @@ export default {
|
||||
deleteNodeImgTip: '是否确认删除该节点图片?',
|
||||
autoOpenNodeRichTextTip: '检测到导入了富文本内容,已自动开启富文本模式',
|
||||
localStorageExceededTip:
|
||||
'你创建的思维导图体积已经超过浏览器允许存储的上限,请立即导出,否则数据将丢失!建议下载客户端进行使用,客户端无大小限制。'
|
||||
'你创建的思维导图体积已经超过浏览器允许存储的上限,请立即导出,否则数据将丢失!建议下载客户端进行使用,客户端无大小限制。',
|
||||
withBg: '带背景',
|
||||
tryTipTitle: '功能试用提示',
|
||||
tryTipDesc: '该功能在网页版中为试用功能,请下载客户端使用:',
|
||||
downBaidu: '去百度网盘下载',
|
||||
downGithub: '去Github下载'
|
||||
},
|
||||
mouseAction: {
|
||||
tip1: '当前:左键拖动画布,右键框选节点',
|
||||
|
||||
@ -63,6 +63,7 @@ export default {
|
||||
isShowScrollbar: '顯示捲軸',
|
||||
isUseHandDrawnLikeStyle: '使用手繪風格',
|
||||
isUseMomentum: '是否開啓拖動畫布的動量效果',
|
||||
openBlankMode: '是否開啓演示模式的填空功能',
|
||||
watermark: '浮水印',
|
||||
showWatermark: '顯示浮水印',
|
||||
onlyExport: '僅在匯出時顯示',
|
||||
@ -172,7 +173,8 @@ export default {
|
||||
desc: '說明',
|
||||
options: '選項',
|
||||
isFitBg: '是否顯示完整背景圖片(使用了背景圖片時生效)',
|
||||
format: '格式'
|
||||
format: '格式',
|
||||
confirm: '匯出'
|
||||
},
|
||||
fullscreen: {
|
||||
fullscreenShow: '全螢幕檢視',
|
||||
@ -192,7 +194,10 @@ export default {
|
||||
fileContentError: '檔案內容有誤',
|
||||
importSuccess: '匯入成功',
|
||||
fileParsingFailed: '檔案解析失敗',
|
||||
xmindCanvasSelectDialogTitle: '選擇要匯入的畫布'
|
||||
xmindCanvasSelectDialogTitle: '選擇要匯入的畫布',
|
||||
mdImportDialogTitle: '粘貼Markdown內容導入',
|
||||
mdPlaceholder: '請輸入Markdown格式的內容',
|
||||
mdEmptyTip: '內容不能爲空'
|
||||
},
|
||||
navigatorToolbar: {
|
||||
openMiniMap: '開啟小地圖',
|
||||
@ -200,7 +205,13 @@ export default {
|
||||
readonly: '切換為唯讀模式',
|
||||
edit: '切換為編輯模式',
|
||||
backToRoot: '回到根節點',
|
||||
changeSourceCodeEdit: '切換為原始碼編輯模式'
|
||||
changeSourceCodeEdit: '切換為原始碼編輯模式',
|
||||
shortcutKeys: '快捷鍵',
|
||||
ai: 'AI對話',
|
||||
downloadClient: '下載客戶端',
|
||||
site: '官方網站',
|
||||
current: '當前:',
|
||||
downloadDesc: '可從如下地址下載:'
|
||||
},
|
||||
nodeHyperlink: {
|
||||
title: '超連結',
|
||||
@ -347,7 +358,12 @@ export default {
|
||||
dragTip: '在此釋放以匯入檔案',
|
||||
autoOpenNodeRichTextTip: '檢測到導入了富文本內容,已自動開啓富文本模式',
|
||||
localStorageExceededTip:
|
||||
'你創建的思維導圖體積已經超過浏覽器允許存儲的上限,請立即導出,否則數據將丟失!建議下載客戶端進行使用,客戶端無大小限制。'
|
||||
'你創建的思維導圖體積已經超過浏覽器允許存儲的上限,請立即導出,否則數據將丟失!建議下載客戶端進行使用,客戶端無大小限制。',
|
||||
withBg: '帶背景',
|
||||
tryTipTitle: '功能試用提示',
|
||||
tryTipDesc: '該功能在網頁版中為試用功能,請下載用戶端使用:',
|
||||
downBaidu: '去百度網盤下載',
|
||||
downGithub: '去Github下載'
|
||||
},
|
||||
mouseAction: {
|
||||
tip1: '目前:左鍵拖曳畫布,右鍵框選節點',
|
||||
@ -491,9 +507,8 @@ export default {
|
||||
'】,需要以Markdown格式返回,並且只能使用Markdown的標題和無序列表兩種語法,可以支持多層嵌套。只需返回內容即可。',
|
||||
aiCreatePartMsgPrefix: '我有一個主題爲【',
|
||||
aiCreatePartMsgCenter: '】的思維導圖,幫我續寫其中一個內容爲【',
|
||||
aiCreatePartMsgPostfix:
|
||||
'】的節點的下級內容',
|
||||
aiCreatePartMsgHelp:
|
||||
aiCreatePartMsgPostfix: '】的節點的下級內容',
|
||||
aiCreatePartMsgHelp:
|
||||
'。需要以Markdown格式返回,並且只能使用Markdown的標題和無序列表兩種語法,可以支持多層嵌套。只需返回內容即可。',
|
||||
aiCreatePart: 'AI續寫'
|
||||
},
|
||||
|
||||
@ -126,7 +126,7 @@
|
||||
</el-tabs>
|
||||
</div>
|
||||
<!-- 连线 -->
|
||||
<div class="title noTop">{{ $t('baseStyle.line') }}</div>
|
||||
<div class="title">{{ $t('baseStyle.line') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('baseStyle.color') }}</span>
|
||||
@ -301,63 +301,8 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 流动效果 -->
|
||||
<div class="row" v-if="supportLineFlow">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('style.openLineFlow') }}</span>
|
||||
<el-checkbox
|
||||
v-model="style.lineFlow"
|
||||
@change="
|
||||
value => {
|
||||
update('lineFlow', value)
|
||||
}
|
||||
"
|
||||
></el-checkbox>
|
||||
</div>
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('style.direction') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
v-model="style.lineFlowForward"
|
||||
placeholder=""
|
||||
@change="
|
||||
value => {
|
||||
update('lineFlowForward', value)
|
||||
}
|
||||
"
|
||||
>
|
||||
<el-option
|
||||
key="1"
|
||||
:label="$t('style.forward')"
|
||||
:value="true"
|
||||
></el-option>
|
||||
<el-option
|
||||
key="2"
|
||||
:label="$t('style.reverse')"
|
||||
:value="false"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="supportLineFlow">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('style.lineFlowDuration') }}</span>
|
||||
<el-input-number
|
||||
v-model="style.lineFlowDuration"
|
||||
@change="
|
||||
value => {
|
||||
update('lineFlowDuration', value)
|
||||
}
|
||||
"
|
||||
:min="0.1"
|
||||
size="mini"
|
||||
:step="0.5"
|
||||
></el-input-number>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 彩虹线条 -->
|
||||
<div class="title noTop">{{ $t('baseStyle.rainbowLines') }}</div>
|
||||
<div class="title">{{ $t('baseStyle.rainbowLines') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<el-popover
|
||||
@ -401,7 +346,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 概要连线 -->
|
||||
<div class="title noTop">{{ $t('baseStyle.lineOfOutline') }}</div>
|
||||
<div class="title">{{ $t('baseStyle.lineOfOutline') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('baseStyle.color') }}</span>
|
||||
@ -451,7 +396,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 关联线 -->
|
||||
<div class="title noTop">{{ $t('baseStyle.associativeLine') }}</div>
|
||||
<div class="title">{{ $t('baseStyle.associativeLine') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('baseStyle.associativeLineColor') }}</span>
|
||||
@ -594,7 +539,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 关联线文字 -->
|
||||
<div class="title noTop">{{ $t('baseStyle.associativeLineText') }}</div>
|
||||
<div class="title">{{ $t('baseStyle.associativeLineText') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('baseStyle.fontFamily') }}</span>
|
||||
@ -656,7 +601,7 @@
|
||||
</div>
|
||||
<!-- 节点边框风格 -->
|
||||
<template v-if="showNodeUseLineStyle">
|
||||
<div class="title noTop">{{ $t('baseStyle.nodeBorderType') }}</div>
|
||||
<div class="title">{{ $t('baseStyle.nodeBorderType') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<el-checkbox
|
||||
@ -672,8 +617,8 @@
|
||||
</div>
|
||||
</template>
|
||||
<!-- 内边距 -->
|
||||
<div class="title noTop">{{ $t('baseStyle.nodePadding') }}</div>
|
||||
<div class="row">
|
||||
<div class="title">{{ $t('baseStyle.nodePadding') }}</div>
|
||||
<div class="row noBottom">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('baseStyle.horizontal') }}</span>
|
||||
<el-slider
|
||||
@ -702,8 +647,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 图片 -->
|
||||
<div class="title noTop">{{ $t('baseStyle.image') }}</div>
|
||||
<div class="row">
|
||||
<div class="title">{{ $t('baseStyle.image') }}</div>
|
||||
<div class="row noBottom">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('baseStyle.maximumWidth') }}</span>
|
||||
<el-slider
|
||||
@ -736,7 +681,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 图标 -->
|
||||
<div class="title noTop">{{ $t('baseStyle.icon') }}</div>
|
||||
<div class="title">{{ $t('baseStyle.icon') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('baseStyle.size') }}</span>
|
||||
@ -754,8 +699,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 二级节点外边距 -->
|
||||
<div class="title noTop">{{ $t('baseStyle.nodeMargin') }}</div>
|
||||
<div class="row column">
|
||||
<div class="title">{{ $t('baseStyle.nodeMargin') }}</div>
|
||||
<div class="row column noBottom">
|
||||
<el-tabs
|
||||
class="tab"
|
||||
v-model="marginActiveTab"
|
||||
@ -798,8 +743,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 外框内边距 -->
|
||||
<div class="title noTop">{{ $t('baseStyle.outerFramePadding') }}</div>
|
||||
<div class="row">
|
||||
<div class="title">{{ $t('baseStyle.outerFramePadding') }}</div>
|
||||
<div class="row noBottom">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('baseStyle.horizontal') }}</span>
|
||||
<el-slider
|
||||
@ -880,6 +825,7 @@ export default {
|
||||
rainbowLinesOptions,
|
||||
lineWidthList,
|
||||
fontSizeList,
|
||||
lineStyleMap,
|
||||
activeTab: 'color',
|
||||
marginActiveTab: 'second',
|
||||
style: {
|
||||
@ -932,7 +878,6 @@ export default {
|
||||
activeSidebar: state => state.activeSidebar,
|
||||
localConfig: state => state.localConfig,
|
||||
isDark: state => state.localConfig.isDark,
|
||||
supportLineFlow: state => state.supportLineFlow,
|
||||
bgList: state => state.bgList
|
||||
}),
|
||||
lineStyleList() {
|
||||
@ -958,9 +903,6 @@ export default {
|
||||
fontFamilyList() {
|
||||
return fontFamilyList[this.$i18n.locale] || fontFamilyList.zh
|
||||
},
|
||||
lineStyleMap() {
|
||||
return lineStyleMap[this.$i18n.locale] || lineStyleMap.zh
|
||||
},
|
||||
showNodeUseLineStyle() {
|
||||
return supportNodeUseLineStyleLayouts.includes(this.currentLayout)
|
||||
},
|
||||
@ -1167,7 +1109,7 @@ export default {
|
||||
font-weight: 500;
|
||||
color: rgba(26, 26, 26, 0.9);
|
||||
margin-bottom: 10px;
|
||||
margin-top: 20px;
|
||||
margin-top: 35px;
|
||||
|
||||
&.noTop {
|
||||
margin-top: 0;
|
||||
@ -1179,6 +1121,10 @@ export default {
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&.noBottom {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@ -62,41 +62,6 @@
|
||||
<div class="item" @click="exec('EXPAND_ALL')">
|
||||
<span class="name">{{ $t('contextmenu.expandNodeChild') }}</span>
|
||||
</div>
|
||||
<div class="item" v-if="supportNumbers">
|
||||
<span class="name">{{ $t('contextmenu.number') }}</span>
|
||||
<span class="el-icon-arrow-right"></span>
|
||||
<div
|
||||
class="subItems listBox"
|
||||
:class="{ isDark: isDark, showLeft: subItemsShowLeft }"
|
||||
style="top: -170px"
|
||||
>
|
||||
<div
|
||||
class="item"
|
||||
v-for="item in numberTypeList"
|
||||
:key="'type' + item.value"
|
||||
@click="setNodeNumber('type', item.value)"
|
||||
>
|
||||
<span class="name">{{ item.name }}</span>
|
||||
{{ numberType === item.value ? '√' : '' }}
|
||||
</div>
|
||||
<div class="splitLine"></div>
|
||||
<div
|
||||
class="item"
|
||||
v-for="item in numberLevelList"
|
||||
:key="'level' + item.value"
|
||||
:class="{ disabled: numberType === '' }"
|
||||
@click="setNodeNumber('level', item.value)"
|
||||
>
|
||||
<span class="name">{{ item.name }}</span>
|
||||
{{ numberLevel === item.value ? '√' : '' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" @click="setCheckbox" v-if="supportCheckbox">
|
||||
<span class="name">{{
|
||||
hasCheckbox ? $t('contextmenu.removeToDo') : $t('contextmenu.addToDo')
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="splitLine"></div>
|
||||
<div class="item danger" @click="exec('REMOVE_NODE')">
|
||||
<span class="name">{{ $t('contextmenu.deleteNode') }}</span>
|
||||
@ -134,16 +99,6 @@
|
||||
<div class="item" @click="exec('REMOVE_NOTE')" v-if="hasNote">
|
||||
<span class="name">{{ $t('contextmenu.removeNote') }}</span>
|
||||
</div>
|
||||
<div class="item" @click="exec('LINK_NODE')">
|
||||
<span class="name">{{
|
||||
hasNodeLink
|
||||
? $t('contextmenu.modifyNodeLink')
|
||||
: $t('contextmenu.linkToNode')
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="item" @click="exec('REMOVE_LINK_NODE')" v-if="hasNodeLink">
|
||||
<span class="name">{{ $t('contextmenu.removeNodeLink') }}</span>
|
||||
</div>
|
||||
<div class="item" @click="exec('REMOVE_CUSTOM_STYLES')">
|
||||
<span class="name">{{ $t('contextmenu.removeCustomStyles') }}</span>
|
||||
</div>
|
||||
@ -262,8 +217,6 @@ export default {
|
||||
...mapState({
|
||||
isZenMode: state => state.localConfig.isZenMode,
|
||||
isDark: state => state.localConfig.isDark,
|
||||
supportNumbers: state => state.supportNumbers,
|
||||
supportCheckbox: state => state.supportCheckbox,
|
||||
enableAi: state => state.localConfig.enableAi
|
||||
}),
|
||||
expandList() {
|
||||
@ -491,13 +444,6 @@ export default {
|
||||
case 'REMOVE_NOTE':
|
||||
this.node.setNote('')
|
||||
break
|
||||
case 'LINK_NODE':
|
||||
this.$bus.$emit('show_link_node', this.node)
|
||||
this.hide()
|
||||
break
|
||||
case 'REMOVE_LINK_NODE':
|
||||
this.$bus.$emit('execCommand', 'SET_NODE_LINK', this.node, null)
|
||||
break
|
||||
case 'EXPORT_CUR_NODE_TO_PNG':
|
||||
this.mindMap.export(
|
||||
'png',
|
||||
@ -521,45 +467,6 @@ export default {
|
||||
this.hide()
|
||||
},
|
||||
|
||||
// 设置节点编号
|
||||
setNodeNumber(prop, value) {
|
||||
if (prop === 'type') {
|
||||
this.numberType = value
|
||||
if (value === '') {
|
||||
// 无编号
|
||||
this.numberLevel = ''
|
||||
this.mindMap.execCommand('SET_NUMBER', [], null)
|
||||
return
|
||||
} else {
|
||||
// 有编号
|
||||
if (this.numberLevel === '') {
|
||||
this.numberLevel = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
if (prop === 'level') {
|
||||
this.numberLevel = value
|
||||
}
|
||||
this.mindMap.execCommand('SET_NUMBER', [], {
|
||||
[prop]: value
|
||||
})
|
||||
this.hide()
|
||||
},
|
||||
|
||||
// 设置待办
|
||||
setCheckbox() {
|
||||
this.mindMap.execCommand(
|
||||
'SET_CHECKBOX',
|
||||
[],
|
||||
this.hasCheckbox
|
||||
? null
|
||||
: {
|
||||
done: false
|
||||
}
|
||||
)
|
||||
this.hide()
|
||||
},
|
||||
|
||||
// 复制到剪贴板
|
||||
async copyToClipboard(type) {
|
||||
try {
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
<template>
|
||||
<div class="customNodeContent">
|
||||
<p>{{ title }}</p>
|
||||
<p v-html="html"></p>
|
||||
<p :style="{ backgroundColor: color }" @click="onClick">点击我会变色</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
html: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: '我是自定义节点',
|
||||
color: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
this.color = 'red'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.customNodeContent {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@ -34,7 +34,6 @@
|
||||
v-if="mindMap"
|
||||
:mindMap="mindMap"
|
||||
></NodeNoteContentShow>
|
||||
<NodeAttachment v-if="mindMap" :mindMap="mindMap"></NodeAttachment>
|
||||
<NodeImgPreview v-if="mindMap" :mindMap="mindMap"></NodeImgPreview>
|
||||
<SidebarTrigger v-if="!isZenMode"></SidebarTrigger>
|
||||
<Search v-if="mindMap" :mindMap="mindMap"></Search>
|
||||
@ -43,7 +42,6 @@
|
||||
<OutlineEdit v-if="mindMap" :mindMap="mindMap"></OutlineEdit>
|
||||
<Scrollbar v-if="isShowScrollbar && mindMap" :mindMap="mindMap"></Scrollbar>
|
||||
<FormulaSidebar v-if="mindMap" :mindMap="mindMap"></FormulaSidebar>
|
||||
<SourceCodeEdit v-if="mindMap" :mindMap="mindMap"></SourceCodeEdit>
|
||||
<NodeOuterFrame v-if="mindMap" :mindMap="mindMap"></NodeOuterFrame>
|
||||
<NodeTagStyle v-if="mindMap" :mindMap="mindMap"></NodeTagStyle>
|
||||
<Setting :configData="mindMapConfig" :mindMap="mindMap"></Setting>
|
||||
@ -54,10 +52,6 @@
|
||||
<NodeNoteSidebar v-if="mindMap" :mindMap="mindMap"></NodeNoteSidebar>
|
||||
<AiCreate v-if="mindMap && enableAi" :mindMap="mindMap"></AiCreate>
|
||||
<AiChat v-if="enableAi"></AiChat>
|
||||
<LinkNodeSelect
|
||||
v-if="mindMap && supportNodeLink"
|
||||
:mindMap="mindMap"
|
||||
></LinkNodeSelect>
|
||||
<div
|
||||
class="dragMask"
|
||||
v-if="showDragMask"
|
||||
@ -96,22 +90,6 @@ import NodeBase64ImageStorage from 'simple-mind-map/src/plugins/NodeBase64ImageS
|
||||
import Themes from 'simple-mind-map-plugin-themes'
|
||||
// 协同编辑插件
|
||||
// import Cooperate from 'simple-mind-map/src/plugins/Cooperate.js'
|
||||
// 以下插件为付费插件,详情请查看开发文档。依次为:手绘风格插件、标记插件、编号插件、Freemind软件格式导入导出插件、Excel软件格式导入导出插件、待办插件、节点连线流动效果插件、动量效果插件、向右鱼骨图插件、节点链接插件、扩展节点形状插件、扩展主题列表插件
|
||||
import HandDrawnLikeStyle from 'simple-mind-map-plugin-handdrawnlikestyle'
|
||||
import Notation from 'simple-mind-map-plugin-notation'
|
||||
import Numbers from 'simple-mind-map-plugin-numbers'
|
||||
import Freemind from 'simple-mind-map-plugin-freemind'
|
||||
import Excel from 'simple-mind-map-plugin-excel'
|
||||
import Checkbox from 'simple-mind-map-plugin-checkbox'
|
||||
import LineFlow from 'simple-mind-map-plugin-lineflow'
|
||||
import Momentum from 'simple-mind-map-plugin-momentum'
|
||||
import RightFishbone from 'simple-mind-map-plugin-right-fishbone'
|
||||
import NodeLink from 'simple-mind-map-plugin-node-link'
|
||||
import MoreShapes from 'simple-mind-map-plugin-more-shapes'
|
||||
import MoreThemes from 'simple-mind-map-plugin-more-themes'
|
||||
// npm link simple-mind-map simple-mind-map-plugin-excel simple-mind-map-plugin-freemind simple-mind-map-plugin-numbers simple-mind-map-plugin-notation simple-mind-map-plugin-handdrawnlikestyle simple-mind-map-plugin-checkbox simple-mind-map-plugin-lineflow simple-mind-map-plugin-momentum simple-mind-map-plugin-right-fishbone simple-mind-map-plugin-node-link
|
||||
// simple-mind-map-plugin-themes
|
||||
// simple-mind-map-plugin-more-themes simple-mind-map-plugin-more-shapes
|
||||
import OutlineSidebar from './OutlineSidebar.vue'
|
||||
import Style from './Style.vue'
|
||||
import BaseStyle from './BaseStyle.vue'
|
||||
@ -129,23 +107,17 @@ import NodeImgPreview from './NodeImgPreview.vue'
|
||||
import SidebarTrigger from './SidebarTrigger.vue'
|
||||
import { mapState } from 'vuex'
|
||||
import icon from '@/config/icon'
|
||||
import CustomNodeContent from './CustomNodeContent.vue'
|
||||
import Color from './Color.vue'
|
||||
import Vue from 'vue'
|
||||
import router from '../../../router'
|
||||
import store from '../../../store'
|
||||
import i18n from '../../../i18n'
|
||||
import Search from './Search.vue'
|
||||
import NodeIconSidebar from './NodeIconSidebar.vue'
|
||||
import NodeIconToolbar from './NodeIconToolbar.vue'
|
||||
import OutlineEdit from './OutlineEdit.vue'
|
||||
import { showLoading, hideLoading } from '@/utils/loading'
|
||||
import handleClipboardText from '@/utils/handleClipboardText'
|
||||
import { getParentWithClass } from '@/utils'
|
||||
import Scrollbar from './Scrollbar.vue'
|
||||
import exampleData from 'simple-mind-map/example/exampleData'
|
||||
import FormulaSidebar from './FormulaSidebar.vue'
|
||||
import SourceCodeEdit from './SourceCodeEdit.vue'
|
||||
import NodeAttachment from './NodeAttachment.vue'
|
||||
import NodeOuterFrame from './NodeOuterFrame.vue'
|
||||
import NodeTagStyle from './NodeTagStyle.vue'
|
||||
import Setting from './Setting.vue'
|
||||
@ -154,7 +126,6 @@ import NodeImgPlacementToolbar from './NodeImgPlacementToolbar.vue'
|
||||
import NodeNoteSidebar from './NodeNoteSidebar.vue'
|
||||
import AiCreate from './AiCreate.vue'
|
||||
import AiChat from './AiChat.vue'
|
||||
import LinkNodeSelect from './LinkNodeSelect.vue'
|
||||
|
||||
// 注册插件
|
||||
MindMap.usePlugin(MiniMap)
|
||||
@ -207,8 +178,6 @@ export default {
|
||||
OutlineEdit,
|
||||
Scrollbar,
|
||||
FormulaSidebar,
|
||||
SourceCodeEdit,
|
||||
NodeAttachment,
|
||||
NodeOuterFrame,
|
||||
NodeTagStyle,
|
||||
Setting,
|
||||
@ -216,8 +185,7 @@ export default {
|
||||
NodeImgPlacementToolbar,
|
||||
NodeNoteSidebar,
|
||||
AiCreate,
|
||||
AiChat,
|
||||
LinkNodeSelect
|
||||
AiChat
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -238,13 +206,9 @@ export default {
|
||||
enableDragImport: state => state.localConfig.enableDragImport,
|
||||
useLeftKeySelectionRightKeyDrag: state =>
|
||||
state.localConfig.useLeftKeySelectionRightKeyDrag,
|
||||
isUseHandDrawnLikeStyle: state =>
|
||||
state.localConfig.isUseHandDrawnLikeStyle,
|
||||
isUseMomentum: state => state.localConfig.isUseMomentum,
|
||||
extraTextOnExport: state => state.extraTextOnExport,
|
||||
isDragOutlineTreeNode: state => state.isDragOutlineTreeNode,
|
||||
enableAi: state => state.localConfig.enableAi,
|
||||
supportNodeLink: state => state.supportNodeLink
|
||||
enableAi: state => state.localConfig.enableAi
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
@ -261,25 +225,10 @@ export default {
|
||||
} else {
|
||||
this.removeScrollbarPlugin()
|
||||
}
|
||||
},
|
||||
isUseHandDrawnLikeStyle() {
|
||||
if (this.isUseHandDrawnLikeStyle) {
|
||||
this.addHandDrawnLikeStylePlugin()
|
||||
} else {
|
||||
this.removeHandDrawnLikeStylePlugin()
|
||||
}
|
||||
},
|
||||
isUseMomentum() {
|
||||
if (this.isUseMomentum) {
|
||||
this.addMomentumPlugin()
|
||||
} else {
|
||||
this.removeMomentumPlugin()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
showLoading()
|
||||
// this.showNewFeatureInfo()
|
||||
this.getData()
|
||||
this.init()
|
||||
this.$bus.$on('execCommand', this.execCommand)
|
||||
@ -294,6 +243,8 @@ export default {
|
||||
this.$bus.$on('showLoading', this.handleShowLoading)
|
||||
this.$bus.$on('localStorageExceeded', this.onLocalStorageExceeded)
|
||||
window.addEventListener('resize', this.handleResize)
|
||||
this.$bus.$on('showDownloadTip', this.showDownloadTip)
|
||||
this.webTip()
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('execCommand', this.execCommand)
|
||||
@ -308,6 +259,7 @@ export default {
|
||||
this.$bus.$off('showLoading', this.handleShowLoading)
|
||||
this.$bus.$off('localStorageExceeded', this.onLocalStorageExceeded)
|
||||
window.removeEventListener('resize', this.handleResize)
|
||||
this.$bus.$off('showDownloadTip', this.showDownloadTip)
|
||||
this.mindMap.destroy()
|
||||
},
|
||||
methods: {
|
||||
@ -417,6 +369,9 @@ export default {
|
||||
},
|
||||
openRealtimeRenderOnNodeTextEdit: true,
|
||||
enableAutoEnterTextEditWhenKeydown: true,
|
||||
demonstrateConfig: {
|
||||
openBlankMode: false
|
||||
},
|
||||
...(config || {}),
|
||||
iconList: [...icon],
|
||||
useLeftKeySelectionRightKeyDrag: this.useLeftKeySelectionRightKeyDrag,
|
||||
@ -490,116 +445,6 @@ export default {
|
||||
})
|
||||
})
|
||||
}
|
||||
// createNodePrefixContent: node => {
|
||||
// const el = document.createElement('div')
|
||||
// el.style.width = '50px'
|
||||
// el.style.height = '50px'
|
||||
// el.style.background = 'red'
|
||||
// return {
|
||||
// el,
|
||||
// width: 50,
|
||||
// height: 50
|
||||
// }
|
||||
// },
|
||||
// createNodePostfixContent: node => {
|
||||
// const domparser = new DOMParser()
|
||||
// const doc = domparser.parseFromString(
|
||||
// '<b style="background-color: rgb(214, 239, 214);">白日依山尽</b>',
|
||||
// 'text/html'
|
||||
// )
|
||||
// const el = doc.querySelector('b')
|
||||
// return {
|
||||
// el,
|
||||
// width: 50,
|
||||
// height: 50
|
||||
// }
|
||||
// },
|
||||
// addContentToHeader: () => {
|
||||
// const el = document.createElement('div')
|
||||
// el.className = 'footer'
|
||||
// el.innerHTML = '理想青年实验室'
|
||||
// const cssText = `
|
||||
// .header {
|
||||
// width: 100%;
|
||||
// height: 50px;
|
||||
// background: #f5f5f5;
|
||||
// display: flex;
|
||||
// justify-content: center;
|
||||
// align-items: center
|
||||
// }
|
||||
// `
|
||||
// return {
|
||||
// el,
|
||||
// cssText,
|
||||
// height: 50
|
||||
// }
|
||||
// },
|
||||
// beforeShortcutRun: (key, activeNodeList) => {
|
||||
// console.log(key, activeNodeList)
|
||||
// // 阻止删除快捷键行为
|
||||
// if (key === 'Backspace') {
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
// handleNodePasteImg: img => {
|
||||
// console.log(img)
|
||||
// return new Promise(resolve => {
|
||||
// setTimeout(() => {
|
||||
// resolve({
|
||||
// url: require('../../../assets/img/themes/autumn.jpg'),
|
||||
// size: {
|
||||
// width: 100,
|
||||
// height: 100
|
||||
// }
|
||||
// })
|
||||
// }, 200)
|
||||
// })
|
||||
// }
|
||||
// isUseCustomNodeContent: true,
|
||||
// 示例1:组件里用到了router、store、i18n等实例化vue组件时需要用到的东西
|
||||
// customCreateNodeContent: (node) => {
|
||||
// let el = document.createElement('div')
|
||||
// let Comp = Vue.extend(Color)
|
||||
// let comp = new Comp({
|
||||
// router,
|
||||
// store,
|
||||
// i18n
|
||||
// })
|
||||
// comp.$mount(el)
|
||||
// return comp.$el
|
||||
// },
|
||||
// 示例2:组件里没有用到示例1的东西
|
||||
// customCreateNodeContent: (node) => {
|
||||
// let el = document.createElement('div')
|
||||
// let Comp = Vue.extend(CustomNodeContent)
|
||||
// let comp = new Comp({
|
||||
// propsData: {
|
||||
// html: node.nodeData.data.text
|
||||
// }
|
||||
// })
|
||||
// comp.$mount(el)
|
||||
// return comp.$el
|
||||
// },
|
||||
// 示例3:普通元素
|
||||
// customCreateNodeContent: node => {
|
||||
// let el = document.createElement('div')
|
||||
// el.style.cssText = `
|
||||
// width: 203px;
|
||||
// height: 78px;
|
||||
// opacity: 0.8;
|
||||
// background-image: linear-gradient(0deg, rgba(53,130,172,0.06) 0%, rgba(24,75,116,0.06) 100%);
|
||||
// box-shadow: inset 0 1px 15px 0 rgba(119,196,255,0.40);
|
||||
// border-radius: 2px;
|
||||
// display: flex;
|
||||
// justify-content: center;
|
||||
// align-items: center;
|
||||
// `
|
||||
// el.innerHTML = `
|
||||
// ${node.nodeData.data.text}
|
||||
// <img crossOrigin="anonymous" src="/img/cactus.jpg" />
|
||||
// `
|
||||
// return el
|
||||
// }
|
||||
})
|
||||
this.loadPlugins()
|
||||
this.mindMap.keyCommand.addShortcut('Control+s', () => {
|
||||
@ -639,7 +484,6 @@ export default {
|
||||
})
|
||||
})
|
||||
this.bindSaveEvent()
|
||||
this.testDynamicCreateNodes()
|
||||
// 如果应用被接管,那么抛出事件传递思维导图实例
|
||||
if (window.takeOverApp) {
|
||||
this.$bus.$emit('app_inited', this.mindMap)
|
||||
@ -656,93 +500,12 @@ export default {
|
||||
}
|
||||
// 协同测试
|
||||
this.cooperateTest()
|
||||
// 销毁
|
||||
// setTimeout(() => {
|
||||
// console.log('销毁')
|
||||
// this.mindMap.destroy()
|
||||
// }, 10000)
|
||||
// 测试
|
||||
// setTimeout(() => {
|
||||
// console.log(this.mindMap.renderer.root.getRect())
|
||||
// console.log(this.mindMap.renderer.root.getRectInSvg())
|
||||
// }, 5000);
|
||||
// setTimeout(() => {
|
||||
// this.mindMap.renderer.renderTree.data.fillColor = 'red'
|
||||
// this.mindMap.render()
|
||||
// this.mindMap.reRender()
|
||||
// this.mindMap.render()
|
||||
// }, 5000)
|
||||
},
|
||||
|
||||
// 加载相关插件
|
||||
loadPlugins() {
|
||||
if (this.openNodeRichText) this.addRichTextPlugin()
|
||||
if (this.isShowScrollbar) this.addScrollbarPlugin()
|
||||
if (typeof HandDrawnLikeStyle !== 'undefined') {
|
||||
this.$store.commit('setSupportHandDrawnLikeStyle', true)
|
||||
if (this.isUseHandDrawnLikeStyle) this.addHandDrawnLikeStylePlugin()
|
||||
}
|
||||
if (typeof Momentum !== 'undefined') {
|
||||
this.$store.commit('setSupportMomentum', true)
|
||||
if (this.isUseMomentum) this.addMomentumPlugin()
|
||||
}
|
||||
if (typeof Notation !== 'undefined') {
|
||||
this.mindMap.addPlugin(Notation)
|
||||
this.$store.commit('setSupportMark', true)
|
||||
}
|
||||
if (typeof Numbers !== 'undefined') {
|
||||
this.mindMap.addPlugin(Numbers)
|
||||
this.$store.commit('setSupportNumbers', true)
|
||||
}
|
||||
if (typeof Freemind !== 'undefined') {
|
||||
this.mindMap.addPlugin(Freemind)
|
||||
this.$store.commit('setSupportFreemind', true)
|
||||
Vue.prototype.Freemind = Freemind
|
||||
}
|
||||
if (typeof Excel !== 'undefined') {
|
||||
this.mindMap.addPlugin(Excel)
|
||||
this.$store.commit('setSupportExcel', true)
|
||||
Vue.prototype.Excel = Excel
|
||||
}
|
||||
if (typeof Checkbox !== 'undefined') {
|
||||
this.mindMap.addPlugin(Checkbox)
|
||||
this.$store.commit('setSupportCheckbox', true)
|
||||
}
|
||||
if (typeof LineFlow !== 'undefined') {
|
||||
this.mindMap.addPlugin(LineFlow)
|
||||
this.$store.commit('setSupportLineFlow', true)
|
||||
}
|
||||
if (typeof RightFishbone !== 'undefined') {
|
||||
this.mindMap.addPlugin(RightFishbone)
|
||||
this.$store.commit('setSupportRightFishbone', true)
|
||||
}
|
||||
if (typeof NodeLink !== 'undefined') {
|
||||
this.mindMap.addPlugin(NodeLink)
|
||||
this.$store.commit('setSupportNodeLink', true)
|
||||
}
|
||||
if (typeof MoreShapes !== 'undefined') {
|
||||
this.mindMap.addPlugin(MoreShapes)
|
||||
this.$store.commit('setSupportMoreShapes', true)
|
||||
}
|
||||
// 扩展侧边主题列表
|
||||
if (typeof MoreThemes !== 'undefined') {
|
||||
const extendThemeGroupList = [
|
||||
{
|
||||
name: '带背景', // 主题组名称
|
||||
// 主题列表
|
||||
list: [...MoreThemes.lightList, ...MoreThemes.darkList].map(
|
||||
item => {
|
||||
return {
|
||||
...item,
|
||||
img: MoreThemes.themeImgMap[item.value]
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
]
|
||||
this.$store.commit('setExtendThemeGroupList', extendThemeGroupList)
|
||||
this.$store.commit('setBgList', MoreThemes.bgList)
|
||||
}
|
||||
},
|
||||
|
||||
// url中是否存在要打开的文件
|
||||
@ -802,21 +565,6 @@ export default {
|
||||
this.mindMap.updateConfig(data)
|
||||
},
|
||||
|
||||
// 显示新特性提示
|
||||
showNewFeatureInfo() {
|
||||
let showed = localStorage.getItem('SIMPLE_MIND_MAP_NEW_FEATURE_TIP_1')
|
||||
if (!showed) {
|
||||
this.$notify.info({
|
||||
title: this.$t('edit.newFeatureNoticeTitle'),
|
||||
message: this.$t('edit.newFeatureNoticeMessage'),
|
||||
duration: 0,
|
||||
onClose: () => {
|
||||
localStorage.setItem('SIMPLE_MIND_MAP_NEW_FEATURE_TIP_1', true)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// 加载节点富文本编辑插件
|
||||
addRichTextPlugin() {
|
||||
if (!this.mindMap) return
|
||||
@ -839,153 +587,6 @@ export default {
|
||||
this.mindMap.removePlugin(ScrollbarPlugin)
|
||||
},
|
||||
|
||||
// 加载手绘风格插件
|
||||
addHandDrawnLikeStylePlugin() {
|
||||
try {
|
||||
if (!this.mindMap) return
|
||||
this.mindMap.addPlugin(HandDrawnLikeStyle)
|
||||
this.mindMap.reRender()
|
||||
} catch (error) {
|
||||
console.log('手绘风格插件不存在')
|
||||
}
|
||||
},
|
||||
|
||||
// 移除手绘风格插件
|
||||
removeHandDrawnLikeStylePlugin() {
|
||||
try {
|
||||
this.mindMap.removePlugin(HandDrawnLikeStyle)
|
||||
this.mindMap.reRender()
|
||||
} catch (error) {
|
||||
console.log('手绘风格插件不存在')
|
||||
}
|
||||
},
|
||||
|
||||
// 加载动量效果插件
|
||||
addMomentumPlugin() {
|
||||
try {
|
||||
if (!this.mindMap) return
|
||||
this.mindMap.addPlugin(Momentum)
|
||||
} catch (error) {
|
||||
console.log('动量效果插件不存在')
|
||||
}
|
||||
},
|
||||
|
||||
// 移除动量效果插件
|
||||
removeMomentumPlugin() {
|
||||
try {
|
||||
this.mindMap.removePlugin(Momentum)
|
||||
} catch (error) {
|
||||
console.log('动量效果插件不存在')
|
||||
}
|
||||
},
|
||||
|
||||
// 测试动态插入节点
|
||||
testDynamicCreateNodes() {
|
||||
// return
|
||||
setTimeout(() => {
|
||||
// 动态给指定节点添加子节点
|
||||
// this.mindMap.execCommand(
|
||||
// 'INSERT_CHILD_NODE',
|
||||
// false,
|
||||
// null,
|
||||
// {
|
||||
// text: '自定义内容'
|
||||
// },
|
||||
// [
|
||||
// {
|
||||
// data: {
|
||||
// text: '自定义子节点'
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 动态给指定节点添加同级节点
|
||||
// this.mindMap.execCommand(
|
||||
// 'INSERT_NODE',
|
||||
// false,
|
||||
// null,
|
||||
// {
|
||||
// text: '自定义内容'
|
||||
// },
|
||||
// [
|
||||
// {
|
||||
// data: {
|
||||
// text: '自定义同级节点'
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// data: {
|
||||
// text: '自定义同级节点2'
|
||||
// },
|
||||
// children: []
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 动态插入多个子节点
|
||||
// this.mindMap.execCommand('INSERT_MULTI_CHILD_NODE', null, [
|
||||
// {
|
||||
// data: {
|
||||
// text: '自定义节点1'
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// data: {
|
||||
// text: '自定义节点1-1'
|
||||
// },
|
||||
// children: []
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// data: {
|
||||
// text: '自定义节点2'
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// data: {
|
||||
// text: '自定义节点2-1'
|
||||
// },
|
||||
// children: []
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ])
|
||||
// 动态插入多个同级节点
|
||||
// this.mindMap.execCommand('INSERT_MULTI_NODE', null, [
|
||||
// {
|
||||
// data: {
|
||||
// text: '自定义节点1'
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// data: {
|
||||
// text: '自定义节点1-1'
|
||||
// },
|
||||
// children: []
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// data: {
|
||||
// text: '自定义节点2'
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// data: {
|
||||
// text: '自定义节点2-1'
|
||||
// },
|
||||
// children: []
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ])
|
||||
// 动态删除指定节点
|
||||
// this.mindMap.execCommand('REMOVE_NODE', this.mindMap.renderer.root.children[0])
|
||||
}, 5000)
|
||||
},
|
||||
|
||||
// 协同测试
|
||||
cooperateTest() {
|
||||
if (this.mindMap.cooperate && this.$route.query.userName) {
|
||||
@ -1012,9 +613,11 @@ export default {
|
||||
if (!this.enableDragImport || this.isDragOutlineTreeNode) return
|
||||
this.showDragMask = true
|
||||
},
|
||||
|
||||
onDragleave() {
|
||||
this.showDragMask = false
|
||||
},
|
||||
|
||||
onDrop(e) {
|
||||
if (!this.enableDragImport) return
|
||||
this.showDragMask = false
|
||||
@ -1022,6 +625,70 @@ export default {
|
||||
const file = dt.files && dt.files[0]
|
||||
if (!file) return
|
||||
this.$bus.$emit('importFile', file)
|
||||
},
|
||||
|
||||
// 网页版试用提示
|
||||
webTip() {
|
||||
const storageKey = 'webUseTip'
|
||||
const data = localStorage.getItem(storageKey)
|
||||
if (data) {
|
||||
return
|
||||
}
|
||||
this.showDownloadTip(
|
||||
'重要提示',
|
||||
'网页版已暂停更新,部分功能缺失,请下载客户端获得完整体验~'
|
||||
)
|
||||
localStorage.setItem(storageKey, 1)
|
||||
},
|
||||
|
||||
showDownloadTip(title, desc) {
|
||||
const h = this.$createElement
|
||||
this.$msgbox({
|
||||
title,
|
||||
message: h('div', null, [
|
||||
h(
|
||||
'p',
|
||||
{
|
||||
style: {
|
||||
marginBottom: '12px'
|
||||
}
|
||||
},
|
||||
desc
|
||||
),
|
||||
h('div', null, [
|
||||
h(
|
||||
'a',
|
||||
{
|
||||
attrs: {
|
||||
href:
|
||||
'https://pan.baidu.com/s/1huasEbKsGNH2Af68dvWiOg?pwd=3bp3',
|
||||
target: '_blank'
|
||||
},
|
||||
style: {
|
||||
color: '#409eff',
|
||||
marginRight: '12px'
|
||||
}
|
||||
},
|
||||
this.$t('edit.downBaidu')
|
||||
),
|
||||
h(
|
||||
'a',
|
||||
{
|
||||
attrs: {
|
||||
href: 'https://github.com/wanglin2/mind-map/releases',
|
||||
target: '_blank'
|
||||
},
|
||||
style: {
|
||||
color: '#409eff'
|
||||
}
|
||||
},
|
||||
this.$t('edit.downGithub')
|
||||
)
|
||||
])
|
||||
]),
|
||||
showCancelButton: false,
|
||||
showConfirmButton: false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1059,11 +726,6 @@ export default {
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
// left: 100px;
|
||||
// top: 100px;
|
||||
// right: 100px;
|
||||
// bottom: 100px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -12,16 +12,6 @@
|
||||
:top="isMobile ? '20px' : '15vh'"
|
||||
>
|
||||
<div class="exportContainer" :class="{ isDark: isDark }">
|
||||
<!-- 文件名称输入 -->
|
||||
<div class="nameInputBox">
|
||||
<span class="name">{{ $t('export.filename') }}</span>
|
||||
<el-input
|
||||
style="max-width: 300px"
|
||||
v-model="fileName"
|
||||
size="mini"
|
||||
@keydown.native.stop
|
||||
></el-input>
|
||||
</div>
|
||||
<!-- 导出类型选择 -->
|
||||
<div class="downloadTypeSelectBox">
|
||||
<!-- 类型列表 -->
|
||||
@ -30,100 +20,127 @@
|
||||
class="downloadTypeItem"
|
||||
v-for="item in downTypeList"
|
||||
:key="item.type"
|
||||
:class="{ active: exportType === item.type }"
|
||||
:class="{
|
||||
active: exportType === item.type
|
||||
}"
|
||||
@click="exportType = item.type"
|
||||
>
|
||||
<div class="icon iconfont" :class="[item.icon, item.type]"></div>
|
||||
<div class="typeIcon" :class="[item.type]"></div>
|
||||
<div class="name">{{ item.name }}</div>
|
||||
<div class="icon checked el-icon-check"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 类型内容 -->
|
||||
<div class="downloadTypeContent customScrollbar">
|
||||
<div class="contentRow">
|
||||
<div class="contentName">{{ $t('export.desc') }}</div>
|
||||
<div class="contentValue">
|
||||
{{ currentTypeData ? currentTypeData.desc : '' }}
|
||||
<div class="downloadTypeContent">
|
||||
<!-- 文件名称输入 -->
|
||||
<div class="nameInputBox">
|
||||
<div class="nameInput">
|
||||
<span class="name">{{ $t('export.filename') }}</span>
|
||||
<el-input
|
||||
style="max-width: 250px"
|
||||
v-model="fileName"
|
||||
size="mini"
|
||||
@keydown.native.stop
|
||||
></el-input>
|
||||
</div>
|
||||
<span class="closeBtn el-icon-close" @click="cancel"></span>
|
||||
</div>
|
||||
<div class="contentRow">
|
||||
<div class="contentName">{{ $t('export.options') }}</div>
|
||||
<div class="contentValue">
|
||||
<div
|
||||
class="valueItem"
|
||||
v-show="['smm', 'json'].includes(exportType)"
|
||||
>
|
||||
<el-checkbox v-model="widthConfig">{{
|
||||
$t('export.include')
|
||||
}}</el-checkbox>
|
||||
<!-- 配置 -->
|
||||
<div class="contentBox customScrollbar">
|
||||
<div class="contentRow">
|
||||
<div class="contentName">{{ $t('export.format') }}</div>
|
||||
<div class="contentValue info">
|
||||
{{ currentTypeData ? '.' + currentTypeData.type : '' }}
|
||||
</div>
|
||||
<div
|
||||
class="valueItem"
|
||||
v-show="['svg', 'png', 'pdf'].includes(exportType)"
|
||||
>
|
||||
<div class="valueSubItem" v-if="['png'].includes(exportType)">
|
||||
<span class="name">{{ $t('export.format') }}</span>
|
||||
<el-radio-group v-model="imageFormat">
|
||||
<el-radio label="png">PNG</el-radio>
|
||||
<el-radio label="jpg">JPG</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="valueSubItem">
|
||||
<span class="name">{{ $t('export.paddingX') }}</span>
|
||||
<el-input
|
||||
style="width: 200px"
|
||||
v-model="paddingX"
|
||||
size="mini"
|
||||
@change="onPaddingChange"
|
||||
@keydown.native.stop
|
||||
></el-input>
|
||||
</div>
|
||||
<div class="valueSubItem">
|
||||
<span class="name">{{ $t('export.paddingY') }}</span>
|
||||
<el-input
|
||||
style="width: 200px"
|
||||
v-model="paddingY"
|
||||
size="mini"
|
||||
@change="onPaddingChange"
|
||||
@keydown.native.stop
|
||||
></el-input>
|
||||
</div>
|
||||
<div class="valueSubItem">
|
||||
<span class="name">{{
|
||||
this.$t('export.addFooterText')
|
||||
}}</span>
|
||||
<el-input
|
||||
style="width: 200px"
|
||||
v-model="extraText"
|
||||
size="mini"
|
||||
:placeholder="$t('export.addFooterTextPlaceholder')"
|
||||
@keydown.native.stop
|
||||
></el-input>
|
||||
</div>
|
||||
<div class="valueSubItem">
|
||||
<el-checkbox
|
||||
v-show="['png', 'pdf'].includes(exportType)"
|
||||
v-model="isTransparent"
|
||||
>{{ $t('export.isTransparent') }}</el-checkbox
|
||||
>
|
||||
</div>
|
||||
<div class="valueSubItem">
|
||||
<el-checkbox v-show="showFitBgOption" v-model="isFitBg">{{
|
||||
$t('export.isFitBg')
|
||||
</div>
|
||||
<div class="contentRow">
|
||||
<div class="contentName">{{ $t('export.desc') }}</div>
|
||||
<div class="contentValue info">
|
||||
{{ currentTypeData ? currentTypeData.desc : '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="contentRow">
|
||||
<div class="contentName">{{ $t('export.options') }}</div>
|
||||
<div class="contentValue info" v-if="noOptions">无</div>
|
||||
<div class="contentValue" v-else>
|
||||
<div
|
||||
class="valueItem"
|
||||
v-show="['smm', 'json'].includes(exportType)"
|
||||
>
|
||||
<el-checkbox v-model="widthConfig">{{
|
||||
$t('export.include')
|
||||
}}</el-checkbox>
|
||||
</div>
|
||||
<div
|
||||
class="valueItem"
|
||||
v-show="['svg', 'png', 'pdf'].includes(exportType)"
|
||||
>
|
||||
<div class="valueSubItem" v-if="['png'].includes(exportType)">
|
||||
<span class="name">{{ $t('export.format') }}</span>
|
||||
<el-radio-group v-model="imageFormat">
|
||||
<el-radio label="png">PNG</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="valueSubItem">
|
||||
<span class="name">{{ $t('export.paddingX') }}</span>
|
||||
<el-input
|
||||
style="width: 200px"
|
||||
v-model="paddingX"
|
||||
size="mini"
|
||||
@change="onPaddingChange"
|
||||
@keydown.native.stop
|
||||
></el-input>
|
||||
</div>
|
||||
<div class="valueSubItem">
|
||||
<span class="name">{{ $t('export.paddingY') }}</span>
|
||||
<el-input
|
||||
style="width: 200px"
|
||||
v-model="paddingY"
|
||||
size="mini"
|
||||
@change="onPaddingChange"
|
||||
@keydown.native.stop
|
||||
></el-input>
|
||||
</div>
|
||||
<div class="valueSubItem">
|
||||
<span class="name">{{
|
||||
this.$t('export.addFooterText')
|
||||
}}</span>
|
||||
<el-input
|
||||
style="width: 200px"
|
||||
v-model="extraText"
|
||||
size="mini"
|
||||
:placeholder="$t('export.addFooterTextPlaceholder')"
|
||||
@keydown.native.stop
|
||||
></el-input>
|
||||
</div>
|
||||
<div class="valueSubItem">
|
||||
<el-checkbox
|
||||
v-show="['png', 'pdf'].includes(exportType)"
|
||||
v-model="isTransparent"
|
||||
>{{ $t('export.isTransparent') }}</el-checkbox
|
||||
>
|
||||
</div>
|
||||
<div class="valueSubItem">
|
||||
<el-checkbox v-show="showFitBgOption" v-model="isFitBg">{{
|
||||
$t('export.isFitBg')
|
||||
}}</el-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 按钮 -->
|
||||
<div class="btnList">
|
||||
<el-button @click="cancel" size="small">{{
|
||||
$t('dialog.cancel')
|
||||
}}</el-button>
|
||||
<el-button type="primary" @click="confirm" size="small">{{
|
||||
$t('export.confirm')
|
||||
}}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel">{{ $t('dialog.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="confirm">{{
|
||||
$t('dialog.confirm')
|
||||
}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
@ -157,18 +174,16 @@ export default {
|
||||
...mapState({
|
||||
openNodeRichText: state => state.localConfig.openNodeRichText,
|
||||
isDark: state => state.localConfig.isDark,
|
||||
supportFreemind: state => state.supportFreemind,
|
||||
supportExcel: state => state.supportExcel
|
||||
}),
|
||||
|
||||
downTypeList() {
|
||||
const list = downTypeList[this.$i18n.locale] || downTypeList.zh
|
||||
return list.filter(item => {
|
||||
if (item.type === 'mm') {
|
||||
return this.supportFreemind
|
||||
return false
|
||||
}
|
||||
if (item.type === 'xlsx') {
|
||||
return this.supportExcel
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
@ -184,6 +199,10 @@ export default {
|
||||
|
||||
showFitBgOption() {
|
||||
return ['png', 'pdf'].includes(this.exportType) && !this.isTransparent
|
||||
},
|
||||
|
||||
noOptions() {
|
||||
return ['md', 'xmind', 'txt', 'xlsx', 'mm'].includes(this.exportType)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@ -251,22 +270,6 @@ export default {
|
||||
this.isTransparent,
|
||||
this.isFitBg
|
||||
)
|
||||
} else if (this.exportType === 'mm') {
|
||||
this.$bus.$emit('export', this.exportType, true, this.fileName, {
|
||||
transformNote: note => {
|
||||
if (!md) {
|
||||
md = new MarkdownIt()
|
||||
}
|
||||
return md.render(note)
|
||||
},
|
||||
transformImage: img => {
|
||||
if (/^https?:\/\//.test(img)) {
|
||||
return img
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$bus.$emit('export', this.exportType, true, this.fileName)
|
||||
}
|
||||
@ -284,14 +287,10 @@ export default {
|
||||
.nodeExportDialog {
|
||||
.exportContainer {
|
||||
&.isDark {
|
||||
.nameInputBox {
|
||||
.name {
|
||||
color: hsla(0, 0%, 100%, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.downloadTypeSelectBox {
|
||||
.downloadTypeList {
|
||||
background-color: #363b3f;
|
||||
|
||||
.downloadTypeItem {
|
||||
background-color: #363b3f;
|
||||
|
||||
@ -306,15 +305,39 @@ export default {
|
||||
}
|
||||
|
||||
.downloadTypeContent {
|
||||
.contentRow {
|
||||
.contentName {
|
||||
color: hsla(0, 0%, 100%, 0.6);
|
||||
.nameInputBox {
|
||||
border-bottom: 1px solid hsla(0, 0%, 100%, 0.6);
|
||||
|
||||
.nameInput {
|
||||
.name {
|
||||
color: hsla(0, 0%, 100%, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.contentValue {
|
||||
.closeBtn {
|
||||
color: hsla(0, 0%, 100%, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.contentBox {
|
||||
.contentRow {
|
||||
.contentName {
|
||||
color: hsla(0, 0%, 100%, 0.6);
|
||||
}
|
||||
|
||||
.contentValue {
|
||||
color: hsla(0, 0%, 100%, 0.6);
|
||||
|
||||
&.info {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btnList {
|
||||
border-top: 1px solid hsla(0, 0%, 100%, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -332,10 +355,17 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-dialog {
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
.el-dialog__header {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-dialog__body {
|
||||
padding: 0;
|
||||
border-top: 1px solid #f2f4f7;
|
||||
border-bottom: 1px solid #f2f4f7;
|
||||
|
||||
.el-checkbox__input.is-checked + .el-checkbox__label {
|
||||
color: #409eff !important;
|
||||
@ -359,11 +389,13 @@ export default {
|
||||
align-items: center;
|
||||
overflow-x: auto;
|
||||
height: 60px;
|
||||
overflow-y: hidden;
|
||||
|
||||
.downloadTypeItem {
|
||||
width: 100px;
|
||||
flex-shrink: 0;
|
||||
padding-left: 10px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
|
||||
.icon {
|
||||
margin-right: 5px;
|
||||
@ -376,21 +408,33 @@ export default {
|
||||
}
|
||||
|
||||
.downloadTypeContent {
|
||||
.contentRow {
|
||||
flex-direction: column;
|
||||
.nameInputBox {
|
||||
height: 70px;
|
||||
|
||||
.contentName {
|
||||
margin-bottom: 10px;
|
||||
.nameInput {
|
||||
.name {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.contentValue {
|
||||
.valueItem {
|
||||
.valueSubItem {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.contentBox {
|
||||
.contentRow {
|
||||
flex-direction: column;
|
||||
|
||||
.name {
|
||||
margin-bottom: 5px;
|
||||
.contentName {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.contentValue {
|
||||
.valueItem {
|
||||
.valueSubItem {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.name {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -403,25 +447,11 @@ export default {
|
||||
|
||||
.exportContainer {
|
||||
width: 100%;
|
||||
height: 450px;
|
||||
height: 552px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.nameInputBox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
height: 50px;
|
||||
flex-shrink: 0;
|
||||
border-bottom: 1px solid #f2f4f7;
|
||||
|
||||
.name {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.downloadTypeSelectBox {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@ -429,17 +459,18 @@ export default {
|
||||
display: flex;
|
||||
|
||||
.downloadTypeList {
|
||||
width: 210px;
|
||||
width: 208px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
background-color: #f2f4f7;
|
||||
flex-shrink: 0;
|
||||
padding: 16px 0;
|
||||
|
||||
.downloadTypeItem {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
padding-left: 28px;
|
||||
height: 52px;
|
||||
padding: 0 30px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -457,40 +488,7 @@ export default {
|
||||
|
||||
.icon {
|
||||
font-size: 25px;
|
||||
margin-right: 15px;
|
||||
flex-shrink: 0;
|
||||
|
||||
&.png {
|
||||
color: #ffc038;
|
||||
}
|
||||
|
||||
&.pdf {
|
||||
color: #ff6c4d;
|
||||
}
|
||||
|
||||
&.md {
|
||||
color: #2b2b2b;
|
||||
}
|
||||
|
||||
&.json {
|
||||
color: #12c87e;
|
||||
}
|
||||
|
||||
&.svg {
|
||||
color: #4380ff;
|
||||
}
|
||||
|
||||
&.smm {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
&.xmind {
|
||||
color: #f55e5e;
|
||||
}
|
||||
|
||||
&.txt {
|
||||
color: #70798e;
|
||||
}
|
||||
font-weight: 700;
|
||||
|
||||
&.checked {
|
||||
color: #409eff;
|
||||
@ -500,53 +498,183 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.typeIcon {
|
||||
margin-right: 18px;
|
||||
flex-shrink: 0;
|
||||
width: 23px;
|
||||
height: 26px;
|
||||
background-size: cover;
|
||||
|
||||
&.png {
|
||||
background-image: url('../../../assets/img/foramt/2.png');
|
||||
}
|
||||
|
||||
&.pdf {
|
||||
background-image: url('../../../assets/img/foramt/4.png');
|
||||
}
|
||||
|
||||
&.md {
|
||||
background-image: url('../../../assets/img/foramt/5.png');
|
||||
}
|
||||
|
||||
&.json {
|
||||
background-image: url('../../../assets/img/foramt/10.png');
|
||||
}
|
||||
|
||||
&.svg {
|
||||
background-image: url('../../../assets/img/foramt/3.png');
|
||||
}
|
||||
|
||||
&.smm {
|
||||
background-image: url('../../../assets/img/foramt/1.png');
|
||||
}
|
||||
|
||||
&.xmind {
|
||||
background-image: url('../../../assets/img/foramt/6.png');
|
||||
}
|
||||
|
||||
&.txt {
|
||||
background-image: url('../../../assets/img/foramt/7.png');
|
||||
}
|
||||
|
||||
&.mm {
|
||||
background-image: url('../../../assets/img/foramt/8.png');
|
||||
}
|
||||
|
||||
&.xlsx {
|
||||
background-image: url('../../../assets/img/foramt/9.png');
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
color: #1a1a1a;
|
||||
color: #333;
|
||||
font-size: 15px;
|
||||
margin-bottom: 5px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.downloadTypeContent {
|
||||
padding: 30px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.contentRow {
|
||||
.nameInputBox {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 67px;
|
||||
flex-shrink: 0;
|
||||
border-bottom: 1px solid #f2f4f7;
|
||||
padding-left: 40px;
|
||||
padding-right: 20px;
|
||||
padding-top: 16px;
|
||||
|
||||
.contentName {
|
||||
width: 80px;
|
||||
color: #666;
|
||||
.nameInput {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
|
||||
.name {
|
||||
margin-right: 10px;
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.contentValue {
|
||||
color: #1a1a1a;
|
||||
.closeBtn {
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.valueItem {
|
||||
.valueSubItem {
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
.contentBox {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding: 15px 40px;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
.contentRow {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.name {
|
||||
margin-right: 12px;
|
||||
width: 100px;
|
||||
&:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.contentName {
|
||||
min-width: 40px;
|
||||
color: #808080;
|
||||
flex-shrink: 0;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
line-height: 25px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.contentValue {
|
||||
color: #808080;
|
||||
line-height: 23px;
|
||||
font-weight: 500;
|
||||
border: 1px solid transparent;
|
||||
font-size: 14px;
|
||||
|
||||
&.info {
|
||||
color: rgb(90, 158, 247);
|
||||
background-color: rgb(245, 248, 249);
|
||||
border: 1px solid rgb(90, 158, 247);
|
||||
border-radius: 5px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.valueItem {
|
||||
.valueSubItem {
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&.alignCenter {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-right: 12px;
|
||||
min-width: 85px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btnList {
|
||||
padding: 0 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
height: 69px;
|
||||
flex-shrink: 0;
|
||||
border-top: 1px solid #f2f4f7;
|
||||
|
||||
/deep/ .el-button--small {
|
||||
height: 25px;
|
||||
padding: 0 30px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
class="nodeImportDialog"
|
||||
:title="$t('import.title')"
|
||||
:visible.sync="dialogVisible"
|
||||
width="300px"
|
||||
width="350px"
|
||||
>
|
||||
<el-upload
|
||||
ref="upload"
|
||||
@ -59,7 +59,7 @@
|
||||
<script>
|
||||
import xmind from 'simple-mind-map/src/parse/xmind.js'
|
||||
import markdown from 'simple-mind-map/src/parse/markdown.js'
|
||||
import { mapMutations, mapState } from 'vuex'
|
||||
import { mapMutations } from 'vuex'
|
||||
import Vue from 'vue'
|
||||
|
||||
// 导入
|
||||
@ -71,23 +71,13 @@ export default {
|
||||
selectPromiseResolve: null,
|
||||
xmindCanvasSelectDialogVisible: false,
|
||||
selectCanvas: '',
|
||||
canvasList: []
|
||||
canvasList: [],
|
||||
mdStr: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
supportFreemind: state => state.supportFreemind,
|
||||
supportExcel: state => state.supportExcel
|
||||
}),
|
||||
supportFileStr() {
|
||||
let res = '.smm,.json,.xmind,.md'
|
||||
if (this.supportFreemind) {
|
||||
res += ',.mm'
|
||||
}
|
||||
if (this.supportExcel) {
|
||||
res += ',.xlsx'
|
||||
}
|
||||
return res
|
||||
return '.smm,.json,.xmind,.md'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@ -115,11 +105,7 @@ export default {
|
||||
},
|
||||
|
||||
getRegexp() {
|
||||
return new RegExp(
|
||||
`\.(smm|json|xmind|md${this.supportFreemind ? '|mm' : ''}${
|
||||
this.supportExcel ? '|xlsx' : ''
|
||||
})$`
|
||||
)
|
||||
return new RegExp(`\.(smm|json|xmind|md)$`)
|
||||
},
|
||||
|
||||
// 检查url中是否操作需要打开的文件
|
||||
@ -141,12 +127,8 @@ export default {
|
||||
this.handleSmm(data)
|
||||
} else if (type === 'xmind') {
|
||||
this.handleXmind(data)
|
||||
} else if (type === 'xlsx') {
|
||||
this.handleExcel(data)
|
||||
} else if (type === 'md') {
|
||||
this.handleMd(data)
|
||||
} else if (type === 'mm') {
|
||||
this.handleMm(data)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
@ -193,12 +175,8 @@ export default {
|
||||
this.handleSmm(file)
|
||||
} else if (/\.xmind$/.test(file.name)) {
|
||||
this.handleXmind(file)
|
||||
} else if (/\.xlsx$/.test(file.name)) {
|
||||
this.handleExcel(file)
|
||||
} else if (/\.md$/.test(file.name)) {
|
||||
this.handleMd(file)
|
||||
} else if (/\.mm$/.test(file.name)) {
|
||||
this.handleMm(file)
|
||||
}
|
||||
this.cancel()
|
||||
this.setActiveSidebar(null)
|
||||
@ -240,36 +218,6 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// 处理Freemind格式
|
||||
handleMm(file) {
|
||||
const fileReader = new FileReader()
|
||||
fileReader.readAsText(file.raw)
|
||||
fileReader.onload = async evt => {
|
||||
try {
|
||||
const data = await Vue.prototype.Freemind.freemindToSmm(
|
||||
evt.target.result,
|
||||
{
|
||||
// withStyle: true,
|
||||
transformImg: image => {
|
||||
return new Promise(resolve => {
|
||||
if (/^https?:\/\//.test(image)) {
|
||||
resolve({ url: image })
|
||||
} else {
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
this.$bus.$emit('setData', data)
|
||||
this.$message.success(this.$t('import.importSuccess'))
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.$message.error(this.$t('import.fileParsingFailed'))
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 显示xmind文件的多个画布选择弹窗
|
||||
showSelectXmindCanvasDialog(content) {
|
||||
this.canvasList = content
|
||||
@ -285,18 +233,6 @@ export default {
|
||||
this.selectCanvas = 0
|
||||
},
|
||||
|
||||
// 处理.xlsx文件
|
||||
async handleExcel(file) {
|
||||
try {
|
||||
const res = await Vue.prototype.Excel.excelTo(file.raw)
|
||||
this.$bus.$emit('setData', res)
|
||||
this.$message.success(this.$t('import.importSuccess'))
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.$message.error(this.$t('import.fileParsingFailed'))
|
||||
}
|
||||
},
|
||||
|
||||
// 处理markdown文件
|
||||
async handleMd(file) {
|
||||
let fileReader = new FileReader()
|
||||
|
||||
@ -1,177 +0,0 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="nodeLinkSelectDialog"
|
||||
:title="$t('nodeLink.linkToNode')"
|
||||
:visible.sync="dialogVisible"
|
||||
:show-close="false"
|
||||
append-to-body
|
||||
width="400px"
|
||||
>
|
||||
<div class="nodeTreeWrap customScrollbar">
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
class="outlineTree"
|
||||
node-key="uid"
|
||||
default-expand-all
|
||||
:class="{ isDark: isDark }"
|
||||
:data="treeData"
|
||||
:props="defaultProps"
|
||||
:highlight-current="true"
|
||||
:expand-on-click-node="false"
|
||||
@current-change="onCurrentChange"
|
||||
>
|
||||
</el-tree>
|
||||
</div>
|
||||
<div slot="footer" class="footer">
|
||||
<el-checkbox v-model="isAddReturn" style="margin-right: auto;">{{
|
||||
$t('nodeLink.addReturn')
|
||||
}}</el-checkbox>
|
||||
<el-button @click="cancel">{{ $t('dialog.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="confirm">{{
|
||||
$t('dialog.confirm')
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
nodeRichTextToTextWithWrap,
|
||||
htmlEscape
|
||||
} from 'simple-mind-map/src/utils'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
mindMap: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
treeData: [],
|
||||
defaultProps: {
|
||||
label: 'label'
|
||||
},
|
||||
currentNodeData: null,
|
||||
node: null,
|
||||
isAddReturn: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
isDark: state => state.localConfig.isDark
|
||||
})
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('show_link_node', this.onShowDialog)
|
||||
this.mindMap.on('node_link_not_find', this.onNodeLinkNotFind)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('show_link_node', this.onShowDialog)
|
||||
this.mindMap.off('node_link_not_find', this.onNodeLinkNotFind)
|
||||
},
|
||||
methods: {
|
||||
onShowDialog(node) {
|
||||
this.node = node
|
||||
let data = this.mindMap.getData()
|
||||
let walk = root => {
|
||||
let text = root.data.richText
|
||||
? nodeRichTextToTextWithWrap(root.data.text)
|
||||
: root.data.text
|
||||
text = htmlEscape(text)
|
||||
text = text.replace(/\n/g, '<br>')
|
||||
root.label = text
|
||||
root.uid = root.data.uid
|
||||
if (root.children && root.children.length > 0) {
|
||||
root.children.forEach(item => {
|
||||
walk(item)
|
||||
})
|
||||
}
|
||||
}
|
||||
walk(data)
|
||||
this.treeData = [data]
|
||||
this.dialogVisible = true
|
||||
this.$nextTick(() => {
|
||||
const linkUid = node.getData('nodeLink')
|
||||
if (linkUid) {
|
||||
this.$refs.treeRef.setCurrentKey(linkUid)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
close() {
|
||||
this.dialogVisible = false
|
||||
this.node = null
|
||||
this.treeData = []
|
||||
this.currentNodeData = null
|
||||
this.isAddReturn = false
|
||||
},
|
||||
|
||||
// 当前选中的树节点变化事件
|
||||
onCurrentChange(data) {
|
||||
this.currentNodeData = data
|
||||
},
|
||||
|
||||
cancel() {
|
||||
this.close()
|
||||
},
|
||||
|
||||
confirm() {
|
||||
if (!this.currentNodeData) {
|
||||
this.$message.warning(this.$t('nodeLink.tip1'))
|
||||
return
|
||||
}
|
||||
if (this.currentNodeData.uid === this.node.getData('uid')) {
|
||||
this.$message.warning(this.$t('nodeLink.tip2'))
|
||||
return
|
||||
}
|
||||
this.$bus.$emit(
|
||||
'execCommand',
|
||||
'SET_NODE_LINK',
|
||||
this.node,
|
||||
this.currentNodeData.uid,
|
||||
this.isAddReturn
|
||||
)
|
||||
this.$message.success(this.$t('nodeLink.tip3'))
|
||||
this.close()
|
||||
},
|
||||
|
||||
onNodeLinkNotFind(node) {
|
||||
this.$confirm(this.$t('nodeLink.tip5'), this.$t('edit.tip'), {
|
||||
confirmButtonText: this.$t('setting.confirm'),
|
||||
cancelButtonText: this.$t('setting.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$bus.$emit('execCommand', 'SET_NODE_LINK', node, null)
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: this.$t('nodeLink.tip4')
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.nodeLinkSelectDialog {
|
||||
/deep/ .el-dialog__body {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
.nodeTreeWrap {
|
||||
height: 400px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
<style lang="less" scoped>
|
||||
@import url('../../../style/outlineTree.less');
|
||||
</style>
|
||||
@ -80,7 +80,7 @@
|
||||
@click="toggleDark"
|
||||
></div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<!-- <div class="item">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('navigatorToolbar.changeSourceCodeEdit')"
|
||||
@ -88,19 +88,39 @@
|
||||
>
|
||||
<div class="btn iconfont iconyuanma" @click="openSourceCodeEdit"></div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="item">
|
||||
<Demonstrate :isDark="isDark" :mindMap="mindMap"></Demonstrate>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-dropdown @command="handleCommand">
|
||||
<div class="btn iconfont iconbangzhu"></div>
|
||||
<div class="btn el-icon-more"></div>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="client">下载客户端</el-dropdown-item>
|
||||
<el-dropdown-item command="github">Github</el-dropdown-item>
|
||||
<el-dropdown-item command="site">官方网站</el-dropdown-item>
|
||||
<el-dropdown-item command="issue">意见反馈</el-dropdown-item>
|
||||
<el-dropdown-item disabled>当前:v{{ version }}</el-dropdown-item>
|
||||
<el-dropdown-item command="shortcutKey">
|
||||
<span class="iconfont iconjianpan"></span>
|
||||
{{ $t('navigatorToolbar.shortcutKeys') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="aiChat">
|
||||
<span class="iconfont iconAIshengcheng"></span>
|
||||
{{ $t('navigatorToolbar.ai') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="client">
|
||||
<span class="iconfont iconxiazai"></span>
|
||||
{{ $t('navigatorToolbar.downloadClient') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="github">
|
||||
<span class="iconfont icongithub"></span>
|
||||
Github
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="site">
|
||||
<span class="iconfont iconwangzhan"></span>
|
||||
{{ $t('navigatorToolbar.site') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item disabled
|
||||
>{{ $t('navigatorToolbar.current') }}v{{
|
||||
version
|
||||
}}</el-dropdown-item
|
||||
>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
@ -149,7 +169,12 @@ export default {
|
||||
this.lang = getLang()
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setLocalConfig', 'setIsReadonly', 'setIsSourceCodeEdit']),
|
||||
...mapMutations([
|
||||
'setLocalConfig',
|
||||
'setIsReadonly',
|
||||
'setIsSourceCodeEdit',
|
||||
'setActiveSidebar'
|
||||
]),
|
||||
|
||||
readonlyChange() {
|
||||
this.setIsReadonly(!this.isReadonly)
|
||||
@ -178,6 +203,20 @@ export default {
|
||||
},
|
||||
|
||||
handleCommand(command) {
|
||||
if (command === 'shortcutKey') {
|
||||
this.setActiveSidebar('shortcutKey')
|
||||
return
|
||||
} else if (command === 'aiChat') {
|
||||
this.setActiveSidebar('ai')
|
||||
return
|
||||
} else if (command === 'client') {
|
||||
this.$bus.$emit(
|
||||
'showDownloadTip',
|
||||
this.$t('navigatorToolbar.downloadClient'),
|
||||
this.$t('navigatorToolbar.downloadDesc')
|
||||
)
|
||||
return
|
||||
}
|
||||
let url = ''
|
||||
switch (command) {
|
||||
case 'github':
|
||||
@ -196,8 +235,7 @@ export default {
|
||||
case 'issue':
|
||||
url = 'https://github.com/wanglin2/mind-map/issues/new'
|
||||
break
|
||||
case 'client':
|
||||
url = 'https://pan.baidu.com/s/1huasEbKsGNH2Af68dvWiOg?pwd=3bp3'
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@ -1,275 +0,0 @@
|
||||
<template>
|
||||
<el-popover placement="bottom" width="200" trigger="click">
|
||||
<div class="annotationConfigBox" :class="{ isDark: isDark }">
|
||||
<div class="annotationConfigItem">
|
||||
<span class="name">{{ $t('annotation.show') }}</span>
|
||||
<el-switch
|
||||
v-model="show"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
@change="onChange"
|
||||
>
|
||||
</el-switch>
|
||||
</div>
|
||||
<template v-if="show">
|
||||
<div class="annotationConfigItem">
|
||||
<span class="name">{{ $t('annotation.type') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
v-model="annotationConfig.type"
|
||||
@change="onChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in annotationTypeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="annotationConfigItem">
|
||||
<span class="name">{{ $t('annotation.color') }}</span>
|
||||
<span
|
||||
class="block"
|
||||
v-popover:popover
|
||||
:style="{ backgroundColor: annotationConfig.color }"
|
||||
></span>
|
||||
<el-popover ref="popover" placement="bottom" trigger="hover">
|
||||
<Color
|
||||
:color="annotationConfig.color"
|
||||
@change="onColorChange"
|
||||
></Color>
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="annotationConfigItem">
|
||||
<span class="name">{{ $t('annotation.lineWidth') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
v-model="annotationConfig.strokeWidth"
|
||||
placeholder=""
|
||||
@change="onChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in lineWidthList"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
>
|
||||
<span
|
||||
v-if="item > 0"
|
||||
class="borderLine"
|
||||
:class="{ isDark: isDark }"
|
||||
:style="{ height: item + 'px' }"
|
||||
></span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="annotationConfigItem">
|
||||
<span class="name">{{ $t('annotation.padding') }}</span>
|
||||
<el-input-number
|
||||
v-model="annotationConfig.padding"
|
||||
:step="5"
|
||||
size="mini"
|
||||
@change="onChange"
|
||||
></el-input-number>
|
||||
</div>
|
||||
<div class="annotationConfigItem">
|
||||
<span class="name">{{ $t('annotation.animate') }}</span>
|
||||
<el-switch
|
||||
v-model="annotationConfig.animate"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
@change="onChange"
|
||||
>
|
||||
</el-switch>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div
|
||||
slot="reference"
|
||||
class="toolbarBtn"
|
||||
:style="{
|
||||
marginLeft: dir === 'v' || rightHasBtn ? '0px' : '20px',
|
||||
marginTop: dir === 'v' ? '10px' : '0px',
|
||||
marginRight: rightHasBtn ? '20px' : '0px',
|
||||
marginBottom: dir === 'v' && rightHasBtn ? '10px' : '0px'
|
||||
}"
|
||||
:class="{
|
||||
disabled: activeNodes.length <= 0 || hasGeneralization
|
||||
}"
|
||||
>
|
||||
<span class="icon iconfont iconhighlight"></span>
|
||||
<span class="text">{{ $t('annotation.mark') }}</span>
|
||||
</div>
|
||||
</el-popover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { lineWidthList } from '@/config'
|
||||
import Color from './Color.vue'
|
||||
|
||||
const defaultConfig = {
|
||||
type: 'circle',
|
||||
color: '',
|
||||
strokeWidth: 1,
|
||||
animate: true,
|
||||
padding: 20
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Color
|
||||
},
|
||||
props: {
|
||||
isDark: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
dir: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
rightHasBtn: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lineWidthList: lineWidthList.slice(1),
|
||||
activeNodes: [],
|
||||
show: false,
|
||||
annotationConfig: {
|
||||
...defaultConfig
|
||||
},
|
||||
annotationTypeList: [
|
||||
{
|
||||
label: '圆',
|
||||
value: 'circle'
|
||||
},
|
||||
{
|
||||
label: '边框',
|
||||
value: 'box'
|
||||
},
|
||||
{
|
||||
label: '高亮',
|
||||
value: 'highlight'
|
||||
},
|
||||
{
|
||||
label: '下划线',
|
||||
value: 'underline'
|
||||
},
|
||||
{
|
||||
label: '删除线',
|
||||
value: 'strike-through'
|
||||
},
|
||||
{
|
||||
label: '叉',
|
||||
value: 'crossed-off'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasGeneralization() {
|
||||
return (
|
||||
this.activeNodes.findIndex(node => {
|
||||
return node.isGeneralization
|
||||
}) !== -1
|
||||
)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$bus.$on('node_active', this.onNodeActive)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('node_active', this.onNodeActive)
|
||||
},
|
||||
methods: {
|
||||
onNodeActive(...args) {
|
||||
this.activeNodes = [...args[1]]
|
||||
const node = this.activeNodes[0]
|
||||
if (node) {
|
||||
const notationData = node.getData('notation')
|
||||
if (notationData) {
|
||||
const { show, config } = notationData
|
||||
this.show = show
|
||||
this.annotationConfig = {
|
||||
...defaultConfig,
|
||||
...config
|
||||
}
|
||||
} else {
|
||||
this.reset()
|
||||
}
|
||||
} else {
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
|
||||
reset() {
|
||||
this.show = false
|
||||
this.annotationConfig = {
|
||||
...defaultConfig
|
||||
}
|
||||
},
|
||||
|
||||
onChange() {
|
||||
this.$emit('setAnnotation', this.show, {
|
||||
...this.annotationConfig
|
||||
})
|
||||
},
|
||||
|
||||
onColorChange(color) {
|
||||
this.annotationConfig.color = color
|
||||
this.onChange()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.annotationConfigBox {
|
||||
&.isDark {
|
||||
.annotationConfigItem {
|
||||
.name {
|
||||
color: hsla(0, 0%, 100%, 0.9);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.annotationConfigItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.name {
|
||||
flex-shrink: 0;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.block {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.borderLine {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
background-color: #000;
|
||||
|
||||
&.isDark {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,133 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
class="nodeAttachmentContextMenu"
|
||||
:style="{
|
||||
left: this.left + 'px',
|
||||
top: this.top + 'px',
|
||||
visibility: show ? 'visible' : 'hidden'
|
||||
}"
|
||||
@click.stop="deleteAttachment"
|
||||
>
|
||||
<div class="menuItem">{{ $t('attachment.deleteAttachment') }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
mindMap: {
|
||||
type: Object,
|
||||
default() {
|
||||
return null
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
left: 0,
|
||||
top: 0,
|
||||
node: null,
|
||||
icon: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('node_attachmentClick', this.onNodeAttachmentClick)
|
||||
this.$bus.$on('selectAttachment', this.onSelectAttachment)
|
||||
this.$bus.$on(
|
||||
'node_attachmentContextmenu',
|
||||
this.onNodeAttachmentContextmenu
|
||||
)
|
||||
this.$bus.$on('hide', this.hide)
|
||||
document.body.addEventListener('click', this.hide)
|
||||
this.$bus.$on('node_active', this.hide)
|
||||
this.$bus.$on('scale', this.onScale)
|
||||
this.$bus.$on('translate', this.onScale)
|
||||
this.$bus.$on('svg_mousedown', this.hide)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('node_attachmentClick', this.onNodeAttachmentClick)
|
||||
this.$bus.$off('selectAttachment', this.onSelectAttachment)
|
||||
this.$bus.$off(
|
||||
'node_attachmentContextmenu',
|
||||
this.onNodeAttachmentContextmenu
|
||||
)
|
||||
this.$bus.$off('hide', this.hide)
|
||||
document.body.removeEventListener('click', this.hide)
|
||||
this.$bus.$off('node_active', this.hide)
|
||||
this.$bus.$off('scale', this.onScale)
|
||||
this.$bus.$off('translate', this.onScale)
|
||||
this.$bus.$off('svg_mousedown', this.hide)
|
||||
},
|
||||
methods: {
|
||||
// 选择附件
|
||||
onSelectAttachment(activeNodes) {
|
||||
// activeNodes.forEach(node => {
|
||||
// node.setAttachment('/test.md', '我去')
|
||||
// })
|
||||
},
|
||||
|
||||
// 点击附件图标,一般用来打开或下载附件
|
||||
onNodeAttachmentClick(node, e, icon) {
|
||||
// console.log(node.getData('attachmentUrl'))
|
||||
this.$message.info(this.$t('attachment.tip'))
|
||||
},
|
||||
|
||||
// 显示删除浮层
|
||||
onNodeAttachmentContextmenu(node, e, icon) {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.node = node
|
||||
this.icon = icon
|
||||
this.updatePosition()
|
||||
this.show = true
|
||||
},
|
||||
|
||||
// 更新位置
|
||||
updatePosition() {
|
||||
const iconSize = this.mindMap.themeConfig.iconSize
|
||||
const { x, y } = this.icon.rbox()
|
||||
this.left = x + iconSize
|
||||
this.top = y
|
||||
},
|
||||
|
||||
// 画布缩放事件
|
||||
onScale() {
|
||||
if (!this.node || !this.show) return
|
||||
this.updatePosition()
|
||||
},
|
||||
|
||||
// 删除附件
|
||||
deleteAttachment() {
|
||||
if (!this.node || !this.show) return
|
||||
this.node.setAttachment('', '')
|
||||
this.hide()
|
||||
},
|
||||
|
||||
// 隐藏浮层
|
||||
hide() {
|
||||
this.show = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.nodeAttachmentContextMenu {
|
||||
position: fixed;
|
||||
background-color: #fff;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.06);
|
||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||
|
||||
.menuItem {
|
||||
font-size: 14px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -72,7 +72,7 @@ export default {
|
||||
this.reset()
|
||||
if (this.activeNodes.length > 0) {
|
||||
let firstNode = this.activeNodes[0]
|
||||
let img = firstNode.getData('image') || ''
|
||||
let img = firstNode.getImageUrl() || ''
|
||||
if (img) {
|
||||
if (/^https?:\/\//.test(img)) {
|
||||
this.imgUrl = img
|
||||
|
||||
@ -29,7 +29,7 @@ export default {
|
||||
onNodeTmgDblclick(node, e) {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.images = [node.nodeData.data.image]
|
||||
this.images = [node.getImageUrl()]
|
||||
this.$viewerApi({
|
||||
images: this.images
|
||||
})
|
||||
|
||||
@ -256,26 +256,6 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 是否开启手绘风格 -->
|
||||
<div class="row" v-if="supportHandDrawnLikeStyle">
|
||||
<div class="rowItem">
|
||||
<el-checkbox
|
||||
v-model="localConfigs.isUseHandDrawnLikeStyle"
|
||||
@change="updateLocalConfig('isUseHandDrawnLikeStyle', $event)"
|
||||
>{{ $t('setting.isUseHandDrawnLikeStyle') }}</el-checkbox
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 是否开启动量效果 -->
|
||||
<div class="row" v-if="supportMomentum">
|
||||
<div class="rowItem">
|
||||
<el-checkbox
|
||||
v-model="localConfigs.isUseMomentum"
|
||||
@change="updateLocalConfig('isUseMomentum', $event)"
|
||||
>{{ $t('setting.isUseMomentum') }}</el-checkbox
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 配置鼠标滚轮行为 -->
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
@ -443,8 +423,6 @@ export default {
|
||||
enableNodeRichText: true,
|
||||
localConfigs: {
|
||||
isShowScrollbar: false,
|
||||
isUseHandDrawnLikeStyle: false,
|
||||
isUseMomentum: false,
|
||||
enableDragImport: false,
|
||||
enableAi: false
|
||||
}
|
||||
@ -454,9 +432,7 @@ export default {
|
||||
...mapState({
|
||||
activeSidebar: state => state.activeSidebar,
|
||||
localConfig: state => state.localConfig,
|
||||
isDark: state => state.localConfig.isDark,
|
||||
supportHandDrawnLikeStyle: state => state.supportHandDrawnLikeStyle,
|
||||
supportMomentum: state => state.supportMomentum
|
||||
isDark: state => state.localConfig.isDark
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
@ -483,7 +459,13 @@ export default {
|
||||
// 初始化其他配置
|
||||
initConfig() {
|
||||
Object.keys(this.config).forEach(key => {
|
||||
this.config[key] = this.mindMap.getConfig(key)
|
||||
if (typeof this.config[key] === 'object') {
|
||||
this.config[key] = {
|
||||
...(this.mindMap.getConfig(key) || {})
|
||||
}
|
||||
} else {
|
||||
this.config[key] = this.mindMap.getConfig(key)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
@ -1,214 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
class="sourceCodeEditContainer"
|
||||
:class="{ isDark: isDark }"
|
||||
ref="sourceCodeEditContainer"
|
||||
v-if="isSourceCodeEdit"
|
||||
>
|
||||
<div class="closeBtn">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('sourceCodeEdit.copy')"
|
||||
placement="top"
|
||||
>
|
||||
<span
|
||||
class="icon iconfont iconfuzhi"
|
||||
style="font-size: 26px"
|
||||
@click="copy"
|
||||
></span>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('sourceCodeEdit.format')"
|
||||
placement="top"
|
||||
>
|
||||
<span
|
||||
class="icon iconfont icongeshihua"
|
||||
style="font-size: 24px"
|
||||
@click="format"
|
||||
></span>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('sourceCodeEdit.sourceCodeTip')"
|
||||
placement="top"
|
||||
>
|
||||
<span class="icon el-icon-info"></span>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('sourceCodeEdit.confirm')"
|
||||
placement="top"
|
||||
>
|
||||
<span class="icon el-icon-circle-check" @click="onConfirm"></span>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('sourceCodeEdit.close')"
|
||||
placement="top"
|
||||
>
|
||||
<span class="icon iconfont iconguanbi" @click="onClose"></span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="sourceCodeEditBox">
|
||||
<div class="outlineEdit" ref="outlineEditRef" @keydown.stop></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapMutations } from 'vuex'
|
||||
import CodeMirror from 'codemirror'
|
||||
import 'codemirror/mode/javascript/javascript'
|
||||
import 'codemirror/lib/codemirror.css'
|
||||
import { copy } from '@/utils/index'
|
||||
|
||||
let editor = null
|
||||
|
||||
// 源码编辑
|
||||
export default {
|
||||
props: {
|
||||
mindMap: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
isReadonly: state => state.isReadonly,
|
||||
isDark: state => state.localConfig.isDark,
|
||||
isSourceCodeEdit: state => state.isSourceCodeEdit
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
isSourceCodeEdit(val) {
|
||||
if (val) {
|
||||
this.$nextTick(() => {
|
||||
document.body.appendChild(this.$refs.sourceCodeEditContainer)
|
||||
this.initEditor()
|
||||
this.initData()
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setIsSourceCodeEdit']),
|
||||
|
||||
// 初始化编辑器
|
||||
initEditor() {
|
||||
editor = CodeMirror(this.$refs.outlineEditRef, {
|
||||
mode: { name: 'javascript', json: true },
|
||||
lineWrapping: true,
|
||||
lineNumbers: true
|
||||
})
|
||||
},
|
||||
|
||||
// 初始化数据
|
||||
initData() {
|
||||
editor.setValue(JSON.stringify(this.mindMap.getData(), null, 2))
|
||||
},
|
||||
|
||||
// 完成
|
||||
onConfirm() {
|
||||
try {
|
||||
const content = editor.getValue()
|
||||
const data = JSON.parse(content)
|
||||
this.setIsSourceCodeEdit(false)
|
||||
this.$bus.$emit('setData', data)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.$message.error(this.$t('sourceCodeEdit.formatErrorTip'))
|
||||
}
|
||||
},
|
||||
|
||||
// 关闭
|
||||
onClose() {
|
||||
this.setIsSourceCodeEdit(false)
|
||||
},
|
||||
|
||||
// 复制
|
||||
copy() {
|
||||
const content = editor.getValue()
|
||||
copy(content)
|
||||
this.$message.success(this.$t('sourceCodeEdit.copyTip'))
|
||||
},
|
||||
|
||||
// 格式化
|
||||
format() {
|
||||
try {
|
||||
const content = editor.getValue()
|
||||
const data = JSON.parse(content)
|
||||
editor.setValue(JSON.stringify(data, null, 2))
|
||||
this.$message.success(this.$t('sourceCodeEdit.formatTip'))
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.$message.error(this.$t('sourceCodeEdit.formatErrorTip'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sourceCodeEditContainer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1999;
|
||||
background-color: #f5f5f5;
|
||||
overflow: hidden;
|
||||
|
||||
&.isDark {
|
||||
background-color: #262a2e;
|
||||
|
||||
.closeBtn {
|
||||
.icon {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.closeBtn {
|
||||
position: absolute;
|
||||
right: 40px;
|
||||
top: 20px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
font-size: 28px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.sourceCodeEditBox {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
padding: 50px 0;
|
||||
|
||||
.outlineEdit {
|
||||
width: 1000px;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
font-size: 17px;
|
||||
background-color: #fff;
|
||||
font-family: Menlo, Monaco, Consolas, Andale Mono, Ubuntu Mono,
|
||||
Courier New, monospace;
|
||||
padding: 12px;
|
||||
border-radius: 5px;
|
||||
|
||||
/deep/ .CodeMirror {
|
||||
height: 100%;
|
||||
font-family: Menlo, Monaco, Consolas, Andale Mono, Ubuntu Mono,
|
||||
Courier New, monospace;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -49,19 +49,15 @@ export default {
|
||||
computed: {
|
||||
...mapState({
|
||||
isDark: state => state.localConfig.isDark,
|
||||
activeSidebar: state => state.activeSidebar,
|
||||
supportRightFishbone: state => state.supportRightFishbone
|
||||
activeSidebar: state => state.activeSidebar
|
||||
}),
|
||||
|
||||
layoutGroupList() {
|
||||
const groupList = layoutGroupList[this.$i18n.locale] || layoutGroupList.zh
|
||||
return groupList.map(group => {
|
||||
let list = [...group.list]
|
||||
if (!this.supportRightFishbone) {
|
||||
list = list.filter(item => {
|
||||
return !['rightFishbone', 'rightFishbone2'].includes(item)
|
||||
})
|
||||
}
|
||||
let list = [...group.list].filter(item => {
|
||||
return !['rightFishbone', 'rightFishbone2'].includes(item)
|
||||
})
|
||||
return {
|
||||
name: group.name,
|
||||
list
|
||||
|
||||
@ -437,52 +437,9 @@
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 流动效果 -->
|
||||
<div class="row" v-if="supportLineFlow">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('style.openLineFlow') }}</span>
|
||||
<el-checkbox
|
||||
v-model="style.lineFlow"
|
||||
@change="update('lineFlow')"
|
||||
></el-checkbox>
|
||||
</div>
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('style.direction') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
v-model="style.lineFlowForward"
|
||||
placeholder=""
|
||||
@change="update('lineFlowForward')"
|
||||
>
|
||||
<el-option
|
||||
key="1"
|
||||
:label="$t('style.forward')"
|
||||
:value="true"
|
||||
></el-option>
|
||||
<el-option
|
||||
key="2"
|
||||
:label="$t('style.reverse')"
|
||||
:value="false"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="supportLineFlow">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('style.lineFlowDuration') }}</span>
|
||||
<el-input-number
|
||||
v-model="style.lineFlowDuration"
|
||||
@change="update('lineFlowDuration')"
|
||||
:min="0.1"
|
||||
size="mini"
|
||||
:step="0.5"
|
||||
></el-input-number>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 节点内边距 -->
|
||||
<div class="title noTop">{{ $t('style.nodePadding') }}</div>
|
||||
<div class="row">
|
||||
<div class="title">{{ $t('style.nodePadding') }}</div>
|
||||
<div class="row noBottom">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('style.horizontal') }}</span>
|
||||
<el-slider
|
||||
@ -503,7 +460,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 节点图片布局 -->
|
||||
<div class="title noTop">{{ $t('style.img') }}</div>
|
||||
<div class="title">{{ $t('style.img') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('style.placement') }}</span>
|
||||
@ -528,7 +485,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 节点标签布局 -->
|
||||
<div class="title noTop">{{ $t('style.tag') }}</div>
|
||||
<div class="title">{{ $t('style.tag') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">{{ $t('style.placement') }}</span>
|
||||
@ -623,8 +580,7 @@ export default {
|
||||
computed: {
|
||||
...mapState({
|
||||
isDark: state => state.localConfig.isDark,
|
||||
activeSidebar: state => state.activeSidebar,
|
||||
supportLineFlow: state => state.supportLineFlow
|
||||
activeSidebar: state => state.activeSidebar
|
||||
}),
|
||||
fontFamilyList() {
|
||||
return fontFamilyList[this.$i18n.locale] || fontFamilyList.zh
|
||||
@ -635,23 +591,26 @@ export default {
|
||||
shapeList() {
|
||||
return [
|
||||
...(shapeList[this.$i18n.locale] || shapeList.zh),
|
||||
...this.mindMap.extendShapeList.map(item => {
|
||||
return {
|
||||
width: '40px',
|
||||
name: item.nameShow,
|
||||
value: item.name
|
||||
}
|
||||
})
|
||||
...this.mindMap.extendShapeList
|
||||
.filter(item => {
|
||||
return !['fishHead'].includes(item.name)
|
||||
})
|
||||
.map(item => {
|
||||
return {
|
||||
width: '40px',
|
||||
name: item.nameShow,
|
||||
value: item.name
|
||||
}
|
||||
})
|
||||
]
|
||||
},
|
||||
shapeListMap() {
|
||||
const map = shapeListMap[this.$i18n.locale] || shapeListMap.zh
|
||||
const map2 = {}
|
||||
this.mindMap.extendShapeList.forEach(item => {
|
||||
map2[item.name] = item.path
|
||||
})
|
||||
return {
|
||||
...map,
|
||||
...shapeListMap,
|
||||
...map2
|
||||
}
|
||||
},
|
||||
@ -854,7 +813,7 @@ export default {
|
||||
font-weight: 500;
|
||||
color: rgba(26, 26, 26, 0.9);
|
||||
margin-bottom: 10px;
|
||||
margin-top: 20px;
|
||||
margin-top: 35px;
|
||||
|
||||
&.noTop {
|
||||
margin-top: 0;
|
||||
@ -866,6 +825,10 @@ export default {
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&.noBottom {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.btnGroup {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
@ -178,13 +178,6 @@
|
||||
<span class="icon iconfont iconwaikuang"></span>
|
||||
<span class="text">{{ $t('toolbar.outerFrame') }}</span>
|
||||
</div>
|
||||
<NodeAnnotationBtn
|
||||
v-if="item === 'annotation' && supportMark"
|
||||
:isDark="isDark"
|
||||
:dir="dir"
|
||||
:rightHasBtn="annotationRightHasBtn"
|
||||
@setAnnotation="onSetAnnotation"
|
||||
></NodeAnnotationBtn>
|
||||
<div
|
||||
v-if="item === 'ai'"
|
||||
class="toolbarBtn"
|
||||
@ -202,10 +195,8 @@
|
||||
|
||||
<script>
|
||||
import { mapState, mapMutations } from 'vuex'
|
||||
import NodeAnnotationBtn from './NodeAnnotationBtn.vue'
|
||||
|
||||
export default {
|
||||
components: { NodeAnnotationBtn },
|
||||
props: {
|
||||
dir: {
|
||||
type: String,
|
||||
@ -231,8 +222,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
isDark: state => state.localConfig.isDark,
|
||||
supportMark: state => state.supportMark
|
||||
isDark: state => state.localConfig.isDark
|
||||
}),
|
||||
hasRoot() {
|
||||
return (
|
||||
|
||||
@ -16,10 +16,6 @@ const store = new Vuex.Store({
|
||||
useLeftKeySelectionRightKeyDrag: false,
|
||||
// 是否显示滚动条
|
||||
isShowScrollbar: false,
|
||||
// 是否开启手绘风格
|
||||
isUseHandDrawnLikeStyle: false,
|
||||
// 是否开启动量效果
|
||||
isUseMomentum: true,
|
||||
// 是否是暗黑模式
|
||||
isDark: false,
|
||||
// 是否开启AI功能
|
||||
@ -30,17 +26,6 @@ const store = new Vuex.Store({
|
||||
isReadonly: false, // 是否只读
|
||||
isSourceCodeEdit: false, // 是否是源码编辑模式
|
||||
extraTextOnExport: '', // 导出时底部添加的文字
|
||||
supportHandDrawnLikeStyle: false, // 是否支持设置手绘风格
|
||||
supportMark: false, // 是否支持标记
|
||||
supportNumbers: false, // 是否支持编号
|
||||
supportFreemind: false, // 是否支持Freemind插件
|
||||
supportExcel: false, // 是否支持Excel插件
|
||||
supportCheckbox: false, // 是否支持Checkbox插件
|
||||
supportLineFlow: false, // 是否支持LineFlow插件
|
||||
supportMomentum: false, // 是否支持Momentum插件
|
||||
supportRightFishbone: false, // 是否支持RightFishbone插件
|
||||
supportNodeLink: false, // 是否支持NodeLink插件
|
||||
supportMoreShapes: false, // 是否支持MoreShapes插件
|
||||
isDragOutlineTreeNode: false, // 当前是否正在拖拽大纲树的节点
|
||||
aiConfig: {
|
||||
api: 'http://ark.cn-beijing.volces.com/api/v3/chat/completions',
|
||||
@ -101,61 +86,6 @@ const store = new Vuex.Store({
|
||||
state.extraTextOnExport = data
|
||||
},
|
||||
|
||||
// 设置是否支持手绘风格
|
||||
setSupportHandDrawnLikeStyle(state, data) {
|
||||
state.supportHandDrawnLikeStyle = data
|
||||
},
|
||||
|
||||
// 设置是否支持标记
|
||||
setSupportMark(state, data) {
|
||||
state.supportMark = data
|
||||
},
|
||||
|
||||
// 设置是否支持编号
|
||||
setSupportNumbers(state, data) {
|
||||
state.supportNumbers = data
|
||||
},
|
||||
|
||||
// 设置是否支持Freemind插件
|
||||
setSupportFreemind(state, data) {
|
||||
state.supportFreemind = data
|
||||
},
|
||||
|
||||
// 设置是否支持Excel插件
|
||||
setSupportExcel(state, data) {
|
||||
state.supportExcel = data
|
||||
},
|
||||
|
||||
// 设置是否支持Checkbox插件
|
||||
setSupportCheckbox(state, data) {
|
||||
state.supportCheckbox = data
|
||||
},
|
||||
|
||||
// 设置是否支持Lineflow插件
|
||||
setSupportLineFlow(state, data) {
|
||||
state.supportLineFlow = data
|
||||
},
|
||||
|
||||
// 设置是否支持Momentum插件
|
||||
setSupportMomentum(state, data) {
|
||||
state.supportMomentum = data
|
||||
},
|
||||
|
||||
// 设置是否支持RightFishbone插件
|
||||
setSupportRightFishbone(state, data) {
|
||||
state.supportRightFishbone = data
|
||||
},
|
||||
|
||||
// 设置是否支持NodeLink插件
|
||||
setSupportNodeLink(state, data) {
|
||||
state.supportNodeLink = data
|
||||
},
|
||||
|
||||
// 设置是否支持MoreShapes插件
|
||||
setSupportMoreShapes(state, data) {
|
||||
state.supportMoreShapes = data
|
||||
},
|
||||
|
||||
// 设置树节点拖拽
|
||||
setIsDragOutlineTreeNode(state, data) {
|
||||
state.isDragOutlineTreeNode = data
|
||||
|
||||
@ -83,3 +83,13 @@ export const printOutline = el => {
|
||||
document.body.removeChild(iframe)
|
||||
}, 500)
|
||||
}
|
||||
|
||||
export const getParentWithClass = (el, className) => {
|
||||
if (el.classList.contains(className)) {
|
||||
return el
|
||||
}
|
||||
if (el.parentNode && el.parentNode !== document.body) {
|
||||
return getParentWithClass(el.parentNode, className)
|
||||
}
|
||||
return null
|
||||
}
|
||||