Forráskód Böngészése

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

aamin 2 éve
szülő
commit
b53b16ad85

+ 1 - 1
game/.env.mytest

@@ -1,4 +1,4 @@
 VUE_APP_CLI_MODE=test
 NODE_ENV=production
 PUBLIC_PATH=./
-VUE_APP_API_PREFIX=https://sit-cnzhengquan.4dage.com/
+VUE_APP_API_PREFIX=https://sit-cnzhengquan.4dage.com

+ 31 - 2
game/README.md

@@ -1,14 +1,43 @@
 ## 部署测试环境
-文件存放位置:
 
-访问url:
+### 文件存放位置
+/Default/阿里云/项目节点/项目测试/阿里云-四维时代-项目测试服务器-8.135.106.227/data/data/game_zhongguo_zhengquan_data/game/
+
+### 访问url
+https://sit-cnzhengquan.4dage.com/game/index.html#/
 
 ## 笔记
 
 ## 还缺资源:
 
 ## todo
+拿到游戏规则后才能跳转到游戏界面
+
+积分达到上限时的提示文字样式
+
+
+
+score随时更新到localstorage
+
+
+游戏规则
+
+题目列表
+
+
+
+
+
+查看积分记录
+
+积分商城
+
+
+
+
+
 
+接入unity游戏
 
 
 

+ 8 - 1
game/src/App.vue

@@ -8,7 +8,7 @@
 import { ref, computed, watch, onMounted } from "vue"
 import { useRoute, useRouter } from "vue-router"
 import { useStore } from "vuex"
-import { checkLoginStatusAndProcess } from '@/api.js'
+import { checkLoginStatusAndProcess, getGameRuleList, getScoreLimit } from '@/api.js'
 const {
   windowSizeInCssForRef,
   windowSizeWhenDesignForRef,
@@ -20,6 +20,13 @@ const store = useStore()
 
 checkLoginStatusAndProcess()
 
+getGameRuleList().then((res) => {
+  store.commit('setGameRuleList', res)
+})
+getScoreLimit().then((res) => {
+  store.commit('setScoreLimit', res)
+})
+
 </script>
 
 <style lang="less">

+ 63 - 1
game/src/api.js

@@ -136,4 +136,66 @@ export async function changePassword(newPassword, oldPassword) {
   } else {
     return
   }
-}
+}
+
+export async function getGameRuleList() {
+  const res = await axios({
+    method: 'get',
+    url: `${process.env.VUE_APP_API_PREFIX}/api/show/rule/getList?rnd=${Math.random()}`,
+    params: {
+      type: 'game',
+    },
+  })
+  if (res.data.code !== 0) {
+    throw (`获取游戏规则失败:${res.data.msg}`)
+  } else {
+    return res.data.data
+  }
+}
+export async function getScoreLimit() {
+  const res = await axios({
+    method: 'get',
+    url: `${process.env.VUE_APP_API_PREFIX}/api/show/rule/getList?rnd=${Math.random()}`,
+    params: {
+      type: 'day',
+    },
+  })
+  if (res.data.code !== 0) {
+    throw (`获取积分上限失败:${res.data.msg}`)
+  } else {
+    return res.data.data[0].score
+  }
+}
+export async function getScore() {
+  const res = await axios({
+    method: 'get',
+    url: `${process.env.VUE_APP_API_PREFIX}/api/cms/game/getPoint?rnd=${Math.random()}`,
+    headers: {
+      token: store.state.token,
+    }
+  })
+  if (res.data.code !== 0) {
+    throw (`获取积分失败:${res.data.msg}`)
+  } else {
+    return res.data.data
+  }
+}
+export async function addScore(score) {
+  const res = await axios({
+    method: 'post',
+    url: `${process.env.VUE_APP_API_PREFIX}/api/cms/game/point/add`,
+    data: {
+      score,
+      type: 'game',
+      userId: store.state.userInfo.id,
+    },
+    headers: {
+      token: store.state.token,
+    }
+  })
+  if (res.data.code !== 0) {
+    throw (`新增积分失败:${res.data.msg}`)
+  } else {
+    return res.data.data
+  }
+}

BIN
game/src/assets/images/btn-login-bg-2.png


BIN
game/src/assets/images/btn-sign-up-bg-2.png


BIN
game/src/assets/images/btn-visitor-bg.png


BIN
game/src/assets/images/icon-close.png


