Authored by TaoHuang

add detail list page

<template>
<LayoutApp :title="title">
<DateFilter class="date-filter-wrapper" v-show="showFilter" @on-change="dateHandler"></DateFilter>
<DetailList @on-date-pick="dateHandler"></DetailList>
</LayoutApp>
</template>
<script>
import LayoutApp from '../components/layout/layout-app';
import DetailList from './detailList/detail-list';
import DateFilter from './detailList/components/date-filter';
import {createNamespacedHelpers} from 'vuex';
const {mapState, mapMutations} = createNamespacedHelpers('invite/invite');
export default {
name: 'DetailListPage',
components: {
LayoutApp
LayoutApp,
DetailList,
DateFilter
},
data() {
return {
title: '全部佣金'
};
}
},
computed: {
...mapState(['showFilter', 'date'])
},
methods: {
...mapMutations({
setDate: 'SET_DATE'
}),
dateHandler(p) {
this.showTimePicker();
},
showTimePicker() {
if (!this.timePicker) {
this.timePicker = this.$createDatePicker({
title: '',
min: [2019, 4],
max: new Date(),
value: this.date,
startColumn: 'year',
columnCount: 2,
onSelect: this.selectHandle,
onCancel: this.cancelHandle
});
}
this.timePicker.show();
},
selectHandle(date, selectedVal) {
this.setDate({value: [...selectedVal]});
},
cancelHandle() {
}
},
};
</script>
<style lang="scss" scoped>
.date-filter-wrapper {
position: absolute;
width: 100%;
top: -2px;
background: #f5f5f5;
padding-left: 40px;
z-index: 2;
}
</style>
... ...
<template>
<div class="date-filter">
<div class="date-picker" @click="clickHandle">
{{date[0]}}年{{date[1]}}月 <i class="iconfont icon-arrow arrow"></i>
</div>
<div class="account">
总佣金:¥{{0}} &nbsp; 已打款:¥{{0}} &nbsp; 未打款:¥{{0}}
</div>
</div>
</template>
<script>
import {createNamespacedHelpers} from 'vuex';
const {mapState} = createNamespacedHelpers('invite/invite');
export default {
name: 'DateFilter',
props: {
data: {
type: Object,
default() {
return {};
}
},
},
data() {
return {
};
},
methods: {
clickHandle() {
this.$emit('on-change', {date: this.date});
}
},
computed: {
...mapState(['date'])
}
};
</script>
<style lang="scss" scoped>
.date-filter {
display: flex;
height: 160px;
padding: 34px 0;
flex-direction: column;
justify-content: space-between;
}
.date-picker {
height: 40px;
color: black;
font-size: 28px;
line-height: 40px;
}
.account {
font-size: 24px;
color: #999;
height: 34px;
line-height: 34px;
}
.arrow {
display: inline-block;
}
</style>
... ...
<template>
<div class="record-item">
<div>
<div class="item">
<span class="label">订单编号:</span>
<span class="tip">{{56789123}}</span>
</div>
<div class="item">
<span class="label">下单时间:</span>
<span class="tip">2019.04.08 13:41:22</span>
</div>
<div class="item">
<span class="label">卖家昵称:</span>
<span class="tip">{{'布吉岛'}}</span>
</div>
</div>
<div class="item-right">
<div class="money-wrapper">
<span class="desc">返:</span>
<span class="money">{{'¥30'}}</span>
</div>
<div class="status">
{{'待打款'}}
</div>
</div>
</div>
</template>
<script>
export default {
name: 'RecordItem'
};
</script>
<style lang="scss" scoped>
.record-item {
height: 208px;
padding: 36px 0;
display: flex;
justify-content: space-between;
}
.item {
height: 40px;
line-height: 40px;
}
.item + .item {
margin-top: 12px;
}
.label {
font-size: 28px;
color: #999;
}
.tip {
font-size: 28px;
color: black;
}
.item-right {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.money-wrapper {
display: flex;
height: 48px;
margin-bottom: 12px;
.desc {
font-size: 24px;
height: 48px;
line-height: 48px;
}
.money {
font-size: 40px;
height: 48px;
line-height: 48px;
}
}
.status {
width: 100%;
font-size: 24px;
color: #d0021b;
text-align: right;
}
</style>
... ...
<template>
<div>
<RecordItem class="record-item-wrapper" v-for="(item, index) in data" v-bind="item"></RecordItem>
</div>
</template>
<script>
import RecordItem from './record-item';
export default {
name: 'RecordList',
components: {
RecordItem,
},
props: {
data: {
type: Array,
default() {
return [];
}
}
}
};
</script>
<style lang="scss" scoped>
.record-item-wrapper + .record-item-wrapper {
border-top: 1px solid #eee;
}
</style>
... ...
import TabBar from './tab-bar';
import TabBarItem from './tab-bar-item';
TabBar.Item = TabBarItem;
export default TabBar;
... ...
<template>
<div class="tab-bar-item" :class="getCls" @click="onClick">
{{label}}
</div>
</template>
<script>
export default {
name: 'TabBarItem',
props: ['label', 'value', 'active', 'index'],
data() {
return {
handleActive: this.active
};
},
methods: {
onClick() {
if (!this.handleActive) {
this.$emit('on-change', {
label: this.label,
value: this.value,
index: this.index
});
}
}
},
computed: {
getCls() {
return {
active: this.handleActive
};
}
},
watch: {
active(newVal) {
this.handleActive = newVal;
}
}
};
</script>
<style lang="scss" scoped>
.tab-bar-item {
height: 100px;
line-height: 100px;
text-align: center;
padding: 0 11px;
&.active {
font-size: 40px;
color: black;
font-weight: bold;
box-sizing: border-box;
border-bottom: 5px solid black;
}
}
</style>
... ...
<template>
<div class="tab-bar">
<slot>
<Item
v-for="(i,index) in data" :label="i.label" :value="i.value" :key="i.value" :active="i.value === handleValue" :index="index"
@on-change="onClick"
>
</Item>
</slot>
</div>
</template>
<script>
import Item from './tab-bar-item';
import {createNamespacedHelpers} from 'vuex';
const {mapMutations} = createNamespacedHelpers('invite/invite');
export default {
name: 'TabBar',
components: {
Item
},
props: {
data: {
type: Array,
default: []
},
value: {
type: Number,
default: 1
}
},
data() {
return {
handleValue: this.value
};
},
mounted() {
this.setTop({top: this.$el.clientHeight});
},
methods: {
...mapMutations({
setTop: 'CHANGE_FILTER_TOP'
}),
onClick(p) {
this.$emit('input', p.value);
this.$emit('click', p.value);
this.$emit('change', p.value);
}
},
watch: {
value(newVal) {
this.handleValue = newVal;
}
}
};
</script>
<style lang="scss" scoped>
.tab-bar {
display: flex;
height: 100px;
font-size: 28px;
color: #999;
align-items: center;
justify-content: space-between;
}
</style>
... ...
<template>
<Scroll class="detail-list-wrapper" :options="options" :scrollEvents="['scroll']" @scroll="scrollHandler">
<TabBar class="tab-bar-wrapper" :data="tabs"
v-model="selectedTabs"
@click="clickHandler"
>
</TabBar>
<DateFilter class="date-filter-wrapper" @on-change="changeHandler"></DateFilter>
<RecordList class="record-list-wrapper" :data="list"></RecordList>
</Scroll>
</template>
<script>
import TabBar from './components/tab-bar';
import DateFilter from './components/date-filter';
import RecordList from './components/record-list';
import {Scroll} from 'cube-ui';
import {throttle} from 'lodash';
import {createNamespacedHelpers} from 'vuex';
const {mapState, mapMutations} = createNamespacedHelpers('invite/invite');
export default {
name: 'DetailList',
components: {
TabBar,
DateFilter,
RecordList,
Scroll
},
data() {
return {
title: '全部佣金',
selectedTabs: 1,
tabs: [{
label: '全部',
value: 1,
}, {
label: '待打款',
value: 2,
}, {
label: '已打款',
value: 3,
}],
list: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
options: {
bounce: false,
pullUpLoad: {
txt: {
more: '加载更多',
noMore: '没有更多了'
}
},
probeType: 2
}
};
},
mounted() {
this.scrollEvent = throttle(this.onDounceScroll.bind(this), 200);
},
methods: {
...mapMutations({
showFilter: 'SET_FILTER_TOP'
}),
clickHandler(p) {
console.log(p);
},
onDounceScroll(p) {
if (Math.abs(p.y) >= this.filterTop) {
this.showFilter({show: true});
} else {
this.showFilter({show: false});
}
},
scrollHandler(p) {
this.scrollEvent(p);
},
changeHandler(p) {
this.$emit('on-date-pick', p);
}
},
computed: {
...mapState(['filterTop'])
}
};
</script>
<style lang="scss" scoped>
.detail-list-wrapper {
overflow: scroll;
height: 100%;
}
.tab-bar-wrapper {
width: 450px;
margin-left: 40px;
}
.date-filter-wrapper {
top: -2px;
background: #f5f5f5;
padding-left: 40px;
}
.record-list-wrapper {
padding: 0 40px;
}
</style>
... ...
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1545459019848'); /* IE9*/
src: url('iconfont.eot?t=1545459019848#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
url('iconfont.ttf?t=1545459019848') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('iconfont.svg?t=1545459019848#iconfont') format('svg'); /* iOS 4.1- */
src: url('iconfont.eot?t=1554972747129'); /* IE9 */
src: url('iconfont.eot?t=1554972747129#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAS4AAsAAAAACfQAAARqAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCEAgqGCIUfATYCJAMkCxQABCAFhG0HaxuuCCMRJmyRR/aPxNhYe2Fmj6/aaHCxQRI9gpHqTPD0n/P1juZJfgoQ0ApITtg/1NZQANyFaAVEcpGdfxQAi3OewJgIM5S36NEX0o3Tp+nh7w+VMyYlYPNlfgtKBOceGMBwgAKU3Tm9ZC1IrsAFsS7iGexC4UE3XocABahCI6RXn0GjsBjWpwSQRfPnTscWHJgOumDNXsOt5nvZi4t1djhngT3u5+UHWogFB1dZv2nYnN6z6Bba7CkNooBJGic4nA8Y3gUKNAIMyIuNgZ0aCo1QCsxrDdOAYuK3KoR+WC5sFj7L1svOzJ6KotBWZlFSKEaJQXBQDO7t/ePFsCAea0MhJCxLWQgVggOhj6AQlkMwEDZDcCF8hiCQrYfgQXYmQgyypxxYxPnHSwDFgXsgXYHQyefiCJZgkOpChcQvXKSItVby+fJaxTydfv36mBs3xl67Nvrq1dVSN8rL8puvXx9V4LXPCuR9Enyc+HQ8+UTjcysOCa6RZKLMmHRV6dGpYJEEX9mxmU1ypUYlE2uU6dOibkmH6eON/ihrCmk6nUiWcgolk0GqdGEnlcrLlNXCmUw8PfOVT/I+i3+a+Hj0JVw7Kf2pyFsnG372Vdk3LycuVroYo/Sqff1YvY8PlWP16WLptEg8U7Z4KoUEycVz5o6eNXvNytVR50Mml1scElIj05rUtb/S9h29cUNR+w7LcIoLnzTTT+uJqibuDhYpXqSaMlQym+lQLcvdOj/mfrtX6/QA87+3b2G09l6o+bHOgVrnchSnQ/Vb+cTpWvdyDVbT3AXP1TrQV2pfRLvf0mtWxT4r8Vls1aplB0ocWLZqTYG6Zk2MC0vNKfX1T1t98rB5/twcFlIj05rUVfBJx3f15k1F7bsswym+uvLF4oXbePf393xW1I4ZMcoWvuSqwtJz/LieRJPxE3r0409Gldc2hW/iyPQ5g97+aU/Bn952T+Lcqvxcfn6PHvsP7N/HNA2aGeR52ABAdFyPalcA/capiwLRPX1Pa1qPqch2A8Aj8ipEW7SExv+G56HUnJHFpxbt9JctaAC4ea36QIxFgcdmzWBxYGPlny4Yq8yHr16o107fzPR0ypW6qEaTd4ghfHrjwtdno4CIQESREtw/rKn0xjkQbEE5BIcYlUGx1MIYQiNwKUgr8LB0hQI0pO/dBSnJChQxPtCALQBCMb4ChyIcBaUY5zCGcA9cyvATeBQThQKMkZKPLEiddTJ/d2RUghb0HxpDo5Nu2fn2G1axV5xXO8YLOTRpKNK8XL7iiHyIK8KnKkUcOKYBLvA27HsCz9SikbQW8Ycsc01flBoaJjuOjErQAvoPNIZGZ5bLrvL9N6xir7hj7lz8hRya9YGClHwDzNUwbjT3UraHT1Ui4viYYxqAC/qwFwUCfPO+Fo2k1Dvk/IGMFrlNDenpTcN7vQIUYP1EXxxRMeKKJzGx4ksBFvMf/9Nm0S8tfcdx2STK2u07YpAXtKHYLetjSIZmNLsXWpluqZjpO5kAAAA=') format('woff2'),
url('iconfont.woff?t=1554972747129') format('woff'),
url('iconfont.ttf?t=1554972747129') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1554972747129#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family:"iconfont" !important;
font-size:16px;
font-style:normal;
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-info:before { content: "\e6e5"; }
.icon-info:before {
content: "\e6e5";
}
.icon-up:before { content: "\e608"; }
.icon-up:before {
content: "\e608";
}
.icon-downn:before {
content: "\e609";
}
.icon-downn:before { content: "\e609"; }
.icon-i-add:before {
content: "\e618";
}
.icon-i-add:before { content: "\e618"; }
.icon-question1:before {
content: "\e630";
}
.icon-question1:before { content: "\e630"; }
.icon-plus-minus:before {
content: "\e728";
}
.icon-plus-minus:before { content: "\e728"; }
.icon-back:before {
content: "\e763";
}
.icon-back:before { content: "\e763"; }
.icon-arrow:before {
content: "\e7c4";
}
... ...
... ... @@ -41,6 +41,9 @@ Created by iconfont
<glyph glyph-name="back" unicode="&#59235;" d="M718.08-122.464L208 386.016 718.016 896.032l67.36-67.36-442.56-442.56 442.496-441.12-67.264-67.456z" horiz-adv-x="1024" />
<glyph glyph-name="arrow" unicode="&#59332;" d="M1536 896L768-128 0 896z" horiz-adv-x="1536" />
</font>
... ...
... ... @@ -13,14 +13,20 @@ export default function() {
finishedOrderNum: 0,
inviteRecordList: []
},
status: 0
status: 0,
showFilter: false,
filterTop: 0,
date: [
new Date().getFullYear(),
new Date().getMonth() + 1
]
},
actions,
mutations,
getters: {
getBandLength(state, getters, rootState) {
return rootState.mine.bankCard.bankCardList.length === 1;
}
},
}
};
}
... ...
... ... @@ -9,5 +9,14 @@ export default {
},
[Types.FETCH_INVITE_CODE](state, data) {
state.inviteCode = data;
},
[Types.CHANGE_TOP](state, data) {
state.filterTop = data.top;
},
[Types.SET_TOP](state, {show}) {
state.showFilter = show;
},
[Types.SET_DATE](state, {value}) {
state.date = value;
}
};
... ...
... ... @@ -5,3 +5,8 @@ export const FETCH_BANK_CARD_SUCCESS = 'FETCH_BANK_CARD_SUCCESS';
export const FETCH_INVITE_STATUS = 'FETCH_INVITE_STATUS';
export const FETCH_INVITE_ORDERLIST = 'FETCH_INVITE_ORDERLIST';
export const FETCH_INVITE_CODE = 'FETCH_INVITE_CODE';
export const CHANGE_TOP = 'CHANGE_FILTER_TOP';
export const SET_TOP = 'SET_FILTER_TOP';
export const SET_DATE = 'SET_DATE';
... ...