Просмотр исходного кода

搞搞搞 积分逻辑对接接口

任一存 1 год назад
Родитель
Сommit
b99236a959

+ 27 - 0
game/README.md

@@ -11,7 +11,34 @@ 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
+  }
+}

+ 31 - 0
game/src/store/index.js

@@ -19,6 +19,25 @@ export default createStore({
     },
     // 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: {
   },
@@ -49,6 +68,18 @@ export default createStore({
     },
     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>

+ 21 - 3
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
@@ -201,7 +204,7 @@ 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()
@@ -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',

+ 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%;

+ 33 - 16
game/src/views/PlantTree.vue

@@ -90,6 +90,7 @@
     <button
       v-show="isOver"
       class="game-over-confirm"
+      @click="onClickReturnHome"
     >
       返回首页
     </button>
@@ -105,7 +106,7 @@
           alt=""
           draggable="false"
         >
-        <span class="number">{{ bonusPoint }}</span>
+        <span class="number">{{ bonusPointForShow }}</span>
       </div>
     </div>
   </div>
@@ -119,6 +120,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 +141,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 +201,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 +244,7 @@ function onClickTool(toolIdx) {
   } else {
     if (currentStepIdx.value < stepList.length - 1) {
       currentStepIdx.value++
-      bonusPoint.value += 10
+      bonusPoint.value += store.state.gameRuleList[0].score
     }
   }
 }