提交 da6e909b authored 作者: matian's avatar matian

updates

上级 5d038661
<template>
<div class="app-apply-form">
<h2 class="title">报名咨询</h2>
<div class="form">
<div class="form-item">
<input
type="text"
class="form-input"
placeholder="请输入您的名字"
v-model="ruleForm.name"
/>
</div>
<div class="form-item">
<input
type="number"
class="form-input"
placeholder="请输入您的电话"
maxlength="11"
v-model="ruleForm.phone"
/>
</div>
<div class="form-item">
<input
type="text"
class="form-input"
placeholder="请输入验证码"
maxlength="4"
v-model="phoneCode"
/>
<input
type="button"
class="form-button"
:disabled="codeButtonDisabled"
:value="buttonText"
@click="onSendCode"
/>
</div>
<div class="form-item">
<input
type="button"
value="立即报名"
class="form-button"
@click="onSbumit"
/>
</div>
</div>
</div>
</template>
<script>
import * as api from '@/api/base'
export default {
data() {
return {
ruleForm: {
name: '',
phone: '',
project_id: '5007',
channel: ''
},
phoneCode: '',
codeButtonDisabled: false,
timer: null,
disabledTime: 60
}
},
mounted() {
this.ruleForm.channel = window.localStorage.getItem('channel_num') || 19960
},
computed: {
buttonText() {
return this.codeButtonDisabled ? `${this.disabledTime}s` : '获取验证码'
}
},
methods: {
onSbumit() {
if (!this.ruleForm.name) {
this.$notify('请输入您的姓名')
return
}
if (!this.ruleForm.phone || !/^1[3-9]\d{9}$/.test(this.ruleForm.phone)) {
this.$notify('请输入正确的手机号')
return
}
if (!this.phoneCode) {
this.$notify('请输入短信验证码')
return
}
this.checkPhoneCode().then(this.handleSubmit)
},
handleSubmit() {
const params = { ...this.ruleForm }
api.submit(params).then((response) => {
// this.$notify({ type: 'success', message: response.message })
this.$dialog.alert({ message: response.message }).then(() => {
this.$emit('success')
})
})
},
// 校验短信验证码
checkPhoneCode() {
return api.checkCode({
account: this.ruleForm.phone,
code: this.phoneCode
})
},
onSendCode() {
if (!this.ruleForm.phone || !/^1[3-9]\d{9}$/.test(this.ruleForm.phone)) {
this.$notify('请输入正确的手机号')
return
}
this.sendCode()
},
// 发送验证码
sendCode() {
this.setTimer()
api
.sendCode({ account: this.ruleForm.phone })
.then(() => {
this.$notify({ type: 'success', message: '验证码发送成功,注意查收' })
})
.catch(() => {
this.clearTimer()
})
},
setTimer() {
this.codeButtonDisabled = true
this.disabledTime = 60
this.timer = setInterval(() => {
this.disabledTime--
if (this.disabledTime <= 0) {
this.clearTimer()
}
}, 1000)
},
clearTimer() {
this.codeButtonDisabled = false
this.timer && clearInterval(this.timer)
}
},
destroyed() {
this.clearTimer()
}
}
</script>
<style lang="scss" scoped>
.app-apply-form {
min-width: 290px;
position: relative;
z-index: 3000;
.title {
padding: 30px 0;
font-size: 20px;
color: #fff;
text-align: center;
}
}
.form-item {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.form-input {
padding: 0 10px;
width: 100%;
height: 38px;
background-color: #fff;
box-sizing: border-box;
border: none;
}
.form-select {
position: relative;
padding: 0 10px;
width: 100%;
height: 38px;
background: #fff
url('https://webapp-pub.ezijing.com/www/h5/images/icon_arrows.png')
no-repeat;
background-position: right 0.7em top 50%, 0 0;
background-size: 30px 30px;
box-sizing: border-box;
border: none;
}
.form-button {
padding: 0 10px;
width: 100%;
height: 38px;
font-size: 16px;
color: #aa1941;
background-color: #ffd61b;
box-sizing: border-box;
border: none;
cursor: pointer;
}
.form-input + .form-button {
margin-left: 10px;
}
</style>
\ No newline at end of file
<script setup lang="ts">
import AppHeader from './Header.vue'
import AppFooter from './Footer.vue'
import RightAside from './RightAside.vue'
import RightAsideH5 from './RightAsideH5.vue'
import { useDevice } from '@/composables/useDevice'
const { mobile } = useDevice()
const route = useRoute()
interface Props {
fixed?: boolean
}
......@@ -13,6 +18,16 @@ const props = defineProps<Props>()
<section class="app-layout-container">
<router-view :key="$route.fullPath"></router-view>
</section>
<AppFooter></AppFooter>
<template
v-if="(!mobile && route.path !== '/shop/pay') || route.path !== '/shop'"
>
<AppFooter></AppFooter>
</template>
<template v-if="!mobile">
<RightAside />
</template>
<template v-else>
<RightAsideH5 />
</template>
</div>
</template>
<script >
import { sendCode, checkCode, postNes } from '@/api/base'
const MOBILE_REG =
/^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/
export default {
data() {
return {
tabBtnActive: false,
tabBtnTarget: '',
projectName: '金融硕士保研项目',
sendCode: '',
isBtnDisabled: false,
formInfo: {
name: '',
phone: '',
projectId: '5007'
}
}
},
methods: {
handleMsOver(type) {
this.tabBtnActive = true
if (type !== '') {
this.tabBtnTarget = type
}
},
handleMsOut(type) {
this.tabBtnActive = false
},
submitEnroll() {
let flag = true
Object.keys(this.formInfo).map((item) => {
if (this.formInfo[item] === '') {
flag = false
}
})
if (!flag || !this.sendCode) {
this.$message('请完善信息')
} else if (!MOBILE_REG.test(this.formInfo.phone)) {
this.$message('手机号格式错误')
} else {
this.checkSendcode()
.then((res) => {
return this.enrollQuery()
})
.then((res) => {
this.$message({
type: 'success',
message: '报名成功',
duration: 5000
})
})
.catch((err) => {
if (err && err.type === 'checkcode') this.$message.error(err.msg)
else this.$message.error(err.msg || '报名提交失败')
})
}
},
enrollQuery() {
const params = {
channel: localStorage.getItem('channel_num') || 19962,
project_id: this.formInfo.projectId,
name: this.formInfo.name,
phone: this.formInfo.phone
}
return new Promise((resolve, reject) => {
postNes(params).then((res) => {
if (res && res.status === 200 && res.error === 0) {
resolve({
type: 'enroll',
state: 'success'
})
} else {
reject({
type: 'enroll',
state: 'fail',
msg: res.message || '报名提交失败'
})
}
})
})
},
getSendCode() {
if (!this.formInfo.phone) {
this.$message('手机号不能为空')
} else if (!MOBILE_REG.test(this.formInfo.phone)) {
this.$message('手机号格式错误')
} else {
const param = {
account: this.formInfo.phone,
service: 'ezijing.com'
}
sendCode(param)
.then((res) => {
this.btnDisabledTimer()
if (res && res.code === 0)
this.$message.success('验证码已发送,请注意查收')
else this.$message.error('获取验证码失败,请稍后再试')
})
.catch(() => {})
}
},
checkSendcode() {
const checkCodeParam = {
account: this.formInfo.phone,
code: this.sendCode,
countryCode: 86
}
return new Promise((resolve, reject) => {
checkCode(checkCodeParam).then((res) => {
if (res && res.code === 0) {
res.type = 'checkcode'
resolve({
type: 'checked',
state: 'success'
})
} else {
reject({
type: 'checked',
state: 'fail',
msg: res.msg || '验证码检测失败'
})
}
})
})
},
btnDisabledTimer() {
this.isBtnDisabled = true
let count = 60
document.querySelector('#checkedCode').innerHTML = count + 's'
const timer = setInterval(() => {
count--
if (count < 1) {
clearInterval(timer)
this.isBtnDisabled = false
document.querySelector('#checkedCode').innerHTML = '获取验证码'
} else {
document.querySelector('#checkedCode').innerHTML = count + 's'
}
}, 1000)
}
}
}
</script>
<template>
<div class="right_bar">
<ul class="tab_btns">
<li
:class="{
enroll: true,
active: tabBtnActive && tabBtnTarget === 'enroll'
}"
@mouseenter="handleMsOver('enroll')"
@mouseleave="handleMsOut"
>
<p>报名咨询</p>
</li>
</ul>
<div
id="show-enroll"
v-show="tabBtnActive"
class="tab_cont"
@mouseenter="handleMsOver('')"
@mouseleave="handleMsOut"
>
<div class="enroll_cont" id="show-enroll-content">
<h5>报名咨询</h5>
<div class="p">
<el-input
v-model="formInfo.name"
placeholder="请输入您的名字"
size="small"
></el-input>
</div>
<div class="p">
<el-input
v-model="formInfo.phone"
placeholder="请输入您的电话"
size="small"
></el-input>
</div>
<div class="p sendcode">
<el-input
v-model="sendCode"
placeholder="请输入验证码"
size="small"
></el-input
><el-button
class="btn"
:disabled="isBtnDisabled"
id="checkedCode"
@click="getSendCode"
>
获取验证码
</el-button>
</div>
<div class="p">
<el-button style="width: 100%" @click="submitEnroll"
>立即报名</el-button
>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.right_bar {
position: fixed;
top: 50%;
right: 10px;
z-index: 2000;
transform: translateY(-50%);
.tab_btns {
width: 100px;
font-size: 12px;
border-radius: 4px;
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);
overflow: hidden;
li {
padding: 70px 0 18px;
color: #999;
background-position: center 18px;
background-repeat: no-repeat;
background-color: #fff;
text-align: center;
}
li.active {
background-color: #af1b40;
color: #fff;
opacity: 0.9;
transition: 0.3s;
}
li.enroll {
position: relative;
background-image: url(https://zws-imgs-pub.ezijing.com/static/public/d434fa0ffd77892273e63e6d694cff0a.png);
}
li.enroll:after {
content: '';
width: 100%;
height: 1px;
background: #b8bcbf;
position: absolute;
left: 0;
bottom: 0;
// transform: translateX(-50%) scale(0.5);
}
li.enroll.active {
background-image: url(https://zws-imgs-pub.ezijing.com/static/public/4cbef518113d24b392be80148e921abd.png);
}
li.wx {
background-image: url(https://zws-imgs-pub.ezijing.com/static/public/5526b83d7526b2742f6eba7151c367db.png);
}
li.wx.active {
background-image: url(https://zws-imgs-pub.ezijing.com/static/public/0831ea27fee535ab0ce9f730f467b2e1.png);
}
li > p {
font-size: 12px;
line-height: 14px;
text-align: center;
// transform: scale(0.9);
line-height: 100%;
cursor: default;
}
}
.tab_cont {
position: absolute;
left: -360px;
top: -120px;
width: 346px;
height: 390px;
background: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/right_bg.png);
// display:none;
h5 {
font-size: 24px;
font-weight: 400;
line-height: 19px;
color: #ffffff;
text-align: center;
margin-bottom: 25px;
}
.enroll_cont {
padding: 46px 29px 69px 29px;
box-sizing: border-box;
.p {
margin-bottom: 20px;
position: relative;
:deep(.el-input__inner) {
line-height: 40px;
height: 40px;
}
:deep(.el-input__inner::placeholder) {
font-weight: 300;
font-size: 14px;
color: #999999;
line-height: 40px;
height: 40px;
}
:deep(.el-button) {
background-color: #c1ab85;
border: 1px solid #c1ab85;
color: #ffffff;
height: 40px;
font-size: 16px;
}
}
.sendcode {
display: flex;
justify-content: space-between;
:deep(.el-input) {
width: 170px;
height: 40px;
}
:deep(.el-button) {
height: 40px;
color: #ffffff;
font-size: 14px;
margin-left: 10px;
}
:deep(.is-disabled) {
color: #c0c4cc;
cursor: not-allowed;
background-image: none;
background-color: #fff;
border-color: #ebeef5;
}
}
}
}
}
</style>
<template>
<div class="rigth-aside">
<ul class="right-aside-btns">
<li @click="showApplyForm">
<img
src="https://zws-imgs-pub.ezijing.com/static/public/d434fa0ffd77892273e63e6d694cff0a.png"
/>
<p>报名咨询</p>
</li>
</ul>
</div>
<!-- 我要报名 -->
<van-overlay :show="applyFormVisible" @click="hideApplyForm">
<div class="dialog-box" @click.stop>
<apply-form @success="hideApplyForm"></apply-form>
</div>
</van-overlay>
</template>
<script>
import ApplyForm from './ApplyForm.vue'
export default {
components: { ApplyForm },
data() {
return {
applyFormVisible: false
}
},
methods: {
// 我要报名
showApplyForm() {
this.applyFormVisible = true
},
hideApplyForm() {
this.applyFormVisible = false
}
}
}
</script>
<style lang="scss" scoped>
.van-overlay {
z-index: 1000 !important;
}
.rigth-aside {
position: fixed;
top: 40%;
right: 16px;
z-index: 1000;
transform: translateY(-50%);
.right-aside-btns {
box-shadow: 0 2px 4px 0 rgb(0 0 0 / 10%);
li {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 1rem;
height: 1rem;
font-size: 0.1rem;
color: #999;
background-color: #fff;
cursor: pointer;
border-radius: 0.12rem;
img {
width: 0.46rem;
height: 0.46rem;
}
}
}
}
.dialog-box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
width: 6.9rem;
height: 7.5rem;
background: url('https://webapp-pub.ezijing.com/www/h5/images/dialog_bg.png')
no-repeat;
background-size: cover;
.title {
font-size: 0.4rem;
color: #fff;
text-align: center;
}
}
</style>
<script lang="ts" setup>
import CourseList from '../components/CourseList.vue'
import { useShopStore } from '@/stores/shop'
import { useDevice } from '@/composables/useDevice'
const { mobile } = useDevice()
const shopStore = useShopStore()
const handleTabClick = (tab: any) => {
if (tab.index === '4') {
......@@ -12,7 +13,7 @@ const handleTabClick = (tab: any) => {
</script>
<template>
<div class="main_shop">
<div class="main_shop" v-if="!mobile">
<img
src="https://webapp-pub.ezijing.com/project_online/fi/shop_banner.jpg"
class="shop_banner"
......@@ -38,6 +39,22 @@ const handleTabClick = (tab: any) => {
</div>
</div>
</div>
<div v-else>
<van-tabs>
<van-tab
:title="item.label"
v-for="(item, index) in shopStore.filters.slice(0, 4)"
:key="index"
lazy
>
<CourseList
:type="item.value"
:courseList="shopStore.shopList"
:key="index"
/>
</van-tab>
</van-tabs>
</div>
</template>
<style lang="scss" scoped>
.is-pc {
......@@ -121,7 +138,7 @@ const handleTabClick = (tab: any) => {
font-weight: 500;
line-height: 34px;
color: #eda020;
padding: 0 0.1rem !important;
padding: 0 0.4rem !important;
box-sizing: border-box;
}
:deep(.el-tabs__nav-scroll) {
......@@ -152,4 +169,25 @@ const handleTabClick = (tab: any) => {
display: none;
}
}
:deep(.van-tab--active) {
.van-tab__text {
color: #eda020 !important;
font-size: 0.28rem;
}
}
:deep(.van-tab) {
.van-tab__text {
color: #333333;
font-size: 0.28rem;
}
.van-tabs__nav {
background: none;
}
}
:deep(.van-tabs__line) {
background: #eda023 !important;
}
:deep(.van-tab__panel) {
margin-top: 0.3rem;
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论