feat(app): 兼容darwin版本浏览跳转,保存图片文件等功能

This commit is contained in:
Gico001 2025-07-10 14:49:10 +08:00
parent 58f3009902
commit bbd4bb5b48
9 changed files with 334 additions and 123 deletions

79
app.go
View File

@ -14,6 +14,7 @@ import (
"go-stock/backend/logger"
"go-stock/backend/models"
"os"
"path/filepath"
"strings"
"time"
@ -1201,3 +1202,81 @@ func (a *App) GetStockMoneyTrendByDay(stockCode string, days int) []map[string]a
slice.Reverse(res)
return res
}
// OpenURL
//
// @Description: 跨平台打开默认浏览器
// @receiver a
// @param url
func (a *App) OpenURL(url string) {
runtime.BrowserOpenURL(a.ctx, url)
}
// SaveImage
//
// @Description: 跨平台保存图片
// @receiver a
// @param name
// @param base64Data
// @return error
func (a *App) SaveImage(name, base64Data string) string {
// 打开保存文件对话框
filePath, err := runtime.SaveFileDialog(a.ctx, runtime.SaveDialogOptions{
Title: "保存图片",
DefaultFilename: name + "AI分析.png",
Filters: []runtime.FileFilter{
{
DisplayName: "PNG 图片",
Pattern: "*.png",
},
},
})
if err != nil || filePath == "" {
return "文件路径,无法保存。"
}
// 解码并保存
decodeString, err := base64.StdEncoding.DecodeString(base64Data)
if err != nil {
return "文件内容异常,无法保存。"
}
err = os.WriteFile(filepath.Clean(filePath), decodeString, 0777)
if err != nil {
return "保存结果异常,无法保存。"
}
return filePath
}
// SaveWordFile
//
// @Description: // 跨平台保存word
// @receiver a
// @param filename
// @param base64Data
// @return error
func (a *App) SaveWordFile(filename string, base64Data string) string {
// 弹出保存文件对话框
filePath, err := runtime.SaveFileDialog(a.ctx, runtime.SaveDialogOptions{
Title: "保存 Word 文件",
DefaultFilename: filename,
Filters: []runtime.FileFilter{
{DisplayName: "Word 文件", Pattern: "*.docx"},
},
})
if err != nil || filePath == "" {
return "文件路径,无法保存。"
}
// 解码 base64 内容
decodeString, err := base64.StdEncoding.DecodeString(base64Data)
if err != nil {
return "文件内容异常,无法保存。"
}
// 保存为文件
err = os.WriteFile(filepath.Clean(filePath), decodeString, 0777)
if err != nil {
return "保存结果异常,无法保存。"
}
return filePath
}

View File

@ -1 +1 @@
2d63c3a999d797889c01d6c96451b197
8d3264f90073dfceb29c3619775d830d

View File

