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

更新小游戏;兑奖——证书功能初步

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

BIN
game/public/unity/antibody-battle/Build/Build.data.unityweb


BIN
game/public/unity/antibody-battle/Build/Build.framework.js.unityweb


BIN
game/public/unity/antibody-battle/Build/Build.wasm.unityweb


+ 1 - 1
game/public/unity/antibody-battle/index.html

@@ -75,7 +75,7 @@
         streamingAssetsUrl: "StreamingAssets",
         companyName: "4dage",
         productName: "抗体大作战",
-        productVersion: "0.1.2",
+        productVersion: "0.1.4",
         showBanner: unityShowBanner,
       };
 

BIN
game/public/unity/enviroment-protection/Build/Build.data.unityweb


BIN
game/public/unity/enviroment-protection/Build/Build.framework.js.unityweb


BIN
game/public/unity/enviroment-protection/Build/Build.wasm.unityweb


+ 1 - 1
game/public/unity/enviroment-protection/index.html

@@ -75,7 +75,7 @@
         streamingAssetsUrl: "StreamingAssets",
         companyName: "4dage",
         productName: "生态保护",
-        productVersion: "0.1.2",
+        productVersion: "0.1.3",
         showBanner: unityShowBanner,
       };
 

+ 14 - 0
game/src/api.js

@@ -291,6 +291,20 @@ export async function redeem(description, name, phone, prizeId, score, prizeName
     return res.data.data
   }
 }
