Bladeren bron

商城 兑换表单 UI

任一存 1 jaar geleden
bovenliggende
commit
57e0455b6d
4 gewijzigde bestanden met toevoegingen van 376 en 3 verwijderingen
  1. 0 2
      README.md
  2. 1 1
      src/components/FeedBack.vue
  3. 372 0
      src/components/PrizeRedeem.vue
  4. 3 0
      src/views/ShopView.vue

+ 0 - 2
README.md

@@ -7,8 +7,6 @@
 appId: wx0bc995dace29b2ba
 
 ## 待办
-遗存链接
-
 登录功能
 
 商城

+ 1 - 1
src/components/FeedBack.vue

@@ -276,7 +276,7 @@ function onSubmit() {
           background-repeat: no-repeat;
           background-position: center center;
           &[disabled]{
-            opacity: 0.7;
+            background-image: url(@/assets/images/button-cancel-bg.png);
             cursor: not-allowed;
           }
         }

+ 372 - 0
src/components/PrizeRedeem.vue

@@ -0,0 +1,372 @@
+<template>
+  <div class="prize-redeem">
+    <BtnClose
+      @click="emit('close')"
+    />
+    <div class="paper-wrap">
+      <article class="paper">
+        <h1>奖品兑换</h1>
+        <h2>Award Redemption</h2>
+
+        <div class="row">
+          <div class="key">
+            您的称呼
+          </div>
+          <input
+            v-model="name"
+            aotufocus
+            type="text"
+            placeholder="请输入内容,20字以内"
+            maxlength="20"
+          >
+        </div>
+        <div class="row">
+          <div class="key">
+            联系方式
+          </div>
+          <input
+            v-model="contact"
+            type="text"
+            placeholder="请输入内容,20字以内"
+            maxlength="20"
+          >
+        </div>
+        <div class="row">
+          <div class="key key-feedback">
+            地址及留言
+          </div>
+          <textarea
+            v-model="feedback"
+            placeholder="请输入省市区街道,50字以内"
+            maxlength="50"
+          />
+        </div>
+
+        <div class="splitter" />
+
+        <div class="row-score-current">
+          <div class="key-score">
+            您的积分
+          </div>
+          <div class="value">
+            {{ current }}
+          </div>
+        </div>
+        <div class="row-score-consume">
+          <div class="key-score">
+            消费
+          </div>
+          <div class="value">
+            -{{ consume }}
+          </div>
+        </div>
+        <div class="row-score-remain">
+          <div class="key-score">
+            剩余
+          </div>
+          <div
+            class="value"
+            :class="{
+              minus: remain < 0
+            }"
+          >
+            {{ remain }}
+          </div>
+        </div>
+
+        <div class="btn-group">
+          <button
+            class="cancel"
+            @click="emit('close')"
+          >
+            取消
+          </button>
+          <button
+            class="confirm"
+            :disabled="!canSubmit"
+            @click="onSubmit"
+          >
+            提交
+          </button>
+        </div>
+      </article>
+      <div class="deco" />
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, watch, onMounted, nextTick, inject } from "vue"
+import { useRoute, useRouter } from "vue-router"
+import { useStore } from "vuex"
+import BtnClose from "./BtnClose.vue"
+
+const route = useRoute()
+const router = useRouter()
+const store = useStore()
+
+const $env = inject('$env')
+
+const emit = defineEmits(['close'])
+
+const isShowVerifiCode = ref(true)
+const onClickVerifiCode = utils.throttle(() => {
+  isShowVerifiCode.value = false
+  nextTick(() => {
+    isShowVerifiCode.value = true
+  })
+}, 333)
+
+const name = ref('')
+const contact = ref('')
+const feedback = ref('')
+
+const current = ref(424)
+const consume = ref(200)
+const remain = computed(() => {
+  return current.value - consume.value
+})
+
+const canSubmit = computed(() => {
+  return name.value && contact.value && feedback.value && (remain.value >= 0)
+})
+
+function onSubmit() {
+  emit('close')
+}
+</script>
+
+<style lang="less" scoped>
+.prize-redeem{
+  position: fixed;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0,0,0,0.6);
+  backdrop-filter: blur(10px);
+  z-index: 10;
+  overflow: auto;
+  >div.paper-wrap{
+    position: absolute;
+    left: 50%;
+    top: 60px;
+    transform: translate(-50%, 0);
+    width: 925px;
+    height: 810px;
+    z-index: 0;
+    >article.paper{
+      position: absolute;
+      left: 0;
+      top: 0;
+      width: 100%;
+      height: 100%;
+      background: linear-gradient( 180deg, rgba(200,200,200, 1) 0%, rgba(100,100,100, 1) 100%);
+      z-index: 1;
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      padding-top: 73px;
+      padding-bottom: 64px;
+      >h1{
+        position: absolute;
+        top: -37px;
+        left: 36px;
+        font-family: Source Han Serif CN, Source Han Serif CN;
+        font-weight: bold;
+        font-size: 32px;
+        color: #FFFFFF;
+        line-height: 38px;
+      }
+      >h2{
+        position: absolute;
+        top: 6px;
+        left: 68px;
+        font-family: Source Han Sans CN, Source Han Sans CN;
+        font-weight: 400;
+        font-size: 14px;
+        color: #b0b0b0;
+        line-height: 16px;
+      }
+      >.row{
+        display: flex;
+        align-items: center;
+        margin-bottom: 37px;
+        >.key{
+          font-family: Source Han Serif CN, Source Han Serif CN;
+          font-weight: bold;
+          font-size: 24px;
+          color: #424A4A;
+          line-height: 28px;
+          letter-spacing: 7px;
+          margin-right: 34px;
+        }
+        >.key.key-feedback{
+          letter-spacing: initial;
+        }
+        >input, >textarea{
+          width: 506px;
+          background: rgba(213,221,215,0.5);
+          box-shadow: 0px 1px 3px 0px rgba(255,255,255,0.25);
+          border-radius: 3px 3px 3px 3px;
+          border: 1px solid;
+          border-image: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0.15)) 1 1;
+          font-family: Source Han Sans CN, Source Han Sans CN;
+          font-weight: 400;
+          font-size: 16px;
+          color: #000000;
+          line-height: 19px;
+          padding-left: 20px;
+          padding-right: 2px;
+          &::placeholder{
+            opacity: 0.3;
+          }
+        }
+        >input {
+          height: 51px;
+        }
+        >textarea{
+          width: 506px;
+          height: 238px;
+          resize: none;
+          padding-top: 13px;
+          padding-bottom: 13px;
+        }
+        >input.veri-code-input{
+          width: 338px;
+          margin-right: 15px;
+        }
+        >button.get-veri-code{
+          width: 155px;
+          height: 51px;
+          border-radius: 3px;
+          background-color: #fff;
+          >img{
+            height: 100%;
+            width: 100%;
+            object-fit: contain;
+          }
+        }
+      }
+
+      >.splitter{
+        width: 830px;
+        border: 1px solid #B5C2B9;
+        opacity: 0.6;
+        margin-bottom: 40px;
+      }
+
+      >.row-score-current{
+        width: 660px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 10px;
+        >.key-score{
+          font-family: Source Han Serif CN, Source Han Serif CN;
+          font-weight: bold;
+          font-size: 24px;
+          color: #FFFFFF;
+          line-height: 28px;
+          letter-spacing: 8px;
+        }
+        >.value{
+          font-family: Source Han Sans CN, Source Han Sans CN;
+          font-weight: bold;
+          font-size: 24px;
+          color: #FFFFFF;
+          line-height: 28px;
+        }
+      }
+      >.row-score-consume{
+        width: 660px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 10px;
+        >.key-score{
+          font-family: Source Han Sans CN, Source Han Sans CN;
+          font-weight: 400;
+          font-size: 20px;
+          color: #FFFFFF;
+          line-height: 23px;
+        }
+        >.value{
+          font-family: Source Han Sans CN, Source Han Sans CN;
+          font-weight: bold;
+          font-size: 20px;
+          color: #FF6C63;
+          line-height: 23px;
+        }
+      }
+      >.row-score-remain{
+        width: 660px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        >.key-score{
+          font-family: Source Han Sans CN, Source Han Sans CN;
+          font-weight: bold;
+          font-size: 20px;
+          color: #FFFFFF;
+          line-height: 23px;
+        }
+        >.value{
+          font-family: Source Han Sans CN, Source Han Sans CN;
+          font-weight: bold;
+          font-size: 20px;
+          color: #FFE794;
+          line-height: 23px;
+          &.minus{
+            color: #FF6C63;
+          }
+        }
+      }
+
+      >.btn-group{
+        >button.cancel{
+          width: 194px;
+          height: 94px;
+          padding-bottom: 9px;
+          font-family: Source Han Sans CN, Source Han Sans CN;
+          font-weight: 400;
+          font-size: 20px;
+          color: #FFFFFF;
+          line-height: 23px;
+          background-image: url(@/assets/images/button-cancel-bg.png);
+          background-size: cover;
+          background-repeat: no-repeat;
+          background-position: center center;
+        }
+        >button.confirm{
+          width: 194px;
+          height: 94px;
+          padding-bottom: 9px;
+          font-family: Source Han Sans CN, Source Han Sans CN;
+          font-weight: 400;
+          font-size: 20px;
+          color: #9C6D42;
+          line-height: 23px;
+          background-image: url(@/assets/images/button-confirm-bg.png);
+          background-size: cover;
+          background-repeat: no-repeat;
+          background-position: center center;
+          &[disabled]{
+            background-image: url(@/assets/images/button-cancel-bg.png);
+            cursor: not-allowed;
+          }
+        }
+      }
+    }
+    >.deco{
+      position: absolute;
+      z-index: 0;
+      width: 100%;
+      height: 100%;
+      left: -14px;
+      top: 14px;
+      border: 1px solid rgba(255, 255, 255, 0.5);
+    }
+  }
+}
+</style>

+ 3 - 0
src/views/ShopView.vue

@@ -72,6 +72,8 @@
       >
       <span class="value">4000</span>
     </div>
+
+    <PrizeRedeem />
   </div>
 </template>
 
@@ -79,6 +81,7 @@
 import { ref, computed, watch, onMounted } from "vue"
 import { useRoute, useRouter } from "vue-router"
 import { useStore } from "vuex"
+import PrizeRedeem from '@/components/PrizeRedeem.vue'
 
 const route = useRoute()
 const router = useRouter()