BIN
game/src/assets/images/plant-tree-tree-1.png


BIN
game/src/assets/images/plant-tree-tree-2.png


BIN
game/src/assets/images/plant-tree-tree-3.png


BIN
game/src/assets/images/plant-tree-tree-4.png


BIN
game/src/assets/images/plant-tree-tree-5.png


+ 143 - 0
game/src/components/LoginChoice.vue

@@ -0,0 +1,143 @@
+<template>
+  <div class="login-choice">
+    <div class="btn-wrapper">
+      <button @click="emit('login')">
+        <h3>登录</h3>
+        <span>登录后可获得积分,兑换奖品</span>
+      </button>
+      <button @click="emit('signUp')">
+        <h3>注册</h3>
+      </button>
+      <button @click="emit('visitor')">
+        <h3>游客</h3>
+        <span>游客模式下只能体验游戏<br>无法累积积分</span>
+      </button>
+    </div>
+    <button
+      class="close"
+      @click="emit('close')"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, watch, onMounted } from "vue"
+import { useRoute, useRouter } from "vue-router"
+import { useStore } from "vuex"
+
+const route = useRoute()
+const router = useRouter()
+const store = useStore()
+
+const {
+  windowSizeInCssForRef,
+  windowSizeWhenDesignForRef,
+} = useSizeAdapt(390, 752)
+
+const emit = defineEmits(['login', 'signUp', 'visitor', 'close'])
+
+</script>
+
+<style lang="less" scoped>
+.login-choice{
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0,0,0,0.7);
+  backdrop-filter: blur(calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')));
+  >.btn-wrapper{
+    position: absolute;
+    left: 50%;
+    top: calc(152 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    transform: translate(-50%, 0);
+    width: calc(336 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    height: calc(401 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    background: #FFFFFF;
+    border-radius: calc(11 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    display: flex;
+    flex-direction: column;
+    justify-content: space-evenly;
+    align-items: center;
+    padding-top: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    padding-bottom: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    >button{
+      position: relative;
+      width: calc(289 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      height: calc(99 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      >h3{
+        font-size: calc(24 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-weight: bold;
+        color: #C5A16C;
+        line-height: calc(28 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+      >span{
+        font-size: calc(11 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-weight: 400;
+        color: #C5A16C;
+        line-height: calc(13 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+    }
+    >button:nth-of-type(1) {
+      background-image: url(@/assets/images/btn-login-bg-2.png);
+      background-size: cover;
+      background-repeat: no-repeat;
+      background-position: center center;
+      >h3{
+        position: absolute;
+        left: calc(122 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+      >span{
+        position: absolute;
+        left: calc(122 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(57 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+    }
+    >button:nth-of-type(2) {
+      background-image: url(@/assets/images/btn-sign-up-bg-2.png);
+      background-size: cover;
+      background-repeat: no-repeat;
+      background-position: center center;
+      >h3{
+        position: absolute;
+        top: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        left: calc(122 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+    }
+    >button:nth-of-type(3) {
+      background-image: url(@/assets/images/btn-visitor-bg.png);
+      background-size: cover;
+      background-repeat: no-repeat;
+      background-position: center center;
+      >h3{
+        position: absolute;
+        left: calc(122 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+      >span{
+        position: absolute;
+        left: calc(122 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(52 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        width: calc(121 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        text-align: left;
+      }
+    }
+  }
+  >button.close{
+    position: absolute;
+    left: 50%;
+    top: calc(582 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    transform: translate(-50%, 0);
+    width: calc(52 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    height: calc(52 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    background-image: url(@/assets/images/icon-close.png);
+    background-size: cover;
+    background-repeat: no-repeat;
+    background-position: center center;
+  }
+}
+</style>

+ 0 - 6
game/src/router/index.js

@@ -1,6 +1,5 @@
 import { createRouter, createWebHashHistory } from 'vue-router'
 import HomeView from '../views/HomeView.vue'
-import RedirectView from '../views/RedirectView.vue'
 import SignUp from '../views/SignUp.vue'
 import LoginView from '../views/LoginView.vue'
 import FindPassword from '../views/FindPassword.vue'
@@ -20,11 +19,6 @@ const routes = [
     component: HomeView,
   },
   {
-    path: '/redirect-view',
-    name: 'RedirectView',
-    component: RedirectView,
-  },
-  {
     path: '/sign-up',
     name: 'SignUp',
     component: SignUp,

+ 36 - 1
game/src/store/index.js

@@ -17,7 +17,27 @@ export default createStore({
       // updateTime: "2024-01-08 17:04:43"
       // userName: "1020363151@qq.com"
     },
-    avatar: '',
+    // avatar: '',
+    gameToPlayIdx: null,
+    gameRuleList: [
+      // {
+      // createTime: "2024-01-03 09:47:25",
+      // creatorId: null,
+      // creatorName: "",
+      // description: "完成任一环节(浇水,施肥,除虫,修剪)可得分",
+      // id: 3,
+      // name: "乡村林场",
+      // rtf: "<p>123</p><p>321</p>",
+      // score: 101,
+      // second: null,
+      // second: 60,
+      // type: "game",
+      // updateTime: "2024-01-08 19:28:35",
+      // }
+    ],
+    score: null,
+    ifScoreLimitReached: false,
+    scoreLimit: null,
   },
   getters: {
   },
@@ -46,6 +66,21 @@ export default createStore({
     changeBonusPoint(state, delta) {
       state.avatar += delta
     },
+    setGameToPlayIdx(state, index) {
+      state.gameToPlayIdx = index
+    },
+    setGameRuleList(state, value) {
+      state.gameRuleList = value
+    },
+    setScore(state, value) {
+      state.score = value
+    },
+    setIfScoreLimitReached(state, value) {
+      state.ifScoreLimitReached = value
+    },
+    setScoreLimit(state, value) {
+      state.scoreLimit = value
+    }
   },
   actions: {
   },

+ 19 - 3
game/src/views/ExamPaper2.vue

@@ -78,7 +78,7 @@
           alt=""
           draggable="false"
         >
-        <span class="number">{{ bonusPoint }}</span>
+        <span class="number">{{ bonusPointForShow }}</span>
       </div>
       <div class="info-item time-count">
         <img
@@ -106,6 +106,7 @@ import { useRoute, useRouter } from "vue-router"
 import { useStore } from "vuex"
 import dayjs from 'dayjs'
 import { shuffle } from 'lodash'
+import { addScore, getScore } from '@/api.js'
 
 const route = useRoute()
 const router = useRouter()
@@ -125,7 +126,7 @@ function onClickReturnHome() {
 /**
  * 倒计时
  */
-const timeCount = ref(120)
+const timeCount = ref(store.state.gameRuleList[1].second)
 let timeCountIntervalId = null
 timeCountIntervalId = setInterval(() => {
   timeCount.value--
@@ -149,6 +150,13 @@ const timeCountForShow = computed(() => {
 
 // 积分
 const bonusPoint = ref(0)
+const bonusPointForShow = computed(() => {
+  if (!store.state.ifScoreLimitReached) {
+    return bonusPoint.value
+  } else {
+    return `已达本日上限${store.state.scoreLimit}分`
+  }
+})
 // 答对计数
 const correntCount = ref(0)
 
@@ -195,7 +203,7 @@ const isCorrect = computed(() => {
 function onClickOption(idx) {
   this.selectedIdx = idx
   if (this.selectedIdx === questionList.value[currentQuestionIdx.value].rightOptionIdx) {
-    bonusPoint.value += 10
+    bonusPoint.value += store.state.gameRuleList[1].score
     correntCount.value++
   }
 }
@@ -204,6 +212,14 @@ function onClickNext() {
     currentQuestionIdx.value++
     selectedIdx.value = null
   } else {
+    if (store.state.loginStatus && !store.state.ifScoreLimitReached) {
+      addScore(bonusPoint.value).then(() => {
+        getScore().then((res) => {
+          store.commit('setScore', res.total)
+          store.commit('setIfScoreLimitReached', res.hasOver)
+        })
+      })
+    }
     router.replace({
       name: 'ExamPaper3',
       query: {

+ 7 - 1
game/src/views/ExamPaper3.vue

@@ -37,7 +37,7 @@
       >
         重新答题
       </button>
-      <button>
+      <button @click="onClickReturnHome">
         返回首页
       </button>
     </div>
@@ -58,6 +58,12 @@ const {
   windowSizeWhenDesignForRef,
 } = useSizeAdapt(390, 752)
 
+function onClickReturnHome() {
+  router.push({
+    name: 'HomeView',
+  })
+}
+
 </script>
 
 <style lang="less" scoped>

+ 108 - 18
game/src/views/HomeView.vue

@@ -50,8 +50,11 @@
           >{{ store.state.userInfo.userName }}</span>
         </div>
         <div class="point-bonus">
-          <span class="title">当前积分:</span>
-          <span class="value">{{ store.state.userInfo.score }}</span>
+          <span
+            v-show="store.state.score !== null"
+            class="title"
+          >当前积分:</span>
+          <span class="value">{{ store.state.score }}</span>
         </div>
       </div>
       <button
@@ -83,9 +86,7 @@
       <!-- 乡村林场 -->
       <button
         class="game-entry plant-tree-entry"
-        @click="router.push({
-          name: 'PlantTree',
-        })"
+        @click="onClickGameEntry(0)"
       >
         <img
           class=""
@@ -97,9 +98,7 @@
       <!-- 助农课堂 -->
       <button
         class="game-entry exam-paper-entry"
-        @click="router.push({
-          name: 'ExamPaper1',
-        })"
+        @click="onClickGameEntry(1)"
       >
         <img
           class=""
@@ -111,9 +110,7 @@
       <!-- 企业翻翻看 -->
       <button
         class="game-entry pair-up-entry"
-        @click="router.push({
-          name: 'PairUp',
-        })"
+        @click="onClickGameEntry(2)"
       >
         <img
           class=""
@@ -134,12 +131,7 @@
       <!-- 应急救灾 -->
       <button
         class="game-entry disaster-relief-entry"
-        @click="router.push({
-          name: 'GameByUnity',
-          query: {
-            gameName: 'DisasterRelief'
-          },
-        })"
+        @click="onClickGameEntry(4)"
       >
         <img
           class=""
@@ -193,6 +185,16 @@
         >
       </button>
     </div>
+
+    <!-- 让用户选择是否登录、注册 -->
+    <LoginChoice
+      v-show="isShowLoginChoice"
+      class="login-choice"
+      @login="onClickLogin"
+      @signUp="onClickSignUp"
+      @visitor="onLoginChoiceVisitor"
+      @close="onLoginChoiceClose"
+    />
   </div>
 </template>
 
@@ -202,7 +204,8 @@ import { useRoute, useRouter } from "vue-router"
 import { useStore } from "vuex"
 import ClipboardJS from 'clipboard'
 import { showDialog } from 'vant'
-import { logout } from '@/api.js'
+import { logout, getScore } from '@/api.js'
+import LoginChoice from '@/components/LoginChoice.vue'
 
 const route = useRoute()
 const router = useRouter()
@@ -213,6 +216,21 @@ const {
   windowSizeWhenDesignForRef,
 } = useSizeAdapt(390, 752)
 
+const loginStatus = computed(() => {
+  return store.state.loginStatus
+})
+watch(loginStatus, () => {
+  if (loginStatus.value) {
+    getScore().then((res) => {
+      store.commit('setScore', res.total)
+      store.commit('setIfScoreLimitReached', res.hasOver)
+    })
+  }
+}, {
+  immediate: true,
+})
+
+
 function onClickLogin() {
   router.push({
     name: 'LoginView',
@@ -246,6 +264,78 @@ clipboard.on('success', function(e) {
 onUnmounted(() => {
   clipboard.destroy()
 })
+
+const entryFunctionList = [
+  function () {
+    router.push({
+      name: 'PlantTree',
+    })
+  },
+  function () {
+    router.push({
+      name: 'ExamPaper1',
+    })
+  },
+  function () {
+    router.push({
+      name: 'PairUp',
+    })
+  },
+  function () {
+
+  },
+  function () {
+    router.push({
+      name: 'GameByUnity',
+      query: {
+        gameName: 'DisasterRelief'
+      },
+    })
+  },
+  function () {
+
+  },
+  function () {
+
+  },
+]
+const isShowLoginChoice = ref(false)
+
+function onClickGameEntry(idx) {
+  if (store.state.loginStatus) {
+    entryFunctionList[idx]()
+  } else {
+    store.commit('setGameToPlayIdx', idx)
+    isShowLoginChoice.value = true
+  }
+}
+
+function onLoginChoiceVisitor() {
+  const gameIdx = store.state.gameToPlayIdx
+  store.commit('setGameToPlayIdx', null)
+  isShowLoginChoice.value = false
+  entryFunctionList[gameIdx]()
+}
+function onLoginChoiceClose() {
+  store.commit('setGameToPlayIdx', null)
+  isShowLoginChoice.value = false
+}
+
+// 登录、注册完毕后回到首页,可能需要自动进入游戏页
+if (store.state.gameToPlayIdx !== null) {
+  const gameIdx = store.state.gameToPlayIdx
+  store.state.gameToPlayIdx = null
+  entryFunctionList[gameIdx]()
+}
+
+// 如果通过url要求自动进入游戏页
+if (route.query.gameIdx) {
+  const gameIdx = Number(route.query.gameIdx)
+  router.replace({
+    name: route.name
+  })
+  onClickGameEntry(gameIdx)
+}
 </script>
 
 <style lang="less" scoped>

+ 59 - 37
game/src/views/PairUp.vue

@@ -12,6 +12,14 @@
     >
       请翻开相同的企业logo
     </div>
+    <!-- 左上角按钮 -->
+    <div class="btn-group">
+      <button
+        class="return-home"
+        @click="onClickReturnHome"
+      />
+      <button class="game-rule" />
+    </div>
     <!-- 卡牌列表 -->
     <div
       v-show="!isOver"
@@ -49,14 +57,6 @@
         >
       </div>
     </div>
-    <!-- 左上角按钮 -->
-    <div class="btn-group">
-      <button
-        class="return-home"
-        @click="onClickReturnHome"
-      />
-      <button class="game-rule" />
-    </div>
     <!-- 底部信息栏 -->
     <div
       v-show="!isOver"
@@ -69,7 +69,7 @@
           alt=""
           draggable="false"
         >
-        <span class="number">{{ bonusPoint }}</span>
+        <span class="number">{{ bonusPointForShow }}</span>
       </div>
       <div class="info-item time-count">
         <img
@@ -98,6 +98,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'
 
 const route = useRoute()
 const router = useRouter()
@@ -119,7 +120,7 @@ const isOver = ref(false)
 /**
  * 倒计时
  */
-const timeCount = ref(120)
+const timeCount = ref(store.state.gameRuleList[2].second)
 let timeCountIntervalId = null
 timeCountIntervalId = setInterval(() => {
   timeCount.value--
@@ -139,7 +140,13 @@ const timeCountForShow = computed(() => {
  * 本次游戏积分
  */
 const bonusPoint = ref(0)
-
+const bonusPointForShow = computed(() => {
+  if (!store.state.ifScoreLimitReached) {
+    return bonusPoint.value
+  } else {
+    return `已达本日上限${store.state.scoreLimit}分`
+  }
+})
 /**
  * 本次游戏识别企业数
  */
@@ -150,7 +157,8 @@ const recognizedCorpList = ref([])
  */
 function replay() {
   isOver.value = false
-  timeCount.value = 10
+  bonusPoint.value = 0
+  timeCount.value = store.state.gameRuleList[2].second
   timeCountIntervalId = setInterval(() => {
     timeCount.value--
     if (timeCount.value === 0) {
@@ -161,6 +169,19 @@ function replay() {
   recognizedCorpList.value = 0
 }
 
+watch(isOver, (vNew) => {
+  if (vNew) {
+    if (store.state.loginStatus && !store.state.ifScoreLimitReached) {
+      addScore(bonusPoint.value).then(() => {
+        getScore().then((res) => {
+          store.commit('setScore', res.total)
+          store.commit('setIfScoreLimitReached', res.hasOver)
+        })
+      })
+    }
+  }
+})
+
 /**
  * 具体游戏规则
  */
@@ -241,7 +262,6 @@ function onClickCard(card, cardIdx) {
     setTimeout(() => {
       cardList.value[toDeleteValue1].isDone = true
       cardList.value[toDeleteValue2].isDone = true
-      bonusPoint.value += 1
       if (!recognizedCorpList.value.includes(logoIdx)) {
         recognizedCorpList.value.push(logoIdx)
       }
@@ -258,6 +278,7 @@ function onClickCard(card, cardIdx) {
         if (cardList.value.every((item) => {
           return item.isDone
         })) {
+          bonusPoint.value += store.state.gameRuleList[2].score
           setCardList()
         }
       }, 400)
@@ -310,6 +331,31 @@ function onClickCard(card, cardIdx) {
     color: #FFFFFF;
     line-height: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
   }
+  >.btn-group{
+    position: absolute;
+    top: calc(36 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    right: calc(12 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    display: flex;
+    flex-direction: column;
+    gap: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    z-index: 1;
+    >button.return-home{
+      background-image: url(@/assets/images/icon_home.png);
+      background-size: contain;
+      background-repeat: no-repeat;
+      background-position: center center;
+      width: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    }
+    >button.game-rule{
+      background-image: url(@/assets/images/icon_rules.png);
+      background-size: contain;
+      background-repeat: no-repeat;
+      background-position: center center;
+      width: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    }
+  }
   >.card-list{
     position: absolute;
     top: calc(163 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
@@ -372,30 +418,6 @@ function onClickCard(card, cardIdx) {
       transform: scale(0) rotateZ(360deg);
     }
   }
-  >.btn-group{
-    position: absolute;
-    top: calc(36 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-    right: calc(12 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-    display: flex;
-    flex-direction: column;
-    gap: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-    >button.return-home{
-      background-image: url(@/assets/images/icon_home.png);
-      background-size: contain;
-      background-repeat: no-repeat;
-      background-position: center center;
-      width: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-      height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-    }
-    >button.game-rule{
-      background-image: url(@/assets/images/icon_rules.png);
-      background-size: contain;
-      background-repeat: no-repeat;
-      background-position: center center;
-      width: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-      height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-    }
-  }
   >.common-info-group{
     position: absolute;
     left: 50%;

+ 58 - 21
game/src/views/PlantTree.vue

@@ -20,32 +20,52 @@
       mode="out-in"
     >
       <img
-        v-if="currentStepIdx === 0 || currentStepIdx === 1"
+        v-if="currentStepIdx === 0"
         class="tree"
         :style="{
-          width: `calc(108 / ${windowSizeWhenDesignForRef} * ${windowSizeInCssForRef})`,
+          width: `calc(121 / ${windowSizeWhenDesignForRef} * ${windowSizeInCssForRef})`,
         }"
         src="@/assets/images/plant-tree-tree-1.png"
         alt=""
         draggable="false"
       >
       <img
-        v-else-if="currentStepIdx === 2 || currentStepIdx === 3"
+        v-else-if="currentStepIdx === 1"
         class="tree"
         :style="{
-          width: `calc(242 / ${windowSizeWhenDesignForRef} * ${windowSizeInCssForRef})`,
+          width: `calc(108 / ${windowSizeWhenDesignForRef} * ${windowSizeInCssForRef})`,
         }"
         src="@/assets/images/plant-tree-tree-2.png"
         alt=""
         draggable="false"
       >
       <img
+        v-else-if="currentStepIdx === 2"
+        class="tree"
+        :style="{
+          width: `calc(242 / ${windowSizeWhenDesignForRef} * ${windowSizeInCssForRef})`,
+        }"
+        src="@/assets/images/plant-tree-tree-3.png"
+        alt=""
+        draggable="false"
+      >
+      <img
+        v-else-if="currentStepIdx === 3"
+        class="tree"
+        :style="{
+          width: `calc(242 / ${windowSizeWhenDesignForRef} * ${windowSizeInCssForRef})`,
+        }"
+        src="@/assets/images/plant-tree-tree-4.png"
+        alt=""
+        draggable="false"
+      >
+      <img
         v-else-if="currentStepIdx === 4"
         class="tree"
         :style="{
           width: `calc(380 / ${windowSizeWhenDesignForRef} * ${windowSizeInCssForRef})`,
         }"
-        :src="require(`@/assets/images/plant-tree-tree-3.png`)"
+        :src="require(`@/assets/images/plant-tree-tree-5.png`)"
         alt=""
         draggable="false"
       >
@@ -90,6 +110,7 @@
     <button
       v-show="isOver"
       class="game-over-confirm"
+      @click="onClickReturnHome"
     >
       返回首页
     </button>
@@ -105,7 +126,7 @@
           alt=""
           draggable="false"
         >
-        <span class="number">{{ bonusPoint }}</span>
+        <span class="number">{{ bonusPointForShow }}</span>
       </div>
     </div>
   </div>
@@ -119,6 +140,7 @@ import { useStore } from "vuex"
 import dayjs from 'dayjs'
 import { showDialog } from 'vant'
 import { shuffle } from 'lodash'
+import { addScore, getScore } from '@/api.js'
 
 const route = useRoute()
 const router = useRouter()
@@ -139,6 +161,13 @@ function onClickReturnHome() {
  * 游戏规则
  */
 const bonusPoint = ref(0)
+const bonusPointForShow = computed(() => {
+  if (!store.state.ifScoreLimitReached) {
+    return bonusPoint.value
+  } else {
+    return `已达本日上限${store.state.scoreLimit}分`
+  }
+})
 const toolList = ref([
   {
     toolIdx: 0,
@@ -192,30 +221,38 @@ const stepList = [
 ]
 const currentStepIdx = ref(0)
 const lastPlayTimeStr = localStorage.getItem('plant-tree-last-time')
-// if (process.env.VUE_APP_CLI_MODE !== 'dev') {
-if (lastPlayTimeStr) {
-  const lastPlayTime = new Date(Number(lastPlayTimeStr))
-  const lastPlayYear = lastPlayTime.getFullYear()
-  const lastPlayMonth = lastPlayTime.getMonth()
-  const lastPlayDay = lastPlayTime.getDay()
+if (process.env.VUE_APP_CLI_MODE !== 'dev') {
+  if (lastPlayTimeStr) {
+    const lastPlayTime = new Date(Number(lastPlayTimeStr))
+    const lastPlayYear = lastPlayTime.getFullYear()
+    const lastPlayMonth = lastPlayTime.getMonth()
+    const lastPlayDay = lastPlayTime.getDay()
 
-  const currentTime = new Date()
-  const currentYear = currentTime.getFullYear()
-  const currentMonth = currentTime.getMonth()
-  const currentDay = currentTime.getDay()
+    const currentTime = new Date()
+    const currentYear = currentTime.getFullYear()
+    const currentMonth = currentTime.getMonth()
+    const currentDay = currentTime.getDay()
 
-  if (lastPlayYear === currentYear && lastPlayMonth === currentMonth && lastPlayDay === currentDay) {
-    currentStepIdx.value = stepList.length - 1
-    bonusPoint.value = 40
+    if (lastPlayYear === currentYear && lastPlayMonth === currentMonth && lastPlayDay === currentDay) {
+      currentStepIdx.value = stepList.length - 1
+      bonusPoint.value = 4 * store.state.gameRuleList[0].score
+    }
   }
 }
-// }
 const isOver = computed(() => {
   return currentStepIdx.value === stepList.length - 1
 })
 watch(isOver, (vNew) => {
   if (vNew) {
     localStorage.setItem('plant-tree-last-time', (new Date()).getTime())
+    if (store.state.loginStatus && !store.state.ifScoreLimitReached) {
+      addScore(bonusPoint.value).then(() => {
+        getScore().then((res) => {
+          store.commit('setScore', res.total)
+          store.commit('setIfScoreLimitReached', res.hasOver)
+        })
+      })
+    }
   }
 })
 function onClickTool(toolIdx) {
@@ -227,7 +264,7 @@ function onClickTool(toolIdx) {
   } else {
     if (currentStepIdx.value < stepList.length - 1) {
       currentStepIdx.value++
-      bonusPoint.value += 10
+      bonusPoint.value += store.state.gameRuleList[0].score
     }
   }
 }

+ 0 - 75
game/src/views/RedirectView.vue

@@ -1,75 +0,0 @@
-<template>
-  <div class="redirect-view" />
-</template>
-
-<script setup>
-import { ref, computed, watch, onMounted } from "vue"
-import { useRoute, useRouter } from "vue-router"
-import { useStore } from "vuex"
-
-const route = useRoute()
-const router = useRouter()
-const store = useStore()
-
-console.log('sdfdsdf', route.query)
-switch (route.query.gameIdx) {
-case '0':
-  router.replace({
-    name: 'PlantTree',
-  })
-  break
-case '1':
-  router.replace({
-    name: 'ExamPaper1',
-  })
-  break
-case '2':
-  router.replace({
-    name: 'PairUp',
-  })
-  break
-case '3':
-  router.replace({
-    name: 'GameByUnity',
-    query: {
-      gameName: '',
-    }
-  })
-  break
-case '4':
-  router.replace({
-    name: 'GameByUnity',
-    query: {
-      gameName: 'DisasterRelief',
-    }
-  })
-  break
-case '5':
-  router.replace({
-    name: 'GameByUnity',
-    query: {
-      gameName: '',
-    }
-  })
-  break
-case '6':
-  router.replace({
-    name: 'GameByUnity',
-    query: {
-      gameName: '',
-    }
-  })
-  break
-default:
-  break
-}
-
-
-
-</script>
-
-<style lang="less" scoped>
-.redirect-view{
-
-}
-</style>