修改数据报表
parent
2bbc7ebc65
commit
82329ccc01
|
|
@ -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>
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue