Przeglądaj źródła

feat: 大屏导航栏开发

周玉环 2 dni temu
rodzic
commit
b98a1dd28a

+ 44 - 0
xinkeaboard-admin/src/pages/statistics/bigscreen/components/CountUp.js

@@ -0,0 +1,44 @@
+import React from "react";
+
+class CountUp extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      value: 0,
+    };
+    this.start = 0;
+    this.rafId = null;
+  }
+
+  componentDidMount() {
+    this.animateCount();
+  }
+
+  componentWillUnmount() {
+    cancelAnimationFrame(this.rafId);
+  }
+
+  animateCount() {
+    const { end = 0, duration = 1000 } = this.props;
+    const startTime = performance.now();
+
+    const step = (now) => {
+      const elapsed = now - startTime;
+      const progress = Math.min(elapsed / duration, 1); // 限制在 0~1
+      const currentValue = Math.floor(progress * (end - this.start) + this.start);
+      this.setState({ value: currentValue });
+
+      if (progress < 1) {
+        this.rafId = requestAnimationFrame(step);
+      }
+    };
+
+    this.rafId = requestAnimationFrame(step);
+  }
+
+  render() {
+    return <div className={this.props.className}>{this.state.value.toLocaleString()}</div>;
+  }
+}
+
+export default CountUp;

+ 44 - 27
xinkeaboard-admin/src/pages/statistics/bigscreen/components/DateTimeDisplay.js

@@ -1,22 +1,34 @@
 import React from "react";
