231 lines
6.2 KiB
Vue
231 lines
6.2 KiB
Vue
<template>
|
|
<view class="stat-wrapper">
|
|
<view class="time-header">
|
|
<block v-for="(v, i) in timeList" :key="i">
|
|
<view class="time-item" :class="{ 'selected-time': v.value == vdata.selectedTime }" @tap="switchTime(v.value)">{{ v.label }}</view>
|
|
</block>
|
|
</view>
|
|
<view class="custom-content" :class="{ 'selected-custom': vdata.selectedTime == 'custom' }">
|
|
<view class="start-time" :style="{ color: vdata.startTime ? '#000' : '#666' }" @tap="refStartTime.show">{{ vdata.startTime || '请选择开始时间' }}</view>
|
|
<view class="endTime-time" :style="{ color: vdata.endTime ? '#000' : '#666' }" @tap="refEndTime.show">{{ vdata.endTime || '请选择结束时间' }}</view>
|
|
</view>
|
|
<view class="amount-list">
|
|
<view class="amount-item">
|
|
<view class="amount-num">{{ (vdata.payStat.allAmount / 100).toFixed(2) }}</view>
|
|
成交金额
|
|
</view>
|
|
<view class="amount-item">
|
|
<view class="amount-num">{{ (vdata.payStat.payAmount / 100).toFixed(2) }}</view>
|
|
实收金额
|
|
</view>
|
|
<view class="amount-item">
|
|
<view class="amount-num">{{ vdata.payStat.payCount }} /{{ vdata.payStat.allCount }} </view>
|
|
成交笔数/总笔数
|
|
</view>
|
|
<view class="amount-item">
|
|
<view class="amount-num">{{ (vdata.payStat.refundAmount / 100).toFixed(2) }}</view>
|
|
退款金额
|
|
</view>
|
|
<view class="amount-item">
|
|
<view class="amount-num">{{ vdata.payStat.refundCount }}</view>
|
|
退款笔数
|
|
</view>
|
|
<view class="amount-item">
|
|
<view class="amount-num">{{ vdata.payStat.round }} %</view>
|
|
成功率
|
|
</view>
|
|
</view>
|
|
<view class="pay-title"> 支付方式 </view>
|
|
<block v-for="(v, i) in vdata.payList" :key="v.wayType">
|
|
<PayTypeCard v-bind="v" @upOrDown="upOrDown(v)" />
|
|
</block>
|
|
<view style="height: 60rpx"></view>
|
|
</view>
|
|
<xp-picker mode="ymdhi" ref="refStartTime" @confirm="timeConfirm($event, 'startTime')">
|
|
<view></view>
|
|
</xp-picker>
|
|
<xp-picker mode="ymdhi" ref="refEndTime" @confirm="timeConfirm($event, 'endTime')">
|
|
<view></view>
|
|
</xp-picker>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { reactive, ref } from 'vue'
|
|
import { $payTypeStat, $payTypeStatAll } from '@/http/apiManager'
|
|
import PayTypeCard from './components/PayTypeCard'
|
|
import dayjs from 'dayjs'
|
|
const timeList = [
|
|
{ label: '昨天', value: 'yesterday' },
|
|
{ label: '今天', value: 'today' },
|
|
{ label: '近7天', value: 'near2now_7' },
|
|
{ label: '近30天', value: 'near2yesterday_30' },
|
|
{ label: '自定义', value: 'custom' },
|
|
]
|
|
const vdata = reactive({
|
|
selectedTime: 'today',
|
|
payList: [],
|
|
payStat: {},
|
|
})
|
|
const refStartTime = ref(null)
|
|
const refEndTime = ref(null)
|
|
const params = {
|
|
method: 'wayCodeType',
|
|
queryDateRange: 'today',
|
|
}
|
|
const getPayType = () => {
|
|
$payTypeStat(params).then(({ bizData }) => {
|
|
bizData.records.forEach((v, i) => {
|
|
v.bgColor = uni.$J.dataMap.payImg(v.wayType).bgColor
|
|
v.rgba = uni.$J.dataMap.payImg(v.wayType).rgba
|
|
v.typeName = uni.$J.dataMap.payImg(v.wayType).title
|
|
if (i == 0) return (v.isShow = true)
|
|
v.isShow = false
|
|
})
|
|
vdata.payList = bizData.records
|
|
})
|
|
}
|
|
getPayType()
|
|
const getStatAll = () => {
|
|
$payTypeStatAll(params).then(({ bizData }) => {
|
|
vdata.payStat = bizData
|
|
})
|
|
}
|
|
getStatAll()
|
|
/****
|
|
* 切换 卡片收起 展开状态
|
|
* @param {v} Object 点击的卡片全部数据
|
|
* */
|
|
const upOrDown = (v) => {
|
|
v.isShow = true
|
|
vdata.payList.forEach((ite) => {
|
|
if (ite.wayType != v.wayType) {
|
|
ite.isShow = false
|
|
}
|
|
})
|
|
}
|
|
/***
|
|
* 切换时间选择器
|
|
* @param {val} STring 时间选择的 value 值
|
|
* val = custom 需要展示自定义 时间选择框
|
|
* */
|
|
const switchTime = (val) => {
|
|
vdata.selectedTime = val
|
|
if (val == 'custom') return
|
|
params.queryDateRange = val
|
|
getStatAll()
|
|
getPayType()
|
|
}
|
|
/**
|
|
* @param {e} Object 组件原生 回调 时间戳 日期
|
|
* @param {key} String vdata 对象的 key 值 赋值使用
|
|
* */
|
|
const timeConfirm = (e, key) => {
|
|
vdata[key] = dayjs(e.timestamp).format('YYYY-MM-DD hh:mm')
|
|
if (key == 'endTime' || (vdata.endTime != undefined && dayjs(vdata.startTime).isAfter(vdata.endTime))) {
|
|
params.queryDateRange = `customDateTime_${vdata.startTime + ':00'}_${vdata.endTime + ':00'}`
|
|
getStatAll()
|
|
getPayType()
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.stat-wrapper {
|
|
min-height: 100vh;
|
|
background-color: #ebf2ed;
|
|
.time-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: 20rpx;
|
|
view {
|
|
flex: 0 0 18%;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
height: 45rpx;
|
|
border-radius: 14rpx;
|
|
background-color: #d9dfda;
|
|
font-size: 18rpx;
|
|
color: #666;
|
|
}
|
|
.selected-time {
|
|
background-color: $v-primary;
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
.title {
|
|
font-size: 18rpx;
|
|
color: rgba($color: #fff, $alpha: 0.6);
|
|
}
|
|
.stat-num {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
color: #fff;
|
|
margin: 0 auto;
|
|
margin-top: 35rpx;
|
|
width: 65%;
|
|
height: 120rpx;
|
|
border-radius: 22rpx 22rpx 0 0;
|
|
background-color: $v-primary;
|
|
.num {
|
|
font-size: 35rpx;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
.amount-list {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: space-around;
|
|
align-items: center;
|
|
margin: 0 auto;
|
|
margin-top: 30rpx;
|
|
padding: 15rpx 0;
|
|
width: 92%;
|
|
// height: 110rpx;
|
|
background-color: $v-primary;
|
|
border-radius: 14rpx;
|
|
.amount-item {
|
|
flex: 0 0 33%;
|
|
margin: 15rpx 0;
|
|
text-align: center;
|
|
white-space: nowrap;
|
|
color: rgba($color: #fff, $alpha: 0.6);
|
|
font-size: 20rpx;
|
|
.amount-num {
|
|
margin-bottom: 15rpx;
|
|
color: #fff !important;
|
|
}
|
|
}
|
|
}
|
|
.pay-title {
|
|
margin-top: 35rpx;
|
|
margin-bottom: 15rpx;
|
|
margin-left: 30rpx;
|
|
font-size: 22rpx;
|
|
font-weight: 600;
|
|
}
|
|
.custom-content {
|
|
display: flex;
|
|
justify-content: space-around;
|
|
overflow: hidden;
|
|
margin-top: 30rpx;
|
|
margin-bottom: 60rpx;
|
|
max-height: 0;
|
|
transition: 0.3s linear;
|
|
view {
|
|
flex: 0 0 30%;
|
|
padding: 10rpx 0;
|
|
background-color: #ded7d7;
|
|
text-align: center;
|
|
border-radius: 10rpx;
|
|
font-size: 16rpx;
|
|
}
|
|
}
|
|
.selected-custom {
|
|
max-height: 20vh;
|
|
}
|
|
</style>
|