Files
xgy-oa/klp-ui/src/components/HomeModules/StatisticGroup.vue
砂糖 e900aec86b feat(销售权限): 实现钢卷销售权限分配功能
新增销售权限管理模块,包含以下功能:
1. 在用户模块添加id字段用于权限控制
2. 重构CoilSelector组件支持销售视角权限过滤
3. 新增销售权限分配页面,支持钢卷分配与移除
4. 优化表格样式和交互体验

组件现在支持根据用户权限动态显示和过滤钢卷数据,管理员可在新页面为销售分配钢卷权限
2025-12-18 11:51:14 +08:00

288 lines
7.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-row :gutter="10" class="panel-group">
<el-col v-loading="loading" :xs="12" :sm="12" :md="8" :lg="4" :xl="4" class="card-panel-col"
v-for="(item, index) in statsData" :key="index">
<div class="card-panel" @click="handleSetLineChartData(item.type)">
<div class="card-panel-icon-wrapper" :class="item.iconClass">
<svg-icon :icon-class="item.icon" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
{{ item.title }}
</div>
<count-to :start-val="0" :end-val="item.value" :duration="item.duration" class="card-panel-num" />
</div>
</div>
</el-col>
</el-row>
</template>
<script>
import CountTo from 'vue-count-to'
import { listProduct } from '@/api/wms/product'
import { listRawMaterial } from '@/api/wms/rawMaterial'
import { listMaterialCoil } from '@/api/wms/coil'
import { listEquipmentManagement } from '@/api/mes/eqp/equipmentManagement'
import { listOrder } from '@/api/crm/order'
import { listCustomer } from '@/api/crm/customer'
// import { listSupplier } from '@/api/wms/supplier'
export default {
components: {
CountTo
},
data() {
return {
statsData: [
{
type: 'materialCount',
title: '物料类型',
icon: 'international',
iconClass: 'icon-material',
value: 0,
duration: 2600
},
{
type: 'steelCoilCount',
title: '钢卷数量',
icon: 'coil',
iconClass: 'icon-steel',
value: 0,
duration: 3000
},
{
type: 'orderCount',
title: '订单数量',
icon: 'log',
iconClass: 'icon-order',
value: 0,
duration: 3200
},
{
type: 'customerCount',
title: '客户',
icon: 'people',
iconClass: 'icon-customer',
value: 0,
duration: 3600
},
// {
// type: 'supplierCount',
// title: '供应商',
// icon: 'peoples',
// iconClass: 'icon-supplier',
// value: 0,
// duration: 3600
// },
{
type: 'equipmentCount',
title: '设备数量',
icon: 'redis',
iconClass: 'icon-equipment',
value: 0,
duration: 2800
}
],
loading: false,
}
},
mounted() {
this.fetchStatsData()
},
methods: {
handleSetLineChartData(type) {
this.$emit('handleSetLineChartData', type)
},
// 假设这段代码在一个方法中,给方法添加 async 关键字
async fetchStatsData() {
this.loading = true; // 先开启加载状态
try {
// 顺序请求:前一个请求完成后,再执行下一个
const productRes = await listProduct({ pageSize: 10, pageNum: 1 });
const rawMaterialRes = await listRawMaterial({ pageSize: 10, pageNum: 1 });
const materialCoilRes = await listMaterialCoil({ pageSize: 10, pageNum: 1, dataType: 1 });
const equipmentRes = await listEquipmentManagement({ pageSize: 1, pageNum: 1, status: 'in_service' });
const orderRes = await listOrder({ pageSize: 1, pageNum: 1 });
const customerRes = await listCustomer({ pageSize: 1, pageNum: 1 });
// 如果需要供应商数据,取消下面这行注释(与原代码注释对应)
// const supplierRes = await listSupplier({ pageSize: 1, pageNum: 1 });
// 处理统计数据注意如果不请求supplierRes需注释掉对应的逻辑
this.statsData.forEach(item => {
if (item.type === 'materialCount') {
item.value = (productRes.total || 0) + (rawMaterialRes.total || 0);
} else if (item.type === 'steelCoilCount') {
item.value = materialCoilRes.total || 0;
} else if (item.type === 'orderCount') {
item.value = orderRes.total || 0;
} else if (item.type === 'customerCount') {
item.value = customerRes.total || 0;
} else if (item.type === 'supplierCount') {
// 如果不请求供应商数据这里可以设置默认值如0或注释掉
item.value = 0; // 若取消了supplierRes的请求注释这里改为 supplierRes.total || 0
} else if (item.type === 'equipmentCount') {
item.value = equipmentRes.total || 0;
}
});
} catch (error) {
// 处理请求失败的情况(如打印错误、提示用户等)
console.error('统计数据请求失败:', error);
} finally {
// 无论成功失败,最终关闭加载状态
this.loading = false;
}
}
}
}
</script>
<style lang="scss" scoped>
.panel-group {
margin-top: 18px;
.card-panel-col {
margin-bottom: 32px;
}
.card-panel {
height: 108px;
cursor: pointer;
font-size: 12px;
position: relative;
overflow: hidden;
color: #666;
background: #fff;
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
border-color: rgba(0, 0, 0, .05);
&:hover {
.card-panel-icon-wrapper {
color: #fff;
}
.icon-material {
background: #40c9c6;
}
.icon-steel {
background: #36a3f7;
}
.icon-order {
background: #f4516c;
}
.icon-customer {
background: #34bfa3;
}
.icon-equipment {
background: #722ed1;
}
.icon-supplier {
background: #ffed65;
}
}
.icon-material {
color: #40c9c6;
}
.icon-steel {
color: #36a3f7;
}
.icon-order {
color: #f4516c;
}
.icon-customer {
color: #34bfa3;
}
.icon-equipment {
color: #722ed1;
}
.icon-supplier {
color: #ffed65;
}
.card-panel-icon-wrapper {
float: left;
margin: 14px 0 0 14px;
padding: 16px;
transition: all 0.38s ease-out;
border-radius: 6px;
}
.card-panel-icon {
float: left;
font-size: 48px;
}
.card-panel-description {
float: right;
font-weight: bold;
margin: 26px;
margin-left: 0px;
.card-panel-text {
line-height: 18px;
color: rgba(0, 0, 0, 0.45);
font-size: 16px;
margin-bottom: 12px;
white-space: nowrap;
}
.card-panel-num {
font-size: 20px;
}
}
}
}
@media (max-width: 992px) {
.card-panel-description .card-panel-text {
font-size: 14px;
}
.card-panel-num {
font-size: 18px !important;
}
}
@media (max-width: 768px) {
.card-panel-description {
margin: 16px;
}
.card-panel-icon-wrapper {
padding: 12px;
}
.card-panel-icon {
font-size: 40px;
}
}
@media (max-width: 550px) {
.card-panel-description {
display: none;
}
.card-panel-icon-wrapper {
float: none !important;
width: 100%;
height: 100%;
margin: 0 !important;
.svg-icon {
display: block;
margin: 14px auto !important;
float: none !important;
}
}
}
</style>