瀏覽代碼

Merge branch 'master' of http://192.168.0.115:3000/chenzimin2/ZGZQBWG

aamin 2 年之前
父節點
當前提交
9b534ca976

二進制
game/public/unity/disaster-relief/Build/Build.data.unityweb


二進制
game/public/unity/disaster-relief/Build/Build.framework.js.unityweb


File diff suppressed because it is too large
+ 1 - 1
game/public/unity/disaster-relief/Build/Build.loader.js


二進制
game/public/unity/disaster-relief/Build/Build.wasm.unityweb


+ 33 - 33
game/public/unity/disaster-relief/ServiceWorker.js

@@ -1,33 +1,33 @@
-const cacheName = "4dage-RacingCar-0.1.0";
-const contentToCache = [
-    "Build/Build.loader.js",
-    "Build/Build.framework.js.unityweb",
-    "Build/Build.data.unityweb",
-    "Build/Build.wasm.unityweb",
-    "TemplateData/style.css"
-
-];
-
-self.addEventListener('install', function (e) {
-    console.log('[Service Worker] Install');
-    
-    e.waitUntil((async function () {
-      const cache = await caches.open(cacheName);
-      console.log('[Service Worker] Caching all: app shell and content');
-      await cache.addAll(contentToCache);
-    })());
-});
-
-self.addEventListener('fetch', function (e) {
-    e.respondWith((async function () {
-      let response = await caches.match(e.request);
-      console.log(`[Service Worker] Fetching resource: ${e.request.url}`);
-      if (response) { return response; }
-
-      response = await fetch(e.request);
-      const cache = await caches.open(cacheName);
-      console.log(`[Service Worker] Caching new resource: ${e.request.url}`);
-      cache.put(e.request, response.clone());
-      return response;
-    })());
-});
+const cacheName = "4dage-RacingCar-0.1.0";
+const contentToCache = [
+    "Build/Build.loader.js",
+    "Build/Build.framework.js.unityweb",
+    "Build/Build.data.unityweb",
+    "Build/Build.wasm.unityweb",
+    "TemplateData/style.css"
+
+];
+
+self.addEventListener('install', function (e) {
+    console.log('[Service Worker] Install');
+    
+    e.waitUntil((async function () {
+      const cache = await caches.open(cacheName);
+      console.log('[Service Worker] Caching all: app shell and content');
+      await cache.addAll(contentToCache);
+    })());
+});
+
+self.addEventListener('fetch', function (e) {
+    e.respondWith((async function () {
+      let response = await caches.match(e.request);
+      console.log(`[Service Worker] Fetching resource: ${e.request.url}`);
+      if (response) { return response; }
+
+      response = await fetch(e.request);
+      const cache = await caches.open(cacheName);
+      console.log(`[Service Worker] Caching new resource: ${e.request.url}`);
+      cache.put(e.request, response.clone());
+      return response;
+    })());
+});

+ 11 - 11
game/public/unity/disaster-relief/TemplateData/style.css

@@ -1,11 +1,11 @@
-body { padding: 0; margin: 0 }
-#unity-container { position: fixed; width: 100%; height: 100%; }
-#unity-canvas { width: 100%;
-    height: 100%;
-    background: url('bg.jpg') no-repeat center;
-    background-size: cover; }
-#unity-loading-bar { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: none }
-/*#unity-logo { width: 154px; height: 130px; background: url('unity-logo-dark.png') no-repeat center }*/
-#unity-progress-bar-empty { margin-left: auto; margin-right: auto; width: 141px; height: 18px; margin-top: 10px; background: url('progress-bar-empty-dark.png') no-repeat center }
-#unity-progress-bar-full { width: 0%; height: 18px; margin-top: 10px; background: url('progress-bar-full-dark.png') no-repeat center }
-#unity-warning { position: absolute; left: 50%; top: 5%; transform: translate(-50%); background: white; padding: 10px; display: none }
+body { padding: 0; margin: 0 }
+#unity-container { position: fixed; width: 100%; height: 100%; }
+#unity-canvas { width: 100%;
+    height: 100%;
+    background: url('bg.jpg') no-repeat center;
+    background-size: cover; }
+#unity-loading-bar { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: none }
+/*#unity-logo { width: 154px; height: 130px; background: url('unity-logo-dark.png') no-repeat center }*/
+#unity-progress-bar-empty { margin-left: auto; margin-right: auto; width: 141px; height: 18px; margin-top: 10px; background: url('progress-bar-empty-dark.png') no-repeat center }
+#unity-progress-bar-full { width: 0%; height: 18px; margin-top: 10px; background: url('progress-bar-full-dark.png') no-repeat center }
+#unity-warning { position: absolute; left: 50%; top: 5%; transform: translate(-50%); background: white; padding: 10px; display: none }

