<template>
|
<div class="project-management-container">
|
<!-- 数据概览卡片 -->
|
<div class="overview-cards">
|
<el-card class="overview-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-icon" style="background-color: #409EFF20;">
|
<i class="el-icon-s-data" style="color: #409EFF;"></i>
|
</div>
|
<div class="card-info">
|
<div class="card-title">项目总数</div>
|
<div class="card-value">{{ overviewData.totalProjects }}</div>
|
</div>
|
</div>
|
</el-card>
|
|
<el-card class="overview-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-icon" style="background-color: #67C23A20;">
|
<i class="el-icon-success" style="color: #67C23A;"></i>
|
</div>
|
<div class="card-info">
|
<div class="card-title">进行中</div>
|
<div class="card-value">{{ overviewData.inProgress }}</div>
|
</div>
|
</div>
|
</el-card>
|
|
<el-card class="overview-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-icon" style="background-color: #E6A23C20;">
|
<i class="el-icon-warning" style="color: #E6A23C;"></i>
|
</div>
|
<div class="card-info">
|
<div class="card-title">有风险</div>
|
<div class="card-value">{{ overviewData.atRisk }}</div>
|
</div>
|
</div>
|
</el-card>
|
|
<el-card class="overview-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-icon" style="background-color: #F56C6C20;">
|
<i class="el-icon-error" style="color: #F56C6C;"></i>
|
</div>
|
<div class="card-info">
|
<div class="card-title">已延期</div>
|
<div class="card-value">{{ overviewData.delayed }}</div>
|
</div>
|
</div>
|
</el-card>
|
</div>
|
|
<!-- 主要内容区域 -->
|
<div class="main-content">
|
<!-- 左侧内容 -->
|
<div class="left-content">
|
<!-- 项目进度图表 -->
|
<el-card class="chart-card" style="min-height: 400px" shadow="hover">
|
<div slot="header" class="clearfix row">
|
<div style="flex: 1">项目进度统计</div>
|
<div style="flex: 3;display: flex;justify-content: flex-end">
|
<el-select
|
v-model="selectedMonth"
|
placeholder="选择月份"
|
style="width: 120px; margin-right: 10px;"
|
@change="updateProgressChart"
|
>
|
<el-option
|
v-for="month in months"
|
:key="month.value"
|
:label="month.label"
|
:value="month.value"
|
></el-option>
|
</el-select>
|
<el-select
|
v-model="selectedProjects"
|
multiple
|
collapse-tags
|
placeholder="选择项目"
|
style="width: 350px; margin-right: 10px;"
|
@change="updateProgressChart"
|
>
|
<el-option
|
v-for="project in allProjects"
|
:key="project.id"
|
:label="project.name"
|
:value="project.id"
|
></el-option>
|
</el-select>
|
<el-button type="text" @click="showDetail">详情</el-button>
|
</div>
|
</div>
|
<div class="chart-container" ref="progressChart" style="height: 400px;"></div>
|
</el-card>
|
|
<!-- 卡点任务列表 -->
|
<el-card class="blocking-tasks-card" shadow="hover">
|
<div slot="header" class="clearfix row">
|
<div style="flex: 1">推进卡点</div>
|
<div style="flex: 3; display: flex; justify-content: flex-end">
|
<el-button type="text">全部</el-button>
|
</div>
|
</div>
|
<el-table :data="blockingTasks" style="width: 100%" height="250">
|
<el-table-column prop="taskName" label="任务名称" width="180"></el-table-column>
|
<el-table-column prop="project" label="所属项目"></el-table-column>
|
<el-table-column prop="owner" label="负责人" width="100"></el-table-column>
|
<el-table-column prop="startTime" label="开始时间" width="120"></el-table-column>
|
<el-table-column prop="deadline" label="截止日期" width="120"></el-table-column>
|
<el-table-column prop="overTime" label="已超时" width="120"></el-table-column>
|
<el-table-column prop="totalOverTimes" label="累计超时次数" width="120" align="center"></el-table-column>
|
<el-table-column label="操作" width="80">
|
<template slot-scope="scope">
|
<el-button size="mini" @click="handleTaskDetail(scope.row)">查看</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
</el-card>
|
</div>
|
|
<!-- 右侧内容 -->
|
<div class="right-content">
|
<!-- 资金使用情况 -->
|
<el-card class="chart-card" style="min-height: 400px" shadow="hover">
|
<div slot="header" class="clearfix">
|
<span>资金情况</span>
|
<div style="float: right;">
|
<el-select
|
v-model="fundSelectedProjects"
|
multiple
|
collapse-tags
|
placeholder="选择项目"
|
style="width: 350px; margin-right: 10px;"
|
@change="updateFundChart"
|
>
|
<el-option
|
v-for="project in allProjects"
|
:key="project.id"
|
:label="project.name"
|
:value="project.id"
|
></el-option>
|
</el-select>
|
<el-button type="text" @click="showFundDetail">详情</el-button>
|
</div>
|
</div>
|
<div class="chart-container" ref="fundChart" style="height: 400px;"></div>
|
</el-card>
|
|
<!-- 项目阶段统计 -->
|
<el-card class="chart-card" shadow="hover">
|
<div slot="header" class="clearfix row">
|
<div style="flex:1">项目阶段统计</div>
|
<div style="flex:3;display: flex;justify-content: flex-end">
|
<el-button type="text">详情</el-button>
|
</div>
|
</div>
|
<div class="chart-container" ref="stageChart" style="height: 250px;"></div>
|
</el-card>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import * as echarts from 'echarts';
|
|
export default {
|
name: 'ProjectManagement',
|
data() {
|
return {
|
userName: '张经理',
|
userAvatar: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
|
overviewData: {
|
totalProjects: 42,
|
inProgress: 28,
|
atRisk: 7,
|
delayed: 5
|
},
|
blockingTasks: [
|
{
|
taskName: '取得土地权属',
|
project: '射洪市酒粮基地建设项目',
|
owner: '李四',
|
startTime: '2025-05-15',
|
overTime: '10天06小时',
|
deadline: '2025-06-05',
|
totalOverTimes: 4,
|
status: '紧急'
|
},
|
{
|
taskName: '可行性研究报告申请',
|
project: '射洪市酒粮基地建设项目',
|
owner: '王五',
|
startTime: '2025-05-21',
|
overTime: '8天',
|
deadline: '2025-05-30',
|
totalOverTimes: '5',
|
status: '高风险'
|
},
|
{
|
taskName: '建设工程竣工验收申请',
|
project: '射洪市宜居宜业和美乡村建设项目',
|
owner: '赵六',
|
startTime: '2025-05-24',
|
overTime: '4天14小时',
|
deadline: '2025-06-04',
|
totalOverTimes: '4',
|
status: '延期'
|
},
|
{
|
taskName: '生产建设项目水土保持方案编制',
|
project: '射洪市宜居宜业和美乡村建设项目',
|
owner: '钱七',
|
startTime: '2025-06-01',
|
overTime: '4天',
|
deadline: '2025-06-07',
|
totalOverTimes: '6',
|
status: '进行中'
|
},
|
],
|
progressChart: null,
|
fundChart: null,
|
stageChart: null,
|
// 筛选数据
|
selectedMonth: '2025-06',
|
months: [
|
{ value: '2025-05', label: '2025年5月' },
|
{ value: '2025-06', label: '2025年6月' },
|
{ value: '2025-07', label: '2025年7月' },
|
{ value: '2025-08', label: '2025年8月' }
|
],
|
selectedProjects: [],
|
fundSelectedProjects: [],
|
allProjects: [
|
{ id: 'p1', name: '射洪市国家储备林建设项目(一期)' },
|
{ id: 'p2', name: '射洪市白羽肉鸡产业建设项目' },
|
{ id: 'p3', name: '遂宁市射洪2024—2027年度东北片区高标准农田建设项目' },
|
{ id: 'p4', name: '射洪市现代种业示范基地建设项目' },
|
{ id: 'p5', name: '射洪市宜居宜业和美乡村建设项目' },
|
{ id: 'p6', name: '射洪市沱牌镇综合水利设施建设项目' }
|
],
|
// 项目进度模拟数据
|
progressData: {
|
'2025-05': {
|
'p1': { completed: 30, inProgress: 50, notStarted: 20 },
|
'p2': { completed: 40, inProgress: 40, notStarted: 20 },
|
'p3': { completed: 10, inProgress: 60, notStarted: 30 },
|
'p4': { completed: 60, inProgress: 30, notStarted: 10 },
|
'p5': { completed: 25, inProgress: 45, notStarted: 30 },
|
'p6': { completed: 35, inProgress: 35, notStarted: 30 }
|
},
|
'2025-06': {
|
'p1': { completed: 50, inProgress: 40, notStarted: 10 },
|
'p2': { completed: 60, inProgress: 30, notStarted: 10 },
|
'p3': { completed: 30, inProgress: 50, notStarted: 20 },
|
'p4': { completed: 80, inProgress: 15, notStarted: 5 },
|
'p5': { completed: 45, inProgress: 35, notStarted: 20 },
|
'p6': { completed: 55, inProgress: 25, notStarted: 20 }
|
},
|
'2025-07': {
|
'p1': { completed: 70, inProgress: 25, notStarted: 5 },
|
'p2': { completed: 80, inProgress: 15, notStarted: 5 },
|
'p3': { completed: 50, inProgress: 40, notStarted: 10 },
|
'p4': { completed: 90, inProgress: 10, notStarted: 0 },
|
'p5': { completed: 65, inProgress: 25, notStarted: 10 },
|
'p6': { completed: 75, inProgress: 15, notStarted: 10 }
|
},
|
'2025-08': {
|
'p1': { completed: 90, inProgress: 10, notStarted: 0 },
|
'p2': { completed: 95, inProgress: 5, notStarted: 0 },
|
'p3': { completed: 70, inProgress: 25, notStarted: 5 },
|
'p4': { completed: 100, inProgress: 0, notStarted: 0 },
|
'p5': { completed: 85, inProgress: 10, notStarted: 5 },
|
'p6': { completed: 90, inProgress: 5, notStarted: 5 }
|
}
|
},
|
// 资金使用模拟数据
|
fundData: {
|
'p1': {
|
total: 5000,
|
allocated: 3500,
|
remaining: 1500,
|
completed: 2800,
|
sources: {
|
projectCapital: 2000,
|
countyInvestment: 1500,
|
otherInvestment: 1000,
|
governmentInvestment: 500
|
}
|
},
|
'p2': {
|
total: 3200,
|
allocated: 2500,
|
remaining: 700,
|
completed: 1800,
|
sources: {
|
projectCapital: 1200,
|
countyInvestment: 1000,
|
governmentInvestment: 1000
|
}
|
},
|
'p3': {
|
total: 4200,
|
allocated: 3000,
|
remaining: 1200,
|
completed: 2200,
|
sources: {
|
projectCapital: 1500,
|
otherInvestment: 1200,
|
governmentInvestment: 1500
|
}
|
},
|
'p4': {
|
total: 2800,
|
allocated: 2000,
|
remaining: 800,
|
completed: 1500,
|
sources: {
|
projectCapital: 1000,
|
countyInvestment: 800,
|
otherInvestment: 500,
|
governmentInvestment: 500
|
}
|
},
|
'p5': {
|
total: 3800,
|
allocated: 3000,
|
remaining: 800,
|
completed: 2500,
|
sources: {
|
projectCapital: 1500,
|
countyInvestment: 1000,
|
governmentInvestment: 1300
|
}
|
},
|
'p6': {
|
total: 4500,
|
allocated: 3500,
|
remaining: 1000,
|
completed: 3000,
|
sources: {
|
projectCapital: 2000,
|
countyInvestment: 1500,
|
otherInvestment: 500,
|
governmentInvestment: 500
|
}
|
}
|
}
|
};
|
},
|
mounted() {
|
this.selectedProjects = this.allProjects.map(p => p.id); // 默认全选
|
this.fundSelectedProjects = this.allProjects.map(p => p.id); // 默认全选
|
this.initCharts();
|
window.addEventListener('resize', this.handleResize);
|
},
|
beforeDestroy() {
|
window.removeEventListener('resize', this.handleResize);
|
if (this.progressChart) {
|
this.progressChart.dispose();
|
}
|
if (this.fundChart) {
|
this.fundChart.dispose();
|
}
|
if (this.stageChart) {
|
this.stageChart.dispose();
|
}
|
},
|
methods: {
|
initCharts() {
|
// 初始化项目进度图表
|
this.progressChart = echarts.init(this.$refs.progressChart);
|
this.updateProgressChart();
|
|
// 初始化资金使用情况图表
|
this.fundChart = echarts.init(this.$refs.fundChart);
|
this.updateFundChart();
|
|
// 初始化项目阶段统计图表
|
this.stageChart = echarts.init(this.$refs.stageChart);
|
this.stageChart.setOption({
|
tooltip: {
|
trigger: 'axis',
|
axisPointer: {
|
type: 'shadow'
|
}
|
},
|
grid: {
|
left: '3%',
|
right: '4%',
|
bottom: '3%',
|
containLabel: true
|
},
|
xAxis: {
|
type: 'category',
|
data: ['在库', '储备', '前期', '实施', '竣工'],
|
axisLine: {
|
lineStyle: {
|
color: '#409EFF'
|
}
|
}
|
},
|
yAxis: {
|
type: 'value',
|
axisLine: {
|
lineStyle: {
|
color: '#409EFF'
|
}
|
}
|
},
|
series: [
|
{
|
data: [15, 12, 10, 8, 6, 4, 2],
|
type: 'line',
|
smooth: true,
|
lineStyle: {
|
width: 3,
|
color: '#409EFF'
|
},
|
itemStyle: {
|
color: '#409EFF'
|
},
|
areaStyle: {
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
{
|
offset: 0,
|
color: 'rgba(64, 158, 255, 0.5)'
|
},
|
{
|
offset: 1,
|
color: 'rgba(64, 158, 255, 0.1)'
|
}
|
])
|
}
|
}
|
]
|
});
|
},
|
|
// 更新项目进度图表数据
|
updateProgressChart() {
|
if (!this.progressChart) return;
|
|
const monthData = this.progressData[this.selectedMonth];
|
const filteredProjects = this.allProjects.filter(p =>
|
this.selectedProjects.includes(p.id)
|
);
|
|
const categories = filteredProjects.map(p => p.name);
|
const completedData = filteredProjects.map(p => monthData[p.id].completed);
|
const inProgressData = filteredProjects.map(p => monthData[p.id].inProgress);
|
const notStartedData = filteredProjects.map(p => monthData[p.id].notStarted);
|
|
this.progressChart.setOption({
|
tooltip: {
|
trigger: 'axis',
|
axisPointer: {
|
type: 'shadow'
|
},
|
formatter: function(params) {
|
let result = params[0].name + '<br/>';
|
params.forEach(param => {
|
result += `${param.seriesName}: ${param.value}%<br/>`;
|
});
|
result += `总计: ${params.reduce((sum, param) => sum + param.value, 0)}%`;
|
return result;
|
}
|
},
|
legend: {
|
data: ['已完成事项', '进行中事项', '未开始事项']
|
},
|
grid: {
|
left: '3%',
|
right: '4%',
|
bottom: '3%',
|
containLabel: true
|
},
|
xAxis: {
|
type: 'value',
|
max: 100,
|
axisLabel: {
|
formatter: '{value}%'
|
}
|
},
|
yAxis: {
|
type: 'category',
|
data: categories
|
},
|
series: [
|
{
|
name: '已完成事项',
|
type: 'bar',
|
stack: 'total',
|
emphasis: {
|
focus: 'series'
|
},
|
data: completedData,
|
itemStyle: {
|
color: '#67C23A'
|
},
|
label: {
|
show: true,
|
position: 'inside',
|
formatter: '{c}%'
|
}
|
},
|
{
|
name: '进行中事项',
|
type: 'bar',
|
stack: 'total',
|
emphasis: {
|
focus: 'series'
|
},
|
data: inProgressData,
|
itemStyle: {
|
color: '#409EFF'
|
},
|
label: {
|
show: true,
|
position: 'inside',
|
formatter: '{c}%'
|
}
|
},
|
{
|
name: '未开始事项',
|
type: 'bar',
|
stack: 'total',
|
emphasis: {
|
focus: 'series'
|
},
|
data: notStartedData,
|
itemStyle: {
|
color: '#E6A23C'
|
},
|
label: {
|
show: true,
|
position: 'inside',
|
formatter: '{c}%'
|
}
|
}
|
]
|
});
|
},
|
|
// 更新资金使用图表数据
|
updateFundChart() {
|
if (!this.fundChart) return;
|
|
const filteredProjects = this.allProjects.filter(p =>
|
this.fundSelectedProjects.includes(p.id)
|
);
|
|
const categories = filteredProjects.map(p => p.name);
|
const allocatedData = filteredProjects.map(p => this.fundData[p.id].allocated);
|
const remainingData = filteredProjects.map(p => this.fundData[p.id].remaining);
|
|
// 资金来源数据
|
const projectCapitalData = filteredProjects.map(p =>
|
this.fundData[p.id].sources.projectCapital || 0
|
);
|
const countyInvestmentData = filteredProjects.map(p =>
|
this.fundData[p.id].sources.countyInvestment || 0
|
);
|
const otherInvestmentData = filteredProjects.map(p =>
|
this.fundData[p.id].sources.otherInvestment || 0
|
);
|
const governmentInvestmentData = filteredProjects.map(p =>
|
this.fundData[p.id].sources.governmentInvestment || 0
|
);
|
|
this.fundChart.setOption({
|
tooltip: {
|
trigger: 'axis',
|
axisPointer: {
|
type: 'shadow'
|
},
|
formatter: function(params) {
|
let result = params[0].name + '<br/>';
|
// 资金拨付和剩余
|
result += `资金拨付: ${params[0].value}万元<br/>`;
|
result += `剩余金额: ${params[1].value}万元<br/>`;
|
result += `总金额: ${params[0].value + params[1].value}万元<br/>`;
|
result += `完成投资: ${params[0].axisValueLabel}万元<br/><br/>`;
|
|
// 资金来源
|
result += '<strong>资金来源构成:</strong><br/>';
|
result += `项目本金: ${params[2].value}万元<br/>`;
|
result += `县(市、区)投资: ${params[3].value}万元<br/>`;
|
result += `其他投资: ${params[4].value}万元<br/>`;
|
result += `政府投资: ${params[5].value}万元<br/>`;
|
|
return result;
|
}
|
},
|
legend: {
|
data: ['剩余金额', '资金拨付', '项目本金', '县(市、区)投资', '政府投资', '其他投资']
|
},
|
grid: {
|
top: '30%',
|
left: '3%',
|
right: '4%',
|
bottom: '5%',
|
containLabel: true
|
},
|
xAxis: {
|
type: 'category',
|
data: categories,
|
axisLabel: {
|
interval: 0,
|
rotate: 30
|
}
|
},
|
yAxis: {
|
type: 'value',
|
name: '金额(万元)'
|
},
|
series: [
|
{
|
name: '资金拨付',
|
type: 'bar',
|
stack: 'total',
|
emphasis: {
|
focus: 'series'
|
},
|
data: allocatedData,
|
itemStyle: {
|
color: '#409EFF'
|
},
|
label: {
|
show: true,
|
position: 'inside',
|
formatter: '{c}'
|
}
|
},
|
{
|
name: '剩余金额',
|
type: 'bar',
|
stack: 'total',
|
emphasis: {
|
focus: 'series'
|
},
|
data: remainingData,
|
itemStyle: {
|
color: '#E6A23C'
|
},
|
label: {
|
show: true,
|
position: 'inside',
|
formatter: '{c}'
|
}
|
},
|
{
|
name: '项目本金',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: projectCapitalData,
|
itemStyle: {
|
color: '#67C23A'
|
}
|
},
|
{
|
name: '县(市、区)投资',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: countyInvestmentData,
|
itemStyle: {
|
color: '#F56C6C'
|
}
|
},
|
{
|
name: '其他投资',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: otherInvestmentData,
|
itemStyle: {
|
color: '#909399'
|
}
|
},
|
{
|
name: '政府投资',
|
type: 'bar',
|
stack: 'sources',
|
emphasis: {
|
focus: 'series'
|
},
|
data: governmentInvestmentData,
|
itemStyle: {
|
color: '#8E44AD'
|
}
|
}
|
]
|
});
|
},
|
|
// 更新所有图表
|
updateCharts() {
|
this.updateProgressChart();
|
this.updateFundChart();
|
},
|
|
handleResize() {
|
if (this.progressChart) {
|
this.progressChart.resize();
|
}
|
if (this.fundChart) {
|
this.fundChart.resize();
|
}
|
if (this.stageChart) {
|
this.stageChart.resize();
|
}
|
},
|
getStatusTagType(status) {
|
const map = {
|
'紧急': 'danger',
|
'高风险': 'warning',
|
'延期': 'info',
|
'进行中': 'primary'
|
};
|
return map[status] || '';
|
},
|
handleTaskDetail(task) {
|
this.$message.info(`查看任务详情: ${task.taskName}`);
|
},
|
showDetail() {
|
this.$message.info(`查看${this.selectedMonth}月份的项目进度详情`);
|
},
|
showFundDetail() {
|
this.$message.info('查看资金使用详情');
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.project-management-container {
|
padding: 20px;
|
background-color: #f5f7fa;
|
min-height: 100vh;
|
}
|
|
.page-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20px;
|
padding-bottom: 15px;
|
border-bottom: 1px solid #ebeef5;
|
}
|
|
.page-header h1 {
|
color: #409EFF;
|
margin: 0;
|
}
|
|
.user-info {
|
display: flex;
|
align-items: center;
|
}
|
|
.user-info span {
|
margin-right: 10px;
|
color: #606266;
|
}
|
|
.overview-cards {
|
display: grid;
|
grid-template-columns: repeat(4, 1fr);
|
gap: 20px;
|
margin-bottom: 20px;
|
}
|
|
.overview-card {
|
border-radius: 8px;
|
border-top: 3px solid #409EFF;
|
}
|
|
.overview-card:nth-child(1) {
|
border-top-color: #409EFF;
|
}
|
.overview-card:nth-child(2) {
|
border-top-color: #67C23A;
|
}
|
.overview-card:nth-child(3) {
|
border-top-color: #E6A23C;
|
}
|
.overview-card:nth-child(4) {
|
border-top-color: #F56C6C;
|
}
|
|
.card-content {
|
display: flex;
|
align-items: center;
|
padding: 10px 0;
|
}
|
|
.card-icon {
|
width: 50px;
|
height: 50px;
|
border-radius: 50%;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
margin-right: 15px;
|
}
|
|
.card-icon i {
|
font-size: 24px;
|
}
|
|
.card-info {
|
flex: 1;
|
}
|
|
.card-title {
|
font-size: 14px;
|
color: #909399;
|
margin-bottom: 5px;
|
}
|
|
.card-value {
|
font-size: 24px;
|
font-weight: bold;
|
color: #303133;
|
}
|
|
.main-content {
|
display: grid;
|
grid-template-columns: 2fr 1fr;
|
gap: 20px;
|
}
|
|
.chart-card, .blocking-tasks-card {
|
border-radius: 8px;
|
margin-bottom: 20px;
|
border: 1px solid #ebeef5;
|
}
|
|
.chart-card >>> .el-card__header {
|
background-color: #f5f7fa;
|
border-bottom: 1px solid #ebeef5;
|
padding: 12px 20px;
|
font-weight: bold;
|
color: #409EFF;
|
}
|
|
.blocking-tasks-card >>> .el-card__header {
|
background-color: #f5f7fa;
|
border-bottom: 1px solid #ebeef5;
|
padding: 12px 20px;
|
font-weight: bold;
|
color: #409EFF;
|
}
|
|
.chart-container {
|
width: 100%;
|
}
|
|
.row {
|
display: flex;
|
align-items: center;
|
height: 36px;
|
}
|
</style>
|