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

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"
/>
</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">
<daterange-picker
v-model:startTime="queryParams.start_time"
@ -125,6 +147,7 @@ import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import { apiStoreCategoryLists } from '@/api/store_category'
import { useRoute } from 'vue-router'
import { apiSystemStoreLists } from '@/api/system_store'
const route = useRoute()
@ -133,9 +156,31 @@ const detailsRef = ref(null)
const queryParams = reactive({
start_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[]>([])

View File

@ -8,38 +8,62 @@
<span class="text-[12px]">¥</span>
<span class="text-2xl">{{ leftInfo.money || '0.00' }}</span>
</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 class="w-[1px] bg-[#ccc] mr-4"></div>
<div class="flex-1 flex">
<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-[12px]">
<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 class="text-1xl">
{{ rightInfo1[0]?.name
}}<span class="ml-2 text-[18px]">{{ rightInfo1[0]?.now_money }}</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">昨日: {{ 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-success">{{rightInfo2[0]?.rate}}%</span>
<span class="text-success">{{ rightInfo2[0]?.rate }}%</span>
</div>
</div>
<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-[12px]">
<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 class="text-1xl">
{{ rightInfo1[1]?.name
}}<span class="ml-2 text-[18px]">{{ rightInfo1[1]?.now_money }}</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">昨日: {{ 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-success">{{rightInfo2[1]?.rate}}%</span>
<span class="text-success">{{ rightInfo2[1]?.rate }}%</span>
</div>
</div>
</div>
@ -50,23 +74,52 @@
<span class="text-2xl">交易概况</span>
<div class="flex items-center text-sm">
<span class="mr-4">时间筛选: </span>
<el-date-picker v-model="startEndTime" type="daterange" range-separator="" start-placeholder="开始日期"
end-placeholder="结束日期" unlink-panels :shortcuts="shortcuts" @change="getData" />
<el-date-picker
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>
</div>
</div>
<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="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" />
</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-info">环比增长: <span :class="item.rate > 0 ? 'text-success' : 'text-danger'">{{
item.rate }}%</span></div>
<div class="text-info">
环比增长:
<span :class="item.rate > 0 ? 'text-success' : 'text-danger'"
>{{ item.rate }}%</span
>
</div>
</div>
</div>
</div>
@ -78,7 +131,12 @@
</template>
<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 vCharts from 'vue-echarts'
@ -90,7 +148,7 @@ const shortcuts = [
const start = new Date()
start.setDate(start.getDate() - 7)
return [start, end]
},
}
},
{
text: '本月',
@ -101,7 +159,7 @@ const shortcuts = [
end.setMonth(end.getMonth() + 1)
end.setDate(0)
return [start, end]
},
}
},
{
text: '近一月',
@ -110,7 +168,7 @@ const shortcuts = [
const start = new Date()
start.setMonth(start.getMonth() - 1)
return [start, end]
},
}
},
{
text: '近三月',
@ -119,8 +177,8 @@ const shortcuts = [
const start = new Date()
start.setMonth(start.getMonth() - 3)
return [start, end]
},
},
}
}
]
//
@ -174,11 +232,11 @@ const optionModel = {
type: 'cross'
},
formatter: (params) => {
let str = `<p><b>${params[0].name}点</b></p>`;
let str = `<p><b>${params[0].name}点</b></p>`
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>`;
});
return str;
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
}
},
grid: {
@ -198,13 +256,13 @@ const optionModel = {
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'],
axisLabel: {
show: false, // x
show: false // x
},
axisTick: {
show: false, // x 线
show: false // x 线
},
axisLine: {
show: false, // x 线
show: false // x 线
},
grid: {
show: false
@ -219,18 +277,18 @@ const optionModel = {
show: false
},
axisLabel: {
show: false, // x
show: false // x
},
axisTick: {
show: false, // x 线
show: false // x 线
},
axisLine: {
show: false, // x 线
show: false // x 线
},
grid: {
show: false
}
},
}
],
series: [
{
@ -240,7 +298,7 @@ const optionModel = {
smooth: true,
symbol: 'none', //
itemStyle: {
color: '#ccc',
color: '#ccc'
},
areaStyle: {
color: {
@ -250,14 +308,19 @@ const optionModel = {
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: '#ccc', // 0%
}, {
offset: 0.6, color: '#fff', // 100%
}],
global: false, // false
},
colorStops: [
{
offset: 0,
color: '#ccc' // 0%
},
{
offset: 0.6,
color: '#fff' // 100%
}
],
global: false // false
}
}
},
{
name: '今天',
@ -273,16 +336,21 @@ const optionModel = {
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: '#5B8FF9', // 0%
}, {
offset: 0.6, color: '#fff', // 100%
}],
global: false, // false
},
},
colorStops: [
{
offset: 0,
color: '#5B8FF9' // 0%
},
{
offset: 0.6,
color: '#fff' // 100%
}
],
global: false // false
}
}
}
]
}
const leftInfo = ref({
money: 0,
@ -290,59 +358,87 @@ const leftInfo = ref({
})
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 rightInfo2 = ref([]);
const rightInfo2 = ref([])
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 = () => {
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');
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')
apiGetTopTrade({}).then(res => {
apiGetTopTrade({}).then((res) => {
leftInfo.value = {
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[1].data = res.left.series[0].value;
leftOption.series[0].data = res.left.series[1].value
leftOption.series[1].data = res.left.series[0].value
rightInfo1.value = res.right.today.series;
rightInfo2.value = res.right.month;
rightInfo1.value = res.right.today.series
rightInfo2.value = res.right.month
rightOption1.xAxis.data = res.right.today.x.map((item: any)=>item);
rightOption1.series[0].name = res.right.today.series[0].name;
rightOption1.series[0].data = res.right.today.series[0].value;
rightOption1.series[1].name = res.right.today.series[1].name;
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)
rightOption1.xAxis.data = res.right.today.x.map((item: any) => item)
rightOption1.series[0].name = res.right.today.series[0].name
rightOption1.series[0].data = res.right.today.series[0].value
rightOption1.series[1].name = res.right.today.series[1].name
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
)
})
apiGetBottomTrade({
date: date
}).then(res => {
}).then((res) => {
// echarts
visitorOption.xAxis.data = []
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) => {
return {
type: 'line',
@ -350,21 +446,20 @@ const getData = () => {
data: item.value,
name: item.name,
money: item.money,
rate: item.rate
rate: item.rate,
desc: item.desc
}
});
})
})
}
onMounted(() => {
getData()
})
</script>
<style lang="scss" scoped>
.workbench{
.workbench {
color: #444;
}
</style>