UI修改
This commit is contained in:
parent
8f1840d823
commit
3b0a533934
|
|
@ -25,9 +25,9 @@
|
|||
<el-sub-menu v-if="canViewAllocations" index="allocations">
|
||||
<template #title>
|
||||
<el-icon><Box /></el-icon>
|
||||
<span>弹种配额</span>
|
||||
<span>训练消耗</span>
|
||||
</template>
|
||||
<el-menu-item index="/allocations">配额列表</el-menu-item>
|
||||
<el-menu-item index="/allocations">弹药指标</el-menu-item>
|
||||
<el-menu-item v-if="authStore.canCreateAllocations" index="/allocations/create">创建配额</el-menu-item>
|
||||
<el-menu-item index="/allocations/change-requests">删改申请</el-menu-item>
|
||||
</el-sub-menu>
|
||||
|
|
@ -41,10 +41,11 @@
|
|||
<el-menu-item index="/personnel/create">添加人才</el-menu-item>
|
||||
</el-sub-menu>
|
||||
|
||||
<el-menu-item v-if="authStore.canApprove" index="/approvals">
|
||||
<!-- 审批管理已隐藏,功能已整合到各业务页面 -->
|
||||
<!-- <el-menu-item v-if="authStore.canApprove" index="/approvals">
|
||||
<el-icon><Checked /></el-icon>
|
||||
<span>审批管理</span>
|
||||
</el-menu-item>
|
||||
</el-menu-item> -->
|
||||
|
||||
<el-menu-item v-if="authStore.hasPermission(1)" index="/audit-logs">
|
||||
<el-icon><Document /></el-icon>
|
||||
|
|
|
|||
|
|
@ -1,54 +1,69 @@
|
|||
<template>
|
||||
<div class="dashboard">
|
||||
<el-row :gutter="20">
|
||||
<!-- 师本部和团本部显示弹种配额 -->
|
||||
<el-col v-if="authStore.organizationalLevelNum <= 2" :span="6">
|
||||
<el-card class="stat-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<el-icon :size="24" color="#409EFF"><Box /></el-icon>
|
||||
<span>弹种配额</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="stat-value">{{ stats.allocations }}</div>
|
||||
<div class="stat-label">总配额条数</div>
|
||||
</el-card>
|
||||
<!-- 欢迎横幅 -->
|
||||
<div class="welcome-banner">
|
||||
<div class="welcome-content">
|
||||
<div class="welcome-text">
|
||||
<h1>欢迎回来,{{ authStore.user?.username }}</h1>
|
||||
<p>{{ currentDate }} · {{ levelName }}</p>
|
||||
</div>
|
||||
<div class="welcome-icon">
|
||||
<el-icon :size="64" color="rgba(255,255,255,0.8)"><Promotion /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<el-row :gutter="20" class="stat-row">
|
||||
<el-col v-if="authStore.organizationalLevelNum <= 2" :span="8">
|
||||
<div class="stat-card stat-card-blue">
|
||||
<div class="stat-icon">
|
||||
<el-icon :size="40"><Box /></el-icon>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<div class="stat-value">{{ stats.allocations }}</div>
|
||||
<div class="stat-label">弹种配额</div>
|
||||
</div>
|
||||
<div class="stat-decoration"></div>
|
||||
</div>
|
||||
</el-col>
|
||||
<!-- 师团级和团级显示完成率 -->
|
||||
<el-col v-if="authStore.organizationalLevelNum <= 2" :span="6">
|
||||
<el-card class="stat-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<el-icon :size="24" color="#67C23A"><DataAnalysis /></el-icon>
|
||||
<span>完成率</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="stat-value">{{ stats.completionRate }}%</div>
|
||||
<div class="stat-label">平均完成率</div>
|
||||
</el-card>
|
||||
<el-col v-if="authStore.organizationalLevelNum <= 2" :span="8">
|
||||
<div class="stat-card stat-card-green">
|
||||
<div class="stat-icon">
|
||||
<el-icon :size="40"><DataAnalysis /></el-icon>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<div class="stat-value">{{ stats.completionRate }}%</div>
|
||||
<div class="stat-label">平均完成率</div>
|
||||
</div>
|
||||
<div class="stat-decoration"></div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="authStore.organizationalLevelNum <= 2 ? 6 : 12">
|
||||
<el-card class="stat-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<el-icon :size="24" color="#E6A23C"><User /></el-icon>
|
||||
<span>人才管理</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="stat-value">{{ stats.personnel }}</div>
|
||||
<div class="stat-label">人员总数</div>
|
||||
</el-card>
|
||||
<el-col :span="authStore.organizationalLevelNum <= 2 ? 8 : 24">
|
||||
<div class="stat-card stat-card-orange">
|
||||
<div class="stat-icon">
|
||||
<el-icon :size="40"><User /></el-icon>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<div class="stat-value">{{ stats.personnel }}</div>
|
||||
<div class="stat-label">人才总数</div>
|
||||
</div>
|
||||
<div class="stat-decoration"></div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 饼状图区域 -->
|
||||
<el-row :gutter="20" class="mt-20">
|
||||
<el-row v-if="authStore.organizationalLevelNum <= 2" :gutter="20" class="chart-row">
|
||||
<el-col :span="24">
|
||||
<el-card>
|
||||
<el-card class="chart-card" shadow="hover">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<el-icon :size="24" color="#409EFF"><PieChart /></el-icon>
|
||||
<span>各团物资消耗情况</span>
|
||||
<div class="chart-header">
|
||||
<div class="chart-title">
|
||||
<el-icon :size="22" color="#409EFF"><PieChart /></el-icon>
|
||||
<span>各团物资消耗情况</span>
|
||||
</div>
|
||||
<el-tag type="info" effect="plain">实时数据</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
<div v-if="regimentStats.length > 0" class="pie-charts-container">
|
||||
|
|
@ -57,11 +72,20 @@
|
|||
:key="regiment.regimentId"
|
||||
class="pie-chart-item"
|
||||
>
|
||||
<v-chart :option="getPieOption(regiment)" autoresize class="pie-chart" />
|
||||
<div class="pie-chart-wrapper">
|
||||
<v-chart :option="getPieOption(regiment)" autoresize class="pie-chart" />
|
||||
</div>
|
||||
<div class="regiment-name">{{ regiment.regimentName }}</div>
|
||||
<div class="regiment-info">
|
||||
<span>配额: {{ regiment.totalQuota }}</span>
|
||||
<span>消耗: {{ regiment.totalConsumed }}</span>
|
||||
<div class="info-item">
|
||||
<span class="info-label">配额</span>
|
||||
<span class="info-value">{{ regiment.totalQuota }}</span>
|
||||
</div>
|
||||
<div class="info-divider"></div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">消耗</span>
|
||||
<span class="info-value consumed">{{ regiment.totalConsumed }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -69,15 +93,58 @@
|
|||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 快捷操作 -->
|
||||
<el-row :gutter="20" class="quick-actions-row">
|
||||
<el-col :span="24">
|
||||
<el-card class="quick-card" shadow="hover">
|
||||
<template #header>
|
||||
<div class="chart-header">
|
||||
<div class="chart-title">
|
||||
<el-icon :size="22" color="#E6A23C"><Operation /></el-icon>
|
||||
<span>快捷操作</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="quick-actions">
|
||||
<div v-if="authStore.organizationalLevelNum <= 2" class="action-item" @click="$router.push('/allocations')">
|
||||
<div class="action-icon action-icon-blue">
|
||||
<el-icon :size="28"><Box /></el-icon>
|
||||
</div>
|
||||
<span class="action-text">弹药指标</span>
|
||||
</div>
|
||||
<div class="action-item" @click="$router.push('/personnel')">
|
||||
<div class="action-icon action-icon-orange">
|
||||
<el-icon :size="28"><User /></el-icon>
|
||||
</div>
|
||||
<span class="action-text">人才管理</span>
|
||||
</div>
|
||||
<div class="action-item" @click="$router.push('/personnel/create')">
|
||||
<div class="action-icon action-icon-green">
|
||||
<el-icon :size="28"><Plus /></el-icon>
|
||||
</div>
|
||||
<span class="action-text">添加人才</span>
|
||||
</div>
|
||||
<div v-if="authStore.hasPermission(1)" class="action-item" @click="$router.push('/organizations')">
|
||||
<div class="action-icon action-icon-purple">
|
||||
<el-icon :size="28"><OfficeBuilding /></el-icon>
|
||||
</div>
|
||||
<span class="action-text">组织管理</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { statsApi, type RegimentAllocationStats } from '@/api/stats'
|
||||
import { Box, DataAnalysis, User, PieChart } from '@element-plus/icons-vue'
|
||||
import { Box, DataAnalysis, User, PieChart, Promotion, Operation, Plus, OfficeBuilding } from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { OrganizationalLevel } from '@/types'
|
||||
import VChart from 'vue-echarts'
|
||||
import { use } from 'echarts/core'
|
||||
import { PieChart as EchartsPie } from 'echarts/charts'
|
||||
|
|
@ -98,11 +165,26 @@ const stats = ref({
|
|||
const regimentStats = ref<RegimentAllocationStats[]>([])
|
||||
const loading = ref(false)
|
||||
|
||||
const currentDate = computed(() => {
|
||||
const now = new Date()
|
||||
const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
|
||||
return `${now.getFullYear()}年${now.getMonth() + 1}月${now.getDate()}日 ${weekDays[now.getDay()]}`
|
||||
})
|
||||
|
||||
const levelName = computed(() => {
|
||||
const level = authStore.user?.organizationalLevel
|
||||
switch (level) {
|
||||
case OrganizationalLevel.Division: return '师团级'
|
||||
case OrganizationalLevel.Regiment: return '团级'
|
||||
case OrganizationalLevel.Battalion: return '营级'
|
||||
case OrganizationalLevel.Company: return '连级'
|
||||
default: return ''
|
||||
}
|
||||
})
|
||||
|
||||
function getPieOption(regiment: RegimentAllocationStats) {
|
||||
const consumed = regiment.totalConsumed
|
||||
const remaining = regiment.totalQuota - consumed
|
||||
|
||||
// 当配额为0时,显示全灰色
|
||||
const hasData = regiment.totalQuota > 0
|
||||
|
||||
return {
|
||||
|
|
@ -113,20 +195,20 @@ function getPieOption(regiment: RegimentAllocationStats) {
|
|||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['50%', '70%'],
|
||||
radius: ['55%', '75%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: `${regiment.percentage}%`,
|
||||
fontSize: 18,
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
color: '#303133'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 20,
|
||||
fontSize: 22,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
|
|
@ -160,7 +242,6 @@ async function loadStats() {
|
|||
async function loadRegimentStats() {
|
||||
try {
|
||||
const data = await statsApi.getRegimentAllocationsStats()
|
||||
console.log('Regiment stats loaded:', data)
|
||||
regimentStats.value = data
|
||||
} catch (error) {
|
||||
console.error('加载团级统计数据失败', error)
|
||||
|
|
@ -175,39 +256,144 @@ onMounted(() => {
|
|||
|
||||
<style scoped>
|
||||
.dashboard {
|
||||
padding: 10px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* 欢迎横幅 */
|
||||
.welcome-banner {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 12px;
|
||||
padding: 24px 32px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
|
||||
.welcome-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.welcome-text h1 {
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
margin: 0 0 8px 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.welcome-text p {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.welcome-icon {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* 统计卡片 */
|
||||
.stat-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
position: relative;
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
overflow: hidden;
|
||||
transition: transform 0.3s, box-shadow 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.stat-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.stat-card-blue {
|
||||
background: linear-gradient(135deg, #409EFF 0%, #66b1ff 100%);
|
||||
}
|
||||
|
||||
.stat-card-green {
|
||||
background: linear-gradient(135deg, #67C23A 0%, #85ce61 100%);
|
||||
}
|
||||
|
||||
.stat-card-orange {
|
||||
background: linear-gradient(135deg, #E6A23C 0%, #ebb563 100%);
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
flex: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 32px;
|
||||
font-size: 36px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
color: #fff;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
color: #909399;
|
||||
margin-top: 8px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-size: 14px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.mt-20 {
|
||||
margin-top: 20px;
|
||||
.stat-decoration {
|
||||
position: absolute;
|
||||
right: -20px;
|
||||
bottom: -20px;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
/* 图表区域 */
|
||||
.chart-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.chart-card {
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.chart-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.pie-charts-container {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
gap: 24px;
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.pie-chart-item {
|
||||
|
|
@ -216,17 +402,30 @@ onMounted(() => {
|
|||
align-items: center;
|
||||
flex: 1;
|
||||
min-width: 180px;
|
||||
max-width: 220px;
|
||||
max-width: 240px;
|
||||
padding: 16px;
|
||||
border-radius: 12px;
|
||||
background: #f8f9fa;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.pie-chart-item:hover {
|
||||
background: #f0f2f5;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.pie-chart-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pie-chart {
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
}
|
||||
|
||||
.regiment-name {
|
||||
margin-top: 8px;
|
||||
font-size: 16px;
|
||||
margin-top: 12px;
|
||||
font-size: 20px;
|
||||
color: #303133;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
|
|
@ -234,9 +433,104 @@ onMounted(() => {
|
|||
|
||||
.regiment-info {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-top: 12px;
|
||||
padding: 8px 16px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.info-value.consumed {
|
||||
color: #67C23A;
|
||||
}
|
||||
|
||||
.info-divider {
|
||||
width: 1px;
|
||||
height: 24px;
|
||||
background: #e4e7ed;
|
||||
}
|
||||
|
||||
/* 快捷操作 */
|
||||
.quick-actions-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.quick-card {
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.quick-actions {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px 32px;
|
||||
border-radius: 12px;
|
||||
background: #f8f9fa;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.action-item:hover {
|
||||
background: #f0f2f5;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.action-icon-blue {
|
||||
background: linear-gradient(135deg, #409EFF 0%, #66b1ff 100%);
|
||||
}
|
||||
|
||||
.action-icon-green {
|
||||
background: linear-gradient(135deg, #67C23A 0%, #85ce61 100%);
|
||||
}
|
||||
|
||||
.action-icon-orange {
|
||||
background: linear-gradient(135deg, #E6A23C 0%, #ebb563 100%);
|
||||
}
|
||||
|
||||
.action-icon-purple {
|
||||
background: linear-gradient(135deg, #9b59b6 0%, #b07cc6 100%);
|
||||
}
|
||||
|
||||
.action-text {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
margin-top: 6px;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="login-container">
|
||||
<div class="login-box">
|
||||
<h1 class="login-title">兵团训练物资管控系统</h1>
|
||||
<h1 class="login-title">军事训练管理系统</h1>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
|
|
|
|||
|
|
@ -21,11 +21,19 @@
|
|||
</template>
|
||||
</el-input>
|
||||
<el-select v-model="categoryFilter" placeholder="类别筛选" clearable style="width: 120px; margin-right: 12px">
|
||||
<el-option label="弹药" value="弹药" />
|
||||
<el-option label="装备" value="装备" />
|
||||
<el-option label="其他" value="其他" />
|
||||
<el-option label="器材" value="器材" />
|
||||
<el-option v-for="cat in categories" :key="cat.id" :label="cat.name" :value="cat.name" />
|
||||
</el-select>
|
||||
<el-input
|
||||
v-if="authStore.organizationalLevelNum === 1"
|
||||
v-model="unitFilter"
|
||||
placeholder="搜索单位"
|
||||
clearable
|
||||
style="width: 140px; margin-right: 12px"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><OfficeBuilding /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button v-if="authStore.canCreateAllocations" @click="$router.push('/allocations/categories')">
|
||||
<el-icon><Setting /></el-icon>
|
||||
类别管理
|
||||
|
|
@ -315,7 +323,7 @@
|
|||
:header-cell-style="{ background: '#f5f7fa', color: '#606266', fontWeight: 'bold', fontSize: '14px' }"
|
||||
:row-style="{ height: '60px' }"
|
||||
>
|
||||
<el-table-column prop="targetUnitName" label="目标单位" min-width="150">
|
||||
<el-table-column prop="targetUnitName" label="单位" min-width="150">
|
||||
<template #default="{ row }">
|
||||
<div class="unit-cell">
|
||||
<el-icon class="unit-icon" :size="16"><OfficeBuilding /></el-icon>
|
||||
|
|
@ -323,7 +331,7 @@
|
|||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="unitQuota" label="分配配额" width="120" align="center">
|
||||
<el-table-column prop="unitQuota" label="总配额" width="120" align="center">
|
||||
<template #default="{ row }">
|
||||
<div class="quota-cell-dialog">
|
||||
<span class="quota-number-dialog">{{ formatNumber(row.unitQuota) }}</span>
|
||||
|
|
@ -557,7 +565,7 @@ import { useRouter } from 'vue-router'
|
|||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Plus, Search, View, Edit, Delete, Box, Setting, OfficeBuilding, Clock } from '@element-plus/icons-vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { allocationsApi, type UnitReportSummary, type UnitConsumptionStat } from '@/api'
|
||||
import { allocationsApi, materialCategoriesApi, type UnitReportSummary, type UnitConsumptionStat } from '@/api'
|
||||
import type { MaterialAllocation, AllocationDistribution } from '@/types'
|
||||
|
||||
const router = useRouter()
|
||||
|
|
@ -568,6 +576,7 @@ const distributions = ref<AllocationDistribution[]>([])
|
|||
const consumptionReports = ref<any[]>([])
|
||||
const unitSummaries = ref<UnitReportSummary[]>([])
|
||||
const consumptionStats = ref<UnitConsumptionStat[]>([])
|
||||
const categories = ref<{ id: number; name: string }[]>([])
|
||||
const reportsTabActive = ref('summary')
|
||||
const loading = ref(false)
|
||||
const loadingReports = ref(false)
|
||||
|
|
@ -576,6 +585,7 @@ const showDistributionDialog = ref(false)
|
|||
const showReportsDialog = ref(false)
|
||||
const searchKeyword = ref('')
|
||||
const categoryFilter = ref('')
|
||||
const unitFilter = ref('')
|
||||
const selectedAllocation = ref<MaterialAllocation | null>(null)
|
||||
const selectedDistribution = ref<AllocationDistribution | null>(null)
|
||||
const selectedPeriod = ref('all')
|
||||
|
|
@ -621,6 +631,12 @@ const filteredAllocations = computed(() => {
|
|||
if (categoryFilter.value) {
|
||||
result = result.filter(a => a.category === categoryFilter.value)
|
||||
}
|
||||
if (unitFilter.value) {
|
||||
const keyword = unitFilter.value.toLowerCase()
|
||||
result = result.filter(a =>
|
||||
a.distributions?.some(d => d.targetUnitName?.toLowerCase().includes(keyword))
|
||||
)
|
||||
}
|
||||
return result
|
||||
})
|
||||
|
||||
|
|
@ -1110,7 +1126,16 @@ async function handleDelete(allocation: MaterialAllocation) {
|
|||
|
||||
onMounted(() => {
|
||||
loadAllocations()
|
||||
loadCategories()
|
||||
})
|
||||
|
||||
async function loadCategories() {
|
||||
try {
|
||||
categories.value = await materialCategoriesApi.getAll()
|
||||
} catch {
|
||||
console.error('加载类别失败')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user