修改数据报表

main
unknown 2024-05-28 13:05:37 +08:00
parent 2bbc7ebc65
commit 82329ccc01
2 changed files with 419 additions and 11 deletions

View File

@ -0,0 +1,334 @@
<template>
<view>
<CuNavbar :isBack="false" title="数据报表"></CuNavbar>
<uv-sticky
customNavHeight="44px"
:offset-top="offsetTop"
bgColor="#fff"
v-if="checkPermission(['admin'])"
>
<StoreDown color="#333333" @change="storeChange"></StoreDown>
</uv-sticky>
<view class="card">
<view class="headBox">
<uv-tabs
:lineColor="'#ee2c37'"
:list="tabsList"
:scrollable="false"
:current="tabIndex"
keyName="label"
@change="tabChange"
></uv-tabs>
<view class="text-center text-28rpx py-4rpx" v-if="tabIndex != 0"
>{{ currentC.start }} {{ currentC.end }}
</view>
<view class="text-center text-28rpx" v-else>{{ currentC.start }}</view>
<view class="flex my-20rpx items-center table">
<view class="text-center flex-1 tr">
<view class="flex-center h-80rpx">销售金额</view>
<view class="font-600 flex-center h-80rpx">{{ ledger.sales }}</view>
</view>
<view class="text-center flex-1 tr">
<view
class="flex-center h-80rpx"
v-if="isLotteryStore || checkPermission(['admin'])"
>
<view>兑奖金额</view>
</view>
<view class="flex-center h-80rpx" v-else></view>
<view class="font-600 flex-center h-80rpx">{{
ledger.expenditure
}}</view>
</view>
<view class="text-center flex-1 tr">
<view class="flex-center h-80rpx">销售涨幅</view>
<view
class="font-600 flex-center h-80rpx"
:class="[
ledger.sales_growth_rate > 0 ? 'text-primary' : 'text-green',
]"
>{{ ledger.sales_growth_rate }}%</view
>
</view>
</view>
<uv-tabs
@change="tabChange1"
:lineColor="'#ee2c37'"
:list="[{ name: '销售统计' }, { name: '门店统计' }]"
:scrollable="false"
:current="tabIndex1"
></uv-tabs>
</view>
<template v-if="tabIndex1 == 0">
<List0 :height="boxHeight" :list="list"></List0>
</template>
<template v-if="tabIndex1 == 1">
<List1 :list="list"></List1>
</template>
</view>
</view>
</template>
<script setup>
import StoreDown from '@/pages/home/components/store-down.vue'
import CuNavbar from '@/components/cu-navbar/index'
import { computed, reactive, ref } from 'vue'
import { timeFormat } from '@climblee/uv-ui/libs/function/index'
import { onShow, onReady } from '@dcloudio/uni-app'
import { http } from '@/utils/request'
import List0 from './components/list0.vue'
import List1 from './components/list1.vue'
import checkPermission from '@/utils/permission'
import dayjs from 'dayjs'
import { sys } from '@climblee/uv-ui/libs/function/index'
import { useUserStore } from '@/store/modules/user'
const userStore = useUserStore()
const getRect = (selector, all) => {
return new Promise((resolve) => {
uni
.createSelectorQuery()
[all ? 'selectAll' : 'select'](selector)
.boundingClientRect((rect) => {
if (all && Array.isArray(rect) && rect.length) {
resolve(rect)
}
if (!all && rect) {
resolve(rect)
}
})
.exec()
})
}
const isLotteryStore = computed(
() => userStore.userInfo?.store?.is_lottery_store
)
const tabIndex1 = ref(0)
const tabIndex = ref(0)
const tabsList = ref(generateTimeArrayWithLastPeriod())
const list = ref([])
const boxHeight = ref(0)
const currentTabs = computed(() => tabsList.value[tabIndex.value])
const currentC = computed(() => {
const ob = currentTabs.value.current
return {
start: timeFormat(ob.startDate),
end: timeFormat(ob.endDate),
}
})
const currentL = computed(() => {
const ob = currentTabs.value.lastPeriod
return {
start: timeFormat(ob.startDate),
end: timeFormat(ob.endDate),
}
})
const offsetTop = computed(() => {
return sys().statusBarHeight
})
const shoreInfo = ref({})
if (!checkPermission(['admin'])) {
shoreInfo.value = { store_id: userStore?.userInfo?.store?.id }
}
const result = ref([])
const ledger = ref({
expenditure: '0',
sales: '0',
sales_growth_rate: '0',
})
const activeName = ref('area')
onShow(() => {
getCount()
getList()
})
onReady(() => {
getBox()
})
const getBox = async () => {
getRect('.headBox').then((res) => {
const th = checkPermission(['admin']) ? 44 : 0
boxHeight.value =sys().windowHeight - res.height - th - 44 - 20 - sys().statusBarHeight - 3
})
}
const storeChange = (e) => {
shoreInfo.value = e
getCount()
getList()
}
const getCount = async () => {
const resData = await http.get('/statistics/ledger', {
params: {
start_at: currentC.value.start,
end_at: currentC.value.end,
before_start_at: currentL.value.start,
before_end_at: currentL.value.end,
...shoreInfo.value,
},
})
ledger.value = resData
}
function generateTimeArrayWithLastPeriod() {
const today = dayjs()
const yesterday = today.subtract(1, 'day')
let currentWeekStart = today.startOf('week').add(1, 'day') //
if (today.isBefore(currentWeekStart, 'day')) {
currentWeekStart = currentWeekStart.subtract(1, 'week')
}
const currentWeekEnd = today
let lastWeekStart = currentWeekStart.subtract(1, 'week')
const lastWeekEnd = currentWeekStart.subtract(1, 'day')
let currentMonthStart = today.startOf('month')
if (today.isBefore(currentMonthStart, 'day')) {
currentMonthStart = currentMonthStart.subtract(1, 'month')
}
const currentMonthEnd = today.endOf('day') //
let lastMonthStart = currentMonthStart.subtract(1, 'month')
const lastMonthEnd = currentMonthStart.subtract(1, 'day')
const timeArray = [
generateTimeRange('昨日', yesterday),
generateTimeRange('本周', currentWeekStart, currentWeekEnd),
generateTimeRange('上周', lastWeekStart, lastWeekEnd),
generateTimeRange('本月', currentMonthStart, currentMonthEnd),
generateTimeRange('上月', lastMonthStart, lastMonthEnd),
]
const lastPeriodTimeRanges = {}
//
timeArray.forEach((timeRange) => {
switch (timeRange.label) {
case '昨日':
lastPeriodTimeRanges['昨日'] = {
startDate: dayjs(timeRange.current.startDate)
.subtract(1, 'day')
.toDate(),
endDate: dayjs(timeRange.current.endDate).subtract(1, 'day').toDate(),
}
break
case '本周':
lastPeriodTimeRanges['本周'] = {
startDate: dayjs(timeRange.current.startDate)
.subtract(1, 'week')
.toDate(),
endDate: dayjs(timeRange.current.endDate)
.subtract(1, 'week')
.toDate(),
}
break
case '上周':
lastPeriodTimeRanges['上周'] = {
startDate: dayjs(timeRange.current.startDate)
.subtract(1, 'week')
.toDate(),
endDate: dayjs(timeRange.current.endDate)
.subtract(1, 'week')
.toDate(),
}
break
case '本月':
lastPeriodTimeRanges['本月'] = {
startDate: dayjs(timeRange.current.startDate)
.subtract(1, 'month')
.toDate(),
endDate: dayjs(timeRange.current.endDate)
.subtract(1, 'month')
.toDate(),
}
break
case '上月':
lastPeriodTimeRanges['上月'] = {
startDate: dayjs(timeRange.current.startDate)
.subtract(1, 'month')
.toDate(),
endDate: dayjs(timeRange.current.endDate)
.subtract(1, 'month')
.endOf('month'),
}
break
default:
break
}
})
// timeArray lastPeriod
timeArray.forEach((timeRange) => {
timeRange.lastPeriod = lastPeriodTimeRanges[timeRange.label]
})
return timeArray
}
function generateTimeRange(label, startDate, endDate) {
return {
label,
current: {
startDate: startDate.toDate(),
endDate: (endDate || startDate).toDate(),
},
lastPeriod: { startDate: null, endDate: null },
}
}
const tabChange = (e) => {
list.value = []
tabIndex.value = e.index
getCount()
getList()
}
const tabChange1 = (e) => {
list.value = []
tabIndex1.value = e.index
getList()
}
const getList = async () => {
const url = tabIndex1.value == 0 ? '/statistics/sales' : '/statistics/stores'
let params = {
start_at: currentC.value.start,
end_at: currentC.value.end,
}
if (tabIndex1.value == 0) {
params = {
...params,
...shoreInfo.value,
}
}
const resData = await http.get(url, {
params: params,
})
list.value = resData
}
</script>
<style lang="scss">
.table {
display: flex;
// border: 1px solid;
}
.tr {
border: 0.5px solid #f5f5f5;
}
</style>

