Przeglądaj źródła

新增领取礼包和验证码登录前端界面

pujiaming 2 lat temu
rodzic
commit
2a79db0a90

+ 5 - 0
components.d.ts

@@ -19,6 +19,9 @@ declare module '@vue/runtime-core' {
     VanBackTop: typeof import('vant/es')['BackTop']
     VanButton: typeof import('vant/es')['Button']
     VanCell: typeof import('vant/es')['Cell']
+    VanCollapse: typeof import('vant/es')['Collapse']
+    VanCollapseItem: typeof import('vant/es')['CollapseItem']
+    VanDialog: typeof import('vant/es')['Dialog']
     VanDropdownItem: typeof import('vant/es')['DropdownItem']
     VanDropdownMenu: typeof import('vant/es')['DropdownMenu']
     VanEmpty: typeof import('vant/es')['Empty']
@@ -28,5 +31,7 @@ declare module '@vue/runtime-core' {
     VanSearch: typeof import('vant/es')['Search']
     VanSwipe: typeof import('vant/es')['Swipe']
     VanSwipeItem: typeof import('vant/es')['SwipeItem']
+    VanTab: typeof import('vant/es')['Tab']
+    VanTabs: typeof import('vant/es')['Tabs']
   }
 }

+ 7 - 0
src/App.vue

@@ -49,4 +49,11 @@ onUnmounted(() => {
 
 <style scoped lang="scss">
 
+</style>
+<style lang="scss">
+.van-button.van-button--normal {
+  padding: 5px 15px;
+  width: auto;
+  height: auto;
+}
 </style>

+ 6 - 3
src/components/IndexList.vue

@@ -13,10 +13,13 @@
                         }}</span>
                     </h3>
                     <p class="elli">{{ item.sketch || '暂无简介' }}</p>
-                    <el-button :disabled="item.download_url === '' ? true : false" @click="downGame(item.download_url)"
-                        color="#ed8c0f" class="downMB" :icon="Download">
+                    
+                    <div>
+                        <el-button :disabled="item.download_url === '' ? true : false" @click="downGame(item.download_url)" color="#ed8c0f" class="downMB" :icon="Download">
                         {{ bytesChange(item.size) }}
-                    </el-button>
+                        </el-button>
+                        <slot name="custom-button" :row="item"></slot>
+                    </div>
                 </div>
             </div>
             <img class="right_img" :src="props.prefix + item.screenshot" />

+ 8 - 5
src/components/MobList.vue

@@ -8,7 +8,10 @@
                 <p class="down_msg">下载 | <span style="color: #ed8c0f;">{{ bytesChange(item.size) }}</span></p>
             </div>
         </div>
-        <van-button :disabled="item.download_url === '' ? true : false"  round color="#ed8c0f" @click="downGame(item.download_url)">下载</van-button>
+        <div>
+            <van-button :disabled="item.download_url === '' ? true : false"  round color="#ed8c0f" @click="downGame(item.download_url)">下载</van-button>
+            <slot name="custom-button" :row="item"></slot>
+        </div>
     </div>
 </template>
 
@@ -59,8 +62,8 @@ const downGame = (url: string) => {
     }
 }
 
-.van-button {
-    width: 60px;
-    height: 30px;
-}
+// .van-button {
+//     width: 60px;
+//     height: 30px;
+// }
 </style>

+ 1 - 1
src/main.ts

@@ -10,7 +10,7 @@ import 'element-plus/dist/index.css'
 import './assets/css/normalize.css'
 import './assets/css/property.css'
 import './assets/css/reset.css'
-
+import 'vant/es/toast/style';
 // 引入pinia状态管理工具
 import { store } from './store'
 

+ 21 - 0
src/utils/captcha.ts

