code4eat 2 tuần trước cách đây
mục cha
commit
1f3dffbc50

BIN
BI大屏_web_new.zip


+ 11 - 4
src/components/DrawerButtons.tsx

@@ -1,6 +1,7 @@
 import React, { useState, useEffect } from 'react';
 import styled from 'styled-components';
 import { apiGet } from '../utils/request';
+import { getDefaultDate } from '../App'; // 导入getDefaultDate函数
 
 // 按钮容器
 const ButtonsContainer = styled.div`
@@ -280,9 +281,11 @@ const DrawerButtons: React.FC<DrawerButtonsProps> = ({ currentScreen, equipCode,
     if (activeDrawer === '补药清单') {
       setLoading(true);
       setError(null);
+      // 使用getDefaultDate()函数获取日期,而不是直接使用传入的dateTime
+      const defaultDate = getDefaultDate();
       apiGet('/equipMana/drugReplenishedList', {
         params: {
-          dateTime,
+          dateTime: defaultDate,
           equipCode: equipCode === 'total' ? '0' : equipCode
         }
       })
@@ -303,9 +306,11 @@ const DrawerButtons: React.FC<DrawerButtonsProps> = ({ currentScreen, equipCode,
     if (activeDrawer === '效期清单') {
       setLoading(true);
       setError(null);
+      // 使用getDefaultDate()函数获取日期,而不是直接使用传入的dateTime
+      const defaultDate = getDefaultDate();
       apiGet('/equipMana/drugExpiryDateList', {
         params: {
-          dateTime,
+          dateTime: defaultDate,
           equipCode: equipCode === 'total' ? '0' : equipCode
         }
       })
@@ -326,9 +331,11 @@ const DrawerButtons: React.FC<DrawerButtonsProps> = ({ currentScreen, equipCode,
     if (activeDrawer === '滞销清单') {
       setLoading(true);
       setError(null);
+      // 使用getDefaultDate()函数获取日期,而不是直接使用传入的dateTime
+      const defaultDate = getDefaultDate();
       apiGet('/equipMana/drugSlowMovingList', {
         params: {
-          dateTime,
+          dateTime: defaultDate,
           equipCode: equipCode === 'total' ? '0' : equipCode
         }
       })
@@ -346,7 +353,7 @@ const DrawerButtons: React.FC<DrawerButtonsProps> = ({ currentScreen, equipCode,
         })
         .finally(() => setLoading(false));
     }
-  }, [activeDrawer, equipCode, dateTime]);
+  }, [activeDrawer, equipCode]); // 移除dateTime依赖,因为现在使用getDefaultDate()
   
   // 效期清单数据结构调整
   const expiryData = [

+ 1 - 1
src/components/charts/ConsumedMedicineTop8Chart.tsx

@@ -10,7 +10,7 @@ const ChartWrapper = styled.div`
   height: 100%;
   position: relative;
   overflow: hidden;
-  border: 1px solid #2980B9;
+
   box-sizing: border-box;
   display: flex;
   flex-direction: column;

+ 1 - 1
src/components/charts/CyanDualGaugeChart.tsx

@@ -10,7 +10,7 @@ const ChartWrapper = styled.div`
   height: 100%;
   position: relative;
   overflow: hidden;
-  border: 1px solid #2980B9;
+
 `;
 
 // 内容容器

+ 1 - 1
src/components/charts/DailyMedicineQuantityChart.tsx

@@ -11,7 +11,7 @@ const ChartWrapper = styled.div`
   height: 100%;
   position: relative;
   overflow: hidden;
-  border: 1px solid #2980B9;
+ 
 `;
 
 // 组件标题 - 使用与其他模块相同的样式

+ 1 - 1
src/components/charts/DailyPrescriptionChart.tsx

@@ -11,7 +11,7 @@ const ChartWrapper = styled.div`
   height: 100%;
   position: relative;
   overflow: hidden;
-  border: 1px solid #2980B9;
+
 `;
 
 // 组件标题 - 使用与其他模块相同的样式

+ 1 - 1
src/components/charts/DepartmentPrescriptionTop10Chart.tsx

