瀏覽代碼

登录开屏

ouyj 4 月之前
父節點
當前提交
a1f0ec1d3b
共有 2 個文件被更改,包括 574 次插入0 次删除
  1. 574 0
      pages/splash/index.uvue
  2. 二進制
      static/images/splash/blackground.png

+ 574 - 0
pages/splash/index.uvue

@@ -0,0 +1,574 @@
+<template>
+  <view class="splash-container" v-if="checked && showSplash && userData.rankingItems.length > 0">
+    <!-- 使用image组件作为背景图 -->
+    <image class="splash-background-image" src="/static/images/splash/blackground.png" mode="aspectFill"></image>
+    <view class="splash-content">
+      <!-- 本月工分模块 -->
+      <view class="module monthly-score">
+        <text class="module-title">本月工分</text>
+        <view class="score-container">
+          <text class="score-icon">🏆</text>
+          <text class="score-value">{{ userData.monthlyScore }}</text>
+        </view>
+      </view>
+
+      <!-- 个人排名模块 -->
+      <view class="module personal-ranking">
+        <text class="module-title">个人排名</text>
+      </view>
+
+      <!-- 排名模块 -->
+      <view class="module station-ranking" v-for="(item, index) in userData.rankingItems" :key="index">
+        <view class="ranking-item">
+          <template v-if="getRankingIcon(index).type === 'emoji'">
+            <text class="ranking-icon">{{ getRankingIcon(index).value }}</text>
+          </template>
+          <template v-else>
+            <image class="ranking-icon" :src="getRankingIcon(index).value" mode="aspectFit"></image>
+          </template>
+          <text class="ranking-name">{{ item.name }}</text>
+          <view class="ranking-circle-wrapper">
+            <view class="ranking-number" :class="getRankingSizeClass(index)">
+              <text class="ranking-number-text">{{ item.rank }}/{{ item.total }}</text>
+            </view>
+          </view>
+          <text class="ranking-label">第{{ item.rank }}名</text>
+        </view>
+      </view>
+    </view>
+
+    <!-- 倒计时和关闭按钮 -->
+    <view class="splash-footer">
+      <view class="countdown" @tap="closeSplash">
+        <text class="countdown-text">{{ countdown }}s 后跳过</text>
+      </view>
+      <view class="close-button" @tap="closeSplash">
+        <text class="close-text">关闭</text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script lang="uts">
+import { ref, onMounted, onUnmounted } from 'vue';
+import { getConfigKey } from '@/api/system/config';
+import { selectHomePageData } from '@/api/index/index';
+// 用户数据类型定义
+type RankingItem = {
+  name: string;
+  rank: number;
+  total: number;
+}
+
+type UserData = {
+  monthlyScore: number;
+  rankingItems: RankingItem[]
+}
+
+type SplashConfig = {
+  enable: boolean
+}
+
+type RankingIcon = {
+  type: 'emoji' | 'image';
+  value: string;
+}
+
+type ApiResponse<T> = {
+  data: T;
+}
+
+export default {
+  setup() {
+    // 响应式数据
+    const countdown = ref<number>(3);
+    const showSplash = ref<boolean>(false);  // 默认不显示
+    const checked = ref<boolean>(false);     // 是否已完成配置检查
+    /* const userData = ref<UserData>({
+      monthlyScore: 120,
+      rankingItems: [
+        { name: '东山电场', rank: 3, total: 15 },
+        { name: '陆上设备维护中心', rank: 12, total: 86 },
+        { name: '公司', rank: 45, total: 320 }
+      ]
+    }); */
+	const userData = ref<UserData>({
+      monthlyScore: 0,
+      rankingItems: []
+    });
+    let countdownTimer: number | null = null;
+    let hasRedirected = false; // 防止重复跳转
+	
+	// 关闭跳转页
+	const closeSplash = (): void => {
+	  if (hasRedirected) return; // 防止重复跳转
+	  
+	  if (countdownTimer != null) {
+	    clearInterval(countdownTimer as number);
+	    countdownTimer = null;
+	  }
+	  
+	  hasRedirected = true;
+	  // 跳转到主页
+	  uni.navigateTo({
+	    url: '/pages/index/index'
+	  });
+	};
+
+    // 检查后端配置是否启用跳转页
+    const checkSplashConfig = async (): Promise<void> => {
+      try {
+        // 调用后端API获取配置
+        const response = await getConfigKey('gxt.app.splash'); 
+        
+        console.log("完整响应:", response);
+        
+        let showSplashValue = false; 
+		const respObj = response as UTSJSONObject;
+		if (respObj.hasOwnProperty('msg')) {
+			const msgValue = respObj['msg'] as string;
+			showSplashValue = msgValue == '1';
+			console.log("msgValue:", msgValue);
+		} 
+        
+        showSplash.value = showSplashValue;
+        checked.value = true; // 标记已检查完配置
+        
+        console.log("showSplash.value:", showSplash.value);
+        
+        // 如果不启用跳转页,直接关闭
+        if (!showSplashValue) {
+          closeSplash();
+        }
+      } catch (error) {
+        console.error('获取跳转页配置失败:', error);
+        // 出错时默认不显示跳转页
+        showSplash.value = false;
+        checked.value = true;
+        closeSplash();
+      }
+    };
+
+    // 获取用户数据
+    const fetchUserData = async (): Promise<void> => {
+      try {
+        // 调用后端API获取用户数据
+        const response = await selectHomePageData();
+        console.log("response====",response)
+        // 根据响应结果更新userData
+        if (response != null) {
+          const respObj = response as UTSJSONObject; 
+          const data = respObj['data'] as UTSJSONObject; 
+          
+          // 更新月度工分
+          if (data.hasOwnProperty('score')) {
+            const scoreVal = data['score'] as number;
+            userData.value.monthlyScore = Math.round(scoreVal * 100) / 100;
+          }
+          
+          // 初始化默认值
+          let deptName = '未知部门';
+          let center = '未知中心';
+          let companyName = '未知公司';
+          
+          // 从scoreDept中提取部门、中心和公司名称
+          if (data.hasOwnProperty('scoreDept') && Array.isArray(data['scoreDept']) && (data['scoreDept'] as any[]).length > 0) {
+            const scoreDept = data['scoreDept'] as UTSJSONObject[];
+            const firstItem = scoreDept[0];
+            if (firstItem.hasOwnProperty('deptName')) {
+              deptName = firstItem['deptName'] as string;
+            }
+            if (firstItem.hasOwnProperty('center')) {
+              center = firstItem['center'] as string;
+            }
+            if (firstItem.hasOwnProperty('companyName')) {
+              companyName = firstItem['companyName'] as string;
+            }
+          }
+          
+          // 更新排名信息
+          const rankingItems : RankingItem[] = [];
+          
+          // 部门排名(东山电场)
+          if (data.hasOwnProperty('deptSort') && data.hasOwnProperty('scoreDept')) {
+            const deptSort = typeof data['deptSort'] === 'number' ? data['deptSort'] as number : 0;
+            const scoreDept = Array.isArray(data['scoreDept']) ? data['scoreDept'] as any[] : [];
+            // 只有当部门排序大于0且scoreDept数组不为空时才添加
+            if (deptSort > 0 && scoreDept.length > 0) {
+              rankingItems.push({
+                name: deptName,
+                rank: deptSort,
+                total: scoreDept.length
+              });
+            }
+          }
+          
+          // 中心排名(陆上设备维护中心)
+          if (data.hasOwnProperty('centerSort') && data.hasOwnProperty('scoreCenter')) {
+            const centerSort = typeof data['centerSort'] === 'number' ? data['centerSort'] as number : 0;
+            const scoreCenter = Array.isArray(data['scoreCenter']) ? data['scoreCenter'] as any[] : [];
+            // 只有当中心排序大于0且scoreCenter数组不为空时才添加
+            if (centerSort > 0 && scoreCenter.length > 0) {
+              rankingItems.push({
+                name: center,
+                rank: centerSort,
+                total: scoreCenter.length
+              });
+            }
+          }
+          
+          // 公司排名
+          if (data.hasOwnProperty('companySort') && data.hasOwnProperty('scoreCompany')) {
+            const companySort = typeof data['companySort'] === 'number' ? data['companySort'] as number : 0;
+            const scoreCompany = Array.isArray(data['scoreCompany']) ? data['scoreCompany'] as any[] : [];
+            // 只有当公司排序大于0且scoreCompany数组不为空时才添加
+            if (companySort > 0 && scoreCompany.length > 0) {
+              rankingItems.push({
+                name: companyName,
+                rank: companySort,
+                total: scoreCompany.length
+              });
+            }
+          }
+          
+          // 更新rankingItems
+          userData.value.rankingItems = rankingItems;
+          
+          // 如果rankingItems为空,直接跳转到登录页
+          if (rankingItems.length === 0) {
+            closeSplash();
+          }
+        } else {
+          // 如果没有获取到数据,直接跳转到登录页
+          closeSplash();
+        }
+      } catch (error) {
+        console.error('获取用户数据失败:', error);
+        // 出错时直接跳转到登录页
+        closeSplash();
+      }
+    };
+
+    // 开始倒计时
+    const startCountdown = (): void => {
+      if (hasRedirected) return; // 如果已经跳转则不启动倒计时
+      
+      countdownTimer = setInterval(() => {
+        if (countdown.value > 1) {
+          countdown.value--;
+        } else {
+          closeSplash();
+        }
+      }, 1000);
+    };
+
+    // 生命周期钩子
+    onMounted(() => {
+      checkSplashConfig().then(() => {
+        // 只有在确定显示开屏页的情况下才获取数据和启动倒计时
+        if (showSplash.value) {
+          fetchUserData().then(() => {
+            // 只有在rankingItems有数据的情况下才启动倒计时
+            if (userData.value.rankingItems.length > 0) {
+              startCountdown();
+            } else {
+              // 否则直接跳转
+              closeSplash();
+            }
+          });
+        }
+      });
+    });
+
+    // 根据索引获取对应的图标信息
+    const getRankingIcon = (index: number): RankingIcon => {
+      //索引0对应电场,索引1对应维护中心,索引2对应公司
+      const icons: RankingIcon[] = [
+        { type: 'emoji', value: '🏭' },
+        { type: 'emoji', value: '⚙️' },
+        { type: 'emoji', value: '🏢' }
+      ];
+	  
+	  /* const icons = [
+	    { type: 'image', value: '/static/icons/power-plant.png' },
+	    { type: 'image', value: '/static/icons/maintenance-center.png' },
+	    { type: 'image', value: '/static/icons/company.png' }
+	  ]; */
+
+      return index >= 0 && index < icons.length ? icons[index] : { type: 'emoji', value: '' };
+    };
+    
+    // 根据索引获取排名圆圈的大小类
+    const getRankingSizeClass = (index: number): string => {
+      // size-1 对应最小的圆圈,size-3 对应最大的圆圈
+      const size = Math.min(index + 1, 3);
+      return `size-${size}`;
+    };
+
+    onUnmounted(() => {
+      if (countdownTimer != null) {
+        clearInterval(countdownTimer as number);
+        countdownTimer = null;
+      }
+    });
+
+    return {
+      countdown,
+      showSplash,
+      checked,
+      userData,
+      closeSplash,
+      getRankingIcon,
+      getRankingSizeClass
+    };
+  }
+};
+</script>
+
+<style lang="scss">
+.splash-container {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  z-index: 9999;
+  /* background-image: url('/static/images/splash/blackground.png');
+  background-size: cover;
+  background-position: center; */
+}
+
+.splash-background-image {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: -1;
+}
+
+.splash-content {
+  width: 100%;
+  max-width: 400px;
+  margin: 0 auto;
+}
+
+.module {
+  background: linear-gradient(to right, rgba(40, 80, 140, 0.7), rgba(20, 40, 80, 0.8));
+  border-radius: 16px;
+  padding: 40rpx;
+  border: 1.5px solid #93c5fd;
+  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.15);
+  margin-bottom: 20rpx;
+  margin-left: auto;
+  margin-right: auto;
+  width: 90%;
+}
+
+.personal-ranking {
+  background: linear-gradient(to right, rgba(40, 80, 140, 0.6), rgba(20, 40, 80, 0.7));
+  border-radius: 16px;
+  padding: 45rpx;
+  border: 1px solid rgba(147, 197, 253, 0.2);
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
+  margin-bottom: 20rpx;
+  margin-left: auto;
+  margin-right: auto;
+  width: 90%;
+}
+
+.monthly-score {
+  text-align: center;
+  margin-bottom: 10rpx;
+  position: relative;
+  top: -60rpx;
+  z-index: 10;
+  padding: 70rpx 40rpx !important;
+  margin-top: 60rpx;
+  border-radius: 30px !important;
+  border: 1.5px solid #93c5fd !important;
+  background: linear-gradient(to right, rgba(30, 70, 130, 0.8), rgba(10, 30, 60, 0.9)) !important;
+  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.15);
+}
+
+.monthly-score .module-title {
+  font-size: 50rpx;
+  font-weight: bold;
+  margin-bottom: 30rpx;
+  transform: translateY(-10rpx);
+}
+
+.personal-ranking .module-title {
+  text-align: left !important;
+  display: flex;
+  align-items: center;
+  justify-content: flex-start;
+  height: 100%;
+  padding: 0;
+  margin-bottom: 0;
+}
+
+.module-title {
+  color: #ffffff;
+  font-size: 36rpx;
+  font-weight: bold;
+  margin-bottom: 0;
+  text-align: center;
+}
+
+.score-container {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+}
+
+.score-icon {
+  font-size: 80rpx;
+  margin-right: 30rpx;
+}
+
+.score-value {
+  color: #38bdf8;
+  font-size: 96rpx;
+  font-weight: bold;
+}
+
+.ranking-item {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  width: 100%;
+  padding-left: 0;
+  margin-left: 0;
+}
+
+.ranking-icon {
+  font-size: 48rpx;
+  width: 48rpx;
+  height: 48rpx;
+  margin-right: 20rpx;
+  margin-left: 0rpx;
+  color: #94a3b8;
+}
+
+.ranking-icon[image] {
+  width: 48rpx;
+  height: 48rpx;
+}
+
+.ranking-name {
+  color: #ffffff;
+  font-size: 32rpx;
+  font-weight: normal;
+  flex: 1;
+  margin-left: -10rpx;
+}
+
+.ranking-number {
+  background: #38bdf8;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  box-shadow: 0 0 20px rgba(59, 130, 246, 0.6);
+}
+
+.ranking-circle-wrapper {
+  width: 120rpx;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin: 0 20rpx;
+  margin-left: 0;
+}
+
+.ranking-number.size-1 {
+  width: 80rpx;
+  height: 80rpx;
+  border-radius: 40rpx;
+}
+
+.ranking-number.size-2 {
+  width: 90rpx;
+  height: 90rpx;
+  border-radius: 45rpx;
+}
+
+.ranking-number.size-3 {
+  width: 100rpx;
+  height: 100rpx;
+  border-radius: 50rpx;
+}
+
+.ranking-number-text {
+  color: #ffffff;
+  font-weight: normal;
+  text-align: center;
+  font-size: 28rpx;
+}
+
+.ranking-number.size-1 .ranking-number-text {
+  font-size: 22rpx;
+}
+
+.ranking-number.size-2 .ranking-number-text {
+  font-size: 24rpx;
+}
+
+.ranking-number.size-3 .ranking-number-text {
+  font-size: 26rpx;
+}
+
+.ranking-label {
+  color: #ffffff;
+  font-size: 32rpx;
+  white-space: nowrap;
+  margin-right: 20rpx;
+}
+
+.splash-footer {
+  position: absolute;
+  top: 80rpx;
+  right: 30rpx;
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+  width: 250rpx;
+  height: 60rpx;
+  background: rgba(0, 0, 0, 0.3);
+  border-radius: 30rpx;
+  border: 1px solid rgba(147, 197, 253, 0.1);
+  padding: 0 20rpx;
+}
+
+.splash-footer .countdown {
+  margin-bottom: 0;
+  background: transparent;
+  border: none;
+  padding: 0;
+}
+
+.splash-footer .close-button {
+  background: transparent;
+  border: none;
+  padding: 0;
+  margin-left: 10rpx;
+}
+
+.countdown-text {
+  color: #ffffff;
+  font-size: 28rpx;
+  font-weight: bold;
+}
+
+.close-text {
+  color: #ffffff;
+  font-size: 28rpx;
+  font-weight: normal;
+}
+</style>

二進制
static/images/splash/blackground.png