@@ -0,0 +1,21 @@
+const checkRestTime = (sessionItem:string, validTime:number = 60) => {
+    let LASTTIME:number, restTime:number
+
+    let hasRecord = sessionStorage.getItem(sessionItem)
+    const nowTime = Math.round(new Date().getTime() / 1000)
+    if(hasRecord){
+        LASTTIME = Math.round(Number(hasRecord))
+    }else{
+        return null
+    }
+    
+    if(LASTTIME && nowTime - LASTTIME < validTime){
+        restTime = validTime - (nowTime - LASTTIME)
+        return restTime
+    }else if (LASTTIME && nowTime - LASTTIME >= 60) {
+        sessionStorage.removeItem(sessionItem)
+        return null
+    }
+
+}
+export default checkRestTime

+ 54 - 7
src/view/m_views/login/index.vue

@@ -4,11 +4,21 @@
             <img src="@/assets/img/logo.png" class="img">
         </div>
         <div class="input">
-            <van-form @submit="submitForm">
+            <van-form @submit.prevent="submitForm" >
+                <van-tabs v-model:active="login_typ" @change="resetForm">
+                    <van-tab title="密码登录" name="pwd"></van-tab>
+                    <van-tab title="验证码登录" name="sms"></van-tab>
+                </van-tabs>
                 <van-field style="font-size: 16px;" v-model="loginForm.account" name="用户名" label="用户名"
                     placeholder="请输入用户名" :rules="[{ required: true, message: '请填写用户名' }]" />
-                <van-field style="font-size: 16px;" v-model="loginForm.password" type="password" name="密码"
+                <van-field v-if="login_typ === 'pwd'" style="font-size: 16px;" v-model="loginForm.password" type="password" name="密码"
                     label="密&emsp;码" placeholder="请输入密码" :rules="[{ required: true, message: '请填写密码' }]" />
+                <van-field v-else-if="login_typ === 'sms'" style="font-size: 16px;" v-model="loginForm.smsCaptcha" type="number" name="密码"
+                    label="验证码" placeholder="请输入验证码" :rules="[{ required: true, message: '请填写验证码' }]">
+                    <template #button>
+                        <van-button size="small" type="primary" style="width: 20vw;" :disabled="!can_send" @click="getCaptcha">{{ smsMessage }}</van-button>
+                    </template>
+                </van-field>
                 <van-field style="font-size: 16px;" v-model="loginForm.password" type="hidden" id="md5_password" />
                 <div style="margin: 20px;" class="df jcsb aic">
                     <van-button round type="primary" color="rgba(25, 137, 250, .7)" plain
@@ -23,25 +33,32 @@
 </template>
 
 <script setup lang="ts">
-import { reactive } from 'vue';
+import { reactive, ref, onMounted } from 'vue';
 import { getUserLogin } from '@/api/index'
 import Message from '@/utils/Message'
 import { useRouter } from 'vue-router'
 import { useStore } from '@/store/index'
 import local from '@/utils/local';
-
+import checkRestTime from '@/utils/captcha'
+import { showSuccessToast, showFailToast } from 'vant';
 const user = useStore('user')
 const router = useRouter()