@@ -10,7 +10,7 @@ const ChartWrapper = styled.div`
   height: 100%;
   position: relative;
   overflow: hidden;
-  border: 1px solid #2980B9;
+
   box-sizing: border-box;
   display: flex;
   flex-direction: column;

+ 1 - 1
src/components/charts/DeviceOverviewChart.tsx

@@ -36,7 +36,7 @@ const ContentBox = styled.div`
   flex-direction: column;
   padding: 0.5vw;
   padding-top: 1.2vw;
-  height: calc(100% - 2.3vw);
+  height: calc(100% - 1.6vw);
   gap: 0.8vw;
   flex: 1;
   overflow: visible;

+ 1 - 1
src/components/charts/GreenDualGaugeChart.tsx

@@ -10,7 +10,7 @@ const ChartWrapper = styled.div`
   height: 100%;
   position: relative;
   overflow: hidden;
-  border: 1px solid #2980B9;
+
 `;
 
 // 内容容器

+ 1 - 1
src/components/charts/HospitalStatusChart.tsx

@@ -41,7 +41,7 @@ const DualPanelLayout = styled.div`
   display: grid;
   grid-template-columns: 1fr 1fr;
   grid-gap: 2vw; // 增加中间间距
-  height: calc(100% - 2.5vw);
+  height: calc(100% - 1.6vw);
   align-items: stretch;
   
   @media (max-width: 1200px) {

+ 1 - 1
src/components/charts/HourlyTrendChart.tsx

@@ -36,7 +36,7 @@ const PanelHeader = styled.div`
 const ContentLayout = styled.div`
   display: flex;
   flex-direction: column;
-  height: calc(100% - 2.3vw);
+  height: calc(100% - 1.6vw);
   padding: 0.5vw 1.5%;
 `;
 

+ 1 - 1
src/components/charts/InventoryManagement.tsx

@@ -38,7 +38,7 @@ const ContentBox = styled.div`
   flex-direction: column;
   padding: 0.5vw;
   padding-top: 1.2vw;
-  height: calc(100% - 1vw);
+  height: calc(100% - 1.6vw);
  
 `;
 

+ 1 - 1
src/components/charts/MedicineExpiryChart.tsx

@@ -37,7 +37,7 @@ const ContentBox = styled.div`
   flex-direction: column;
   padding: 0.5vw;
   padding-top: 1.2vw;
-  height: calc(100% - 2.3vw);
+  height: calc(100% - 1.6vw);
 `;
 
 interface ExpiryData {

+ 53 - 21
src/components/charts/MedicineStatusChart.tsx

@@ -36,7 +36,7 @@ const PanelHeader = styled.div`
 // 内容布局
 const ContentLayout = styled.div`
   display: flex;
-  height: calc(100% - 2.3vw);
+  height: calc(100% - 1.6vw);  // 只减去标题高度
   padding: 0.5vw;
 `;
 
@@ -46,6 +46,7 @@ const PieChartContainer = styled.div`
   height: 100%;
   position: relative;
   display: flex;
+  padding-top: 2vw;
 `;
 
 // 饼图区域
@@ -55,7 +56,8 @@ const ChartArea = styled.div`
   height: 100%;
   display: flex;
   flex-direction: column;
-  justify-content: center;
+  justify-content: flex-start; // 顶部对齐
+  align-items: flex-start; // 左上对齐
   padding-left: 0vw;
 `;
 
@@ -64,8 +66,9 @@ const LegendArea = styled.div`
   width: 3vw;
   height: 100%;
   display: flex;
-  justify-content: flex-start;
-  align-items: center;
+  flex-direction: column;
+  justify-content: flex-start; // 顶部对齐
+  align-items: flex-start;
   margin-left: 0vw;
 `;
 
@@ -134,7 +137,7 @@ const MetricData = styled.div`
     /* font-weight: bold; */
     color: #fff;
     line-height: 1.8vw;
-    margin-bottom: 0.1vw;
+    margin-bottom: 1vw;
     font-family: 'DingTalk JinBuTi', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
   }
   
@@ -200,13 +203,37 @@ const LegendItem = styled.div<{ color: string }>`
   }
 `;
 
