增加VIP的功能
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2479351 */
|
||||
src: url('iconfont.woff2?t=1739843331607') format('woff2'),
|
||||
url('iconfont.woff?t=1739843331607') format('woff'),
|
||||
url('iconfont.ttf?t=1739843331607') format('truetype');
|
||||
src: url('iconfont.woff2?t=1740018646112') format('woff2'),
|
||||
url('iconfont.woff?t=1740018646112') format('woff'),
|
||||
url('iconfont.ttf?t=1740018646112') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,6 +13,10 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.iconhuiyuan-:before {
|
||||
content: "\e615";
|
||||
}
|
||||
|
||||
.iconAIshengcheng:before {
|
||||
content: "\e6b5";
|
||||
}
|
||||
|
||||
BIN
web/src/assets/img/vip/1.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
web/src/assets/img/vip/2.jpg
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
web/src/assets/img/vip/3.jpg
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
web/src/assets/img/vip/4.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
web/src/assets/img/vip/5.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
web/src/assets/img/vip/6.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
web/src/assets/img/vip/7.gif
Normal file
|
After Width: | Height: | Size: 125 KiB |
BIN
web/src/assets/img/vip/8.gif
Normal file
|
After Width: | Height: | Size: 496 KiB |
@ -156,3 +156,5 @@ export const rainbowLinesOptions = [
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
export const vipFileUrl = 'https://simple-mind-map.oss-cn-beijing.aliyuncs.com/vip.json'
|
||||
@ -1,5 +1,6 @@
|
||||
import { BrowserWindow, ipcMain, shell } from 'electron'
|
||||
import { saveClientConfig, getClientConfig } from './storage'
|
||||
import { execSync } from 'child_process'
|
||||
|
||||
export const bindOtherHandleEvent = () => {
|
||||
// 处理缩放事件
|
||||
@ -26,4 +27,61 @@ export const bindOtherHandleEvent = () => {
|
||||
ipcMain.handle('getClientConfig', () => {
|
||||
return getClientConfig()
|
||||
})
|
||||
|
||||
// 获取机器码
|
||||
ipcMain.handle('getClientUUID', () => {
|
||||
try {
|
||||
if (process.platform === 'win32') {
|
||||
const stdout = execSync('wmic csproduct get uuid', {
|
||||
windowsHide: true
|
||||
})
|
||||
return stdout
|
||||
.toString()
|
||||
.split('\n')[1]
|
||||
.trim()
|
||||
} else if (process.platform === 'darwin') {
|
||||
const stdout = execSync('wmic csproduct get uuid', {
|
||||
windowsHide: true
|
||||
})
|
||||
return stdout
|
||||
.toString()
|
||||
.split('\n')[1]
|
||||
.trim()
|
||||
} else if (process.platform === 'linux') {
|
||||
if (require('fs').existsSync('/etc/machine-id')) {
|
||||
return require('fs')
|
||||
.readFileSync('/etc/machine-id')
|
||||
.toString()
|
||||
.trim()
|
||||
}
|
||||
const stdout = execSync('sudo dmidecode -s system-uuid', {
|
||||
timeout: 1000
|
||||
})
|
||||
return stdout.toString().trim()
|
||||
}
|
||||
} catch (e) {
|
||||
return [
|
||||
process.arch,
|
||||
process.env.COMPUTERNAME || process.env.HOSTNAME,
|
||||
Math.random()
|
||||
.toString(36)
|
||||
.slice(2)
|
||||
].join(':')
|
||||
}
|
||||
})
|
||||
|
||||
//
|
||||
ipcMain.handle('openExternal', (event, url) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
shell
|
||||
.openExternal(url)
|
||||
.then(() => {
|
||||
resolve()
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('openExternal失败:', err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -40,5 +40,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
||||
getIsMaximize: id => ipcRenderer.invoke('getIsMaximize', id),
|
||||
selectOpenFolder: () => ipcRenderer.invoke('selectOpenFolder'),
|
||||
getFilesInDir: (dir, ext) => ipcRenderer.invoke('getFilesInDir', dir, ext),
|
||||
checkFileExist: filePath => ipcRenderer.invoke('checkFileExist', filePath)
|
||||
checkFileExist: filePath => ipcRenderer.invoke('checkFileExist', filePath),
|
||||
getClientUUID: () => ipcRenderer.invoke('getClientUUID'),
|
||||
openExternal: url => ipcRenderer.invoke('openExternal', url),
|
||||
})
|
||||
|
||||
@ -93,14 +93,14 @@ 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 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'
|
||||
// npm link 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 simple-mind-map-plugin-themes simple-mind-map-plugin-lineflow simple-mind-map-plugin-momentum
|
||||
import OutlineSidebar from './OutlineSidebar'
|
||||
import Style from './Style'
|
||||
@ -147,6 +147,8 @@ import AssociativeLineStyle from './AssociativeLineStyle.vue'
|
||||
import NodeImgPlacementToolbar from './NodeImgPlacementToolbar.vue'
|
||||
import AiCreate from './AiCreate.vue'
|
||||
import AiChat from './AiChat.vue'
|
||||
import { vipFileUrl } from '@/config/constant'
|
||||
import axios from 'axios'
|
||||
|
||||
// 注册插件
|
||||
MindMap.usePlugin(MiniMap)
|
||||
@ -235,7 +237,8 @@ export default {
|
||||
extraTextOnExport: state => state.extraTextOnExport,
|
||||
isDragOutlineTreeNode: state => state.isDragOutlineTreeNode,
|
||||
isDark: state => state.localConfig.isDark,
|
||||
enableAi: state => state.localConfig.enableAi
|
||||
enableAi: state => state.localConfig.enableAi,
|
||||
isVIP: state => state.isVIP
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
@ -269,6 +272,7 @@ export default {
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
await this.getVipInfo()
|
||||
showLoading()
|
||||
// this.showNewFeatureInfo()
|
||||
await this.getData()
|
||||
@ -305,7 +309,20 @@ export default {
|
||||
this.mindMap.destroy()
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setFileName', 'setIsUnSave']),
|
||||
...mapMutations(['setFileName', 'setIsUnSave', 'setIsVIP']),
|
||||
|
||||
// 获取会员信息
|
||||
async getVipInfo() {
|
||||
try {
|
||||
const clientUUID = await window.electronAPI.getClientUUID()
|
||||
const { data } = await axios.get(vipFileUrl, {
|
||||
responseType: 'json'
|
||||
})
|
||||
this.setIsVIP(data.includes(clientUUID))
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
|
||||
handleStartTextEdit() {
|
||||
this.mindMap.renderer.startTextEdit()
|
||||
@ -735,39 +752,41 @@ export default {
|
||||
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 (this.isVIP) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -5,10 +5,39 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import { mapMutations } from 'vuex'
|
||||
import { vipFileUrl } from '@/config/constant'
|
||||
|
||||
export default {
|
||||
name: 'Workbenche',
|
||||
created() {
|
||||
document.title = '思绪思维导图'
|
||||
this.getVipInfo()
|
||||
this.$bus.$on('refreshVIP', this.getVipInfo)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('refreshVIP', this.getVipInfo)
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setIsVIP']),
|
||||
|
||||
// 获取会员信息
|
||||
async getVipInfo(showTip = false) {
|
||||
try {
|
||||
const clientUUID = await window.electronAPI.getClientUUID()
|
||||
const { data } = await axios.get(vipFileUrl, {
|
||||
responseType: 'json'
|
||||
})
|
||||
this.setIsVIP(data.includes(clientUUID))
|
||||
if (showTip) {
|
||||
this.$message.success('会员状态获取成功')
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.$message.error('会员信息获取失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -21,9 +21,9 @@
|
||||
<p>
|
||||
下载最新版本:
|
||||
<span @click="open('baiduNet')">百度云</span>
|
||||
<span @click="open('releases')">releases</span>
|
||||
<span @click="open('releases')">Github</span>
|
||||
</p>
|
||||
<p>如需进微信交流群参与讨论,可微信添加:wanglinguanfang。备注:客户端</p>
|
||||
<p style="font-size: 12px;">如需进微信交流群参与讨论,可微信添加:wanglinguanfang。备注:客户端</p>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
437
web/src/pages/Workbenche/components/VipDialog.vue
Normal file
@ -0,0 +1,437 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
class="vipDialog"
|
||||
title="思绪会员"
|
||||
:visible.sync="dialogVisible"
|
||||
width="700px"
|
||||
@close="onClose"
|
||||
>
|
||||
<div class="vipBox customScrollbar">
|
||||
<div class="statusBox">
|
||||
<div class="left" :class="{ isVIP: isVIP }">
|
||||
<span class="iconfont iconhuiyuan-"></span>您{{
|
||||
isVIP ? '已' : '还不'
|
||||
}}是会员~
|
||||
</div>
|
||||
<div class="center">
|
||||
<div class="btn" @click="vipFunctionDialogVisible = true">
|
||||
会员功能一览
|
||||
</div>
|
||||
</div>
|
||||
<div class="right"></div>
|
||||
</div>
|
||||
<div class="desc">
|
||||
<p>
|
||||
从0.13.1版本开始,<span class="btn" @click="open('plugins')"
|
||||
>SimpleMindMap付费插件</span
|
||||
>的功能在客户端中也需要付费才能使用。
|
||||
</p>
|
||||
<p>
|
||||
一定的收益可以带给开发者持续开发和维护的动力,希望您能理解。当然,您也可以选择安装之前的版本:<span
|
||||
class="btn"
|
||||
@click="open('baiduNet')"
|
||||
>百度云</span
|
||||
>或<span class="btn" @click="open('releases')">Github</span
|
||||
>。或者使用:<span class="btn" @click="open('online')">在线版</span
|
||||
>。
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
思绪会员为<span class="emphasize">终身制</span
|
||||
>,后续所有新出的功能均无需再次付费。目前价格为:<span
|
||||
class="emphasize"
|
||||
>¥100</span
|
||||
>。最多允许三台电脑使用。
|
||||
</p>
|
||||
<p>
|
||||
<strong>购买方式:</strong>扫码进行支付,请备注<span class="emphasize"
|
||||
>会员购买</span
|
||||
>,支付完成后,可以手动将下面的<span class="btn" @click="doCopy(uuid)"
|
||||
>机器码</span
|
||||
>发送到指定邮箱<span class="btn" @click="doCopy(mailAddress)">{{
|
||||
mailAddress
|
||||
}}</span
|
||||
>。
|
||||
<!-- 也可以直接点击:<span class="btn" @click="sendMail">一键发送</span
|
||||
>。 -->
|
||||
</p>
|
||||
<div class="desc">
|
||||
<p>
|
||||
最多可发送三个机器码,您可以打开其他需要使用的电脑安装思绪思维导图,然后打开会员弹窗复制机器码一并进行发送。当然,也可以日后再单独发送。
|
||||
</p>
|
||||
<p>
|
||||
如果您觉得发邮件比较麻烦,也可以直接微信添加:<span
|
||||
class="btn"
|
||||
@click="doCopy('wanglinguanfang')"
|
||||
>wanglinguanfang</span
|
||||
>。然后直接发送机器码即可。
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
<strong>支付方式:</strong>
|
||||
<span class="btn" @click="openPayDialog('alipay')"
|
||||
>点此支付宝支付</span
|
||||
>
|
||||
或
|
||||
<span class="btn" @click="openPayDialog('wechat')">点此微信支付</span>
|
||||
</p>
|
||||
<p class="row">
|
||||
<span class="text">机器码:</span>
|
||||
<el-input v-model="uuid" size="small" readonly>
|
||||
<el-button slot="append" @click="doCopy(uuid)">复制</el-button>
|
||||
</el-input>
|
||||
</p>
|
||||
<p class="row">
|
||||
<span class="text">邮箱地址:</span>
|
||||
<el-input v-model="mailAddress" size="small" readonly>
|
||||
<el-button slot="append" @click="doCopy(mailAddress)"
|
||||
>复制</el-button
|
||||
>
|
||||
</el-input>
|
||||
</p>
|
||||
<div class="desc">
|
||||
<p>
|
||||
温馨提醒:因为是人工录入,所以存在一定延迟,录入完成后会发送提醒邮件,当您收到邮件后可以尝试重新启动客户端,或者点击:<span
|
||||
class="btn"
|
||||
@click="refreshVIP"
|
||||
>刷新会员状态</span
|
||||
>。
|
||||
</p>
|
||||
<p>
|
||||
如有疑问,可添加微信咨询:<span
|
||||
class="btn"
|
||||
@click="doCopy('wanglinguanfang')"
|
||||
>wanglinguanfang</span
|
||||
>。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
class="qrCodeDialog"
|
||||
:title="showPayType === 'alipay' ? '支付宝扫码' : '微信扫码'"
|
||||
:visible.sync="qrCodeDialogVisible"
|
||||
width="400px"
|
||||
@close="qrCodeDialogVisible = false"
|
||||
>
|
||||
<div>
|
||||
<img
|
||||
src="../../../assets/img/alipay.jpg"
|
||||
alt=""
|
||||
v-if="showPayType === 'alipay'"
|
||||
/>
|
||||
<img
|
||||
src="../../../assets/img/wechat.jpg"
|
||||
alt=""
|
||||
v-if="showPayType === 'wechat'"
|
||||
/>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
class="vipFunctionDialog"
|
||||
title="会员功能一览"
|
||||
:visible.sync="vipFunctionDialogVisible"
|
||||
width="800px"
|
||||
@close="vipFunctionDialogVisible = false"
|
||||
>
|
||||
<div class="tableBox">
|
||||
<el-table :data="functionList" style="width: 100%;" height="450">
|
||||
<el-table-column
|
||||
type="index"
|
||||
width="50"
|
||||
:index="indexMethod"
|
||||
></el-table-column>
|
||||
<el-table-column prop="name" label="功能" width="150">
|
||||
</el-table-column>
|
||||
<el-table-column prop="desc" label="描述"> </el-table-column>
|
||||
<el-table-column prop="img" label="截图">
|
||||
<template slot-scope="scope">
|
||||
<img style="width: 200px;" :src="scope.row.img" alt="" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import { copy } from '@/utils'
|
||||
import img1 from '@/assets/img/vip/1.png'
|
||||
import img2 from '@/assets/img/vip/2.jpg'
|
||||
import img3 from '@/assets/img/vip/3.jpg'
|
||||
import img4 from '@/assets/img/vip/4.png'
|
||||
import img5 from '@/assets/img/vip/5.png'
|
||||
import img6 from '@/assets/img/vip/6.png'
|
||||
import img7 from '@/assets/img/vip/7.gif'
|
||||
import img8 from '@/assets/img/vip/8.gif'
|
||||
|
||||
const functionList = [
|
||||
{
|
||||
name: '手绘风格',
|
||||
desc:
|
||||
'开启后思维导图连线和形状会显示为手绘风格样式。可以在【设置】里开启或关闭。',
|
||||
img: img1
|
||||
},
|
||||
{
|
||||
name: '节点标记',
|
||||
desc:
|
||||
'可以标记单个节点,也就是可以在单个节点上加一个手绘风格的圈、背景、删除线等等,支持动画效果。',
|
||||
img: img2
|
||||
},
|
||||
{
|
||||
name: '节点编号',
|
||||
desc: '可以一键编号某个节点的子节点,支持多种编号形式,支持编号指定层级。',
|
||||
img: img3
|
||||
},
|
||||
{
|
||||
name: '导出Freemind文件',
|
||||
desc: '可以导入和导出Freemind软件的格式,即.mm文件格式。',
|
||||
img: img4
|
||||
},
|
||||
{
|
||||
name: '导出Excel文件',
|
||||
desc: '可以导入和导出Excel软件的格式,即.xlsx文件格式。',
|
||||
img: img5
|
||||
},
|
||||
{
|
||||
name: '节点待办',
|
||||
desc:
|
||||
'支持给节点添加待办,即可以给节点添加一个勾选框,点击勾选框可以切换完成和未完成的状态。',
|
||||
img: img6
|
||||
},
|
||||
{
|
||||
name: '节点连线流动效果',
|
||||
desc: '可以给节点连线添加流动效果,仅在连线为虚线的情况下生效。',
|
||||
img: img7
|
||||
},
|
||||
{
|
||||
name: '动量效果',
|
||||
desc:
|
||||
'开启后,鼠标按住拖动画布,然后松开后画布会根据惯性继续移动一段距离。可以在【设置】里开启或关闭。',
|
||||
img: img8
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
uuid: '',
|
||||
qrCodeDialogVisible: false,
|
||||
mailAddress: '1013335014@qq.com',
|
||||
showPayType: '',
|
||||
vipFunctionDialogVisible: false,
|
||||
functionList
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['isVIP'])
|
||||
},
|
||||
watch: {
|
||||
value(val, oldVal) {
|
||||
this.dialogVisible = val
|
||||
if (val) {
|
||||
this.getUUID()
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getUUID()
|
||||
},
|
||||
methods: {
|
||||
async getUUID() {
|
||||
try {
|
||||
if (this.uuid) return
|
||||
const clientUUID = await window.electronAPI.getClientUUID()
|
||||
this.uuid = clientUUID
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
|
||||
indexMethod(index) {
|
||||
return index + 1
|
||||
},
|
||||
|
||||
openPayDialog(type) {
|
||||
this.showPayType = type
|
||||
this.qrCodeDialogVisible = true
|
||||
},
|
||||
|
||||
doCopy(text) {
|
||||
copy(text)
|
||||
this.$message.success('复制成功')
|
||||
},
|
||||
|
||||
refreshVIP() {
|
||||
this.$bus.$emit('refreshVIP', true)
|
||||
},
|
||||
|
||||
async sendMail() {
|
||||
const mailtoUrl = `mailto:${
|
||||
this.mailAddress
|
||||
}?subject=${encodeURIComponent('会员购买')}&body=${encodeURIComponent(
|
||||
this.uuid
|
||||
)}`
|
||||
try {
|
||||
await window.electronAPI.openExternal(mailtoUrl)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.$message.error('一键发送失败,请手动发送')
|
||||
}
|
||||
},
|
||||
|
||||
onClose() {
|
||||
this.$emit('change', false)
|
||||
},
|
||||
|
||||
open(type) {
|
||||
let url = ''
|
||||
switch (type) {
|
||||
case 'plugins':
|
||||
url =
|
||||
'https://wanglin2.github.io/mind-map-docs/plugins/handDrawnLikeStyle.html'
|
||||
break
|
||||
case 'baiduNet':
|
||||
url = 'https://pan.baidu.com/s/1huasEbKsGNH2Af68dvWiOg?pwd=3bp3'
|
||||
break
|
||||
case 'releases':
|
||||
url = 'https://github.com/wanglin2/mind-map/releases'
|
||||
break
|
||||
case 'online':
|
||||
url = 'https://wanglin2.github.io/mind-map/'
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
window.electronAPI.openUrl(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.vipDialog,
|
||||
.qrCodeDialog,
|
||||
.vipFunctionDialog {
|
||||
/deep/ .el-dialog__body {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.vipFunctionDialog {
|
||||
.tableBox {
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.qrCodeDialog {
|
||||
div {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.vipBox {
|
||||
padding: 20px;
|
||||
padding-top: 0;
|
||||
height: 400px;
|
||||
overflow-y: auto;
|
||||
|
||||
.statusBox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.left {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #f56c6c;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
|
||||
&.isVIP {
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.right,
|
||||
.center {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.btn {
|
||||
font-weight: bold;
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.desc {
|
||||
padding: 12px;
|
||||
background-color: #f5f5f5;
|
||||
margin: 12px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.text {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.btn {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.emphasize {
|
||||
font-weight: bold;
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -10,11 +10,15 @@
|
||||
<div class="workbencheHomeHeader">
|
||||
<MacControl></MacControl>
|
||||
<div class="rightBar">
|
||||
<div
|
||||
class="vipBtn iconfont iconhuiyuan-"
|
||||
@click="showVipDialog = true"
|
||||
></div>
|
||||
<el-dropdown @command="handleCommand" style="margin-right: 12px;">
|
||||
<span class="settingBtn el-icon-setting"></span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="about">关于软件</el-dropdown-item>
|
||||
<el-dropdown-item command="sponsor">友情赞助</el-dropdown-item>
|
||||
<!-- <el-dropdown-item command="sponsor">友情赞助</el-dropdown-item> -->
|
||||
<el-dropdown-item command="help">使用帮助</el-dropdown-item>
|
||||
<el-dropdown-item command="doc">开发文档</el-dropdown-item>
|
||||
<el-dropdown-item command="setting">设置</el-dropdown-item>
|
||||
@ -30,6 +34,7 @@
|
||||
<AboutDialog v-model="showAboutDialog"></AboutDialog>
|
||||
<SponsorDialog v-model="showSponsorDialog"></SponsorDialog>
|
||||
<SettingDialog v-model="showSettingDialog"></SettingDialog>
|
||||
<VipDialog v-model="showVipDialog"></VipDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -41,6 +46,7 @@ import FileList from '../components/FileList.vue'
|
||||
import AboutDialog from '../components/AboutDialog.vue'
|
||||
import SponsorDialog from '../components/SponsorDialog.vue'
|
||||
import SettingDialog from '../components/SettingDialog.vue'
|
||||
import VipDialog from '../components/VipDialog.vue'
|
||||
import { getLocalConfig } from '@/api'
|
||||
import { mapState, mapActions, mapMutations } from 'vuex'
|
||||
|
||||
@ -52,13 +58,15 @@ export default {
|
||||
FileList,
|
||||
AboutDialog,
|
||||
SponsorDialog,
|
||||
SettingDialog
|
||||
SettingDialog,
|
||||
VipDialog
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showAboutDialog: false,
|
||||
showSponsorDialog: false,
|
||||
showSettingDialog: false
|
||||
showSettingDialog: false,
|
||||
showVipDialog: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -75,6 +83,9 @@ export default {
|
||||
this.initLocalConfig()
|
||||
this.setBodyDark()
|
||||
},
|
||||
mounted() {
|
||||
this.showTip()
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setLocalConfig']),
|
||||
|
||||
@ -164,6 +175,27 @@ export default {
|
||||
onDragleave(e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
},
|
||||
|
||||
showTip() {
|
||||
const isTipped = localStorage.getItem('vip_tip')
|
||||
if (!isTipped) {
|
||||
const n = this.$notify({
|
||||
title: '提示',
|
||||
dangerouslyUseHTMLString: true,
|
||||
message:
|
||||
'会员功能上线了~<span style="color: #409eff; font-weight: bold; cursor: pointer;">点击了解</span>一下吧。',
|
||||
duration: 0,
|
||||
onClick: () => {
|
||||
this.showVipDialog = true
|
||||
n.close()
|
||||
localStorage.setItem('vip_tip', true)
|
||||
},
|
||||
onClose: () => {
|
||||
localStorage.setItem('vip_tip', true)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -211,6 +243,14 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.vipBtn {
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
color: #e6a23c;
|
||||
font-weight: bold;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.settingBtn {
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
|
||||
@ -51,7 +51,8 @@ const store = new Vuex.Store({
|
||||
port: 3456,
|
||||
method: 'POST'
|
||||
},
|
||||
currentFolder: '' // 当前打开的目录
|
||||
currentFolder: '', // 当前打开的目录
|
||||
isVIP: false // 是否是会员
|
||||
},
|
||||
mutations: {
|
||||
// 设置本地文件名
|
||||
@ -172,6 +173,11 @@ const store = new Vuex.Store({
|
||||
// 设置树节点拖拽
|
||||
setIsDragOutlineTreeNode(state, data) {
|
||||
state.isDragOutlineTreeNode = data
|
||||
},
|
||||
|
||||
// 设置是否是会员
|
||||
setIsVIP(state, data) {
|
||||
state.isVIP = data
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
||||