+import styles from "../styles/date_time_display.less";
 
 class DateTimeDisplay extends React.Component {
-  state = {
-    currentTime: "",
-  };
+  constructor(props) {
+    super(props);
+    this.state = {
+      now: new Date(),
+    };
+    this.timer = null;
+  }
+
   componentDidMount() {
-    this.timeInterval = setInterval(() => setState(new Date()), 1000);
-    return () => clearInterval(this.timeInterval);
+    // 每秒更新时间
+    this.timer = setInterval(() => {
+      this.setState({ now: new Date() });
+    }, 1000);
   }
 
   componentWillUnmount() {
-    clearInterval(this.timeInterval);
+    // 清除定时器
+    clearInterval(this.timer);
   }
 
-  formatDate = (date) => {
+  formatDate(date) {
     const year = date.getFullYear();
-    const month = `${date.getMonth() + 1}`.padStart(2, "0");
-    const day = `${date.getDate()}`.padStart(2, "0");
+    const month = (date.getMonth() + 1).toString().padStart(2, "0");
+    const day = date
+      .getDate()
+      .toString()
+      .padStart(2, "0");
     const weekdays = [
       "星期日",
       "星期一",
@@ -26,29 +38,34 @@ class DateTimeDisplay extends React.Component {
       "星期五",
       "星期六",
     ];
-    return `${year}/${month}/${day} ${weekdays[date.getDay()]}`;
-  };
+    const weekday = weekdays[date.getDay()];
 
-  formatTime = (date) => {
-    const hours = `${date.getHours()}`.padStart(2, "0");
-    const minutes = `${date.getMinutes()}`.padStart(2, "0");
-    const seconds = `${date.getSeconds()}`.padStart(2, "0");
-    return `${hours}:${minutes}:${seconds}`;
-  };
+    const hours = date
+      .getHours()
+      .toString()
+      .padStart(2, "0");
+    const minutes = date
+      .getMinutes()
+      .toString()
+      .padStart(2, "0");
+    const seconds = date
+      .getSeconds()
+      .toString()
+      .padStart(2, "0");
 
-  render() {
-    const { currentTime } = this.state;
     return (
-      <div className="bg-gray-900 text-white px-4 py-2 flex items-center justify-end rounded-r-lg font-mono">
-        <span className="text-blue-400 mr-2">
-          {this.formatDate(currentTime)}
-        </span>
-        <span className="text-white text-xl font-bold">
-          {this.formatTime(currentTime)}
-        </span>
-      </div>
+      <>
+        <span className={styles.date}>{`${year}/${month}/${day} `}</span>
+        <span className={styles.week}>{`${weekday} `}</span>
+        <span className={styles.time}>{`${hours}:${minutes}:${seconds}`}</span>
+      </>
     );
   }
+
+  render() {
+    const { now } = this.state;
+    return this.formatDate(now);
+  }
 }
 
 export default DateTimeDisplay;

+ 4 - 1
xinkeaboard-admin/src/pages/statistics/bigscreen/components/HeadContent.js

@@ -1,5 +1,6 @@
 import React from "react";
 import { connect } from "dva";
+import DateTimeDisplay from "./DateTimeDisplay";
 import styles from "../styles/header_content.less";
 
 class HeaderContent extends React.Component {
@@ -40,7 +41,9 @@ class HeaderContent extends React.Component {
           <span>更新时间: </span>
           <span>{currentTime}</span>
         </div>
-        <div className={styles.headerContentTime}>{currentTime}</div>
+        <div className={styles.headerContentTime}>
+          <DateTimeDisplay />
+        </div>
       </div>
     );
   }

+ 24 - 11
xinkeaboard-admin/src/pages/statistics/bigscreen/components/Overview.js

@@ -1,4 +1,5 @@
 import React from "react";
+import CountUp from "./CountUp";
 import styles from "../styles/overview.less";
 
 class OverView extends React.Component {
@@ -14,15 +15,19 @@ class OverView extends React.Component {
   render() {
     return (
       <div className={styles.overview}>
-        <img className={styles.overview_bg} src={require("../../../../assets/bigscreen/overview-bg.png")} />
+        <img
+          className={styles.overview_bg}
+          src={require("../../../../assets/bigscreen/overview-bg.png")}
+        />
         <span className={styles.overview_title}>平台数据汇总</span>
         <div className={styles.overview_content}>
           <div className={styles.overview_content_item}>
             <img
+              className={styles.item_img}
               src={require("../../../../assets/bigscreen/member.png")}
             />
-            <div className={styles.item_value}>123456</div>
-            <div className={styles.item_label}>用户总数</div>
+            <CountUp className={styles.item_value} end={123456} />
+            <div className={styles.item_label}>会员</div>
           </div>
           <div className={styles.overview_content_item}>
             <img
@@ -30,24 +35,32 @@ class OverView extends React.Component {
               src={require("../../../../assets/bigscreen/dis.png")}
             />
 
-            <div className={styles.item_value}>123456</div>
-            <div className={styles.item_label}>订单总数</div>
+            <CountUp className={styles.item_value} end={123456} />
+            <div className={styles.item_label}>分销商</div>
           </div>
           <div className={styles.overview_content_item}>
             <img
+              className={styles.item_img}
               src={require("../../../../assets/bigscreen/store.png")}
             />
-
-            <div className={styles.item_value}>123456</div>
-            <div className={styles.item_label}>商品总数</div>
+            <CountUp className={styles.item_value} end={123456} />
+            <div className={styles.item_label}>店铺</div>
           </div>
           <div className={styles.overview_content_item}>
             <img
+              className={styles.item_img}
               src={require("../../../../assets/bigscreen/dis.png")}
             />
-
-            <div className={styles.item_value}>123456</div>
-            <div className={styles.item_label}>访问总数</div>
+            <CountUp className={styles.item_value} end={123456} />
+            <div className={styles.item_label}>服务商</div>
+          </div>
+          <div className={styles.overview_content_item}>
+            <img
+              className={styles.item_img}
+              src={require("../../../../assets/bigscreen/member.png")}
+            />
+            <CountUp className={styles.item_value} end={123456} />
+            <div className={styles.item_label}>商品总数</div>
           </div>
         </div>
       </div>

+ 18 - 0
xinkeaboard-admin/src/pages/statistics/bigscreen/styles/date_time_display.less

@@ -0,0 +1,18 @@
+.date {
+  font-weight: 400;
+  font-size: 28px;
+  color: #036eb8;
+}
+
+.week {
+  font-weight: 400;
+  font-size: 28px;
+  color: #036eb8;
+  margin: 0 20px;
+}
+
+.time {
+  font-weight: 400;
+  font-size: 48px;
+  color: #ffffff;
+}

+ 1 - 7
xinkeaboard-admin/src/pages/statistics/bigscreen/styles/header_content.less

@@ -32,13 +32,7 @@
 
   .headerContentTime {
     position: absolute;
-    bottom: 0px;
+    top: 5px;
     right: 100px;
-    font-size: @font-title-sub;
-    background: linear-gradient(90deg, #00c6ff, #0072ff);
-    -webkit-background-clip: text;
-    -webkit-text-fill-color: transparent;
-    background-clip: text;
-    color: transparent;
   }
 }

+ 30 - 23
xinkeaboard-admin/src/pages/statistics/bigscreen/styles/overview.less

@@ -28,29 +28,36 @@
     display: flex;
 
     .overview_content_item {
-        flex: 1;
-        height: 100%;
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-        justify-content: center;
-    
-        .item_img {
-            width: 172px;
-            height: 240px;
-        }
-    
-        .item_value {
-            font-size: 48px;
-            font-weight: bold;
-            color: #fff;
-            margin-bottom: 8px;
-        }
-    
-        .item_label {
-            font-size: 24px;
-            color: #fff;
-        }
+      position: relative;
+      flex: 1;
+      height: 100%;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+
+      .item_img {
+        width: 172px;
+        height: 240px;
+      }
+
+      .item_value {
+        position: absolute;
+        top: 0;
+        font-family: YouSheBiaoTiHei;
+        font-weight: 400;
+        font-size: 64px;
+        color: #ffffff;
+      }
+
+      .item_label {
+        position: absolute;
+        top: 100px;
+        font-family: Source Han Sans CN, Source Han Sans CN;
+        font-weight: 400;
+        font-size: 32px;
+        color: #ffffff;
+      }
     }
   }
 }