View File

@ -21,10 +21,11 @@
@change="tabChange"
></uv-tabs>
<view class="text-center text-28rpx py-4rpx" v-if="tabIndex != 0"
>{{ currentC.start }} {{ currentC.end }}
<view class="h-40rpx flex-center" @click="openCalendars">
<view class="text-center text-28rpx py-4rpx"
>{{ showDate }}
</view>
</view>
<view class="text-center text-28rpx" v-else>{{ currentC.start }}</view>
<view class="flex my-20rpx items-center table">
<view class="text-center flex-1 tr">
@ -56,7 +57,6 @@
>
</view>
</view>
<uv-tabs
@change="tabChange1"
:lineColor="'#ee2c37'"
@ -72,6 +72,17 @@
<List1 :list="list"></List1>
</template>
</view>
<uv-calendars
ref="calendars"
mode="range"
title="选择日期"
start-text="开始"
end-text="结束"
:date="selected"
:allowSameDay="true"
@confirm="confirm"
/>
</view>
</template>
<script setup>
@ -92,7 +103,6 @@ const userStore = useUserStore()
const getRect = (selector, all) => {
return new Promise((resolve) => {
uni
.createSelectorQuery()
[all ? 'selectAll' : 'select'](selector)
@ -110,12 +120,15 @@ const getRect = (selector, all) => {
const isLotteryStore = computed(
() => userStore.userInfo?.store?.is_lottery_store
)
const selected = ref(null)
const calendars = ref(null)
const tabIndex1 = ref(0)
const tabIndex = ref(0)
const tabsList = ref(generateTimeArrayWithLastPeriod())
const list = ref([])
const boxHeight = ref(0)
const currentTabs = computed(() => tabsList.value[tabIndex.value])
const isCalendar = ref(false)
const currentC = computed(() => {
const ob = currentTabs.value.current
return {
@ -123,6 +136,17 @@ const currentC = computed(() => {
end: timeFormat(ob.endDate),
}
})
const showDate = computed(() => {
let start = currentC.value.start
let end = currentC.value.end
if(isCalendar.value){
start = selected.value[0]
end = selected.value[1]
}
if(start===end) return start
return `${start}${end}`
})
const currentL = computed(() => {
const ob = currentTabs.value.lastPeriod
return {
@ -140,7 +164,7 @@ if (!checkPermission(['admin'])) {
shoreInfo.value = { store_id: userStore?.userInfo?.store?.id }
}
const result = ref([])
const ledger = ref({
expenditure: '0',
sales: '0',
@ -158,10 +182,40 @@ onReady(() => {
getBox()
})
const confirm = ({ range }) => {
isCalendar.value = true
const { before, after } = range
selected.value = [before, after]
getCount()
getList()
}
function calculatePreviousPeriodByDays(startDate, endDate) {
const start = dayjs(startDate)
const end = dayjs(endDate)
//
const daysDiff = end.diff(start, 'day') + 1
//
const prevEnd = start.subtract(1, 'day')
const prevStart = prevEnd.subtract(daysDiff - 1, 'day')
return {
previousStart: prevStart.format('YYYY-MM-DD'),
previousEnd: prevEnd.format('YYYY-MM-DD'),
}
}
const openCalendars = () => {
calendars.value.open()
}
const getBox = async () => {
getRect('.headBox').then((res) => {
const th = checkPermission(['admin']) ? 44 : 0
boxHeight.value =sys().windowHeight - res.height - th - 44 - 20 - sys().statusBarHeight - 3
boxHeight.value =
sys().windowHeight - res.height - th - 44 - 20 - sys().statusBarHeight - 3
})
}
@ -172,12 +226,23 @@ const storeChange = (e) => {
}
const getCount = async () => {
const params = {
start_at: currentC.value.start,
end_at: currentC.value.end,
before_start_at: currentL.value.start,
before_end_at: currentL.value.end,
}
if(isCalendar.value) {
params.start_at = selected.value[0]
params.end_at = selected.value[1]
const { previousStart, previousEnd } = calculatePreviousPeriodByDays(params.start_at, params.end_at)
params.before_start_at = previousStart
params.before_end_at = previousEnd
}
const resData = await http.get('/statistics/ledger', {
params: {
start_at: currentC.value.start,
end_at: currentC.value.end,
before_start_at: currentL.value.start,
before_end_at: currentL.value.end,
...params,
...shoreInfo.value,
},
})
@ -292,8 +357,10 @@ function generateTimeRange(label, startDate, endDate) {
}
const tabChange = (e) => {
isCalendar.value = false
list.value = []
tabIndex.value = e.index
selected.value = [currentC.value.start, currentC.value.end]
getCount()
getList()
}
@ -310,6 +377,13 @@ const getList = async () => {
start_at: currentC.value.start,
end_at: currentC.value.end,
}
if(isCalendar.value) {
params.start_at = selected.value[0]
params.end_at = selected.value[1]
}
if (tabIndex1.value == 0) {
params = {
...params,