-// 底部文本
-const BottomText = styled.div`
-  position: absolute;
-  bottom: 0.5vw;
-  left:3vw;
+// 饼图内容包装器
+const PieContentWrapper = styled.div`
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: flex-start; // 顶部对齐,减少与饼图的整体间距
+  width: 100%;
+  height: 100%;
+`;
+
+// 饼图标题
+const PieChartTitle = styled.div`
+  font-size: 0.53vw;
+  color: #CCE6FF;
+  margin-top: 1vw; // 与左侧“待发药”保持一致的上边距
+  margin-bottom: 1vw;
+  text-align: left;
+  flex-shrink: 0;
+  font-family: 'DingTalk JinBuTi', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
+  white-space: nowrap;
+  line-height: 1.2;
+`;
+
+// 顶部文本(待发药)
+const TopText = styled.div`
   font-size: 0.7vw;
   color: #7e9bcc;
+  margin-top: 0.4vw; // 减小顶部间距
+  text-align: center;
+  flex-shrink: 0;
   
   span {
     font-size: 1vw;
@@ -396,7 +423,7 @@ const MedicineStatusChart: React.FC = () => {
           type: 'pie',
           roseType: 'area',
           radius: ['15%', '60%'],
-          center: ['50%', '50%'],
+          center: ['50%', '40%'],
           avoidLabelOverlap: false,
           itemStyle: {
             borderRadius: 0,
@@ -545,7 +572,7 @@ const MedicineStatusChart: React.FC = () => {
     return (
       <MedicineStatusPanel>
         <PanelHeader>发药状态一览</PanelHeader>
-        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: 'calc(100% - 2.3vw)' }}>
+        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: 'calc(100% - 1.6vw)' }}>
           <div style={{ color: '#7e9bcc', fontSize: '0.8vw' }}>数据加载中...</div>
         </div>
       </MedicineStatusPanel>
@@ -558,17 +585,22 @@ const MedicineStatusChart: React.FC = () => {
       <ContentLayout>
         <PieChartContainer>
           <ChartArea>
-            <ReactECharts
-              ref={pieChartRef}
-              option={getPieOption()}
-              style={{ height: '100%', width: '100%' }}
-              opts={{ renderer: 'canvas' }}
-            />
-            <BottomText>
-              待发药:<span>{data?.pendingTaskCount ?? 0}</span>
-            </BottomText>
+            <PieContentWrapper>
+              <TopText>
+                待发药:<span>{data?.pendingTaskCount ?? 0}</span>
+              </TopText>
+              <div style={{ height: '10vw', width: '10vw', flexShrink: 0 }}>
+                <ReactECharts
+                  ref={pieChartRef}
+                  option={getPieOption()}
+                  style={{ height: '100%', width: '100%' }}
+                  opts={{ renderer: 'canvas' }}
+                />
+              </div>
+            </PieContentWrapper>
           </ChartArea>
           <LegendArea>
+            <PieChartTitle>待发药科室top5</PieChartTitle>
             <Legend>
               {/* 饼图图例,顺序与topDepartments一致,安全处理 */}
               {(data.topDepartments && Array.isArray(data.topDepartments)) 

+ 57 - 17
src/components/charts/PatientMedicineTimeChart.tsx

@@ -185,7 +185,8 @@ interface HourlyPickupRate {
   pickupIntervalRates?: PickupIntervalRate[]; // 该时段内的取药区间率数据
   // 兼容实际接口返回的字段
   hour?: string;                 // 小时,如 "8"
-  hourLabel?: string;            // 小时标签,如 "08:00"
+  hourLabel?: string;            // 小时标签,如 "08:00"(取药接口使用)
+  hourLable?: string;            // 小时标签,如 "08:00"(配药接口使用,注意拼写)
   preparationIntervalRates?: PreparationIntervalRate[]; // 配药时间区间数据
 }
 
@@ -402,11 +403,18 @@ const PatientMedicineTimeChart: React.FC = () => {
     xAxisData = ptTakeDrugData.hourlyPickupRates
       .map(item => item.timePeriodStart || '')
       .filter(Boolean);
+    console.log('取药时间x轴数据:', xAxisData, '原始数据:', ptTakeDrugData.hourlyPickupRates);
   } else if (!defaultFlag && drugPrepareData && drugPrepareData.hourlyRates) {
-    // 患者配药时间接口:使用 hourLabel
+    // 患者配药时间接口:使用 hourLable(注意接口返回的字段名拼写)
     xAxisData = drugPrepareData.hourlyRates
-      .map(item => item.hourLabel || '')
+      .map(item => item.hourLable || '')
       .filter(Boolean);
+    console.log('配药时间x轴数据:', xAxisData, '原始数据:', drugPrepareData.hourlyRates);
+  }
+  
+  // 如果x轴数据为空,记录日志但不添加假数据
+  if (xAxisData.length === 0) {
+    console.warn('x轴数据为空,接口未返回有效数据');
   }
   
   // 准备柱状图数据,只使用接口真实数据,不再使用模拟数据填充
@@ -505,23 +513,41 @@ const PatientMedicineTimeChart: React.FC = () => {
         textStyle: { fontSize: axisFontSize }
       },
       legend: { show: false },
-      grid: { left: '2%', right: '2%', bottom: '6%', top: '10%', containLabel: true },
+      grid: { left: '3%', right: '3%', bottom: '2%', top: '10%', containLabel: true },
       xAxis: {
         type: 'category',
-        data: xAxisData.length > 0 ? xAxisData : [],
-        axisLine: { lineStyle: { color: 'rgba(255,255,255,0.3)' } },
-        axisLabel: { color: '#CCE6FF', fontSize: axisFontSize, align: 'center' },
-        axisTick: { alignWithLabel: true }
+        data: xAxisData,
+        axisLine: { 
+          show: xAxisData.length > 0,
+          lineStyle: { color: 'rgba(255,255,255,0.3)' } 
+        },
+        axisLabel: { 
+          show: xAxisData.length > 0,
+          color: '#CCE6FF', 
+          fontSize: axisFontSize, 
+          align: 'center',
+          margin: 8,
+          interval: 0  // 显示所有标签
+        },
+        axisTick: { 
+          show: xAxisData.length > 0,
+          alignWithLabel: true,
+          length: 4
+        }
       },
       yAxis: {
         type: 'value',
-        min: 0, // 修改最小值为0,以适应实际数据
+        min: 0,
         max: 100,
-        interval: 20, // 调整间隔更合理
+        interval: 20,
         axisLine: { show: false },
         axisTick: { show: false },
-        splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)', type: 'solid' } },
+        splitLine: { 
+          show: xAxisData.length > 0,
+          lineStyle: { color: 'rgba(255,255,255,0.1)', type: 'solid' } 
+        },
         axisLabel: {
+          show: xAxisData.length > 0,
           color: '#CCE6FF',
           fontSize: axisFontSize,
           formatter: (val: number) => val + '%'
@@ -556,12 +582,26 @@ const PatientMedicineTimeChart: React.FC = () => {
               </LegendItem>
             ))}
           </LegendBar>
-          <ReactECharts
-            ref={chartRef}
-            option={getBarConfig()}
-            style={{ width: '100%', height: '80%' }}
-            opts={{ renderer: 'canvas' }}
-          />
+          {xAxisData.length > 0 ? (
+            <ReactECharts
+              ref={chartRef}
+              option={getBarConfig()}
+              style={{ width: '100%', height: '80%' }}
+              opts={{ renderer: 'canvas' }}
+            />
+          ) : (
+            <div style={{ 
+              width: '100%', 
+              height: '80%', 
+              display: 'flex', 
+              justifyContent: 'center', 
+              alignItems: 'center',
+              color: '#7e9bcc',
+              fontSize: '0.8vw'
+            }}>
+              暂无数据
+            </div>
+          )}
         </ChartArea>
         {/* 右侧水波比例卡片区 */}
         <CardArea>

+ 1 - 1
src/components/charts/PeakHoursChart.tsx

@@ -11,7 +11,7 @@ const ChartWrapper = styled.div`
   height: 100%;
   position: relative;
   overflow: hidden;
-  border: 1px solid #2980B9;
+
 `;
 
 // 组件标题 - 使用与其他模块相同的样式

+ 1 - 2
src/components/charts/PharmacistWorkloadChart.tsx

@@ -10,7 +10,6 @@ const ChartWrapper = styled.div`
   height: 100%;
   position: relative;
   overflow: hidden;
-  border: 1px solid #2980B9;
   box-sizing: border-box;
   display: flex;
   flex-direction: column;
@@ -207,7 +206,7 @@ const PharmacistWorkloadChart: React.FC = () => {
           <Table>
             <TableHeader>
               <tr>
-                <th>员工编号</th>
+                <th>药师工号</th>
                 <th>调配处方量</th>
                 <th>发药处方量</th>
                 <th>总工作量</th>

+ 0 - 1
src/components/charts/PrescriptionBoxDistributionChart.tsx

@@ -12,7 +12,6 @@ const ChartWrapper = styled.div`
   height: 100%;
   position: relative;
   overflow: hidden;
-  border: 1px solid #2980B9;
   display: flex;
   flex-direction: column;
 `;

+ 1 - 1
src/components/charts/PrescriptionDistributionChart.tsx

@@ -12,7 +12,7 @@ const ChartWrapper = styled.div`
   height: 100%;
   position: relative;
   overflow: hidden;
-  border: 1px solid #2980B9;
+
   display: flex;
   flex-direction: column;
 `;

+ 1 - 1
src/components/charts/PurpleDualGaugeChart.tsx

@@ -10,7 +10,7 @@ const ChartWrapper = styled.div`
   height: 100%;
   position: relative;
   overflow: hidden;
-  border: 1px solid #2980B9;
+
 `;
 
 // 内容容器

+ 1 - 1
src/components/charts/TodayForecastTotalChart.tsx

@@ -40,7 +40,7 @@ const CardsLayout = styled.div`
   display: flex;
   justify-content: space-around;
   align-items: center;
-  height: calc(100% - 2.3vw);
+  height: calc(100% - 1.6vw);
   /* padding: 1vw 2vw; */
 `;
 

+ 38 - 10
src/components/charts/WindowMonitorChart.tsx

@@ -35,7 +35,7 @@ const PanelHeader = styled.div`
 // 主体布局
 const MainLayout = styled.div`
   display: flex;
-  height: calc(100% - 2.3vw);
+  height: calc(100% - 1.6vw);
   width: 100%;
 `;
 
@@ -236,7 +236,9 @@ const WindowMonitorChart: React.FC = () => {
   const chartRef = useRef<ReactECharts>(null);
   // 柱形图圆角和字体自适应
   const [barRadius, setBarRadius] = useState(6); // 默认6
-  const [barFontSize, setBarFontSize] = useState(12); // 默认12
+  const [barFontSize, setBarFontSize] = useState(12); // 默认12(用于柱顶标签、图例等)
+  const [axisFontSize, setAxisFontSize] = useState(12); // 坐标轴字号
+  const [dotFontSize, setDotFontSize] = useState(14); // x轴状态圆点字号(与坐标轴分离)
 
   // 动态计算圆角和字体大小
   const calcBarRadius = () => {
@@ -245,9 +247,15 @@ const WindowMonitorChart: React.FC = () => {
       const width = container.offsetWidth;
       const radius = Math.max(2, Math.min(16, Math.floor(width * 0.006)));
       setBarRadius(radius);
-      // 自适应字体大小,最小10,最大18
+      // 自适应字体大小:柱顶/图例用(保持原范围)
       const fontSize = Math.max(10, Math.min(18, Math.floor(width * 0.012)));
       setBarFontSize(fontSize);
+      // 自适应坐标轴字体大小:略小一些
+      const axisSize = Math.max(10, Math.min(20, Math.floor(width * 0.013)));
+      setAxisFontSize(axisSize);
+      // 自适应圆点字号:略微调小整体尺寸
+      const dotSize = Math.max(axisSize + 6, Math.min(40, Math.floor(width * 0.023)));
+      setDotFontSize(dotSize);
     }
   };
 
@@ -288,7 +296,7 @@ const WindowMonitorChart: React.FC = () => {
       });
       // 如需定时模拟更新,可加定时器
     } else {
-      // 正式环境下用接口数据
+      // 正式环境下用接口数据 
       const dateTime = getDefaultDate();
       apiGet('/todayData/windowMonitor', { params: { dateTime } })
         .then(res => {
@@ -406,7 +414,7 @@ const WindowMonitorChart: React.FC = () => {
       axisLine: { lineStyle: { color: 'rgba(255,,255,0.3)' } },
       axisLabel: {
         color: '#CCE6FF',
-        fontSize: barFontSize,
+        fontSize: axisFontSize,
         align: 'center',
         interval: 0,
         rotate: 0,
@@ -426,10 +434,10 @@ const WindowMonitorChart: React.FC = () => {
           return '{dotGray|●} ' + value;
         },
         rich: {
-          dotRed: { color: '#FF3456', fontSize: Math.floor(barFontSize * 0.6), padding: [0, 5, 0, 0] },
-          dotGreen: { color: '#44E695', fontSize: Math.floor(barFontSize * 0.6), padding: [0, 5, 0, 0] },
-          dotBlue: { color: '#2D4F72', fontSize: Math.floor(barFontSize * 0.6), padding: [0, 5, 0, 0] },
-          dotGray: { color: '#999999', fontSize: Math.floor(barFontSize * 0.6), padding: [0, 5, 0, 0] }
+          dotRed: { color: '#FF3456', fontSize: dotFontSize, padding: [0, Math.floor(dotFontSize * 0.2), 0, 0], fontFamily: 'DingTalk JinBuTi, PingFang SC, Microsoft YaHei, Arial, sans-serif' },
+          dotGreen: { color: '#44E695', fontSize: dotFontSize, padding: [0, Math.floor(dotFontSize * 0.2), 0, 0], fontFamily: 'DingTalk JinBuTi, PingFang SC, Microsoft YaHei, Arial, sans-serif' },
+          dotBlue: { color: '#2D4F72', fontSize: dotFontSize, padding: [0, Math.floor(dotFontSize * 0.2), 0, 0], fontFamily: 'DingTalk JinBuTi, PingFang SC, Microsoft YaHei, Arial, sans-serif' },
+          dotGray: { color: '#999999', fontSize: dotFontSize, padding: [0, Math.floor(dotFontSize * 0.2), 0, 0], fontFamily: 'DingTalk JinBuTi, PingFang SC, Microsoft YaHei, Arial, sans-serif' }
         }
       },
       axisTick: { alignWithLabel: true }
@@ -462,7 +470,7 @@ const WindowMonitorChart: React.FC = () => {
       splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)', type: 'dashed' } },
       axisLabel: { 
         color: '#CCE6FF', 
-        fontSize: barFontSize
+        fontSize: axisFontSize
       }
     },
     // series用窗口的待取人数和待发人数
@@ -482,6 +490,16 @@ const WindowMonitorChart: React.FC = () => {
           },
           borderRadius: [barRadius, barRadius, 0, 0] // 圆角自适应
         },
+        label: {
+          show: true,
+          position: 'top',
+          color: '#CCE6FF',
+          fontSize: barFontSize,
+          fontFamily: 'DingTalk JinBuTi',
+          formatter: function(params: any) {
+            return params.value > 0 ? params.value : '';
+          }
+        },
         data: windowData.windowsstatusList.map(item => item.pendingPreparationCount)
       },
       {
@@ -499,6 +517,16 @@ const WindowMonitorChart: React.FC = () => {
           },
           borderRadius: [barRadius, barRadius, 0, 0] // 圆角自适应
         },
+        label: {
+          show: true,
+          position: 'top',
+          color: '#CCE6FF',
+          fontSize: barFontSize,
+          fontFamily: 'DingTalk JinBuTi',
+          formatter: function(params: any) {
+            return params.value > 0 ? params.value : '';
+          }
+        },
         data: windowData.windowsstatusList.map(item => item.pendingDispensingCount)
       }
     ]

+ 4 - 3
src/components/styled/DashboardStyles.ts

@@ -64,9 +64,10 @@ export const ContentInner = styled.div`
   display: grid;
   grid-template-columns: repeat(2, 1fr);
   grid-template-rows: repeat(3, 1fr);
-  gap: 30px;
-  padding: 3.5vw; // 内容区内边距
-  padding-top: 2.5vw;
+  column-gap: 2vw; // 列间距使用响应式单位
+  row-gap: 1vw;    // 行间距使用响应式单位,减少垂直占用
+  padding: 2.5vw;  // 减少内边距
+  padding-top: 1.5vw; // 减少顶部内边距
   box-sizing: border-box;
 `;