|
|
@@ -206,16 +206,17 @@
|
|
|
|
|
|
<script>
|
|
|
import * as echarts from 'echarts'
|
|
|
+import { getSaleOrderSummary, getSaleOrderTrendSummary } from '@/api/home/index'
|
|
|
let chartInstances = {}
|
|
|
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
|
marketing: {
|
|
|
- yearOrderCount: 23,
|
|
|
- yearOrderAmount: 98,
|
|
|
- monthOrderCount: 23,
|
|
|
- monthOrderAmount: 98
|
|
|
+ yearOrderCount: 0,
|
|
|
+ yearOrderAmount: 0,
|
|
|
+ monthOrderCount: 0,
|
|
|
+ monthOrderAmount: 0
|
|
|
},
|
|
|
production: {
|
|
|
yearWorkOrder: 23,
|
|
|
@@ -239,15 +240,17 @@ export default {
|
|
|
monthProduceIn: 98,
|
|
|
monthDeliveryOut: 98
|
|
|
},
|
|
|
+ currentYear: '',
|
|
|
+ currentMonth: '',
|
|
|
chartData: {
|
|
|
marketingChart: {
|
|
|
categories: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'],
|
|
|
// 混合图表:柱状图(订单量) + 折线图(订单金额)
|
|
|
series: [
|
|
|
- { name: '月订单量', data: [15, 20, 25, 30, 45, 50, 48, 40, 35, 42, 48, 52], type: 'bar' },
|
|
|
- { name: '去年同期订单量', data: [12, 18, 22, 28, 40, 45, 42, 38, 32, 38, 45, 48], type: 'bar' },
|
|
|
- { name: '月订单金额', data: [8.5, 10.2, 12.5, 15.0, 22.5, 25.0, 24.0, 20.0, 17.5, 21.0, 24.0, 26.0], type: 'line' },
|
|
|
- { name: '去年同期订单金额', data: [6.0, 9.0, 11.0, 14.0, 20.0, 22.5, 21.0, 19.0, 16.0, 19.0, 22.5, 24.0], type: 'line' }
|
|
|
+ { name: '月订单量', data: [], type: 'bar' },
|
|
|
+ { name: '去年同期订单量', data: [], type: 'bar' },
|
|
|
+ { name: '月订单金额', data: [], type: 'line' },
|
|
|
+ { name: '去年同期订单金额', data: [], type: 'line' }
|
|
|
]
|
|
|
},
|
|
|
productionChart: {
|
|
|
@@ -292,8 +295,15 @@ export default {
|
|
|
// NOTE: manage 作为 homeNew 的子组件使用时,UniApp 页面级钩子(onReady/onLoad/onUnload)不会触发。
|
|
|
// initCharts() 由父组件 homeNew 在 mounted 中通过 $refs.manageRef?.initCharts() 调用。
|
|
|
mounted() {
|
|
|
+ const now = new Date()
|
|
|
+ this.currentYear = now.getFullYear()
|
|
|
+ this.currentMonth = String(now.getMonth() + 1).padStart(2, '0')
|
|
|
+
|
|
|
+ this.getSaleOrderSummary()
|
|
|
+ this.getSaleOrderTrendSummary()
|
|
|
// 作为备用:如果父组件没有调用 initCharts,这里兜底执行
|
|
|
this.$nextTick(() => {
|
|
|
+
|
|
|
if (Object.keys(chartInstances).length === 0) {
|
|
|
this.initCharts()
|
|
|
}
|
|
|
@@ -306,6 +316,54 @@ export default {
|
|
|
chartInstances = {}
|
|
|
},
|
|
|
methods: {
|
|
|
+ async getSaleOrderTrendSummary() {
|
|
|
+ let res = await getSaleOrderTrendSummary({
|
|
|
+ year: this.currentYear
|
|
|
+ })
|
|
|
+ console.log('getSaleOrderTrendSummary', res)
|
|
|
+
|
|
|
+ const trends = res?.trends || []
|
|
|
+ // 初始化12个月的数据,默认0
|
|
|
+ const quantityArr = new Array(12).fill(0)
|
|
|
+ const lastQuantityArr = new Array(12).fill(0)
|
|
|
+ const amountArr = new Array(12).fill(0)
|
|
|
+ const lastAmountArr = new Array(12).fill(0)
|
|
|
+
|
|
|
+ trends.forEach((item) => {
|
|
|
+ const idx = item.month - 1 // month 为 1-12,转为数组索引 0-11
|
|
|
+ if (idx >= 0 && idx < 12) {
|
|
|
+ quantityArr[idx] = item.quantity || 0
|
|
|
+ lastQuantityArr[idx] = item.lastQuantity || 0
|
|
|
+ amountArr[idx] = +((item.amount || 0) / 10000).toFixed(2)
|
|
|
+ lastAmountArr[idx] = +((item.lastAmount || 0) / 10000).toFixed(2)
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ this.chartData.marketingChart.series[0].data = quantityArr
|
|
|
+ this.chartData.marketingChart.series[1].data = lastQuantityArr
|
|
|
+ this.chartData.marketingChart.series[2].data = amountArr
|
|
|
+ this.chartData.marketingChart.series[3].data = lastAmountArr
|
|
|
+
|
|
|
+ // 数据更新后刷新图表
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (chartInstances.marketingChart) {
|
|
|
+ this.initChart('marketingChart', this.chartData.marketingChart)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ async getSaleOrderSummary() {
|
|
|
+
|
|
|
+ let res = await getSaleOrderSummary({
|
|
|
+ year: this.currentYear,
|
|
|
+ month: this.currentMonth
|
|
|
+ })
|
|
|
+
|
|
|
+ this.marketing.yearOrderCount = res?.yearlySummary?.quantity || 0
|
|
|
+ this.marketing.yearOrderAmount = (res?.yearlySummary?.amount / 10000).toFixed(2) || 0
|
|
|
+ this.marketing.monthOrderCount = res?.monthlySummary?.quantity || 0
|
|
|
+ this.marketing.monthOrderAmount = (res?.monthlySummary?.amount / 10000).toFixed(2) || 0
|
|
|
+ console.log('getSaleOrderSummary', res)
|
|
|
+ },
|
|
|
toSaleOrderDetail(type) {
|
|
|
uni.navigateTo({
|
|
|
url: '/pages/home/pages/manage/saleOrderDetail?type=' + type
|
|
|
@@ -323,38 +381,49 @@ export default {
|
|
|
})
|
|
|
},
|
|
|
initChart(domId, data) {
|
|
|
- const query = uni.createSelectorQuery().in(this)
|
|
|
- query.select(`#${domId}`).boundingClientRect()
|
|
|
- query.exec(res => {
|
|
|
- if (!res[0]) {
|
|
|
- console.error(`Element #${domId} not found`)
|
|
|
- return
|
|
|
- }
|
|
|
- const width = res[0].width || 355
|
|
|
- const height = res[0].height || 200
|
|
|
- console.log('init chart:', domId, width, height)
|
|
|
-
|
|
|
- const chart = echarts.init(document.getElementById(domId))
|
|
|
- chart.resize({ width, height })
|
|
|
-
|
|
|
- const option = {
|
|
|
- grid: {
|
|
|
- left: 35,
|
|
|
- right: 15,
|
|
|
- top: 35,
|
|
|
- bottom: 30
|
|
|
- },
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- // 注意: triggerOn: 'click' 会劫持 click 事件,导致自定义 chart.on('click') 失效。
|
|
|
- // 使用默认的 'mousemove',移动端自动降级为 touch。
|
|
|
- backgroundColor: 'rgba(50, 50, 50, 0.9)',
|
|
|
- borderColor: '#333',
|
|
|
- textStyle: {
|
|
|
- color: '#fff',
|
|
|
- fontSize: 12
|
|
|
+ this.$nextTick(() => {
|
|
|
+ setTimeout(() => {
|
|
|
+ const query = uni.createSelectorQuery().in(this)
|
|
|
+ query.select(`#${domId}`).boundingClientRect()
|
|
|
+ query.exec(res => {
|
|
|
+ if (!res[0]) {
|
|
|
+ console.error(`Element #${domId} not found`)
|
|
|
+ return
|
|
|
}
|
|
|
- },
|
|
|
+ const width = res[0].width || 355
|
|
|
+ const height = res[0].height || 200
|
|
|
+ console.log('init chart:', domId, width, height)
|
|
|
+
|
|
|
+ const dom = document.getElementById(domId)
|
|
|
+ if (!dom) return
|
|
|
+
|
|
|
+ // 销毁旧实例,避免重复初始化
|
|
|
+ if (chartInstances[domId]) {
|
|
|
+ chartInstances[domId].dispose()
|
|
|
+ chartInstances[domId] = null
|
|
|
+ }
|
|
|
+
|
|
|
+ const chart = echarts.init(dom)
|
|
|
+ chart.resize({ width, height })
|
|
|
+
|
|
|
+ const option = {
|
|
|
+ grid: {
|
|
|
+ left: '14%',
|
|
|
+ right: '6%',
|
|
|
+ top: '12%',
|
|
|
+ bottom: '10%'
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ confine: true,
|
|
|
+ extraCssText: 'z-index: 99999 !important; pointer-events: auto;',
|
|
|
+ backgroundColor: 'rgba(50, 50, 50, 0.9)',
|
|
|
+ borderColor: '#333',
|
|
|
+ textStyle: {
|
|
|
+ color: '#fff',
|
|
|
+ fontSize: 12
|
|
|
+ }
|
|
|
+ },
|
|
|
xAxis: {
|
|
|
type: 'category',
|
|
|
data: data.categories,
|
|
|
@@ -409,14 +478,26 @@ export default {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
- chart.setOption(option)
|
|
|
- chartInstances[domId] = chart
|
|
|
+ chart.setOption(option)
|
|
|
+ chartInstances[domId] = chart
|
|
|
+
|
|
|
+ // H5 修复:setOption 后 canvas 才创建,延迟强制设置交互属性
|
|
|
+ setTimeout(() => {
|
|
|
+ const canvas = dom.querySelector('canvas')
|
|
|
+ if (canvas) {
|
|
|
+ canvas.style.pointerEvents = 'auto'
|
|
|
+ canvas.style.touchAction = 'auto'
|
|
|
+ }
|
|
|
+ }, 100)
|
|
|
|
|
|
- // 先解绑再绑定,防止重复初始化时多次绑定
|
|
|
- chart.off('click')
|
|
|
- chart.on('click', (params) => {
|
|
|
- console.log('chart click:', domId, params.name, params)
|
|
|
- })
|
|
|
+ // 先解绑再绑定,防止重复初始化时多次绑定
|
|
|
+ chart.off('click')
|
|
|
+ // zrender 层级兜底
|
|
|
+ chart.getZr().on('click', (params) => {
|
|
|
+ console.log('zr click:', domId, params)
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }, 100)
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
@@ -435,6 +516,7 @@ export default {
|
|
|
.section {
|
|
|
margin-top: 2rpx;
|
|
|
padding-bottom: 8rpx;
|
|
|
+ overflow: visible;
|
|
|
|
|
|
.section-header {
|
|
|
padding: 24rpx 0 24rpx;
|
|
|
@@ -449,6 +531,7 @@ export default {
|
|
|
}
|
|
|
.section-content {
|
|
|
background: #fff;
|
|
|
+ overflow: visible;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -495,7 +578,7 @@ export default {
|
|
|
}
|
|
|
|
|
|
.data-value {
|
|
|
- font-size: 34rpx;
|
|
|
+ font-size: 30rpx;
|
|
|
font-weight: 700;
|
|
|
color: #fff;
|
|
|
}
|
|
|
@@ -512,6 +595,7 @@ export default {
|
|
|
/* 图表 */
|
|
|
.chart-wrapper {
|
|
|
padding: 0 20rpx 8rpx;
|
|
|
+ overflow: visible;
|
|
|
|
|
|
.chart-title {
|
|
|
font-size: 26rpx;
|
|
|
@@ -523,7 +607,9 @@ export default {
|
|
|
.chart-box {
|
|
|
// background: #f7f7f7;
|
|
|
border-radius: 10rpx;
|
|
|
- overflow: hidden;
|
|
|
+ position: relative;
|
|
|
+ z-index: 0;
|
|
|
+ /* overflow: hidden 已移除:会裁剪 ECharts tooltip */
|
|
|
}
|
|
|
|
|
|
.chart {
|
|
|
@@ -531,6 +617,11 @@ export default {
|
|
|
height: 280px;
|
|
|
min-height: 200px;
|
|
|
display: block;
|
|
|
+ position: relative;
|
|
|
+ z-index: 1;
|
|
|
+ pointer-events: auto;
|
|
|
+ touch-action: auto;
|
|
|
+ overflow: visible;
|
|
|
}
|
|
|
}
|
|
|
|