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

updates

上级 2a4818af
......@@ -16,6 +16,7 @@
"query-string": "^7.1.1",
"querystring": "^0.2.1",
"swiper": "^8.4.4",
"vant": "^3.6.5",
"vue": "^3.2.45",
"vue-router": "^4.1.6"
},
......@@ -483,6 +484,21 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@vant/icons": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@vant/icons/-/icons-1.8.0.tgz",
"integrity": "sha512-sKfEUo2/CkQFuERxvkuF6mGQZDKu3IQdj5rV9Fm0weJXtchDSSQ+zt8qPCNUEhh9Y8shy5PzxbvAfOOkCwlCXg=="
},
"node_modules/@vant/popperjs": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@vant/popperjs/-/popperjs-1.3.0.tgz",
"integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw=="
},
"node_modules/@vant/use": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@vant/use/-/use-1.4.3.tgz",
"integrity": "sha512-rSnETN7P9qT1WbItMpQxBqe3cHeK2ZFYp1sCxWUXaTeI71TqA8sOdzC36ledZ36NQgFNTch9fsRPYOkrCgZfQA=="
},
"node_modules/@vitejs/plugin-vue": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz",
......@@ -4401,6 +4417,19 @@
"node": ">= 0.12.0"
}
},
"node_modules/vant": {
"version": "3.6.5",
"resolved": "https://registry.npmjs.org/vant/-/vant-3.6.5.tgz",
"integrity": "sha512-TVTs5impkF6qPvCn+qhpcuNyxy0rCRA161JYkK5rFpKhwWftq4TOSTZAHGCW2kVFtrwl0Zp715GXEed/hxivYw==",
"dependencies": {
"@vant/icons": "^1.8.0",
"@vant/popperjs": "^1.2.1",
"@vant/use": "^1.4.2"
},
"peerDependencies": {
"vue": "^3.0.0"
}
},
"node_modules/vite": {
"version": "3.2.4",
"resolved": "https://registry.npmmirror.com/vite/-/vite-3.2.4.tgz",
......@@ -4981,6 +5010,21 @@
"eslint-visitor-keys": "^3.3.0"
}
},
"@vant/icons": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@vant/icons/-/icons-1.8.0.tgz",
"integrity": "sha512-sKfEUo2/CkQFuERxvkuF6mGQZDKu3IQdj5rV9Fm0weJXtchDSSQ+zt8qPCNUEhh9Y8shy5PzxbvAfOOkCwlCXg=="
},
"@vant/popperjs": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@vant/popperjs/-/popperjs-1.3.0.tgz",
"integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw=="
},
"@vant/use": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@vant/use/-/use-1.4.3.tgz",
"integrity": "sha512-rSnETN7P9qT1WbItMpQxBqe3cHeK2ZFYp1sCxWUXaTeI71TqA8sOdzC36ledZ36NQgFNTch9fsRPYOkrCgZfQA=="
},
"@vitejs/plugin-vue": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz",
......@@ -7886,6 +7930,16 @@
"unescape": "^1.0.1"
}
},
"vant": {
"version": "3.6.5",
"resolved": "https://registry.npmjs.org/vant/-/vant-3.6.5.tgz",
"integrity": "sha512-TVTs5impkF6qPvCn+qhpcuNyxy0rCRA161JYkK5rFpKhwWftq4TOSTZAHGCW2kVFtrwl0Zp715GXEed/hxivYw==",
"requires": {
"@vant/icons": "^1.8.0",
"@vant/popperjs": "^1.2.1",
"@vant/use": "^1.4.2"
}
},
"vite": {
"version": "3.2.4",
"resolved": "https://registry.npmmirror.com/vite/-/vite-3.2.4.tgz",
......
......@@ -23,6 +23,7 @@
"query-string": "^7.1.1",
"querystring": "^0.2.1",
"swiper": "^8.4.4",
"vant": "^3.6.5",
"vue": "^3.2.45",
"vue-router": "^4.1.6"
},
......
<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
......@@ -2,6 +2,7 @@
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()
......@@ -17,10 +18,16 @@ const props = defineProps<Props>()
<section class="app-layout-container">
<router-view :key="$route.fullPath"></router-view>
</section>
<template v-if="!mobile && route.path !=='/shop/pay' ">
<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>
<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>
<transition
name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
<div
id="show-enroll"
v-show="tabBtnActive"
class="tab_cont"
@mouseenter="handleMsOver('')"
@mouseleave="handleMsOut"
>
<div class="enroll_cont" id="show-enroll-content" v-show="tabBtnTarget === 'enroll'">
<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>
</transition>
</div>
</template>
<script>
<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}$/
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 {
......@@ -74,7 +30,7 @@ export default {
},
submitEnroll() {
let flag = true
Object.keys(this.formInfo).map(item => {
Object.keys(this.formInfo).map((item) => {
if (this.formInfo[item] === '') {
flag = false
}
......@@ -85,17 +41,17 @@ export default {
this.$message('手机号格式错误')
} else {
this.checkSendcode()
.then(res => {
.then((res) => {
return this.enrollQuery()
})
.then(res => {
.then((res) => {
this.$message({
type: 'success',
message: '报名成功',
duration: 5000
})
})
.catch(err => {
.catch((err) => {
if (err && err.type === 'checkcode') this.$message.error(err.msg)
else this.$message.error(err.msg || '报名提交失败')
})
......@@ -109,7 +65,7 @@ export default {
phone: this.formInfo.phone
}
return new Promise((resolve, reject) => {
postNes(params).then(res => {
postNes(params).then((res) => {
if (res && res.status === 200 && res.error === 0) {
resolve({
type: 'enroll',
......@@ -136,9 +92,10 @@ export default {
service: 'ezijing.com'
}
sendCode(param)
.then(res => {
.then((res) => {
this.btnDisabledTimer()
if (res && res.code === 0) this.$message.success('验证码已发送,请注意查收')
if (res && res.code === 0)
this.$message.success('验证码已发送,请注意查收')
else this.$message.error('获取验证码失败,请稍后再试')
})
.catch(() => {})
......@@ -151,7 +108,7 @@ export default {
countryCode: 86
}
return new Promise((resolve, reject) => {
checkCode(checkCodeParam).then(res => {
checkCode(checkCodeParam).then((res) => {
if (res && res.code === 0) {
res.type = 'checkcode'
resolve({
......@@ -177,7 +134,7 @@ export default {
if (count < 1) {
clearInterval(timer)
this.isBtnDisabled = false
document.querySelector('#checkedCode').innerHTML = this.$t('aside.codeBtn')
document.querySelector('#checkedCode').innerHTML = '获取验证码'
} else {
document.querySelector('#checkedCode').innerHTML = count + 's'
}
......@@ -186,9 +143,79 @@ export default {
}
}
</script>
<template>
<div class="right_bar">
<ul class="tab_btns" v-if="!mobile">
<li
:class="{
enroll: true,
active: tabBtnActive && tabBtnTarget === 'enroll'
}"
@mouseenter="handleMsOver('enroll')"
@mouseleave="handleMsOut"
>
<p>报名咨询</p>
</li>
</ul>
<ul class="tab_btns" v-else>
<li>
<img
src="https://zws-imgs-pub.ezijing.com/static/public/d434fa0ffd77892273e63e6d694cff0a.png"
alt=""
/>
<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 {
display: none;
position: fixed;
top: 50%;
right: 10px;
......
<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() {
console.log('11')
this.applyFormVisible = false
}
}
}
</script>
<style lang="scss" scoped>
.van-overlay {
z-index: 1000 !important;
}
.rigth-aside {
position: fixed;
top: 50%;
right: 16px;
z-index: 99;
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;
img {
width: 0.46rem;
height: 0.46rem;
}
}
li + li {
border-top: 1px solid #999;
}
}
}
.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>
......@@ -7,6 +7,10 @@ import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import { Overlay } from 'vant';
// 2. 引入组件样式
import 'vant/lib/index.css';
// 公共css
import './assets/css/base.css'
// 公共组件
......@@ -16,12 +20,13 @@ import AppContainer from '@/components/base/AppContainer.vue'
import modules from './modules'
const app = createApp(App)
// 注册公共组件
app.component('AppCard', AppCard).component('AppContainer', AppContainer)
// 注册模块
modules({ router })
app.use(Overlay)
app.use(createPinia())
app.use(router)
app.use(ElementPlus)
......
<script lang="ts" setup>
import { Swiper, SwiperSlide } from 'swiper/vue'
import 'swiper/css'
const list = [{ url: 'https://webapp-pub.ezijing.com/project_online/fi/banner.jpg' }]
const list = [
{ url: 'https://webapp-pub.ezijing.com/project_online/fi/banner.jpg' }
]
</script>
<template>
<div class="banner">
......@@ -21,9 +23,4 @@ const list = [{ url: 'https://webapp-pub.ezijing.com/project_online/fi/banner.jp
object-position: center;
}
}
.is-h5 {
.banner {
padding: 0 0.15rem;
}
}
</style>
<script lang="ts" setup>
import { Swiper, SwiperSlide } from 'swiper/vue'
import { Navigation } from 'swiper'
import 'swiper/css'
import 'swiper/css/navigation'
import { useDevice } from '@/composables/useDevice'
const { mobile } = useDevice()
const swiper1 = ref(null)
const list = [
{
img: 'https://webapp-pub.ezijing.com/project_online/fi/main4.png',
desc: '清控紫荆金融保险研究院&清控紫荆金融保险学院,基于政策指导,通过汇聚清华等国内外高校、行业骨干企业、行业研究机构的科研资源与实践成果,打造国内顶尖、国际卓越的金融保险智库,达到“产学研”的深度融合。'
},
{
img: 'https://webapp-pub.ezijing.com/project_online/fi/main5.png',
desc: '通过创立通晓金融保险理论与行业实务双方面的金融保险课题研发团队,针对金融保险不同领域、不同阶段的学习需求,为金融从业者提供专业学习契机、为金融机构培育高素质国际化人才。'
}
]
</script>
<template>
<div v-if="!mobile">
<div class="main1">
<div class="main_con">
<img src="https://webapp-pub.ezijing.com/project_online/fi/main1.png" alt="" />
<img
src="https://webapp-pub.ezijing.com/project_online/fi/main1.png"
alt=""
/>
<div class="con_content">
清控紫荆金融保险研究院&清控紫荆金融保险学院,基于政策指导,通过汇聚清华等国内外高校、行业骨干企业、行业研究机构的科研资源与实践成果,打造国内顶尖、国际卓越的金融保险智库,达到“产学研”的深度融合。
</div>
......@@ -32,25 +17,19 @@ const list = [
<div class="con_content">
通过创立通晓金融保险理论与行业实务双方面的金融保险课题研发团队,针对金融保险不同领域、不同阶段的学习需求,为金融从业者提供专业学习契机、为金融机构培育高素质国际化人才。
</div>
<img src="https://webapp-pub.ezijing.com/project_online/fi/main3.png" alt="" />
</div>
<img
src="https://webapp-pub.ezijing.com/project_online/fi/main3.png"
alt=""
/>
</div>
</div>
<div v-else>
<Swiper loop :slidesPerView="1" :spaceBetween="10" :modules="[Navigation]" @swiper="swiper => (swiper1 = swiper)">
<SwiperSlide v-for="(item, index) in list" :key="index" class="main_list">
<img :src="item.img" alt="" class="list_img" />
<div class="list_con">{{ item.desc }}</div>
</SwiperSlide>
</Swiper>
</div>
<div class="main3">
核心产品为紫荆教育专属版权产品,站在高起点、高站位、高规格的“三高”教育标准平台上,向社会和企业精<br />英人士教授与传承“<span>格与质</span>”、“<span>道与术</span>”、“<span>欲与渔</span>”的经营管理品格和能力,主打行业认证类、行业标<br />准类和定制专属类等三类金融职业类培育体系。
</div>
</template>
<style lang="scss" scoped>
.is-pc {
.main1 {
.main1 {
padding: 70px 0 75px 0;
.main_con {
width: 1200px;
......@@ -71,8 +50,8 @@ const list = [
text-align: justify;
}
}
}
.main2 {
}
.main2 {
background: #f5f5f5;
padding: 70px 0 75px 0;
......@@ -95,10 +74,11 @@ const list = [
text-align: justify;
}
}
}
.main3 {
}
.main3 {
height: 308px;
background: url('https://webapp-pub.ezijing.com/project_online/fi/main2.png') no-repeat center;
background: url('https://webapp-pub.ezijing.com/project_online/fi/main2.png')
no-repeat center;
background-size: 100% 100%;
font-size: 24px;
font-weight: 400;
......@@ -111,52 +91,5 @@ const list = [
font-size: 30px;
font-weight: bold;
}
}
}
.is-h5 {
overflow-x: auto;
:deep(.swiper-slide) {
width: 6.1rem;
height: 6.44rem;
background: red;
border-radius: 12px;
}
.main_list {
padding: 0.1rem;
.list_img {
width: 5.7rem;
height: 3.4rem;
object-fit: cover;
}
.list_con {
width: 5.7rem;
font-size: 0.24rem;
font-weight: 400;
line-height: 2;
color: #333333;
margin-top: 0.37rem;
}
}
.main3 {
height: 3.97rem;
background: url('https://webapp-pub.ezijing.com/project_online/fi/main2.png') no-repeat center;
background-size: 100% 100%;
font-size: 0.26rem;
font-weight: 400;
line-height: 2;
color: #ffffff;
text-align: justify;
box-sizing: border-box;
padding: 0.4rem 0.4rem 0 0.4rem;
margin-top: 0.4rem;
span {
font-size: 0.15rem;
font-weight: bold;
}
}
}
</style>
......@@ -99,17 +99,13 @@ const handlePay = () => {
ElMessage.warning('请先勾选紫荆金保服务协议')
} else {
if (user.isLogin) {
console.log(mobile)
if (!mobile.value) {
console.log('111')
const params = {
payMode: payMode.value,
status: 'order'
}
emit('success', params)
} else {
console.log('222')
handleCreateOrder()
}
} else {
......@@ -138,10 +134,7 @@ const handlePrev = () => {
<div class="con_tit">课程信息确认</div>
<div class="con_pay">
<div class="pay_course">
<img
src="https://img1.baidu.com/it/u=3009731526,373851691&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"
alt=""
/>
<img :src="shopItem?.image_url" alt="" />
<div class="course_info">
<div class="info_tit">{{ shopItem?.title }}</div>
<div class="info_range">
......@@ -212,10 +205,7 @@ const handlePrev = () => {
<div class="nav_title">确认订单</div>
</div>
<div class="course_con">
<img
src="https://img1.baidu.com/it/u=3009731526,373851691&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"
alt=""
/>
<img :src="shopItem?.image_url" alt="" />
<div class="course_dec">
<div class="info_title">{{ shopItem?.title }}</div>
<div class="info_date">
......
......@@ -27,10 +27,7 @@ const handleDetail = (item: any) => {
:key="index"
@click="handleDetail(item)"
>
<img
src="https://img1.baidu.com/it/u=3009731526,373851691&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"
alt=""
/>
<img :src="item.image_url" alt="" />
<div class="list_info">
<div class="tit">{{ item.title }}</div>
<div class="hour">{{ item.course_hour }}</div>
......@@ -50,7 +47,10 @@ const handleDetail = (item: any) => {
<span class="custom-tree-node">
<span class="label">{{ node.label }}</span>
<span class="icon">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/icon_jt.png" alt="" />
<img
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/icon_jt.png"
alt=""
/>
</span>
</span>
</template>
......@@ -62,8 +62,7 @@ const handleDetail = (item: any) => {
<style lang="scss" scoped>
.course_info {
.course_info {
margin-top: 0.3rem;
.info_tit {
......@@ -81,17 +80,15 @@ const handleDetail = (item: any) => {
border: 1px solid #fff5e1;
border-radius: 15px;
margin-top: 0.2rem;
.custom-tree-node{
.label{
.custom-tree-node {
.label {
width: 5rem;
display: inline-block;
}
.icon{
img{
height:0.09rem;
.icon {
img {
height: 0.09rem;
}
}
}
......@@ -132,25 +129,25 @@ const handleDetail = (item: any) => {
}
}
}
}
}
:deep(.el-tree-node__content){
:deep(.el-tree-node__content) {
height: 0.6rem;
margin-bottom: 0.2rem;
border-radius: 10px;
background: #f5f8fb;
}
}
:deep(.el-icon svg) {
:deep(.el-icon svg) {
display: none;
}
:deep(.el-tree-node__label) {
}
:deep(.el-tree-node__label) {
font-size: 0.24rem;
font-weight: 400;
line-height: 0.32rem;
color: #333333;
}
:deep(.el-tree-node__children) {
}
:deep(.el-tree-node__children) {
.el-tree-node__content {
background: #ffffff !important;
border-bottom: 0.01rem solid #f4f4f4;
......@@ -166,6 +163,5 @@ const handleDetail = (item: any) => {
.icon {
display: none;
}
}
}
</style>
\ No newline at end of file
......@@ -27,10 +27,7 @@ const handleDetail = (item: any) => {
:key="index"
@click="handleDetail(item)"
>
<img
src="https://img1.baidu.com/it/u=3009731526,373851691&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"
alt=""
/>
<img :src="item.image_url" alt="" />
<div class="list_info">
<div class="tit">{{ item.title }}</div>
<div class="hour">{{ item.course_hour }}</div>
......@@ -50,7 +47,10 @@ const handleDetail = (item: any) => {
<span class="custom-tree-node">
<span class="label">{{ node.label }}</span>
<span style="margin-left: 205px" class="icon">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/icon_jt.png" alt="" />
<img
src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project_online/fi/icon_jt.png"
alt=""
/>
</span>
</span>
</template>
......@@ -62,10 +62,10 @@ const handleDetail = (item: any) => {
<style lang="scss" scoped>
.course_info1 {
.course_info1 {
margin-top: 40px;
}
.course_info {
}
.course_info {
.info_tit {
font-size: 18px;
font-weight: 500;
......@@ -97,9 +97,10 @@ const handleDetail = (item: any) => {
font-weight: 400;
line-height: 32px;
color: #333333;
.custom-tree-node{
.label{
width: 403px; display: inline-block;
.custom-tree-node {
.label {
width: 403px;
display: inline-block;
}
}
......@@ -137,25 +138,25 @@ const handleDetail = (item: any) => {
}
}
}
}
}
:deep(.el-tree-node__content){
:deep(.el-tree-node__content) {
height: 50px;
margin-bottom: 16px;
border-radius: 10px;
background: #f5f8fb;
}
}
:deep(.el-icon svg) {
:deep(.el-icon svg) {
display: none;
}
:deep(.el-tree-node__label) {
}
:deep(.el-tree-node__label) {
font-size: 16px;
font-weight: 400;
line-height: 32px;
color: #333333;
}
:deep(.el-tree-node__children) {
}
:deep(.el-tree-node__children) {
.el-tree-node__content {
background: #ffffff !important;
border-bottom: 1px solid #f4f4f4;
......@@ -171,12 +172,11 @@ const handleDetail = (item: any) => {
.icon {
display: none;
}
}
.is-h5{
.info_con1{
.custom-tree-node{
}
.is-h5 {
.info_con1 {
.custom-tree-node {
}
}
}
......
<script lang="ts" setup>
import { useDevice } from '@/composables/useDevice'
import { useUserStore } from '@/stores/user'
const user = useUserStore()
const { mobile } = useDevice()
const router = useRouter()
const props = defineProps({
payStatus:{
type:String
payStatus: {
type: String
},
shopItem:{
type:Object
shopItem: {
type: Object
}
})
const buyDialogVisible = ref(false)
const handleBuyCourse = () => {
console.log('999')
if (user.isLogin) {
if (props.payStatus === '4' || props.shopItem?.isBuy === true) {
window.open('https://paa-learning.ezijing.com')
} else {
......@@ -22,11 +26,21 @@ const handleBuyCourse = () => {
router.push(`/shop/pay/${props.shopItem?.id}`)
}
}
} else {
window.location.href = `${
import.meta.env.VITE_LOGIN_URL
}?rd=${encodeURIComponent(location.href)}`
}
}
</script>
<template>
<div class="detail_footer">
<div class="left_status" v-if="payStatus === '4' ||shopItem?.isBuy === true">已购买</div>
<div
class="left_status"
v-if="payStatus === '4' || shopItem?.isBuy === true"
>
已购买
</div>
<template v-else>
<div class="footer_left">
<div class="left_tit">全部课程价格</div>
......@@ -34,29 +48,33 @@ const handleBuyCourse = () => {
</div>
<div class="footer_price" v-if="!mobile">
<div class="price_icon">¥</div>
<div class="price_price">{{shopItem?.price }}</div>
<div class="price_price">{{ shopItem?.price }}</div>
</div>
</template>
<div v-if="!mobile">
<div class="footer_btn" @click="handleBuyCourse">
{{ payStatus === '4' ||shopItem?.isBuy === true ? '立即学习' : '立即购买' }}
{{
payStatus === '4' || shopItem?.isBuy === true
? '立即学习'
: '立即购买'
}}
</div>
</div>
<div v-else>
<div class="footer_btn" @click="handleBuyCourse" v-if="payStatus === '4' ||shopItem?.isBuy === true">
<div class="btn_buy">
立即学习
<div
class="footer_btn"
@click="handleBuyCourse"
v-if="payStatus === '4' || shopItem?.isBuy === true"
>
<div class="btn_buy">立即学习</div>
</div>
</div>
<div class="footer_btn" @click="handleBuyCourse" v-else >
<div class="footer_btn" @click="handleBuyCourse" v-else>
<div class="footer_price">
<div class="price_icon">¥</div>
<div class="price_price">{{shopItem?.price }}</div>
</div>
<div class="btn_buy">
立即购买
<div class="price_price">{{ shopItem?.price }}</div>
</div>
<div class="btn_buy">立即购买</div>
</div>
</div>
</div>
......@@ -65,8 +83,8 @@ const handleBuyCourse = () => {
<style lang="scss" scoped>
.is-pc{
.detail_footer {
.is-pc {
.detail_footer {
width: 1200px;
height: 100px;
background: #ffffff;
......@@ -129,63 +147,63 @@ const handleBuyCourse = () => {
cursor: pointer;
}
}
}
.is-h5{
.detail_footer{
}
.is-h5 {
.detail_footer {
border-radius: 0.2rem 0.2rem 0 0;
background: #ffffff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.3rem;
.left_status{
.left_status {
font-size: 0.24rem;
font-weight: normal;
color: #666666;
}
.footer_left{
.left_tit{
.footer_left {
.left_tit {
font-size: 0.24rem;
color: #333333;
}
.left_desc{
.left_desc {
font-size: 0.22rem;
color: #999999;
}
.footer_price{
.footer_price {
display: none;
}
}
.footer_btn{
.footer_btn {
width: 4.08rem;
height:0.8rem;
background: linear-gradient(102deg, #F2CA8C 0%, #E69B1C 100%);
height: 0.8rem;
background: linear-gradient(102deg, #f2ca8c 0%, #e69b1c 100%);
border-radius: 0.4rem;
text-align: center;
line-height: 0.8rem;
color: #FFFFFF;
color: #ffffff;
display: flex;
justify-content: space-around;
.footer_price{
cursor: pointer;
.footer_price {
display: flex;
padding-left: 0.48rem;
margin-right: 0.18rem;
.price_icon{
.price_icon {
font-size: 0.24rem;
color:#ffffff;
margin-top:0.05rem;
color: #ffffff;
margin-top: 0.05rem;
}
.price_price{
.price_price {
font-size: 0.4rem;
}
}
.btn_buy{
.btn_buy {
font-size: 0.28rem;
color:#ffffff;
color: #ffffff;
cursor: pointer;
}
}
}
}
}
</style>
\ No newline at end of file
<script setup lang="ts">
import ContactDialog from '../components/ContactDialog.vue'
import { useDevice } from '@/composables/useDevice'
import { useUserStore } from '@/stores/user'
const { mobile } = useDevice()
const user = useUserStore()
const router = useRouter()
const buyDialogVisible = ref(false)
......@@ -17,6 +20,7 @@ const handleDatail = (item: any) => {
})
}
const handleBuy = (courseItem: any) => {
if (user.isLogin) {
if (courseItem?.isBuy === true) {
window.open('https://paa-learning.ezijing.com')
} else {
......@@ -26,7 +30,12 @@ const handleBuy = (courseItem: any) => {
router.push(`/shop/pay/${courseItem.id}`)
}
}
} else {
window.location.href = `${
import.meta.env.VITE_LOGIN_URL
}?rd=${encodeURIComponent(location.href)}`
}
}
</script>
<template>
......@@ -34,13 +43,7 @@ const handleBuy = (courseItem: any) => {
<div class="tab_con">
<div class="con_left" @click="handleDatail(courseItem?.id)">
<div class="left_img">
<img
:src="
courseItem?.image_url ||
'https://img1.baidu.com/it/u=3009731526,373851691&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500'
"
class="left_img"
/>
<img :src="courseItem?.image_url" class="left_img" />
</div>
<div class="left_type">{{ courseItem?.type }}</div>
</div>
......@@ -61,7 +64,13 @@ const handleBuy = (courseItem: any) => {
<div class="price_num">{{ courseItem?.price }}</div>
</div>
<div class="bottom_btn">
<div class="btn_detail" v-if="!mobile" @click="handleDatail(courseItem?.id)">查看详情</div>
<div
class="btn_detail"
v-if="!mobile"
@click="handleDatail(courseItem?.id)"
>
查看详情
</div>
<div class="btn_buy" @click="handleBuy(courseItem)">
{{ courseItem?.isBuy === true ? '立即学习' : '立即购买' }}
</div>
......@@ -280,7 +289,7 @@ const handleBuy = (courseItem: any) => {
.right_bottom {
display: flex;
justify-content: flex-end;
margin-top:0.24rem;
margin-top: 0.24rem;
.bottom_btn {
.btn_buy {
width: 1.3rem;
......
......@@ -2,6 +2,8 @@
import ShareDialog from './ShareDialog.vue'
import ContactDialog from '../components/ContactDialog.vue'
import { useDevice } from '@/composables/useDevice'
import { useUserStore } from '@/stores/user'
const user = useUserStore()
const { mobile } = useDevice()
const props = defineProps({
shopItem: {
......@@ -18,6 +20,7 @@ const handleShare = () => {
shareDialogVisible.value = true
}
const handleBuyCourse = () => {
if (user.isLogin) {
if (props.payStatus === '4' || props.shopItem?.isBuy === true) {
window.open('https://paa-learning.ezijing.com')
} else {
......@@ -27,6 +30,11 @@ const handleBuyCourse = () => {
router.push(`/shop/pay/${props.shopItem?.id}`)
}
}
} else {
window.location.href = `${
import.meta.env.VITE_LOGIN_URL
}?rd=${encodeURIComponent(location.href)}`
}
}
</script>
......@@ -48,7 +56,10 @@ const handleBuyCourse = () => {
</div>
<div class="con_share">
<div class="share_btn" @click="handleShare">
<img src="https://webapp-pub.ezijing.com/project_online/fi/icon_share.png" alt="" />
<img
src="https://webapp-pub.ezijing.com/project_online/fi/icon_share.png"
alt=""
/>
分享
</div>
</div>
......@@ -57,7 +68,12 @@ const handleBuyCourse = () => {
</div>
<div class="detail_buy">
<div class="buy_left">
<div class="left_status" v-if="payStatus === '4' || shopItem?.isBuy === true">已购买</div>
<div
class="left_status"
v-if="payStatus === '4' || shopItem?.isBuy === true"
>
已购买
</div>
<div class="left_price" v-else>
<div class="price_icon">¥</div>
<div class="price_num">{{ shopItem?.price }}</div>
......@@ -68,25 +84,33 @@ const handleBuyCourse = () => {
</div>
</div>
<div class="buy_right" @click="handleBuyCourse" v-if="!mobile">
{{ payStatus === '4' || shopItem?.isBuy === true ? '立即学习' : '立即购买' }}
{{
payStatus === '4' || shopItem?.isBuy === true ? '立即学习' : '立即购买'
}}
</div>
</div>
<div class="detail_info" v-if="mobile">
<div class="info_top">
<div class="top_icon">适用人群</div>
<div class="top_for">{{shopItem?.for_people}}</div>
<div class="top_for">{{ shopItem?.for_people }}</div>
</div>
<div class="info_tit">{{shopItem?.title}}</div>
<div class="info_tit">{{ shopItem?.title }}</div>
<div class="info_tips">{{ shopItem?.course_card }}</div>
<div class="info_time">
<div class="time_left">
<div class="left_tit">课程节数</div>
<div class="left_con"><span class="con_num">{{ shopItem?.course_chapter }}</span> <span class="con_txt"></span></div>
<div class="left_con">
<span class="con_num">{{ shopItem?.course_chapter }}</span>
<span class="con_txt"></span>
</div>
</div>
<div class="time_line"></div>
<div class="time_left">
<div class="left_tit">总课时</div>
<div class="left_con"><span class="con_num">{{ shopItem?.course_total_hour }}</span> <span class="con_txt">小时</span></div>
<div class="left_con">
<span class="con_num">{{ shopItem?.course_total_hour }}</span>
<span class="con_txt">小时</span>
</div>
</div>
</div>
</div>
......
......@@ -14,7 +14,6 @@ defineProps({
})
const swiper1 = ref(null)
function prev(swiper) {
console.log(swiper, '111')
swiper?.slidePrev()
}
function next(swiper) {
......@@ -38,7 +37,7 @@ const handleDetail = (item) => {
:spaceBetween="20"
:slidePreview="1"
:modules="[Navigation, Grid]"
@swiper="swiper => (swiper1 = swiper)"
@swiper="(swiper) => (swiper1 = swiper)"
>
<SwiperSlide
v-for="(item, index) in shopRelatedList"
......@@ -46,13 +45,7 @@ const handleDetail = (item) => {
class="course-item"
@click="handleDetail(item)"
>
<img
:src="
item.avatar ||
'https://img1.baidu.com/it/u=3009731526,373851691&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500'
"
class="img"
/>
<img :src="item.image_url" class="img" />
<div class="item_right">
<div class="right_name">{{ item.title }}</div>
<div class="right_price">
......@@ -68,17 +61,13 @@ const handleDetail = (item) => {
</template>
</div>
<div v-else>
<div class="course-item" v-for="(item, index) in shopRelatedList"
<div
class="course-item"
v-for="(item, index) in shopRelatedList"
:key="index"
@click="handleDetail(item)"
>
<img
:src="
item.avatar ||
'https://img1.baidu.com/it/u=3009731526,373851691&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500'
"
class="img"
/>
<img :src="item.image_url" class="img" />
<div class="item_right">
<div class="right_name">{{ item.title }}</div>
<div class="right_price">
......@@ -94,9 +83,8 @@ const handleDetail = (item) => {
</template>
<style lang="scss" scoped>
.is-pc{
.teacher_list {
.is-pc {
.teacher_list {
margin-top: 20px;
.list_con {
width: 396px;
......@@ -165,30 +153,30 @@ const handleDetail = (item) => {
}
}
}
}
}
}
.is-h5{
.teacher_list{
padding:0.32rem 0.2rem;
.is-h5 {
.teacher_list {
padding: 0.32rem 0.2rem;
margin: 0.3rem;
background: #FFFFFF;
background: #ffffff;
border-radius: 0.12rem;
.list_con{
.con_tit{
.list_con {
.con_tit {
font-size: 0.28rem;
color: #333333;
font-weight: 500;
}
.con_line{
.con_line {
display: none;
}
}
.con_course{
.con_course {
margin-top: 0.2rem;
background: #F4F8FB;
background: #f4f8fb;
padding: 0.2rem 0.24rem;
border-radius: 0.16rem;
.course-item:last-child{
.course-item:last-child {
border: none;
}
.course-item {
......@@ -196,8 +184,8 @@ const handleDetail = (item) => {
display: flex;
align-items: center;
cursor: pointer;
border-bottom: 0.01rem solid #E5E5E5;
padding:0.2rem 0;
border-bottom: 0.01rem solid #e5e5e5;
padding: 0.2rem 0;
.img {
width: 2.2rem;
height: 1.4rem;
......@@ -221,23 +209,20 @@ const handleDetail = (item) => {
font-size: 0.2rem;
font-weight: 500;
line-height: 0.34rem;
color: #E5A12F;
color: #e5a12f;
}
.price_num {
font-size: 0.24rem;
font-weight: normal;
line-height: 0.34rem;
color: #E5A12F;
color: #e5a12f;
}
}
}
}
}
}
}
}
.my-swiper {
--swiper-navigation-size: 14px;
--swiper-navigation-color: #333333;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论