feat
This commit is contained in:
BIN
src/assets/logo.png
Normal file
BIN
src/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
@@ -4,7 +4,7 @@
|
||||
<header class="navbar">
|
||||
<div class="navbar-content">
|
||||
<div class="logo">
|
||||
<img src="@/assets/logo.svg" alt="Logo" />
|
||||
<img src="@/assets/logo.png" alt="Logo" />
|
||||
<span class="logo-text">智能运维管理系统</span>
|
||||
</div>
|
||||
<nav class="nav-links">
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
<div class="feature-grid">
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<div class="feature-icon icon-blue">
|
||||
<icon-dashboard />
|
||||
</div>
|
||||
<h3>实时监控仪表盘</h3>
|
||||
@@ -46,15 +46,15 @@
|
||||
</div>
|
||||
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<icon-alert />
|
||||
<div class="feature-icon icon-orange">
|
||||
<icon-exclamation-circle />
|
||||
</div>
|
||||
<h3>智能告警管理</h3>
|
||||
<p>灵活的告警策略配置,多渠道通知,确保问题及时发现和处理</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<div class="feature-icon icon-green">
|
||||
<icon-chart-line />
|
||||
</div>
|
||||
<h3>数据大屏中心</h3>
|
||||
@@ -62,7 +62,7 @@
|
||||
</div>
|
||||
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<div class="feature-icon icon-purple">
|
||||
<icon-settings />
|
||||
</div>
|
||||
<h3>数据采集</h3>
|
||||
@@ -70,7 +70,7 @@
|
||||
</div>
|
||||
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<div class="feature-icon icon-cyan">
|
||||
<icon-shield />
|
||||
</div>
|
||||
<h3>数据中心</h3>
|
||||
@@ -78,8 +78,8 @@
|
||||
</div>
|
||||
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<icon-feedback />
|
||||
<div class="feature-icon icon-pink">
|
||||
<icon-message-circle />
|
||||
</div>
|
||||
<h3>工单管理</h3>
|
||||
<p>完善的问题反馈机制,全流程跟踪,快速响应解决工单</p>
|
||||
@@ -112,6 +112,14 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useRouter } from 'vue-router'
|
||||
import {
|
||||
IconDashboard,
|
||||
IconExclamationCircle,
|
||||
IconChartLine,
|
||||
IconSettings,
|
||||
IconShield,
|
||||
IconMessageCircle,
|
||||
} from '@tabler/icons-vue'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@@ -318,11 +326,40 @@ const scrollToSection = (id: string) => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgb(var(--primary-6));
|
||||
border-radius: 12px;
|
||||
margin-bottom: 24px;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
transition: transform 0.3s, box-shadow 0.3s;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
&.icon-blue {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
|
||||
&.icon-orange {
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
}
|
||||
|
||||
&.icon-green {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
}
|
||||
|
||||
&.icon-purple {
|
||||
background: linear-gradient(135deg, #a18cd1 0%, #fbc2eb 100%);
|
||||
}
|
||||
|
||||
&.icon-cyan {
|
||||
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
||||
}
|
||||
|
||||
&.icon-pink {
|
||||
background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
|
||||
@@ -222,7 +222,7 @@ const handleUpload = async (option: any) => {
|
||||
|
||||
if (res.code === 0) {
|
||||
// 上传成功,设置文件URL
|
||||
form.value.layout_plan = res.details?.result_url || ''
|
||||
form.value.layout_plan = res.data?.result_url || ''
|
||||
option.onSuccess(res)
|
||||
Message.success('上传成功')
|
||||
} else {
|
||||
|
||||
184
src/views/ops/pages/dc/database/components/ConnChart.vue
Normal file
184
src/views/ops/pages/dc/database/components/ConnChart.vue
Normal file
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<div v-if="!configured" class="not-configured">
|
||||
未配置
|
||||
</div>
|
||||
<div v-else class="chart-container">
|
||||
<Chart :options="chartOptions" :height="height" :width="width" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import Chart from '@/components/chart/index.vue'
|
||||
|
||||
interface Props {
|
||||
recordId: number | string
|
||||
configured?: boolean
|
||||
height?: string
|
||||
width?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
configured: true,
|
||||
height: '60px',
|
||||
width: '160px',
|
||||
})
|
||||
|
||||
// 生成 Conn 多条曲线数据(活跃连接、空闲连接、等待连接)
|
||||
const generateConnData = (id: number | string) => {
|
||||
const numericId = typeof id === 'string' ? parseInt(id, 10) || 1 : id
|
||||
const baseActive = (numericId * 23) % 50 + 20
|
||||
const baseIdle = (numericId * 17) % 30 + 10
|
||||
const baseWaiting = (numericId * 11) % 20 + 5
|
||||
|
||||
const activeData: number[] = []
|
||||
const idleData: number[] = []
|
||||
const waitingData: number[] = []
|
||||
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const variation = Math.sin(i + numericId * 0.5) * 15
|
||||
activeData.push(Math.max(0, Math.min(100, baseActive + variation + Math.random() * 10)))
|
||||
idleData.push(Math.max(0, Math.min(80, baseIdle + Math.cos(i + numericId) * 10 + Math.random() * 8)))
|
||||
waitingData.push(Math.max(0, Math.min(50, baseWaiting + Math.sin(i * 0.8 + numericId) * 8 + Math.random() * 5)))
|
||||
}
|
||||
|
||||
return { activeData, idleData, waitingData }
|
||||
}
|
||||
|
||||
// 获取图表配置
|
||||
const chartOptions = computed(() => {
|
||||
const { activeData, idleData, waitingData } = generateConnData(props.recordId)
|
||||
|
||||
return {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: (params: any) => {
|
||||
if (params && params.length > 0) {
|
||||
let result = ''
|
||||
params.forEach((item: any) => {
|
||||
result += `${item.marker}${item.seriesName}: ${item.value.toFixed(1)}<br/>`
|
||||
})
|
||||
return result
|
||||
}
|
||||
return ''
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
grid: {
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 18,
|
||||
bottom: 5,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
show: false,
|
||||
data: activeData.map((_, i) => i),
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
show: false,
|
||||
min: 0,
|
||||
max: 100,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '活跃',
|
||||
type: 'line',
|
||||
data: activeData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
width: 2,
|
||||
color: '#165DFF',
|
||||
},
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(22, 93, 255, 0.3)' },
|
||||
{ offset: 1, color: 'rgba(22, 93, 255, 0.05)' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '空闲',
|
||||
type: 'line',
|
||||
data: idleData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
width: 2,
|
||||
color: '#00B42A',
|
||||
},
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(0, 180, 42, 0.3)' },
|
||||
{ offset: 1, color: 'rgba(0, 180, 42, 0.05)' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '等待',
|
||||
type: 'line',
|
||||
data: waitingData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
width: 2,
|
||||
color: '#FF7D00',
|
||||
},
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(255, 125, 0, 0.3)' },
|
||||
{ offset: 1, color: 'rgba(255, 125, 0, 0.05)' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.not-configured {
|
||||
color: rgb(var(--text-3));
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4px 0;
|
||||
}
|
||||
</style>
|
||||
133
src/views/ops/pages/dc/database/components/QpsChart.vue
Normal file
133
src/views/ops/pages/dc/database/components/QpsChart.vue
Normal file
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div v-if="!configured" class="not-configured">
|
||||
未配置
|
||||
</div>
|
||||
<div v-else class="chart-container">
|
||||
<Chart :options="chartOptions" :height="height" :width="width" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import Chart from '@/components/chart/index.vue'
|
||||
|
||||
interface Props {
|
||||
recordId: number | string
|
||||
configured?: boolean
|
||||
height?: string
|
||||
width?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
configured: true,
|
||||
height: '60px',
|
||||
width: '160px',
|
||||
})
|
||||
|
||||
// 生成随机 QPS 数据
|
||||
const generateQpsData = (id: number | string) => {
|
||||
const numericId = typeof id === 'string' ? parseInt(id, 10) || 1 : id
|
||||
const baseValue = (numericId * 17) % 100 + 50
|
||||
const data: number[] = []
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const variation = Math.sin(i + numericId) * 30
|
||||
data.push(Math.max(0, Math.min(200, baseValue + variation + Math.random() * 20)))
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// 获取图表配置
|
||||
const chartOptions = computed(() => {
|
||||
const data = generateQpsData(props.recordId)
|
||||
const avgValue = data.reduce((a, b) => a + b, 0) / data.length
|
||||
|
||||
return {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: (params: any) => {
|
||||
if (params && params.length > 0) {
|
||||
return `QPS: ${params[0].value.toFixed(1)}`
|
||||
}
|
||||
return ''
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 5,
|
||||
bottom: 5,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
show: false,
|
||||
data: data.map((_, i) => i),
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
show: false,
|
||||
min: 0,
|
||||
max: 200,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
data,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
width: 2,
|
||||
color: '#165DFF',
|
||||
},
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(22, 93, 255, 0.3)' },
|
||||
{ offset: 1, color: 'rgba(22, 93, 255, 0.05)' },
|
||||
],
|
||||
},
|
||||
},
|
||||
markLine: {
|
||||
silent: true,
|
||||
symbol: 'none',
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
color: '#86909C',
|
||||
width: 1,
|
||||
},
|
||||
data: [
|
||||
{
|
||||
yAxis: avgValue,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.not-configured {
|
||||
color: rgb(var(--text-3));
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4px 0;
|
||||
}
|
||||
</style>
|
||||
@@ -48,13 +48,13 @@ export const columns = [
|
||||
{
|
||||
dataIndex: 'sys_indicator',
|
||||
title: '系统指标',
|
||||
width: 150,
|
||||
slotName: 'cpu',
|
||||
width: 200,
|
||||
slotName: 'sys_indicator',
|
||||
},
|
||||
{
|
||||
dataIndex: 'qps',
|
||||
title: '数据库指标 QPS',
|
||||
width: 150,
|
||||
width: 180,
|
||||
slotName: 'qps',
|
||||
},
|
||||
{
|
||||
|
||||
@@ -62,6 +62,64 @@
|
||||
{{ record.port || '-' }}
|
||||
</template>
|
||||
|
||||
<!-- 系统指标 -->
|
||||
<template #sys_indicator="{ record }">
|
||||
<div v-if="!record.agent_config" class="not-configured">
|
||||
未配置
|
||||
</div>
|
||||
<div v-else class="sys-indicator-display">
|
||||
<!-- CPU -->
|
||||
<div class="resource-display">
|
||||
<div class="resource-info">
|
||||
<span class="resource-label">CPU</span>
|
||||
<span class="resource-value">{{ record.cpu_info?.value || 0 }}%</span>
|
||||
</div>
|
||||
<a-progress
|
||||
:percent="(record.cpu_info?.value || 0) / 100"
|
||||
:color="getProgressColor(record.cpu_info?.value || 0)"
|
||||
size="small"
|
||||
:show-text="false"
|
||||
/>
|
||||
</div>
|
||||
<!-- 内存 -->
|
||||
<div class="resource-display">
|
||||
<div class="resource-info">
|
||||
<span class="resource-label">内存</span>
|
||||
<span class="resource-value">{{ record.memory_info?.value || 0 }}%</span>
|
||||
</div>
|
||||
<a-progress
|
||||
:percent="(record.memory_info?.value || 0) / 100"
|
||||
:color="getProgressColor(record.memory_info?.value || 0)"
|
||||
size="small"
|
||||
:show-text="false"
|
||||
/>
|
||||
</div>
|
||||
<!-- 硬盘 -->
|
||||
<div class="resource-display">
|
||||
<div class="resource-info">
|
||||
<span class="resource-label">硬盘</span>
|
||||
<span class="resource-value">{{ record.disk_info?.value || 0 }}%</span>
|
||||
</div>
|
||||
<a-progress
|
||||
:percent="(record.disk_info?.value || 0) / 100"
|
||||
:color="getProgressColor(record.disk_info?.value || 0)"
|
||||
size="small"
|
||||
:show-text="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 数据库指标 QPS -->
|
||||
<template #qps="{ record }">
|
||||
<QpsChart :record-id="record.id" :configured="record.agent_config" />
|
||||
</template>
|
||||
|
||||
<!-- 数据库指标 Conn -->
|
||||
<template #conn="{ record }">
|
||||
<ConnChart :record-id="record.id" :configured="record.agent_config" />
|
||||
</template>
|
||||
|
||||
<!-- 状态 -->
|
||||
<template #status="{ record }">
|
||||
<a-tag :color="getStatusColor(record.status)">
|
||||
@@ -161,6 +219,8 @@ import { searchFormConfig } from './config/search-form'
|
||||
import FormDialog from '../pc/components/FormDialog.vue'
|
||||
import QuickConfigDialog from '../pc/components/QuickConfigDialog.vue'
|
||||
import { columns as columnsConfig } from './config/columns'
|
||||
import QpsChart from './components/QpsChart.vue'
|
||||
import ConnChart from './components/ConnChart.vue'
|
||||
import {
|
||||
fetchServerList,
|
||||
deleteServer,
|
||||
@@ -182,6 +242,9 @@ const mockServerData = [
|
||||
port: '3306',
|
||||
remote_access: true,
|
||||
agent_config: true,
|
||||
cpu_info: { value: 45, total: '8核', used: '3.6核' },
|
||||
memory_info: { value: 62, total: '32GB', used: '19.8GB' },
|
||||
disk_info: { value: 78, total: '1TB', used: '780GB' },
|
||||
data_collection: true,
|
||||
status: 'online',
|
||||
},
|
||||
@@ -197,6 +260,9 @@ const mockServerData = [
|
||||
port: '5432',
|
||||
remote_access: true,
|
||||
agent_config: true,
|
||||
cpu_info: { value: 78, total: '16核', used: '12.5核' },
|
||||
memory_info: { value: 85, total: '64GB', used: '54.4GB' },
|
||||
disk_info: { value: 92, total: '2TB', used: '1.84TB' },
|
||||
data_collection: true,
|
||||
status: 'online',
|
||||
},
|
||||
@@ -212,6 +278,9 @@ const mockServerData = [
|
||||
port: '6379',
|
||||
remote_access: false,
|
||||
agent_config: false,
|
||||
cpu_info: { value: 0, total: '4核', used: '0核' },
|
||||
memory_info: { value: 0, total: '16GB', used: '0GB' },
|
||||
disk_info: { value: 0, total: '500GB', used: '0GB' },
|
||||
data_collection: false,
|
||||
status: 'offline',
|
||||
},
|
||||
@@ -227,6 +296,9 @@ const mockServerData = [
|
||||
port: '27017',
|
||||
remote_access: true,
|
||||
agent_config: true,
|
||||
cpu_info: { value: 35, total: '8核', used: '2.8核' },
|
||||
memory_info: { value: 68, total: '32GB', used: '21.8GB' },
|
||||
disk_info: { value: 42, total: '1TB', used: '420GB' },
|
||||
data_collection: true,
|
||||
status: 'online',
|
||||
},
|
||||
@@ -242,6 +314,9 @@ const mockServerData = [
|
||||
port: '1521',
|
||||
remote_access: true,
|
||||
agent_config: true,
|
||||
cpu_info: { value: 28, total: '12核', used: '3.4核' },
|
||||
memory_info: { value: 45, total: '48GB', used: '21.6GB' },
|
||||
disk_info: { value: 88, total: '10TB', used: '8.8TB' },
|
||||
data_collection: true,
|
||||
status: 'maintenance',
|
||||
},
|
||||
@@ -257,6 +332,9 @@ const mockServerData = [
|
||||
port: '1433',
|
||||
remote_access: false,
|
||||
agent_config: false,
|
||||
cpu_info: { value: 0, total: '4核', used: '0核' },
|
||||
memory_info: { value: 0, total: '8GB', used: '0GB' },
|
||||
disk_info: { value: 0, total: '256GB', used: '0GB' },
|
||||
data_collection: false,
|
||||
status: 'retired',
|
||||
},
|
||||
@@ -272,6 +350,9 @@ const mockServerData = [
|
||||
port: '9200',
|
||||
remote_access: true,
|
||||
agent_config: true,
|
||||
cpu_info: { value: 55, total: '8核', used: '4.4核' },
|
||||
memory_info: { value: 72, total: '32GB', used: '23.0GB' },
|
||||
disk_info: { value: 65, total: '1TB', used: '650GB' },
|
||||
data_collection: true,
|
||||
status: 'online',
|
||||
},
|
||||
@@ -287,6 +368,9 @@ const mockServerData = [
|
||||
port: '3307',
|
||||
remote_access: true,
|
||||
agent_config: true,
|
||||
cpu_info: { value: 68, total: '8核', used: '5.4核' },
|
||||
memory_info: { value: 75, total: '16GB', used: '12GB' },
|
||||
disk_info: { value: 55, total: '500GB', used: '275GB' },
|
||||
data_collection: true,
|
||||
status: 'online',
|
||||
},
|
||||
@@ -522,4 +606,55 @@ export default {
|
||||
.container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.not-configured {
|
||||
color: rgb(var(--text-3));
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.sys-indicator-display {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.resource-display {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
padding: 2px 0;
|
||||
|
||||
.resource-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.resource-label {
|
||||
font-size: 12px;
|
||||
color: rgb(var(--text-2));
|
||||
}
|
||||
|
||||
.resource-value {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: rgb(var(--text-1));
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.arco-progress) {
|
||||
margin: 0;
|
||||
|
||||
.arco-progress-bar-bg {
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.arco-progress-bar {
|
||||
border-radius: 2px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user