go wails桌面应用开发、股票数据接口调用
前言
本文主要是介绍和分享go-wails开发的股票Api数据查看桌面应用,通过定时器,轮询请求股票Api获取股票交易数据和趋势图,
本示例仅是个人学习wails的demo,仅供学习使用,源代码可下载:
一、前期准备:
- golang 1.18+
- walis (安装、使用)
- npm(node>15+)
- 股票数据接口key获取
二、源代码块
1、股票数据布局和股票代码初始化:
- 初始化股票代码列表(有默认)
- 获取接口请求Key,并配置
- 引入股票数据组件模块
<script>
import {GetStockList, GetStockInfo, ChangeStockConf} from '../../wailsjs/go/main/App'
import {SetStorage,GetStorage,GetAllStorage,RemoveStorage,ClearStorage} from '../config/localstorage'
import StockInfoComponent from '../components/StockInfoComponent.vue'
export default {
data() {
return {
title:'go wails 股票查询新系统',
name: "",
url:'https://www.juhe.cn/s/sujmbk6wkw718a=',
vipUrl:'https://www.juhe.cn/s/surjdal9mjdatr=',
stocks:[],
stockInfo:[],
code:'',
tabPosition:'left',
addable :true,
stockCode:'',
appKey:'',
defalutStocks:[
{code: "sz002610", name: "爱康科技"},
{code: "sz002665", name: "首行高科"},
{code: "sh600339", name: "中油工程"}
],
timer:null,
apiEnable:false,
addCode:'',
removCode:''
}
},
components:{
StockInfoComponent
},
created(){
this.initStockList()
this.getStockList();
},
methods:{
clickCopy(el,val){
if(el ==='vip'){
navigator.clipboard.writeText(this.vipUrl).then(() => {
this.$message.success("链接复制成功")
});
} else {
navigator.clipboard.writeText(this.url).then(() => {
this.$message.success("链接复制成功")
});
}
},
// 获取股票列表信息
getStockList() {
console.log('getStockList',this.stocks)
this.stocks = GetStorage('storcklist')
console.log('getStockList2',this.stocks)
if(this.stocks.length >0 ){
this.stockCode = this.stocks[0].code
}
this.appKey = GetStorage('appkey')
if(this.appKey) {
this.changeApiKey()
} else {
this.$message.error('请先获取AppKey,并配置')
}
},
initStockList(){
console.log('mounted',this.stocks)
SetStorage('storcklist',this.defalutStocks)
},
changeApiKey(){
if(this.appKey.length != 32){
this.appkeyEnable = false
this.$message.error('接口apiKey不正确');
} else {
ChangeStockConf(this.appKey).then(result => {
if(result.error_code === 0){
this.apiEnable = true;
SetStorage('appkey',this.appKey);
}
console.log('changeApiKeyResult:',result)
})
}
console.log('changeApiKey:',this.appKey)
},
setApiDisable(){
this.apiEnable=false
console.log('setApiDisable')
},
}
}
</script>
<template>
<div class="main">
<el-header class="header">
<div class="title">
{{ title }}
</div>
<div class="setting">
<el-input class="el-input" v-model="appKey" style="width: 400px" placeholder="配置接口AppKey"/>
<el-button type="primary" @click="changeApiKey">设置AppKey</el-button>
</div>
<div class="setting" style="margin-top:15px">
<el-input class="el-input" v-model="url" name="api" style="width: 400px" readonly @click="clickCopy('api')"/>
<el-button type="primary" name="api" @click="clickCopy('api')">点击复制、免费获取股票数据接口AppKey</el-button>
</div>
<div class="setting" style="margin-top:15px">
<el-input class="el-input" v-model="vipUrl" name="vip" style="width: 400px" readonly @click="clickCopy('vip')"/>
<el-button type="primary" name="vip" @click="clickCopy('vip')">点击复制、获取免费无限次调用解决方案</el-button>
</div>
</el-header>
<el-main>
<div v-if="apiEnable">
<el-row :gutter="20">
<el-col :span="12" v-for="(oprionts,id) in stocks" :key="id" :name="oprionts.code" ><div class="grid-content bg-purple"><StockInfoComponent @set-api-disable="setApiDisable" :stockCode="oprionts"/></div></el-col>
</el-row>
</div>
</el-main>
<el-footer>Footer</el-footer>
</div>
</template>
<style scoped>
.header{
height: 150px;
}
.main .setting{
margin-top:15px
}
.main .setting .el-input{
width: 200px;
}
.el-col {
margin-bottom: 20px;
}
.main /deep/ .el-tabs__item{
color:gray
}
.main /deep/ .el-tabs__item.is-active{
color:white
}
.main /deep/ .el-tabs__new-tab{
color:white
}
.main /deep/ .el-tabs__new-tab:hover{
color:red
}
</style>
2、单个股票数据展示组件(源码):
- 通过接口获取股票交易数据信息,以及趋势k图
- setInterval定时器,定时查询数据
- 可控制交易K线图是否显示
<script>
import {GetStockInfo} from '../../wailsjs/go/main/App'
export default {
data() {
return {
stockInfo:[],
addable :true,
dataTime:'',
appKey:'',
timer:null,
hasData:false,
showImg:false,
apiErr:false,
}
},
props:{
stockCode:{
type:Object,
required:true,
}
},
mounted(){
console.log("child - mounted")
this.getStorckInfo()
setTimeout(()=>{
if(!this.apiErr){
this.setIntervalStock();
}
},300)
},
created(){
console.log("child - created")
},
methods:{
appkeyError(){
this.$emit('set-api-disable', false)
},
getStorckInfo() {
this.dataTime=this.getDateTimeStr();
console.log('当前时间',this.dataTime)
const stockCode = this.stockCode.code
// 接口出错,取消定时任务
if(this.apiErr && this.timer){
console.log("可以清除定时任务了:",this.apiErr ,this.timer)
clearInterval(this.timer)
}
// 获取接口信息
GetStockInfo(stockCode).then(result => {
if(result.error_code !== 0) {
if(result.error_code === 10012){
this.$message.error('接口请求次数超限,如需无限制,请升级黑钻会员')
}else {
this.$message.error(result.reason)
}
if(result.error_code > 10000 && result.error_code < 10021) {
this.apiErr = true;
this.appkeyError()
}
console.log(result)
} else {
this.stockInfo = result
this.hasData=true
console.log('stockInfo',result)
}
});
},
setIntervalStock(){
const stockCode = this.stockCode.code
// 判断是否有定时器,有就清空
if(this.timer){
clearInterval(this.timer)
}
// 设置定时器
console.log('开始设置定时器....',stockCode)
this.timer = setInterval(()=>{
this.getStorckInfo()
},10000)
console.log('设置定时器结束....',this.timer)
},
changeImageShow(){
},
getDateTimeStr(){
Date.prototype.format = function(fmt)
{
var o = {
"M+" : this.getMonth()+1, //月份
"d+" : this.getDate(), //日
"h+" : this.getHours()%12 == 0 ? 12 : this.getHours()%12, //小时
"H+" : this.getHours(), //小时
"m+" : this.getMinutes(), //分
"s+" : this.getSeconds(), //秒
"q+" : Math.floor((this.getMonth()+3)/3), //季度
"S" : this.getMilliseconds() //毫秒
};
if(/(y+)/.test(fmt))
fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
for(var k in o)
if(new RegExp("("+ k +")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
return fmt;
}
return new Date().format("yyyy-MM-dd HH:mm:ss");
}
}
}
</script>
<template>
<div class="main-child" >
<el-container style="display:block">
<el-header>{{stockCode.name}}({{ stockCode.code }}) - {{ dataTime }} | <el-switch v-model="showImg" active-text="显示" inactive-text="隐藏" @change="changeImageShow">
</el-switch>
</el-header>
<el-main>
<div v-if="hasData" class="table">
<table>
<tr>
<th>名称</th>
<th>当前价格</th>
<th>涨量</th>
<th>涨幅(%)</th>
<th>成交额(万)</th>
<th>成交量</th>
</tr>
<tr>
<td>{{ stockInfo.result.daPan.name}}</td>
<td>{{ stockInfo.result.daPan.dot}}</td>
<td>{{ stockInfo.result.daPan.nowPic}}</td>
<td>{{ stockInfo.result.daPan.rate}}</td>
<td>{{ stockInfo.result.daPan.traAmount}}</td>
<td>{{ stockInfo.result.daPan.traNumber}}</td>
</tr>
</table>
</div>
<div v-if="showImg && hasData" class="images">
<h4>趋势图</h4>
<img v-for="(img ,id) in stockInfo.result.images" :key="id" :src="img"/>
</div>
</el-main>
</el-container>
</div>
</template>
<style scoped>
.main-child{
background-color: white;
color: black;
}
.main-child .table table{
width: 100%;
}
.main-child .images img{
}
.el-header {
background-color: #b3c0d1;
color: var(--el-text-color-primary);
text-align: center;
line-height: 60px;
}
</style>
三、最终应用展示:
四、源码下载
- 示例源码下载
- 提取码:988i