266 lines
6.6 KiB
Vue
266 lines
6.6 KiB
Vue
<template>
|
||
<view class="supplier-overview">
|
||
<view class="section-title">供应链概览</view>
|
||
|
||
<!-- 核心KPI卡片 -->
|
||
<view class="metrics-row">
|
||
<view class="metric-card">
|
||
<text class="metric-value" style="color: #9B7EDE;">{{ kpiData.totalSuppliers || 0 }}</text>
|
||
<text class="metric-label">合作供应商/个</text>
|
||
</view>
|
||
<view class="metric-card">
|
||
<text class="metric-value" style="color: #52C41A;">{{ kpiData.avgDeliveryRate || 0 }}%</text>
|
||
<text class="metric-label">平均送达率</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="metrics-row">
|
||
<view class="metric-card">
|
||
<text class="metric-value" style="color: #1890FF;">{{ kpiData.inventoryTurnover || 0 }}</text>
|
||
<text class="metric-label">库存周转/天</text>
|
||
</view>
|
||
<view class="metric-card">
|
||
<text class="metric-value" style="color: #FF8F6F;">¥{{ formatMoney(kpiData.monthlyPurchase) }}</text>
|
||
<text class="metric-label">本月采购额</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 供应商类别分布 -->
|
||
<view class="chart-title">供应商类别分布</view>
|
||
<view class="chart-section">
|
||
<view class="chart-container">
|
||
<!-- 图表加载效果 -->
|
||
<ChartLoading v-if="isLoading" text="数据加载中..." />
|
||
<!-- 实际饼图 -->
|
||
<QiunDataCharts v-else type="pie" :opts="categoryPieOpts" :chartData="categoryPieData" :canvas2d="true"
|
||
:inScrollView="true" canvasId="supplierCategoryPie" tooltipFormat="supplierCategoryPie" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 预警提示 -->
|
||
<!-- <view class="alert-card">
|
||
<view class="alert-icon">⚠️</view>
|
||
<view class="alert-content">
|
||
<text class="alert-title">预警提示</text>
|
||
<view class="alert-value">
|
||
<text class="alert-number">{{ alertData.totalAlerts || 0 }}</text>
|
||
<text class="alert-unit">个异常</text>
|
||
</view>
|
||
</view>
|
||
</view> -->
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import QiunDataCharts from './qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue'
|
||
import ChartLoading from './ChartLoading.vue'
|
||
|
||
export default {
|
||
components: {
|
||
QiunDataCharts,
|
||
ChartLoading
|
||
},
|
||
|
||
data() {
|
||
return {
|
||
isLoading: false,
|
||
kpiData: {
|
||
totalSuppliers: 128,
|
||
avgDeliveryRate: 95.6,
|
||
inventoryTurnover: 12,
|
||
monthlyPurchase: 2800000
|
||
},
|
||
alertData: {
|
||
totalAlerts: 3
|
||
},
|
||
categoryData: [
|
||
{ name: '食品供应商', value: 35 },
|
||
{ name: '日用品供应商', value: 28 },
|
||
{ name: '服务类供应商', value: 22 },
|
||
{ name: '设备供应商', value: 18 },
|
||
{ name: '其他', value: 25 }
|
||
]
|
||
}
|
||
},
|
||
|
||
props: {
|
||
selectTime: {
|
||
type: String,
|
||
default: ""
|
||
}
|
||
},
|
||
|
||
computed: {
|
||
// 供应商类别饼图数据
|
||
categoryPieData() {
|
||
return {
|
||
series: [{
|
||
data: this.categoryData.filter(item => item.value > 0)
|
||
}]
|
||
}
|
||
},
|
||
|
||
// 供应商类别饼图配置
|
||
categoryPieOpts() {
|
||
return {
|
||
color: ['#9B7EDE', '#52C41A', '#1890FF', '#FF8F6F', '#FAAD14'],
|
||
padding: [15, 15, 15, 15],
|
||
dataLabel: false,
|
||
legend: {
|
||
show: true,
|
||
position: 'right',
|
||
float: 'center',
|
||
padding: 5,
|
||
margin: 10
|
||
},
|
||
extra: {
|
||
pie: {
|
||
activeOpacity: 0.5,
|
||
activeRadius: 10,
|
||
labelWidth: 0,
|
||
border: true,
|
||
borderWidth: 0,
|
||
borderColor: '#FFFFFF'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
onReady() {
|
||
this.loadData()
|
||
},
|
||
|
||
methods: {
|
||
async loadData() {
|
||
this.isLoading = true
|
||
// TODO: 实际API调用
|
||
setTimeout(() => {
|
||
this.isLoading = false
|
||
}, 500)
|
||
},
|
||
|
||
// 格式化金额,添加千分号
|
||
formatMoney(amount) {
|
||
if (!amount && amount !== 0) return '0'
|
||
return Number(amount).toLocaleString('zh-CN')
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="less">
|
||
@text-primary: #333;
|
||
@text-secondary: #666;
|
||
@bg-white: #ffffff;
|
||
|
||
.supplier-overview {
|
||
width: 100%;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
color: @text-primary;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
.metrics-row {
|
||
display: flex;
|
||
gap: 24rpx;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
.metric-card {
|
||
flex: 1;
|
||
background: @bg-white;
|
||
border-radius: 16rpx;
|
||
padding: 16rpx;
|
||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||
text-align: center;
|
||
}
|
||
|
||
.metric-value {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
display: block;
|
||
}
|
||
|
||
.metric-label {
|
||
font-size: 24rpx;
|
||
color: @text-secondary;
|
||
}
|
||
|
||
.chart-title {
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
color: @text-primary;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
.chart-section {
|
||
background: @bg-white;
|
||
border-radius: 16rpx;
|
||
padding: 24rpx 24rpx 0;
|
||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||
margin-bottom: 32rpx;
|
||
}
|
||
|
||
.chart-container {
|
||
width: 100%;
|
||
height: 400rpx;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.alert-card {
|
||
background: linear-gradient(135deg, #FF8F6F, #FF4D4F);
|
||
border-radius: 16rpx;
|
||
padding: 16rpx 24rpx;
|
||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 24rpx;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
.alert-icon {
|
||
font-size: 48rpx;
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
background: rgba(255, 255, 255, 0.2);
|
||
border-radius: 16rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.alert-content {
|
||
flex: 1;
|
||
}
|
||
|
||
.alert-title {
|
||
font-size: 24rpx;
|
||
color: #fff;
|
||
font-weight: 500;
|
||
margin-bottom: 8rpx;
|
||
display: block;
|
||
}
|
||
|
||
.alert-value {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 8rpx;
|
||
}
|
||
|
||
.alert-number {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #fff;
|
||
}
|
||
|
||
.alert-unit {
|
||
font-size: 24rpx;
|
||
color: rgba(255, 255, 255, 0.8);
|
||
}
|
||
</style>
|