+ 105 - 105
game/public/unity/disaster-relief/index.html

@@ -1,105 +1,105 @@
-<!DOCTYPE html>
-<html lang="en-us">
-  <head>
-    <meta charset="utf-8">
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <title>应急救灾</title>
-    <link rel="shortcut icon" href="TemplateData/favicon.ico">
-    <link rel="stylesheet" href="TemplateData/style.css">
-    <link rel="manifest" href="manifest.webmanifest">
-  </head>
-  <body>
-    <div id="unity-container">
-      <canvas id="unity-canvas" width=960 height=600 tabindex="-1"></canvas>
-      <div id="unity-loading-bar">
-        <div id="unity-logo"></div>
-        <div id="unity-progress-bar-empty">
-          <div id="unity-progress-bar-full"></div>
-        </div>
-      </div>
-      <div id="unity-warning"> </div>
-    </div>
-    <script src="unity.js">//添加 unity.js 的引用</script>
-    <script>
-      window.addEventListener("load", function () {
-        if ("serviceWorker" in navigator) {
-          navigator.serviceWorker.register("ServiceWorker.js");
-        }
-      });
-
-      var container = document.querySelector("#unity-container");
-      var canvas = document.querySelector("#unity-canvas");
-      var loadingBar = document.querySelector("#unity-loading-bar");
-      var progressBarFull = document.querySelector("#unity-progress-bar-full");
-      var warningBanner = document.querySelector("#unity-warning");
-
-      // Shows a temporary message banner/ribbon for a few seconds, or
-      // a permanent error message on top of the canvas if type=='error'.
-      // If type=='warning', a yellow highlight color is used.
-      // Modify or remove this function to customize the visually presented
-      // way that non-critical warnings and error messages are presented to the
-      // user.
-      function unityShowBanner(msg, type) {
-        function updateBannerVisibility() {
-          warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
-        }
-        var div = document.createElement('div');
-        div.innerHTML = msg;
-        warningBanner.appendChild(div);
-        if (type == 'error') div.style = 'background: red; padding: 10px;';
-        else {
-          if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
-          setTimeout(function() {
-            warningBanner.removeChild(div);
-            updateBannerVisibility();
-          }, 5000);
-        }
-        updateBannerVisibility();
-      }
-
-      var buildUrl = "Build";
-      var loaderUrl = buildUrl + "/Build.loader.js";
-      var config = {
-        arguments: [],
-        dataUrl: buildUrl + "/Build.data.unityweb",
-        frameworkUrl: buildUrl + "/Build.framework.js.unityweb",
-        codeUrl: buildUrl + "/Build.wasm.unityweb",
-        streamingAssetsUrl: "StreamingAssets",
-        companyName: "4dage",
-        productName: "RacingCar",
-        productVersion: "0.1.0",
-        showBanner: unityShowBanner,
-      };
-
-      // By default Unity keeps WebGL canvas render target size matched with
-      // the DOM size of the canvas element (scaled by window.devicePixelRatio)
-      // Set this to false if you want to decouple this synchronization from
-      // happening inside the engine, and you would instead like to size up
-      // the canvas DOM size and WebGL render target sizes yourself.
-      // config.matchWebGLToCanvasSize = false;
-
-      if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
-        // Mobile device style: fill the whole browser client area with the game canvas:
-        var meta = document.createElement('meta');
-        meta.name = 'viewport';
-        meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes';
-        document.getElementsByTagName('head')[0].appendChild(meta);
-      }
-
-      loadingBar.style.display = "block";
-
-      var script = document.createElement("script");
-      script.src = loaderUrl;
-      script.onload = () => {
-        createUnityInstance(canvas, config, (progress) => {
-          progressBarFull.style.width = 100 * progress + "%";
-        }).then((unityInstance) => {
-          loadingBar.style.display = "none";
-        }).catch((message) => {
-          alert(message);
-        });
-      };
-      document.body.appendChild(script);
-    </script>
-  </body>
-</html>
+<!DOCTYPE html>
+<html lang="en-us">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+    <title>应急救灾</title>
+    <link rel="shortcut icon" href="TemplateData/favicon.ico">
+    <link rel="stylesheet" href="TemplateData/style.css">
+    <link rel="manifest" href="manifest.webmanifest">
+  </head>
+  <body>
+    <div id="unity-container">
+      <canvas id="unity-canvas" width=960 height=600 tabindex="-1"></canvas>
+      <div id="unity-loading-bar">
+        <div id="unity-logo"></div>
+        <div id="unity-progress-bar-empty">
+          <div id="unity-progress-bar-full"></div>
+        </div>
+      </div>
+      <div id="unity-warning"> </div>
+    </div>
+    <script src="unity.js">//添加 unity.js 的引用</script>
+    <script>
+      window.addEventListener("load", function () {
+        if ("serviceWorker" in navigator) {
+          navigator.serviceWorker.register("ServiceWorker.js");
+        }
+      });
+
+      var container = document.querySelector("#unity-container");
+      var canvas = document.querySelector("#unity-canvas");
+      var loadingBar = document.querySelector("#unity-loading-bar");
+      var progressBarFull = document.querySelector("#unity-progress-bar-full");
+      var warningBanner = document.querySelector("#unity-warning");
+
+      // Shows a temporary message banner/ribbon for a few seconds, or
+      // a permanent error message on top of the canvas if type=='error'.
+      // If type=='warning', a yellow highlight color is used.
+      // Modify or remove this function to customize the visually presented
+      // way that non-critical warnings and error messages are presented to the
+      // user.
+      function unityShowBanner(msg, type) {
+        function updateBannerVisibility() {
+          warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
+        }
+        var div = document.createElement('div');
+        div.innerHTML = msg;
+        warningBanner.appendChild(div);
+        if (type == 'error') div.style = 'background: red; padding: 10px;';
+        else {
+          if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
+          setTimeout(function() {
+            warningBanner.removeChild(div);
+            updateBannerVisibility();
+          }, 5000);
+        }
+        updateBannerVisibility();
+      }
+
+      var buildUrl = "Build";
+      var loaderUrl = buildUrl + "/Build.loader.js";
+      var config = {
+        arguments: [],
+        dataUrl: buildUrl + "/Build.data.unityweb",
+        frameworkUrl: buildUrl + "/Build.framework.js.unityweb",
+        codeUrl: buildUrl + "/Build.wasm.unityweb",
+        streamingAssetsUrl: "StreamingAssets",
+        companyName: "4dage",
+        productName: "RacingCar",
+        productVersion: "0.1.0",
+        showBanner: unityShowBanner,
+      };
+
+      // By default Unity keeps WebGL canvas render target size matched with
+      // the DOM size of the canvas element (scaled by window.devicePixelRatio)
+      // Set this to false if you want to decouple this synchronization from
+      // happening inside the engine, and you would instead like to size up
+      // the canvas DOM size and WebGL render target sizes yourself.
+      // config.matchWebGLToCanvasSize = false;
+
+      if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
+        // Mobile device style: fill the whole browser client area with the game canvas:
+        var meta = document.createElement('meta');
+        meta.name = 'viewport';
+        meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes';
+        document.getElementsByTagName('head')[0].appendChild(meta);
+      }
+
+      loadingBar.style.display = "block";
+
+      var script = document.createElement("script");
+      script.src = loaderUrl;
+      script.onload = () => {
+        createUnityInstance(canvas, config, (progress) => {
+          progressBarFull.style.width = 100 * progress + "%";
+        }).then((unityInstance) => {
+          loadingBar.style.display = "none";
+        }).catch((message) => {
+          alert(message);
+        });
+      };
+      document.body.appendChild(script);
+    </script>
+  </body>
+</html>

