最近半个月都好忙,连着4、5个活动,都没啥自己的时间了,今天整理下其中一个比较小的活动代码吧
包含的功能点:
(进入正题,下面这个花了大概3天的时间包括项目切分支新建、ui样式还原、接口对接、测试、测试bug修改、上线)
技术栈:vue、vue-router、vant-ui、微信sdk,还引入了flexible.js和pxtorem字体大小自适应<这块代码没列出来>
一全局:分享功能、百度统计
二首页:距离截止日期倒计时、若是已经申请的话从首页自动跳审核页、点申请跳申请页
三申请页:表单必填项验证提示、获取验证码接口、提交接口、样式处理、提交成功的审核时间的缓存
四审核页:有审核中样式、审核成功样式、根据缓存时间显示审核或成功的逻辑判断、老师接口、老师id对应的二维码缓存
一全局:分享功能
一:全局分享功能的实现
main.js添加下面二行代码
import state from "../libs/state"
Vue.use(state);
libs新建state.js文件,且state.js的代码如下
import Vue from 'vue';
export default {
install() {
const state = new Vue({
data: {
},
created() {
this.share();
},
methods: {
share() {
iceflower.wxShare({ // iceflower是已经封装了的分享的功能的
appId: '***8',
url: location.href.split('#/')[0],
apiTicket: '***',
title: `全国人才助学计划`,
desc: '你有1000元学历补贴待领取',
imgUrl: '*',
success: function () {
console.log('分享成功');
}
});
}
}
})
Vue.prototype.$state = state;
}
}
二首页:距离截止日期倒计时、若是已经申请的话从首页自动跳审核页、点申请跳申请页
二首页:距离截止日期倒计时、若是已经申请的话从首页自动跳审核页、点申请跳申请页
新建index.vue页面,代码如下
<template>
<section class="container">
<img class="img_box" src="****" alt="">
<div class="time_box">
<p class="tipTitle">距离名额申请截止还剩:</p>
<p class="tipTime">
<van-count-down style="display: inline-block" :time="endTime">
<template v-slot="timeData">
<span class="item">{{
timeData.days * 24 + timeData.hours > 9
? timeData.days * 24 + timeData.hours
: "0" + (timeData.days * 24 + timeData.hours)
}}</span>
时
<span class="item">{{timeData.minutes > 9 ? timeData.minutes : "0" + timeData.minutes}}</span>分
<span class="item">{{timeData.seconds > 9 ? timeData.seconds : "0" + timeData.seconds}}</span>秒
</template>
</van-count-down>
</p>
</div>
<div class="btn_box" @click="goPath('/userForm')">
<img src="***" alt="">
</div>
</section>
</template>
<script>
export default {
components: {},
data() {
return {
endTime: new Date("2021/03/31 23:59").getTime() - new Date().getTime(),
}
},
mounted() {
this.init()
},
methods: {
init() {
if(localStorage.getItem('submitTime')) { // 如果有缓存了的话 就直接跳第等待成功页
this.goPath('/waiting')
}
},
goPath(path) {
this.$router.push({
path: path
});
}
}
}
</script>
三申请页:表单必填项验证提示、获取验证码接口、提交接口、样式处理、提交成功的审核时间的缓存
三申请页:表单必填项验证提示、获取验证码接口、提交接口、样式处理、提交成功的审核时间的缓存
这块代码写的不好 原先是用van-field自带的必填检验的,后来说不要又改了一波校验
新建form.vue页面,代码如下
<template>
<div class="form-container">
<div class="img_box">
<img class="banner" src="../../assets/img/loginbg.png" alt="">
<p class="title">2021年个人学历补贴申请表</p>
</div>
<div class="head_box"></div>
<div class="form_box">
<van-form class="van-form">
<van-field
readonly
required
clickable
name="area"
v-model="area"
label="省份"
placeholder="请选择"
@click="showArea = true"
/>
<van-popup v-model="showArea" position="bottom">
<van-area
:area-list="areaList"
@confirm="chooseArea"
@cancel="showArea = false"
:columns-num="1"
/>
</van-popup>
<van-field
required
class="mt20"
v-model="studentName"
name="studentName"
label="姓名"
placeholder="请填写真实姓名"
/>
<van-field
required
class="mt20"
type="tel"
v-model="phone"
name="phone"
label="电话"
placeholder="请输入电话"
/>
<van-field
v-model="sms"
name="sms"
required
class="mt20"
center
maxlength="6"
type="number"
clearable
label="验证码"
placeholder="请输入验证码"
>
<template #button>
<van-button v-if="!smsCodeLoading" size="small" type="info" @click="smsHandled" style="background-color:#1F69C3;">获取验证码</van-button>
<van-button v-else size="small" type="info">{{time}}s</van-button>
</template>
</van-field>
<van-field
required
class="mt20"
v-model="cause"
name="cause"
:rows="3"
label="申请原因"
type="textarea"
placeholder="请输入申请原因"
/>
<div class="btn_box">
<van-button round block type="info" native-type="submit" class="btn_tijiao" @click="onSubmit">
提 交
</van-button>
</div>
</van-form>
</div>
<div class="tips_box">
<div class="tips_title">注意说明:</div>
<div>1、本次补贴面向所有需要提升学历的人员,请符合条件的学员进行申请。</div>
<div>2、上传信息将作为补贴申领凭证,请确保信息无误后提交。</div>
<div>3、请妥善保管个人信息,勿随意向他人透露申领资料,谨防上当受骗。</div>
</div>
</div>
</template>
<script>
import md5 from 'js-md5';
import { Toast } from 'vant';
import areaList from "../../../libs/area.js"
import axios from "axios"
import qs from 'qs'
import common from "../../../libs/common"
export default {
data() {
return {
studentName: '',
phone: '',
sms: '',
major: '',
area: '',
cause: '',
areaDetail: '',
showPicker: false,
showArea: false,
areaList: areaList, // 数据格式见 Area 组件文档
smsCodeLoading: false,
time: 60
};
},
mounted() {
},
methods: {
onConfirm(value) {
this.major = value;
this.showPicker = false;
},
chooseArea(values) {
this.area = values.map(item => item.name).join('/');
this.showArea = false;
},
// 点击获取验证码按钮
smsHandled: function() {
if(common.checkMobile(this.phone)) {
this.sendPhoneApi()
} else {
Toast.fail({ message: '请输入正确手机号'});
return;
}
},
onSubmit() {
let values = {
studentName: this.studentName,
phone: this.phone,
sms: this.sms,
area: this.area,
cause: this.cause,
}
for(let params in values) {
if(values[params] === '') {
Toast.fail({ message: '请填完整所有必填项'});
return;
}
if(params === 'phone' && !common.checkMobile(values.phone)) {
Toast.fail({ message: '手机格式错误'});
return;
}
}
if(this.sms.length !== 6) {
Toast.fail({ message: '请输入正确的验证码'});
return ;
}
values.activityId = common.getQueryString('activityId');
values.id = common.getQueryString('id');
values = Object.assign(values, { // 拼接这些固定的参数
labelInfo: '**',
productId: 1,
subjectId: 1,
courseId: ''
})
let params = common.paramsFilters(values)
this.verifySmsCode(params);
},
verifySmsCode(params) {
axios.post('***/insertCrmOpportunityPool',qs.stringify(params)).then(res => {
if(res.data.code === 'Success') {
localStorage.setItem('submitTime',new Date().getTime() + 300000)
this.$router.push("/waiting")
}else {
Toast(res.data.msg);
}
})
},
sendPhoneApi() {
var that = this;
that.smsCodeLoading = true;
that.time = 60;
let countDownClock = setInterval(function() {
that.time--;
if (that.time <= 0) {
clearInterval(countDownClock);
that.smsCodeLoading = false;
}
}, 1000);
let params = common.paramsFilters({phone: this.phone});
axios.post('***/sendPhone',qs.stringify(params)).then(res => {
if(res.data.code === 'Success') {
Toast.success("发送成功")
}else {
that.smsCodeLoading = false;
clearInterval(countDownClock);
Toast(res.data.msg);
}
})
}
},
};
</script>
四审核页:有审核中样式、审核成功样式、根据缓存时间显示审核或成功的逻辑判断、老师接口、老师id对应的二维码缓存
四审核页:有审核中样式、审核成功样式、根据缓存时间显示审核或成功的逻辑判断、老师接口、老师id对应的二维码缓存
新建result.vue页面,代码如下
<template>
<section v-if="this.status == 1" class="w-container">
<img class="img_box" src="**/xueli_zx_zhong.png" alt="">
<div class="content_box">
<div class="content_top">您已成功提交,资格审核中……</div>
</div>
<div class="tips_box">
<div>您的信息将由专业机构人工审核,</div>
<div>预计耗时5分钟,请耐心等待。</div>
</div>
<div class="qrcode_box">
<img class="qrcode_title" src="*/xueli_zx_er1.png" alt="">
<img class="qrcode_teacher" :src="teacherQrcode" alt="">
</div>
</section>
<section v-else class="w-container">
<img class="img_box" src="**/xueli_zx_cheng.png" alt="">
<div class="content_box2">
<div class="content_top">已通过审核</div>
<div class="content_bottom">获得 <span>1000</span> 元 学历补贴</div>
</div>
<div class="tips_box">
<div>您已通过2021年全国人才助学计划</div>
<div>资格名额审核,</div>
<div>可享有成人高考学历补贴,</div>
<div>请联系学历顾问激活个人名额。</div>
</div>
<div class="qrcode_box">
<img class="qrcode_title" src="*/xueli_zx_er2.png" alt="">
<img class="qrcode_teacher" :src="teacherQrcode" alt="">
</div>
</section>
</template>
<script>
import axios from "axios"
import qs from 'qs'
import common from "../../../libs/common"
import { Toast } from 'vant';
export default {
components: {},
data() {
return {
status: 1,
submitTime: '',
teacherQrcode: ''
}
},
mounted() {
this.init();
this.getTeacherQrCode();
},
methods: {
init() {
if(!localStorage.getItem('submitTime')) {
setTimeout(() => {
this.status = 2
}, 5 * 60000)
} else if(localStorage.getItem('submitTime') > new Date().getTime()) {
let newTime = localStorage.getItem('submitTime') - new Date().getTime()
setTimeout(() => {
this.status = 2
}, newTime)
} else {
this.status = 2
}
},
getTeacherQrCode() {
if(localStorage.getItem(`TeacherQrCode_${common.getQueryString('id')}`)) {
this.teacherQrcode = localStorage.getItem(`TeacherQrCode_${common.getQueryString('id')}`);
return ;
}
let params = common.paramsFilters({activityId:common.getQueryString('activityId'),id: common.getQueryString('id') })
axios.post('*/getTeacherQrCode',qs.stringify(params)).then(res => {
if(res.data.code === 'Success') {
this.teacherQrcode = res.data.dataJson.qrCode;
localStorage.setItem(`TeacherQrCode_${common.getQueryString('id')}`, res.data.dataJson.qrCode)
}else {
}
})
},
}
}
</script>
五:路由的配置
五:路由的配置
在main.js中添加如下几行代码
import router from "../libs/router"
new Vue({
router,
render: h => h(App),
}).$mount('#app')
然后新建libs/router.js页,具体代码如下
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
scrollBehavior (to, from, savedPosition) { // 可以解决页面切换后自动滚动的顶部的问题提
return { x: 0, y: 0 }
} ,
routes: [
{
path: '/',
name: 'xueliZxPlan',
component: () => import('@/pages/xueliZxPlan/index'),
meta: {
title: '全国人才助学计划'
}
},
{
path: '/form',
name: 'form',
component: () => import('@/pages/xueliZxPlan/form'),
meta: {
title: '全国人才助学计划'
}
},
{
path: '/result',
name: 'result',
component: () => import('@/pages/xueliZxPlan/result'),
meta: {
title: '全国人才助学计划'
}
},
]
})
拓展:如果需要百度统计的话,添加在public/index.html中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0 maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title></title>
<script src="<%= BASE_URL %>flexible.js" ></script>
<script src="<%= BASE_URL %>iceflower.js" ></script>
<body>
<div id="app"></div>
<script>
// 百度统计代码
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://***";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</body>
</html>
然后就是npm run build打包,我使用部署到线上的软件是FileZilla,拖拽打包后的文件dist,就可以访问链接了✌️