根据数据范围自动计算合适的Y轴最大值和刻度间隔: - 小于等于10:向上取整到整数 - 10-50:向上取整到10的倍数 - 50-100:向上取整到10的倍数 - 100-500:向上取整到50的倍数 - 500-1000:向上取整到100的倍数 - 大于1000:向上取整到500的倍数 自动计算刻度间隔,确保显示6-8个刻度,提升图表可读性
722 lines
18 KiB
Vue
722 lines
18 KiB
Vue
<template>
|
||
<div class="dash-entry-container">
|
||
<!-- 标题和帮助按钮 -->
|
||
<div class="entry-header">
|
||
<div class="entry-title">AI 心航360°</div>
|
||
<el-tooltip
|
||
effect="dark"
|
||
placement="bottom"
|
||
:show-after="200"
|
||
>
|
||
<template #content>
|
||
<div class="help-content">
|
||
<div class="help-item">
|
||
<strong>数据说明:</strong>
|
||
<p>本页面展示的统计数据基于监区管理系统的实时数据统计。</p>
|
||
</div>
|
||
<div class="help-item">
|
||
<strong>全部人员:</strong>
|
||
<p>统计系统中所有在押罪犯的总人数。</p>
|
||
</div>
|
||
<div class="help-item">
|
||
<strong>高危人员:</strong>
|
||
<p>风险等级为"极高风险"或"高风险"的人员数量。</p>
|
||
</div>
|
||
<div class="help-item">
|
||
<strong>预警人员:</strong>
|
||
<p>风险等级为"中风险"且存在预警信息的人员数量。</p>
|
||
</div>
|
||
<div class="help-item">
|
||
<strong>普通人员:</strong>
|
||
<p>风险等级为"低风险"或"中风险"且无预警信息的人员数量。</p>
|
||
</div>
|
||
<div class="help-item">
|
||
<strong>本月新增:</strong>
|
||
<p>对比上月新增的罪犯数量(正数表示增加,负数表示减少)。</p>
|
||
</div>
|
||
<div class="help-item">
|
||
<strong>风险等级分布:</strong>
|
||
<p>统计各风险等级人员占比,数据来源于罪犯风险等级评估结果。</p>
|
||
</div>
|
||
<div class="help-item">
|
||
<strong>风险趋势图:</strong>
|
||
<p>展示近12个月各风险等级人员数量变化趋势。</p>
|
||
</div>
|
||
<div class="help-item">
|
||
<strong>重点关注对象:</strong>
|
||
<p>根据风险等级、心理评估结果、违纪记录等因素筛选出的需要重点关注的罪犯。</p>
|
||
</div>
|
||
<div class="help-item">
|
||
<strong>数据更新频率:</strong>
|
||
<p>统计数据每小时自动更新一次,确保数据实时性。</p>
|
||
</div>
|
||
<div class="help-item">
|
||
<strong>全景画像:</strong>
|
||
<p>点击"全景画像"可查看该罪犯的完整详细信息,包括基本信息、风险评估、消费记录、奖惩记录等。</p>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<div class="help-icon">
|
||
<Icon icon="ep:question-filled" :size="18" />
|
||
</div>
|
||
</el-tooltip>
|
||
</div>
|
||
<!-- 顶部四个数据卡片 -->
|
||
<div class="stats-cards">
|
||
<div v-for="(card, index) in statsCards" :key="index" class="stat-card">
|
||
<div class="stat-card-icon" :class="`icon-${card.type}`">
|
||
<Icon :icon="card.icon" :size="24" />
|
||
</div>
|
||
<div class="stat-card-content">
|
||
<div class="stat-card-title">{{ card.title }}</div>
|
||
<div class="stat-card-value">{{ card.value }}</div>
|
||
<div class="stat-card-subtitle">
|
||
{{ card.subtitle }}
|
||
<span class="trend-icon" :class="card.trend === 'up' ? 'trend-up' : 'trend-down'">{{
|
||
card.trend === 'up' ? '↑' : '↓'
|
||
}}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 中间图表区域 -->
|
||
<div class="charts-section">
|
||
<!-- 左侧:风险等级分布(环形图) -->
|
||
<div class="chart-card">
|
||
<div class="chart-title">风险等级分布</div>
|
||
<div class="chart-content">
|
||
<EChart :options="riskDistributionOptions" :height="'200px'" />
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧:风险趋势图(折线图) -->
|
||
<div class="chart-card">
|
||
<div class="chart-title">风险趋势图</div>
|
||
<div class="chart-content">
|
||
<EChart :options="riskTrendOptions" :height="'200px'" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 底部表格 -->
|
||
<div class="table-section">
|
||
<div class="table-title">重点关注对象列表</div>
|
||
<el-table :data="tableData.results" style="width: 100%" stripe v-loading="loading">
|
||
<el-table-column prop="name" label="姓名" width="`16.3%`" class-name="name-column">
|
||
<template #default="{ row }">
|
||
<span v-if="row.isNew" class="new-tag" :class="`tag-${row.riskLevelType}`">新增</span>
|
||
{{ row.name }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="gender" label="性别" width="`10%`" />
|
||
<el-table-column prop="age" label="年龄" width="`10%`" />
|
||
<el-table-column prop="riskLevel" label="风险等级" width="`15%`">
|
||
<template #default="{ row }">
|
||
<span :class="`risk-level risk-${row.riskLevelType}`">
|
||
{{ row.riskLevel }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="supervisionArea" label="监区" width="`15%`" />
|
||
<el-table-column prop="psychologicalRiskLevel" label="心理风险等级" width="`18.7%`" />
|
||
<el-table-column label="操作" width="`15%`">
|
||
<template #default="{ row }">
|
||
<el-link type="primary" @click="handleView(row)">全景画像</el-link>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<div class="table-pagination">
|
||
<span class="total-count">共{{ tableData.total }}条</span>
|
||
<el-pagination
|
||
v-model:current-page="tableData.current"
|
||
v-model:page-size="pageSize"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:total="tableData.total"
|
||
layout="sizes, prev, pager, next"
|
||
@size-change="handleSizeChange"
|
||
@current-change="handleCurrentChange"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, computed, onMounted } from 'vue'
|
||
import type { EChartsOption } from 'echarts'
|
||
// @ts-ignore
|
||
import EChart from '@/components/Echart/src/Echart.vue'
|
||
import { Icon } from '@/components/Icon'
|
||
import { useRouter } from 'vue-router'
|
||
import { AiDashEntryApi, type AiDashEntryStatisticsVO, type FocusPersonVO } from '@/api/prison/ai-dash-entry'
|
||
import { ElMessage } from 'element-plus'
|
||
|
||
defineOptions({ name: 'DashEntry' })
|
||
|
||
const router = useRouter()
|
||
const loading = ref(false)
|
||
|
||
// 统计数据
|
||
const statistics = ref<AiDashEntryStatisticsVO>({
|
||
totalCount: 0,
|
||
monthlyNewCount: 0,
|
||
monthlyChange: 0,
|
||
highRiskCount: 0,
|
||
highRiskMonthlyNew: 0,
|
||
highRiskMonthlyChange: 0,
|
||
warningCount: 0,
|
||
warningMonthlyNew: 0,
|
||
warningMonthlyChange: 0,
|
||
normalCount: 0,
|
||
normalMonthlyNew: 0,
|
||
normalMonthlyChange: 0,
|
||
riskDistribution: [],
|
||
riskTrendData: []
|
||
})
|
||
|
||
// 统计数据卡片
|
||
const statsCards = computed(() => [
|
||
{
|
||
title: '全部人员',
|
||
value: `${statistics.value.totalCount}人`,
|
||
subtitle: `本月${statistics.value.monthlyNewCount}人 ${statistics.value.monthlyChange >= 0 ? '+' : ''}${statistics.value.monthlyChange}`,
|
||
trend: statistics.value.monthlyChange >= 0 ? 'up' : 'down',
|
||
type: 'all',
|
||
icon: 'ep:user'
|
||
},
|
||
{
|
||
title: '高危人员',
|
||
value: `${statistics.value.highRiskCount}人`,
|
||
subtitle: `本月${statistics.value.highRiskMonthlyNew}人 ${statistics.value.highRiskMonthlyChange >= 0 ? '+' : ''}${statistics.value.highRiskMonthlyChange}`,
|
||
trend: statistics.value.highRiskMonthlyChange >= 0 ? 'up' : 'down',
|
||
type: 'high',
|
||
icon: 'ep:warning-filled'
|
||
},
|
||
{
|
||
title: '预警人员',
|
||
value: `${statistics.value.warningCount}人`,
|
||
subtitle: `本月${statistics.value.warningMonthlyNew}人 ${statistics.value.warningMonthlyChange >= 0 ? '+' : ''}${statistics.value.warningMonthlyChange}`,
|
||
trend: statistics.value.warningMonthlyChange >= 0 ? 'up' : 'down',
|
||
type: 'warning',
|
||
icon: 'ep:bell'
|
||
},
|
||
{
|
||
title: '普通人员',
|
||
value: `${statistics.value.normalCount}人`,
|
||
subtitle: `本月${statistics.value.normalMonthlyNew}人 ${statistics.value.normalMonthlyChange >= 0 ? '+' : ''}${statistics.value.normalMonthlyChange}`,
|
||
trend: statistics.value.normalMonthlyChange >= 0 ? 'up' : 'down',
|
||
type: 'normal',
|
||
icon: 'ep:user-filled'
|
||
}
|
||
])
|
||
|
||
// 风险等级分布图表配置(环形图)
|
||
const riskDistributionOptions = computed<EChartsOption>(() => {
|
||
const distribution = statistics.value.riskDistribution || []
|
||
const total = distribution.reduce((sum, item) => sum + item.value, 0)
|
||
|
||
const data = distribution.map(item => {
|
||
const percentage = total > 0 ? Math.round((item.value / total) * 100) : 0
|
||
return {
|
||
value: item.value,
|
||
name: `${item.name} (${percentage}%)`,
|
||
itemStyle: { color: item.color }
|
||
}
|
||
})
|
||
|
||
return {
|
||
tooltip: {
|
||
trigger: 'item',
|
||
formatter: '{b}: {c} ({d}%)'
|
||
},
|
||
legend: {
|
||
show: true,
|
||
bottom: 0,
|
||
left: 'center',
|
||
itemGap: 20,
|
||
icon: 'circle',
|
||
textStyle: {
|
||
fontSize: 12
|
||
},
|
||
data: data.map(item => item.name)
|
||
},
|
||
series: [
|
||
{
|
||
name: '风险等级分布',
|
||
type: 'pie',
|
||
radius: ['40%', '70%'],
|
||
center: ['50%', '50%'],
|
||
avoidLabelOverlap: false,
|
||
itemStyle: {
|
||
borderRadius: 10,
|
||
borderColor: '#fff',
|
||
borderWidth: 2
|
||
},
|
||
label: {
|
||
show: true,
|
||
formatter: '{b}\n{d}%'
|
||
},
|
||
emphasis: {
|
||
label: {
|
||
show: true,
|
||
fontSize: 12,
|
||
fontWeight: 'bold'
|
||
}
|
||
},
|
||
data: data
|
||
}
|
||
]
|
||
}
|
||
})
|
||
|
||
// 风险趋势图配置(折线图)
|
||
const riskTrendOptions = computed<EChartsOption>(() => {
|
||
const trendData = statistics.value.riskTrendData || []
|
||
const months = trendData.map(item => item.month)
|
||
const highRiskData = trendData.map(item => item.highRisk)
|
||
const warningData = trendData.map(item => item.warning)
|
||
const normalData = trendData.map(item => item.normal)
|
||
|
||
// 计算最大值用于设置Y轴范围
|
||
const allValues = [...highRiskData, ...warningData, ...normalData]
|
||
const maxValue = Math.max(...allValues, 10)
|
||
|
||
// 动态计算Y轴最大值,根据数据范围自动向上取整到合适的量级
|
||
let yAxisMax: number
|
||
if (maxValue === 0) {
|
||
yAxisMax = 10
|
||
} else if (maxValue <= 10) {
|
||
yAxisMax = Math.ceil(maxValue)
|
||
} else if (maxValue <= 50) {
|
||
// 对于10-50的数据,向上取整到10的倍数
|
||
yAxisMax = Math.ceil(maxValue / 10) * 10
|
||
} else if (maxValue <= 100) {
|
||
// 对于50-100的数据,向上取整到10的倍数
|
||
yAxisMax = Math.ceil(maxValue / 10) * 10
|
||
} else if (maxValue <= 500) {
|
||
// 对于100-500的数据,向上取整到50的倍数
|
||
yAxisMax = Math.ceil(maxValue / 50) * 50
|
||
} else if (maxValue <= 1000) {
|
||
// 对于500-1000的数据,向上取整到100的倍数
|
||
yAxisMax = Math.ceil(maxValue / 100) * 100
|
||
} else {
|
||
// 对于大于1000的数据,向上取整到500的倍数
|
||
yAxisMax = Math.ceil(maxValue / 500) * 500
|
||
}
|
||
|
||
// 计算合适的刻度间隔,确保显示6-8个刻度
|
||
const interval = Math.max(Math.ceil(yAxisMax / 6), 1)
|
||
|
||
return {
|
||
tooltip: {
|
||
trigger: 'axis'
|
||
},
|
||
legend: {
|
||
data: ['高危', '预警', '普通'],
|
||
bottom: 0
|
||
},
|
||
grid: {
|
||
left: '3%',
|
||
right: '4%',
|
||
bottom: '15%',
|
||
containLabel: true
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
boundaryGap: false,
|
||
data: months
|
||
},
|
||
yAxis: {
|
||
type: 'value',
|
||
min: 0,
|
||
max: yAxisMax,
|
||
interval: interval
|
||
},
|
||
series: [
|
||
{
|
||
name: '高危',
|
||
type: 'line',
|
||
data: highRiskData,
|
||
itemStyle: { color: '#ee6666' },
|
||
lineStyle: { color: '#ee6666' },
|
||
symbol: 'circle',
|
||
symbolSize: 6
|
||
},
|
||
{
|
||
name: '预警',
|
||
type: 'line',
|
||
data: warningData,
|
||
itemStyle: { color: '#fac858' },
|
||
lineStyle: { color: '#fac858', type: 'dashed' },
|
||
symbol: 'circle',
|
||
symbolSize: 6
|
||
},
|
||
{
|
||
name: '普通',
|
||
type: 'line',
|
||
data: normalData,
|
||
itemStyle: { color: '#666' },
|
||
lineStyle: { color: '#666' },
|
||
symbol: 'circle',
|
||
symbolSize: 6
|
||
}
|
||
]
|
||
}
|
||
})
|
||
|
||
// 表格数据
|
||
const tableData = ref<{
|
||
current: number
|
||
total: number
|
||
results: FocusPersonVO[]
|
||
}>({
|
||
current: 1,
|
||
total: 0,
|
||
results: []
|
||
})
|
||
|
||
// 分页
|
||
const pageSize = ref(10)
|
||
|
||
// 处理每页大小变化
|
||
const handleSizeChange = (val: number) => {
|
||
pageSize.value = val
|
||
tableData.value.current = 1
|
||
loadFocusPersonPage()
|
||
}
|
||
|
||
// 处理当前页变化
|
||
const handleCurrentChange = (val: number) => {
|
||
tableData.value.current = val
|
||
loadFocusPersonPage()
|
||
}
|
||
|
||
const handleView = (row: FocusPersonVO) => {
|
||
router.push({
|
||
path: '/prisoner/prisoner/dashboard',
|
||
query: {
|
||
prisonerId: row.id
|
||
}
|
||
})
|
||
}
|
||
|
||
// 加载统计数据
|
||
const loadStatistics = async () => {
|
||
try {
|
||
const data = await AiDashEntryApi.getStatistics()
|
||
if (data) {
|
||
statistics.value = data
|
||
}
|
||
} catch (error) {
|
||
console.error('加载统计数据失败:', error)
|
||
ElMessage.error('加载统计数据失败')
|
||
}
|
||
}
|
||
|
||
// 加载重点关注对象列表
|
||
const loadFocusPersonPage = async () => {
|
||
loading.value = true
|
||
try {
|
||
const data = await AiDashEntryApi.getFocusPersonPage({
|
||
pageNo: tableData.value.current,
|
||
pageSize: pageSize.value
|
||
})
|
||
if (data) {
|
||
tableData.value.results = data.list || []
|
||
tableData.value.total = data.total || 0
|
||
}
|
||
} catch (error) {
|
||
console.error('加载重点关注对象失败:', error)
|
||
ElMessage.error('加载重点关注对象列表失败')
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
loadStatistics()
|
||
loadFocusPersonPage()
|
||
})
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.dash-entry-container {
|
||
padding: 10px;
|
||
background: #fff;
|
||
min-height: 100vh;
|
||
width: 100%;
|
||
height: 100%;
|
||
overflow: scroll;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.entry-title {
|
||
font-size: 24px;
|
||
margin-bottom: 10px;
|
||
text-align: center;
|
||
font-weight: 500;
|
||
color: #65CFE3;
|
||
}
|
||
|
||
.entry-header {
|
||
position: relative;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin-bottom: 10px;
|
||
padding: 0 50px;
|
||
|
||
.help-icon {
|
||
position: absolute;
|
||
right: 0;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
color: #909399;
|
||
cursor: pointer;
|
||
transition: color 0.3s;
|
||
|
||
&:hover {
|
||
color: #409EFF;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 帮助提示内容样式
|
||
:deep(.el-tooltip__popper) {
|
||
max-width: 400px !important;
|
||
|
||
.help-content {
|
||
.help-item {
|
||
margin-bottom: 12px;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
strong {
|
||
display: block;
|
||
margin-bottom: 4px;
|
||
color: #303133;
|
||
font-size: 14px;
|
||
}
|
||
|
||
p {
|
||
margin: 0;
|
||
color: #606266;
|
||
font-size: 13px;
|
||
line-height: 1.6;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 统计卡片区域
|
||
.stats-cards {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
gap: 8px;
|
||
margin-bottom: 15px;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.stat-card {
|
||
background: #ffffff;
|
||
border-radius: 8px;
|
||
padding: 10px 20px;
|
||
display: flex;
|
||
align-items: center;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||
transition: transform 0.2s;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
min-width: 0;
|
||
position: relative;
|
||
&:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||
}
|
||
}
|
||
|
||
.stat-card-icon {
|
||
position: absolute;
|
||
top: 10px;
|
||
right: 0;
|
||
width: 32px;
|
||
height: 32px;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 16px;
|
||
|
||
&.icon-all {
|
||
background: #e6f4ff;
|
||
color: #1890ff;
|
||
}
|
||
|
||
&.icon-high {
|
||
background: #fff1f0;
|
||
color: #ff4d4f;
|
||
}
|
||
|
||
&.icon-warning {
|
||
background: #fff7e6;
|
||
color: #faad14;
|
||
}
|
||
|
||
&.icon-normal {
|
||
background: #f6ffed;
|
||
color: #52c41a;
|
||
}
|
||
}
|
||
|
||
.stat-card-content {
|
||
flex: 1;
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.stat-card-title {
|
||
font-size: 14px;
|
||
color: #666;
|
||
margin-bottom: 6px;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
.stat-card-value {
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 6px;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
.stat-card-subtitle {
|
||
font-size: 14px;
|
||
color: #999;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
|
||
.trend-icon {
|
||
margin-left: 4px;
|
||
&.trend-up {
|
||
color: #52c41a;
|
||
}
|
||
|
||
&.trend-down {
|
||
color: #ff4d4f;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 图表区域
|
||
.charts-section {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 16px;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.chart-card {
|
||
background: #ffffff;
|
||
border-radius: 8px;
|
||
padding: 10px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.chart-title {
|
||
font-size: 15px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.chart-content {
|
||
height: 200px;
|
||
}
|
||
|
||
// 表格区域
|
||
.table-section {
|
||
background: #ffffff;
|
||
border-radius: 8px;
|
||
padding: 20px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.table-title {
|
||
font-size: 15px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
:deep(.name-column) {
|
||
padding-left: 32px;
|
||
}
|
||
|
||
.new-tag {
|
||
display: inline-block;
|
||
position: absolute;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
left: 0;
|
||
padding: 2px 8px;
|
||
font-size: 13px;
|
||
border-radius: 4px;
|
||
&.tag-high {
|
||
color: #ff4d4f;
|
||
background: #fff1f0;
|
||
}
|
||
|
||
&.tag-warning {
|
||
color: #faad14;
|
||
background: #fff7e6;
|
||
}
|
||
|
||
&.tag-normal {
|
||
color: #666;
|
||
background: #f5f5f5;
|
||
}
|
||
}
|
||
|
||
.risk-level {
|
||
padding: 4px 8px;
|
||
border-radius: 4px;
|
||
font-size: 13px;
|
||
|
||
&.risk-high {
|
||
color: #ff4d4f;
|
||
background: #fff1f0;
|
||
}
|
||
|
||
&.risk-warning {
|
||
color: #faad14;
|
||
background: #fff7e6;
|
||
}
|
||
|
||
&.risk-normal {
|
||
color: #666;
|
||
background: #f5f5f5;
|
||
}
|
||
}
|
||
|
||
.table-pagination {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-top: 16px;
|
||
|
||
.total-count {
|
||
color: #666;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
</style>
|