@ -0,0 +1 @@ |
||||
public/* linguist-vendored |
@ -0,0 +1,21 @@ |
||||
.DS_Store |
||||
node_modules |
||||
/dist |
||||
|
||||
# local env files |
||||
.env.local |
||||
.env.*.local |
||||
|
||||
# Log files |
||||
npm-debug.log* |
||||
yarn-debug.log* |
||||
yarn-error.log* |
||||
|
||||
# Editor directories and files |
||||
.idea |
||||
.vscode |
||||
*.suo |
||||
*.ntvs* |
||||
*.njsproj |
||||
*.sln |
||||
*.sw* |
@ -0,0 +1,10 @@ |
||||
module.exports = { |
||||
presets: ['@vue/cli-plugin-babel/preset'], |
||||
plugins: [ |
||||
[ |
||||
'import', |
||||
{ libraryName: 'vant', libraryDirectory: 'es', style: true }, |
||||
'vant' |
||||
] |
||||
] |
||||
}; |
@ -0,0 +1,64 @@ |
||||
{ |
||||
"name": "vant-demo-vue2", |
||||
"version": "1.0.0", |
||||
"description": "Collection of vant demos.", |
||||
"author": "neverland <chenjiahan@neverl.com>", |
||||
"license": "MIT", |
||||
"scripts": { |
||||
"serve": "vue-cli-service serve", |
||||
"build": "vue-cli-service build", |
||||
"lint": "vue-cli-service lint" |
||||
}, |
||||
"dependencies": { |
||||
"@vue/composition-api": "^1.0.0-rc.5", |
||||
"ali-oss": "^6.13.2", |
||||
"axios": "^0.21.1", |
||||
"clipboard": "^2.0.6", |
||||
"core-js": "^3.4.3", |
||||
"crypto-js": "^4.0.0", |
||||
"echarts": "^4.2.0-rc.2", |
||||
"js-md5": "^0.7.3", |
||||
"jsencrypt": "^3.0.1", |
||||
"v-charts": "^1.19.0", |
||||
"vant": "^2.2.0", |
||||
"vue": "^2.6.10", |
||||
"vue-localstorage": "^0.6.2", |
||||
"vue-router": "^3.0.5", |
||||
"vue-visibility-change": "^1.2.1" |
||||
}, |
||||
"devDependencies": { |
||||
"@vue/cli-plugin-babel": "^4.1.1", |
||||
"@vue/cli-plugin-eslint": "^4.1.1", |
||||
"@vue/cli-service": "^4.1.1", |
||||
"babel-eslint": "^10.0.3", |
||||
"babel-plugin-import": "^1.13.3", |
||||
"eslint": "^4.19.1", |
||||
"eslint-plugin-vue": "^6.0.1", |
||||
"less": "^3.8.1", |
||||
"less-loader": "^5.0.0", |
||||
"vue-template-compiler": "^2.6.10" |
||||
}, |
||||
"eslintConfig": { |
||||
"root": true, |
||||
"env": { |
||||
"node": true |
||||
}, |
||||
"extends": [ |
||||
"plugin:vue/essential", |
||||
"eslint:recommended" |
||||
], |
||||
"rules": {}, |
||||
"parserOptions": { |
||||
"parser": "babel-eslint" |
||||
} |
||||
}, |
||||
"postcss": { |
||||
"plugins": { |
||||
"autoprefixer": {} |
||||
} |
||||
}, |
||||
"browserslist": [ |
||||
"Android >= 4.0", |
||||
"iOS >= 7" |
||||
] |
||||
} |
After Width: | Height: | Size: 17 KiB |
@ -0,0 +1,14 @@ |
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<meta charset="utf-8"> |
||||
<!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />--> |
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover"> |
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
||||
<title>算力云</title> |
||||
</head> |
||||
<body> |
||||
<div id="app"></div> |
||||
</body> |
||||
</html> |
@ -0,0 +1,74 @@ |
||||
#!/bin/bash |
||||
AppName=sliyun-admin.jar |
||||
|
||||
#使用说明,用来提示输入参数 |
||||
usage() { |
||||
echo "Usage: sh a.sh [start|stop|restart|status]" # a.sh 为这个脚本名称 替换为你喜欢的名称即可 |
||||
exit 1 |
||||
} |
||||
|
||||
#检查程序是否在运行 |
||||
is_exist() { |
||||
pid=`ps -ef | grep $APP_NAME | grep -v grep | awk '{print $2}' ` |
||||
#如果不存在返回1,存在返回0 |
||||
if [ -z "${pid}" ]; then |
||||
return 1 |
||||
else |
||||
return 0 |
||||
fi |
||||
} |
||||
|
||||
#启动方法 |
||||
start() { |
||||
is_exist |
||||
if [ $? -eq "0" ]; then |
||||
echo "${APP_NAME} is already running. pid=${pid} ." |
||||
else |
||||
nohup java -jar -Dspring.config.location=$CONFIG_NAME $APP_NAME > /dev/null 2>&1 & |
||||
fi |
||||
} |
||||
|
||||
#停止方法 |
||||
stop() { |
||||
is_exist |
||||
if [ $? -eq "0" ]; then |
||||
kill -9 $pid |
||||
else |
||||
echo "${APP_NAME} is not running" |
||||
fi |
||||
} |
||||
|
||||
#输出运行状态 |
||||
status() { |
||||
is_exist |
||||
if [ $? -eq "0" ]; then |
||||
echo "${APP_NAME} is running. Pid is ${pid}" |
||||
else |
||||
echo "${APP_NAME} is not running." |
||||
fi |
||||
} |
||||
|
||||
#重启 |
||||
restart() { |
||||
stop |
||||
start |
||||
} |
||||
|
||||
#根据输入参数,选择执行对应方法,不输入则执行使用说明 |
||||
case "$1" in |
||||
"start") |
||||
start |
||||
;; |
||||
"stop") |
||||
stop |
||||
;; |
||||
"status") |
||||
status |
||||
;; |
||||
"restart") |
||||
restart |
||||
;; |
||||
*) |
||||
usage |
||||
;; |
||||
esac |
@ -0,0 +1,21 @@ |
||||
<template> |
||||
<div id="app"> |
||||
<router-view/> |
||||
</div> |
||||
</template> |
||||
<script></script> |
||||
<style> |
||||
|
||||
/*html, body, #app {*/ |
||||
/* width: 100%;*/ |
||||
/* height: 100%;*/ |
||||
/* font-size: 14px;*/ |
||||
/* background-color: #ffffff;*/ |
||||
/* -webkit-font-smoothing: antialiased;*/ |
||||
/* margin: 0; padding: 0;*/ |
||||
/*}*/ |
||||
|
||||
/*.content {*/ |
||||
/*}*/ |
||||
|
||||
</style> |
@ -0,0 +1,34 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
|
||||
const address = { |
||||
create: '/v1/member/address/create', |
||||
list: '/v1/member/address/list', |
||||
delete: '/v1/member/address/delete', |
||||
edit: '/v1/member/address/edit', |
||||
} |
||||
|
||||
export function CoinTokenList(parameter) { |
||||
return request({ |
||||
url: address.list, |
||||
method: 'get', |
||||
params: parameter, |
||||
data: parameter |
||||
}) |
||||
} |
||||
|
||||
export function CoinTokenAdd(parameter) { |
||||
return request({ |
||||
url: address.create, |
||||
method: 'post', |
||||
data: parameter |
||||
}) |
||||
} |
||||
|
||||
export function CoinTokenDelete(parameter) { |
||||
return request({ |
||||
url: address.delete, |
||||
method: 'post', |
||||
data: parameter |
||||
}) |
||||
} |
@ -0,0 +1,13 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
const appApi = { |
||||
Home: '/v1/app/home', |
||||
} |
||||
|
||||
export function getHomeInfo(parameter) { |
||||
return request({ |
||||
url: appApi.Home, |
||||
method: 'get', |
||||
data: parameter |
||||
}) |
||||
} |
@ -0,0 +1,23 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
|
||||
const coinApi = { |
||||
List: '/v1/coin/list', |
||||
packageList: '/v1/coin/package/list', |
||||
|
||||
} |
||||
|
||||
|
||||
export function CoinList() { |
||||
return request({ |
||||
url: coinApi.List, |
||||
method: 'get', |
||||
}) |
||||
} |
||||
export function getCoinPackage(parameter) { |
||||
return request({ |
||||
url: coinApi.packageList, |
||||
method: 'get', |
||||
data: parameter |
||||
}) |
||||
} |
@ -0,0 +1,75 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
|
||||
const orderApi = { |
||||
orderCreate:'/v1/order/create', |
||||
orderInfo:'/v1/order/info', |
||||
oderPayInfo:'/v1/order/payInfo', |
||||
orderList:'/v1/order/list', |
||||
orderDetail:'/v1/order/detail', |
||||
orderPayState:'/v1/order/payState', |
||||
basicInfo:'/v1/order/basicInfo', |
||||
|
||||
} |
||||
|
||||
|
||||
|
||||
export function getOrderBasicInfo() { |
||||
return request({ |
||||
url: orderApi.basicInfo, |
||||
method: 'get', |
||||
}) |
||||
} |
||||
|
||||
|
||||
export function orderCreate(parameter) { |
||||
return request({ |
||||
url: orderApi.orderCreate, |
||||
method: 'post', |
||||
data: parameter |
||||
}) |
||||
} |
||||
|
||||
export function getOrderPayInfo(parameter) { |
||||
return request({ |
||||
url: orderApi.oderPayInfo, |
||||
method: 'post', |
||||
data: parameter |
||||
}) |
||||
} |
||||
export function getOrderInfo(parameter) { |
||||
return request({ |
||||
url: orderApi.orderInfo, |
||||
method: 'get', |
||||
data: parameter |
||||
}) |
||||
} |
||||
|
||||
export function getOrderList(parameter) { |
||||
return request({ |
||||
url: orderApi.orderList, |
||||
method: 'get', |
||||
data: parameter |
||||
}) |
||||
} |
||||
|
||||
export function getOrderPayState(parameter) { |
||||
return request({ |
||||
url: orderApi.orderPayState, |
||||
method: 'get', |
||||
params: parameter, |
||||
data: parameter |
||||
}) |
||||
} |
||||
|
||||
export function getOrderDetail(parameter) { |
||||
return request({ |
||||
url: orderApi.orderDetail, |
||||
method: 'get', |
||||
params: parameter, |
||||
data: parameter |
||||
}) |
||||
} |
||||
|
||||
|
||||
|
@ -0,0 +1,55 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
|
||||
const userApi = { |
||||
Register: '/v1/member/register', |
||||
Logout: '/v1/member/logout', |
||||
Login: '/v1/member/login', |
||||
ForgePassword: '/v1/member/forgePassword', |
||||
UpdatePassword: '/v1/member/updatePassword', |
||||
profitList: '/v1/member/profit/list', |
||||
|
||||
// get my info
|
||||
UserInfo: '/v1/user/info', |
||||
|
||||
} |
||||
|
||||
export function Register(parameter) { |
||||
return request({ |
||||
url: userApi.Register, |
||||
method: 'post', |
||||
data: parameter |
||||
}) |
||||
} |
||||
|
||||
export function Login(parameter) { |
||||
return request({ |
||||
url: userApi.Login, |
||||
method: 'post', |
||||
data: parameter |
||||
}) |
||||
} |
||||
|
||||
export function Logout() { |
||||
return request({ |
||||
url: userApi.Logout, |
||||
method: 'post', |
||||
}) |
||||
} |
||||
|
||||
export function UpdatePassword(parameter) { |
||||
return request({ |
||||
url: userApi.UpdatePassword, |
||||
method: 'post', |
||||
data: parameter |
||||
}) |
||||
} |
||||
|
||||
export function getProfitList(parameter) { |
||||
return request({ |
||||
url: userApi.profitList, |
||||
method: 'get', |
||||
data: parameter |
||||
}) |
||||
} |
||||
|
@ -0,0 +1,9 @@ |
||||
html, body, #app { |
||||
width: 100%; |
||||
height: 100%; |
||||
font-size: 14px; |
||||
background-color: #ffffff; |
||||
-webkit-font-smoothing: antialiased; |
||||
margin: 0; |
||||
padding: 0; |
||||
} |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 4.5 KiB |
@ -0,0 +1,87 @@ |
||||
<template> |
||||
<div id="uploadFile"> |
||||
<input type="file" :id="name" @change="doUpload" v-if="multiple==false" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"> |
||||
<input type="file" :id="name" @change="doUpload" :multiple="multiple" v-if="multiple==true" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"> |
||||
<button type="button" class="ivu-btn ivu-btn-ghost"><Icon type="ios-cloud-upload-outline"></Icon><span>上传文件</span></button> |
||||
<span class="size">建议尺寸:{{size}},图片大小不超过2M</span> |
||||
<div class="uploadView" v-if="uploadImg"> |
||||
<div v-for="(item,index) in uploadImg" :key="index"> |
||||
<div> |
||||
<img :src="item" :style="{width:width+'px',height:height+'px'}"> |
||||
<div class="handleBtn"> |
||||
<Icon type="ios-eye-outline" v-if="defaultView" @click.native="handleView(item)"></Icon> |
||||
<Icon type="ios-eye-outline" v-if="currentView" @click.native="handleView(item.url)"></Icon> |
||||
<Icon type="ios-trash-outline" @click.native="handleRemove(index)"></Icon> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<Modal title="查看图片" v-model="visible"> |
||||
<img :src="viewUrl" style="width: 100%"> |
||||
</Modal> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
export default { |
||||
props:{ |
||||
width:Number, |
||||
height:Number, |
||||
name:String, |
||||
size:String, |
||||
multiple:Boolean |
||||
}, |
||||
data () { |
||||
return { |
||||
region: '', |
||||
bucket: '', |
||||
uploadImg:[], |
||||
visible:false, |
||||
viewUrl:'', |
||||
defaultView:false, |
||||
currentView:false |
||||
} |
||||
}, |
||||
mounted(){ |
||||
this.setData(); |
||||
}, |
||||
methods: { |
||||
setData(){ |
||||
this.region='这里换成自己的region'; |
||||
this.bucket='这里换成自己的bucket'; |
||||
}, |
||||
doUpload(){ |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
<style lang="less"> |
||||
#uploadFile{ |
||||
width:300px; |
||||
} |
||||
#uploadFile input { |
||||
position: relative; |
||||
z-index: 100; |
||||
opacity: 0; |
||||
filter: alpha(opacity=0); |
||||
cursor: pointer; |
||||
width: 100%; |
||||
} |
||||
#uploadFile .size { |
||||
position: absolute; |
||||
left:40%; |
||||
} |
||||
#uploadFile .ivu-btn{ |
||||
margin-top: -62px; |
||||
} |
||||
.uploadView{ |
||||
width:100%; |
||||
height:auto; |
||||
img{ |
||||
width:100%; |
||||
height:auto; |
||||
} |
||||
} |
||||
.handleBtn .ivu-icon{ |
||||
font-size:25px; |
||||
} |
||||
</style> |
@ -0,0 +1,23 @@ |
||||
/** |
||||
* Custom icon list |
||||
* All icons are loaded here for easy management |
||||
* @see https://vue.ant.design/components/icon/#Custom-Font-Icon
|
||||
* |
||||
* 自定义图标加载表 |
||||
* 所有图标均从这里加载,方便管理 |
||||
*/ |
||||
import pay_ali from '@/assets/icon_pay_ali.png' // path to your '*.svg?inline' file.
|
||||
import pay_wchat from '@/assets/icon_pay_wchat.png' // path to your '*.svg?inline' file.
|
||||
import logo from '@/assets/logo.png' // path to your '*.svg?inline' file.
|
||||
import wallet from '@/assets/icon_order_wallet.png' // path to your '*.svg?inline' file.
|
||||
import time from '@/assets/icon_order_time.png' // path to your '*.svg?inline' file.
|
||||
import service from '@/assets/icon_order_service.png' // path to your '*.svg?inline' file.
|
||||
import excavate from '@/assets/icon_order_excavate.png' // path to your '*.svg?inline' file.
|
||||
import default_user from '@/assets/icon_default_user.png' // path to your '*.svg?inline' file.
|
||||
import icon_password from '@/assets/icon_password.png' // path to your '*.svg?inline' file.
|
||||
import icon_user from '@/assets/icon_account.png' // path to your '*.svg?inline' file.
|
||||
|
||||
|
||||
|
||||
|
||||
export { pay_ali,pay_wchat,logo,wallet,time,service,excavate,default_user,icon_password,icon_user} |
@ -0,0 +1,17 @@ |
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
||||
import { logo } from '@/core/icons' |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const app = { |
||||
info: { |
||||
name: '算力云', |
||||
logo: logo, |
||||
} |
||||
} |
||||
|
||||
export default app |
@ -0,0 +1,55 @@ |
||||
import Vue from 'vue'; |
||||
import App from './App'; |
||||
import {router} from './router'; |
||||
import {Tabbar, TabbarItem} from 'vant'; |
||||
import {Icon} from 'vant'; |
||||
import {Overlay} from 'vant'; |
||||
import {Loading} from 'vant'; |
||||
import {Dialog} from 'vant'; |
||||
import {ActionSheet} from 'vant'; |
||||
import {Toast} from 'vant'; |
||||
import {Image as VanImage} from 'vant'; |
||||
import {Card} from 'vant'; |
||||
import {Skeleton} from 'vant'; |
||||
import {Col, Row} from 'vant'; |
||||
import {Cell, CellGroup} from 'vant'; |
||||
import {NavBar} from 'vant'; |
||||
import {Button} from 'vant'; |
||||
import {Form} from 'vant'; |
||||
import {Field} from 'vant'; |
||||
import VueLocalStorage from 'vue-localstorage' |
||||
import {List} from 'vant'; |
||||
import {PullRefresh} from 'vant'; |
||||
import {NoticeBar} from 'vant'; |
||||
import {Swipe, SwipeItem} from 'vant'; |
||||
import { Lazyload } from 'vant'; |
||||
import { Divider } from 'vant'; |
||||
import { Grid, GridItem } from 'vant'; |
||||
import { RadioGroup, Radio } from 'vant'; |
||||
|
||||
import { VueAxios } from './utils/request' |
||||
|
||||
|
||||
import VeLine from 'v-charts/lib/line.common' |
||||
Vue.component(VeLine.name, VeLine) |
||||
|
||||
|
||||
import 'vant/lib/index.css'; |
||||
import './assets/css/index.css'; |
||||
|
||||
//缓存
|
||||
Vue.use(VueLocalStorage).use(Lazyload) |
||||
|
||||
Vue.use(Tabbar).use(TabbarItem).use(Icon).use(Overlay).use(Loading).use(Dialog).use(ActionSheet).use(Toast).use(VanImage).use(Card) |
||||
Vue.use(Skeleton).use(Col).use(Row).use(Cell).use(CellGroup).use(NavBar).use(Form).use(Field).use(Button) |
||||
Vue.use(List).use(PullRefresh).use(NoticeBar).use(Swipe).use(SwipeItem) |
||||
Vue.use(Divider).use(Grid).use(GridItem).use(RadioGroup).use(Radio) |
||||
|
||||
// mount axios to `Vue.$http` and `this.$http`
|
||||
Vue.use(VueAxios) |
||||
|
||||
new Vue({ |
||||
router, |
||||
el: '#app', |
||||
render: h => h(App) |
||||
}); |
@ -0,0 +1,109 @@ |
||||
import Vue from 'vue'; |
||||
import Router from 'vue-router'; |
||||
|
||||
Vue.use(Router); |
||||
|
||||
const routes = [ |
||||
{ |
||||
path: '*', |
||||
redirect: '/home' |
||||
}, |
||||
{ |
||||
name: 'main', |
||||
component: () => import('./view/main'), |
||||
meta: {title: 'BEAM'} |
||||
}, { |
||||
name: 'home', |
||||
component: () => import('./view/home'), |
||||
meta: {title: '首页'} |
||||
}, |
||||
{ |
||||
name: 'user', |
||||
component: () => import('./view/user'), |
||||
meta: {title: '会员中心'} |
||||
}, { |
||||
name: 'userInfo', |
||||
component: () => import('./view/user/UserInfo'), |
||||
meta: {title: '个人信息'} |
||||
}, { |
||||
name: 'register', |
||||
component: () => import('./view/user/Register'), |
||||
meta: {title: '注册'} |
||||
}, { |
||||
name: 'login', |
||||
component: () => import('./view/user/Login'), |
||||
meta: {title: '登录'} |
||||
}, |
||||
{ |
||||
name: 'update/password', |
||||
component: () => import('./view/user/UpdatePassword'), |
||||
meta: {title: '修改密码'} |
||||
}, |
||||
{ |
||||
name: 'wallet/coin/address/list', |
||||
component: () => import('./view/wallet/CoinAddressList'), |
||||
meta: {title: '钱包地址'} |
||||
}, |
||||
{ |
||||
name: 'wallet/coin/address/add', |
||||
component: () => import('./view/wallet/AddCoinAddress'), |
||||
meta: {title: '添加钱包地址'} |
||||
}, { |
||||
name: 'wallet/coin/address/select', |
||||
component: () => import('./view/wallet/CoinAddressSelect'), |
||||
meta: {title: '选择钱包地址'} |
||||
}, |
||||
{ |
||||
name: 'profit/list', |
||||
component: () => import('./view/history/HistoryRecords'), |
||||
meta: {title: '历史记录'} |
||||
} |
||||
, { |
||||
name: 'profit/detail', |
||||
component: () => import('./view/history/HistoryRecordsDetail'), |
||||
meta: {title: '历史记录详情'}, |
||||
props: true |
||||
} |
||||
, |
||||
{ |
||||
name: 'order/list', |
||||
component: () => import('./view/order'), |
||||
meta: {title: '订单记录'} |
||||
}, { |
||||
name: 'order/detail', |
||||
component: () => import('./view/order/OrderDetail'), |
||||
meta: {title: '订单详情', keepAlive: true} |
||||
}, { |
||||
name: 'order/create', |
||||
component: () => import('./view/order/CreateOrder'), |
||||
meta: {title: '算力租赁' ,keepAlive: true} |
||||
}, { |
||||
name: 'order/confirm', |
||||
component: () => import('./view/order/OrderConfirm'), |
||||
meta: {title: '确认订单',keepAlive: true} |
||||
}, { |
||||
name: 'order/pay/success', |
||||
component: () => import('./view/order/OrderPaySuccess'), |
||||
meta: {title: '支付成功'} |
||||
}, |
||||
] |
||||
; |
||||
|
||||
// add route path
|
||||
routes.forEach(route => { |
||||
route.path = route.path || '/' + (route.name || ''); |
||||
}); |
||||
|
||||
const router = new Router({routes}); |
||||
|
||||
router.beforeEach((to, from, next) => { |
||||
const title = to.meta && to.meta.title; |
||||
if (title) { |
||||
document.title = title; |
||||
} |
||||
next(); |
||||
}); |
||||
|
||||
export { |
||||
router |
||||
}; |
@ -0,0 +1,35 @@ |
||||
const VueAxios = { |
||||
vm: {}, |
||||
// eslint-disable-next-line no-unused-vars
|
||||
install (Vue, instance) { |
||||
if (this.installed) { |
||||
return |
||||
} |
||||
this.installed = true |
||||
|
||||
if (!instance) { |
||||
// eslint-disable-next-line no-console
|
||||
console.error('You have to install axios') |
||||
return |
||||
} |
||||
|
||||
Vue.axios = instance |
||||
|
||||
Object.defineProperties(Vue.prototype, { |
||||
axios: { |
||||
get: function get () { |
||||
return instance |
||||
} |
||||
}, |
||||
$http: { |
||||
get: function get () { |
||||
return instance |
||||
} |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
|
||||
export { |
||||
VueAxios |
||||
} |
@ -0,0 +1,27 @@ |
||||
import JSEncrypt from 'jsencrypt'; |
||||
|
||||
|
||||
const PublicKey = "/nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJpkSi2LFIgkbybBA+m2wmynUfi9L8NDbUKAwBvr+zr9kUTNQ/wyZt43LyfAgpkAfv0KNxli+MxdAWjX3JrAnWUCAwEAAQ==" |
||||
|
||||
export function isEmpty(obj) { |
||||
if (typeof obj == "undefined" || obj == null || obj == "") { |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
export function rsaEncrypt(value) { |
||||
window.console.log(value); |
||||
var encrypt = new JSEncrypt(); |
||||
encrypt.setPublicKey(PublicKey); |
||||
const encrypted = encrypt.encrypt(value); |
||||
window.console.log("value:"+value); |
||||
window.console.log("PublicKey:"+PublicKey); |
||||
window.console.log("encrypted:"+encrypted); |
||||
|
||||
return encrypted; |
||||
} |
||||
|
||||
|
||||
|
@ -0,0 +1,79 @@ |
||||
import axios from 'axios' |
||||
import {VueAxios} from './axios' |
||||
import Vue from 'vue'; |
||||
import {Toast} from 'vant'; |
||||
import {router} from "../router"; |
||||
|
||||
Vue.use(Toast); |
||||
// 创建 axios 实例
|
||||
const request = axios.create({ |
||||
// API 请求的默认前缀
|
||||
// baseURL: 'http://mapi.sliyun.cn',
|
||||
baseURL: 'http://192.168.0.182:8892', |
||||
timeout: 50000// 请求超时时间
|
||||
}) |
||||
axios.defaults.withCredentials = true |
||||
|
||||
|
||||
// 异常拦截处理器
|
||||
const errorHandler = (error) => { |
||||
window.console.log("error" + error) |
||||
|
||||
if (error.response) { |
||||
const data = error.response.data |
||||
|
||||
// 从 localstorage 获取 token
|
||||
const token = localStorage.getItem('ACCESS_TOKEN') |
||||
if (error.response.status === 403) { |
||||
Toast.fail(data.message); |
||||
} |
||||
if (error.response.status === 400) { |
||||
window.console.log("code:" + data.code) |
||||
Toast.fail(data.message); |
||||
if (data.code==10001) { |
||||
localStorage.removeItem('ACCESS_TOKEN') |
||||
localStorage.removeItem('UserInfo') |
||||
router.push("/login") |
||||
} |
||||
} |
||||
if (error.response.status === 401) { |
||||
if (token) { |
||||
Toast.fail(data.message); |
||||
} |
||||
} |
||||
} |
||||
return Promise.reject(error) |
||||
} |
||||
|
||||
// request interceptor
|
||||
request.interceptors.request.use(config => { |
||||
// const token = storage.get(ACCESS_TOKEN)
|
||||
const token = localStorage.getItem('ACCESS_TOKEN') |
||||
// 如果 token 存在
|
||||
// 让每个请求携带自定义 token 请根据实际情况自行修改
|
||||
if (token) { |
||||
config.headers['Access-Token'] = token |
||||
config.headers['Token'] = token |
||||
} |
||||
config.headers['Access-Token'] = 'application/json;charset=UTF-8' |
||||
return config |
||||
}, errorHandler) |
||||
|
||||
// response interceptor
|
||||
request.interceptors.response.use((response) => { |
||||
return response.data |
||||
}, errorHandler) |
||||
|
||||
const installer = { |
||||
vm: {}, |
||||
install(Vue) { |
||||
Vue.use(VueAxios, request) |
||||
} |
||||
} |
||||
|
||||
export default request |
||||
|
||||
export { |
||||
installer as VueAxios, |
||||
request as axios |
||||
} |
@ -0,0 +1,149 @@ |
||||
<template> |
||||
<div class="content"> |
||||
<van-nav-bar |
||||
title="历史记录" |
||||
left-text="返回" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
/> |
||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh"> |
||||
<van-list |
||||
v-model="loading" |
||||
:finished="finished" |
||||
finished-text="没有更多了" |
||||
@load="onLoad" |
||||
> |
||||
<div v-for="item in list" |
||||
:key="item.id" |
||||
:name="item.id" |
||||
@click="onItemClick(item)"> |
||||
<div class="history-list-item"> |
||||
<van-image |
||||
style="float: left;" |
||||
round |
||||
width="30" |
||||
height="30" |
||||
:src=item.icon |
||||
/> |
||||
<div style="float: left; margin-left: 10px"> |
||||
<div class="history-list-coin-name" style="top:8px; left:8px">{{item.cnName}}</div> |
||||
<div style="top:28px ;left:8px">{{item.enName}}</div> |
||||
</div> |
||||
<div> |
||||
<div class="history-list-item-detail">详情 |
||||
</div> |
||||
<div style="flex: 1;text-align: right; float: right;"> |
||||
<div style="color: #1796e8">{{item.type==1?"+":"+"}}{{item.profit}}</div> |
||||
<div>{{item.createTime}}</div> |
||||
</div> |
||||
</div> |
||||
<span class="history-list-item-type">{{item.tag}}</span> |
||||
</div> |
||||
<div class="history-list-item-divider"/> |
||||
</div> |
||||
|
||||
</van-list> |
||||
</van-pull-refresh> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import {getProfitList} from '@/api/user' |
||||
|
||||
export default { |
||||
name: "ProfitList", |
||||
data() { |
||||
return { |
||||
list: [], |
||||
loading: false, |
||||
finished: false, |
||||
refreshing: false, |
||||
} |
||||
}, methods: { |
||||
onClickLeft() { |
||||
this.$router.go(-1) |
||||
}, |
||||
onItemClick(item) { |
||||
window.console.log(item) |
||||
this.$router.push({name: 'profit/detail', query:{item: JSON.stringify(item)}}) |
||||
}, |
||||
onLoad() { |
||||
setTimeout(() => { |
||||
if (this.refreshing) { |
||||
this.list = []; |
||||
this.refreshing = false; |
||||
} |
||||
getProfitList().then(res => { |
||||
window.console.log("history:" + res.data.length) |
||||
this.list = res.data; |
||||
} |
||||
) |
||||
// 加载状态结束 |
||||
this.loading = true; |
||||
// 数据全部加载完成 |
||||
this.finished = true; |
||||
}, 1000); |
||||
}, |
||||
onRefresh() { |
||||
// 清空列表数据 |
||||
this.finished = false; |
||||
// 重新加载数据 |
||||
// 将 loading 设置为 true,表示处于加载状态 |
||||
this.loading = true; |
||||
this.onLoad(); |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
body { |
||||
height: 100%; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.content { |
||||
background: white; |
||||
height: 100%; |
||||
} |
||||
|
||||
|
||||
.history-list-item { |
||||
min-height: 35px; |
||||
position: relative; |
||||
font-size: 12px; |
||||
margin: 5px 15px; |
||||
} |
||||
|
||||
.history-list-coin-name { |
||||
font-size: 12px; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.history-list-item-type { |
||||
font-size: 8px; |
||||
left: 50%; |
||||
top: 50%; |
||||
} |
||||
|
||||
.history-list-item-detail { |
||||
float: right; |
||||
padding: 3px; |
||||
border: 1px solid #1796e8; |
||||
border-radius: 4px; |
||||
margin-left: 10px; |
||||
font-size: 6px; |
||||
color: #1796e8; |
||||
right: 8px; |
||||
bottom: 8px; |
||||
|
||||
} |
||||
|
||||
.history-list-item-divider { |
||||
background: #e8e8e8; |
||||
height: 1px; |
||||
margin-left: 55px; |
||||
margin-right: 15px; |
||||
} |
||||
</style> |
@ -0,0 +1,143 @@ |
||||
<template> |
||||
<div class="content"> |
||||
<van-nav-bar |
||||
title="详情" |
||||
left-text="返回" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
@click-right="onClickRight" |
||||
/> |
||||
<div class="hrd-content"> |
||||
<van-image class="hrd-coin-logo" |
||||
round |
||||
width="60px" |
||||
|
||||
height="60px" |
||||
v-bind:src=item.icon> |
||||
<template v-slot:loading> |
||||
<van-loading type="spinner" size="20"/> |
||||
</template> |
||||
</van-image> |
||||
|
||||
<div class="hrd-top-item"> |
||||
<div class="hrd-title">{{item.cnName}}({{item.enName}})</div> |
||||
<div class="hrd-sum">{{item.type==1?"+":"+"}}{{item.profit}}</div> |
||||
<div>{{"区块奖励"}}</div> |
||||
</div> |
||||
|
||||
|
||||
<div class="hrd-card"> |
||||
<div class="hrd-card-item"> |
||||
<span>创建时间</span> |
||||
<span class="hrd-card-item-right">{{item.createTime}}</span> |
||||
|
||||
</div> |
||||
<div class="hrd-card-item"> |
||||
<span>备注说明</span> |
||||
<span class="hrd-card-item-right">算力租赁订单号:{{item.orderSn}}</span> |
||||
|
||||
</div> |
||||
<div class="hrd-card-item"> |
||||
<span>记录ID</span> |
||||
<span class="hrd-card-item-right">{{item.recordSn}}</span> |
||||
|
||||
</div> |
||||
|
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
|
||||
export default { |
||||
name: "historyRecordsDetail", |
||||
data() { |
||||
let params = JSON.parse(this.$route.query.item) |
||||
window.console.log('submit', params); |
||||
this.item = params; |
||||
return { |
||||
fullHeight: document.documentElement.clientHeight - 160, |
||||
beam: { |
||||
logo: "", |
||||
name: "BEAM" |
||||
}, |
||||
item: params |
||||
} |
||||
}, |
||||
created() { |
||||
// let params =this.props['item'] |
||||
// window.console.log('submit', params); |
||||
// window.console.log('submit', params.name); |
||||
// this.item = params; |
||||
} |
||||
, |
||||
methods: { |
||||
onClickLeft() { |
||||
this.$router.go(-1) |
||||
} |
||||
, |
||||
onClickRight() { |
||||
} |
||||
} |
||||
, |
||||
setup() { |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.content { |
||||
height: calc(100vh); |
||||
background: #f7f8fa; |
||||
width: 100%; |
||||
text-align: center; |
||||
bottom: 0px; |
||||
} |
||||
|
||||
|
||||
.hrd-coin-logo { |
||||
margin-top: 40px; |
||||
|
||||
} |
||||
|
||||
.hrd-top-item div { |
||||
margin-bottom: 10px; |
||||
margin-top: 10px; |
||||
} |
||||
|
||||
.hrd-title { |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.hrd-sum { |
||||
font-size: 18px; |
||||
font-weight: bold; |
||||
color: #ff4444; |
||||
} |
||||
|
||||
.hrd-card { |
||||
background-color: #ffffff; |
||||
margin: 10px; |
||||
border: 3px solid #ffffff; |
||||
border-radius: 10px; |
||||
font-size: 12px; |
||||
padding: 15px 10px; |
||||
text-align: left; |
||||
color: black; |
||||
|
||||
} |
||||
|
||||
|
||||
.hrd-card-item { |
||||
color: black; |
||||
min-height: 40px; |
||||
} |
||||
|
||||
.hrd-card-item-right { |
||||
right: 0; |
||||
float: right; |
||||
} |
||||
|
||||
</style> |
@ -0,0 +1,20 @@ |
||||
<template> |
||||
<div class="content"> |
||||
<van-nav-bar |
||||
title="历史记录" |
||||
left-text="返回" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
/> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: "NoticeVue" |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
|
||||
</style> |
@ -0,0 +1,342 @@ |
||||
<template> |
||||
<div id="home"> |
||||
<van-overlay :show="overlayShow" @click="overlayShow = false"> |
||||
<div class="wrapper" @click.stop> |
||||
<div class="block"> |
||||
<van-loading color="#1989fa"/> |
||||
</div> |
||||
</div> |
||||
</van-overlay> |
||||
|
||||
<div class="home-top"> |
||||
<van-image class="home-logo" width="25px" height="25px" v-bind:src=logo |
||||
/> |
||||
<span>算力云</span> |
||||
</div> |
||||
<div class="home-banner"> |
||||
<van-swipe class="home-banner-list" :autoplay="3000" indicator-color="white"> |
||||
<van-swipe-item class="home-banner-item" v-for="(item, index) in banner" :key="index" |
||||
@click="onBanner(item)"> |
||||
<van-image fit="fill" width="100%" height="160" v-bind:src=item.imgUrl radius="10px"/> |
||||
</van-swipe-item> |
||||
</van-swipe> |
||||
</div> |
||||
|
||||
<van-notice-bar left-icon="volume-o" :scrollable="false"> |
||||
<van-swipe vertical class="notice-swipe" :autoplay="3000" :show-indicators="false"> |
||||
<van-swipe-item v-for="(item, id) in notice" :key="id" @click="onNotice(item)"> |
||||
<span class="home-notice-time">{{getNoticeTime(item.noticeTimestamp)}}</span> |
||||
{{getNoticeSource(item.noticeSource)}} 获得 {{item.profit}} {{item.coinName}} |
||||
</van-swipe-item> |
||||
</van-swipe> |
||||
</van-notice-bar> |
||||
<div class="home-list-title"> |
||||
快速挖矿 |
||||
</div> |
||||
|
||||
<van-list class="home-list" |
||||
v-model="loading" |
||||
:finished="finished" |
||||
finished-text="没有更多了" |
||||
@load="onLoad" |
||||
> |
||||
<div class="home-list-item" v-for="item in list" :key="item.id"> |
||||
<van-image |
||||
style="float: left;" |
||||
round |
||||
width="40" |
||||
height="40" |
||||
:src=item.icon |
||||
/> |
||||
<div style="float: left; margin-left: 10px"> |
||||
<div style="top:8px; left:8px;font-weight: bold">{{item.cnName}}</div> |
||||
<div style="top:28px ;left:8px">{{item.enName}}</div> |
||||
</div> |
||||
|
||||
<div style="position:absolute;bottom:8px; left:8px"> |
||||
<div>平均出块:{{getAverageTime(item.averageDuration)}}</div> |
||||
<div>距上次出块:{{ getLatestTime(item.latestTime)}}</div> |
||||
</div> |
||||
<div style="float:right;top:8px; right:8px"> |
||||
<div class="home-list-item-right">¥{{item.currentPrice}} / {{item.enName}}</div> |
||||
<div class="home-list-item-right">区块奖励: {{item.reward}} {{item.enName}}</div> |
||||
</div> |
||||
<van-button style="position:absolute;right:8px;bottom:8px;" type="info" size="mini" |
||||
@click="onItemClick(item)">租用算力 |
||||
</van-button> |
||||
</div> |
||||
<!-- <van-cell v-for="item in list" :key="item" :title="item"/>--> |
||||
</van-list> |
||||
|
||||
|
||||
<router-view/> |
||||
<van-tabbar route> |
||||
<van-tabbar-item replace to="/home" icon="wap-home-o">首页</van-tabbar-item> |
||||
<van-tabbar-item @click="replace" icon="user-o">{{tabName}}</van-tabbar-item> |
||||
</van-tabbar> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import Vue from 'vue'; |
||||
import {Overlay} from 'vant'; |
||||
import {logo} from '@/core/icons' |
||||
import {getHomeInfo} from '@/api/app' |
||||
import {isEmpty} from "../../utils/common"; |
||||
|
||||
Vue.use(Overlay); |
||||
|
||||
let userToken; |
||||
export default { |
||||
components: {}, |
||||
data() { |
||||
userToken = localStorage.getItem('ACCESS_TOKEN') |
||||
return { |
||||
tabName: userToken === null ? "注册/登录" : "个人中心", |
||||
logo: logo, |
||||
banner: [], |
||||
list: [], |
||||
notice: [], |
||||
overlayShow: true, |
||||
loading: false, |
||||
finished: false, |
||||
pageIndex: 1, |
||||
} |
||||
}, created() { |
||||
}, method() { |
||||
}, |
||||
methods: { |
||||
replace() { |
||||
userToken = localStorage.getItem('ACCESS_TOKEN') |
||||
if (isEmpty(userToken)) { |
||||
this.$router.push('/login'); |
||||
} else { |
||||
this.$router.replace('user'); |
||||
|
||||
} |
||||
}, |
||||
onBanner(item) { |
||||
window.console.log("item:" + item) |
||||
window.location = item.actionEvent |
||||
}, |
||||
onNotice(item) { |
||||
window.console.log("Index:" + item.name) |
||||
window.location = item.url; |
||||
}, |
||||
getNoticeTime(time) { |
||||
const timestamp = Date.parse(new Date()) / 1000; |
||||
let s = timestamp - time; |
||||
return Math.floor(s / 60) + "分钟前"; |
||||
}, |
||||
getLatestTime(time) { |
||||
const timestamp = Date.parse(new Date()) / 1000; |
||||
let s = timestamp - time; |
||||
window.console.log("getLatestTime min:" + time + "|" + s); |
||||
|
||||
return Math.floor(s / 60) + "分钟前"; |
||||
}, |
||||
getAverageTime(duration) { |
||||
let m = Math.floor((duration / 60 % 60)) < 10 ? Math.floor((duration / 60 % 60)) : Math.floor((duration / 60 % 60)); |
||||
let s = Math.floor((duration % 60)) < 10 ? Math.floor((duration % 60)) : Math.floor((duration % 60)); |
||||
// window.console.log("AverageTime min:" + m + "|" + s); |
||||
if (m > 0 && s > 0) { |
||||
return m + "分 " + (s > 0) ? s + "秒" : ""; |
||||
} else if (m > 0) { |
||||
return m + "分 "; |
||||
} else { |
||||
return s + "秒"; |
||||
} |
||||
}, |
||||
getNoticeSource(source) { |
||||
if (source.length > 10) { |
||||
return source.substring(0, 10) + "..." |
||||
} |
||||
return source; |
||||
}, |
||||
onItemClick(item) { |
||||
window.console.log("Index:" + item.name) |
||||
this.$router.push({name: 'order/create', params: {item: item}}) |
||||
}, |
||||
onLoad() { |
||||
this.loading = false; |
||||
const params = { |
||||
'page': this.pageIndex, |
||||
'size': 20, |
||||
} |
||||
getHomeInfo(params).then(response => { |
||||
window.console.log(response) |
||||
window.console.log(response.data) |
||||
window.console.log(response.data.coin) |
||||
this.overlayShow = false; |
||||
|
||||
if (this.pageIndex == 1) { |
||||
this.list = []; |
||||
} |
||||
|
||||
this.banner = response.data.banner; |
||||
this.notice = response.data.notice; |
||||
for (let i = 0; i < response.data.coin.length; i++) { |
||||
this.list.push(response.data.coin[i]); |
||||
} |
||||
// 加载状态结束 |
||||
this.loading = true; |
||||
if (this.list.length < 20) { |
||||
this.finished = true; |
||||
} else { |
||||
this.pageIndex++; |
||||
} |
||||
|
||||
} |
||||
) |
||||
|
||||
// // 异步更新数据 |
||||
// // setTimeout 仅做示例,真实场景中一般为 ajax 请求 |
||||
// setTimeout(() => { |
||||
// for (let i = 0; i < 40; i++) { |
||||
// this.list.push({ |
||||
// id: i, |
||||
// enName: "BTC" + i, |
||||
// cnName: "比特币" + i, |
||||
// icon: "BTC" + i, |
||||
// average: "" + i + "5 分 08 秒", |
||||
// last: '5分钟', |
||||
// amount: 789 * i, |
||||
// reward: '3.' + i, |
||||
// }); |
||||
// } |
||||
// // 加载状态结束 |
||||
// this.loading = false; |
||||
// |
||||
// // 数据全部加载完成 |
||||
// if (this.list.length >= 40) { |
||||
// this.finished = true; |
||||
// } |
||||
// }, 1000); |
||||
}, |
||||
|
||||
|
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style> |
||||
body { |
||||
font-size: 16px; |
||||
background-color: #ffffff; |
||||
-webkit-font-smoothing: antialiased; |
||||
} |
||||
|
||||
.home-top { |
||||
text-align: center; |
||||
overflow: hidden; |
||||
height: 40px; |
||||
font-weight: bold; |
||||
background-color: white; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
} |
||||
|
||||
.home-top span { |
||||
margin-left: 5px; |
||||
} |
||||
|
||||
.home-logo { |
||||
display: inline-block; |
||||
} |
||||
|
||||
.home-banner { |
||||
height: 160px; |
||||
padding: 10px; |
||||
margin: 0px; |
||||
background: white; |
||||
} |
||||
|
||||
.home-list-title { |
||||
padding-left: 10px; |
||||
height: 40px; |
||||
line-height: 40px; |
||||
background-color: white; |
||||
font-size: 14px; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.home-banner-list { |
||||
height: 160px; |
||||
} |
||||
|
||||
.home-banner-item { |
||||
height: 160px; |
||||
|
||||
} |
||||
|
||||
.notice-swipe { |
||||
height: 40px; |
||||
line-height: 40px; |
||||
margin-top: 10px; |
||||
margin-bottom: 10px; |
||||
} |
||||
|
||||
.home-notice-time { |
||||
border: 1px solid #f60; |
||||
border-radius: 20px; |
||||
padding: 3px 5px; |
||||
margin-right: 6px; |
||||
|
||||
} |
||||
|
||||
.home-list { |
||||
padding-top: 1px; |
||||
background-color: #f7f8fa; |
||||
|
||||
} |
||||
|
||||
.home-list-item { |
||||
height: 80px; |
||||
margin: 10px; |
||||
padding: 10px; |
||||
border: 1px solid #f5f6f9; |
||||
background-color: #ffffff; |
||||
border-radius: 10px; |
||||
position: relative; |
||||
font-size: 12px; |
||||
box-shadow: 0 1px 1px #f5f6f9 |
||||
} |
||||
|
||||
.home-list-item-left { |
||||
height: 25px; |
||||
font-size: 12px; |
||||
text-align: left; |
||||
line-height: 25px; |
||||
} |
||||
|
||||
.home-list-item-right { |
||||
right: 0; |
||||
text-align: right; |
||||
} |
||||
|
||||
.wrapper { |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: center; |
||||
height: 100%; |
||||
background: white; |
||||
} |
||||
|
||||
.block { |
||||
width: 80px; |
||||
border-radius: 10px; |
||||
height: 80px; |
||||
background-color: rgba(255, 255, 255, 255); |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
text-align: center; |
||||
} |
||||
</style> |
@ -0,0 +1,36 @@ |
||||
<template> |
||||
<div id="app"> |
||||
<router-view/> |
||||
<van-tabbar route> |
||||
<van-tabbar-item replace to="/home" icon="wap-home-o">首页</van-tabbar-item> |
||||
<van-tabbar-item replace to="/user" icon="user-o">注册/登录</van-tabbar-item> |
||||
</van-tabbar> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import {ref} from 'vue'; |
||||
|
||||
|
||||
export default { |
||||
components: {}, |
||||
data() { |
||||
return{} |
||||
}, method() { |
||||
}, |
||||
methods: {}, |
||||
created() { |
||||
}, setup() { |
||||
const active = ref(0); |
||||
return {active}; |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style> |
||||
body { |
||||
font-size: 16px; |
||||
background-color: #f8f8f8; |
||||
-webkit-font-smoothing: antialiased; |
||||
} |
||||
</style> |
@ -0,0 +1,595 @@ |
||||
<template> |
||||
<div class="content"> |
||||
<van-nav-bar |
||||
title="算力租赁" |
||||
left-text="返回" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
@click-right="onClickRight"/> |
||||
<div class="order-create-content"> |
||||
|
||||
|
||||
<div class="order-create-top"> |
||||
<span>{{getOrderInfo()}} |
||||
</span> |
||||
</div> |
||||
|
||||
<div> |
||||
<div class="order-create-item-title"> |
||||
<van-image width="20" height="20" :src=icon_service |
||||
/> |
||||
<span>算力包</span> |
||||
</div> |
||||
<div class="coin-sku-list"> |
||||
<div :class="skuActive==item.id?'active':'Classification'" v-for="(item, id) in basicInfo.skuList" :key="id" |
||||
@click="onSkuItemClick(item)"> |
||||
<span>{{item.number}}{{item.packageUnitName}}/S</span> |
||||
</div> |
||||
</div> |
||||
<!-- <div class="order-create-specs" @click="onSpecsClick">--> |
||||
<!-- <span>{{item.specs}}</span>--> |
||||
<!-- </div>--> |
||||
<div class="order-create-divider"></div> |
||||
</div> |
||||
<div> |
||||
<div class="order-create-item-title"> |
||||
<van-image width="20" height="20" :src=icon_time |
||||
/> |
||||
<span>租用时段</span> |
||||
</div> |
||||
|
||||
<div class="order-create-time"> |
||||
<div class="order-create-time-time" @click="onTimeSelect(0)">{{time.startTime}} |
||||
<span></span> |
||||
</div> |
||||
<div class="order-create-time-divider"> |
||||
<span class="order-create-time-divider-bg"></span> |
||||
</div> |
||||
<div class="order-create-time-time" @click="onTimeSelect(1)">{{time.endTime}} |
||||
<span></span> |
||||
</div> |
||||
</div> |
||||
<div class="order-create-divider"></div> |
||||
</div> |
||||
<div> |
||||
<div class="order-create-item-title"> |
||||
<van-image width="20" height="20" :src=icon_excavate |
||||
/> |
||||
<span>挖矿类型</span> |
||||
</div> |
||||
<div class="coin-list"> |
||||
<div :class="active==item.id?'active':'Classification'" v-for="(item, id) in basicInfo.coinList" :key="id" |
||||
@click="onItemClick(item)"> |
||||
<van-image |
||||
round |
||||
width="20" |
||||
height="20" |
||||
:src=item.icon |
||||
/> |
||||
<span>{{item.enName}}</span> |
||||
</div> |
||||
</div> |
||||
<div class="order-create-divider"></div> |
||||
</div> |
||||
<div> |
||||
<div class="order-create-item-title"> |
||||
<van-image width="20" height="20" :src=icon_wallet |
||||
/> |
||||
<span>钱包地址</span> |
||||
</div> |
||||
<van-field |
||||
class="sinput" |
||||
v-model="coinAddress" |
||||
center |
||||
clearable |
||||
placeholder="请输入钱包地址" |
||||
> |
||||
<template #button> |
||||
<van-button size="mini" type="info" @click="onSelect">选择</van-button> |
||||
</template> |
||||
</van-field> |
||||
<div class="order-create-divider"></div> |
||||
</div> |
||||
|
||||
</div> |
||||
<div class="order-create-footer" @click="goConfirm(1)"> |
||||
<span> |
||||
租 赁 |
||||
</span> |
||||
</div> |
||||
<van-popup v-model="startTimeShow" position="bottom" :style="{ height: '40%' }"> |
||||
<van-datetime-picker |
||||
v-model="currentDate" |
||||
type="datetime" |
||||
title="选择开始时间" |
||||
:min-date="minDate" |
||||
:max-date="maxDate" |
||||
:formatter="formatter" |
||||
@confirm="onTimePicker" |
||||
@cancel="startTimeShow = false" |
||||
/> |
||||
</van-popup> |
||||
<van-popup v-model="timeShow" position="bottom" :style="{ height: '40%' }"> |
||||
<van-datetime-picker |
||||
type="datetime" |
||||
title="选择结束时间" |
||||
:min-date="endMinDate" |
||||
:max-date="maxDate" |
||||
:filter="minuteFilter" |
||||
:formatter="formatter" |
||||
@confirm="onTimePicker" |
||||
@cancel="timeShow = false" |
||||
/> |
||||
</van-popup> |
||||
|
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import {Tag} from 'vant'; |
||||
import Vue from 'vue'; |
||||
import {DatetimePicker} from 'vant'; |
||||
import {Popup} from 'vant'; |
||||
import {orderCreate,getOrderBasicInfo} from '@/api/order' |
||||
import {Toast} from 'vant'; |
||||
import {isEmpty} from '@/utils/common' |
||||
|
||||
import {pay_ali, wallet, time, service, excavate} from '@/core/icons' |
||||
|
||||
|
||||
Vue.use(Tag).use(Popup).use(DatetimePicker); |
||||
|
||||
export default { |
||||
name: "CreateOrder", |
||||
components: {}, |
||||
data() { |
||||
return { |
||||
coinAddress: '', |
||||
minDate: new Date(), |
||||
maxDate: new Date(2030, 12, 30), |
||||
currentDate: new Date(), |
||||
endMinDate: new Date(), |
||||
endCurrentDate: new Date(), |
||||
timeShow: false, |
||||
startTimeShow: false, |
||||
icon_wallet: wallet, |
||||
icon_time: time, |
||||
icon_service: service, |
||||
icon_excavate: excavate, |
||||
ali_icon: pay_ali, |
||||
minInterval: 1, |
||||
time: { |
||||
startTimeStamp: 0, |
||||
endTimeStamp: 0, |
||||
startTime: "开始时间", |
||||
endTime: "结束时间", |
||||
currentType: -1, |
||||
}, |
||||
item: {}, |
||||
skuItem: {}, |
||||
coinItem: {}, |
||||
basicInfo:{ |
||||
skuList: [], |
||||
coinList: [], |
||||
}, |
||||
skuActive: '', |
||||
active: '' |
||||
} |
||||
}, |
||||
created() { |
||||
getOrderBasicInfo().then(response => { |
||||
window.console.log("getOrderBasicInfo:" + response) |
||||
this.basicInfo = response.data; |
||||
this.currentDate = new Date(response.data.startTime); |
||||
window.console.log(response) |
||||
}) |
||||
const addressEntity = JSON.parse(localStorage.getItem('selectAddress')) |
||||
if (addressEntity) { |
||||
this.coinAddress = addressEntity.address |
||||
localStorage.removeItem('selectAddress') |
||||
} |
||||
}, |
||||
methods: { |
||||
onClickLeft() { |
||||
this.$router.go(-1) |
||||
}, |
||||
onClickRight() { |
||||
}, |
||||
onTimeSelect(index) { |
||||
if (isEmpty(this.skuItem.id)) { |
||||
Toast.fail("请选择算力包") |
||||
return; |
||||
} |
||||
if (this.time.startTimeStamp === 0 && index == 1) { |
||||
Toast.fail("请选择开始时间") |
||||
return; |
||||
} |
||||
if (index == 0) { |
||||
this.startTimeShow = true; |
||||
} else { |
||||
this.timeShow = true; |
||||
} |
||||
this.time.currentType = index; |
||||
}, |
||||
onTimePicker(val) { |
||||
window.console.log(val); |
||||
this.timeShow = false; |
||||
this.startTimeShow = false; |
||||
let year = val.getFullYear() |
||||
let month = val.getMonth() + 1 |
||||
let day = val.getDate() |
||||
let hour = val.getHours() |
||||
let minute = val.getMinutes() |
||||
if (month >= 1 && month <= 9) { |
||||
month = `0${month}` |
||||
} |
||||
if (day >= 1 && day <= 9) { |
||||
day = `0${day}` |
||||
} |
||||
if (hour >= 0 && hour <= 9) { |
||||
hour = `0${hour}` |
||||
} |
||||
if (minute >= 0 && minute <= 9) { |
||||
minute = `0${minute}` |
||||
} |
||||
let timeValue = `${year}-${month}-${day} ${hour}:${minute}` |
||||
let timestamp = this.currentDate.getTime() / 1000; |
||||
if (this.time.currentType === 0) { |
||||
this.time.startTimeStamp = timestamp; |
||||
this.time.startTime = timeValue; |
||||
// this.endCurrentDate = new Date( this.currentDate.getTime() + this.minInterval * 60 * 1000) |
||||
this.endMinDate = new Date(this.currentDate.getTime() + this.minInterval * 60 * 1000) |
||||
} else { |
||||
this.time.endTime = timeValue; |
||||
this.time.endTimeStamp = timestamp; |
||||
} |
||||
}, |
||||
goConfirm() { |
||||
let userToken = localStorage.getItem('ACCESS_TOKEN') |
||||
if (isEmpty(userToken)) { |
||||
this.$router.push('/login'); |
||||
return; |
||||
} |
||||
if (isEmpty(this.skuItem.id)) { |
||||
Toast.fail("请选择算力包") |
||||
return; |
||||
} |
||||
if (this.time.startTimeStamp === 0) { |
||||
Toast.fail("请选择开始时间") |
||||
return; |
||||
} |
||||
if (this.time.endTimeStamp === 0) { |
||||
Toast.fail("请选择结束时间") |
||||
return; |
||||
} |
||||
if (isEmpty(this.coinItem.id)) { |
||||
Toast.fail("请选择挖矿类型") |
||||
return; |
||||
} |
||||
if (isEmpty(this.coinAddress)) { |
||||
Toast.fail("请输入或选择货币地址") |
||||
return; |
||||
} |
||||
const params = { |
||||
"coinId": this.coinItem.id, |
||||
"skuId": this.skuItem.id, |
||||
"startTime": this.time.startTimeStamp, |
||||
"endTime": this.time.endTimeStamp, |
||||
"coinAddress": this.coinAddress, |
||||
} |
||||
window.console.log("params:" + JSON.stringify(params)) |
||||
|
||||
orderCreate(params).then(res => { |
||||
window.console.log(res) |
||||
this.$router.push({ |
||||
name: 'order/confirm', |
||||
query: { |
||||
item: JSON.stringify(res.data), |
||||
hash: this.skuItem.number + this.skuItem.packageUnitName |
||||
} |
||||
}) |
||||
}).catch(error => { |
||||
window.console.log(error) |
||||
}) |
||||
}, |
||||
onItemClick(item) { |
||||
if (item.enName != "BSV") { |
||||
Toast.fail("敬请期待") |
||||
return; |
||||
} |
||||
this.coinItem = item; |
||||
window.console.log(item) |
||||
this.active = item.id |
||||
}, |
||||
onSkuItemClick(item) { |
||||
this.skuItem = item; |
||||
window.console.log(item) |
||||
this.skuActive = item.id |
||||
this.minInterval = item.duration |
||||
|
||||
}, |
||||
onSelect() { |
||||
let userToken = localStorage.getItem('ACCESS_TOKEN') |
||||
if (isEmpty(userToken)) { |
||||
this.$router.push('/login'); |
||||
} else { |
||||
if (isEmpty(this.coinItem.id)) { |
||||
Toast.fail("请选择挖矿类型") |
||||
return; |
||||
} |
||||
this.$router.push({name: 'wallet/coin/address/select', query: {coinId: this.coinItem.id}}) |
||||
} |
||||
}, |
||||
// 选项格式化函数 |
||||
formatter(type, value) { |
||||
if (type === 'year') { |
||||
return `${value}年` |
||||
} else if (type === 'month') { |
||||
return `${value}月` |
||||
} else if (type === 'day') { |
||||
return `${value}日` |
||||
} else if (type === 'hour') { |
||||
return `${value}时` |
||||
} else if (type === 'minute') { |
||||
return `${value}分` |
||||
} else if (type === 'second') { |
||||
return `${value}秒` |
||||
} |
||||
return value |
||||
}, |
||||
minuteFilter(type, options) { |
||||
if (type === 'minute') { |
||||
return options.filter((option) => option % this.minInterval === 0); |
||||
} |
||||
return options; |
||||
}, |
||||
getOrderInfo() { |
||||
window.console.log("startTimeStamp:" + this.time.startTimeStamp); |
||||
window.console.log("endTimeStamp:" + this.time.endTimeStamp); |
||||
window.console.log("skuItem:" + this.skuItem == null); |
||||
if (isEmpty(this.skuItem.id) && this.time.startTimeStamp === 0 && this.time.endTimeStamp === 0) { |
||||
return; |
||||
} |
||||
if (!isEmpty(this.skuItem.id) && this.time.startTimeStamp === 0 || this.time.endTimeStamp === 0) { |
||||
return "¥" + (this.skuItem.price) + "/" + this.secondToDate(this.skuItem.duration * 60); |
||||
} |
||||
if (this.time.startTimeStamp === 0) { |
||||
return; |
||||
} |
||||
if (this.time.endTimeStamp === 0) { |
||||
return; |
||||
} |
||||
let s = this.time.startTime.replace(/-/g, '/'); //必须把日期'-'转为'/' |
||||
this.time.startTimeStamp = new Date(s).getTime() / 1000 |
||||
|
||||
let e = this.time.endTime.replace(/-/g, '/'); //必须把日期'-'转为'/' |
||||
this.time.endTimeStamp = new Date(e).getTime() / 1000 |
||||
|
||||
const seconds = (this.time.endTimeStamp - this.time.startTimeStamp); |
||||
window.console.log("startTimeStamp:" + this.time.startTimeStamp); |
||||
window.console.log("endTimeStamp:" + this.time.endTimeStamp); |
||||
window.console.log("skuItem:" + this.skuItem); |
||||
window.console.log("second:" + seconds); |
||||
if (seconds <= 0) { |
||||
return; |
||||
} |
||||
return "¥" + (this.skuItem.price * (seconds / 60)) + "/" + this.secondToDate(seconds); |
||||
}, |
||||
secondToDate(duration) { |
||||
window.console.log("result:" + duration) |
||||
let m = Math.floor((duration / 60 % 60)) < 10 ? Math.floor((duration / 60 % 60)) : Math.floor((duration / 60 % 60)); |
||||
return m + "min (分钟)"; |
||||
// // let h = Math.floor(result / 3600) < 10 ? Math.floor(result / 3600) : Math.floor(result / 3600); |
||||
// let m = Math.floor((result / 60 % 60)) < 10 ? Math.floor((result / 60 % 60)) : Math.floor((result / 60 % 60)); |
||||
// let s = Math.floor((result % 60)) < 10 ? Math.floor((result % 60)) : Math.floor((result % 60)); |
||||
// window.console.log("h:" + h + " m:" + m + " s:" + s); |
||||
// if (h > 0 && m > 0 && s > 0) { |
||||
// return h + "h" + m + "min " + (s > 0) ? s + "秒" : ""; |
||||
// } else if (h > 0 && m > 0) { |
||||
// return h + "h" + m + "min "; |
||||
// } else if (h > 0 && s > 0) { |
||||
// return h + "h" + (s > 0) ? s + "秒" : ""; |
||||
// } else if (h > 0) { |
||||
// return h + "h"; |
||||
// } else if (m > 0 && s > 0) { |
||||
// return m + "min " + (s > 0) ? s + "秒" : ""; |
||||
// } else if (m > 0) { |
||||
// return m + "min "; |
||||
// } else { |
||||
// return s + "秒"; |
||||
// } |
||||
} |
||||
}, |
||||
|
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
|
||||
body { |
||||
background-color: #ffffff; |
||||
} |
||||
|
||||
.order-create-content { |
||||
margin-right: 15px; |
||||
margin-left: 15px; |
||||
background: white; |
||||
} |
||||
|
||||
.order-create-top { |
||||
margin-top: 35px; |
||||
margin-bottom: 20px; |
||||
font-weight: bold; |
||||
font-size: 18px; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
} |
||||
|
||||
.order-create-divider { |
||||
background-color: #f2f2f2; |
||||
height: 1px; |
||||
margin: 0px; |
||||
clear: both; |
||||
|
||||
} |
||||
|
||||
.order-create-item-title { |
||||
margin-top: 8px; |
||||
height: 30px; |
||||
text-align: center; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
clear: both; |
||||
|
||||
} |
||||
|
||||
.order-create-item-title span { |
||||
margin-left: 5px; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.order-create-specs { |
||||
width: 25%; |
||||
height: 30px; |
||||
margin-left: 10px; |
||||
margin-top: 10px; |
||||
margin-bottom: 10px; |
||||
padding-left: 5px; |
||||
padding-right: 5px; |
||||
background: #1796e8; |
||||
margin-bottom: 10px; |
||||
border-radius: 6px; |
||||
font-size: 12px; |
||||
color: white; |
||||
text-align: center; |
||||
line-height: 30px; |
||||
} |
||||
|
||||
.order-create-time { |
||||
width: 100%; |
||||
height: 40px; |
||||
line-height: 40px; |
||||
display: flex; |
||||
display: -webkit-flex; /* Safari */ |
||||
} |
||||
|
||||
.order-create-time-time { |
||||
background-color: #ffffff; |
||||
margin: 0 auto; |
||||
flex: 1; |
||||
text-align: center; |
||||
font-size: 12px; |
||||
} |
||||
|
||||
.order-create-time-divider { |
||||
background-color: #ffffff; |
||||
height: 1px; |
||||
width: 60px; |
||||
text-align: center; |
||||
margin: 0 auto; |
||||
height: 40px; |
||||
line-height: 40px; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
} |
||||
|
||||
.order-create-time-divider span { |
||||
height: 1.5px; |
||||
width: 100%; |
||||
background-color: #f7f8fa; |
||||
} |
||||
|
||||
|
||||
.sinput { |
||||
margin: 0px; |
||||
padding: 0px; |
||||
background-color: white; |
||||
outline: none; |
||||
|
||||
} |
||||
|
||||
.sinput button { |
||||
margin-left: 5px; |
||||
margin-right: 5px; |
||||
} |
||||
|
||||
.order-create-footer { |
||||
height: 40px; |
||||
background: #1796e8; |
||||
text-align: center; |
||||
position: fixed; |
||||
font-size: 12px; |
||||
bottom: 0; |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
font-weight: bold; |
||||
color: white; |
||||
|
||||
} |
||||
|
||||
.coin-list { |
||||
margin-top: 10px; |
||||
} |
||||
|
||||
.active { |
||||
float: left; |
||||
width: 25%; |
||||
height: 30px; |
||||
padding-left: 5px; |
||||
padding-right: 5px; |
||||
line-height: 30px; |
||||
margin-left: 10px; |
||||
background: #1796e8; |
||||
margin-bottom: 10px; |
||||
border-radius: 6px; |
||||
font-size: 12px; |
||||
color: white; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
|
||||
} |
||||
|
||||
.active span { |
||||
margin-left: 5px |
||||
} |
||||
|
||||
.Classification { |
||||
width: 25%; |
||||
float: left; |
||||
height: 30px; |
||||
line-height: 30px; |
||||
margin-left: 10px; |
||||
background: #f4f4f4; |
||||
margin-bottom: 10px; |
||||
border-radius: 6px; |
||||
padding-left: 5px; |
||||
padding-right: 5px; |
||||
font-size: 12px; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
} |
||||
|
||||
.Classification span { |
||||
margin-left: 5px; |
||||
} |
||||
</style> |
@ -0,0 +1,283 @@ |
||||
<template> |
||||
<div class="content"> |
||||
<van-nav-bar |
||||
title="确认订单" |
||||
left-text="返回" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
@click-right="onClickRight"/> |
||||
<div class="order-confirm-title"> |
||||
<span>费用明细</span> |
||||
<div></div> |
||||
</div> |
||||
<div class="order-confirm-item"> |
||||
<span class="order-confirm-item-left">{{hash}}/S算力</span> |
||||
<span class="order-confirm-item-right">¥{{item.totalAmount}}</span> |
||||
</div> |
||||
<div class="order-confirm-item"> |
||||
<span class="order-confirm-item-left">租用时长(分钟)</span> |
||||
<span class="order-confirm-item-right">{{item.duration/60}}</span> |
||||
</div> |
||||
<div class="order-confirm-item-divider"></div> |
||||
<div class="order-confirm-item"> |
||||
<span class="order-confirm-item-left">实付</span> |
||||
<span class="order-confirm-item-right">¥{{item.payAmount}}</span> |
||||
</div> |
||||
|
||||
|
||||
<div class="order-confirm-pay-type"> |
||||
<div class="order-confirm-pay-ali" @click="onAliPay"> |
||||
<van-image |
||||
width="20" |
||||
height="20" |
||||
:src=ali_icon |
||||
/> |
||||
<span> |
||||
支付宝 |
||||
</span> |
||||
</div> |
||||
<div class="order-confirm-pay-wchat" @click="onWchatPay"> |
||||
<van-image |
||||
width="20" |
||||
height="20" |
||||
:src=wchat |
||||
/> |
||||
<span> |
||||
微信支付 |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
</template> |
||||
|
||||
<script> |
||||
import {pay_ali, pay_wchat} from '@/core/icons' |
||||
import {getOrderPayInfo, getOrderPayState} from '@/api/order' |
||||
import {Toast} from 'vant'; |
||||
import {Dialog} from 'vant' |
||||
|
||||
export default { |
||||
name: "OrderConfirm", |
||||
components: {}, |
||||
data() { |
||||
this.hash = this.$route.query.hash; |
||||
let params = JSON.parse(this.$route.query.item) |
||||
window.console.log('submit', params); |
||||
this.item = params; |
||||
return { |
||||
ali_icon: pay_ali, |
||||
wchat: pay_wchat, |
||||
hash: {}, |
||||
item: { |
||||
coin: "40 PH/s 算力", |
||||
price: "249", |
||||
duration: "10", |
||||
total: "249", |
||||
sum: "249", |
||||
paid: "249" |
||||
} |
||||
} |
||||
}, |
||||
created() { |
||||
window.addEventListener('pageshow', this.handleVisibility); |
||||
this.item = JSON.parse(this.$route.query.item); |
||||
window.console.log("params:" + JSON.stringify(this.item)) |
||||
window.console.log("params:" + JSON.stringify(this.hash)) |
||||
}, |
||||
method() { |
||||
this.onTips(); |
||||
}, |
||||
methods: { |
||||
onClickLeft() { |
||||
this.$router.go(-1) |
||||
}, |
||||
onClickRight() { |
||||
}, |
||||
onAliPay() { |
||||
const params = { |
||||
"orderSn": this.item.orderSn, |
||||
"payChannel": 1 |
||||
} |
||||
getOrderPayInfo(params).then(res => { |
||||
window.console.log("res:" + res) |
||||
window.location.href = res.data.h5_pay_url |
||||
// this.$router.link({name: res.h5_pay_url, params: {type: 'ali'}}) |
||||
}) |
||||
}, |
||||
onWchatPay() { |
||||
Toast.fail("敬请期待") |
||||
// this.$router.push({name: 'order/pay/success', params: {type: 'wchat'}}) |
||||
}, |
||||
onTips() { |
||||
window.console.log("onTips:" + window.performance.navigation.type) |
||||
Dialog.confirm({ |
||||
title: '支付确认', |
||||
message: '是否已经支付?', |
||||
confirmButtonText: "确认" |
||||
}) |
||||
.then(() => { |
||||
const params = { |
||||
"orderSn": this.item.orderSn, |
||||
} |
||||
window.console.log("params:" + params) |
||||
getOrderPayState(params).then(res => { |
||||
window.console.log("res:" + JSON.stringify(res)) |
||||
window.console.log("IntStatus:" + res.data.IntStatus) |
||||
const item = res.data; |
||||
if (item.IntStatus == "0" || item.IntStatus == 0) { |
||||
Toast.fail("订单还未支付") |
||||
} else { |
||||
this.$router.push({name: 'order/pay/success', query: {item: JSON.stringify(item)}}) |
||||
} |
||||
}) |
||||
}) |
||||
.catch(() => { |
||||
}) |
||||
}, |
||||
handleVisibility(event) { |
||||
window.console.log('window.performance.navigation.type: ' + window.performance.navigation.type) |
||||
if (event.persisted || window.performance && window.performance.navigation.type == 2) { |
||||
this.onTips(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
body { |
||||
height: 100%; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.content { |
||||
background: white; |
||||
height: 100%; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.order-confirm-title { |
||||
text-align: center; |
||||
margin-top: 80px; |
||||
margin-bottom: 30px; |
||||
font-size: 16px; |
||||
|
||||
} |
||||
|
||||
.order-confirm-title div { |
||||
background-color: #172941; |
||||
height: 1px; |
||||
width: 80px; |
||||
text-align: center; |
||||
margin: 0 auto; |
||||
} |
||||
|
||||
.order-confirm-item { |
||||
height: 30px; |
||||
font-size: 12px; |
||||
text-align: left; |
||||
margin: 0 20px 0 20px;; |
||||
|
||||
} |
||||
|
||||
.order-confirm-item-divider { |
||||
background-color: #172941; |
||||
color: #071724; |
||||
height: 0.5px; |
||||
margin: 0px; |
||||
margin: 5px 20px 5px 20px;; |
||||
} |
||||
|
||||
.order-confirm-item-left { |
||||
height: 25px; |
||||
font-size: 12px; |
||||
text-align: left; |
||||
} |
||||
|
||||
.order-confirm-item-right { |
||||
right: 0; |
||||
float: right; |
||||
text-align: right; |
||||
} |
||||
|
||||
.order-confirm-pay-type { |
||||
height: 30px; |
||||
font-size: 12px; |
||||
text-align: left; |
||||
margin: 80px 80px 0 80px; |
||||
line-height: 30px; |
||||
|
||||
} |
||||
|
||||
.order-confirm-pay-type { |
||||
height: 30px; |
||||
font-size: 12px; |
||||
text-align: left; |
||||
margin: 80px 80px 0 80px; |
||||
line-height: 30px; |
||||
|
||||
} |
||||
|
||||
.order-confirm-pay-ali { |
||||
width: 80px; |
||||
right: 0; |
||||
float: left; |
||||
height: 30px; |
||||
border-radius: 3px; |
||||
margin-left: 15px; |
||||
font-size: 8px; |
||||
border: 1px solid #1796e8; |
||||
color: #1796e8; |
||||
text-align: center; |
||||
line-height: 30px; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
} |
||||
|
||||
.order-confirm-pay-ali span { |
||||
margin-left: 5px; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
} |
||||
|
||||
.order-confirm-pay-wchat { |
||||
width: 80px; |
||||
right: 0; |
||||
float: right; |
||||
height: 30px; |
||||
border-radius: 3px; |
||||
margin-left: 15px; |
||||
font-size: 8px; |
||||
border: 1px solid #1796e8; |
||||
color: #1796e8; |
||||
text-align: center; |
||||
line-height: 30px; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
} |
||||
|
||||
.order-confirm-pay-wchat span { |
||||
margin-left: 5px; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
} |
||||
</style> |
@ -0,0 +1,303 @@ |
||||
<template> |
||||
<div class="content"> |
||||
<van-nav-bar |
||||
title="算力详情 " |
||||
left-text="返回" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
@click-right="onClickRight" |
||||
/> |
||||
<div class="order-detail-content"> |
||||
<div class="order-detail-top"> |
||||
<span>{{detail.totalProfit==0?"未挖到区块": '+'+ detail.totalProfit}} |
||||
</span> |
||||
</div> |
||||
<div> |
||||
<div class="order-detail-top-item"> |
||||
<span>算力:</span> {{detail.enName}} | {{detail.coinPackage.number}}{{detail.coinPackage.packageUnitName}}/S |
||||
</div> |
||||
<div class="order-detail-top-item"> |
||||
<span>租用状态:</span>{{getLeaseStatus(detail.leaseStatus)}} |
||||
</div> |
||||
<div class="order-detail-top-item"> |
||||
<span>租用时长:</span> {{detail.duration}} min(分钟) |
||||
</div> |
||||
<div class="order-detail-top-item"> |
||||
<span>剩余时长:</span> {{getLeaseTime(detail.leaseEndTime)}} min(分钟) |
||||
</div> |
||||
<div class="order-detail-divider"></div> |
||||
</div> |
||||
<!-- 算力监控 /--> |
||||
<div> |
||||
<div class="order-detail-title"> |
||||
<span>算力监控</span> |
||||
</div> |
||||
<ve-line :data-empty="dataEmpty" :settings="chartSettings" :data="chartData" :resize-delay="1000" |
||||
:extend="extend" width="100%" |
||||
height="280px"></ve-line> |
||||
</div> |
||||
<!-- 区块记录 /--> |
||||
<div> |
||||
<div class="order-detail-title"> |
||||
<span>区块记录</span> |
||||
</div> |
||||
<div class="order-detail-record"> |
||||
<div class="order-detail-record-left"> |
||||
<span>时间</span> |
||||
</div> |
||||
<div class="order-detail-record-right"> |
||||
<span>收益(单位)</span> |
||||
</div> |
||||
</div> |
||||
<div class="order-detail-divider" style="margin-top: 10px"></div> |
||||
<van-list |
||||
style="margin-top: 10px" |
||||
v-model="loading" |
||||
:finished="finished" |
||||
@load="onLoad" |
||||
> |
||||
<div class="order-detail-record-item" v-for="item in detail.blockList" :key="item.id"> |
||||
<span>{{timestampToTime(item.created_at)}}</span> |
||||
<span class="order-detail-record-item-right">+{{item.rewards}} {{detail.enName}}</span> |
||||
</div> |
||||
</van-list> |
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import {getOrderDetail} from '@/api/order' |
||||
import 'v-charts/lib/style.css' |
||||
|
||||
export default { |
||||
name: "OrderDetail", |
||||
data() { |
||||
this.extend = { |
||||
darkMode: "auto", |
||||
color: colorPalette, |
||||
title: { |
||||
show: false, |
||||
padding: 0, |
||||
height: 0, |
||||
}, |
||||
legend: { |
||||
show: false, |
||||
padding: 0, |
||||
height: 0, |
||||
}, |
||||
series: { |
||||
type: "line", |
||||
smooth: false, |
||||
}, |
||||
grid: { |
||||
top: 25, |
||||
bottom: 15, |
||||
show: false, |
||||
}, |
||||
xAxis: {}, |
||||
}; |
||||
let colorPalette = ['#4992ff', '#7cffb2', '#fddd60', '#ff6e76', '#58d9f9', '#05c091', '#ff8a45', '#8d48e3', '#dd79ff', '#91ca8c', '#f49f42']; |
||||
return { |
||||
profit: "+12.3482 BTC", |
||||
detail: { |
||||
coinPackage: {}, |
||||
profit: [], |
||||
}, |
||||
list: [], |
||||
loading: false, |
||||
finished: false, |
||||
dataEmpty: true, |
||||
chartSettings: { |
||||
area: true,//是否显示为面积图 |
||||
xAxisType: "category", |
||||
yAxisType: "value", |
||||
yAxisName: "", |
||||
boundaryGap: false, |
||||
lineStyle: {// 使用深浅的间隔色 |
||||
color: ['#B9B8CE'], |
||||
}, |
||||
itemStyle: { |
||||
normal: { |
||||
color: '#100C2A', |
||||
color0: '#0CF49B', |
||||
borderColor: '#100C2A', |
||||
borderColor0: '#0CF49B' |
||||
} |
||||
} |
||||
}, |
||||
chartData: { |
||||
columns: ["time", "hash"], |
||||
rows: [ |
||||
{time: "12:00", hash: 1393}, |
||||
{time: "12:30", hash: 3530}, |
||||
{time: "12:40", hash: 2923}, |
||||
{time: "12:50", hash: 3792}, |
||||
{time: "13:00", hash: 4593} |
||||
] |
||||
}, |
||||
} |
||||
}, |
||||
created() { |
||||
// let params = this.$route.query.item |
||||
// window.console.log('submit', params); |
||||
// this.item = JSON.parse(params); |
||||
}, |
||||
mounted() { |
||||
}, |
||||
methods: { |
||||
onClickLeft() { |
||||
this.$router.go(-1) |
||||
}, |
||||
onClickRight() { |
||||
}, |
||||
onLogin() { |
||||
this.$router.go(-1) |
||||
}, |
||||
getLeaseStatus(status) { |
||||
if (status == "0") { |
||||
return "待进行"; |
||||
} else if (status == "1") { |
||||
return "进行中"; |
||||
} else if (status == "2") { |
||||
return "已完成"; |
||||
} |
||||
return "暂无" |
||||
}, |
||||
onLoad() { |
||||
const params = { |
||||
"orderSn": this.$route.query.orderSn |
||||
} |
||||
getOrderDetail(params).then(res => { |
||||
this.detail = res.data; |
||||
this.chartData.rows = res.data.hash |
||||
if (this.detail.hash.length > 0) { |
||||
this.dataEmpty = false; |
||||
} |
||||
}) |
||||
this.loading = false; |
||||
this.finished = true; |
||||
}, |
||||
timestampToTime(timestamp) { |
||||
var date = new Date(timestamp * 1000);//时间戳为10位需*1000,时间戳为13位的话不需乘1000 |
||||
var Y = date.getFullYear() + '-'; |
||||
var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'; |
||||
var D = date.getDate() + ' '; |
||||
var h = date.getHours() + ':'; |
||||
var m = date.getMinutes() + ':'; |
||||
var s = date.getSeconds(); |
||||
return Y + M + D + h + m + s; |
||||
}, |
||||
getLeaseTime(time) { |
||||
let date = new Date(time);//时间戳为10位需*1000,时间戳为13位的话不需乘1000 |
||||
let timestamp = date.getTime(); |
||||
if (this.detail.leaseStatus == "0") { |
||||
return this.detail.duration; |
||||
} else if (this.detail.leaseStatus == "1") { |
||||
return timestamp - new Date().getTime()/1000; |
||||
} |
||||
return "0"; |
||||
} |
||||
} |
||||
, |
||||
setup() { |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.order-detail-content { |
||||
margin-right: 15px; |
||||
margin-left: 15px; |
||||
background: white; |
||||
} |
||||
|
||||
.order-detail-top { |
||||
margin-top: 35px; |
||||
margin-left: 20px; |
||||
margin-bottom: 20px; |
||||
font-weight: bold; |
||||
font-size: 16px; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
} |
||||
|
||||
.order-detail-top-item { |
||||
height: 30px; |
||||
margin-left: 20px; |
||||
font-weight: normal; |
||||
font-size: 14px; |
||||
} |
||||
|
||||
.order-detail-title { |
||||
height: 35px; |
||||
line-height: 35px; |
||||
margin-left: 20px; |
||||
font-weight: bold; |
||||
font-size: 18px; |
||||
|
||||
} |
||||
|
||||
.order-detail-divider { |
||||
margin: 10px 20px; |
||||
background-color: #f2f2f2; |
||||
height: 1px; |
||||
clear: both; |
||||
|
||||
} |
||||
|
||||
|
||||
.order-detail-record { |
||||
margin-left: 20px; |
||||
margin-right: 20px; |
||||
} |
||||
|
||||
.order-detail-record-left { |
||||
float: left; |
||||
} |
||||
|
||||
.order-detail-record-right { |
||||
float: right; |
||||
|
||||
} |
||||
|
||||
.order-detail-record-item { |
||||
margin-left: 20px; |
||||
margin-right: 20px; |
||||
min-height: 30px; |
||||
line-height: 30px; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
} |
||||
|
||||
.order-detail-record-item-right { |
||||
right: 0; |
||||
float: right; |
||||
} |
||||
|
||||
.order-detail-item-title { |
||||
margin-top: 8px; |
||||
height: 30px; |
||||
text-align: center; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
clear: both; |
||||
|
||||
} |
||||
|
||||
|
||||
.order-detail-item-title span { |
||||
margin-left: 5px; |
||||
margin-left: 20px; |
||||
|
||||
font-weight: bold; |
||||
} |
||||
|
||||
</style> |
@ -0,0 +1,74 @@ |
||||
<template> |
||||
<div class="content"> |
||||
<van-nav-bar |
||||
title="支付成功" |
||||
left-text="返回首页" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
@click-right="onClickRight"/> |
||||
|
||||
<div class="order-pay-success"> |
||||
<van-icon name="passed" color="#1989fa" size="40"/> |
||||
<div>支付成功</div> |
||||
</div> |
||||
<div class="order-pay-success"> |
||||
<van-button class="order-pay-success-btn" type="info" size="small" @click="onOrderDetail">查看详情</van-button> |
||||
</div> |
||||
</div> |
||||
|
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: "OrderPaySuccess", |
||||
components: {}, |
||||
data() { |
||||
return { |
||||
} |
||||
}, |
||||
methods: { |
||||
onClickLeft() { |
||||
this.$router.push("home") |
||||
}, |
||||
onClickRight() { |
||||
}, |
||||
onOrderDetail() { |
||||
this.$router.push({name: 'order/detail', query: {orderSn: this.$route.query.orderSn}}) |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
body { |
||||
height: 100%; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.content { |
||||
background: white; |
||||
height: 100%; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.order-pay-success { |
||||
text-align: center; |
||||
margin-top: 80px; |
||||
margin-bottom: 30px; |
||||
font-size: 16px; |
||||
|
||||
} |
||||
|
||||
.order-pay-success-btn { |
||||
width: 100px; |
||||
text-align: center; |
||||
margin-top: 1px; |
||||
margin-bottom: 30px; |
||||
font-size: 16px; |
||||
|
||||
} |
||||
|
||||
|
||||
</style> |
@ -0,0 +1,251 @@ |
||||
<template> |
||||
<div class="order"> |
||||
<van-nav-bar |
||||
title="订单记录" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
@click-right="onClickRight" |
||||
/> |
||||
<van-tabs @click="onClick"> |
||||
<van-tab title="进行中"> |
||||
<!-- <van-pull-refresh v-model="refreshing" @refresh="onRefresh">--> |
||||
<!-- <van-list--> |
||||
<!-- v-model="loading"--> |
||||
<!-- :finished="finished"--> |
||||
<!-- finished-text="没有更多了"--> |
||||
<!-- @load="onLoad"--> |
||||
<!-- >--> |
||||
<!-- <div v-for="item in list"--> |
||||
<!-- :key="item.id"--> |
||||
<!-- :name="item.id"--> |
||||
<!-- >--> |
||||
<!-- <div class="order-card">--> |
||||
<!-- <div class="order-card-top">--> |
||||
<!-- <span class="order-card-top-left">订单号:{{item.orderNo}}</span>--> |
||||
<!-- <span class="order-card-top-right">{{item.createTime}}</span>--> |
||||
<!-- </div>--> |
||||
<!-- <div class="order-card-item-divider"></div>--> |
||||
|
||||
<!-- <div class="order-card-bottom">--> |
||||
<!-- <div>40P/S</div>--> |
||||
<!-- <div>1 份/10min(分钟)</div>--> |
||||
<!-- <div>¥250</div>--> |
||||
<!-- <div class="order-card-dot">--> |
||||
<!-- <i class="circle"></i><span>进行中</span>--> |
||||
<!-- </div>--> |
||||
<!-- <div class="order-card-bottom-r">--> |
||||
<!-- <van-button size="mini" type="info" class="order-card-bottom-btn"--> |
||||
<!-- @click="onItemClick(item)">详 情--> |
||||
<!-- </van-button>--> |
||||
<!-- <van-button size="mini" type="info" class="order-card-bottom-btn"--> |
||||
<!-- @click="onAgainBuy(item)">再次租用--> |
||||
<!-- </van-button>--> |
||||
<!-- </div>--> |
||||
<!-- </div>--> |
||||
<!-- </div>--> |
||||
<!-- </div>--> |
||||
<!-- </van-list>--> |
||||
<!-- </van-pull-refresh>--> |
||||
|
||||
<order-list :orderStatus="0" :on-item-click="onItemClick" :on-again-buy="onAgainBuy"/> |
||||
</van-tab> |
||||
<van-tab title="已完成"> |
||||
<order-list :orderStatus="1" :on-item-click="onItemClick" :on-again-buy="onAgainBuy"/> |
||||
|
||||
</van-tab> |
||||
</van-tabs> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import Vue from 'vue'; |
||||
import {Tab, Tabs} from 'vant'; |
||||
import {getOrderList} from '@/api/order' |
||||
import OrderList from "./modules/OrderList"; |
||||
|
||||
Vue.use(Tab); |
||||
Vue.use(Tabs); |
||||
|
||||
export default { |
||||
name: 'orderIndex', |
||||
components: {OrderList}, |
||||
data() { |
||||
const images = [ |
||||
'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3159572006,3515833347&fm=26&gp=0.jpg', |
||||
'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1120727829,3224049468&fm=26&gp=0.jpg', |
||||
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1810305784,348181924&fm=26&gp=0.jpg', |
||||
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3791732603,832613035&fm=26&gp=0.jpg' |
||||
]; |
||||
return { |
||||
logo: "https://d1icd6shlvmxi6.cloudfront.net/gsc/LUPI5Z/ae/58/5d/ae585de70e1b4582a578e9432d61f8c1/images/%E9%A6%96%E9%A1%B5/logo_u60.png?token=6b278b3ce4b902555191bd387d810fa9f2937870205b457374117ee3e3bc7139", |
||||
images, |
||||
list: [], |
||||
loading: false, |
||||
finished: false, |
||||
refreshing: false, |
||||
} |
||||
}, method() { |
||||
}, |
||||
methods: { |
||||
onClickLeft() { |
||||
this.$router.go(-1) |
||||
}, |
||||
onClickRight() { |
||||
}, |
||||
onClick(name, title) { |
||||
window.console.log(title) |
||||
// Toast(title); |
||||
}, |
||||
onItemClick(item) { |
||||
window.console.log(item) |
||||
this.$router.push({name: 'order/detail', query: {orderSn: item.orderSn}}) |
||||
}, |
||||
onAgainBuy(item) { |
||||
window.console.log(item) |
||||
this.$router.push({name: 'order/create', query: {item: item}}) |
||||
}, |
||||
onLoad() { |
||||
if (this.refreshing) { |
||||
this.list = []; |
||||
this.refreshing = false; |
||||
} |
||||
// 异步更新数据 |
||||
getOrderList().then(res => { |
||||
window.console.log("history:" + res.data.length) |
||||
this.list.push.apply(this.list, res.data); |
||||
// 加载状态结束 |
||||
this.loading = true; |
||||
// 数据全部加载完成 |
||||
this.finished = true; |
||||
} |
||||
) |
||||
}, |
||||
onRefresh() { |
||||
// 清空列表数据 |
||||
this.finished = false; |
||||
// 重新加载数据 |
||||
// 将 loading 设置为 true,表示处于加载状态 |
||||
this.loading = true; |
||||
this.onLoad(); |
||||
} |
||||
}, |
||||
created() { |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style> |
||||
.order { |
||||
height: calc(100vh); |
||||
font-size: 16px; |
||||
background-color: #f7f8fa; |
||||
} |
||||
|
||||
.order-card { |
||||
background-color: #ffffff; |
||||
margin: 10px; |
||||
border: 1px solid #f7f8fa; |
||||
border-radius: 5px; |
||||
font-size: 12px; |
||||
color: black; |
||||
|
||||
} |
||||
|
||||
.order-card-top { |
||||
height: 40px; |
||||
font-size: 12px; |
||||
text-align: left; |
||||
line-height: 40px; |
||||
margin: 0 10px 0 10px;; |
||||
} |
||||
|
||||
.order-card-top-left { |
||||
height: 40px; |
||||
font-size: 12px; |
||||
text-align: left; |
||||
line-height: 40px; |
||||
} |
||||
|
||||
.order-card-top-right { |
||||
right: 0; |
||||
float: right; |
||||
text-align: right; |
||||
line-height: 40px; |
||||
} |
||||
|
||||
|
||||
.order-card-item-divider { |
||||
background-color: #f2f2f2; |
||||
height: 1px; |
||||
padding: 0px; |
||||
margin: 0px; |
||||
width: 100%; |
||||
} |
||||
|
||||
.order-card-bottom { |
||||
margin: 10px; |
||||
position: relative |
||||
} |
||||
|
||||
.order-card-bottom-r { |
||||
float: right; |
||||
margin-left: 10px; |
||||
font-size: 6px; |
||||
color: #1796e8; |
||||
right: 0px; |
||||
bottom: 0px; |
||||
position: absolute; |
||||
} |
||||
|
||||
.order-card-bottom-btn { |
||||
min-width: 60px; |
||||
border-radius: 3px; |
||||
margin-left: 15px; |
||||
font-size: 8px; |
||||
} |
||||
|
||||
|
||||
.order-card-bottom div { |
||||
min-height: 20px; |
||||
} |
||||
|
||||
.order-card-dot { |
||||
color: #00FF7F; |
||||
float: right; |
||||
margin-left: 10px; |
||||
font-size: 6px; |
||||
right: 0px; |
||||
top: 0px; |
||||
position: absolute; |
||||
} |
||||
|
||||
.circle { |
||||
height: 8px; |
||||
width: 8px; |
||||
background-color: #00FF7F; |
||||
border-radius: 50%; |
||||
margin-right: 5px; |
||||
display: inline-block; |
||||
|
||||
} |
||||
|
||||
.order-card-dot-n { |
||||
color: #778899; |
||||
float: right; |
||||
margin-left: 10px; |
||||
font-size: 6px; |
||||
right: 0px; |
||||
top: 0px; |
||||
position: absolute; |
||||
} |
||||
|
||||
.circle-n { |
||||
height: 8px; |
||||
width: 8px; |
||||
background-color: #778899; |
||||
border-radius: 50%; |
||||
margin-right: 5px; |
||||
display: inline-block; |
||||
|
||||
} |
||||
</style> |
@ -0,0 +1,102 @@ |
||||
<template> |
||||
<div> |
||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh"> |
||||
<van-list |
||||
v-model="loading" |
||||
:finished="finished" |
||||
finished-text="没有更多了" |
||||
@load="onLoad" |
||||
> |
||||
<div v-for="item in list" |
||||
:key="item.id" |
||||
:name="item.id" |
||||
> |
||||
<div class="order-card"> |
||||
<div class="order-card-top"> |
||||
<span class="order-card-top-left">订单号:{{item.orderSn}}</span> |
||||
<span class="order-card-top-right">{{item.createTime}}</span> |
||||
</div> |
||||
<div class="order-card-item-divider"></div> |
||||
|
||||
<div class="order-card-bottom"> |
||||
<div>40P/S</div> |
||||
<div>1 份/{{item.duration/60}}min(分钟)</div> |
||||
<div>¥{{item.totalAmount}}</div> |
||||
<div :class="item.leaseStatus=='1'?'order-card-dot':'order-card-dot-n'"> |
||||
<div v-bind:orderStatus="0" :style="item.leaseStatus!='2'?'visibility: visible':'visibility: hidden'"> |
||||
<i :class="item.leaseStatus=='1'?'circle':'circle-n'" ></i><span>{{item.leaseStatus=='1'?"进行中":"待进行"}}</span> |
||||
</div> |
||||
</div> |
||||
<div class="order-card-bottom-r"> |
||||
<van-button size="mini" type="info" class="order-card-bottom-btn" |
||||
@click="onItemClick(item)">详 情 |
||||
</van-button> |
||||
<van-button size="mini" type="info" class="order-card-bottom-btn" |
||||
@click="onAgainBuy(item)">再次租用 |
||||
</van-button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</van-list> |
||||
</van-pull-refresh> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import {getOrderList} from '@/api/order' |
||||
|
||||
export default { |
||||
name: "OrderList", |
||||
props: { |
||||
orderStatus: Number, |
||||
onItemClick: Function, |
||||
onAgainBuy: Function, |
||||
}, |
||||
data() { |
||||
const images = [ |
||||
'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3159572006,3515833347&fm=26&gp=0.jpg', |
||||
'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1120727829,3224049468&fm=26&gp=0.jpg', |
||||
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1810305784,348181924&fm=26&gp=0.jpg', |
||||
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3791732603,832613035&fm=26&gp=0.jpg' |
||||
]; |
||||
return { |
||||
logo: "https://d1icd6shlvmxi6.cloudfront.net/gsc/LUPI5Z/ae/58/5d/ae585de70e1b4582a578e9432d61f8c1/images/%E9%A6%96%E9%A1%B5/logo_u60.png?token=6b278b3ce4b902555191bd387d810fa9f2937870205b457374117ee3e3bc7139", |
||||
images, |
||||
list: [], |
||||
loading: false, |
||||
finished: false, |
||||
refreshing: false, |
||||
} |
||||
}, |
||||
methods: { |
||||
onLoad() { |
||||
if (this.refreshing) { |
||||
this.list = []; |
||||
this.refreshing = false; |
||||
} |
||||
getOrderList().then(res => { |
||||
window.console.log("history:" + res.data.length) |
||||
this.list.push.apply(this.list, res.data); |
||||
// 加载状态结束 |
||||
this.loading = true; |
||||
// 数据全部加载完成 |
||||
this.finished = true; |
||||
} |
||||
) |
||||
}, |
||||
onRefresh() { |
||||
// 清空列表数据 |
||||
this.finished = false; |
||||
// 重新加载数据 |
||||
// 将 loading 设置为 true,表示处于加载状态 |
||||
this.loading = true; |
||||
this.onLoad(); |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
|
||||
</style> |
@ -0,0 +1,157 @@ |
||||
<template> |
||||
<div class="content"> |
||||
<van-nav-bar |
||||
title="登录" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
@click-right="onClickRight" |
||||
/> |
||||
<div class="login_top"> |
||||
<van-image class="user_av" |
||||
width="60px" |
||||
height="60px" |
||||
:src=app.logo> |
||||
<template v-slot:loading> |
||||
<van-loading type="spinner" size="20"/> |
||||
</template> |
||||
</van-image> |
||||
<div class="van-ellipsis">{{app.name}}</div> |
||||
</div> |
||||
|
||||
<div class="login_form"> |
||||
<van-field |
||||
ref="username" |
||||
v-model="login.phone" |
||||
placeholder="请填写手机号" |
||||
:left-icon="icon_user" |
||||
@input="onInput" |
||||
:rules="[{ required: true, message: '请填写手机号' }]" |
||||
/> |
||||
<van-field |
||||
ref="password" |
||||
v-model="login.password" |
||||
type="password" |
||||
:left-icon="icon_password" |
||||
placeholder="请填写密码" |
||||
@input="onInput" |
||||
:rules="[{ required: true, message: '请填写密码' }]" |
||||
/> |
||||
<div style="margin: 16px;"> |
||||
<van-button :disabled="disabled" redround block type="info" @click="onLogin">登录 |
||||
</van-button> |
||||
</div> |
||||
</div> |
||||
<!-- 右对齐 --> |
||||
<van-row class="login_register" type="flex"> |
||||
<van-col @click="goRegister">无登录账号?快速注册</van-col> |
||||
</van-row> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import {Login} from '@/api/user' |
||||
import {Toast} from 'vant'; |
||||
import core from '@/core' |
||||
import {isEmpty} from '@/utils/common' |
||||
import md5 from 'js-md5'; |
||||
import {icon_password, icon_user} from '@/core/icons' |
||||
|
||||
|
||||
export default { |
||||
name: "Login", |
||||
data() { |
||||
return { |
||||
icon_password: icon_password, |
||||
icon_user: icon_user, |
||||
disabled: true, |
||||
app: { |
||||
logo: core.info.logo, |
||||
name: core.info.name, |
||||
}, |
||||
login: { |
||||
phone: "", |
||||
password: "", |
||||
password1: "", |
||||
} |
||||
} |
||||
}, |
||||
mounted() { |
||||
}, |
||||
methods: { |
||||
onClickLeft() { |
||||
this.$router.go(-1) |
||||
}, |
||||
onClickRight() { |
||||
}, |
||||
onInput() { |
||||
if (isEmpty(this.login.phone) || isEmpty(this.login.password)) { |
||||
this.disabled = true; |
||||
} else { |
||||
this.disabled = false; |
||||
} |
||||
}, |
||||
onLogin() { |
||||
window.console.log(JSON.stringify(this.login)); |
||||
const params = { |
||||
'phone': this.login.phone, |
||||
'password': md5('sunaliyun_'+this.login.password), |
||||
} |
||||
window.console.log(JSON.stringify(params)); |
||||
|
||||
Login(params).then(response => { |
||||
window.console.log(response) |
||||
window.console.log(response.data) |
||||
window.console.log(response.data.token) |
||||
|
||||
Toast.fail("登录成功") |
||||
window.console.log(response) |
||||
localStorage.setItem('UserInfo', JSON.stringify(response.data)) |
||||
localStorage.setItem('ACCESS_TOKEN', response.data.token) |
||||
this.$router.back(); |
||||
} |
||||
) |
||||
}, |
||||
goRegister() { |
||||
this.$router.push('register'); |
||||
} |
||||
}, setup() { |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
body { |
||||
height: 100%; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.content { |
||||
background: white; |
||||
height: 100%; |
||||
} |
||||
|
||||
.login_top { |
||||
height: 140px; |
||||
padding: 10px; |
||||
background: white; |
||||
text-align: center; |
||||
} |
||||
|
||||
.user_av { |
||||
display: inline-block; |
||||
margin-top: 30px; |
||||
} |
||||
|
||||
.login_form { |
||||
margin-left: 20px; |
||||
margin-right: 20px; |
||||
} |
||||
|
||||
.login_register { |
||||
margin-right: 40px; |
||||
float: right; |
||||
} |
||||
|
||||
|
||||
</style> |
@ -0,0 +1,185 @@ |
||||
<template> |
||||
<div class="content"> |
||||
<van-nav-bar |
||||
title="注册" |
||||
left-text="返回" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
@click-right="onClickRight" |
||||
/> |
||||
<div class="login_top"> |
||||
<van-image class="user_av" |
||||
width="60px" |
||||
height="60px" |
||||
:src=app.logo> |
||||
<template v-slot:loading> |
||||
<van-loading type="spinner" size="20"/> |
||||
</template> |
||||
</van-image> |
||||
<div class="van-ellipsis">{{app.name}}</div> |
||||
</div> |
||||
|
||||
<div class="login_form"> |
||||
<van-field |
||||
ref="username" |
||||
v-model="register.phone" |
||||
placeholder="请填写手机号" |
||||
:left-icon="icon_user" |
||||
@input="onInput" |
||||
:rules="[{ required: true, message: '请填写手机号' }]" |
||||
/> |
||||
<van-field |
||||
ref="password" |
||||
v-model="register.password" |
||||
type="password" |
||||
:left-icon="icon_password" |
||||
placeholder="请填写密码" |
||||
@input="onInput" |
||||
:rules="[{ required: true, message: '请填写密码' }]" |
||||
/> |
||||
<van-field |
||||
ref="password" |
||||
v-model="register.password2" |
||||
type="password" |
||||
:left-icon="icon_password" |
||||
placeholder="请再次输入密码" |
||||
@input="onInput" |
||||
:rules="[{ required: true, message: '请填写密码' }]" |
||||
/> |
||||
<div style="margin: 16px;"> |
||||
<van-button :disabled="disabled" redround block type="info" @click="onRegister">注册 |
||||
</van-button> |
||||
</div> |
||||
</div> |
||||
<!-- 右对齐 --> |
||||
<van-row type="flex" justify="center"> |
||||
<van-col @click="onLogin">我有账户,直接登录</van-col> |
||||
</van-row> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import {Register} from '@/api/user' |
||||
import {Toast} from 'vant'; |
||||
import {Dialog} from 'vant'; |
||||
import core from '@/core' |
||||
import md5 from 'js-md5'; |
||||
import {icon_password, icon_user} from '@/core/icons' |
||||
|
||||
function isEmpty(obj) { |
||||
if (typeof obj == "undefined" || obj == null || obj == "") { |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
export default { |
||||
name: "register", |
||||
data() { |
||||
return { |
||||
icon_password: icon_password, |
||||
icon_user: icon_user, |
||||
disabled: true, |
||||
app: { |
||||
logo: core.info.logo, |
||||
name: core.info.name, |
||||
}, |
||||
register: { |
||||
phone: "", |
||||
password: "", |
||||
password2: "" |
||||
} |
||||
} |
||||
}, methods: { |
||||
onClickLeft() { |
||||
this.$router.go(-1) |
||||
}, |
||||
onClickRight() { |
||||
}, |
||||
onInput() { |
||||
window.console.log(JSON.stringify(this.login)); |
||||
window.console.log(isEmpty(this.register.phone) + "/" + isEmpty(this.register.password) + "/" + this.disabled); |
||||
if (isEmpty(this.register.phone) || isEmpty(this.register.password) || isEmpty(this.register.password2)) { |
||||
this.disabled = true; |
||||
} else { |
||||
this.disabled = false; |
||||
} |
||||
}, |
||||
onRegister() { |
||||
window.console.log('submit', JSON.stringify(this.register)); |
||||
if (this.register.password != this.register.password2) { |
||||
Toast.fail("两次密码不一致") |
||||
return |
||||
} |
||||
const params = { |
||||
'phone': this.register.phone, |
||||
'password': md5('sunaliyun_'+this.register.password), |
||||
'code': '' |
||||
} |
||||
window.console.log('submit', params); |
||||
let _this = this; |
||||
Register(params).then(response => { |
||||
Toast.fail("注册成功") |
||||
window.console.log(response) |
||||
this.$router.go(-1) |
||||
} |
||||
).catch(error => { |
||||
window.console.log(error.response.data) |
||||
const data = error.response.data |
||||
window.console.log(data.code) |
||||
if (data.code === 1001) { |
||||
Dialog.confirm({ |
||||
message: '账户已注册,是否直接登录', |
||||
}).then(function () { |
||||
_this.$router.go(-1) |
||||
}) |
||||
} else { |
||||
Toast.fail(data.message) |
||||
} |
||||
}); |
||||
}, |
||||
onLogin() { |
||||
this.$router.go(-1) |
||||
} |
||||
}, setup() { |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
body { |
||||
height: 100%; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.content { |
||||
background: white; |
||||
height: 100%; |
||||
} |
||||
|
||||
.login_top { |
||||
height: 140px; |
||||
padding: 10px; |
||||
background: white; |
||||
text-align: center; |
||||
} |
||||
|
||||
.user_av { |
||||
display: inline-block; |
||||
margin-top: 30px; |
||||
} |
||||
|
||||
.login_form { |
||||
margin-left: 20px; |
||||
margin-right: 20px; |
||||
} |
||||
|
||||
.login_register { |
||||
margin-right: 40px; |
||||
float: right; |
||||
} |
||||
|
||||
|
||||
</style> |
@ -0,0 +1,154 @@ |
||||
<template> |
||||
<div class="content"> |
||||
<van-nav-bar |
||||
title="修改密码" |
||||
left-text="返回" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
@click-right="onClickRight" |
||||
/> |
||||
<div class="login_top"> |
||||
<van-image class="user_av" |
||||
width="60px" |
||||
height="60px" |
||||
:src=app.logo> |
||||
<template v-slot:loading> |
||||
<van-loading type="spinner" size="20"/> |
||||
</template> |
||||
</van-image> |
||||
<div class="van-ellipsis">{{app.name}}</div> |
||||
</div> |
||||
|
||||
<div class="login_form"> |
||||
<van-field |
||||
v-model="updatePwd.oldPassword" |
||||
placeholder="请输入旧密码" |
||||
type="password" |
||||
:left-icon="icon_password" |
||||
@input="onInput" |
||||
:rules="[{ required: true, message: '请输入旧密码' }]" |
||||
/> |
||||
<van-field |
||||
v-model="updatePwd.password" |
||||
type="password" |
||||
:left-icon="icon_password" |
||||
placeholder="请输入新密码" |
||||
@input="onInput" |
||||
:rules="[{ required: true, message: '请填写密码' }]" |
||||
/> |
||||
<van-field |
||||
v-model="updatePwd.password2" |
||||
type="password" |
||||
:left-icon="icon_password" |
||||
placeholder="请再次输入密码" |
||||
@input="onInput" |
||||
:rules="[{ required: true, message: '请填写密码' }]" |
||||
/> |
||||
<div style="margin: 16px;"> |
||||
<van-button :disabled="disabled" ref="updatePassword" redround block type="info" @click="updatePassword">修改</van-button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import {UpdatePassword} from '@/api/user' |
||||
import {Toast} from 'vant'; |
||||
import core from '@/core' |
||||
import md5 from 'js-md5'; |
||||
import {isEmpty} from '@/utils/common' |
||||
import {icon_password, icon_user} from '@/core/icons' |
||||
|
||||
export default { |
||||
name: "update_password", |
||||
data() { |
||||
return { |
||||
icon_password: icon_password, |
||||
icon_user: icon_user, |
||||
app: { |
||||
logo: core.info.logo, |
||||
name: core.info.name, |
||||
}, |
||||
disabled: true, |
||||
updatePwd: { |
||||
oldPassword: "", |
||||
password: "", |
||||
password2: "" |
||||
} |
||||
} |
||||
}, methods: { |
||||
onClickLeft() { |
||||
|
||||
this.$router.go(-1) |
||||
}, |
||||
onClickRight() { |
||||
}, |
||||
onInput() { |
||||
if (isEmpty(this.updatePwd.oldPassword) || isEmpty(this.updatePwd.password)||isEmpty(this.updatePwd.password2)) { |
||||
this.disabled = true; |
||||
} else { |
||||
this.disabled = false; |
||||
} |
||||
}, |
||||
updatePassword() { |
||||
if (this.updatePwd.password != this.updatePwd.password2) { |
||||
Toast.fail("两次密码不一致") |
||||
return |
||||
} |
||||
const params = { |
||||
'oldPassword': md5('sunaliyun_' + this.updatePwd.oldPassword), |
||||
'password': md5('sunaliyun_' + this.updatePwd.password), |
||||
'code': '' |
||||
} |
||||
window.console.log(params); |
||||
UpdatePassword(params).then(response => { |
||||
window.console.log('submit' + response); |
||||
Toast('密码修改成功') |
||||
this.$router.go(-1); |
||||
} |
||||
) |
||||
}, |
||||
onLogin() { |
||||
this.$router.go(-1) |
||||
} |
||||
}, setup() { |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
body { |
||||
height: 100%; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.content { |
||||
background: white; |
||||
height: 100%; |
||||
} |
||||
|
||||
.login_top { |
||||
height: 140px; |
||||
padding: 10px; |
||||
background: white; |
||||
text-align: center; |
||||
} |
||||
|
||||
.user_av { |
||||
display: inline-block; |
||||
margin-top: 30px; |
||||
} |
||||
|
||||
.login_form { |
||||
margin-left: 20px; |
||||
margin-right: 20px; |
||||
} |
||||
|
||||
.login_register { |
||||
margin-right: 40px; |
||||
float: right; |
||||
} |
||||
|
||||
|
||||
</style> |
@ -0,0 +1,62 @@ |
||||
<template> |
||||
<div id="user-info"> |
||||
<van-nav-bar |
||||
title="个人信息" |
||||
left-text="返回" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
/> |
||||
<van-cell-group> |
||||
<van-cell icon="contact" title="修改密码" is-link @click="onUpdatePassword"/> |
||||
</van-cell-group> |
||||
|
||||
<div class="logout" > |
||||
<van-button ref="onLogin" redround block type="info" @click="onLogout">注销</van-button> |
||||
</div> |
||||
|
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import {Logout} from '@/api/user' |
||||
import {Toast} from 'vant'; |
||||
export default { |
||||
name: "UserInfo" |
||||
, |
||||
components: {}, |
||||
created(){ |
||||
}, |
||||
methods: { |
||||
onClickLeft() { |
||||
this.$router.go(-1); |
||||
}, |
||||
onUpdatePassword() { |
||||
this.$router.push("update/password"); |
||||
}, |
||||
onLogout() { |
||||
Logout().then(res=>{ |
||||
window.console.log(res) |
||||
Toast("退出成功") |
||||
localStorage.removeItem('ACCESS_TOKEN') |
||||
localStorage.removeItem('UserInfo') |
||||
this.$router.push("home"); |
||||
}) |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
body { |
||||
height: 100%; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.logout { |
||||
position: absolute; |
||||
bottom: 0; |
||||
width: 90%; |
||||
margin: 16px; |
||||
} |
||||
</style> |
@ -0,0 +1,145 @@ |
||||
<template> |
||||
<div> |
||||
<div class="user-top"> |
||||
<van-image class="user_av" |
||||
round |
||||
fit="fill" |
||||
width="60px" |
||||
height="60px" |
||||
:error-icon=default_user |
||||
v-bind:src=user.avatar> |
||||
<template v-slot:loading> |
||||
<van-loading type="spinner" size="20"/> |
||||
</template> |
||||
</van-image> |
||||
<div class="van-ellipsis">{{user.name}}</div> |
||||
</div> |
||||
|
||||
|
||||
<van-cell-group> |
||||
<van-cell icon="contact" title="个人信息" is-link @click="onUserInfo"/> |
||||
<van-cell icon="pending-payment" title="钱包地址" is-link @click="onWalletAddress"/> |
||||
<van-cell icon="orders-o" title="订单信息" is-link @click="onOrder"/> |
||||
<van-cell icon="records" title="历史记录" is-link @click="onHistory"/> |
||||
</van-cell-group> |
||||
<router-view/> |
||||
<van-tabbar route> |
||||
<van-tabbar-item replace to="/home" icon="wap-home-o">首页</van-tabbar-item> |
||||
<van-tabbar-item replace to="/user" icon="user-o">{{tabName}}</van-tabbar-item> |
||||
</van-tabbar> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import {ref} from 'vue'; |
||||
import {default_user} from '@/core/icons' |
||||
import {isEmpty} from '@/utils/common' |
||||
|
||||
let userToken |
||||
|
||||
export default { |
||||
data() { |
||||
userToken = localStorage.getItem('ACCESS_TOKEN') |
||||
return { |
||||
default_user: default_user, |
||||
tabName: userToken === null ? "注册/登录" : "个人中心", |
||||
user: { |
||||
name: "未登录", |
||||
avatar: default_user |
||||
} |
||||
} |
||||
}, |
||||
components: {}, |
||||
created() { |
||||
}, |
||||
setup() { |
||||
const active = ref(0); |
||||
return {active}; |
||||
}, |
||||
mounted() { |
||||
userToken = localStorage.getItem('ACCESS_TOKEN') |
||||
const userInfo = JSON.parse(localStorage.getItem('UserInfo')) |
||||
if (userInfo != null) { |
||||
this.user.name = userInfo.nickname; |
||||
this.user.avatar = userInfo.avatar; |
||||
window.console.log('userInfo', userInfo); |
||||
window.console.log('userInfoname', this.user.name); |
||||
window.console.log('ACCESS_TOKEN', userToken); |
||||
} |
||||
}, |
||||
methods: { |
||||
|
||||
onUserInfo() { |
||||
userToken = localStorage.getItem('ACCESS_TOKEN') |
||||
window.console.log('token', userToken); |
||||
if (isEmpty(userToken)) { |
||||
this.$router.push('login'); |
||||
} else { |
||||
this.$router.push('userInfo'); |
||||
} |
||||
}, |
||||
onWalletAddress() { |
||||
userToken = localStorage.getItem('ACCESS_TOKEN') |
||||
if (isEmpty(userToken)) { |
||||
this.$router.push('login'); |
||||
} else { |
||||
this.$router.push('wallet/coin/address/list'); |
||||
} |
||||
}, |
||||
onOrder() { |
||||
userToken = localStorage.getItem('ACCESS_TOKEN') |
||||
if (isEmpty(userToken)) { |
||||
this.$router.push('login'); |
||||
} else { |
||||
this.$router.push('order/list'); |
||||
} |
||||
}, |
||||
onHistory() { |
||||
userToken = localStorage.getItem('ACCESS_TOKEN') |
||||
if (isEmpty(userToken)) { |
||||
this.$router.push('login'); |
||||
} else { |
||||
this.$router.push('profit/list'); |
||||
} |
||||
}, |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="less"> |
||||
.user { |
||||
&-poster { |
||||
width: 100%; |
||||
height: 53vw; |
||||
display: block; |
||||
} |
||||
|
||||
&-group { |
||||
margin-bottom: 15px; |
||||
} |
||||
|
||||
&-links { |
||||
padding: 15px 0; |
||||
font-size: 12px; |
||||
text-align: center; |
||||
background-color: #fff; |
||||
|
||||
.van-icon { |
||||
display: block; |
||||
font-size: 24px; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.user-top { |
||||
height: 140px; |
||||
padding: 10px; |
||||
background: white; |
||||
text-align: center; |
||||
|
||||
.user_av { |
||||
display: inline-block; |
||||
margin-top: 30px; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,289 @@ |
||||
<template> |
||||
<div class="content" > |
||||
<van-nav-bar |
||||
title="添加钱包地址" |
||||
left-text="返回" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
/> |
||||
|
||||
<div class="coin-list"> |
||||
<div :class="active==item.id?'active':'Classification'" v-for="(item, id) in list" :key="id" |
||||
@click="onItemClick(item)"> |
||||
<van-image |
||||
round |
||||
width="20" |
||||
height="20" |
||||
:src=item.icon |
||||
/> |
||||
<span>{{item.enName}}</span> |
||||
</div> |
||||
</div> |
||||
<div class="coin-add-input-title"> |
||||
钱包地址 |
||||
</div> |
||||
<van-field |
||||
type="text" |
||||
v-model="value" |
||||
placeholder="请输入钱包地址"> |
||||
</van-field> |
||||
<div class="aca-divider"/> |
||||
<div class="aca-bottom-add" @click="onAddAddress"> |
||||
<span> |
||||
确定 |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import {Toast} from 'vant'; |
||||
import {CoinList} from '@/api/coin' |
||||
import {CoinTokenAdd} from '@/api/address' |
||||
|
||||
import {isEmpty} from '@/utils/common' |
||||
|
||||
|
||||
export default { |
||||
name: "AddCoinAddress", |
||||
data() { |
||||
return { |
||||
list: [], |
||||
loading: false, |
||||
finished: false, |
||||
refreshing: false, |
||||
radio: '1', |
||||
activeIcon: 'https://img01.yzcdn.cn/vant/user-active.png', |
||||
inactiveIcon: 'https://img01.yzcdn.cn/vant/user-inactive.png', |
||||
value: '', |
||||
item: {}, |
||||
active: '', |
||||
|
||||
} |
||||
}, |
||||
created() { |
||||
CoinList().then(response => { |
||||
this.list = response.data; |
||||
window.console.log(response) |
||||
}) |
||||
}, |
||||
method() { |
||||
}, |
||||
methods: { |
||||
change(evt, hidden) { |
||||
window.console.log("hidden:" + hidden) |
||||
//hidden为false的时候,表示从别的页面切换回当前页面 |
||||
//hidden为true的时候,表示从当前页面切换到别的页面 |
||||
if (hidden === false) { |
||||
window.console.log('回到当前页了!') |
||||
} |
||||
}, |
||||
onClickLeft() { |
||||
this.$router.go(-1) |
||||
}, |
||||
async onPaste() { |
||||
const text = await window.navigator.clipboard.readText(); |
||||
this.value = text; |
||||
}, |
||||
onItemClick(item) { |
||||
window.console.log(item.name) |
||||
this.item = item |
||||
this.active = item.id |
||||
}, |
||||
onAddAddress() { |
||||
window.console.log("value:" + this.value) |
||||
window.console.log("value:" + this.item) |
||||
|
||||
let token = this.value; |
||||
if (isEmpty(this.item.cnName)) { |
||||
Toast("请选择钱包地址类型") |
||||
return |
||||
} |
||||
if (isEmpty(token)) { |
||||
Toast("请输入钱包地址") |
||||
return; |
||||
} |
||||
const userInfo = JSON.parse(localStorage.getItem('UserInfo')) |
||||
|
||||
const params = { |
||||
'coinId': this.item.id, |
||||
'token': token, |
||||
'memberId': userInfo.id, |
||||
} |
||||
window.console.log("params:" + JSON.stringify(params)) |
||||
window.console.log("userInfo:" + JSON.stringify(userInfo)) |
||||
|
||||
CoinTokenAdd(params).then(res => { |
||||
window.console.log("res:" + res) |
||||
Toast("添加成功") |
||||
this.$router.go(-1) |
||||
}) |
||||
}, |
||||
onLoad() { |
||||
}, |
||||
handleVisibility(e) { |
||||
window.console.log("handleVisiable:" + e) |
||||
if (e.target.visibilityState === 'visible') { |
||||
// 要执行的方法 |
||||
Toast.fail("回来") |
||||
} else { |
||||
Toast.fail("离开") |
||||
|
||||
} |
||||
} |
||||
}, |
||||
mounted() { |
||||
document.addEventListener('visibilitychange', this.handleVisibility) |
||||
}, |
||||
destroyed() { |
||||
document.removeEventListener('visibilitychange', this.handleVisibility) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
body { |
||||
height: 100%; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.content { |
||||
background: white; |
||||
height: 100%; |
||||
} |
||||
|
||||
.content a { |
||||
margin-top: 20px; |
||||
margin-left: 15px; |
||||
font-size: 16px; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.coin-add-input-title { |
||||
padding-left: 10px; |
||||
height: 40px; |
||||
line-height: 40px; |
||||
background-color: white; |
||||
font-size: 14px; |
||||
font-weight: bold; |
||||
clear: both; |
||||
|
||||
} |
||||
|
||||
.aca-bottom-add { |
||||
height: 40px; |
||||
background: #1796e8; |
||||
text-align: center; |
||||
position: fixed; |
||||
font-size: 12px; |
||||
bottom: 0; |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
font-weight: bold; |
||||
color: white; |
||||
|
||||
} |
||||
|
||||
|
||||
.aca-item { |
||||
width: 25%; |
||||
height: 26px; |
||||
border-radius: 8px; |
||||
border: 1px #000 solid; |
||||
transition: all 0.3s linear; |
||||
text-align: center; |
||||
justify-content: center; |
||||
align-items: center; |
||||
clear: both; |
||||
|
||||
} |
||||
|
||||
ul { |
||||
padding: 0; |
||||
list-style: none; |
||||
margin: 150px 150px; |
||||
} |
||||
|
||||
li { |
||||
width: 80px; |
||||
height: 30px; |
||||
display: inline-block; |
||||
border-radius: 8px; |
||||
border: 1px #000 solid; |
||||
text-align: center; |
||||
line-height: 30px; |
||||
cursor: pointer; |
||||
transition: all 0.3s linear; |
||||
margin-left: 5px; |
||||
} |
||||
|
||||
aca-item:hover { |
||||
background-color: #0CF; |
||||
color: #fff; |
||||
border: 1px #fff solid; |
||||
} |
||||
|
||||
aca-item:focus { |
||||
background-color: #0CF; |
||||
color: #fff; |
||||
border: 1px #fff solid; |
||||
} |
||||
|
||||
.coin-list { |
||||
margin-top: 10px; |
||||
clear: both; |
||||
|
||||
} |
||||
|
||||
.active { |
||||
float: left; |
||||
width: 25%; |
||||
height: 30px; |
||||
padding-left: 5px; |
||||
padding-right: 5px; |
||||
line-height: 30px; |
||||
margin-left: 10px; |
||||
background: #1796e8; |
||||
margin-bottom: 10px; |
||||
border-radius: 6px; |
||||
font-size: 12px; |
||||
color: white; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
|
||||
} |
||||
|
||||
.active span { |
||||
margin-left: 5px |
||||
} |
||||
|
||||
.Classification { |
||||
width: 25%; |
||||
float: left; |
||||
height: 30px; |
||||
line-height: 30px; |
||||
margin-left: 10px; |
||||
background: #f4f4f4; |
||||
margin-bottom: 10px; |
||||
border-radius: 6px; |
||||
padding-left: 5px; |
||||
padding-right: 5px; |
||||
font-size: 12px; |
||||
/*flex 布局*/ |
||||
display: flex; |
||||
/*实现垂直居中*/ |
||||
align-items: center; |
||||
/*实现水平居中*/ |
||||
justify-content: center; |
||||
} |
||||
|
||||
.Classification span { |
||||
margin-left: 5px; |
||||
} |
||||
</style> |
@ -0,0 +1,214 @@ |
||||
<template> |
||||
<div class="content"> |
||||
<van-nav-bar |
||||
title="钱包地址" |
||||
left-text="返回" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
/> |
||||
<van-pull-refresh class="cls-list" v-model="refreshing" @refresh="onRefresh"> |
||||
<van-list |
||||
v-model="loading" |
||||
:finished="finished" |
||||
finished-text="没有更多了" |
||||
@load="onLoad" |
||||
> |
||||
<div v-for="item in list" |
||||
:key="item.id" |
||||
:name="item.id" |
||||
> |
||||
<div class="cls-list-item"> |
||||
<van-image |
||||
style="float: left;" |
||||
round |
||||
width="40" |
||||
height="40" |
||||
:src=item.icon |
||||
/> |
||||
<div style="float: left; margin-left: 10px"> |
||||
<div class="cls-list-item-coin-name" style="top:8px; left:8px"> |
||||
{{item.cnName}}({{item.enName}}) |
||||
</div> |
||||
<div id="address" style="position:absolute;bottom:0;">{{item.address}}</div> |
||||
</div> |
||||
<div style="float: right"> |
||||
<van-button class="cal-copy" plain type="info" size="mini" @click="onCopy(item.address)"> |
||||
复制 |
||||
</van-button> |
||||
<van-button plain type="info" size="mini" color="red" @click="onDel(item,item.id)">删除 |
||||
</van-button> |
||||
</div> |
||||
</div> |
||||
<div class="history-list-item-divider"/> |
||||
</div> |
||||
|
||||
</van-list> |
||||
</van-pull-refresh> |
||||
|
||||
<div class="cls-bottom-add" @click="onAddCoinAddress"> |
||||
<span> |
||||
添加钱包地址 |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import {Dialog} from 'vant'; |
||||
import {Toast} from 'vant'; |
||||
import Clipboard from 'clipboard'; |
||||
import {CoinTokenList, CoinTokenDelete} from '@/api/address' |
||||
|
||||
export default { |
||||
name: "CoinAddressLit", |
||||
data() { |
||||
return { |
||||
list: [], |
||||
loading: false, |
||||
finished: false, |
||||
refreshing: false, |
||||
} |
||||
}, |
||||
methods: { |
||||
onClickLeft() { |
||||
this.$router.go(-1) |
||||
}, |
||||
onAddCoinAddress() { |
||||
this.$router.push({name: 'wallet/coin/address/add', params: {}}) |
||||
}, |
||||
onCopy(address) { |
||||
window.console.log("" + address) |
||||
new Clipboard('.cal-copy', { |
||||
text: function () { |
||||
return address; |
||||
} |
||||
}) |
||||
Toast("地址已经复制") |
||||
window.console.log("剪切板内容:" + address) |
||||
|
||||
}, |
||||
onDel(item, id) { |
||||
window.console.log("" + item + "/" + id) |
||||
let _this = this; |
||||
Dialog.confirm({ |
||||
title: '删除确认', |
||||
message: '确认删掉', |
||||
}) |
||||
.then(() => { |
||||
const userInfo = JSON.parse(localStorage.getItem('UserInfo')) |
||||
const params = { |
||||
'id': id, |
||||
'userId': userInfo.id, |
||||
} |
||||
CoinTokenDelete(params).then(response => { |
||||
window.console.log(response) |
||||
_this.list.some((item, i) => { |
||||
if (item.id == id) { |
||||
_this.list.splice(i, 1) |
||||
// 在数组的some方法中,如果return true,就会立即终止这个数组的后续循环,所以相比较foreach,如果想要终止循环,那么建议使用some |
||||
return true; |
||||
} |
||||
}) |
||||
}) |
||||
Toast("删除成功") |
||||
}) |
||||
.catch(() => { |
||||
}); |
||||
}, |
||||
onLoad() { |
||||
if (this.refreshing) { |
||||
this.list = []; |
||||
this.refreshing = false; |
||||
} |
||||
|
||||
CoinTokenList().then(response => { |
||||
window.console.log(response) |
||||
this.list = response.data; |
||||
// 加载状态结束 |
||||
this.loading = true; |
||||
this.finished = true; |
||||
}) |
||||
|
||||
// setTimeout(() => { |
||||
// if (this.refreshing) { |
||||
// this.list = []; |
||||
// this.refreshing = false; |
||||
// } |
||||
// |
||||
// for (let i = 0; i < 5; i++) { |
||||
// this.list.push({ |
||||
// id: i, |
||||
// name: 'BTC' + i, |
||||
// address: 'aodgffiashdoajsodijapsdjpasdasdasdosjd' + i, |
||||
// img: '', |
||||
// }); |
||||
// } |
||||
// // 加载状态结束 |
||||
// this.loading = true; |
||||
// this.finished = true; |
||||
// }, 1000); |
||||
}, |
||||
onRefresh() { |
||||
// 清空列表数据 |
||||
this.finished = false; |
||||
// 重新加载数据 |
||||
// 将 loading 设置为 true,表示处于加载状态 |
||||
this.loading = true; |
||||
this.onLoad(); |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
body { |
||||
height: 100%; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.content { |
||||
background: white; |
||||
height: 100%; |
||||
} |
||||
|
||||
.cls-list-item { |
||||
min-height: 45px; |
||||
position: relative; |
||||
font-size: 12px; |
||||
margin: 5px 15px; |
||||
} |
||||
|
||||
.cls-list-item-coin-name { |
||||
font-size: 12px; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
|
||||
.history-list-item-divider { |
||||
background: #e8e8e8; |
||||
height: 1px; |
||||
margin-left: 55px; |
||||
margin-right: 15px; |
||||
} |
||||
|
||||
.cls-list { |
||||
margin-bottom: 40px; |
||||
|
||||
} |
||||
|
||||
.cls-bottom-add { |
||||
height: 40px; |
||||
background: #1796e8; |
||||
text-align: center; |
||||
position: fixed; |
||||
font-size: 12px; |
||||
bottom: 0; |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
font-weight: bold; |
||||
color: white; |
||||
} |
||||
</style> |
@ -0,0 +1,203 @@ |
||||
<template> |
||||
<div class="content"> |
||||
<van-nav-bar |
||||
title="钱包地址" |
||||
left-text="返回" |
||||
left-arrow |
||||
@click-left="onClickLeft" |
||||
/> |
||||
<van-pull-refresh class="cls-list" v-model="refreshing" @refresh="onRefresh"> |
||||
<van-list |
||||
v-model="loading" |
||||
:finished="finished" |
||||
finished-text="没有更多了" |
||||
@load="onLoad" |
||||
> |
||||
<div v-for="item in list" |
||||
:key="item.id" |
||||
:name="item.id" |
||||
> |
||||
<div class="cls-list-item" @click="onItemClick(item)"> |
||||
<van-image |
||||
style="float: left;" |
||||
round |
||||
width="40" |
||||
height="40" |
||||
:src=item.icon |
||||
/> |
||||
<div style="float: left; margin-left: 10px"> |
||||
<div class="cls-list-item-coin-name" style="top:8px; left:8px"> |
||||
{{item.cnName}}({{item.enName}}) |
||||
</div> |
||||
<div id="address" style="position:absolute;bottom:0;">{{item.address}}</div> |
||||
</div> |
||||
<div style="float: right"> |
||||
<van-button class="cal-copy" plain type="info" size="mini" @click="onCopy(item.address)"> |
||||
复制 |
||||
</van-button> |
||||
<van-button plain type="info" size="mini" color="red" @click="onDel(item,item.id)">删除 |
||||
</van-button> |
||||
</div> |
||||
</div> |
||||
<div class="history-list-item-divider"/> |
||||
</div> |
||||
|
||||
</van-list> |
||||
</van-pull-refresh> |
||||
|
||||
<div class="cls-bottom-add" @click="onAddCoinAddress"> |
||||
<span> |
||||
添加钱包地址 |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import {Dialog} from 'vant'; |
||||
import {Toast} from 'vant'; |
||||
import Clipboard from 'clipboard'; |
||||
import {CoinTokenList, CoinTokenDelete} from '@/api/address' |
||||
|
||||
export default { |
||||
name: "CoinAddressSelect", |
||||
data() { |
||||
return { |
||||
list: [], |
||||
loading: false, |
||||
finished: false, |
||||
refreshing: false, |
||||
} |
||||
}, |
||||
methods: { |
||||
onClickLeft() { |
||||
this.$router.go(-1) |
||||
}, |
||||
onAddCoinAddress() { |
||||
this.$router.push({name: 'wallet/coin/address/add', params: {}}) |
||||
}, |
||||
onItemClick(item) { |
||||
window.console.log("item" + item) |
||||
localStorage.setItem('selectAddress', JSON.stringify(item)) |
||||
this.$router.back() |
||||
}, |
||||
onCopy(address) { |
||||
window.console.log("" + address) |
||||
new Clipboard('.cal-copy', { |
||||
text: function () { |
||||
return address; |
||||
} |
||||
}) |
||||
Toast("地址已经复制") |
||||
window.console.log("剪切板内容:" + address) |
||||
|
||||
}, |
||||
onDel(item, id) { |
||||
window.console.log("" + item + "/" + id) |
||||
let _this = this; |
||||
Dialog.confirm({ |
||||
title: '删除确认', |
||||
message: '确认删掉', |
||||
}) |
||||
.then(() => { |
||||
const userInfo = JSON.parse(localStorage.getItem('UserInfo')) |
||||
const params = { |
||||
'id': id, |
||||
'userId': userInfo.id, |
||||
} |
||||
CoinTokenDelete(params).then(response => { |
||||
window.console.log(response) |
||||
_this.list.some((item, i) => { |
||||
if (item.id == id) { |
||||
_this.list.splice(i, 1) |
||||
// 在数组的some方法中,如果return true,就会立即终止这个数组的后续循环,所以相比较foreach,如果想要终止循环,那么建议使用some |
||||
return true; |
||||
} |
||||
}) |
||||
}) |
||||
Toast("删除成功") |
||||
}) |
||||
.catch(() => { |
||||
}); |
||||
}, |
||||
onLoad() { |
||||
if (this.refreshing) { |
||||
this.list = []; |
||||
this.refreshing = false; |
||||
} |
||||
const params = { |
||||
"coinId": this.$route.query.coinId, |
||||
} |
||||
CoinTokenList(params).then(response => { |
||||
window.console.log(response) |
||||
this.list = response.data; |
||||
// 加载状态结束 |
||||
this.loading = true; |
||||
this.finished = true; |
||||
}) |
||||
|
||||
}, |
||||
onRefresh() { |
||||
// 清空列表数据 |
||||
this.finished = false; |
||||
// 重新加载数据 |
||||
// 将 loading 设置为 true,表示处于加载状态 |
||||
this.loading = true; |
||||
this.onLoad(); |
||||
} |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style scoped> |
||||
body { |
||||
height: 100%; |
||||
padding: 0; |
||||
margin: 0; |
||||
} |
||||
|
||||
.content { |
||||
background: white; |
||||
height: 100%; |
||||
} |
||||
|
||||
.cls-list-item { |
||||
min-height: 45px; |
||||
position: relative; |
||||
font-size: 12px; |
||||
margin: 5px 15px; |
||||
} |
||||
|
||||
.cls-list-item-coin-name { |
||||
font-size: 12px; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
|
||||
.history-list-item-divider { |
||||
background: #e8e8e8; |
||||
height: 1px; |
||||
margin-left: 55px; |
||||
margin-right: 15px; |
||||
} |
||||
|
||||
.cls-list { |
||||
margin-bottom: 40px; |
||||
|
||||
} |
||||
|
||||
.cls-bottom-add { |
||||
height: 40px; |
||||
background: #1796e8; |
||||
text-align: center; |
||||
position: fixed; |
||||
font-size: 12px; |
||||
bottom: 0; |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: center; |
||||
font-weight: bold; |
||||
color: white; |
||||
} |
||||
</style> |
@ -0,0 +1,14 @@ |
||||
module.exports = { |
||||
outputDir: 'dist', |
||||
publicPath: process.env.NODE_ENV === 'production' ? './' : './', |
||||
css: { |
||||
loaderOptions: { |
||||
less: { |
||||
modifyVars: { |
||||
// 直接覆盖变量
|
||||
'background-color': '#ffffff' |
||||
}, |
||||
}, |
||||
} |
||||
} |
||||
} |