757 lines
19 KiB
Vue
757 lines
19 KiB
Vue
<template>
|
||
<div class="personnel p-2 h-full flex flex-col">
|
||
<div class="flex flex-items-center searchBox">
|
||
<div class="searchLabel">选择日期</div>
|
||
<el-date-picker
|
||
v-model="dataTime"
|
||
type="date"
|
||
placeholder="选择日期"
|
||
value-format="YYYY-MM-DD"
|
||
format="YYYY-MM-DD"
|
||
style="width: 400px; margin-right: 10px"
|
||
></el-date-picker>
|
||
<el-button type="primary" @click="querySearch">查询</el-button>
|
||
<el-button @click="reset">重置</el-button>
|
||
</div>
|
||
<div style="margin-bottom: 15px; position: relative; z-index: 2">
|
||
<el-row :gutter="20">
|
||
<el-col :lg="14" :xl="14">
|
||
<div class="cardbox">
|
||
<div>收入来源</div>
|
||
<div class="card_infoall">
|
||
<div>应缴费用:{{ formatMoneyWithUnit(form.totalDue) }}</div>
|
||
<div>已收:{{ formatMoneyWithUnit(form.totalPaid) }}</div>
|
||
<div>待收:{{ formatMoneyWithUnit(form.totalUnpaid) }}</div>
|
||
</div>
|
||
<div class="cardbody" style="height: 165px">
|
||
<div
|
||
v-for="(opt, index) in incomeChartOptions"
|
||
:key="index"
|
||
class="chart-item flex flex-col items-center"
|
||
style="width: 165px; height: 100%"
|
||
>
|
||
<Echarts :options="opt.options as EChartsOption" style="width: 100%; height: 165px"></Echarts>
|
||
<!-- 如果需要额外显示名称,可以在这里加 div,但图表中心已显示 -->
|
||
<div class="chart-item-name">{{ opt.name }}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-col>
|
||
|
||
<el-col :lg="10" :xl="10">
|
||
<div class="cardbox">
|
||
<div>欠费分布</div>
|
||
<div class="cardbody w-full" style="height: 150px">
|
||
<Echarts :options="options2"></Echarts>
|
||
</div>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
<div style="margin-bottom: 15px; position: relative; z-index: 2">
|
||
<el-row :gutter="20">
|
||
<el-col :lg="12" :xl="14">
|
||
<div class="cardbox w-full">
|
||
<div>欠费分布</div>
|
||
<div class="cardbody w-full" style="height: 330px">
|
||
<Echarts :options="options3"></Echarts>
|
||
</div>
|
||
</div>
|
||
</el-col>
|
||
<el-col :lg="12" :xl="10">
|
||
<div class="cardbox w-full" style="height: 400px">
|
||
<div style="height: 50px; margin-bottom: 20px">缴费来源</div>
|
||
<div flex flex-items-center justify-center>
|
||
<ul class="legendbox">
|
||
<li v-for="(item, index) in paytypelist" :key="index">
|
||
<i
|
||
:style="{
|
||
backgroundColor: item.color
|
||
}"
|
||
></i>
|
||
<span class="ml-2">{{ item.label }}</span>
|
||
</li>
|
||
</ul>
|
||
<ul class="circlebox">
|
||
<li :data-level="index" :style="{ backgroundColor: item.color }" v-for="(item, index) in paytypelist" :key="index">
|
||
{{ item.number }}%
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
<div style="position: relative; z-index: 2">
|
||
<el-row>
|
||
<el-col :span="24">
|
||
<!-- <div class="cardbox w-full" style="height: 450px">
|
||
<Echarts :options="flowLineOption"></Echarts>
|
||
</div> -->
|
||
<div class="cardbox w-full">
|
||
<div>缴费走势分析</div>
|
||
<div class="cardbody w-full" style="height: 400px">
|
||
<Echarts :options="flowLineOption"></Echarts>
|
||
</div>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
<Teleport to="body">
|
||
<i v-if="open" class="bgColor"></i>
|
||
</Teleport>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
// TODO 缴费分析
|
||
import { ref } from 'vue';
|
||
import Echarts from '@/components/Echarts/index.vue';
|
||
import { formatMoneyWithUnit } from '@/utils/money';
|
||
import { EChartsOption } from 'echarts';
|
||
import { getLast7Days, getPastDayDate } from '@/utils/time';
|
||
import { income_statsApi } from '@/api/system/Payment/index';
|
||
|
||
const open = ref(false);
|
||
const dataTime = ref('2025-01-01');
|
||
const form = ref({
|
||
'totalDue': '',
|
||
'totalPaid': '',
|
||
'totalUnpaid': '',
|
||
'paidPercentage': '',
|
||
'payWx': null,
|
||
'payZfb': null,
|
||
'payOffline': null,
|
||
'totalPay': null,
|
||
'feeTypeStats': [],
|
||
'dailyStats': []
|
||
});
|
||
|
||
const defaultDay = 30; // 默认查询近30天数据
|
||
|
||
/** 收入来源 */
|
||
/** 收入来源图表配置 */
|
||
const incomeChartOptions = ref<
|
||
{
|
||
name: string;
|
||
options?: EChartsOption;
|
||
}[]
|
||
>([
|
||
{
|
||
'name': '停车费'
|
||
},
|
||
{
|
||
'name': '物业费'
|
||
},
|
||
{
|
||
'name': '水电费'
|
||
},
|
||
{
|
||
'name': '商铺租金'
|
||
},
|
||
{
|
||
'name': '维修费'
|
||
}
|
||
]);
|
||
|
||
/** 缴费方式 */
|
||
const options2 = shallowRef<EChartsOption>({
|
||
legend: {
|
||
top: 'center',
|
||
left: '0',
|
||
orient: 'vertical',
|
||
itemGap: 50
|
||
},
|
||
clockwise: true,
|
||
series: [
|
||
{
|
||
name: 'Access From',
|
||
type: 'pie',
|
||
startAngle: 280,
|
||
radius: ['50%', '100%'],
|
||
avoidLabelOverlap: false,
|
||
left: '50%',
|
||
label: {
|
||
show: false,
|
||
position: 'center'
|
||
},
|
||
tooltip: {
|
||
show: false
|
||
},
|
||
emphasis: {
|
||
label: {
|
||
show: false,
|
||
fontSize: 20,
|
||
fontWeight: 'bold'
|
||
}
|
||
},
|
||
labelLine: {
|
||
show: false
|
||
},
|
||
data: [
|
||
{ value: 50, name: '支付宝', itemStyle: { color: '#0a74fe' } },
|
||
{ value: 30, name: '微信', itemStyle: { color: '#f74043' } },
|
||
{ value: 20, name: '线下', itemStyle: { color: '#fcd152' } }
|
||
]
|
||
}
|
||
]
|
||
});
|
||
|
||
// 【新增】定义12个月份
|
||
const monthX = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'];
|
||
/** 欠费分布 散点图 */
|
||
/** 欠费分布 散点图 (带特效版) */
|
||
const options3 = shallowRef<EChartsOption>({
|
||
tooltip: {
|
||
trigger: 'item',
|
||
formatter: (params: any) => {
|
||
return `${monthX[params.value[0]]}<br/>欠费金额: <b>${params.value[1]}</b> 万元`;
|
||
},
|
||
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
||
borderColor: '#eee',
|
||
textStyle: { color: '#333' }
|
||
},
|
||
grid: {
|
||
left: '1%',
|
||
right: '2%',
|
||
top: '12%',
|
||
bottom: '12%',
|
||
containLabel: true
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: monthX,
|
||
boundaryGap: false,
|
||
axisTick: {
|
||
alignWithLabel: true,
|
||
length: 5, // 刻度线长度
|
||
lineStyle: { color: '#ccc' }
|
||
},
|
||
axisLine: { lineStyle: { color: '#eee' }, onZero: false },
|
||
axisLabel: {
|
||
color: '#666',
|
||
interval: 0, // 强制显示所有月份
|
||
margin: 12 // 标签与轴线的距离
|
||
},
|
||
splitLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
color: '#f0f0f0',
|
||
type: 'dashed',
|
||
width: 1
|
||
}
|
||
}
|
||
},
|
||
yAxis: {
|
||
type: 'value',
|
||
name: '金额(万元)',
|
||
nameTextStyle: { color: '#999', padding: [0, 0, 0, 10] },
|
||
splitLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
color: '#f0f0f0',
|
||
type: 'dashed' // 虚线网格更轻盈
|
||
}
|
||
},
|
||
axisLabel: { color: '#999', margin: 20 }
|
||
},
|
||
series: [
|
||
{
|
||
name: '欠费金额',
|
||
type: 'scatter',
|
||
symbolSize: (data: any) => {
|
||
const value = data[1];
|
||
return Math.min(Math.max(value * 1.5, 10), 40);
|
||
},
|
||
itemStyle: {
|
||
color: (params: any) => {
|
||
const index = params.dataIndex;
|
||
if (index % 2 === 0) {
|
||
return '#739ff0';
|
||
} else {
|
||
return '#86c9d0';
|
||
}
|
||
}
|
||
},
|
||
// 【特效 2】高亮状态(鼠标悬停)
|
||
emphasis: {
|
||
scale: 1.2 // 悬停时额外放大
|
||
},
|
||
data: [
|
||
[0, 12.5],
|
||
[1, 10.2],
|
||
[2, 15.8],
|
||
[3, 9.5],
|
||
[4, 11.0],
|
||
[5, 18.3],
|
||
[6, 14.2],
|
||
[7, 16.5],
|
||
[8, 13.1],
|
||
[9, 10.8],
|
||
[10, 12.4],
|
||
[11, 19.6]
|
||
]
|
||
}
|
||
]
|
||
});
|
||
|
||
// ! 进十日缴费数量情况 -------------------------------------------------------------------------------------
|
||
// 近10天日期
|
||
const dayX = getLast7Days(10);
|
||
|
||
// 小区真实规模:人员流入 / 流出 数据
|
||
const inData = [97, 145, 63, 112, 88, 156, 74, 131, 102, 59];
|
||
const outData = [121, 85, 142, 71, 135, 93, 116, 66, 148, 104];
|
||
|
||
/** 进十日缴费数量情况 - 平滑折线图 */
|
||
const flowLineOption = shallowRef<EChartsOption>({
|
||
tooltip: {
|
||
trigger: 'axis',
|
||
confine: true
|
||
},
|
||
grid: {
|
||
left: '3%',
|
||
right: '4%',
|
||
top: '12%',
|
||
bottom: '8%',
|
||
containLabel: true
|
||
},
|
||
legend: {
|
||
data: ['已缴费', '未缴费'],
|
||
right: 10,
|
||
top: 0
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
data: dayX,
|
||
boundaryGap: false,
|
||
axisLine: { lineStyle: { color: '#eee' } }
|
||
},
|
||
yAxis: {
|
||
type: 'value',
|
||
splitLine: {
|
||
show: true,
|
||
lineStyle: { color: '#eee' }
|
||
}
|
||
},
|
||
series: [
|
||
{
|
||
name: '已缴费',
|
||
type: 'line',
|
||
smooth: true, // 平滑折线 核心
|
||
data: inData,
|
||
symbol: 'circle',
|
||
symbolSize: 6,
|
||
itemStyle: { color: '#f94144' },
|
||
lineStyle: { width: 4 },
|
||
areaStyle: {
|
||
color: {
|
||
type: 'linear',
|
||
x: 0,
|
||
y: 0,
|
||
x2: 0,
|
||
y2: 1,
|
||
colorStops: [
|
||
{ offset: 0, color: '#fbd7d9' },
|
||
{ offset: 1, color: '#fbd7d9' }
|
||
]
|
||
}
|
||
}
|
||
},
|
||
{
|
||
name: '未缴费',
|
||
type: 'line',
|
||
smooth: true, // 平滑折线 核心
|
||
data: outData,
|
||
symbol: 'circle',
|
||
symbolSize: 6,
|
||
itemStyle: { color: '#f9c74f' },
|
||
lineStyle: { width: 4 },
|
||
areaStyle: {
|
||
color: {
|
||
type: 'linear',
|
||
x: 0,
|
||
y: 0,
|
||
x2: 0,
|
||
y2: 1,
|
||
colorStops: [
|
||
{ offset: 0, color: '#fcf2dc' },
|
||
{ offset: 1, color: '#fcf2dc' }
|
||
]
|
||
}
|
||
}
|
||
}
|
||
]
|
||
});
|
||
// ! 进十日缴费数量情况 -------------------------------------------------------------------------------------
|
||
|
||
const paytypelist = ref([
|
||
{ label: '微信', value: 'payWx', number: 0, color: '#4a3afe' },
|
||
{ label: '支付宝', value: 'payZfb', number: 0, color: '#1e1b39' },
|
||
{ label: '线下', value: 'payOffline', number: 0, color: '#c893fd' }
|
||
]);
|
||
|
||
function getlist() {
|
||
const startData = getPastDayDate(defaultDay);
|
||
income_statsApi(dataTime.value === '' ? startData : dataTime.value).then((res) => {
|
||
form.value = res.data;
|
||
const { payOffline, payWx, payZfb, feeTypeStats, dailyStats } = res.data;
|
||
|
||
const total = (payOffline ?? 0) + (payWx ?? 0) + (payZfb ?? 0);
|
||
if (total > 0) {
|
||
form.value.payOffline = Number.isNaN((payOffline / total) * 100) ? 0 : ((payOffline / total) * 100).toFixed(2);
|
||
form.value.payWx = Number.isNaN((payWx / total) * 100) ? 0 : ((payWx / total) * 100).toFixed(2);
|
||
form.value.payZfb = Number.isNaN((payZfb / total) * 100) ? 0 : ((payWx / total) * 100).toFixed(2);
|
||
|
||
paytypelist.value[0].number = form.value.payOffline;
|
||
paytypelist.value[1].number = form.value.payWx;
|
||
paytypelist.value[2].number = form.value.payZfb;
|
||
paytypelist.value.sort((a, b) => Number(b.number) - Number(a.number));
|
||
}
|
||
|
||
// 收入来源
|
||
// 2. 处理收入来源 (新逻辑)
|
||
if (feeTypeStats && Array.isArray(feeTypeStats)) {
|
||
updateIncomeChart(feeTypeStats);
|
||
}
|
||
|
||
// 3. 【新增】处理缴费走势 (近十日缴费情况)
|
||
if (dailyStats && Array.isArray(dailyStats)) {
|
||
updateFlowLineChart(dailyStats);
|
||
}
|
||
});
|
||
}
|
||
/**
|
||
* 更新缴费走势图表
|
||
* @param stats 后端返回的 dailyStats 数组
|
||
*/
|
||
function updateFlowLineChart(stats: any[]) {
|
||
if (!stats.length) {
|
||
flowLineOption.value.series = [];
|
||
flowLineOption.value.xAxis.data = [];
|
||
return;
|
||
}
|
||
|
||
// 提取数据
|
||
const dates = stats.map((item) => item.statDate);
|
||
const paidData = stats.map((item) => Number(item.totalPaid) || 0);
|
||
const unpaidData = stats.map((item) => Number(item.totalUnpaid) || 0);
|
||
|
||
// 更新图表配置
|
||
// 使用 shallowRef 时,建议替换整个对象或确保深层属性被正确追踪
|
||
// 这里我们直接修改 series 和 xAxis 的数据
|
||
flowLineOption.value = {
|
||
...flowLineOption.value,
|
||
xAxis: {
|
||
...flowLineOption.value.xAxis,
|
||
data: dates
|
||
},
|
||
series: [
|
||
{
|
||
name: '已缴费',
|
||
type: 'line',
|
||
smooth: true,
|
||
data: paidData,
|
||
symbol: 'circle',
|
||
symbolSize: 6,
|
||
itemStyle: { color: '#f94144' },
|
||
lineStyle: { width: 4 },
|
||
areaStyle: {
|
||
color: {
|
||
type: 'linear',
|
||
x: 0,
|
||
y: 0,
|
||
x2: 0,
|
||
y2: 1,
|
||
colorStops: [
|
||
{ offset: 0, color: '#fbd7d9' },
|
||
{ offset: 1, color: '#fbd7d9' }
|
||
]
|
||
}
|
||
}
|
||
},
|
||
{
|
||
name: '未缴费',
|
||
type: 'line',
|
||
smooth: true,
|
||
data: unpaidData,
|
||
symbol: 'circle',
|
||
symbolSize: 6,
|
||
itemStyle: { color: '#f9c74f' },
|
||
lineStyle: { width: 4 },
|
||
areaStyle: {
|
||
color: {
|
||
type: 'linear',
|
||
x: 0,
|
||
y: 0,
|
||
x2: 0,
|
||
y2: 1,
|
||
colorStops: [
|
||
{ offset: 0, color: '#fcf2dc' },
|
||
{ offset: 1, color: '#fcf2dc' }
|
||
]
|
||
}
|
||
}
|
||
}
|
||
]
|
||
};
|
||
}
|
||
/**
|
||
* 更新收入来源图表数组
|
||
* @param stats 后端返回的 feeTypeStats 数组
|
||
*/
|
||
function updateIncomeChart(stats: any[]) {
|
||
let statslist = stats;
|
||
if (statslist.length === 0) {
|
||
incomeChartOptions.value = [];
|
||
statslist = [
|
||
{
|
||
'feeName': '停车费'
|
||
},
|
||
{
|
||
'feeName': '物业费'
|
||
},
|
||
{
|
||
'feeName': '水电费'
|
||
},
|
||
{
|
||
'feeName': '商铺租金'
|
||
},
|
||
{
|
||
'feeName': '维修费'
|
||
}
|
||
];
|
||
}
|
||
|
||
// 【修改点 2】映射生成多个独立的 ECharts 配置
|
||
incomeChartOptions.value = statslist.map((item, index) => {
|
||
const percentage = Number(item.paidPercentage) || 0;
|
||
const color = '#409eff';
|
||
return {
|
||
name: item.feeName, // 图表名称
|
||
options: {
|
||
tooltip: {
|
||
show: false,
|
||
trigger: 'item',
|
||
formatter: '{b}: {c}%'
|
||
},
|
||
series: [
|
||
{
|
||
type: 'pie',
|
||
radius: ['50%', '70%'], // 环形大小
|
||
center: ['50%', '50%'], // 每个图表各自居中
|
||
select: {
|
||
scale: false
|
||
},
|
||
labelLine: {
|
||
show: false
|
||
},
|
||
data: [
|
||
{
|
||
value: 100 - percentage,
|
||
itemStyle: {
|
||
color: '#ebeef5' // 背景色
|
||
},
|
||
emphasis: {
|
||
itemStyle: {
|
||
color: '#ebeef5'
|
||
},
|
||
scale: false
|
||
}
|
||
},
|
||
{
|
||
value: percentage,
|
||
name: item.feeName,
|
||
itemStyle: { color: color },
|
||
label: {
|
||
show: true,
|
||
position: 'center', // 显示在圆环中心
|
||
formatter: '{c}%', // 显示百分比数值
|
||
fontSize: 14,
|
||
fontWeight: 'bold',
|
||
color: '#4ce19c'
|
||
},
|
||
emphasis: {
|
||
scale: true
|
||
}
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
};
|
||
});
|
||
console.log(incomeChartOptions.value);
|
||
}
|
||
function querySearch() {
|
||
getlist();
|
||
}
|
||
function reset() {
|
||
dataTime.value = '';
|
||
querySearch();
|
||
}
|
||
onMounted(() => {
|
||
open.value = true;
|
||
getlist();
|
||
});
|
||
onUnmounted(() => {
|
||
open.value = false;
|
||
});
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.personnel {
|
||
background: linear-gradient(180deg, #deedff 0%, #f8f9fe 50%);
|
||
overflow: auto;
|
||
.el-button {
|
||
width: 80px;
|
||
height: 32px;
|
||
border-radius: 4px;
|
||
}
|
||
.searchBox {
|
||
margin-bottom: 20px;
|
||
}
|
||
.searchLabel {
|
||
width: 100px;
|
||
font-size: 0.95rem;
|
||
}
|
||
/* 入住清空 */
|
||
.cardbox {
|
||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, #ffffff 70%);
|
||
border-radius: 16px 16px 16px 16px;
|
||
border: 2px solid #ffffff;
|
||
font-size: 20px;
|
||
padding: 20px;
|
||
min-height: 275px;
|
||
@media (max-width: 1600px) {
|
||
font-size: 18px;
|
||
}
|
||
@media (max-width: 1300px) {
|
||
font-size: 20px;
|
||
}
|
||
@media (max-width: 1200px) {
|
||
margin-bottom: 20px;
|
||
}
|
||
.card_infoall {
|
||
padding-left: 40px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 20px;
|
||
height: 20px;
|
||
line-height: 20px;
|
||
color: rgba(51, 51, 51, 1);
|
||
font-size: 14px;
|
||
margin-top: 15px;
|
||
}
|
||
|
||
.cardbody {
|
||
padding: 0 30px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
.chart-item {
|
||
flex-shrink: 0;
|
||
}
|
||
.card_leftbox {
|
||
text-align: center;
|
||
.labelbox {
|
||
font-size: 16px;
|
||
}
|
||
.valuebox {
|
||
font-weight: 600;
|
||
font-size: 36px;
|
||
color: #222222;
|
||
}
|
||
}
|
||
.echartsbox {
|
||
width: 400px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.legendbox {
|
||
font-size: 15px;
|
||
li {
|
||
margin-bottom: 20px;
|
||
position: relative;
|
||
width: 100px;
|
||
height: 50px;
|
||
line-height: 50px;
|
||
text-align: left;
|
||
padding-left: 30px;
|
||
i {
|
||
display: block;
|
||
position: absolute;
|
||
left: 0;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
display: block;
|
||
width: 20px;
|
||
height: 20px;
|
||
border-radius: 50%;
|
||
}
|
||
}
|
||
}
|
||
.circlebox {
|
||
margin-left: 60px;
|
||
position: relative;
|
||
width: 300px;
|
||
height: 200px;
|
||
transform: translateY(-40px);
|
||
li {
|
||
position: absolute;
|
||
border-radius: 50%;
|
||
border: 3px solid white;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: #fff;
|
||
font-weight: 450;
|
||
transition: all 0.3s ease; // 添加过渡动画
|
||
|
||
// 默认样式 (作为 Level 1 或基础样式)
|
||
width: 120px;
|
||
height: 120px;
|
||
font-size: 1.2rem;
|
||
right: 40px;
|
||
top: 40px;
|
||
z-index: 10;
|
||
background-color: #c893fd; // 默认颜色,会被 data-bg 覆盖
|
||
|
||
// Level 0: 最大值 (排序后的第一个)
|
||
&[data-level='0'] {
|
||
width: 180px;
|
||
height: 180px;
|
||
left: 0;
|
||
top: 15px;
|
||
right: auto;
|
||
font-size: 1.8rem;
|
||
z-index: 9; // 层级最低,
|
||
}
|
||
|
||
// Level 1: 中间值
|
||
&[data-level='1'] {
|
||
width: 130px;
|
||
height: 130px;
|
||
left: 150px; // 重叠在大球右侧
|
||
top: 0;
|
||
right: auto;
|
||
font-size: 1.3rem;
|
||
z-index: 10;
|
||
}
|
||
|
||
// Level 2: 最小值
|
||
&[data-level='2'] {
|
||
width: 90px;
|
||
height: 90px;
|
||
left: 150px; // 更靠右
|
||
top: 100px; // 靠下
|
||
right: auto;
|
||
font-size: 1rem;
|
||
z-index: 11; // 层级最高,浮在最上面
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|