(修改了交易统计页面的样式和数据展示逻辑)

This commit is contained in:
mkm 2024-08-02 17:44:19 +08:00
parent 8e484b6c4d
commit 2fa176e2e2
2 changed files with 239 additions and 99 deletions

View File

@ -23,6 +23,28 @@
@change="resetPage" @change="resetPage"
/> />
</el-form-item> --> </el-form-item> -->
<el-form-item label="门店" prop="store_id" v-if="queryParams.is_all == 1">
<!-- <el-input class="w-[280px]" v-model="queryParams.store_name" clearable placeholder="请输入门店id" /> -->
<el-select
v-model="queryParams.store_id"
filterable
remote
reserve-keyword
placeholder="输入门店名称搜索"
remote-show-suffix
:remote-method="remoteMethod"
:loading="storeloading"
style="width: 240px"
@change="resetPage"
>
<el-option
v-for="item in storeList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="" prop="create_time"> <el-form-item label="" prop="create_time">
<daterange-picker <daterange-picker
v-model:startTime="queryParams.start_time" v-model:startTime="queryParams.start_time"
@ -125,6 +147,7 @@ import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback' import feedback from '@/utils/feedback'
import { apiStoreCategoryLists } from '@/api/store_category' import { apiStoreCategoryLists } from '@/api/store_category'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { apiSystemStoreLists } from '@/api/system_store'
const route = useRoute() const route = useRoute()
@ -133,9 +156,31 @@ const detailsRef = ref(null)
const queryParams = reactive({ const queryParams = reactive({
start_time: '', start_time: '',
end_time: '', end_time: '',
is_all: '' is_all: '',
store_id: ''
}) })
const storeloading = ref(false)
const storeList = ref([])
const remoteMethod = (e = '') => {
storeloading.value = true
apiSystemStoreLists({
name: e,
page_size: 50
})
.then((res) => {
storeList.value = res.lists
setTimeout(() => {
storeloading.value = false
}, 300)
})
.catch((err) => {
setTimeout(() => {
storeloading.value = false
}, 300)
})
}
// //
const selectData = ref<any[]>([]) const selectData = ref<any[]>([])

View File