+ 14 - 14
game/public/unity/disaster-relief/manifest.webmanifest

@@ -1,15 +1,15 @@
-{
-    "name": "RacingCar",
-    "short_name": "RacingCar",
-    "start_url": "index.html",
-    "display": "fullscreen",
-    "background_color": "#231F20",
-    "theme_color": "#000",
-    "description": "",
-    "icons": [{
-      "src": "TemplateData/icons/unity-logo-dark.png",
-      "sizes": "144x144",
-      "type": "image/png",
-      "purpose": "any maskable"
-    }]
+{
+    "name": "RacingCar",
+    "short_name": "RacingCar",
+    "start_url": "index.html",
+    "display": "fullscreen",
+    "background_color": "#231F20",
+    "theme_color": "#000",
+    "description": "",
+    "icons": [{
+      "src": "TemplateData/icons/unity-logo-dark.png",
+      "sizes": "144x144",
+      "type": "image/png",
+      "purpose": "any maskable"
+    }]
   }

二進制
game/public/unity/lost-children/Build/H5Game-ChinaSecuritiesMuseumMaze.data.unityweb


二進制
game/public/unity/lost-children/Build/H5Game-ChinaSecuritiesMuseumMaze.framework.js.unityweb


二進制
game/public/unity/lost-children/Build/H5Game-ChinaSecuritiesMuseumMaze.wasm.unityweb


+ 5 - 3
game/src/App.vue

@@ -70,9 +70,11 @@ html, body {
 // }
 
 // 滚动条,只设置某一项可能导致不生效。
-::-webkit-scrollbar { background: #dddecc; width: 6px; height: 6px; }
-::-webkit-scrollbar-thumb { background: #828a5b; border-radius: 3px; }
-::-webkit-scrollbar-corner { background: #dddecc; }
+.not-mobile{
+  ::-webkit-scrollbar { background: #dddecc; width: 6px; height: 6px; }
+  ::-webkit-scrollbar-thumb { background: #828a5b; border-radius: 3px; }
+  ::-webkit-scrollbar-corner { background: #dddecc; }
+}
 
 // vue组件过渡效果
 .fade-out-leave-active {

+ 8 - 2
game/src/api.js

@@ -194,12 +194,13 @@ export async function getScore() {
   }
 }
 export async function addScore(score) {
+  const scoreEncrypted = encodeStr(Base64.encode(score))
   const res = await axios({
     method: 'post',
     url: `${process.env.VUE_APP_DEPLOY_ORIGIN}/api/cms/game/point/add`,
     data: {
-      score,
-      type: 'game',
+      score: scoreEncrypted,
+      type: '玩游戏',
       userId: store.state.userInfo.id,
     },
     headers: {
@@ -290,4 +291,9 @@ export async function redeem(description, name, phone, prizeId, score) {
   } else {
     return res.data.data
   }
+}
+
+export function notifyQuit() {
+  console.log('小游戏:调用父窗口的goBackSceneFu方法……')
+  window.parent?.goBackSceneFu()
 }

二進制
game/src/assets/images/icon_home_2.png


二進制
game/src/assets/images/no-list.png


二進制
game/src/assets/images/no-prize.png


+ 2 - 0
game/src/main.js

@@ -102,4 +102,6 @@ VueViewer.setDefaults({
 // 必须在vue根组件挂载之后执行
 if (uaInfo.device.type === 'mobile') {
   document.getElementById('app').classList.add('mobile')
+} else {
+  document.getElementById('app').classList.add('not-mobile')
 }

+ 6 - 2
game/src/store/index.js

@@ -33,8 +33,9 @@ export default createStore({
       // second: 60,
       // type: "game",
       // updateTime: "2024-01-08 19:28:35",
-      // }
+      // },
     ],
+    isDirectPlayGame: false,
     score: undefined,
     ifScoreLimitReached: undefined,
     scoreLimit: undefined,
@@ -80,7 +81,10 @@ export default createStore({
     },
     setScoreLimit(state, value) {
       state.scoreLimit = value
-    }
+    },
+    setIsDirectPlayGame(state, value) {
+      state.isDirectPlayGame = value
+    },
   },
   actions: {
   },

+ 8 - 4
game/src/views/ExamPaper2.vue

@@ -130,7 +130,7 @@ import { useRoute, useRouter } from "vue-router"
 import { useStore } from "vuex"
 import dayjs from 'dayjs'
 import { shuffle } from 'lodash'
-import { addScore, getScore, getExamQuestionList } from '@/api.js'
+import { addScore, getScore, getExamQuestionList, notifyQuit } from '@/api.js'
 import GameRule from '@/components/GameRule.vue'
 import NotifyBonusPointReachedLimit from '@/components/NotifyBonusPointReachedLimit.vue'
 
@@ -184,9 +184,13 @@ getExamQuestionList().then((res) => {
 })
 
 function onClickReturnHome() {
-  router.push({
-    name: 'HomeView',
-  })
+  if (store.state.isDirectPlayGame) {
+    notifyQuit()
+  } else {
+    router.push({
+      name: 'HomeView',
+    })
+  }
 }
 
 /**

+ 8 - 3
game/src/views/ExamPaper3.vue

@@ -48,6 +48,7 @@
 import { ref, computed, watch, onMounted } from "vue"
 import { useRoute, useRouter } from "vue-router"
 import { useStore } from "vuex"
+import { notifyQuit } from '@/api.js'
 
 const route = useRoute()
 const router = useRouter()
@@ -59,9 +60,13 @@ const {
 } = useSizeAdapt(390, 752)
 
 function onClickReturnHome() {
-  router.push({
-    name: 'HomeView',
-  })
+  if (store.state.isDirectPlayGame) {
+    notifyQuit()
+  } else {
+    router.push({
+      name: 'HomeView',
+    })
+  }
 }
 
 </script>

+ 8 - 3
game/src/views/GameByUnity.vue

@@ -44,6 +44,7 @@ import { useStore } from "vuex"
 import GameRule from '@/components/GameRule.vue'
 import NotifyBonusPointReachedLimit from '@/components/NotifyBonusPointReachedLimit.vue'
 import { onBeforeUnmount } from "vue"
+import { notifyQuit } from '@/api.js'
 
 const route = useRoute()
 const router = useRouter()
@@ -77,9 +78,13 @@ const returnHomeBtnBgImgUrl = require(`@/assets/images/icon_home${floatingBtnFil
 const gameRuleBtnBgImgUrl = require(`@/assets/images/icon_rules${floatingBtnFileNameAffix}.png`)
 
 function onClickReturnHome() {
-  router.push({
-    name: 'HomeView',
-  })
+  if (store.state.isDirectPlayGame) {
+    notifyQuit()
+  } else {
+    router.push({
+      name: 'HomeView',
+    })
+  }
 }
 
 const gameRuleConfigMap = {

+ 16 - 2
game/src/views/HomeView.vue

@@ -196,6 +196,17 @@
           draggable="false"
         >
       </button>
+      <button
+        class="quit"
+        @click="onClickQuit"
+      >
+        <img
+          class=""
+          src="@/assets/images/icon_home_2.png"
+          alt=""
+          draggable="false"
+        >
+      </button>
     </div>
 
     <!-- 让用户选择是否登录、注册 -->
@@ -222,7 +233,7 @@ import { useRoute, useRouter } from "vue-router"
 import { useStore } from "vuex"
 import ClipboardJS from 'clipboard'
 import { showDialog } from 'vant'
-import { logout, getScore } from '@/api.js'
+import { logout, getScore, notifyQuit } from '@/api.js'
 import LoginChoice from '@/components/LoginChoice.vue'
 
 const route = useRoute()
@@ -393,6 +404,7 @@ if (route.query.gameIdx) {
   router.replace({
     name: route.name
   })
+  store.commit('setIsDirectPlayGame', true)
   if (isShowLoading.value) {
     hideLoadingCallback = () => {
       onClickGameEntry(gameIdx)
@@ -402,7 +414,9 @@ if (route.query.gameIdx) {
   }
 }
 
-console.log(route.query)
+function onClickQuit() {
+  notifyQuit()
+}
 </script>
 
 <style lang="less" scoped>

+ 8 - 4
game/src/views/PairUp.vue

@@ -114,7 +114,7 @@ import { useStore } from "vuex"
 import dayjs from 'dayjs'
 import { shuffle } from 'lodash'
 import PairUpOver from '@/components/PairUpOver.vue'
-import { addScore, getScore } from '@/api.js'
+import { addScore, getScore, notifyQuit } from '@/api.js'
 import GameRule from '@/components/GameRule.vue'
 import NotifyBonusPointReachedLimit from '@/components/NotifyBonusPointReachedLimit.vue'
 
@@ -130,9 +130,13 @@ const {
 const isShowRule = ref(false)
 
 function onClickReturnHome() {
-  router.push({
-    name: 'HomeView',
-  })
+  if (store.state.isDirectPlayGame) {
+    notifyQuit()
+  } else {
+    router.push({
+      name: 'HomeView',
+    })
+  }
 }
 
 const isOver = ref(false)

+ 8 - 4
game/src/views/PlantTree.vue

@@ -155,7 +155,7 @@ import { useStore } from "vuex"
 import dayjs from 'dayjs'
 import { showDialog } from 'vant'
 import { shuffle } from 'lodash'
-import { addScore, getScore } from '@/api.js'
+import { addScore, getScore, notifyQuit } from '@/api.js'
 import GameRule from '@/components/GameRule.vue'
 import NotifyBonusPointReachedLimit from '@/components/NotifyBonusPointReachedLimit.vue'
 
@@ -169,9 +169,13 @@ const {
 } = useSizeAdapt(390, 752)
 
 function onClickReturnHome() {
-  router.push({
-    name: 'HomeView',
-  })
+  if (store.state.isDirectPlayGame) {
+    notifyQuit()
+  } else {
+    router.push({
+      name: 'HomeView',
+    })
+  }
 }
 
 const isShowRule = ref(false)

+ 19 - 0
game/src/views/RedeemForm.vue

@@ -96,11 +96,30 @@ const prizeInfo = JSON.parse(route.query.prizeInfo)
 const result = ref(store.state.score - prizeInfo.score)
 
 const name = ref('')
+watch(name, (vNew) => {
+  if (vNew.length > 20) {
+    vNew = vNew.slice(0, 20)
+    name.value = vNew
+  }
+})
 const contact = ref('')
+watch(contact, (vNew) => {
+  if (vNew.length > 20) {
+    vNew = vNew.slice(0, 20)
+    contact.value = vNew
+  }
+})
 const detail = ref('')
+watch(detail, (vNew) => {
+  if (vNew.length > 50) {
+    vNew = vNew.slice(0, 50)
+    detail.value = vNew
+  }
+})
 
 const ifShowNotify = ref(false)
 const haveSubmitted = ref(false)
+
 function submit() {
   redeem(detail.value, name.value, contact.value, prizeInfo.id, prizeInfo.score).then((res) => {
     ifShowNotify.value = true

+ 118 - 10
game/src/views/ShopView.vue

@@ -50,8 +50,10 @@
         </button>
       </div>
       <div
-        v-if="prizeList.length && currentTabIdx === 0"
+        v-if="prizeList && prizeList.length && currentTabIdx === 0"
+        ref="prizeListRef"
         class="prize-list"
+        @scroll="onPrizeListScroll"
       >
         <article
           v-for="prizeItem in prizeList"
@@ -95,8 +97,24 @@
         </article>
       </div>
       <div
-        v-if="recordList.length && currentTabIdx === 1"
+        v-if="prizeList?.length === 0 && currentTabIdx === 0"
+        class="prize-list"
+      >
+        <img
+          class="no-data"
+          src="@/assets/images/no-prize.png"
+          alt=""
+          draggable="false"
+        >
+        <p class="no-data">
+          礼物准备中
+        </p>
+      </div>
+      <div
+        v-if="recordList && recordList.length && currentTabIdx === 1"
+        ref="recordListRef"
         class="record-list"
+        @scroll="onRecordListScroll"
       >
         <div
           v-for="recordItem in recordList"
@@ -121,6 +139,20 @@
           </div>
         </div>
       </div>
+      <div
+        v-if="recordList?.length === 0 && currentTabIdx === 1"
+        class="record-list"
+      >
+        <img
+          class="no-data"
+          src="@/assets/images/no-list.png"
+          alt=""
+          draggable="false"
+        >
+        <p class="no-data">
+          暂无记录
+        </p>
+      </div>
     </div>
   </div>
 </template>
@@ -147,11 +179,47 @@ getScore().then((res) => {
 
 const currentTabIdx = ref(0)
 
-const prizeList = ref([])
-getPrizeList(0, 20).then((res) => {
-  prizeList.value = res.records
-  console.log(prizeList.value)
-})
+/**
+ * 奖品列表
+ */
+const prizeListRef = ref(null)
+const prizeList = ref(null)
+const isFetchingMorePrize = ref(false)
+const haveGotAllPrize = ref(false)
+
+function fetchMorePrizeData() {
+  if (haveGotAllPrize.value) {
+    return
+  }
+  if (isFetchingMorePrize.value) {
+    return
+  }
+  isFetchingMorePrize.value = true
+  getPrizeList(prizeList.value?.length / 10 + 1 || 0, 10).then((res) => {
+    if (prizeList.value) {
+      prizeList.value = prizeList.value.concat(res.records)
+    } else {
+      prizeList.value = res.records
+    }
+    console.log(prizeList.value.length, res.total)
+    if (prizeList.value.length >= res.total) {
+      haveGotAllPrize.value = true
+    }
+  }).finally(() => {
+    isFetchingMorePrize.value = false
+  })
+}
+
+fetchMorePrizeData()
+
+function onPrizeListScroll(e) {
+  console.log(prizeListRef.value.scrollHeight)
+  console.log(prizeListRef.value.scrollTop + prizeListRef.value.clientHeight)
+  if (Math.abs(prizeListRef.value.scrollTop + prizeListRef.value.clientHeight - prizeListRef.value.scrollHeight) < 10) {
+    fetchMorePrizeData()
+  }
+}
+
 function onClickPrizeItem(prizeItem) {
   router.push({
     name: 'RedeemForm',
@@ -161,9 +229,11 @@ function onClickPrizeItem(prizeItem) {
   })
 }
 
-const recordList = ref([])
+const recordList = ref(null)
 getBonusPointRecord().then((res) => {
-  recordList.value = res.reverse()
+  recordList.value = res.filter((item) => {
+    return item.score !== 0 && item.score !== '0' && item.score !== '+0' && item.score !== '-0'
+  })
 })
 
 </script>
@@ -262,6 +332,7 @@ getBonusPointRecord().then((res) => {
       height: calc(513 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       overflow: auto;
       padding-left: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      position: relative;
       >article.prize-item{
         display: inline-block;
         width: calc(168 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
@@ -270,7 +341,7 @@ getBonusPointRecord().then((res) => {
         border-radius: calc(11 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         padding: calc(15 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) calc(12 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         position: relative;
-        margin-right: calc(15 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        margin-right: calc(14 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         margin-bottom: calc(15 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         cursor: pointer;
         >img.thumb{
@@ -337,12 +408,31 @@ getBonusPointRecord().then((res) => {
       >article.prize-item.disabled{
         pointer-events: none;
       }
+      >img.no-data{
+        position: absolute;
+        left: 50%;
+        top: 50%;
+        top: calc(120 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        transform: translate(-50%, 0);
+      }
+      >p.no-data{
+        position: absolute;
+        left: 50%;
+        top: calc(265 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        transform: translate(-50%, 0);
+        font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-weight: 400;
+        color: #AF9D85;
+        line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
     }
     >div.record-list{
       height: calc(515 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       overflow: auto;
       padding-left: calc(26 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       padding-right: calc(26 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      position: relative;
       >.record-item{
         width: 100%;
         margin-bottom: calc(15 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
@@ -379,6 +469,24 @@ getBonusPointRecord().then((res) => {
           color: #FF4040;
         }
       }
+      >img.no-data{
+        position: absolute;
+        left: 50%;
+        top: 50%;
+        top: calc(120 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        transform: translate(-50%, 0);
+      }
+      >p.no-data{
+        position: absolute;
+        left: 50%;
+        top: calc(265 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        transform: translate(-50%, 0);
+        font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-weight: 400;
+        color: #AF9D85;
+        line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
     }
   }
 }