源文件
This commit is contained in:
131
jeepay-ui-uapp-face/pages/stat/components/PayTypeCard.vue
Normal file
131
jeepay-ui-uapp-face/pages/stat/components/PayTypeCard.vue
Normal file
@@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<view class="type-card" :style="{ backgroundColor: rgba }">
|
||||
<view class="type-header" :style="{ backgroundColor: bgColor }" @tap="emits('upOrDown')">
|
||||
<view> {{ typeName }} </view>
|
||||
<view class="type-num">¥{{ (allAmount / 100).toFixed(2) }} /{{ allCount }}笔
|
||||
<image src="/static/iconImg/down.svg" style="transition: 0.3s linear" :class="{ 'img-up': !isShow }"
|
||||
mode="scaleToFill" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="type-main" :style="{ maxHeight: isShow ? '40vh' : '0' }">
|
||||
<view class="type-item">
|
||||
<view class="type-num">
|
||||
<view> ¥{{ (allAmount / 100).toFixed(2) }}</view>
|
||||
<view class="title"> 成交金额 </view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="type-item">
|
||||
<view class="type-num">
|
||||
<view> ¥{{ ((payAmount - refundAmount) / 100).toFixed(2) }}</view>
|
||||
<view class="title"> 实收金额</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="type-item">
|
||||
<view class="type-num">
|
||||
<view> ¥{{ payCount }}/{{ allCount }}</view>
|
||||
<view class="title"> 成交笔数/总笔数 </view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="type-item">
|
||||
<view class="type-num">
|
||||
<view> ¥{{ (refundAmount / 100).toFixed(2) }}</view>
|
||||
<view class="title"> 退款金额</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="type-item">
|
||||
<view class="type-num">
|
||||
<view> {{ refundCount }}</view>
|
||||
<view class="title"> 退款笔数 </view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="type-item">
|
||||
<view class="type-num">
|
||||
<view> {{ round }}%</view>
|
||||
<view class="title"> 成功率</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { reactive, ref } from 'vue'
|
||||
const emits = defineEmits(['upOrDown'])
|
||||
const props = defineProps({
|
||||
typeName: { type: String },
|
||||
allCount: { type: [String, Number] },
|
||||
allAmount: { type: [String, Number] },
|
||||
bgColor: { type: String },
|
||||
rgba: { type: String },
|
||||
isShow: { type: Boolean },
|
||||
refundAmount: { type: [String, Number] },
|
||||
round: { type: [String, Number] },
|
||||
payCount: { type: [String, Number] },
|
||||
payAmount: { type: [String, Number] },
|
||||
refundCount: { type: [String, Number] },
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.type-card {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
margin: 0 auto;
|
||||
box-sizing: border-box;
|
||||
width: 95%;
|
||||
|
||||
border-radius: 14rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.type-header {
|
||||
padding: 25rpx 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
|
||||
.type-num {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
image {
|
||||
margin-left: 10rpx;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.type-main {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
padding: 0 20rpx;
|
||||
overflow: hidden;
|
||||
// max-height: 0;
|
||||
transition: 0.3s linear;
|
||||
|
||||
.type-item {
|
||||
flex: 0 0 30%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
|
||||
.title {
|
||||
margin-top: 10rpx;
|
||||
color: rgba($color: #fff, $alpha: 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.img-up {
|
||||
transform: rotate(-180deg);
|
||||
}</style>
|
||||
230
jeepay-ui-uapp-face/pages/stat/stat.vue
Normal file
230
jeepay-ui-uapp-face/pages/stat/stat.vue
Normal file
@@ -0,0 +1,230 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user