@ -6,40 +6,64 @@
<div class="text-2xl">今日订单金额</div> <div class="text-2xl">今日订单金额</div>
<div> <div>
<span class="text-[12px]">¥</span> <span class="text-[12px]">¥</span>
<span class="text-2xl">{{ leftInfo.money || '0.00' }}</span> <span class="text-2xl">{{ leftInfo.money || '0.00' }}</span>
</div> </div>
<v-charts style="height: 200px;" :option="leftOption" :autoresize="true"></v-charts> <v-charts
style="height: 200px"
:option="leftOption"
:autoresize="true"
></v-charts>
</div> </div>
<div class="w-[1px] bg-[#ccc] mr-4"></div> <div class="w-[1px] bg-[#ccc] mr-4"></div>
<div class="flex-1 flex"> <div class="flex-1 flex">
<div class="flex-1"> <div class="flex-1">
<div class="text-1xl">{{ rightInfo1[0]?.name }}<span class="ml-2 text-[18px]">{{ rightInfo1[0]?.now_money }}</span></div> <div class="text-1xl">
<div class="text-[12px]"> {{ rightInfo1[0]?.name
<span class="text-info">昨日: {{rightInfo1[0]?.last_money}}</span> }}<span class="ml-2 text-[18px]">{{ rightInfo1[0]?.now_money }}</span>
<span class="text-info ml-2">日环比: </span>
<span class="text-success">{{rightInfo1[0]?.rate}}%</span>
</div> </div>
<v-charts style="height: 160px;margin-bottom: 20px;" :option="rightOption1" :autoresize="true"></v-charts>
<div class="text-1xl">{{ rightInfo2[0]?.name }}<span class="ml-2 text-[18px]">{{ rightInfo2[0]?.now_money }}</span></div>
<div class="text-[12px]"> <div class="text-[12px]">
<span class="text-info">上月: {{rightInfo2[0]?.last_money}}</span> <span class="text-info">昨日: {{ rightInfo1[0]?.last_money }}</span>
<span class="text-info ml-2">日环比: </span>
<span class="text-success">{{ rightInfo1[0]?.rate }}%</span>
</div>
<v-charts
style="height: 160px; margin-bottom: 20px"
:option="rightOption1"
:autoresize="true"
></v-charts>
<div class="text-1xl">
{{ rightInfo2[0]?.name
}}<span class="ml-2 text-[18px]">{{ rightInfo2[0]?.now_money }}</span>
</div>
<div class="text-[12px]">
<span class="text-info">上月: {{ rightInfo2[0]?.last_money }}</span>
<span class="text-info ml-2">月环比: </span> <span class="text-info ml-2">月环比: </span>
<span class="text-success">{{rightInfo2[0]?.rate}}%</span> <span class="text-success">{{ rightInfo2[0]?.rate }}%</span>
</div> </div>
</div> </div>
<div class="flex-1"> <div class="flex-1">
<div class="text-1xl">{{ rightInfo1[1]?.name }}<span class="ml-2 text-[18px]">{{ rightInfo1[1]?.now_money }}</span></div> <div class="text-1xl">
<div class="text-[12px]"> {{ rightInfo1[1]?.name
<span class="text-info">昨日: {{rightInfo1[1]?.last_money}}</span> }}<span class="ml-2 text-[18px]">{{ rightInfo1[1]?.now_money }}</span>
<span class="text-info ml-2">日环比: </span>
<span class="text-success">{{rightInfo1[1]?.rate}}%</span>
</div> </div>
<v-charts style="height: 160px;margin-bottom: 20px;" :option="rightOption2" :autoresize="true"></v-charts>
<div class="text-1xl">{{ rightInfo2[1]?.name }}<span class="ml-2 text-[18px]">{{ rightInfo2[1]?.now_money }}</span></div>
<div class="text-[12px]"> <div class="text-[12px]">
<span class="text-info">上月: {{rightInfo2[1]?.last_money}}</span> <span class="text-info">昨日: {{ rightInfo1[1]?.last_money }}</span>
<span class="text-info ml-2">日环比: </span>
<span class="text-success">{{ rightInfo1[1]?.rate }}%</span>
</div>
<v-charts
style="height: 160px; margin-bottom: 20px"
:option="rightOption2"
:autoresize="true"
></v-charts>
<div class="text-1xl">
{{ rightInfo2[1]?.name
}}<span class="ml-2 text-[18px]">{{ rightInfo2[1]?.now_money }}</span>
</div>
<div class="text-[12px]">
<span class="text-info">上月: {{ rightInfo2[1]?.last_money }}</span>
<span class="text-info ml-2">月环比: </span> <span class="text-info ml-2">月环比: </span>
<span class="text-success">{{rightInfo2[1]?.rate}}%</span> <span class="text-success">{{ rightInfo2[1]?.rate }}%</span>
</div> </div>
</div> </div>
</div> </div>
@ -50,23 +74,52 @@
<span class="text-2xl">交易概况</span> <span class="text-2xl">交易概况</span>
<div class="flex items-center text-sm"> <div class="flex items-center text-sm">
<span class="mr-4">时间筛选: </span> <span class="mr-4">时间筛选: </span>
<el-date-picker v-model="startEndTime" type="daterange" range-separator="" start-placeholder="开始日期" <el-date-picker
end-placeholder="结束日期" unlink-panels :shortcuts="shortcuts" @change="getData" /> v-model="startEndTime"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
unlink-panels
:shortcuts="shortcuts"
@change="getData"
/>
<el-button type="primary" class="ml-4" @click="getData">查询</el-button> <el-button type="primary" class="ml-4" @click="getData">查询</el-button>
</div> </div>
</div> </div>
<div class="flex flex-wrap"> <div class="flex flex-wrap">
<div class="w-1/5 flex mb-6" v-for="(item, index) in visitorOption.series" :key="index"> <div
class="w-1/5 flex mb-6"
v-for="(item, index) in visitorOption.series"
:key="index"
>
<div class="mr-2"> <div class="mr-2">
<div class="rounded-full p-2" :style="{ 'background-color': colorList[index % 4] }"> <div
class="rounded-full p-2"
:style="{ 'background-color': colorList[index % 4] }"
>
<iconfont :iconName="iconList[index]" white className="text-6xl" /> <iconfont :iconName="iconList[index]" white className="text-6xl" />
</div> </div>
</div> </div>
<div> <div>
<div class="text-info">{{ item.name }}</div> <div class="text-info">
{{ item.name }}
<el-tooltip
class="box-item"
effect="dark"
:content="item.desc"
placement="top-start"
>
<el-icon><Warning /></el-icon>
</el-tooltip>
</div>
<div class="text-6xl">{{ item.money }}</div> <div class="text-6xl">{{ item.money }}</div>
<div class="text-info">环比增长: <span :class="item.rate > 0 ? 'text-success' : 'text-danger'">{{ <div class="text-info">
item.rate }}%</span></div> 环比增长:
<span :class="item.rate > 0 ? 'text-success' : 'text-danger'"
>{{ item.rate }}%</span
>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -78,7 +131,12 @@
</template> </template>
<script lang="ts" setup name="statistics_user"> <script lang="ts" setup name="statistics_user">
import { apiGetUserBasic, apiGetUserTrend, apiGetBottomTrade, apiGetTopTrade } from '@/api/workbench' import {
apiGetUserBasic,
apiGetUserTrend,
apiGetBottomTrade,
apiGetTopTrade
} from '@/api/workbench'
import moment from 'moment' import moment from 'moment'
import vCharts from 'vue-echarts' import vCharts from 'vue-echarts'
@ -90,7 +148,7 @@ const shortcuts = [
const start = new Date() const start = new Date()
start.setDate(start.getDate() - 7) start.setDate(start.getDate() - 7)
return [start, end] return [start, end]
}, }
}, },
{ {
text: '本月', text: '本月',
@ -101,7 +159,7 @@ const shortcuts = [
end.setMonth(end.getMonth() + 1) end.setMonth(end.getMonth() + 1)
end.setDate(0) end.setDate(0)
return [start, end] return [start, end]
}, }
}, },
{ {
text: '近一月', text: '近一月',
@ -110,7 +168,7 @@ const shortcuts = [
const start = new Date() const start = new Date()
start.setMonth(start.getMonth() - 1) start.setMonth(start.getMonth() - 1)
return [start, end] return [start, end]
}, }
}, },
{ {
text: '近三月', text: '近三月',
@ -119,8 +177,8 @@ const shortcuts = [
const start = new Date() const start = new Date()
start.setMonth(start.getMonth() - 3) start.setMonth(start.getMonth() - 3)
return [start, end] return [start, end]
}, }
}, }
] ]
// //
@ -174,11 +232,11 @@ const optionModel = {
type: 'cross' type: 'cross'
}, },
formatter: (params) => { formatter: (params) => {
let str = `<p><b>${params[0].name}点</b></p>`; let str = `<p><b>${params[0].name}点</b></p>`
params.forEach((item) => { params.forEach((item) => {
str += `<p><span style="display:inline-block;width:8px;height:4px;background-color:${item.color};"></span> ${item.seriesName}: <strong>${item.value}</strong></p>`; str += `<p><span style="display:inline-block;width:8px;height:4px;background-color:${item.color};"></span> ${item.seriesName}: <strong>${item.value}</strong></p>`
}); })
return str; return str
} }
}, },
grid: { grid: {
@ -198,13 +256,13 @@ const optionModel = {
boundaryGap: false, boundaryGap: false,
// data: ['03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '00', '01', '02'], // data: ['03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '00', '01', '02'],
axisLabel: { axisLabel: {
show: false, // x show: false // x
}, },
axisTick: { axisTick: {
show: false, // x 线 show: false // x 线
}, },
axisLine: { axisLine: {
show: false, // x 线 show: false // x 线
}, },
grid: { grid: {
show: false show: false
@ -219,18 +277,18 @@ const optionModel = {
show: false show: false
}, },
axisLabel: { axisLabel: {
show: false, // x show: false // x
}, },
axisTick: { axisTick: {
show: false, // x 线 show: false // x 线
}, },
axisLine: { axisLine: {
show: false, // x 线 show: false // x 线
}, },
grid: { grid: {
show: false show: false
} }
}, }
], ],
series: [ series: [
{ {
@ -240,7 +298,7 @@ const optionModel = {
smooth: true, smooth: true,
symbol: 'none', // symbol: 'none', //
itemStyle: { itemStyle: {
color: '#ccc', color: '#ccc'
}, },
areaStyle: { areaStyle: {
color: { color: {
@ -250,14 +308,19 @@ const optionModel = {
y: 0, y: 0,
x2: 0, x2: 0,
y2: 1, y2: 1,
colorStops: [{ colorStops: [
offset: 0, color: '#ccc', // 0% {
}, { offset: 0,
offset: 0.6, color: '#fff', // 100% color: '#ccc' // 0%
}], },
global: false, // false {
}, offset: 0.6,
}, color: '#fff' // 100%
}
],
global: false // false
}
}
}, },
{ {
name: '今天', name: '今天',
@ -273,16 +336,21 @@ const optionModel = {
y: 0, y: 0,
x2: 0, x2: 0,
y2: 1, y2: 1,
colorStops: [{ colorStops: [
offset: 0, color: '#5B8FF9', // 0% {
}, { offset: 0,
offset: 0.6, color: '#fff', // 100% color: '#5B8FF9' // 0%
}], },
global: false, // false {
}, offset: 0.6,
}, color: '#fff' // 100%
}, }
], ],
global: false // false
}
}
}
]
} }
const leftInfo = ref({ const leftInfo = ref({
money: 0, money: 0,
@ -290,59 +358,87 @@ const leftInfo = ref({
}) })
const leftOption: any = reactive(JSON.parse(JSON.stringify(optionModel))) const leftOption: any = reactive(JSON.parse(JSON.stringify(optionModel)))
const rightInfo1 = ref([]); const rightInfo1 = ref([])
const rightOption1: any = reactive(JSON.parse(JSON.stringify(optionModel))) const rightOption1: any = reactive(JSON.parse(JSON.stringify(optionModel)))
const rightInfo2 = ref([]); const rightInfo2 = ref([])
const rightOption2: any = reactive(JSON.parse(JSON.stringify(optionModel))) const rightOption2: any = reactive(JSON.parse(JSON.stringify(optionModel)))
// //
const colorList = ['#5DB1FF', '#4CD384', '#FFC46A', '#CAA5F1', '#FFC46A', '#4CD384', '#5DB1FF', '#CAA5F1'] const colorList = [
'#5DB1FF',
'#4CD384',
'#FFC46A',
'#CAA5F1',
'#FFC46A',
'#4CD384',
'#5DB1FF',
'#CAA5F1'
]
// , 访, , , , , , 退, 退, 访- // , 访, , , , , , 退, 退, 访-
const iconList = ref(['RectangleCopy58', 'RectangleCopy48', 'RectangleCopy65', 'RectangleCopy62', 'RectangleCopy56', 'RectangleCopy55', 'RectangleCopy57', 'RectangleCopy65', 'RectangleCopy61', 'RectangleCopy52', 'RectangleCopy14', 'RectangleCopy32']); const iconList = ref([
'RectangleCopy58',
'RectangleCopy48',
'RectangleCopy65',
'RectangleCopy62',
'RectangleCopy56',
'RectangleCopy55',
'RectangleCopy57',
'RectangleCopy65',
'RectangleCopy61',
'RectangleCopy52',
'RectangleCopy14',
'RectangleCopy32'
])
const startEndTime = ref([new Date(), new Date()]); const startEndTime = ref([new Date(), new Date()])
// //
const getData = () => { const getData = () => {
let date = ''; let date = ''
if (startEndTime.value[0] && startEndTime.value[1]) date = moment(startEndTime.value[0]).format('YYYY/MM/DD') + '-' + moment(startEndTime.value[1]).format('YYYY/MM/DD'); if (startEndTime.value[0] && startEndTime.value[1])
date =
moment(startEndTime.value[0]).format('YYYY/MM/DD') +
'-' +
moment(startEndTime.value[1]).format('YYYY/MM/DD')
apiGetTopTrade({}).then(res => { apiGetTopTrade({}).then((res) => {
leftInfo.value = { leftInfo.value = {
money: res.left.series[0].money, money: res.left.series[0].money,
name: res.left.name, name: res.left.name
} }
leftOption.series[0].data = res.left.series[1].value; leftOption.series[0].data = res.left.series[1].value
leftOption.series[1].data = res.left.series[0].value; leftOption.series[1].data = res.left.series[0].value
rightInfo1.value = res.right.today.series; rightInfo1.value = res.right.today.series
rightInfo2.value = res.right.month; rightInfo2.value = res.right.month
rightOption1.xAxis.data = res.right.today.x.map((item: any)=>item); rightOption1.xAxis.data = res.right.today.x.map((item: any) => item)
rightOption1.series[0].name = res.right.today.series[0].name; rightOption1.series[0].name = res.right.today.series[0].name
rightOption1.series[0].data = res.right.today.series[0].value; rightOption1.series[0].data = res.right.today.series[0].value
rightOption1.series[1].name = res.right.today.series[1].name; rightOption1.series[1].name = res.right.today.series[1].name
rightOption1.series[1].data = res.right.today.series[1].value; rightOption1.series[1].data = res.right.today.series[1].value
rightOption2.xAxis.data = Object.keys(res.right.month[0].value).map((item: any)=>item)
rightOption2.series[0].name = res.right.month[0].name;
rightOption2.series[0].data = Object.values(res.right.month[0].value).map((item: any)=>item)
rightOption2.series[1].name = res.right.month[1].name;
rightOption2.series[1].data = Object.values(res.right.month[1].value).map((item: any)=>item)
rightOption2.xAxis.data = Object.keys(res.right.month[0].value).map((item: any) => item)
rightOption2.series[0].name = res.right.month[0].name
rightOption2.series[0].data = Object.values(res.right.month[0].value).map(
(item: any) => item
)
rightOption2.series[1].name = res.right.month[1].name
rightOption2.series[1].data = Object.values(res.right.month[1].value).map(
(item: any) => item
)
}) })
apiGetBottomTrade({ apiGetBottomTrade({
date: date date: date
}).then(res => { }).then((res) => {
// echarts // echarts
visitorOption.xAxis.data = [] visitorOption.xAxis.data = []
visitorOption.series = [] visitorOption.series = []
console.log(res); console.log(res)
visitorOption.legend.data = Object.values(res.series).map((item: any) => item.name); visitorOption.legend.data = Object.values(res.series).map((item: any) => item.name)
// //
visitorOption.xAxis.data = res.x; visitorOption.xAxis.data = res.x
visitorOption.series = Object.values(res.series).map((item: any) => { visitorOption.series = Object.values(res.series).map((item: any) => {
return { return {
type: 'line', type: 'line',
@ -350,21 +446,20 @@ const getData = () => {
data: item.value, data: item.value,
name: item.name, name: item.name,
money: item.money, money: item.money,
rate: item.rate rate: item.rate,
desc: item.desc
} }
}); })
}) })
} }
onMounted(() => { onMounted(() => {
getData() getData()
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.workbench{ .workbench {
color: #444; color: #444;
} }
</style> </style>