+const login_typ = ref<'pwd'| 'sms'>('pwd')
+const can_send = ref<boolean>(true)
+const smsMessage = ref<'获取验证码' | number>('获取验证码')
+const VALID = 60
 
 interface login {
     account: string,
     password: string,
-    timestamp: string | number
+    timestamp: string | number,
+    smsCaptcha:number | undefined
 }
 const loginForm = reactive<login>({
     account: '',
     password: '',
-    timestamp: parseInt(`${Date.now() / 1000}`)
+    timestamp: parseInt(`${Date.now() / 1000}`),
+    smsCaptcha: undefined
 })
 
 const submitForm = async () => {
@@ -81,8 +98,38 @@ const submitForm = async () => {
 
 const resetForm = () => {
     loginForm.account = ''
-    loginForm.password = ''
+    loginForm.password = '',
+    loginForm.smsCaptcha = null
+}
+const getCaptcha = () => {
+   can_send.value = false
+   smsMessage.value = VALID
+   settimes()
+   sessionStorage.setItem('LOGIN_CAPTCHA', Math.round(new Date().getTime() / 1000).toString())
+   showSuccessToast('验证码已发送,请注意查收');
 }
+const settimes = () => {
+    var interval
+    const setTimeFn = () => {
+        (smsMessage.value as number)--
+        if (smsMessage.value as number < 0 || can_send.value === true) {
+            clearInterval(interval)
+            can_send.value = true
+            smsMessage.value = '获取验证码'
+        }
+    }
+    interval = setInterval(function() {
+        setTimeFn()
+    }, 1000)
+}
+onMounted(() => {
+    let res = checkRestTime('LOGIN_CAPTCHA', VALID)
+    if(res){
+        smsMessage.value = res
+        can_send.value = false
+        settimes()
+    }
+})
 </script>
 
 <style lang="scss" scoped>

+ 25 - 3
src/view/m_views/mine/index.vue

@@ -3,7 +3,13 @@
     <div v-if="token">
         <div v-if="mineGame.length > 0">
             <div style="padding:15px">
-                <MobList :gameLis="mineGame" :prefix="prefix"></MobList>
+                <MobList :gameLis="mineGame" :prefix="prefix">
+                    <template #custom-button="scope">
+                        <div>
+                            <van-button round color="#ed8c0f" @click="showGifts(scope.row)">查看礼包</van-button>
+                        </div>
+                    </template>
+                </MobList>
             </div>
             <div style="padding: 10px;background-color: #f7f7f7;" class="df aic jcc"
                 v-if="params.page * params.pagesize <= mineGame.length">
@@ -21,7 +27,17 @@
             <van-button color="#ed8c0f" @click="goLogin">去登录 &gt;&gt;</van-button>
         </van-empty>
     </div>
-
+    <van-dialog v-model:show="dialogVisible" title="查看礼包" confirm-button-text="关闭">
+        <van-collapse v-model="activeNames">
+            <van-collapse-item title="新手礼包" name="1">
+                <template #value>
+                    <van-button round color="#ed8c0f">领取礼包</van-button>
+                </template>
+                代码是写出来给人看的,附带能在机器上运行。
+            </van-collapse-item>
+            
+        </van-collapse>
+    </van-dialog>
     <van-back-top style="background-color: #ed8c0f;" />
     <!-- <m_footer></m_footer> -->
 </template>
@@ -96,7 +112,12 @@ const loadMore = () => {
 const goLogin = () => {
     router.push({ path: 'm_login' })
 }
-
+const activeNames = ref(['1']);
+const dialogVisible = ref<boolean>(false)
+const showGifts = (row:any) => {
+   console.log(row);
+   dialogVisible.value = true
+}
 </script>
 
 <style scoped lang="scss">
@@ -126,4 +147,5 @@ const goLogin = () => {
         border: 1px solid #c7c7c7;
     }
 }
+
 </style>

+ 71 - 16
src/view/p_views/login/index.vue

@@ -4,56 +4,79 @@
             <!-- <img src="http://gm.nkfzs.com/favicon.ico"> -->
             <img src="@/assets/img/logo.png">
         </div>
+        
         <el-form ref="ruleFormRef" :rules="rules" class="login_from df fdc aic jcc" label-position="left"
-            label-width="80px" :model="loginForm" style="max-width: 400px" @submit="submitForm">
-            <el-form-item label="用户名" prop="account">
+            label-width="80px" :model="loginForm" style="max-width: 400px" @submit.prevent="submitForm(ruleFormRef)">
+            <el-tabs v-model="login_typ" style="" @tab-change="resetForm">
+                <el-tab-pane label="密码登录" name="pwd" />
+                <el-tab-pane label="验证码登录" name="sms" />
+            </el-tabs>
+            <template v-if="login_typ === 'pwd'">
+                <el-form-item label="用户名" prop="account">
                 <el-input v-model="loginForm.account" type="text" placeholder="请输入账号" clearable :prefix-icon="User" />
-            </el-form-item>
-            <el-form-item label="密&emsp;码" prop="password">
-                <el-input v-model="loginForm.password" type="password" show-password placeholder="请输入密码"
-                    :prefix-icon="Lock" />
-                <el-input v-model="loginForm.password" type="hidden" id="md5_password" show-password placeholder="请输入密码"
-                    :prefix-icon="Lock" />
-            </el-form-item>
+                </el-form-item>
+                <el-form-item label="密&emsp;码" prop="password">
+                    <el-input v-model="loginForm.password" type="password" show-password placeholder="请输入密码"
+                        :prefix-icon="Lock" />
+                    <el-input v-model="loginForm.password" type="hidden" id="md5_password" show-password placeholder="请输入密码"
+                        :prefix-icon="Lock" />
+                </el-form-item>
+            </template>
+            <template v-else-if="login_typ === 'sms'">
+                <el-form-item label="用户名" prop="account">
+                <el-input v-model="loginForm.account" type="text" placeholder="请输入账号" clearable :prefix-icon="User" />
+                </el-form-item>
+                <el-form-item label="验证码" prop="smsCaptcha">
+                    <el-input v-model="loginForm.smsCaptcha" type="number" placeholder="请输入验证码" :prefix-icon="Lock">
+                        <template #append>
+                            <el-button @click="getCaptcha" style="width: 100px;" :disabled ="!can_send">{{smsMessage}}</el-button>
+                        </template>
+                    </el-input>
+                </el-form-item>
+            </template>
             <!-- <el-form-item style="margin-top:-10px;margin-bottom:-5px;">
                     <el-checkbox v-model="checked" style="color:#a0a0a0;margin-top:-10px;">记住我</el-checkbox>
                 </el-form-item> -->
             <div class="btn df aic jcsb">
                 <el-button type="primary" plain round class="submit_btn" @click="resetForm(ruleFormRef)">重&emsp;置</el-button>
                 <el-button color="#ed8c0f" plain round class="submit_btn"
-                    @click="submitForm(ruleFormRef)">登&emsp;录</el-button>
+                    native-type="submit">登&emsp;录</el-button>
             </div>
         </el-form>
     </div>
 </template>
 
 <script setup lang="ts">
-import { reactive, ref } from 'vue';
+import { reactive, ref, onMounted } from 'vue';
 import { Lock, User } from '@element-plus/icons-vue'
 import type { FormInstance, FormRules } from 'element-plus'
 import { getUserLogin } from '@/api/index'
 // import '@/utils/md5'
 import Message from '@/utils/Message'
+import checkRestTime from '@/utils/captcha'
 import { useRouter } from 'vue-router'
 import { useStore } from '@/store/index'
 import local from '@/utils/local';
 
 const user = useStore('user')
 const router = useRouter()
-
+const VALID = 60
+const login_typ = ref<'pwd'| 'sms'>('pwd')
 const viewWidth = ref<number>(document.documentElement.clientHeight - 80)
-
+const smsMessage = ref<'获取验证码' | number>('获取验证码')
 const ruleFormRef = ref<FormInstance>()
-
+const can_send = ref<boolean>(true)
 interface login {
     account: string,
     password: string,
-    timestamp: number | string
+    timestamp: number | string,
+    smsCaptcha:number | null
 }
 const loginForm = reactive<login>({
     account: '',
     password: '',
-    timestamp: parseInt(`${Date.now() / 1000}`)
+    timestamp: parseInt(`${Date.now() / 1000}`),
+    smsCaptcha: null
 })
 
 const rules = reactive<FormRules>({
@@ -64,6 +87,9 @@ const rules = reactive<FormRules>({
     password: [
         { required: true, message: '请输入密码', trigger: 'blur' },
         { min: 6, max: 20, message: '请输入6-20位密码', trigger: 'blur,change' }
+    ],
+    smsCaptcha:[
+        { required: true, message: '请输入验证码', trigger: 'blur' }
     ]
 })
 
@@ -113,6 +139,35 @@ const resetForm = (formEl: FormInstance | undefined) => {
     if (!formEl) return
     formEl.resetFields()
 }
+const getCaptcha = () => {
+   can_send.value = false
+   smsMessage.value = VALID
+   settimes()
+   sessionStorage.setItem('LOGIN_CAPTCHA', Math.round(new Date().getTime() / 1000).toString())
+   Message.success('验证码已发送,请注意查收')
+}
+const settimes = () => {
+    var interval
+    const setTimeFn = () => {
+        (smsMessage.value as number)--
+        if (smsMessage.value as number < 0 || can_send.value === true) {
+            clearInterval(interval)
+            can_send.value = true
+            smsMessage.value = '获取验证码'
+        }
+    }
+    interval = setInterval(function() {
+        setTimeFn()
+    }, 1000)
+}
+onMounted(() => {
+    let res = checkRestTime('LOGIN_CAPTCHA', VALID)
+    if(res){
+        smsMessage.value = res
+        can_send.value = false
+        settimes()
+    }
+})
 </script>
 
 <style scoped lang="scss">

+ 40 - 3
src/view/p_views/mine/index.vue

@@ -1,4 +1,6 @@
 <template>
+    <div>
+
     <div v-if="token">
         <loading v-if="isLoading" :style="{ height: viewWidth + 'px' }" />
         <div v-else class="w1000" style="margin: 20px auto;">
@@ -8,7 +10,11 @@
                     <el-button class="df aic jcc" @click="loadMore">更多</el-button>
                 </div> -->
                 <div v-if="mineGame.length > 0">
-                    <IndexList :list="mineGame" :prefix="prefix"></IndexList>
+                    <IndexList :list="mineGame" :prefix="prefix">
+                        <template #custom-button="scope">
+                            <el-button @click="showGifts(scope.row)">查看礼包</el-button>
+                        </template>
+                    </IndexList>
                     <div class="more df aic jcc" v-if="params.page * params.pagesize <= mineGame.length">
                         <el-button class="df aic jcc" @click="loadMore">更多</el-button>
                     </div>
@@ -25,6 +31,33 @@
             <el-button style="color:#fff" color="#ed8c0f" @click="goLogin">去登录 &gt;&gt;</el-button>
         </el-empty>
     </div>
+    <el-dialog  v-model="dialogVisible" title="游戏礼包">
+        <el-collapse v-model="activeName" accordion>
+            <div style="display: flex;justify-content: space-between; align-items: center;">
+                <el-collapse-item title="新手礼包" name="1" style="width: 70%;">
+                    <div>
+                    礼包内容:守护符[武器]*1,守护符[防具]*1,强化石*1幸运符(5%)*5
+                    </div>
+                    <div>使用方法: 活动-礼包码兑换-邮件领取</div>
+                    <div>有效期:2023-08-02-2025-12-31</div>
+                </el-collapse-item>
+                <div style="width: 20%;">
+                    <el-button @click="dialogVisible = false">领取礼包</el-button>
+                </div>
+            </div>
+            
+        </el-collapse>
+        <!-- <template #footer>
+            <span class="dialog-footer">
+                <el-button @click="dialogVisible = false">Cancel</el-button>
+                <el-button type="primary" @click="dialogVisible = false">
+                Confirm
+                </el-button>
+            </span>
+        </template> -->
+    </el-dialog>
+</div>
+
 </template>
 
 <script setup lang="ts">
@@ -39,7 +72,7 @@ import local from '@/utils/local'
 const router = useRouter()
 const route = useRoute()
 // const header = useStore('header')
-
+const dialogVisible = ref<boolean>(false)
 const mineGame: any = ref([])
 const prefix = ref<string>('')
 const total = ref<number>(0)
@@ -47,7 +80,7 @@ const isLoading = ref<boolean>(true)
 const viewWidth = ref<number>(document.documentElement.clientHeight - 80)
 const userAccount = ref<string | null>(localStorage.getItem('account'))
 const token = ref<string | null>(localStorage.getItem('token'))
-
+const activeName = ref('1')
 interface params {
     page: number,
     pagesize: number,
@@ -96,6 +129,10 @@ const goLogin = () => {
     router.push({ path: 'p_login' })
     local.remove('headerPath')
 }
+const showGifts = (row:any) => {
+   console.log(row);
+   dialogVisible.value = true
+}
 
 </script>