This commit is contained in:
ylj20011123 2025-10-24 14:51:57 +08:00
parent 188282c4f0
commit 7cc6a538e7
8 changed files with 267 additions and 105 deletions

View File

@ -45,7 +45,7 @@
<view class="chart-content">
<view class="pie-chart-container">
<QiunDataCharts type="pie" :opts="pieChartOpts" :chartData="pieChartData" :canvas2d="true"
:inScrollView="true" canvasId="inventoryStructurePieChart" />
:inScrollView="true" canvasId="inventoryStructurePieChart" tooltipFormat="ShopTypeNumberRate" />
</view>
</view>
</view>
@ -156,7 +156,8 @@ export default {
padding: [5, 5, 5, 5],
dataLabel: true,
legend: {
show: true
show: true,
lineHeight: 30
},
extra: {
pie: {

View File

@ -72,14 +72,8 @@
</view>
<view class="chart-content">
<view class="line-chart-container">
<QiunDataCharts
type="line"
:opts="timeDistributionOpts"
:chartData="timeDistributionChartData"
:canvas2d="true"
:inScrollView="true"
canvasId="timeDistributionChart"
/>
<QiunDataCharts type="line" :opts="timeDistributionOpts" :chartData="timeDistributionChartData"
:canvas2d="true" :inScrollView="true" canvasId="timeDistributionChart" />
</view>
</view>
</view>
@ -92,21 +86,8 @@
</view>
<view class="chart-content">
<view class="map-chart-container">
<QiunDataCharts
type="pie"
:opts="regionDistributionOpts"
:chartData="regionDistributionData"
:canvas2d="true"
:inScrollView="true"
canvasId="regionDistributionChart"
/>
<view class="region-legend">
<view class="legend-item" v-for="(item, index) in regionData" :key="index">
<view class="legend-color" :style="{ backgroundColor: item.color }"></view>
<text class="legend-name">{{ item.name }}</text>
<text class="legend-value">¥{{ formatMoney(item.amount) }}</text>
</view>
</view>
<QiunDataCharts type="pie" :opts="regionDistributionOpts" :chartData="regionDistributionData" :canvas2d="true"
:inScrollView="true" canvasId="regionDistributionChart" />
</view>
</view>
</view>
@ -119,14 +100,8 @@
</view>
<view class="chart-content">
<view class="bar-chart-container">
<QiunDataCharts
type="column"
:opts="salesVolumeOpts"
:chartData="salesVolumeChartData"
:canvas2d="true"
:inScrollView="true"
canvasId="salesVolumeChart"
/>
<QiunDataCharts type="column" :opts="salesVolumeOpts" :chartData="salesVolumeChartData" :canvas2d="true"
:inScrollView="true" canvasId="salesVolumeChart" />
</view>
</view>
</view>
@ -139,14 +114,8 @@
</view>
<view class="chart-content">
<view class="bar-chart-container">
<QiunDataCharts
type="column"
:opts="salesAmountOpts"
:chartData="salesAmountChartData"
:canvas2d="true"
:inScrollView="true"
canvasId="salesAmountChart"
/>
<QiunDataCharts type="column" :opts="salesAmountOpts" :chartData="salesAmountChartData" :canvas2d="true"
:inScrollView="true" canvasId="salesAmountChart" />
</view>
</view>
</view>
@ -154,7 +123,9 @@
</template>
<script>
import { wrapTreeNode } from '../../../util/dateTime';
import QiunDataCharts from './qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue'
import request from "@/util/index.js";
export default {
components: {
@ -171,38 +142,18 @@ export default {
dealUsers: 8834,
avgOrderValue: 5136,
//
//
timeDistributionData: {
categories: ['00:00', '02:00', '04:00', '06:00', '08:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00'],
transactionData: [234, 156, 89, 123, 567, 1234, 2345, 1876, 1567, 2890, 2456, 1876],
amountData: [12345, 8234, 4567, 6789, 34567, 67890, 123456, 98765, 82345, 156789, 123456, 98765]
categories: [],
transactionData: [],
amountData: []
},
//
regionData: [
{ name: '云南省', amount: 5678901, percentage: 28.5, color: '#576EFF' },
{ name: '广东省', amount: 3456789, percentage: 17.3, color: '#52C41A' },
{ name: '北京市', amount: 2345678, percentage: 11.8, color: '#FAAD14' },
{ name: '上海市', amount: 1987654, percentage: 10.0, color: '#FF7875' },
{ name: '四川省', amount: 1567890, percentage: 7.9, color: '#B37FEB' },
{ name: '浙江省', amount: 1234567, percentage: 6.2, color: '#13C2C2' },
{ name: '江苏省', amount: 987654, percentage: 5.0, color: '#722ED1' },
{ name: '其他', amount: 2567890, percentage: 13.3, color: '#999999' }
],
regionData: [],
//
salesVolumeData: [
{ name: '云南白药套装', volume: 3456 },
{ name: '普洱茶礼盒', volume: 2890 },
{ name: '鲜花饼组合', volume: 2345 },
{ name: '三七粉精品', volume: 1876 },
{ name: '云南咖啡豆', volume: 1567 },
{ name: '玉石手镯', volume: 1234 },
{ name: '民族服饰', volume: 987 },
{ name: '鲜花精油', volume: 876 },
{ name: '手工皂套装', volume: 654 },
{ name: '银饰项链', volume: 543 }
],
salesVolumeData: [],
//
salesAmountData: [
@ -227,12 +178,12 @@ export default {
categories: this.timeDistributionData.categories,
series: [
{
name: '交易量',
name: '客单量',
data: this.timeDistributionData.transactionData
},
{
name: '交易额(÷100)',
data: this.timeDistributionData.amountData.map(v => v / 100)
name: '交易额',
data: this.timeDistributionData.amountData
}
]
}
@ -245,7 +196,7 @@ export default {
padding: [15, 15, 15, 15],
dataLabel: false,
legend: {
show: false
show: true
},
xAxis: {
disableGrid: true
@ -279,7 +230,7 @@ export default {
series: [{
data: this.regionData.map(item => ({
name: item.name,
value: item.amount
value: item.value
}))
}]
}
@ -288,11 +239,10 @@ export default {
//
regionDistributionOpts() {
return {
color: this.regionData.map(item => item.color),
padding: [5, 5, 5, 5],
dataLabel: true,
legend: {
show: false
show: true
},
extra: {
pie: {
@ -316,7 +266,7 @@ export default {
),
series: [{
name: '销售量',
data: this.salesVolumeData.map(item => item.volume)
data: this.salesVolumeData.map(item => item.value)
}]
}
},
@ -406,8 +356,142 @@ export default {
}
}
},
onReady() {
//
this.handleGetAllData()
},
methods: {
//
handleGetAllData() {
//
this.handleGetTradingHoursData()
//
this.handleGetDistributionOfRegion()
//
this.hanleGetShopSalesVolumeData()
},
//
async hanleGetShopSalesVolumeData() {
const req = {
action_type: "getCommoditySaleSort",
province_code: 5564,
rowNum: 5
}
const data = await request.$cloudUrlGet(req);
console.log('datadatadatadatadata', data);
let list = data.COMMODITYSALE_DESC
let res = []
if (list && list.length > 0) {
list.forEach((item) => {
res.push({
name: item.COMMODITY_NAME,
value: item.SELLCOUNT,
})
})
}
this.salesVolumeData = res
//
// salesVolumeData: [
// { name: '', value: 3456 },
// { name: '', value: 2890 },
// ]
},
//
async handleGetDistributionOfRegion() {
const serviceReq = {
Province_Code: "530000"
}
const serviceList = await request.$apiGet(
"CommercialApi/BaseInfo/GetServerpartList",
serviceReq
);
console.log('serviceListserviceListserviceList', serviceList);
let serviceLists = serviceList.Result_Data.List
let allService = ""
if (serviceLists && serviceLists.length > 0) {
serviceLists.forEach((item) => {
if (allService) {
allService += `,${item.SERVERPART_ID}`
} else {
allService = `${item.SERVERPART_ID}`
}
})
}
// id id
const req = {
StartDate: "2025-04-01",
EndDate: "2025-04-30",
DataType: 1,
ServerpartIds: allService,
DataSourceType: 1,
}
const data = await request.$apiGet(
"EShangApiMain/Revenue/GetRevenueReport",
req
);
let list = wrapTreeNode(data.Result_Data.List)
console.log('交易地域分布', list);
let res = []
if (list && list.length > 0) {
list.forEach((item) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem) => {
res.push({ name: subItem.Serverpart_Name, value: subItem.TotalRevenue.Revenue_Amount })
})
}
})
}
this.regionData = res
//
// regionData: [
// { name: '', value: 5678901 },
// { name: '广', value: 3456789 },
// ],
},
//
async handleGetTradingHoursData() {
const req = {
Province_Code: '530000',
Statistics_Date: '2025-09-01',
Serverpart_ID: '',
TimeSpan: 1
}
const data = await request.$apiGet(
"CommercialApi/Revenue/GetTransactionTimeAnalysis",
req
);
let list = data.Result_Data.CommonScatterList
console.log('交易时间分布', list);
let categories = []
let transactionData = [] //
let amountData = [] //
if (list && list.length > 0) {
list.forEach((item) => {
let hour = Number(item.name)
if (hour % 4 === 0 || hour === 0) {
categories.push(`${item.name}`)
}
// let hour = Number(item.name) < 10 ? `0${item.name}:00` : `${item.name}:00`
transactionData.push(item.data)
amountData.push(item.key)
})
}
this.timeDistributionData = {
categories: categories,
transactionData: transactionData,
amountData: amountData
}
//
// timeDistributionData: {
// categories: ['00:00', '02:00', '04:00', '06:00', '08:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00'],
// transactionData: [234, 156, 89, 123, 567, 1234, 2345, 1876, 1567, 2890, 2456, 1876],
// amountData: [12345, 8234, 4567, 6789, 34567, 67890, 123456, 98765, 82345, 156789, 123456, 98765]
// }
},
formatNumber(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
},
@ -498,32 +582,80 @@ export default {
&.total-amount {
background: linear-gradient(135deg, #1890ff, #40a9ff);
&::after { content: '📊'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
&::after {
content: '📊';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24rpx;
}
}
&.total-money {
background: linear-gradient(135deg, #52c41a, #73d13d);
&::after { content: '💰'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
&::after {
content: '💰';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24rpx;
}
}
&.conversion-rate {
background: linear-gradient(135deg, #faad14, #ffc53d);
&::after { content: '📈'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
&::after {
content: '📈';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24rpx;
}
}
&.order-users {
background: linear-gradient(135deg, #722ed1, #9254de);
&::after { content: '👥'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
&::after {
content: '👥';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24rpx;
}
}
&.deal-users {
background: linear-gradient(135deg, #eb2f96, #f759ab);
&::after { content: '✅'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
&::after {
content: '✅';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24rpx;
}
}
&.avg-order {
background: linear-gradient(135deg, #13c2c2, #36cfc9);
&::after { content: '🛒'; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24rpx; }
&::after {
content: '🛒';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24rpx;
}
}
}

View File

@ -46,7 +46,7 @@
<view class="chart-content">
<view class="pie-chart-container">
<QiunDataCharts type="pie" :opts="pieChartOpts" :chartData="pieChartData" :canvas2d="true"
:inScrollView="true" canvasId="productTypePieChart" />
:inScrollView="true" canvasId="productTypePieChart" tooltipFormat="ShopTypeDistribution" />
</view>
</view>
</view>
@ -384,9 +384,6 @@ export default {
this.salesRankingData = res
this.productList = list
},
//
getScreenWidth() {
try {

View File

@ -77,7 +77,7 @@
<view class="chart-content">
<view class="trend-chart-container">
<QiunDataCharts type="line" :opts="trendChartOpts" :chartData="trendChartData" :canvas2d="true"
:inScrollView="true" canvasId="trendChart" />
:inScrollView="true" canvasId="trendChart" tooltipFormat="tradingTrendData" />
</view>
</view>
</view>

View File

@ -95,6 +95,20 @@ const cfu = {
"option": {},
//下面是自定义format配置因除H5端外的其他端无法通过props传递函数只能通过此属性对应下标的方式来替换
"formatter": {
"ShopTypeNumberRate": function (item, category, index, opts) {
console.log('', item);
console.log('', category);
console.log('', index);
console.log('', opts);
return `${item.name}${item.data}`
},
"tradingTrendData": function (item, category, index, opts) {
return `${category}${item.name} ${item.data}${item.name === '订单量' ? '笔' : '元'}`
},
"ShopTypeDistribution": function (item, category, index, opts) {
return `${item.name}${item.data}`
},
'SalesRankingOfProducts': function (item, category, index, opts) {
// console.log('', item);
// console.log('', category);

View File

@ -1,6 +1,7 @@
<template>
<page-meta :page-style="'overflow-x:hidden'"></page-meta>
<scroll-view scroll-y @scroll="handleScroll" class="digital-dashboard">
<scroll-view scroll-y @scroll="handleScroll" class="digital-dashboard" :scroll-into-view="scrollIntoView"
:scroll-with-animation="true">
<!-- Tab切换区域 -->
<view class="tab-container">
<view class="tab-list">
@ -31,7 +32,7 @@
</view>
</view>
</view>
<view id="top"> </view>
<!-- 内容展示区域 -->
<view class="content-container">
<!-- 经营数据分析 -->
@ -182,7 +183,7 @@ export default {
},
data() {
return {
activeTab: 1,
activeTab:2,
tabList: [
{ name: '经营数据分析', key: 'business' },
{ name: '供应链数据分析', key: 'supply' },
@ -227,7 +228,8 @@ export default {
isNavCollapsed: true,
//
sessionData: {},
pageScrollTop: 0
pageScrollTop: 0,
scrollIntoView: ""
}
},
computed: {
@ -257,6 +259,7 @@ export default {
},
methods: {
switchTab(index) {
this.scrollIntoView = 'top'
this.activeTab = index;
//
@ -273,21 +276,23 @@ export default {
//
scrollToComponent(componentId) {
this.scrollIntoView = componentId
this.activeNavItem = componentId;
setTimeout(() => {
uni.createSelectorQuery().select('#' + componentId).boundingClientRect((data) => {
if (data) {
uni.createSelectorQuery().selectViewport().scrollOffset((scrollData) => {
const targetScrollTop = scrollData.scrollTop + data.top - 80;
uni.pageScrollTo({
scrollTop: Math.max(0, targetScrollTop),
duration: 300
});
}).exec();
}
}).exec();
}, 100);
// setTimeout(() => {
// uni.createSelectorQuery().select('#' + componentId).boundingClientRect((data) => {
// if (data) {
// uni.createSelectorQuery().selectViewport().scrollOffset((scrollData) => {
// const targetScrollTop = scrollData.scrollTop + data.top - 80;
// uni.pageScrollTo({
// scrollTop: Math.max(0, targetScrollTop),
// duration: 300
// });
// }).exec();
// }
// }).exec();
// }, 100);
},
//
@ -334,11 +339,13 @@ export default {
.tab-container {
background: @bg-white;
box-shadow: @shadow-light;
position: sticky;
// position: sticky;
position: fixed;
top: 0;
z-index: 100;
.tab-list {
height: 80rpx;
display: flex;
padding: 0 32rpx;
box-sizing: border-box;
@ -417,6 +424,7 @@ export default {
.content-container {
padding: 32rpx;
padding-top: 112rpx;
.tab-content {
/* 移除切换动画 */

View File

@ -10,6 +10,7 @@ export default {
// EshangUrl: 'https://eshangtech.com/',
// apiurl: 'https://erysfeipeng.oicp.net/', // web api
testApiurl: 'http://dev.eshangtech.com:8001/', // web api测试接口地址
apiEsUrl: "https://api.eshangtech.com/",
mobUrl: 'http://192.168.11.125:8000/Coop.Merchant/Handler/handler_ajax.ashx', // 接口
testURL1: 'http://192.168.10.123:8000', // 测试ip

View File

@ -31,6 +31,15 @@ export default {
data.action_type = controller
return this.post(data)
},
$apiGet: function (controller, data) {
return Api.request('GET', ApiPath.apiEsUrl + controller, data || {}, true)
},
$apiPost: function (controller, data) {
return Api.request('POST', ApiPath.apiEsUrl + controller, data || {}, true)
},
$posGet: function (controller, data) {
return Api.request('GET', ApiPath.posApiurl + controller, data || {}, true)
},
$posPost: function (controller, data) {
return Api.request('POST', ApiPath.posApiurl + controller, data || {}, true)
},