@ -1,6 +1,7 @@
<script setup lang="ts">
import {onBeforeMount, onUnmounted, ref} from 'vue'
import {HotTopic} from "../../wailsjs/go/main/App";
import {HotTopic, OpenURL} from "../../wailsjs/go/main/App";
import {Environment} from "../../wailsjs/runtime";
const list = ref([])
const task =ref()
@ -18,11 +19,20 @@ function openCenteredWindow(url, width, height) {
const left = (window.screen.width - width) / 2;
const top = (window.screen.height - height) / 2;
return window.open(
url,
'centeredWindow',
`width=${width},height=${height},left=${left},top=${top}`
);
Environment().then(env => {
switch (env.platform) {
case 'windows':
window.open(
url,
'centeredWindow',
`width=${width},height=${height},left=${left},top=${top}`
)
break
default:
OpenURL(url)
break
}
})
}
function showPage(htid) {
openCenteredWindow(`https://gubatopic.eastmoney.com/topic_v3.html?htid=${htid}`, 1000, 600)

View File

@ -1,16 +1,19 @@
<script setup lang="ts">
import {h, onBeforeMount, onMounted, onUnmounted, ref} from 'vue'
import {SearchStock,GetHotStrategy} from "../../wailsjs/go/main/App";
import {useMessage, NText, NTag,NButton} from 'naive-ui'
import {SearchStock, GetHotStrategy, OpenURL} from "../../wailsjs/go/main/App";
import {useMessage, NText, NTag, NButton} from 'naive-ui'
import {Environment} from "../../wailsjs/runtime"
import {RefreshCircleSharp} from "@vicons/ionicons5";
const message = useMessage()
const search = ref('')
const columns = ref([])
const dataList = ref([])
const hotStrategy = ref([])
const traceInfo = ref('')
function Search() {
if(!search.value){
if (!search.value) {
message.warning('请输入选股指标或者要求')
return
}
@ -18,69 +21,69 @@ function Search() {
const loading = message.loading("正在获取选股数据...", {duration: 0});
SearchStock(search.value).then(res => {
loading.destroy()
// console.log(res)
if(res.code==100){
traceInfo.value=res.data.traceInfo.showText
// message.success(res.msg)
columns.value=res.data.result.columns.filter(item=>!item.hiddenNeed&&(item.title!="市场码"&&item.title!="市场简称")).map(item=>{
if(item.children){
// console.log(res)
if (res.code == 100) {
traceInfo.value = res.data.traceInfo.showText
// message.success(res.msg)
columns.value = res.data.result.columns.filter(item => !item.hiddenNeed && (item.title != "市场码" && item.title != "市场简称")).map(item => {
if (item.children) {
return {
title:item.title+(item.unit?'['+item.unit+']':''),
key:item.key,
title: item.title + (item.unit ? '[' + item.unit + ']' : ''),
key: item.key,
resizable: true,
minWidth:200,
minWidth: 200,
ellipsis: {
tooltip: true
},
children:item.children.filter(item=>!item.hiddenNeed).map(item=>{
children: item.children.filter(item => !item.hiddenNeed).map(item => {
return {
title:item.dateMsg,
key:item.key,
minWidth:100,
title: item.dateMsg,
key: item.key,
minWidth: 100,
resizable: true,
ellipsis: {
tooltip: true
},
sorter: (row1, row2) => {
if(isNumeric(row1[item.key])&&isNumeric(row2[item.key])){
if (isNumeric(row1[item.key]) && isNumeric(row2[item.key])) {
return row1[item.key] - row2[item.key];
}else{
} else {
return 'default'
}
},
}
})
}
}else{
} else {
return {
title:item.title+(item.unit?'['+item.unit+']':''),
key:item.key,
title: item.title + (item.unit ? '[' + item.unit + ']' : ''),
key: item.key,
resizable: true,
minWidth:120,
minWidth: 120,
ellipsis: {
tooltip: true
},
sorter: (row1, row2) => {
if(isNumeric(row1[item.key])&&isNumeric(row2[item.key])){
if (isNumeric(row1[item.key]) && isNumeric(row2[item.key])) {
return row1[item.key] - row2[item.key];
}else{
} else {
return 'default'
}
},
}
}
})
dataList.value=res.data.result.dataList
}else {
message.error(res.msg)
}
dataList.value = res.data.result.dataList
} else {
message.error(res.msg)
}
}).catch(err => {
message.error(err)
})
}
function isNumeric(value) {
return !isNaN(parseFloat(value)) && isFinite(value);
}
@ -88,9 +91,9 @@ function isNumeric(value) {
onBeforeMount(() => {
GetHotStrategy().then(res => {
console.log(res)
if(res.code==1){
hotStrategy.value=res.data
search.value=hotStrategy.value[0].question
if (res.code == 1) {
hotStrategy.value = res.data
search.value = hotStrategy.value[0].question
Search()
}
}).catch(err => {
@ -98,8 +101,9 @@ onBeforeMount(() => {
})
})
function DoSearch(question){
search.value= question
function DoSearch(question) {
search.value = question
Search()
}
@ -107,60 +111,70 @@ function openCenteredWindow(url, width, height) {
const left = (window.screen.width - width) / 2;
const top = (window.screen.height - height) / 2;
return window.open(
url,
'centeredWindow',
`width=${width},height=${height},left=${left},top=${top},location=no,menubar=no,toolbar=no,display=standalone`
);
Environment().then(env => {
switch (env.platform) {
case 'windows':
window.open(
url,
'centeredWindow',
`width=${width},height=${height},left=${left},top=${top},location=no,menubar=no,toolbar=no,display=standalone`
)
break
default:
OpenURL(url)
}
})
}
</script>
<template>
<n-grid :cols="24" style="max-height: calc(100vh - 170px)">
<n-gi :span="4" >
<n-list bordered style="text-align: left;" hoverable clickable>
<n-scrollbar style="max-height: calc(100vh - 170px);" >
<n-list-item v-for="item in hotStrategy" :key="item.rank" @click="DoSearch(item.question)">
<n-ellipsis line-clamp="1" :tooltip="true" >
<n-tag size="small" :bordered="false" type="info">#{{item.rank}}</n-tag><n-text type="warning">{{item.question }}</n-text>
<template #tooltip>
<div style="text-align: center;max-width: 180px">
<n-text type="warning">{{item.question }}</n-text>
</div>
</template>
</n-ellipsis>
</n-list-item>
<n-gi :span="4">
<n-list bordered style="text-align: left;" hoverable clickable>
<n-scrollbar style="max-height: calc(100vh - 170px);">
<n-list-item v-for="item in hotStrategy" :key="item.rank" @click="DoSearch(item.question)">
<n-ellipsis line-clamp="1" :tooltip="true">
<n-tag size="small" :bordered="false" type="info">#{{ item.rank }}</n-tag>
<n-text type="warning">{{ item.question }}</n-text>
<template #tooltip>
<div style="text-align: center;max-width: 180px">
<n-text type="warning">{{ item.question }}</n-text>
</div>
</template>
</n-ellipsis>
</n-list-item>
</n-scrollbar>
</n-list>
<!-- <n-virtual-list :items="hotStrategy" :item-size="hotStrategy.length">-->
<!-- <template #default="{ item, index }">-->
<!-- <n-card :title="''" size="small">-->
<!-- <template #header-extra>-->
<!-- {{item.rank}}-->
<!-- </template>-->
<!-- <n-ellipsis expand-trigger="click" line-clamp="3" :tooltip="false" >-->
<!-- <n-text type="warning">{{item.question }}</n-text>-->
<!-- </n-ellipsis>-->
<!-- </n-card>-->
<!-- <n-virtual-list :items="hotStrategy" :item-size="hotStrategy.length">-->
<!-- <template #default="{ item, index }">-->
<!-- <n-card :title="''" size="small">-->
<!-- <template #header-extra>-->
<!-- {{item.rank}}-->
<!-- </template>-->
<!-- <n-ellipsis expand-trigger="click" line-clamp="3" :tooltip="false" >-->
<!-- <n-text type="warning">{{item.question }}</n-text>-->
<!-- </n-ellipsis>-->
<!-- </n-card>-->
<!-- </template>-->
<!-- </n-virtual-list>-->
<!-- </template>-->
<!-- </n-virtual-list>-->
</n-gi>
<n-gi :span="20" >
<n-gi :span="20">
<n-flex>
<n-input-group style="text-align: left">
<n-input :rows="1" clearable v-model:value="search" placeholder="请输入选股指标或者要求" />
<n-input :rows="1" clearable v-model:value="search" placeholder="请输入选股指标或者要求"/>
<n-button type="primary" @click="Search">搜索A股</n-button>
</n-input-group>
</n-flex>
<n-flex justify="start" v-if="traceInfo" style="margin: 5px 0">
<n-ellipsis line-clamp="1" :tooltip="true" >
<n-text type="info" :bordered="false">选股条件</n-text><n-text type="warning" :bordered="true">{{traceInfo}}</n-text>
<n-ellipsis line-clamp="1" :tooltip="true">
<n-text type="info" :bordered="false">选股条件</n-text>
<n-text type="warning" :bordered="true">{{ traceInfo }}</n-text>
<template #tooltip>
<div style="text-align: center;max-width: 580px">
<n-text type="warning">{{traceInfo}}</n-text>
<n-text type="warning">{{ traceInfo }}</n-text>
</div>
</template>
</n-ellipsis>
@ -204,7 +218,10 @@ function openCenteredWindow(url, width, height) {
}
}"
/>
<n-text>共找到<n-tag type="info" :bordered="false">{{dataList.length}}</n-tag>只股</n-text>
<n-text>共找到
<n-tag type="info" :bordered="false">{{ dataList.length }}</n-tag>
只股
</n-text>
</n-gi>
</n-grid>

View File

@ -3,8 +3,8 @@
// preview.cssstyle.css
import 'md-editor-v3/lib/preview.css';
import {h, onBeforeUnmount, onMounted, ref} from 'vue';
import {CheckUpdate, GetVersionInfo,GetSponsorInfo} from "../../wailsjs/go/main/App";
import {EventsOff, EventsOn} from "../../wailsjs/runtime";
import {CheckUpdate, GetVersionInfo,GetSponsorInfo,OpenURL} from "../../wailsjs/go/main/App";
import {EventsOff, EventsOn,Environment} from "../../wailsjs/runtime";
import {NAvatar, NButton, useNotification} from "naive-ui";
const updateLog = ref('');
const versionInfo = ref('');
@ -85,7 +85,16 @@ EventsOn("updateVersion",async (msg) => {
type: 'primary',
size: 'small',
onClick: () => {
window.open(msg.html_url)
Environment().then(env => {
switch (env.platform) {
case 'windows':
window.open(msg.html_url)
break
default :
OpenURL(msg.html_url)
break
}
})
}
}, { default: () => '查看' })
}

View File

@ -7,7 +7,7 @@ import {
GetConfig,
GetFollowedFund,
GetfundList,
GetVersionInfo,
GetVersionInfo, OpenURL,
UnFollowFund
} from "../../wailsjs/go/main/App";
import vueDanmaku from 'vue3-danmaku'
@ -147,8 +147,19 @@ function formatterTitle(title){
function search(code,name){
setTimeout(() => {
window.open("https://fund.eastmoney.com/"+code+".html","_blank","noreferrer,width=1000,top=100,left=100,status=no,toolbar=no,location=no,scrollbars=no")
//window.open("https://fund.eastmoney.com/"+code+".html","_blank","noreferrer,width=1000,top=100,left=100,status=no,toolbar=no,location=no,scrollbars=no")
//window.open("https://finance.sina.com.cn/fund/quotes/"+code+"/bc.shtml","_blank","width=1000,height=800,top=100,left=100,toolbar=no,location=no")
Environment().then(env => {
switch (env.platform) {
case 'windows':
window.open("https://fund.eastmoney.com/"+code+".html","_blank","noreferrer,width=1000,top=100,left=100,status=no,toolbar=no,location=no,scrollbars=no")
break
default :
OpenURL("https://fund.eastmoney.com/"+code+".html")
}
})
}, 500)
}

View File

@ -26,7 +26,10 @@ import {
SetStockAICron,
SetStockSort,
ShareAnalysis,
UnFollow
UnFollow,
OpenURL,
SaveImage,
SaveWordFile
} from '../../wailsjs/go/main/App'
import {
NAvatar,
@ -41,6 +44,7 @@ import {
useNotification
} from 'naive-ui'
import {
Environment,
EventsEmit,
EventsOff,
EventsOn,
@ -103,7 +107,7 @@ const modalShow3 = ref(false)
const modalShow4 = ref(false)
const modalShow5 = ref(false)
const addBTN = ref(true)
const enableTools= ref(false)
const enableTools = ref(false)
const formModel = ref({
name: "",
code: "",
@ -384,7 +388,15 @@ EventsOn("updateVersion", async (msg) => {
type: 'primary',
size: 'small',
onClick: () => {
window.open(msg.html_url)
Environment().then(env => {
switch (env.platform) {
case 'windows':
window.open(msg.html_url)
break
default :
OpenURL(msg.html_url)
}
})
}
}, {default: () => '查看'})
}
@ -441,7 +453,7 @@ function AddStock() {
Follow(data.code).then(result => {
if (result === "关注成功") {
if (data.code.startsWith("us")) {
data.code= "gb_" + data.code.replace("us", "").toLowerCase()
data.code = "gb_" + data.code.replace("us", "").toLowerCase()
}
stocks.value.push(data.code)
message.success(result)
@ -614,12 +626,24 @@ function onSelect(item) {
function openCenteredWindow(url, width, height) {
const left = (window.screen.width - width) / 2;
const top = (window.screen.height - height) / 2;
Environment().then(env => {
switch (env.platform) {
case 'windows':
window.open(url, target, features)
break
default :
OpenURL(url)
break
}
})
return window.open(
url,
'centeredWindow',
`width=${width},height=${height},left=${left},top=${top}`
);
//
// return window.open(
// url,
// 'centeredWindow',
// `width=${width},height=${height},left=${left},top=${top}`
// );
}
function search(code, name) {
@ -631,7 +655,7 @@ function search(code, name) {
//window.open("https://www.iwencai.com/unifiedwap/result?w=" + name)
//window.open("https://www.iwencai.com/chat/?question="+code)
openCenteredWindow("https://www.iwencai.com/unifiedwap/result?w=" + name,1000,800)
openCenteredWindow("https://www.iwencai.com/unifiedwap/result?w=" + name, 1000, 800)
}, 500)
}
@ -1359,7 +1383,7 @@ function aiReCheckStock(stock, stockCode) {
//
//message.info("sysPromptId:"+data.sysPromptId)
NewChatStream(stock, stockCode, data.question, data.sysPromptId,enableTools.value)
NewChatStream(stock, stockCode, data.question, data.sysPromptId, enableTools.value)
}
function aiCheckStock(stock, stockCode) {
@ -1437,21 +1461,42 @@ window.onerror = function (msg, source, lineno, colno, error) {
};
function saveAsImage(name, code) {
const element = document.querySelector('.md-editor-preview');
if (element) {
html2canvas(element, {
useCORS: true, //
scale: 2, //
allowTaint: true, //
}).then(canvas => {
const link = document.createElement('a');
link.href = canvas.toDataURL('image/png');
link.download = name + "[" + code + ']-ai-analysis-result.png';
link.click();
});
} else {
message.error('无法找到分析结果元素');
}
Environment().then(env => {
switch (env.platform) {
case 'windows':
const element = document.querySelector('.md-editor-preview');
if (element) {
html2canvas(element, {
useCORS: true, //
scale: 2, //
allowTaint: true, //
}).then(canvas => {
const link = document.createElement('a');
link.href = canvas.toDataURL('image/png');
link.download = name + "[" + code + ']-ai-analysis-result.png';
link.click();
});
} else {
message.error('无法找到分析结果元素');
}
break
default :
saveCanvasImage(name)
}
})
}
async function saveCanvasImage(name) {
const element = document.querySelector('.md-editor-preview'); // DOM
const canvas = await html2canvas(element)
const dataUrl = canvas.toDataURL('image/png') // base64
const base64 = dataUrl.replace(/^data:image\/png;base64,/, '')
// Go Wails
await SaveImage(name,base64).then(result => {
message.success(result)
})
}
async function copyToClipboard() {
@ -1511,13 +1556,26 @@ AI赋能股票分析自选股行情获取成本盈亏展示涨跌报警
`
// landscapeportraitportrait
const blob = await asBlob(value, {orientation: 'portrait'})
const a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = `${data.name}[${data.code}]-ai-analysis-result.docx`;
a.click()
//
URL.revokeObjectURL(a.href);
a.remove()
const { platform } = await Environment()
switch (platform) {
case 'windows':
const a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = `${data.name}[${data.code}]-ai-analysis-result.docx`;
a.click()
//
URL.revokeObjectURL(a.href);
a.remove()
break
default:
const arrayBuffer = await blob.arrayBuffer()
const uint8Array = new Uint8Array(arrayBuffer)
const binary = uint8Array.reduce((data, byte) => data + String.fromCharCode(byte), '')
const base64 = btoa(binary)
await SaveWordFile(`${data.name}[${data.code}]-ai-analysis-result.docx`, base64).then(result => {
message.success(result)
})
}
}
function share(code, name) {
@ -1747,7 +1805,8 @@ function searchStockReport(stockCode) {
取消关注
</n-button>&nbsp;
<n-button size="tiny" v-if="data.openAiEnable" secondary type="warning" @click="aiCheckStock(result['股票名称'],result['股票代码'])">
<n-button size="tiny" v-if="data.openAiEnable" secondary type="warning"
@click="aiCheckStock(result['股票名称'],result['股票代码'])">
AI分析
</n-button>
</template>
@ -1756,7 +1815,9 @@ function searchStockReport(stockCode) {
<n-text :type="'info'">{{ result["日期"] + " " + result["时间"] }}</n-text>
<n-tag size="small" v-if="result.volume>0" :type="result.profitType">{{ result.volume + "股" }}</n-tag>
<n-tag size="small" v-if="result.costPrice>0" :type="result.profitType">
{{ "成本:" + result.costPrice + "*" + result.costVolume + " " + result.profit + "%" + " ( " + result.profitAmount + " ¥ )" }}
{{
"成本:" + result.costPrice + "*" + result.costVolume + " " + result.profit + "%" + " ( " + result.profitAmount + " ¥ )"
}}
</n-tag>
</n-flex>
</template>
@ -1815,7 +1876,8 @@ function searchStockReport(stockCode) {
</n-text>
</n-gi>
<n-gi :span="6">
<stock-spark-line :last-price="Number(result['当前价格'])" :open-price="Number(result['昨日收盘价'])" :stock-code="result['股票代码']" :stock-name="result['股票名称']" ></stock-spark-line>
<stock-spark-line :last-price="Number(result['当前价格'])" :open-price="Number(result['昨日收盘价'])"
:stock-code="result['股票代码']" :stock-name="result['股票名称']"></stock-spark-line>
</n-gi>
</n-grid>
<n-grid :cols="2" :y-gap="4" :x-gap="4">
@ -1886,9 +1948,10 @@ function searchStockReport(stockCode) {
取消关注
</n-button>&nbsp;
<n-button size="tiny" v-if="data.openAiEnable" secondary type="warning" @click="aiCheckStock(result['股票名称'],result['股票代码'])">
AI分析
</n-button>
<n-button size="tiny" v-if="data.openAiEnable" secondary type="warning"
@click="aiCheckStock(result['股票名称'],result['股票代码'])">
AI分析
</n-button>
<n-button secondary type="error" size="tiny"
@click="delStockGroup(result['股票代码'],result['股票名称'],group.ID)">移出分组
</n-button>
@ -1898,7 +1961,9 @@ function searchStockReport(stockCode) {
<n-text :type="'info'">{{ result["日期"] + " " + result["时间"] }}</n-text>
<n-tag size="small" v-if="result.volume>0" :type="result.profitType">{{ result.volume + "股" }}</n-tag>
<n-tag size="small" v-if="result.costPrice>0" :type="result.profitType">
{{ "成本:" + result.costPrice + "*" + result.costVolume + " " + result.profit + "%" + " ( " + result.profitAmount + " ¥ )" }}
{{
"成本:" + result.costPrice + "*" + result.costVolume + " " + result.profit + "%" + " ( " + result.profitAmount + " ¥ )"
}}
</n-tag>
</n-flex>
</template>
@ -2087,7 +2152,9 @@ function searchStockReport(stockCode) {
不启用AI函数工具调用
</template>
</n-switch>
<n-gradient-text type="error" style="margin-left: 10px">*AI函数工具调用可以增强AI获取数据的能力,但会消耗更多tokens</n-gradient-text>
<n-gradient-text type="error" style="margin-left: 10px">
*AI函数工具调用可以增强AI获取数据的能力,但会消耗更多tokens
</n-gradient-text>
</n-flex>
<n-flex justify="space-between" style="margin-bottom: 10px">
<n-select style="width: 49%" v-model:value="data.sysPromptId" label-field="name" value-field="ID"

View File

@ -89,6 +89,8 @@ export function NewChatStream(arg1:string,arg2:string,arg3:string,arg4:any,arg5:
export function NewsPush(arg1:any):Promise<void>;
export function OpenURL(arg1:string):Promise<void>;
export function ReFleshTelegraphList(arg1:string):Promise<any>;
export function RemoveGroup(arg1:number):Promise<string>;
@ -99,6 +101,10 @@ export function SaveAIResponseResult(arg1:string,arg2:string,arg3:string,arg4:st
export function SaveAsMarkdown(arg1:string,arg2:string):Promise<string>;
export function SaveImage(arg1:string,arg2:string):Promise<string>;
export function SaveWordFile(arg1:string,arg2:string):Promise<string>;
export function SearchStock(arg1:string):Promise<Record<string, any>>;
export function SendDingDingMessage(arg1:string,arg2:string):Promise<string>;

View File

@ -174,6 +174,10 @@ export function NewsPush(arg1) {
return window['go']['main']['App']['NewsPush'](arg1);
}
export function OpenURL(arg1) {
return window['go']['main']['App']['OpenURL'](arg1);
}
export function ReFleshTelegraphList(arg1) {
return window['go']['main']['App']['ReFleshTelegraphList'](arg1);
}
@ -194,6 +198,14 @@ export function SaveAsMarkdown(arg1, arg2) {
return window['go']['main']['App']['SaveAsMarkdown'](arg1, arg2);
}
export function SaveImage(arg1, arg2) {
return window['go']['main']['App']['SaveImage'](arg1, arg2);
}
export function SaveWordFile(arg1, arg2) {
return window['go']['main']['App']['SaveWordFile'](arg1, arg2);
}
export function SearchStock(arg1) {
return window['go']['main']['App']['SearchStock'](arg1);
}