+export async function checkCertificationStatus() {
+  const res = await axios({
+    method: 'get',
+    url: `${process.env.VUE_APP_DEPLOY_ORIGIN}/api/cms/game/redeem/check`,
+    headers: {
+      token: store.state.token,
+    },
+  })
+  if (res.data.code !== 0) {
+    throw (`检查证书状态失败:${res.data.msg}`)
+  } else {
+    return res.data.data
+  }
+}
 
 export function notifyQuit() {
   console.log('小游戏:调用父窗口的goBackSceneFu方法……')

BIN
game/src/assets/images/already-redeem.png


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

@@ -13,6 +13,8 @@ import GameByUnity from '../views/GameByUnity.vue'
 import ShopView from '../views/ShopView.vue'
 import ShopForVisitor from '../views/ShopForVisitor.vue'
 import RedeemForm from '../views/RedeemForm.vue'
+import RedeemFormForCertification from '../views/RedeemFormForCertification.vue'
+import CertificationView from '../views/CertificationView.vue'
 // import store from '@/store/index.js'
 
 const routes = [
@@ -86,6 +88,16 @@ const routes = [
     name: 'RedeemForm',
     component: RedeemForm,
   },
+  {
+    path: '/redeem-form-for-certification',
+    name: 'RedeemFormForCertification',
+    component: RedeemFormForCertification,
+  },
+  {
+    path: '/certification-view',
+    name: 'CertificationView',
+    component: CertificationView,
+  },
 ]
 
 const router = createRouter({

+ 54 - 0
game/src/views/CertificationView.vue

@@ -0,0 +1,54 @@
+<template>
+  <div class="certification-view">
+    sfdjslfdjk
+    <button
+      class="return"
+      @click="router.go(-1)"
+    >
+      返回
+    </button>
+  </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)
+
+
+</script>
+
+<style lang="less" scoped>
+.certification-view{
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(207, 187, 156, 1);
+  >button.return{
+    position: absolute;
+    width: calc(348 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    height: calc(60 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    top: calc(630 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    left: 50%;
+    transform: translate(-50%, 0);
+    background-color: #FFE6A5;
+    border-radius: calc(3 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    font-family: Source Han Sans SC, Source Han Sans SC;
+    font-weight: bold;
+    color: #A97C46;
+    line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+  }
+}
+</style>

+ 233 - 0
game/src/views/RedeemFormForCertification.vue

@@ -0,0 +1,233 @@
+<template>
+  <div class="redeem-form">
+    <div class="paper">
+      <div class="form-item">
+        <h3>您的称呼</h3>
+        <input
+          v-model="name"
+          type="text"
+          autofocus
+          placeholder="请输入内容,5字以内"
+        >
+      </div>
+
+      <hr>
+
+      <div class="number-info-item">
+        <div class="key">
+          您的积分
+        </div>
+        <div class="value">
+          {{ store.state.score }}
+        </div>
+      </div>
+      <div class="number-info-item">
+        <div class="key">
+          礼品消费
+        </div>
+        <div class="value red">
+          -{{ prizeInfo.score }}
+        </div>
+      </div>
+      <div class="number-info-item">
+        <div class="key bold">
+          剩余
+        </div>
+        <div class="value">
+          {{ result }}
+        </div>
+      </div>
+    </div>
+
+    <button
+      class="submit"
+      :class="{
+        needInfo: !name,
+        notEnough: result < 0,
+        over: haveSubmitted,
+      }"
+      @click="submit"
+    >
+      发起兑换
+    </button>
+
+    <transition name="fade-in-out">
+      <NotifyComp
+        v-show="ifShowNotify"
+        text="提交成功,工作人员会与您及时联系"
+      />
+    </transition>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, watch, onMounted } from "vue"
+import { useRoute, useRouter } from "vue-router"
+import { useStore } from "vuex"
+import { redeem, getScore } from '@/api.js'
+import NotifyComp from '@/components/NotifyComp.vue'
+
+const route = useRoute()
+const router = useRouter()
+const store = useStore()
+
+const {
+  windowSizeInCssForRef,
+  windowSizeWhenDesignForRef,
+} = useSizeAdapt(390, 752)
+
+const prizeInfo = JSON.parse(route.query.prizeInfo)
+
+const result = ref(store.state.score - prizeInfo.score)
+
+const name = ref('')
+watch(name, (vNew) => {
+  if (vNew.length > 5) {
+    vNew = vNew.slice(0, 5)
+    name.value = vNew
+  }
+})
+const ifShowNotify = ref(false)
+const haveSubmitted = ref(false)
+
+function submit() {
+  redeem('', name.value, '', prizeInfo.id, prizeInfo.score, prizeInfo.name).then((res) => {
+    haveSubmitted.value = true
+    getScore().then((res) => {
+      store.commit('setScore', res.total)
+      store.commit('setIfScoreLimitReached', res.hasOver)
+    })
+    router.replace({
+      name: 'CertificationView'
+    })
+  })
+}
+</script>
+
+<style lang="less" scoped>
+.redeem-form{
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(207, 187, 156, 1);
+  >.paper{
+    position: absolute;
+    width: calc(348 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    height: calc(582 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    top: calc(24 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    left: 50%;
+    transform: translate(-50%, 0);
+    background-image: url(@/assets/images/redeem-paper.png);
+    background-size: contain;
+    background-repeat: no-repeat;
+    background-position: center center;
+    padding-top: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    padding-left: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    padding-right: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    >.form-item{
+      margin-bottom: calc(410 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      >h3{
+        font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-weight: bold;
+        color: #A97C46;
+        line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        margin-bottom: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+      >input{
+        font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-weight: 400;
+        color: rgba(169, 124, 70, 1);
+        line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        width: 100%;
+        border-bottom: 1px dashed #CFBB9C;
+        padding-bottom: calc(9 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        &::placeholder {
+          font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+          font-family: Source Han Sans SC, Source Han Sans SC;
+          font-weight: 400;
+          color: #B8B8B8;
+          line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        }
+      }
+    }
+    >.form-item.last{
+      margin-bottom: calc(60 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    }
+    >hr{
+      position: absolute;
+      top: calc(468 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      left: 50%;
+      transform: translate(-50%, 0);
+      width: calc(306 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      height: 0;
+      border-top: 1px dashed #CFBB9C;
+    }
+    >.number-info-item{
+      margin-bottom: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      >.key{
+        font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-weight: 400;
+        color: #A97C46;
+        line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+      >.key.bold{
+        font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-weight: bold;
+        color: #A97C46;
+        line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+      >.value{
+        font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-weight: bold;
+        color: #A97C46;
+        line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+      >.value.red{
+        font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        font-family: Source Han Sans SC, Source Han Sans SC;
+        font-weight: bold;
+        color: #FF4040;
+        line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+    }
+  }
+  >button.submit{
+    position: absolute;
+    width: calc(348 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    height: calc(60 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    top: calc(630 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    left: 50%;
+    transform: translate(-50%, 0);
+    background-color: #FFE6A5;
+    border-radius: calc(3 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    font-family: Source Han Sans SC, Source Han Sans SC;
+    font-weight: bold;
+    color: #A97C46;
+    line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+  }
+  >button.submit.needInfo{
+    opacity: 0.5;
+    pointer-events: none;
+  }
+  >button.submit.notEnough{
+    opacity: 1;
+    color: #7B7B7B;
+    background: #CECECE;
+    pointer-events: none;
+  }
+  >button.over{
+    pointer-events: none;
+  }
+}
+</style>

+ 6 - 1
game/src/views/ShopForVisitor.vue

@@ -35,7 +35,12 @@
           <div class="title">
             {{ prizeItem.name }}
           </div>
-          <div class="remaining">
+          <div
+            class="remaining"
+            :style="{
+              color: prizeItem.name === '公益合伙人证书' ? 'transparent' : '',
+            }"
+          >
             剩余:{{ prizeItem.stock }}
           </div>
           <div class="price">

+ 67 - 24
game/src/views/ShopView.vue

@@ -60,7 +60,7 @@
           :key="prizeItem.id"
           class="prize-item"
           :class="{
-            disabled: prizeItem.stock === 0
+            disabled: prizeItem.stock === 0,
           }"
           @click="onClickPrizeItem(prizeItem)"
         >
@@ -73,27 +73,50 @@
           <div class="title">
             {{ prizeItem.name }}
           </div>
-          <div class="remaining">
+          <div
+            class="remaining"
+            :style="{
+              color: prizeItem.name === '公益合伙人证书' ? 'transparent' : '',
+            }"
+          >
             剩余:{{ prizeItem.stock }}
           </div>
           <div class="price">
             <span class="number">{{ prizeItem.score }}</span>
             <span class="not-number">积分</span>
           </div>
-          <img
-            v-show="prizeItem.isEnabled && prizeItem.stock > 0"
-            class="icon-enabled"
-            src="@/assets/images/icon-gift.png"
-            alt=""
-            draggable="false"
-          >
-          <img
-            v-show="prizeItem.isEnabled && prizeItem.stock === 0"
-            class="icon-no-stock"
-            src="@/assets/images/no-stock.png"
-            alt=""
-            draggable="false"
-          >
+          <template v-if="prizeItem.name !== '公益合伙人证书'">
+            <img
+              v-show="prizeItem.isEnabled && prizeItem.stock > 0"
+              class="icon-enabled"
+              src="@/assets/images/icon-gift.png"
+              alt=""
+              draggable="false"
+            >
+            <img
+              v-show="prizeItem.isEnabled && prizeItem.stock === 0"
+              class="icon-no-stock"
+              src="@/assets/images/no-stock.png"
+              alt=""
+              draggable="false"
+            >
+          </template>
+          <template v-else>
+            <img
+              v-show="prizeItem.isEnabled && haveGotCertification === false"
+              class="icon-enabled"
+              src="@/assets/images/icon-gift.png"
+              alt=""
+              draggable="false"
+            >
+            <img
+              v-show="prizeItem.isEnabled && haveGotCertification"
+              class="icon-no-stock"
+              src="@/assets/images/already-redeem.png"
+              alt=""
+              draggable="false"
+            >
+          </template>
         </article>
       </div>
       <div
@@ -135,7 +158,7 @@
               negative: recordItem.type === '奖品兑换',
             }"
           >
-            {{ recordItem.type === '奖品兑换' ? '' : '+' }}{{ recordItem.score }}
+            {{ recordItem.score > 0 ? '+' : '' }}{{ recordItem.score }}
           </div>
         </div>
       </div>
@@ -161,7 +184,7 @@
 import { ref, computed, watch, onMounted } from "vue"
 import { useRoute, useRouter } from "vue-router"
 import { useStore } from "vuex"
-import { getScore, getPrizeList, getBonusPointRecord } from '@/api.js'
+import { getScore, getPrizeList, getBonusPointRecord, checkCertificationStatus } from '@/api.js'
 
 const route = useRoute()
 const router = useRouter()
@@ -220,13 +243,33 @@ function onPrizeListScroll(e) {
   }
 }
 
+const haveGotCertification = ref(undefined)
+checkCertificationStatus().then((res) => {
+  haveGotCertification.value = res
+})
+
 function onClickPrizeItem(prizeItem) {
-  router.push({
-    name: 'RedeemForm',
-    query: {
-      prizeInfo: JSON.stringify(prizeItem),
-    }
-  })
+  if (prizeItem.name !== '公益合伙人证书') {
+    router.push({
+      name: 'RedeemForm',
+      query: {
+        prizeInfo: JSON.stringify(prizeItem),
+      }
+    })
+  } else if (prizeItem.name === '公益合伙人证书' && haveGotCertification.value === undefined) {
+    return
+  } else if (prizeItem.name === '公益合伙人证书' && haveGotCertification.value === false) {
+    router.push({
+      name: 'RedeemFormForCertification',
+      query: {
+        prizeInfo: JSON.stringify(prizeItem),
+      }
+    })
+  } else if (prizeItem.name === '公益合伙人证书' && haveGotCertification.value === true) {
+    router.push({
+      name: 'CertificationView',
+    })
+  }
 }
 
 const recordList = ref(null)