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

Merge branch 'dev'

...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
"$ref": true, "$ref": true,
"$shallowRef": true, "$shallowRef": true,
"$toRef": true, "$toRef": true,
"EffectScope": true,
"asyncComputed": true, "asyncComputed": true,
"autoResetRef": true, "autoResetRef": true,
"computed": true, "computed": true,
...@@ -31,6 +30,7 @@ ...@@ -31,6 +30,7 @@
"defineComponent": true, "defineComponent": true,
"eagerComputed": true, "eagerComputed": true,
"effectScope": true, "effectScope": true,
"EffectScope": true,
"extendRef": true, "extendRef": true,
"getCurrentInstance": true, "getCurrentInstance": true,
"getCurrentScope": true, "getCurrentScope": true,
...@@ -38,8 +38,6 @@ ...@@ -38,8 +38,6 @@
"ignorableWatch": true, "ignorableWatch": true,
"inject": true, "inject": true,
"isDefined": true, "isDefined": true,
"isProxy": true,
"isReactive": true,
"isReadonly": true, "isReadonly": true,
"isRef": true, "isRef": true,
"logicAnd": true, "logicAnd": true,
...@@ -125,8 +123,8 @@ ...@@ -125,8 +123,8 @@
"useDark": true, "useDark": true,
"useDateFormat": true, "useDateFormat": true,
"useDebounce": true, "useDebounce": true,
"useDebounceFn": true,
"useDebouncedRefHistory": true, "useDebouncedRefHistory": true,
"useDebounceFn": true,
"useDeviceMotion": true, "useDeviceMotion": true,
"useDeviceOrientation": true, "useDeviceOrientation": true,
"useDevicePixelRatio": true, "useDevicePixelRatio": true,
...@@ -207,8 +205,8 @@ ...@@ -207,8 +205,8 @@
"useTemplateRefsList": true, "useTemplateRefsList": true,
"useTextSelection": true, "useTextSelection": true,
"useThrottle": true, "useThrottle": true,
"useThrottleFn": true,
"useThrottledRefHistory": true, "useThrottledRefHistory": true,
"useThrottleFn": true,
"useTimeAgo": true, "useTimeAgo": true,
"useTimeout": true, "useTimeout": true,
"useTimeoutFn": true, "useTimeoutFn": true,
...@@ -219,10 +217,10 @@ ...@@ -219,10 +217,10 @@
"useTransition": true, "useTransition": true,
"useUrlSearchParams": true, "useUrlSearchParams": true,
"useUserMedia": true, "useUserMedia": true,
"useVModel": true,
"useVModels": true,
"useVibrate": true, "useVibrate": true,
"useVirtualList": true, "useVirtualList": true,
"useVModel": true,
"useVModels": true,
"useWakeLock": true, "useWakeLock": true,
"useWebNotification": true, "useWebNotification": true,
"useWebSocket": true, "useWebSocket": true,
...@@ -238,8 +236,6 @@ ...@@ -238,8 +236,6 @@
"watchIgnorable": true, "watchIgnorable": true,
"watchOnce": true, "watchOnce": true,
"watchPausable": true, "watchPausable": true,
"watchPostEffect": true,
"watchSyncEffect": true,
"watchThrottled": true, "watchThrottled": true,
"watchWithFilter": true, "watchWithFilter": true,
"whenever": true "whenever": true
......
// Generated by 'unplugin-auto-import' // Generated by 'unplugin-auto-import'
export {} // We suggest you to commit this file into source control
declare global { declare global {
const $$: typeof import('vue/macros')['$$']
const $: typeof import('vue/macros')['$'] const $: typeof import('vue/macros')['$']
const $$: typeof import('vue/macros')['$$']
const $computed: typeof import('vue/macros')['$computed'] const $computed: typeof import('vue/macros')['$computed']
const $customRef: typeof import('vue/macros')['$customRef'] const $customRef: typeof import('vue/macros')['$customRef']
const $ref: typeof import('vue/macros')['$ref'] const $ref: typeof import('vue/macros')['$ref']
const $shallowRef: typeof import('vue/macros')['$shallowRef'] const $shallowRef: typeof import('vue/macros')['$shallowRef']
const $toRef: typeof import('vue/macros')['$toRef'] const $toRef: typeof import('vue/macros')['$toRef']
const EffectScope: typeof import('vue')['EffectScope']
const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
const computed: typeof import('vue')['computed'] const computed: typeof import('vue')['computed']
...@@ -32,6 +31,7 @@ declare global { ...@@ -32,6 +31,7 @@ declare global {
const defineComponent: typeof import('vue')['defineComponent'] const defineComponent: typeof import('vue')['defineComponent']
const eagerComputed: typeof import('@vueuse/core')['eagerComputed'] const eagerComputed: typeof import('@vueuse/core')['eagerComputed']
const effectScope: typeof import('vue')['effectScope'] const effectScope: typeof import('vue')['effectScope']
const EffectScope: typeof import('vue')['EffectScope']
const extendRef: typeof import('@vueuse/core')['extendRef'] const extendRef: typeof import('@vueuse/core')['extendRef']
const getCurrentInstance: typeof import('vue')['getCurrentInstance'] const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope'] const getCurrentScope: typeof import('vue')['getCurrentScope']
...@@ -39,8 +39,6 @@ declare global { ...@@ -39,8 +39,6 @@ declare global {
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
const inject: typeof import('vue')['inject'] const inject: typeof import('vue')['inject']
const isDefined: typeof import('@vueuse/core')['isDefined'] const isDefined: typeof import('@vueuse/core')['isDefined']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly'] const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef'] const isRef: typeof import('vue')['isRef']
const logicAnd: typeof import('@vueuse/core')['logicAnd'] const logicAnd: typeof import('@vueuse/core')['logicAnd']
...@@ -126,8 +124,8 @@ declare global { ...@@ -126,8 +124,8 @@ declare global {
const useDark: typeof import('@vueuse/core')['useDark'] const useDark: typeof import('@vueuse/core')['useDark']
const useDateFormat: typeof import('@vueuse/core')['useDateFormat'] const useDateFormat: typeof import('@vueuse/core')['useDateFormat']
const useDebounce: typeof import('@vueuse/core')['useDebounce'] const useDebounce: typeof import('@vueuse/core')['useDebounce']
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory'] const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory']
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion'] const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion']
const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation'] const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation']
const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio'] const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio']
...@@ -208,8 +206,8 @@ declare global { ...@@ -208,8 +206,8 @@ declare global {
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList'] const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
const useTextSelection: typeof import('@vueuse/core')['useTextSelection'] const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
const useThrottle: typeof import('@vueuse/core')['useThrottle'] const useThrottle: typeof import('@vueuse/core')['useThrottle']
const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn']
const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory'] const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory']
const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn']
const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo'] const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo']
const useTimeout: typeof import('@vueuse/core')['useTimeout'] const useTimeout: typeof import('@vueuse/core')['useTimeout']
const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn'] const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn']
...@@ -220,10 +218,10 @@ declare global { ...@@ -220,10 +218,10 @@ declare global {
const useTransition: typeof import('@vueuse/core')['useTransition'] const useTransition: typeof import('@vueuse/core')['useTransition']
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams'] const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
const useUserMedia: typeof import('@vueuse/core')['useUserMedia'] const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
const useVModel: typeof import('@vueuse/core')['useVModel']
const useVModels: typeof import('@vueuse/core')['useVModels']
const useVibrate: typeof import('@vueuse/core')['useVibrate'] const useVibrate: typeof import('@vueuse/core')['useVibrate']
const useVirtualList: typeof import('@vueuse/core')['useVirtualList'] const useVirtualList: typeof import('@vueuse/core')['useVirtualList']
const useVModel: typeof import('@vueuse/core')['useVModel']
const useVModels: typeof import('@vueuse/core')['useVModels']
const useWakeLock: typeof import('@vueuse/core')['useWakeLock'] const useWakeLock: typeof import('@vueuse/core')['useWakeLock']
const useWebNotification: typeof import('@vueuse/core')['useWebNotification'] const useWebNotification: typeof import('@vueuse/core')['useWebNotification']
const useWebSocket: typeof import('@vueuse/core')['useWebSocket'] const useWebSocket: typeof import('@vueuse/core')['useWebSocket']
...@@ -239,9 +237,8 @@ declare global { ...@@ -239,9 +237,8 @@ declare global {
const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable'] const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable']
const watchOnce: typeof import('@vueuse/core')['watchOnce'] const watchOnce: typeof import('@vueuse/core')['watchOnce']
const watchPausable: typeof import('@vueuse/core')['watchPausable'] const watchPausable: typeof import('@vueuse/core')['watchPausable']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
const watchThrottled: typeof import('@vueuse/core')['watchThrottled'] const watchThrottled: typeof import('@vueuse/core')['watchThrottled']
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter'] const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
const whenever: typeof import('@vueuse/core')['whenever'] const whenever: typeof import('@vueuse/core')['whenever']
} }
export {}
...@@ -32,3 +32,11 @@ export function uploadFile(data: object) { ...@@ -32,3 +32,11 @@ export function uploadFile(data: object) {
export function getVideoView(params: { id: string }) { export function getVideoView(params: { id: string }) {
return httpRequest.get('/api/psp/v1/admission/video-view', { params }) return httpRequest.get('/api/psp/v1/admission/video-view', { params })
} }
// 获取推荐课程列表
export function getRecommendCourse(params?: { page_size?: string; page?: string }) {
return httpRequest.get('/api/psp/v1/recommend-course/list', { params })
}
// 获取导师列表
export function getTeacherList(params?: { page_size?: string; page?: string; type?: string }) {
return httpRequest.get('/api/psp/v1/lecturer/list', { params })
}
...@@ -42,11 +42,11 @@ const onClick = (data: IVideoItem) => { ...@@ -42,11 +42,11 @@ const onClick = (data: IVideoItem) => {
<style lang="scss"> <style lang="scss">
.video-item { .video-item {
width: 2rem; width: 2.2rem;
cursor: pointer; cursor: pointer;
img { img {
width: 2rem; width: 2.2rem;
height: 1.9rem; height: 1.6rem;
border-radius: 0.1rem; border-radius: 0.1rem;
overflow: hidden; overflow: hidden;
object-fit: cover; object-fit: cover;
......
...@@ -21,6 +21,9 @@ defineProps<{ title?: string }>() ...@@ -21,6 +21,9 @@ defineProps<{ title?: string }>()
<style lang="scss"> <style lang="scss">
.app-card { .app-card {
margin: 0.3rem 0; margin: 0.3rem 0;
padding: 0.2rem;
background: #ffffff;
border-radius: 0.2rem;
} }
.app-card-hd { .app-card-hd {
display: flex; display: flex;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<template> <template>
<header class="app-header"> <header class="app-header">
<div class="app-header__logo"> <div class="app-header__logo">
<router-link to="/"><img src="https://webapp-pub.ezijing.com/project/prp-h5/logo.png" /></router-link> <router-link to="/"><img src="https://webapp-pub.ezijing.com/project/prp-h5/logo1.png" /></router-link>
</div> </div>
<ul class="app-header-right"> <ul class="app-header-right">
<li> <li>
......
...@@ -14,7 +14,8 @@ import AppHeader from './Header.vue' ...@@ -14,7 +14,8 @@ import AppHeader from './Header.vue'
min-height: 100vh; min-height: 100vh;
max-width: 750px; max-width: 750px;
margin: 0 auto; margin: 0 auto;
background: #f3f4f8 url(https://webapp-pub.ezijing.com/project/prp-h5/bg.png) no-repeat; // background: #f3f4f8 url(https://webapp-pub.ezijing.com/project/prp-h5/bg.png) no-repeat;
background: #f7f7f7;
background-size: 100% auto; background-size: 100% auto;
padding: 0 0.3rem; padding: 0 0.3rem;
box-sizing: border-box; box-sizing: border-box;
......
...@@ -3,7 +3,7 @@ import { ref, onMounted } from 'vue' ...@@ -3,7 +3,7 @@ import { ref, onMounted } from 'vue'
import { getDocView } from '../api' import { getDocView } from '../api'
import DocView from '@/components/DocView.vue' import DocView from '@/components/DocView.vue'
const props = defineProps<{ id: string }>() const props = defineProps<{ id: string }>()
const route = useRoute()
const data = ref() const data = ref()
function fetchDocView() { function fetchDocView() {
getDocView({ id: props.id }).then(res => { getDocView({ id: props.id }).then(res => {
...@@ -11,6 +11,7 @@ function fetchDocView() { ...@@ -11,6 +11,7 @@ function fetchDocView() {
}) })
} }
onMounted(() => { onMounted(() => {
console.log(route.query, '111')
fetchDocView() fetchDocView()
}) })
</script> </script>
......
import type { RouteRecordRaw } from 'vue-router'
import AppLayout from '@/components/layout/Index.vue'
export const routes: Array<RouteRecordRaw> = [
{
path: '/course',
component: AppLayout,
children: [{ path: '', component: () => import('./views/Index.vue') }]
}
]
<script setup lang="ts">
import { getRecommendCourse } from '@/api/base'
import type { IRecommendCourse } from '@/types'
import num from '@/utils/numTo'
interface IRecommendCourseAllList {
loading: boolean
page: number
total: number
list: IRecommendCourse[]
}
const courseList = reactive<IRecommendCourseAllList>({ loading: false, page: 1, total: 0, list: [] })
const handleGetCourseList = () => {
const params: any = { page_size: 10, page: courseList.page }
courseList.loading = true
getRecommendCourse(params)
.then(res => {
const { total, list } = res.data
courseList.total = total
courseList.list = courseList.list.concat(list)
if (courseList.list.length <= total) {
courseList.page++
}
})
.finally(() => {
courseList.loading = false
})
}
// 滚动加载
const el = ref<HTMLElement>()
useInfiniteScroll(
document,
() => {
// load more
!courseList.loading && handleGetCourseList()
},
{ distance: 10 }
)
onMounted(() => {
handleGetCourseList()
})
const handleClickItem = (item: any) => {
if (item.url) {
location.href = item.url
}
}
</script>
<template>
<img src="https://webapp-pub.ezijing.com/project/prp-h5/course_banner.png" style="width: 100%" />
<AppCard title="推荐课程">
<div ref="el">
<div class="list_item" v-for="(item, index) in courseList.list" :key="index" @click="handleClickItem(item)">
<img :src="item.cover" class="item_img" />
<div class="item_right">
<div class="right_tit">{{ item.name }}</div>
<div class="right_bottom">
<div class="views">{{ num(item.pv) }}播放</div>
<div class="is_free" :class="item.is_free === '1' ? 'free' : 'unfree'">
{{ item.is_free_name }}
</div>
</div>
</div>
</div>
</div>
</AppCard>
</template>
<style lang="scss" scoped>
img {
width: 6.9rem;
}
.list_item:last-child {
border-bottom: none;
}
.list_item {
display: flex;
margin-bottom: 0.2rem;
padding-bottom: 0.2rem;
border-bottom: 1px solid #e0e0e0;
.item_img {
width: 2.2rem;
height: 1.4rem;
object-fit: cover;
border-radius: 0.1rem;
}
.item_right {
margin-left: 0.21rem;
padding-top: 0.17rem;
display: flex;
flex-direction: column;
justify-content: space-between;
box-sizing: border-box;
.right_tit {
font-size: 0.28rem;
font-weight: 500;
line-height: 0.36rem;
color: #333333;
}
.right_bottom {
margin-top: 0.21rem;
display: flex;
justify-content: space-between;
align-items: center;
width: 4.09rem;
.views {
font-size: 0.22rem;
font-weight: 400;
color: #999999;
}
.is_free {
font-size: 0.22rem;
font-weight: 400;
line-height: 30px;
padding-right: 0.3rem;
}
.free {
color: #4ad1a3;
}
.unfree {
color: #e9a724;
}
}
}
}
</style>
<script setup lang="ts">
// import { useRouter } from 'vue-router'
import { Notify } from 'vant'
// import { Swiper, SwiperSlide } from 'swiper/vue'
// import 'swiper/css'
// import VideoItem from '@/components/VideoItem.vue'
// import type { IDocItem, IVideoItem } from '../types'
// defineProps<{ docs: IDocItem[]; videos: IVideoItem[] }>()
// const router = useRouter()
const docs = [
{
title: 'PRP认证培训',
url: 'https://prp.ezijing.com/'
},
{
title: 'PAA系列认证',
url: 'https://paa.ezijing.com/'
},
{
title: '新型人才培育',
url: ''
},
{
title: '更多FI项目',
url: 'https://fi.ezijing.com/'
}
]
function handleViewDoc(data: any) {
// window.open(data.url)
if (data.url) {
location.href = data.url
} else {
Notify({ type: 'primary', message: '尚未开放' })
}
}
// function showTips() {
// Notify({ type: 'primary', message: '尚未开放' })
// }
</script>
<template>
<AppCard id="admission">
<div class="admission">
<div class="admission-right">
<div class="box box-test">
<h2>免费课程</h2>
<p class="t1">实战精华等你来看</p>
<p class="t2"><a href="https://fi.ezijing.com/shop/?activeIndex=2&type=free_course">去看看 ></a></p>
</div>
<div class="box box-notice">
<h2>系统小课</h2>
<p class="t1">专业思维 赢战未来</p>
<p class="t2"><a href="https://fi.ezijing.com/shop/?activeIndex=3&type=system_course">去看看 ></a></p>
</div>
</div>
<div class="admission-left">
<h2>认证课程包</h2>
<!-- <div class="box"> -->
<ul>
<li v-for="(item, index) in docs" :key="index" @click="handleViewDoc(item)">
<p>{{ item.title }}</p>
<!-- <span>{{ item.pv }}</span> -->
<van-icon name="arrow" />
</li>
</ul>
<!-- </div> -->
</div>
</div>
<!-- <div class="admission-box" v-if="videos.length">
<h2>免费视频观看</h2>
<swiper slides-per-view="auto" :space-between="10">
<swiper-slide v-for="item in videos" :key="item.id" class="video-swiper-slide">
<VideoItem :data="item"></VideoItem>
</swiper-slide>
</swiper>
</div> -->
</AppCard>
</template>
<style lang="scss" scoped>
.admission {
display: flex;
justify-content: space-between;
}
.admission-left {
padding: 0.1rem;
width: 3.33rem;
margin-left: 0.24rem;
background: url(https://webapp-pub.ezijing.com/project/prp-h5/certifation_course_bg.png) no-repeat;
background-size: contain;
box-sizing: border-box;
h2 {
margin: 0.1rem 0.1rem 0.14rem;
font-size: 0.28rem;
font-weight: 500;
line-height: 1.5;
color: #fff;
}
// .box {
// width: 3.13rem;
// height: 3.43rem;
// background: #fff url(https://webapp-pub.ezijing.com/project/prp-h5/query_bg_1.png) no-repeat center bottom;
// background-size: 100% auto;
// border-radius: 0.1rem;
ul {
overflow: hidden;
}
li {
margin: 0.2rem 0.14rem 0;
display: flex;
align-items: center;
font-size: 0.24rem;
color: #333333;
cursor: pointer;
background: #ffffff;
padding: 0.14rem 0.2rem;
border-radius: 0.3rem;
cursor: pointer;
}
p {
flex: 1;
font-size: 0.24rem;
color: #333333;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
span {
min-width: 0.44rem;
font-size: 0.2rem;
color: #c6c6c6;
}
}
// }
.admission-right {
flex: 1;
.box {
padding: 0.22rem 0.2rem;
// width: 3.33rem;
height: 2.01rem;
background: #fff;
border-radius: 0.2rem;
box-sizing: border-box;
cursor: pointer;
h2 {
font-size: 0.28rem;
line-height: 1.5;
font-weight: 500;
color: #333;
}
.t1 {
margin-top: 0.14rem;
font-size: 0.24rem;
font-weight: 400;
color: #666666;
}
.t2 {
margin-top: 0.35rem;
font-size: 0.24rem;
font-weight: 400;
color: #e6a522;
}
}
.box + .box {
margin-top: 0.2rem;
}
.box-test {
background: #ffffff url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/project/prp-h5/free_course_logo.png)
no-repeat right bottom;
background-size: 1.7rem 1.36rem;
}
.box-notice {
background: #fff5e3 url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/project/prp-h5/system_course_logo.png)
no-repeat right bottom;
background-size: 1.7rem 1.36rem;
}
}
</style>
<script setup lang="ts"></script>
<template>
<div class="output_main">
<AppCard title="知识输出者" id="team">
<template #header-aside>
<div class="more">
<router-link to="/qa">知识IP践行 <van-icon name="arrow" /></router-link>
</div>
</template>
<div class="output_banner">
<a href="https://mp.weixin.qq.com/s/wUOtrmOttyNCyIecswqC4w" target="_blank">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project/prp-h5/output_banner.png" alt="" />
</a>
</div>
</AppCard>
</div>
<div class="input_main">
<AppCard title="知识输入者" id="team">
<template #header-aside>
<div class="more">
<router-link to="/learn/course">如何成为知识获得者 <van-icon name="arrow" /></router-link>
</div>
</template>
<div class="output_banner">
<a href="https://mp.weixin.qq.com/s/fDf4NpPZH4BNI_KEo" target="_blank">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project/prp-h5/input_banner.png" alt="" />
</a>
</div>
</AppCard>
</div>
</template>
<style lang="scss" scoped>
.output_main {
.app-card {
background: url('https://webapp-pub.oss-cn-beijing.aliyuncs.com/project/prp-h5/output_bg.png') no-repeat;
background-size: 100% 100%;
}
.app-card-hd {
margin-top: 0.2rem !important;
}
.more {
font-size: 0.24rem;
font-weight: 500;
color: #f39929;
}
.output_banner {
padding: 0.06rem;
img {
width: 100%;
-webkit-filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.1)); /*考虑浏览器兼容性:兼容 Chrome, Safari, Opera */
filter: drop-shadow(0px 5px 2px rgba(0, 0, 0, 0.1));
}
}
}
.input_main {
.app-card {
background: url('https://webapp-pub.oss-cn-beijing.aliyuncs.com/project/prp-h5/input_bg.png') no-repeat;
background-size: 100% 100%;
}
.more {
font-size: 0.24rem;
font-weight: 500;
color: #bc2d29;
}
.output_banner {
padding: 0.06rem;
img {
width: 100%;
-webkit-filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.1)); /*考虑浏览器兼容性:兼容 Chrome, Safari, Opera */
filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.1));
}
}
}
</style>
...@@ -27,10 +27,16 @@ function showTips() { ...@@ -27,10 +27,16 @@ function showTips() {
<template> <template>
<AppCard title="学习地图" id="learning"> <AppCard title="学习地图" id="learning">
<template #header-aside> <!-- <template #header-aside>
<div class="button"><a href="https://mp.weixin.qq.com/s/EdS6wpcdL0IEMK11WQ1Oyg" target="_blank">去学习</a></div> <div class="button"><a href="https://mp.weixin.qq.com/s/EdS6wpcdL0IEMK11WQ1Oyg" target="_blank">去学习</a></div>
</template> </template> -->
<van-tabs v-model:active="active" shrink background="transparent" title-active-color="#033974" title-inactive-color="#4E4E4E" line-height="0"> <van-tabs
v-model:active="active"
shrink
background="transparent"
title-active-color="#E9A724"
title-inactive-color="#4E4E4E"
>
<van-tab title="课程导学"> <van-tab title="课程导学">
<div class="learn-box"> <div class="learn-box">
<LearningMapVideo></LearningMapVideo> <LearningMapVideo></LearningMapVideo>
...@@ -60,18 +66,18 @@ function showTips() { ...@@ -60,18 +66,18 @@ function showTips() {
</div> </div>
</van-tab> </van-tab>
</van-tabs> </van-tabs>
<div class="learn-banner"> <!-- <div class="learn-banner">
<router-link to="/learn/course"> <router-link to="/learn/course">
<img src="https://webapp-pub.ezijing.com/project/prp-h5/learning_map_banner.png" /> <img src="https://webapp-pub.ezijing.com/project/prp-h5/learning_map_banner.png" />
</router-link> </router-link>
</div> </div> -->
</AppCard> </AppCard>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.learn-box { .learn-box {
height: 3.1rem; height: 3.1rem;
padding: 0.3rem; padding: 0.3rem 0;
background: #fff; background: #fff;
border-radius: 0.2rem; border-radius: 0.2rem;
overflow: hidden; overflow: hidden;
...@@ -126,7 +132,8 @@ function showTips() { ...@@ -126,7 +132,8 @@ function showTips() {
// 学前测评 // 学前测评
.learn-test { .learn-test {
background: #fff url(https://webapp-pub.ezijing.com/project/prp-h5/learning_map_test.png) no-repeat right 0.2rem bottom 0.5rem; background: #fff url(https://webapp-pub.ezijing.com/project/prp-h5/learning_map_test.png) no-repeat right 0.2rem
bottom 0.5rem;
background-size: 2.08rem; background-size: 2.08rem;
h2 { h2 {
margin-top: 0.2rem; margin-top: 0.2rem;
...@@ -158,5 +165,25 @@ function showTips() { ...@@ -158,5 +165,25 @@ function showTips() {
} }
.learn-course { .learn-course {
background-color: #f4e6d3; background-color: #f4e6d3;
padding: 0.3rem 0 0 0.3rem;
margin-top: 0.2rem;
}
:deep(.van-tabs__line) {
background: #e9a724;
width: 55px;
}
:deep(.van-tabs) {
margin-left: -0.05rem;
}
:deep(.van-tabs__wrap) {
margin-left: -0.2rem;
}
.app-card-hd {
display: flex;
align-items: flex-start;
justify-content: flex-start;
}
:deep(.van-tabs__content) {
margin-right: -0.2rem;
} }
</style> </style>
...@@ -28,6 +28,7 @@ onMounted(() => { ...@@ -28,6 +28,7 @@ onMounted(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
.video-swiper-slide { .video-swiper-slide {
width: 2rem; width: 2.2rem;
} }
</style> </style>
<script setup lang="ts">
// const newsList = [
// { tit: '111111111111111111111111111111111111111111111111111111111111111111' },
// { tit: '222' },
// { tit: '333' },
// { tit: '444' }
// ]
import type { INews } from '../types'
const router = useRouter()
defineProps<{ docs: INews[] }>()
const handleViewNews = (item: INews) => {
if (item.desc_type === '2') {
location.href = item.url
} else {
router.push('/news/doc/' + item.id)
}
}
</script>
<template>
<div>
<van-swipe vertical :autoplay="3000">
<van-swipe-item v-for="(item, index) in docs" :key="index" @click="handleViewNews(item)">
<div class="item_news">
<div class="news_tips"></div>
<div class="news_tit">{{ item.title }}</div>
<div class="news_arrow">
<van-icon name="arrow" />
</div>
</div>
</van-swipe-item>
</van-swipe>
</div>
</template>
<style lang="scss" scoped>
:deep(.van-swipe) {
width: 6.9rem;
height: 0.84rem;
background: #ffffff;
border-radius: 0.16rem;
}
:deep(.van-swipe-item) {
display: flex;
align-items: center;
justify-content: space-between;
padding-left: 0.2rem;
cursor: pointer;
}
:deep(.van-swipe__indicator) {
display: none;
}
.item_news {
display: flex;
align-items: center;
.news_tips {
width: 0.33rem;
height: 0.33rem;
background: linear-gradient(313deg, #ef9446 0%, #de3a39 100%);
border-radius: 0.06rem;
font-size: 0.22rem;
font-weight: 400;
line-height: 0.33rem;
color: #ffffff;
text-align: center;
}
.news_tit {
width: 4.8rem;
margin-left: 0.12rem;
font-size: 0.24rem;
font-weight: 400;
color: #4e4e4e;
line-height: 0.33rem;
overflow: hidden;
text-overflow: ellipsis;
}
.news_arrow {
margin-left: 1.1rem;
}
}
</style>
...@@ -2,39 +2,31 @@ ...@@ -2,39 +2,31 @@
<AppCard title="权益查看" id="query"> <AppCard title="权益查看" id="query">
<div class="query"> <div class="query">
<div class="query-left"> <div class="query-left">
<div class="box box-avatar"> <div class="box">
<router-link to="/query?active=2"> <router-link to="/query?active=1">
<h2> <h2><img src="https://webapp-pub.ezijing.com/project/prp-h5/query_icon_5.png" />证书查询</h2>
<img <p class="t1">考试通过后可查看</p>
src="https://webapp-pub.ezijing.com/project/prp-h5/query_icon_1.png" </router-link>
style="width: 0.48rem" </div>
/>持证人展示 <div class="box box1">
</h2> <router-link to="/query?active=0">
<p class="t1">先人一步 胜人一筹</p> <h2><img src="https://webapp-pub.ezijing.com/project/prp-h5/query_icon_6.png" />名片展示</h2>
<p class="t2">去看看</p> <p class="t1">持证人专属</p>
</router-link> </router-link>
</div> </div>
</div> </div>
<div class="query-right"> <div class="query-right">
<div class="box"> <div class="box">
<router-link to="/query?active=1"> <router-link to="/query?active=2">
<h2> <h2><img src="https://webapp-pub.ezijing.com/project/prp-h5/query_icon_7.png" />持证人展示</h2>
<img
src="https://webapp-pub.ezijing.com/project/prp-h5/query_icon_2.png"
style="width: 0.38rem"
/>证书查询
</h2>
<p class="t1">考试通过后可查看</p> <p class="t1">考试通过后可查看</p>
<!-- <p class="t2">去看看</p> -->
</router-link> </router-link>
</div> </div>
<div class="box">
<div class="box box1">
<router-link to="/query?active=0"> <router-link to="/query?active=0">
<h2> <h2><img src="https://webapp-pub.ezijing.com/project/prp-h5/query_icon_8.png" />考试系统</h2>
<img
src="https://webapp-pub.ezijing.com/project/prp-h5/query_icon_3.png"
style="width: 0.48rem"
/>名片展示
</h2>
<p class="t1">持证人专属</p> <p class="t1">持证人专属</p>
</router-link> </router-link>
</div> </div>
...@@ -48,9 +40,9 @@ ...@@ -48,9 +40,9 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
.box { .box {
padding: 0.22rem 0.2rem; padding: 0.2rem;
width: 3.33rem; width: 3.15rem;
height: 1.56rem; height: 1.42rem;
background: #fff url(https://webapp-pub.ezijing.com/project/prp-h5/query_bg_2.png) no-repeat; background: #fff url(https://webapp-pub.ezijing.com/project/prp-h5/query_bg_2.png) no-repeat;
background-size: contain; background-size: contain;
border-radius: 0.2rem; border-radius: 0.2rem;
...@@ -64,12 +56,14 @@ ...@@ -64,12 +56,14 @@
} }
img { img {
margin-right: 0.1rem; margin-right: 0.1rem;
width: 0.5rem;
} }
.t1 { .t1 {
margin-top: 0.14rem;
font-size: 0.26rem; font-size: 0.26rem;
color: #033974; color: #666666;
margin-top: 0.12rem;
} }
.t2 { .t2 {
display: inline-block; display: inline-block;
padding: 0 0.2rem; padding: 0 0.2rem;
...@@ -80,7 +74,7 @@ ...@@ -80,7 +74,7 @@
background-color: #033974; background-color: #033974;
} }
} }
.box + .box { .box1 {
margin-top: 0.2rem; margin-top: 0.2rem;
} }
.box-avatar { .box-avatar {
......
...@@ -3,8 +3,9 @@ import { Toast } from 'vant' ...@@ -3,8 +3,9 @@ import { Toast } from 'vant'
import PublishItem from '@/components/PublishItem.vue' import PublishItem from '@/components/PublishItem.vue'
import { createQuestionComment } from '../api' import { createQuestionComment } from '../api'
defineProps<{ data: { total: number; list: Record<string, any>[] } }>() const props = defineProps<{ data: { total: number; list: Record<string, any>[] } }>()
const isMoreClick = ref(false)
const commentList: any = ref([])
// 评论 // 评论
const onSubmitComment = (data: any, action: string) => { const onSubmitComment = (data: any, action: string) => {
if (action === 'comment') { if (action === 'comment') {
...@@ -26,6 +27,17 @@ const onSubmitComment = (data: any, action: string) => { ...@@ -26,6 +27,17 @@ const onSubmitComment = (data: any, action: string) => {
}) })
} }
} }
watchEffect(() => {
if (isMoreClick.value === false) {
commentList.value = props.data.list.slice(0, 2)
} else {
commentList.value = props.data.list
}
})
const handleViewMore = () => {
isMoreClick.value = true
commentList.value = props.data.list
}
</script> </script>
<template> <template>
...@@ -34,7 +46,16 @@ const onSubmitComment = (data: any, action: string) => { ...@@ -34,7 +46,16 @@ const onSubmitComment = (data: any, action: string) => {
<div class="button"><router-link to="/qa/publish">发表问答</router-link></div> <div class="button"><router-link to="/qa/publish">发表问答</router-link></div>
</template> </template>
<template v-if="data.list?.length"> <template v-if="data.list?.length">
<PublishItem v-for="item in data.list" :data="item" :key="item.id" @submitComment="onSubmitComment"></PublishItem> <PublishItem
v-for="(item, index) in commentList"
:data="item"
:key="index"
@submitComment="onSubmitComment"
></PublishItem>
<div class="line"></div>
<div class="btn" color="#FCEDD0" round size="large" @click="handleViewMore" v-if="data.list.length > 2">
查看更多问答
</div>
</template> </template>
<van-empty description="暂无内容" v-else /> <van-empty description="暂无内容" v-else />
</AppCard> </AppCard>
...@@ -47,4 +68,23 @@ const onSubmitComment = (data: any, action: string) => { ...@@ -47,4 +68,23 @@ const onSubmitComment = (data: any, action: string) => {
background: #fff; background: #fff;
border-radius: 0.2rem; border-radius: 0.2rem;
} }
.btn {
margin: 0.2rem auto;
width: 5.78rem;
height: 0.69rem;
background: #fcedd0;
text-align: center;
line-height: 0.69rem;
color: #e2a022;
font-size: 0.24rem;
border-radius: 0.35rem;
cursor: pointer;
}
.line {
width: 5.97rem;
height: 0px;
border-top: 0.01rem solid #d3d3d3;
margin: auto;
}
</style> </style>
<script setup lang="ts">
import { getRecommendCourse } from '@/api/base'
import type { IRecommendCourse } from '@/types'
import num from '@/utils/numTo'
const courseList = ref<{ total: number; list: IRecommendCourse[] }>({ total: 0, list: [] })
getRecommendCourse().then(res => {
courseList.value = res.data
if (res.data.length > 3) {
courseList.value = res.data.slice(0, 3)
}
})
const handleClickItem = (item: any) => {
if (item.url) {
location.href = item.url
}
}
</script>
<template>
<img src="https://webapp-pub.ezijing.com/project/prp-h5/course_banner.png" class="exam_banner" />
<AppCard title="推荐课程" id="team">
<template #header-aside>
<div class="more">
<router-link to="/course">查看更多 <van-icon name="arrow" /></router-link>
</div>
</template>
<div class="course_list">
<div class="list_item" v-for="(item, index) in courseList.list" :key="index" @click="handleClickItem(item)">
<img :src="item.cover" class="item_img" />
<div class="item_right">
<div class="right_tit">{{ item.name }}</div>
<div class="right_bottom">
<div class="views">{{ num(item.pv) }}播放</div>
<div class="is_free" :class="item.is_free === '1' ? 'free' : 'unfree'">
{{ item.is_free_name }}
</div>
</div>
</div>
</div>
</div>
</AppCard>
</template>
<style lang="scss" scoped>
.exam_banner {
width: 6.9rem;
margin-top: 0.3rem;
}
.course_list {
.list_item {
display: flex;
margin-bottom: 0.2rem;
.item_img {
width: 2.2rem;
height: 1.4rem;
object-fit: cover;
border-radius: 0.1rem;
}
.item_right {
margin-left: 0.21rem;
display: flex;
flex-direction: column;
justify-content: space-between;
padding-top: 0.17rem;
box-sizing: border-box;
.right_tit {
font-size: 0.28rem;
font-weight: 500;
line-height: 0.36rem;
color: #333333;
}
.right_bottom {
width: 4.09rem;
margin-top: 0.21rem;
display: flex;
justify-content: space-between;
align-items: center;
.views {
font-size: 0.22rem;
font-weight: 400;
color: #999999;
}
.is_free {
font-size: 0.22rem;
font-weight: 400;
line-height: 30px;
padding-right: 0.3rem;
}
.free {
color: #4ad1a3;
}
.unfree {
color: #e9a724;
}
}
}
}
}
</style>
<script setup lang="ts">
import { Swiper, SwiperSlide } from 'swiper/vue'
import 'swiper/css'
import { getTeacherList } from '@/api/base'
import type { ITeacherList } from '@/types'
const teacherList = ref<{ total: number; list: ITeacherList[] }>({ total: 0, list: [] })
getTeacherList().then(res => {
teacherList.value = res.data
})
</script>
<template>
<div class="team" id="team">
<div class="team_header">
<div class="title">紫荆导师团</div>
<div class="more">
<router-link to="/teacher">查看更多 <van-icon name="arrow" /></router-link>
</div>
</div>
<div class="output_banner">
<swiper slides-per-view="auto" :space-between="10">
<swiper-slide v-for="(item, index) in teacherList.list" :key="index" class="video-swiper-slide">
<img :src="item.avatar" class="img" />
<div class="name">{{ item.name }}</div>
</swiper-slide>
</swiper>
</div>
</div>
</template>
<style lang="scss" scoped>
.video-swiper-slide {
width: 2rem;
}
#team {
border-radius: 0.2rem;
background: #ffffff;
padding-bottom: 0.2rem;
.team_header {
background-size: 100% 100%;
padding: 0.2rem;
box-sizing: border-box;
display: flex;
justify-content: space-between;
.title {
font-size: 0.28rem;
font-weight: 600;
line-height: 1;
color: #333;
}
.more {
color: #999999;
font-size: 0.22rem;
}
}
}
.output_banner {
padding-left: 0.2rem;
}
.img {
width: 1.9rem;
height: 2.3rem;
border-radius: 0.1rem;
object-fit: cover;
}
.name {
font-size: 0.24rem;
font-weight: 500;
color: #4e4e4e;
text-align: center;
margin-top: 0.1rem;
}
</style>
...@@ -4,16 +4,17 @@ defineProps<{ teams: ITeam[] }>() ...@@ -4,16 +4,17 @@ defineProps<{ teams: ITeam[] }>()
</script> </script>
<template> <template>
<AppCard title="荣誉总榜" id="team"> <div id="team">
<template #header-aside> <div class="team_header">
<div class="title">团队荣誉总榜</div>
<div class="more"> <div class="more">
<router-link to="/team">查看更多 <van-icon name="arrow" /></router-link> <router-link to="/team">查看更多</router-link>
</div> </div>
</template> </div>
<div class="team-ranking"> <div class="team-ranking">
<h2>团队荣誉总榜</h2> <!-- <h2>团队荣誉总榜</h2> -->
<ul> <ul>
<li v-for="item in teams" :key="item.id"> <li v-for="item in teams.slice(0, 3)" :key="item.id">
<router-link :to="{ name: 'teamView', params: { id: item.id } }"> <router-link :to="{ name: 'teamView', params: { id: item.id } }">
<h4>{{ item.name }}</h4> <h4>{{ item.name }}</h4>
<p>{{ item.slogan }}<em>|</em>{{ item.members_count }}</p> <p>{{ item.slogan }}<em>|</em>{{ item.members_count }}</p>
...@@ -21,54 +22,70 @@ defineProps<{ teams: ITeam[] }>() ...@@ -21,54 +22,70 @@ defineProps<{ teams: ITeam[] }>()
</li> </li>
</ul> </ul>
</div> </div>
</AppCard> </div>
</template> </template>
<style lang="scss"> <style lang="scss" scoped>
.team-ranking { #team {
background: #fff url(https://webapp-pub.ezijing.com/project/prp-h5/team_bg.png) no-repeat;
background-size: 100%;
border-radius: 0.2rem; border-radius: 0.2rem;
h2 { margin-bottom: 0.29rem;
padding: 0.4rem 0 0.2rem; background: #ffffff;
font-size: 0.36rem; .team_header {
font-weight: 0.6rem; background: #fff url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/project/prp-h5/ranking_bg.png) no-repeat;
color: #955801; background-size: 100% 100%;
text-align: center; padding: 0.4rem 0.37rem 0.47rem 0.37rem;
background: url(https://webapp-pub.ezijing.com/project/prp-h5/team_header_bg.png) no-repeat center center; height: 1.37rem;
background-size: 2.74rem; box-sizing: border-box;
} display: flex;
li { justify-content: space-between;
padding: 0.3rem 0.3rem 0.3rem 1.88rem; .title {
h4 { color: #955801;
font-size: 0.3rem; font-size: 0.36rem;
color: #4e4e4e; font-weight: 600;
line-height: 0.42rem;
}
p {
margin-top: 0.08rem;
font-size: 0.26rem;
color: #999999;
line-height: 0.38rem;
em {
padding: 0 0.2rem;
}
} }
&:nth-child(1) { .more {
background: url(https://webapp-pub.ezijing.com/project/prp-h5/team_1.png) no-repeat 0.68rem center; color: #955815;
background-size: 0.54rem; color: 0.22rem;
} }
&:nth-child(2) { }
background: url(https://webapp-pub.ezijing.com/project/prp-h5/team_2.png) no-repeat 0.68rem center;
background-size: 0.54rem; .team-ranking {
// background: #fff url(https://webapp-pub.ezijing.com/project/prp-h5/team_bg.png) no-repeat;
background-size: 100%;
border-radius: 0.2rem;
li {
padding: 0.3rem 0.3rem 0.3rem 1.88rem;
h4 {
font-size: 0.3rem;
color: #4e4e4e;
line-height: 0.42rem;
}
p {
margin-top: 0.08rem;
font-size: 0.26rem;
color: #999999;
line-height: 0.38rem;
em {
padding: 0 0.2rem;
}
}
&:nth-child(1) {
background: url(https://webapp-pub.ezijing.com/project/prp-h5/team_1.png) no-repeat 0.68rem center;
background-size: 0.54rem;
}
&:nth-child(2) {
background: url(https://webapp-pub.ezijing.com/project/prp-h5/team_2.png) no-repeat 0.68rem center;
background-size: 0.54rem;
}
&:nth-child(3) {
background: url(https://webapp-pub.ezijing.com/project/prp-h5/team_3.png) no-repeat 0.68rem center;
background-size: 0.54rem;
}
} }
&:nth-child(3) { li + li {
background: url(https://webapp-pub.ezijing.com/project/prp-h5/team_3.png) no-repeat 0.68rem center; border-top: 0.01rem solid #e4e4e4;
background-size: 0.54rem;
} }
} }
li + li {
border-top: 0.01rem solid #e4e4e4;
}
} }
</style> </style>
...@@ -8,6 +8,7 @@ export interface HomeInfo { ...@@ -8,6 +8,7 @@ export interface HomeInfo {
exam_strategy_docs: IDocItem[] exam_strategy_docs: IDocItem[]
questions: { total: number; list: Record<string, any>[] } questions: { total: number; list: Record<string, any>[] }
ranking: ITeam[] ranking: ITeam[]
hot_message_docs: INews[]
} }
export interface IBanner { export interface IBanner {
...@@ -26,5 +27,18 @@ export interface IDocItem { ...@@ -26,5 +27,18 @@ export interface IDocItem {
desc_type: '1' | '2' desc_type: '1' | '2'
url: string url: string
} }
export interface INews {
created_time: string
desc_type: string
desc_type_name: string
file: string
id: string
picture: string
pv: string
title: string
type: string
type_name: string
url: string
}
export { IVideoItem, ICourseItem, ITeam } export { IVideoItem, ICourseItem, ITeam }
...@@ -3,11 +3,17 @@ import { ref, onMounted } from 'vue' ...@@ -3,11 +3,17 @@ import { ref, onMounted } from 'vue'
import type { HomeInfo } from '../types' import type { HomeInfo } from '../types'
import * as api from '../api' import * as api from '../api'
import Banner from '../components/Banner.vue' import Banner from '../components/Banner.vue'
import Menu from '../components/Menu.vue' // import Menu from '../components/Menu.vue'
import AdmissionGuide from '../components/AdmissionGuide.vue' // import AdmissionGuide from '../components/AdmissionGuide.vue'
import CourseCard from '../components/CourseCard.vue'
import News from '../components/News.vue'
import RecommendCourse from '../components/RecommendCourse.vue'
import KnowledgeOut from '../components/KnowledgeOut.vue'
import Teacher from '../components/Teacher.vue'
import LearningMap from '../components/LearningMap.vue' import LearningMap from '../components/LearningMap.vue'
import QueryView from '../components/QueryView.vue' import QueryView from '../components/QueryView.vue'
import ExamStrategy from '../components/ExamStrategy.vue' // import ExamStrategy from '../components/ExamStrategy.vue'
import TeamRanking from '../components/TeamRanking.vue' import TeamRanking from '../components/TeamRanking.vue'
import Questions from '../components/Questions.vue' import Questions from '../components/Questions.vue'
import useWXShare from '@/utils/wx' import useWXShare from '@/utils/wx'
...@@ -19,7 +25,8 @@ const data = ref<HomeInfo>({ ...@@ -19,7 +25,8 @@ const data = ref<HomeInfo>({
learning_map_docs: [], learning_map_docs: [],
exam_strategy_docs: [], exam_strategy_docs: [],
questions: { total: 0, list: [] }, questions: { total: 0, list: [] },
ranking: [] ranking: [],
hot_message_docs: []
}) })
// 获取首页数据 // 获取首页数据
const fetchHomeData = () => { const fetchHomeData = () => {
...@@ -35,20 +42,30 @@ onMounted(() => { ...@@ -35,20 +42,30 @@ onMounted(() => {
<template> <template>
<Banner :list="data.banner"></Banner> <Banner :list="data.banner"></Banner>
<Menu></Menu> <!-- <Menu></Menu> -->
<!-- 入学指南 --> <!-- 入学指南 -->
<AdmissionGuide :docs="data.admission_guide_docs" :videos="data.admission_guide_videos"></AdmissionGuide> <!-- <AdmissionGuide :docs="data.admission_guide_docs" :videos="data.admission_guide_videos"></AdmissionGuide> -->
<CourseCard :docs="data.admission_guide_docs" :videos="data.admission_guide_videos" />
<!-- 新闻轮播 -->
<News :docs="data.hot_message_docs" />
<!-- 推荐课程 -->
<RecommendCourse />
<!-- 知识输出者 -->
<KnowledgeOut />
<!-- 讲师团 -->
<Teacher />
<!-- 学习地图 --> <!-- 学习地图 -->
<LearningMap :docs="data.learning_map_docs"></LearningMap> <LearningMap :docs="data.learning_map_docs"></LearningMap>
<!-- 权益查看 --> <!-- 权益查看 -->
<QueryView></QueryView> <QueryView></QueryView>
<RouterLink to="/qa"> <!-- <RouterLink to="/qa">
<img src="https://webapp-pub.ezijing.com/project/prp-h5/qa_banner.png" style="width: 100%" /> <img src="https://webapp-pub.ezijing.com/project/prp-h5/qa_banner.png" style="width: 100%" />
</RouterLink> </RouterLink> -->
<!-- 陪伴问答 -->
<Questions :data="data.questions"></Questions>
<!-- 荣誉总榜 --> <!-- 荣誉总榜 -->
<TeamRanking :teams="data.ranking"></TeamRanking> <TeamRanking :teams="data.ranking"></TeamRanking>
<!-- 考试攻略 --> <!-- 考试攻略 -->
<ExamStrategy :docs="data.exam_strategy_docs"></ExamStrategy> <!-- <ExamStrategy :docs="data.exam_strategy_docs"></ExamStrategy> -->
<!-- 陪伴问答 --> <img src="https://webapp-pub.ezijing.com/project/prp-h5/exam_banner.png" style="width: 100%; margin-bottom: 0.5rem" />
<Questions :data="data.questions"></Questions>
</template> </template>
import httpRequest from '@/utils/axios'
// 获取文档数据
export function getNewsView(params: { id: string }) {
return httpRequest.get('/api/psp/v1/hot-message/doc-view', { params })
}
import type { RouteRecordRaw } from 'vue-router'
import AppLayout from '@/components/layout/Index.vue'
export const routes: Array<RouteRecordRaw> = [
{
path: '/news',
component: AppLayout,
children: [{ path: 'doc/:id', component: () => import('./views/newsDoc.vue'), props: true }]
}
]
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { getNewsView } from '../api'
import DocView from '@/components/DocView.vue'
const props = defineProps<{ id: string }>()
const data = ref()
function fetchDocView() {
getNewsView({ id: props.id }).then(res => {
data.value = res.data
})
}
onMounted(() => {
fetchDocView()
})
</script>
<template>
<DocView :data="data"></DocView>
</template>
...@@ -14,10 +14,10 @@ const dataset = reactive<licenseeList>({ loading: false, page: 1, total: 0, list ...@@ -14,10 +14,10 @@ const dataset = reactive<licenseeList>({ loading: false, page: 1, total: 0, list
// 获取持证人列表 // 获取持证人列表
const handleLicenseList = () => { const handleLicenseList = () => {
const params = { page_size: 10, page: dataset.page } const params = { page_size: 10, page: dataset.page }
dataset.loading = true
api api
.getLicenseList(params) .getLicenseList(params)
.then(res => { .then(res => {
console.log(dataset.page, 'dataset.page')
const { total, list } = res.data const { total, list } = res.data
dataset.total = total dataset.total = total
dataset.list = dataset.list.concat(list) dataset.list = dataset.list.concat(list)
...@@ -29,12 +29,7 @@ const handleLicenseList = () => { ...@@ -29,12 +29,7 @@ const handleLicenseList = () => {
dataset.loading = false dataset.loading = false
}) })
} }
onMounted(() => {
dataset.page = 1
dataset.list = []
// 获取持证人列表
handleLicenseList()
})
// 滚动加载 // 滚动加载
const el = ref<HTMLElement>() const el = ref<HTMLElement>()
useInfiniteScroll( useInfiniteScroll(
...@@ -45,6 +40,10 @@ useInfiniteScroll( ...@@ -45,6 +40,10 @@ useInfiniteScroll(
}, },
{ distance: 10 } { distance: 10 }
) )
onMounted(() => {
// 获取持证人列表
handleLicenseList()
})
</script> </script>
<template> <template>
<div> <div>
......
<script setup lang="ts">
import type { ITeacherList } from '@/types'
defineProps<{ teacherList: ITeacherList[] }>()
</script>
<template>
<div class="teacher_list" v-if="teacherList.length > 0">
<div class="list_item" v-for="(item, index) in teacherList" :key="index">
<div>
<img :src="item.avatar" alt="" />
<div class="item_bottom">
<div class="name">{{ item.name }}</div>
<div class="desc" v-html="item.title"></div>
<div class="desc" v-html="item.office"></div>
</div>
</div>
</div>
</div>
<van-empty v-else description="暂无" />
</template>
<style lang="scss" scoped>
.teacher_list {
margin-top: 0.7rem;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.list_item {
width: 3.35rem;
margin-bottom: 0.2rem;
img {
width: 100%;
height: 3rem;
object-fit: cover;
border-top-left-radius: 0.2rem;
border-top-right-radius: 0.2rem;
}
.item_bottom {
background: url(https://webapp-pub.ezijing.com/project/prp-h5/teacher_bg.png) no-repeat;
background-size: cover;
width: 100%;
height: 2.24rem;
border-bottom-left-radius: 0.2rem;
border-bottom-right-radius: 0.2rem;
padding: 0.13rem 0 0 0.16rem;
box-sizing: border-box;
.name {
font-size: 0.3rem;
font-weight: 500;
color: #333333;
}
.desc {
font-size: 0.24rem;
font-weight: 400;
line-height: 0.32rem;
color: #666666;
margin-top: 0.07rem;
}
}
}
}
</style>
import type { RouteRecordRaw } from 'vue-router'
import AppLayout from '@/components/layout/Index.vue'
export const routes: Array<RouteRecordRaw> = [
{
path: '/teacher',
component: AppLayout,
children: [{ path: '', component: () => import('./views/Index.vue') }]
}
]
<script setup lang="ts">
import { getTeacherList } from '@/api/base'
import type { ITeacherList } from '@/types'
import TeacherList from '../components/TeacherList.vue'
interface ITeacherAllList {
loading: boolean
page: number
total: number
list: ITeacherList[]
}
const teacherList = $ref<ITeacherAllList>({
loading: false,
page: 1,
total: 0,
list: []
})
let tabIndex = $ref(0)
const handleGetTeacherList = (val: any) => {
const params: any = { page_size: 10, page: teacherList.page, type: (val + 1).toString() }
teacherList.loading = true
getTeacherList(params)
.then(res => {
const { total, list } = res.data
teacherList.total = total
teacherList.list = teacherList.list.concat(list)
if (teacherList.list.length <= total) {
teacherList.page++
}
})
.finally(() => {
teacherList.loading = false
})
}
onMounted(() => {
handleGetTeacherList(0)
})
const handleTabClick = (val: number) => {
tabIndex = val
teacherList.page = 1
teacherList.total = 0
teacherList.list = []
handleGetTeacherList(val)
}
// 滚动加载
const el = ref<HTMLElement>()
useInfiniteScroll(
document,
() => {
// load more
if (tabIndex === 0) {
!teacherList.loading && handleGetTeacherList(0)
} else {
!teacherList.loading && handleGetTeacherList(1)
}
},
{ distance: 10 }
)
</script>
<template>
<img src="https://webapp-pub.ezijing.com/project/prp-h5/teacher_banner.png" style="width: 100%" />
<div class="teacher_tab">
<div class="tab_name" :class="tabIndex === 0 ? 'active_tab' : 'inactive_tab'" @click="handleTabClick(0)">
清华硕导教授团
</div>
<div class="tab_line"></div>
<div class="tab_name" :class="tabIndex === 1 ? 'active_tab' : 'inactive_tab'" @click="handleTabClick(1)">
紫荆实战导师团
</div>
</div>
<TeacherList :teacherList="teacherList.list" ref="el" />
</template>
<style lang="scss" scoped>
.teacher_tab {
width: 5.06rem;
height: 0.8rem;
background: #ffffff;
border-top-left-radius: 0.4rem;
border-top-right-radius: 0.4rem;
position: relative;
z-index: 100;
margin: -20px auto;
display: flex;
justify-content: space-around;
align-items: center;
.tab_line {
width: 0px;
height: 0.25rem;
border: 1px solid #d3d3d3;
}
.active_tab {
color: #e9a724;
}
.tab_name {
font-size: 0.28rem;
font-weight: 400;
cursor: pointer;
}
.inactive_tab {
color: #999999;
}
}
.teacher_list {
margin-top: 0.7rem;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.list_item {
width: 3.35rem;
margin-bottom: 0.2rem;
img {
width: 100%;
height: 3rem;
object-fit: cover;
border-top-left-radius: 0.2rem;
border-top-right-radius: 0.2rem;
}
.item_bottom {
background: url(https://webapp-pub.ezijing.com/project/prp-h5/teacher_bg.png) no-repeat;
background-size: cover;
width: 100%;
height: 2.24rem;
border-bottom-left-radius: 0.2rem;
border-bottom-right-radius: 0.2rem;
padding: 0.13rem 0 0 0.16rem;
box-sizing: border-box;
.name {
font-size: 0.3rem;
font-weight: 500;
color: #333333;
}
.desc {
font-size: 0.24rem;
font-weight: 400;
line-height: 0.32rem;
color: #666666;
margin-top: 0.07rem;
}
}
}
}
</style>
...@@ -76,3 +76,28 @@ export interface ITeam { ...@@ -76,3 +76,28 @@ export interface ITeam {
slogan: string slogan: string
star: string star: string
} }
export interface IRecommendCourse {
cover: string
id: string
is_free: string
is_free_name: string
name: string
pv: string
weight: string
url: string
}
export interface ITeacherList {
avatar: string
desc: string
desc_type: string
desc_type_name: string
id: string
name: string
pv: string
title: string
url: string
weight: string
type: string
type_name: string
office: string
}
//数字改变(加万位)
export default function num(value) {
const newValue = ['', '', '']
let fr = 1000
let num = 3
let text1 = ''
let fm = 1
while (value / fr >= 1) {
fr *= 10
num += 1
// console.log('数字', value / fr, 'num:', num)
}
if (num <= 8) {
// 万
text1 = parseInt(num - 4) / 3 > 1 ? '千万' : '万'
// tslint:disable-next-line:no-shadowed-variable
fm = text1 === '万' ? 10000 : 10000000
if (value % fm === 0) {
newValue[0] = parseInt(value / fm) + ''
} else {
newValue[0] = parseFloat(value / fm).toFixed(2) + ''
}
newValue[1] = text1
}
if (value < 1000) {
newValue[0] = value + ''
newValue[1] = ''
}
return newValue.join('')
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论