9 changed files with 996 additions and 18514 deletions
-
18512package-lock.json
-
11src/js/api.js
-
12src/pages.json
-
458src/pages/collection/info/info.vue
-
223src/pages/collection/list/list.vue
-
4src/pages/index/index.vue
-
280src/pages/turnover/turnover.vue
-
BINsrc/static/images/icon/question_mark.png
-
10src/subpackage/device/pages/switch_manage/switch_manage.vue
18512
package-lock.json
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,458 @@ |
|||
<template> |
|||
<view class="collection-info"> |
|||
<view class="ci-header"> |
|||
<view class="ch-stadium"> |
|||
<view class="cs-txt">当前门店</view> |
|||
<picker :range="stadiumList" range-key="name" @change="storeChange"> |
|||
<view class="cs-picker"> |
|||
<input :value="curStadium.name || '-'" disabled /> |
|||
<image mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image> |
|||
</view> |
|||
</picker> |
|||
|
|||
</view> |
|||
<view class="ch-date-scene"> |
|||
<view class="cds-item"> |
|||
<view class="ci-txt">日期</view> |
|||
<view class="ci-frame ci-date"> |
|||
<input disabled :value="curDate || '-'" /> |
|||
<view></view> |
|||
<picker mode="date" @change="dateChange"> |
|||
<image mode="aspectFit" src="/static/images/icon/calendar.png"></image> |
|||
</picker> |
|||
|
|||
</view> |
|||
</view> |
|||
<view class="cds-item"> |
|||
<view class="ci-txt">场景</view> |
|||
<view class="ci-frame ci-scene"> |
|||
<picker class="cs-picker" :range="sceneList" range-key="name" @change="sceneChange"> |
|||
<view class="cp-picker-frame"> |
|||
<input disabled :value="curScene.name || '-'" /> |
|||
<image mode="aspectFit" src="/static/images/icon/arrow_b2.png" style="transform: rotateZ(90deg);"></image> |
|||
</view> |
|||
</picker> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
</view> |
|||
<view class="ci-tab"> |
|||
<view class="ct-item" @click="typeChange(0)"> |
|||
<view :class="[curType == 0?'active':'']">全部</view> |
|||
</view> |
|||
<view class="ct-item" @click="typeChange(1)"> |
|||
<view :class="[curType == 1?'active':'']">退款</view> |
|||
</view> |
|||
</view> |
|||
<view class="ci-total"> |
|||
收款{{ totalInfo.income_num || 0 }}笔(<text>¥{{ totalInfo.income_amount || 0 }}</text>) ,退款{{ totalInfo.refund_num || 0 }}笔(<text>¥{{ totalInfo.refund_amount || 0 }}</text>) |
|||
</view> |
|||
<view class="ci-ls"> |
|||
<block v-for="(e, i) in recordLs" :key="i"> |
|||
<view class="cl-item"> |
|||
<view class="ci-name"> |
|||
<view>{{ e.scene_name || '-' }}</view> |
|||
<view :class="e.amount<=0?'black': ''">{{ e.amount>0?'+':'' }}{{ e.amount || '-' }}</view> |
|||
</view> |
|||
<view class="ci-line"> |
|||
<view>{{ e.order_no || '-' }}</view> |
|||
<view v-if="e.amount<=0">{{ e.refund_desc || '-' }}</view> |
|||
</view> |
|||
<view class="ci-line"> |
|||
<view>{{ e.pay_time || '-' }}</view> |
|||
<view></view> |
|||
</view> |
|||
</view> |
|||
</block> |
|||
|
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { API } from '../../../js/api' |
|||
import { servers } from '../../../js/server' |
|||
import util from '../../../utils/util' |
|||
import { mapState } from 'vuex'; |
|||
export default { |
|||
|
|||
computed: { |
|||
...mapState(['brandInfo']), |
|||
}, |
|||
data(){ |
|||
return { |
|||
optionsQuery: { |
|||
// stadium_id_filter |
|||
// brand_id |
|||
}, |
|||
stadiumList: [], |
|||
curStadium: {}, |
|||
sceneList: [], |
|||
curScene: {}, |
|||
curDate: '', |
|||
curType: 0, // 0 -> 全部, 1 -> 退款; |
|||
|
|||
recordLs: [], |
|||
totalInfo: {}, |
|||
page: 1 |
|||
} |
|||
}, |
|||
onReachBottom(){ |
|||
let { curStadium, optionsQuery, curScene, curDate, curType, page } = this; |
|||
let _query = { |
|||
brand_id: optionsQuery.brand_id || '', |
|||
stadium_id: curStadium.val || '', |
|||
time_str: curDate, |
|||
scene: curScene.scene, |
|||
type: curType == 1 ? '退款' : '全部', |
|||
page: ++page |
|||
} |
|||
|
|||
this.getRecordLs(_query); |
|||
}, |
|||
onLoad(options){ |
|||
this.optionsQuery = options || {}; |
|||
|
|||
this.initPage(options); |
|||
}, |
|||
methods: { |
|||
typeChange(idx){ |
|||
this.curType = idx; |
|||
this.$nextTick(_=>this.refreshList()); |
|||
}, |
|||
async initPage(options){ |
|||
let _stadiumLs = await this.getStoreList(options.stadium_id_filter); |
|||
let _sceneLs = await this.getSceneList(); |
|||
this.curDate = util.formatDate({}); |
|||
this.$nextTick(_=>this.refreshList()); |
|||
}, |
|||
refreshList(){ |
|||
let { curStadium, optionsQuery, curScene, curDate, curType } = this; |
|||
this.page = 1; |
|||
this.recordLs = []; |
|||
|
|||
let _query = { |
|||
brand_id: optionsQuery.brand_id || '', |
|||
stadium_id: curStadium.val || '', |
|||
time_str: curDate, |
|||
scene: curScene.scene, |
|||
type: curType == 1 ? '退款' : '全部' |
|||
} |
|||
|
|||
this.getRecordLs(_query); |
|||
}, |
|||
dateChange(e){ |
|||
this.curDate = e.detail.value; |
|||
this.$nextTick(_=>this.refreshList()); |
|||
|
|||
}, |
|||
sceneChange(e){ |
|||
let { sceneList } = this; |
|||
this.curScene = sceneList[e.detail.value]; |
|||
this.$nextTick(_=>this.refreshList()); |
|||
}, |
|||
async storeChange(e){ |
|||
let { stadiumList } = this; |
|||
this.curStadium = stadiumList[e.detail.value] || {}; |
|||
await this.getSceneList(); |
|||
this.$nextTick(_=>this.refreshList()); |
|||
}, |
|||
getRecordLs({ |
|||
brand_id, |
|||
stadium_id = '', // 空字符全部 -1品牌收款 |
|||
time_str, // 日期y-m-d |
|||
scene, |
|||
type = '全部' , // 全部/退款 |
|||
page_size = 15, |
|||
page = 1, |
|||
}){ |
|||
let { optionsQuery } = this; |
|||
util.showLoad(); |
|||
return servers.get({ |
|||
url: API.consumeCountDetailLs, |
|||
data: { |
|||
brand_id, |
|||
stadium_id: stadium_id, |
|||
time_str, |
|||
page, |
|||
page_size, |
|||
scene, |
|||
type, |
|||
}, |
|||
failMsg: '加载店铺列表失败!', |
|||
|
|||
}) |
|||
.then(res=>{ |
|||
util.hideLoad(); |
|||
let _list = res.list || []; |
|||
this.totalInfo = res || {}; |
|||
if(page == 1)return this.recordLs = _list; |
|||
if(!_list.length)return util.showNone('没有更多!'); |
|||
this.page = page; |
|||
this.recordLs = [...this.recordLs, ..._list]; |
|||
|
|||
}) |
|||
}, |
|||
// 店铺列表 |
|||
getStoreList(stadium_id_filter = ''){ |
|||
let { optionsQuery } = this; |
|||
return servers.get({ |
|||
url: API.consumeCountStadiumList, |
|||
data: { |
|||
brand_id: optionsQuery.brand_id || '', |
|||
}, |
|||
failMsg: '加载店铺列表失败!', |
|||
|
|||
}) |
|||
.then(res=>{ |
|||
let _list = res || []; |
|||
let _cur = null; |
|||
// 页面传参 undefined => 'undefined' |
|||
if(stadium_id_filter != undefined&&stadium_id_filter != 'undefined'){ |
|||
let _fiLs = _list.filter(e=> e.val == stadium_id_filter); |
|||
if(_fiLs.length)_cur = _fiLs[0]; |
|||
} |
|||
|
|||
if(_cur&&_cur.val){ |
|||
this.curStadium = _cur; |
|||
}else{ |
|||
this.curStadium = _list[0] || {}; |
|||
} |
|||
return this.stadiumList = _list; |
|||
}) |
|||
}, |
|||
// 场景列表 |
|||
getSceneList(){ |
|||
let { optionsQuery, curStadium } = this; |
|||
return servers.get({ |
|||
url: API.consumeCountGetScene, |
|||
data: { |
|||
brand_id: optionsQuery.brand_id || '', |
|||
stadium_id: curStadium.val || '', |
|||
}, |
|||
failMsg: '加载场景列表失败!', |
|||
|
|||
}) |
|||
.then(res=>{ |
|||
let _list = res || []; |
|||
if(_list.length)this.curScene = _list[0] |
|||
return this.sceneList = _list; |
|||
}) |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import "~style/public.scss"; |
|||
page{ |
|||
background-color: #fff; |
|||
} |
|||
.collection-info{ |
|||
padding-bottom: 0upx; |
|||
padding-bottom: calc( 0upx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */ |
|||
padding-bottom: calc( 0upx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */ |
|||
.ci-header{ |
|||
padding: 26upx 24upx 0; |
|||
.ch-stadium{ |
|||
padding-bottom: 26upx; |
|||
@include centerFlex(space-between); |
|||
|
|||
.cs-txt{ |
|||
flex-shrink: 0; |
|||
flex-grow: 0; |
|||
margin-right: 20upx; |
|||
font-size: 28upx; |
|||
line-height: 40upx; |
|||
color: #9c9c9f; |
|||
} |
|||
picker{ |
|||
flex-grow: 1; |
|||
} |
|||
.cs-picker{ |
|||
padding: 0 20upx; |
|||
height: 92upx; |
|||
border-radius: 10upx; |
|||
background-color: #f2f1f6; |
|||
@include centerFlex(space-between); |
|||
>input{ |
|||
flex-grow: 1; |
|||
height: 100%; |
|||
font-size: 28upx; |
|||
color: #1a1a1a; |
|||
} |
|||
image{ |
|||
flex-grow: 0; |
|||
flex-shrink: 0; |
|||
width: 28upx; |
|||
height: 28upx; |
|||
transform: rotateZ(90deg); |
|||
} |
|||
} |
|||
} |
|||
.ch-date-scene{ |
|||
margin-bottom: 30upx; |
|||
@include centerFlex(space-between); |
|||
.cds-item{ |
|||
flex-grow: 0; |
|||
flex-shrink: 0; |
|||
@include centerFlex(flex-start); |
|||
.ci-txt{ |
|||
margin-right: 16upx; |
|||
line-height: 34upx; |
|||
font-size: 24upx; |
|||
color: #9c9c9f; |
|||
} |
|||
.ci-frame{ |
|||
height: 64upx; |
|||
border-radius: 10upx; |
|||
background-color: #f2f1f6; |
|||
} |
|||
.ci-date{ |
|||
padding: 0 16upx; |
|||
width: 240upx; |
|||
@include centerFlex(space-between); |
|||
>input{ |
|||
flex-grow: 1; |
|||
height: 100%; |
|||
font-size: 24upx; |
|||
color: #1a1a1a; |
|||
} |
|||
>view{ |
|||
flex-grow: 0; |
|||
flex-shrink: 0; |
|||
margin: 0 14upx; |
|||
height: 32upx; |
|||
width: 2upx; |
|||
background-color: #B2B2B2; |
|||
} |
|||
picker{ |
|||
flex-shrink: 0; |
|||
flex-grow: 0; |
|||
image{ |
|||
margin: 0; |
|||
padding: 0; |
|||
display: block; |
|||
height: 40upx; |
|||
width: 40upx; |
|||
} |
|||
} |
|||
|
|||
} |
|||
.ci-scene{ |
|||
.cs-picker{ |
|||
|
|||
} |
|||
.cp-picker-frame{ |
|||
padding: 0 20upx; |
|||
width: 264upx; |
|||
@include centerFlex(space-between); |
|||
input{ |
|||
flex-grow: 1; |
|||
height: 64upx; |
|||
font-size: 24upx; |
|||
color: #1a1a1a; |
|||
} |
|||
image{ |
|||
flex-shrink: 0; |
|||
flex-grow: 0; |
|||
margin-left: 16upx; |
|||
height: 28upx; |
|||
width: 28upx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
} |
|||
.ci-tab{ |
|||
@include centerFlex(center); |
|||
border-bottom: 2upx solid #D8D8D8; |
|||
.ct-item{ |
|||
flex-grow: 1; |
|||
@include centerFlex(center); |
|||
>view{ |
|||
position: relative; |
|||
display: inline-block; |
|||
text-align: center; |
|||
line-height: 110upx; |
|||
height: 110upx; |
|||
font-size: 32upx; |
|||
color: #9C9C9F; |
|||
&.active{ |
|||
color: $themeColor; |
|||
&::after{ |
|||
content: ''; |
|||
display: block; |
|||
position: absolute; |
|||
left: 50%; |
|||
bottom: 0; |
|||
transform: translateX(-50%); |
|||
width: 200%; |
|||
height: 8upx; |
|||
border-radius: 4upx; |
|||
background-color: $themeColor; |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
.ci-total{ |
|||
padding: 0 24upx; |
|||
line-height: 96upx; |
|||
font-size: 24upx; |
|||
color: #9C9C9F; |
|||
@include textHide(1); |
|||
>text{ |
|||
color: #F6843E; |
|||
} |
|||
|
|||
} |
|||
.ci-ls{ |
|||
padding: 0 30upx; |
|||
.cl-item{ |
|||
padding: 30upx 0; |
|||
&:not(:last-child){ |
|||
border-bottom: 2upx solid #D8D8D8; |
|||
} |
|||
.ci-name{ |
|||
margin-bottom: 8upx; |
|||
@include centerFlex(space-between); |
|||
>view{ |
|||
font-size: 32upx; |
|||
color: #1a1a1a; |
|||
width: 50%; |
|||
@include textHide(1); |
|||
&+view{ |
|||
text-align: right; |
|||
font-weight: 500; |
|||
color: #F6843E; |
|||
&.black{ |
|||
color: #1A1A1A; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.ci-line{ |
|||
@include centerFlex(space-between); |
|||
|
|||
>view{ |
|||
line-height: 34upx; |
|||
font-size: 24upx; |
|||
color: #9C9C9F; |
|||
@include textHide(1); |
|||
&+view{ |
|||
flex-shrink: 0; |
|||
max-width: 50%; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,223 @@ |
|||
<template> |
|||
<view class="collection-list"> |
|||
<view class="cl-date"> |
|||
<view class="cd-txt">收款日期</view> |
|||
<view class="cd-content"> |
|||
<input class="cc-ipt" disabled :value="dateStr" /> |
|||
<view class="cc-icon"></view> |
|||
<picker class="cc-img" mode="date" @change="timeChange"> |
|||
<image mode="aspectFit" src="/static/images/icon/calendar.png"></image> |
|||
</picker> |
|||
</view> |
|||
</view> |
|||
<view class="cl-list"> |
|||
<view class="cl-item" v-for="(e, i) in recordLs" :key="i" @click="toInfo(e)"> |
|||
<view class="ci-tit-name"> |
|||
<view class="ctn-name"> |
|||
<view>{{ e.income_record_name || '-' }}</view> |
|||
<image mode="aspectFit" @click.stop="showModal(e)" src="/static/images/icon/question_mark.png"></image> |
|||
</view> |
|||
<image mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image> |
|||
</view> |
|||
<view class="ci-price"> |
|||
<text>¥</text>{{ e.count_type_actual_income_amount || 0 }}<text></text> |
|||
</view> |
|||
<view class="ci-tip">日总收入</view> |
|||
<view class="ci-preview"> |
|||
<view class="cp-line cp-first"> |
|||
<view><text class="margin">线上 ¥{{ e.online_actual_income_amount || 0 }}</text></view> |
|||
<view><text class="margin">线下 ¥{{ e.offline_actual_income_amount || 0 }}</text></view> |
|||
</view> |
|||
<view class="cp-line"> |
|||
<view><text class="margin">收款{{ e.online_income_num || 0 }}笔</text>(¥{{ e.online_income_amount || 0 }}) </view> |
|||
<view><text class="margin">收款{{ e.offline_income_num || 0 }}笔</text>(¥{{ e.offline_income_amount || 0 }})</view> |
|||
</view> |
|||
<view class="cp-line"> |
|||
<view><text class="margin">退款{{ e.online_refund_num || 0 }}笔</text>(<text class="orange">¥{{ e.online_refund_amount || 0 }}</text>) </view> |
|||
<view><text class="margin">退款{{ e.offline_refund_num || 0 }}笔</text>(<text class="orange">¥{{ e.offline_refund_amount || 0 }}</text>)</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import { API } from '../../../js/api' |
|||
import { servers } from '../../../js/server' |
|||
import util from '../../../utils/util' |
|||
import { mapState } from 'vuex'; |
|||
import numeral from 'numeral'; |
|||
export default { |
|||
computed: { |
|||
...mapState(['brandInfo']), |
|||
}, |
|||
data(){ |
|||
return { |
|||
dateStr: '', |
|||
recordLs: [] |
|||
} |
|||
}, |
|||
onLoad(){ |
|||
let _dateStr = util.formatDate({}); |
|||
this.dateStr = _dateStr; |
|||
this.getRecordList(_dateStr); |
|||
}, |
|||
methods: { |
|||
toInfo(e){ |
|||
let _qyStr = `stadium_id_filter=${e.stadium_id_filter}&brand_id=${e.brand_id}` |
|||
util.routeTo(`/pages/collection/info/info?${_qyStr}`, 'nT') |
|||
}, |
|||
showModal(e){ |
|||
util.showModal({ |
|||
title: '提示', |
|||
content: e.income_record_tips || '-' |
|||
}) |
|||
}, |
|||
timeChange(e){ |
|||
console.warn(e); |
|||
let _date = e.detail.value || ''; |
|||
this.dateStr = _date; |
|||
this.recordLs = []; |
|||
this.getRecordList(_date); |
|||
}, |
|||
getRecordList(time = ''){ |
|||
let { brandInfo } = this; |
|||
util.showLoad(); |
|||
servers.get({ |
|||
url: API.consumeCountLs, |
|||
data: { |
|||
brand_id: brandInfo.brand.id, |
|||
time_str: time |
|||
}, |
|||
failMsg: '加载列表失败!' |
|||
}) |
|||
.then(res=>{ |
|||
util.hideLoad(); |
|||
let _list = res.list || []; |
|||
this.recordLs = _list; |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang='scss'> |
|||
@import '~style/public.scss'; |
|||
.cl-date{ |
|||
padding: 26upx 24upx; |
|||
@include centerFlex(space-between); |
|||
.cd-txt{ |
|||
flex-shrink: 0; |
|||
flex-grow: 0; |
|||
margin-right: 20upx; |
|||
line-height: 40upx; |
|||
font-size: 28upx; |
|||
color: #9C9C9F; |
|||
} |
|||
.cd-content{ |
|||
flex-grow: 1; |
|||
padding: 26upx 20upx; |
|||
border-radius: 10upx; |
|||
background-color: #fff; |
|||
@include centerFlex(space-between); |
|||
.cc-ipt{ |
|||
flex-grow: 1; |
|||
height: 100%; |
|||
font-size: 28upx; |
|||
color: #1a1a1a; |
|||
} |
|||
.cc-icon{ |
|||
flex-shrink: 0; |
|||
flex-grow: 0; |
|||
margin: 0 17upx; |
|||
height: 40upx; |
|||
width: 2upx; |
|||
background-color: #f2f1f6; |
|||
} |
|||
.cc-img{ |
|||
flex-shrink: 0; |
|||
flex-grow: 0; |
|||
image{ |
|||
width: 40upx; |
|||
height: 40upx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
.cl-list{ |
|||
padding: 0 24upx 60upx; |
|||
.cl-item{ |
|||
margin-bottom: 24upx; |
|||
padding: 30upx; |
|||
height: 432upx; |
|||
border-radius: 10upx; |
|||
background-color: #fff; |
|||
.ci-tit-name{ |
|||
margin-bottom: 42upx; |
|||
@include centerFlex(space-between); |
|||
.ctn-name{ |
|||
>view{ |
|||
line-height: 40upx; |
|||
font-size: 28upx; |
|||
color: #1a1a1a; |
|||
@include textHide(1); |
|||
} |
|||
@include centerFlex(flex-start); |
|||
} |
|||
image{ |
|||
flex-shrink: 0; |
|||
flex-grow: 0; |
|||
margin-left: 12upx; |
|||
width: 28upx; |
|||
height: 28upx; |
|||
} |
|||
} |
|||
.ci-price{ |
|||
text-align: center; |
|||
font-size: 64upx; |
|||
font-weight: 500; |
|||
color: #1a1a1a; |
|||
@include textHide(1); |
|||
>text{ |
|||
font-size: 32upx; |
|||
} |
|||
} |
|||
.ci-tip{ |
|||
line-height: 40upx; |
|||
text-align: center; |
|||
font-size: 28upx; |
|||
color: #9c9c9f; |
|||
} |
|||
.ci-preview{ |
|||
padding-top: 38upx; |
|||
.cp-line{ |
|||
@include centerFlex(space-between); |
|||
>view{ |
|||
flex-grow: 0; |
|||
flex-shrink: 0; |
|||
width: 49%; |
|||
line-height: 32upx; |
|||
font-size: 24upx; |
|||
color: #9c9c9f; |
|||
@include textHide(1); |
|||
.margin{ |
|||
margin-right: 10upx; |
|||
} |
|||
.orange{ |
|||
color: #F6843E; |
|||
} |
|||
} |
|||
} |
|||
.cp-first{ |
|||
margin-bottom: 24upx; |
|||
>view{ |
|||
font-size: 28upx; |
|||
font-weight: 500; |
|||
color: #1A1A1A; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
After Width: 56 | Height: 56 | Size: 1023 B |
Write
Preview
Loading…
Cancel
Save
Reference in new issue