Authored by bevishuang

Merge branch 'develop' of http://git.yoho.cn/fe/xianyu-ufo-app-web into develop

... ... @@ -8,7 +8,7 @@ export default {
pullUpLoad: true,
pullUpLoadThreshold: 0,
pullUpLoadMoreTxt: '加载更多',
pullUpLoadNoMoreTxt: '没有更多数据',
pullUpLoadNoMoreTxt: '到底啦~',
customPullDown: true
};
},
... ...
<template>
<LayoutApp :show-back="true" title="绑定支付宝">
<div class="body" ref="body">
<div class="account-form">
<p class="form-title">账号</p>
<div class="form-input-block">
<CubeInput class="account-input" v-model="account" placeholder="请输入您的支付宝账号"></CubeInput>
</div>
<p class="form-title">姓名</p>
<div class="form-input-block">
<CubeInput class="account-input" v-model="name" placeholder="请输入支付宝实名认证的姓名"></CubeInput>
</div>
</div>
<div class="account-footer">
<CubeButton class="submit-btn" :disabled="canSubmit" @click="submitBind">提交</CubeButton>
</div>
</div>
<myDialog :isShow="dialogShow" :data="{name,account}" @cancel-click="cancel" @confirm-click="confirm"></myDialog>
</LayoutApp>
</template>
<script>
import { createNamespacedHelpers } from 'vuex';
import {Input, Button, Style} from 'cube-ui';
import myDialog from './components/bindModel';
const {mapState, mapActions} = createNamespacedHelpers('home/bindAccount');
export default {
data() {
return {
account: '',
name: '',
dialogShow: false
}
},
computed:{
...mapState({
incomeData: (state) => state.assetData
}),
canSubmit() {
return !(this.name && this.account);
}
},
created() {
},
methods: {
...mapActions(['bindAliPayAccount']),
submitBind() {
this.dialogShow = true
},
cancel() {
this.dialogShow = false
},
confirm() {
this.bindAliPayAccount({account: this.account, name: this.name}).then((data) => {
this.dialogShow = false;
if (data.code === 200) {
this.$router.back()
} else {
this.$createToast({
txt: data.message,
time: 1500,
type: 'txt'
}).show();
}
})
},
},
components: {
Style,
CubeInput: Input,
CubeButton: Button,
myDialog
}
};
</script>
<style lang="scss" scoped>
.body {
position: relative;
height: 100%;
overflow-y: auto;
background-color: white;
padding: 0 40px;
}
.account-form {
margin-top: 40px;
}
.form-title {
font-size: 36px;
padding-top: 40px;
line-height: 1.6;
font-weight: 500;
}
.form-input-block {
padding-bottom: 16px;
border-bottom: 1px solid #eee;
position: relative;
}
.account-input {
&:after {
border: 0;
}
/deep/ .cube-input-field {
font-size: 14px;
height: 40px;
border: none;
padding: 0;
}
}
.account-footer {
position: absolute;
padding: 28px 0;
left: 40px;
right: 40px;
bottom: 40px;
.submit-btn {
height: 88px;
line-height: 88px;
padding: 0;
background: #022c46;
border-radius: 44px;
&:after {
border: 0;
}
&.cube-btn_disabled {
background: #ccc;
}
}
}
</style>
... ...
<template>
<div v-if="isShow" class="third-bind-wrapper">
<div class="bind-dialog">
<div class="dialog-title">请确认您的支付宝账号</div>
<div class="dialog-content">
<div class="input-block">
<p class="info-title">账号</p>
<p class="info-text">{{data.account}}</p>
</div>
<div class="input-block">
<p class="info-title">姓名</p>
<p class="info-text">{{data.name}}</p>
</div>
<div class="tip">为了保证您的安全,请再次确认您提供的支付宝账号的正确性!</div>
</div>
<div class="dialog-footer">
<div class="btn-cancel" @click="cancel">返回修改</div>
<div class="btn-confirm" @click="confirm">我已确认</div>
</div>
</div>
</div>
</template>
<script>
import { createNamespacedHelpers } from 'vuex';
const {mapState, mapActions} = createNamespacedHelpers('home/bindAccount');
export default {
name: 'my-dialog',
props: {
isShow: {
type: Boolean,
default: false
},
data: {
type: Object,
default: {}
}
},
data() {
return {
}
},
computed:{
},
methods: {
cancel() {
this.$emit('cancel-click')
},
confirm() {
this.$emit('confirm-click')
}
},
components: {
}
};
</script>
<style lang="scss" scoped>
.third-bind-wrapper {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.4);
z-index: 99;
display: flex;
justify-content: center;
align-items: center;
}
.bind-dialog {
position: relative;
width: 670px;
padding: 64px 48px 80px;
font-size: 28px;
box-sizing: border-box;
background-color: #fff;
}
.dialog-title {
font-size: 28px;
text-align: center;
}
.dialog-content {
padding: 60px 0;
}
.input-block {
margin-bottom: 40px;
.info-title {
font-size: 24px;
color: #999;
}
.info-text {
font-size: 32px;
margin-top: 5px;
}
}
.tip {
color: #D0021B;
font-size: 24px;
}
.dialog-footer {
position: absolute;
bottom: 0;
right: 0;
left: 0;
height: 100px;
border-top: solid 1px #eee;
font-size: 28px;
display: flex;
justify-content: center;
.btn-cancel {
flex: 1;
color: #999;
border-right: solid 1px #eee;
text-align: center;
line-height: 100px;
}
.btn-confirm {
flex: 1;
text-align: center;
line-height: 100px;
}
}
</style>
... ...
export default [{
name: 'bindAccount',
path: '/xianyu/home/bindAccount.html',
component: () => import(/* webpackChunkName: "bindAccount" */ './bindAccount')
}];
... ...
... ... @@ -4,7 +4,7 @@ import Favorite from './favorite';
import news from './news';
import Income from './income';
import Coupon from './coupon';
import BindAccount from './bindAccount';
export default [
{
name: 'IndexPage',
... ... @@ -91,5 +91,6 @@ export default [
...Trade,
...Favorite,
...Income,
...Coupon
...Coupon,
...BindAccount
];
... ...
<template>
<div v-if="validStatus !== 1" class="">
<div @click="goBind" class="bind-alipay">绑定支付宝</div>
<p class="bind-tip">请先设置支付宝账号作为货款和补偿款的收款商户,
绑定完成在我的收入中展示支付宝绑定账户</p>
</div>
</template>
<script>
import { createNamespacedHelpers } from 'vuex';
const {mapState, mapActions} = createNamespacedHelpers('home/bindAccount');
export default {
name: 'bind',
props: {
data: {
type: Object,
default: {}
}
},
data() {
return {
};
},
computed: {
...mapState(['validStatus'])
},
activated() {
this.fetchUserAliPayAccount()
},
methods: {
...mapActions(['fetchUserAliPayAccount']),
goBind() {
this.$router.push({name:this.data.page})
}
}
};
</script>
<style lang="scss" scoped>
.bind-alipay {
width: 100%;
text-align: center;
height: 88px;
line-height: 88px;
background-color: #fff;
color: #D0021B;
border-radius: 88px;
font-size: 32px;
margin-bottom: 20px;
margin-top: 60px;
border: solid 1px #eee;
}
.bind-tip {
margin: 0 40px;
text-align: center;
font-size: 24px;
color: #999;
margin-bottom: 20px;
}
</style>
... ...
<template>
<div class="single-image">
<LayoutLink :href="data.url" class="link">
<LayoutLink :href="data.url" class="link" v-if="data.src">
<img :src="data.src" :alt="data.title" class="img" :style="style">
</LayoutLink>
</div>
... ...
... ... @@ -16,8 +16,10 @@
<div v-else-if="key === 'sale'" class="bg-top">
<tab-item :data="value" noLine titleBold titleSmall></tab-item>
</div>
<bind v-else-if="key === 'bindAccount'" :data="value"></bind>
<tab-item v-else :data="value"></tab-item>
</div>
</div>
</LayoutApp>
</template>
... ... @@ -27,6 +29,7 @@ import tabItem from './components/tabItem';
import order from './components/order';
import scroll from './components/scroll';
import singleImage from './components/singleImage';
import bind from './components/bind';
import { createNamespacedHelpers } from 'vuex';
const { mapGetters, mapActions } = createNamespacedHelpers('home/mine');
... ... @@ -46,18 +49,27 @@ export default {
this.fetchFavoriteNum();
this.fetchOrderSummary();
this.fetchSellerOrder();
// this.fetchAssets(true)
this.fetchUserWalletInfo();
this.fetchAssets(true)
// this.fetchUserWalletInfo();
this.fetchCoupon();
},
beforeRouteEnter (to, from, next) {
// 从我的绑定支付宝后进入交易明细
next(vm => {
if(from.name === 'bindAccount') {
vm.$router.push({name: 'tradeIncome'})
}
})
},
methods: {
...mapActions(['fetchFavoriteNum', 'fetchResource', 'fetchSellerOrder', 'fetchOrderSummary', 'fetchAssets', 'fetchUserWalletInfo', 'fetchCoupon'])
...mapActions(['fetchFavoriteNum', 'fetchResource', 'fetchSellerOrder', 'fetchOrderSummary', 'fetchAssets', 'fetchUserWalletInfo', 'fetchCoupon']),
},
components: {
tabItem,
order,
scroll,
singleImage
singleImage,
bind
}
};
</script>
... ...
... ... @@ -17,7 +17,6 @@ export default {
type: Object,
default: {}
},
},
data() {
return {
... ... @@ -33,24 +32,31 @@ export default {
},
mounted() {
let summary = {}
for(let key in this.data) {
let item = this.data[key];
if(item.includes('¥')) {
let value = this.data[key].split('¥')[1];
summary[key] = value
}
this.startDraw(this.data);
},
watch: {
data: function(val) {
this.startDraw(val)
}
this.drawProgressbg(summary);
this.startProgress(summary);
},
methods: {
startDraw(val) {
let summary = {}
for(let key in val) {
let item = val[key];
if(item.includes('¥')) {
let value = val[key].split('¥')[1];
summary[key] = value
}
}
this.drawProgressbg(summary);
this.startProgress(summary);
},
// 画progress底部背景
drawProgressbg: function (summary) {
let c=document.getElementById("canvasProgressbg");
let ctx=c.getContext("2d");
ctx.lineWidth= 28 ;
ctx.lineWidth= 30 ;
let strokeStyle = '#E0E0E0'
if (summary && summary.totalIncome > 0) {
strokeStyle = '#65AB85';
... ... @@ -61,15 +67,13 @@ export default {
//设置一个原点(110,110),半径为100的圆的路径到当前路径
ctx.arc(120, 120, 100, 0, 2 * Math.PI, false);
ctx.stroke();
//开始绘制
// ctx.draw();
},
// 画progress进度
drawCircle: function (step) {
let c=document.getElementById("canvasProgress");
let context=c.getContext("2d");
context.lineWidth=28;
context.lineWidth=30;
let strokeColor = '#002B47'
context.strokeStyle=strokeColor;
context.lineCap='round';
... ... @@ -77,8 +81,6 @@ export default {
//参数step 为绘制的圆环周长,从0到2为一周 。 -Math.PI / 2 将起始角设在12点钟位置 ,结束角 通过改变 step 的值确定
context.arc(120, 120, 100, -Math.PI / 2, step * Math.PI - Math.PI / 2, false);
context.stroke();
//开始绘制
// context.draw()
},
// 开始progress
... ... @@ -95,20 +97,20 @@ export default {
<style lang="scss" scoped>
.progress-box {
position: absolute;
top: 50px;
top: 36px;
right: 50px;
width: 280px;
height: 280px;
width: 204px;
height: 204px;
}
.progress-bg {
position: absolute;
width: 100%;
height: 100%;
width: 204px;
height: 204px;
}
.progress-canvas {
position: absolute;
width: 100%;
height: 100%;
width: 204px;
height: 204px;
}
</style>
... ...
... ... @@ -19,6 +19,9 @@ export default {
</script>
<style lang="scss" scoped>
.income-detail-header {
margin-top: 15px;
}
.total-income {
font-size: 36px;
color: #000;
... ...
<template>
<div>
<p class="income-title">我的收入</p>
<div class="income-header">
<p class="total-income">收入: {{data.totalIncome}}</p>
<div class="income">
... ... @@ -43,27 +42,23 @@ export default {
.income-header-wrapper {
position: relative;
}
.income-title {
font-size: 60px;
color: #000;
margin-top: 20px;
}
.income-header {
margin: 50px 0;
margin: 48px 0;
}
.total-income {
color: #000;
font-size: 36px;
margin-bottom: 40px;
font-size: 40px;
margin-bottom: 44px;
}
.income {
margin-bottom: 15px;
margin-bottom: 20px;
font-size: 24px;
.dot1,.dot2 {
display: inline-block;
width: 16px;
height: 16px;
border-radius: 16px;
margin-right: 16px;
}
.dot1 {
background-color: #002B47;
... ... @@ -73,6 +68,7 @@ export default {
}
.income-num {
color: #000;
margin-left: 20px;
}
}
</style>
... ...
... ... @@ -9,7 +9,7 @@
</div>
<div class='assets-record-right-view'>
<span class='assets-record-income-txt'>{{data.price}}</span>
<!-- <span class='assets-record-income-tip-txt' v-if="!data.normalFlag">打款失败</span> -->
<span class='assets-record-income-tip-txt'>{{data.normalFlag ? '' : '打款失败'}}</span>
<span class='assets-record-income-desc'>{{data.tradeTypeDesc}}</span>
</div>
</div>
... ... @@ -47,6 +47,7 @@ export default {
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 160px;
padding-top: 30px;
padding-bottom: 30px;
}
... ... @@ -75,13 +76,18 @@ export default {
font-family: PingFang-SC-Regular;
font-size: 28px;
color: #000000;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
overflow: hidden;
}
.size {
display: inline-block;
}
.assets-record-time-txt {
font-family: SFProText-Regular;
font-size: 24px;
font-size: 22px;
color: #999999;
margin-top: 12px;
}
... ... @@ -95,8 +101,12 @@ export default {
font-family: PingFang-SC-Regular;
font-size: 20px;
color: #D0021B;
display: inline-block;
height: 40px;
line-height: 40px;
}
.assets-record-income-desc {
color: #999;
font-size: 22px;
}
</style>
... ...
<template>
<div class="pay-account">
<div v-if="validStatus === 1">
<div class="account">
<p class="account-tip">支付宝账号</p>
<p class="account-name">{{alipayAccount}}</p>
</div>
<p class="tip"><i class="cubeic-warn"></i><span>已绑定的支付宝账号暂无法提供系统换绑和解除,如
需要帮助可致电<a class="phone" href="tel:400-8890-9646"> 400-8890-9646 </a>联系电话客服</span></p>
</div>
<div v-else>
<div class="bind-button" @click="bindAccount">设置支付宝账号</div>
<p class="tip"><i class="cubeic-warn"></i><span>请先设置支付宝账号作为货款和补偿款的收款账户</span></p>
</div>
</div>
</template>
<script>
import { createNamespacedHelpers } from 'vuex';
const {mapState, mapActions} = createNamespacedHelpers('home/bindAccount');
export default {
name: 'pay-account',
props: {
},
activated() {
this.fetchUserAliPayAccount()
},
computed: {
...mapState(['alipayAccount','certName', 'validStatus'])
},
methods: {
...mapActions(['fetchUserAliPayAccount']),
bindAccount() {
this.$router.push({ name: 'bindAccount' });
}
},
};
</script>
<style lang="scss" scoped>
.pay-account {
padding: 40px 0;
.tip {
font-size: 24px;
display: flex;
align-items: center;
}
.cubeic-warn {
font-size: 32px;
margin-right: 16px;
}
}
.phone {
text-decoration: underline;
color: #65AB85;
}
.bind-button {
width: 100%;
text-align: center;
height: 88px;
line-height: 88px;
background-color: #002B47;
color: #fff;
border-radius: 88px;
font-size: 34px;
margin-bottom: 20px;
}
.account {
display: flex;
height: 120px;
line-height: 120px;
border-bottom: solid 1px #eee;
margin-bottom: 20px;
font-size: 28px;
.account-tip {
flex: 1
}
.account-name {
color: #000;
}
}
</style>
... ...
<template>
<LayoutApp :show-back="true">
<LayoutApp :show-back="true" title="我的收入">
<div class="body" ref="body">
<Scroll
ref="scroll"
... ... @@ -8,7 +8,8 @@
@pulling-down="onPullingDown"
@pulling-up="onPullingUp">
<incomeHeader :data="incomeSum"></incomeHeader>
<incomeHeader :data="getAssetSummary"></incomeHeader>
<payAccount></payAccount>
<incomeDetail :data="incomeData">
<template v-for="(item,index) in incomeData.list">
<incomeItem :data="item" :key="index"></incomeItem>
... ... @@ -27,10 +28,11 @@ import incomeHeader from './components/incomeHeader';
import incomeDetail from './components/incomeDetail';
import incomeItem from './components/incomeItem';
import pullDown from './components/pullDown';
import payAccount from './components/payAccount';
import { createNamespacedHelpers } from 'vuex';
import {Style, Scroll} from 'cube-ui';
import scrollMixin from '../../../mixins/scroll';
const {mapState, mapActions} = createNamespacedHelpers('home/mine');
const {mapState, mapGetters, mapActions} = createNamespacedHelpers('home/mine');
export default {
mixins: [scrollMixin],
data() {
... ... @@ -39,27 +41,19 @@ export default {
}
},
computed:{
...mapGetters(['getAssetSummary']),
...mapState({
incomeSum:(state) => {
return {
goodsIncome: state.assetData.goodsIncome,
totalIncome: state.assetData.totalIncome,
compensateIncome: state.assetData.compensateIncome
}
},
incomeData: (state) => state.assetData
}),
},
created() {
},
activated() {
this.fetchAssets(true)
},
watch: {
"incomeData.list": function(val) {
console.log('www')
if(val.length === 0) {
this.$refs.scroll.disable()
} else {
... ... @@ -85,6 +79,7 @@ export default {
incomeDetail,
incomeItem,
pullDown,
payAccount,
Style,
Scroll
}
... ...
import { maskAccount } from '../../utils/mine-handler';
export default function() {
return {
namespaced: true,
state: {
alipayAccount: '',
certName: '',
validStatus: 0
},
mutations: {
addUserAliPayAccount(state, data) {
let {
alipayAccount,
certName,
validStatus
} = data;
state.alipayAccount = maskAccount(alipayAccount);
state.certName = certName;
state.validStatus = validStatus;
}
},
actions: {
async fetchUserAliPayAccount({ commit }) {
const result = await this.$api.get('/api/ufo/home/getUserAliPayAccount');
console.log(result);
if (result.code === 200) {
commit('addUserAliPayAccount', result.data);
}
},
async bindAliPayAccount({ commit }, {account, name}) {
const result = await this.$api.get('/api/ufo/home/bindAliPayAccount', {
alipayAccount: account,
certName: name
});
// commit('addUserAliPayAccount', result.data);
return result;
},
},
};
}
... ...
... ... @@ -3,7 +3,7 @@ import channel from './channel';
import favorite from './favorite';
import news from './news';
import coupon from './coupon';
import bindAccount from './bindAccount';
export default function() {
return {
namespaced: true,
... ... @@ -23,7 +23,8 @@ export default function() {
channel: channel(),
favorite: favorite(),
news: news(),
coupon: coupon()
coupon: coupon(),
bindAccount: bindAccount()
}
};
}
... ...
... ... @@ -102,9 +102,10 @@ export default function() {
resource1: { name: 'resource1', data: state.resource1 },
income: {
title: '我的收入',
num: state.userWalletInfo.walletAmount, // 钱包余额
// num: state.assetData.totalIncome,
page: 'income',
// num: state.userWalletInfo.walletAmount, // 钱包余额
num: state.assetData.totalIncome,
page: 'tradeIncome',
}, // 原交易收入 tradeIncome, 余额 income
buyOrder: {
title: '我的订单',
... ... @@ -135,6 +136,10 @@ export default function() {
title: '我的客服',
page: 'service',
},
bindAccount: {
name: 'bindAccount',
page: 'bindAccount'
},
resource2: { name: 'resource2', data: state.resource2 },
};
... ... @@ -171,6 +176,13 @@ export default function() {
return [yearsData, monthsData];
},
getAssetSummary(state) {
return {
goodsIncome: state.assetData.goodsIncome,
totalIncome: state.assetData.totalIncome,
compensateIncome: state.assetData.compensateIncome
};
}
},
mutations: {
addList(state, { list }) {
... ... @@ -232,9 +244,9 @@ export default function() {
state.couponNum = count;
},
addAssets(state, assetData) {
assetData.totalIncome = formatNumber(assetData.totalIncome);
assetData.compensateIncome = formatNumber(assetData.compensateIncome);
assetData.goodsIncome = formatNumber(assetData.goodsIncome);
assetData.totalIncome = formatNumber(assetData.totalIncome || 0);
assetData.compensateIncome = formatNumber(assetData.compensateIncome || 0);
assetData.goodsIncome = formatNumber(assetData.goodsIncome || 0);
state.assetData = Object.assign({}, state.assetData, assetData);
},
addWallet(state, walletData) {
... ... @@ -310,24 +322,31 @@ export default function() {
});
if (result.code === 200) {
let src = getImgUrl(
get(result, 'data[0].data[0].src') || '',
1000,
240,
);
if (result.data.length !== 0) {
let src = getImgUrl(
get(result, 'data[0].data[0].src') || '',
1000,
240,
);
set(result, 'data[0].data[0].src', src);
commit('addResource', {
resource1: result.data[0]
});
}
set(result, 'data[0].data[0].src', src);
commit('addResource', { resource1: result.data[0] });
}
if (result1.code === 200) {
let src = getImgUrl(
get(result1, 'data[0].data[0].src') || '',
1000,
240,
);
set(result1, 'data[0].data[0].src', src);
commit('addResource', { resource2: result1.data[0] });
if (result.data.length !== 0) {
let src = getImgUrl(
get(result1, 'data[0].data[0].src') || '',
1000,
240,
);
set(result1, 'data[0].data[0].src', src);
commit('addResource', { resource2: result1.data[0] });
}
}
},
async fetchSellerOrder({ commit }) {
... ... @@ -378,7 +397,7 @@ export default function() {
let page = isRefresh ? 1 : currentPage + 1;
const result = await this.$api.get('/api/ufo/mine/assets', {
page,
limit: pageSize,
limit: pageSize
});
// commit('assetFetching', {isFetching: false});
... ... @@ -387,9 +406,7 @@ export default function() {
let newList = [...oldList, ...assetData.list];
assetData.list = newList;
if (typeof assetData.totalIncome !== 'undefined') {
commit('addAssets', assetData);
}
commit('addAssets', assetData);
}
},
... ... @@ -423,7 +440,7 @@ export default function() {
limit: pageSize,
tradeType,
startTime,
endTime,
endTime
});
if (result.code === 200) {
... ...
... ... @@ -119,4 +119,19 @@ module.exports = {
type: {type: String},
}
},
'/api/ufo/home/bindAliPayAccount': {
ufo: true,
auth: true,
api: 'ufo.user.directBindAliPayAccountInfo',
param: {
alipayAccount: {type: String},
certName: {type: String}
}
},
'/api/ufo/home/getUserAliPayAccount': {
ufo: true,
auth: true,
api: 'ufo.user.getUserAliPayAccountInfo',
param: {}
},
};
... ...