123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- <template>
- <view class="page">
- <cu-custom :isBack="true"></cu-custom>
- <view class="header" :style="[{top:topHeader + 'px'}]">
- <view class="header-title">
- <view class="header-title-main">
- <view class="margin-bottom-xs">{{tabList[cate_type].title}}</view>
- <view class="point"></view>
- </view>
- </view>
- <swiper-tab :menuList="tabList[cate_type].list" @changeTab="changeTab"></swiper-tab>
- </view>
- <scroll-view v-if="currentIndex===0" :scroll-y="true"
- :style="[{height:'calc(100vh - 70px - '+ topHeader+'px)'}]"
- class="scroll-main">
- <view class="content">
- <view class="course-img">
- <swiper class="swiper" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval" :duration="swiper.duration">
- <swiper-item v-for="(item,index) in detail.image" :key="index">
- <view class="swiper-item">
- <image :src="item" mode="widthFix"></image>
- </view>
- </swiper-item>
- </swiper>
- </view>
- <!-- 详情 -->
- <view class="detail">
- <view class="detail-title">{{detail.name}}</view>
- <view class="detail-item">
- <view class="detail-item-point"></view>
- <view class="detail-label">周期</view>
- <view class="detail-text">{{detail.period}}<text class="text-gray">({{detail.time[0]}})</text></view>
- </view>
- <view class="detail-item">
- <view class="detail-item-point"></view>
- <view class="detail-label">适用年级</view>
- <view class="detail-text">{{detail.grade}}年级通用</view>
- </view>
- <view class="detail-item">
- <view class="detail-item-point"></view>
- <view class="detail-label">课时</view>
- <view class="detail-text">{{detail.class_total}}课时</view>
- </view>
- <view class="detail-item">
- <view class="detail-item-point"></view>
- <view class="detail-label">单课时价</view>
- <view class="detail-text">¥{{detail.single_money}}</view>
- </view>
- <view class="detail-item">
- <view class="detail-item-point"></view>
- <view class="detail-label">补贴</view>
- <view class="detail-text">¥{{detail.subsidy}}/节课</view>
- </view>
- <view class="detail-item">
- <view class="detail-item-point"></view>
- <view class="detail-label">培养目标</view>
- <view class="detail-text">{{detail.tenet}}</view>
- </view>
- </view>
- </view>
- <!-- 老师介绍 -->
- <view class="teacher flex margin-top-sm shadow" v-if="cate_type===0">
- <image mode="scaleToFill" :src="defaultTeacher" class="avatar lg"></image>
- <view class="flex-sub margin-left">
- <view class="teacher-title">{{detail.teachers.username||''}}老师授课</view>
- <view class="teacher-item">毕业于{{detail.teachers.agency_name||''}}</view>
- <view class="teacher-item">所属机构:{{detail.teachers.orz||''}}</view>
- <view class="teacher-exp flex">
- <view class="exp-item">{{detail.teachers.honor||''}}</view>
- <view class="exp-item">{{detail.teachers.introduce||''}}</view>
- </view>
- </view>
- </view>
- <!-- 道具选择 -->
- <view class="shop margin-top-sm shadow" v-if="detail.prop&&detail.prop.length>0">
- <view class="shop-title">请选择课程所需要的道具</view>
- <radio-group @change="radioChange" class="margin-top-xs">
- <label v-for="radio in radios" :key="radio.value" class="margin-right-sm">
- <radio :value="radio.value" class="cyan" :checked="radio.checked" style="transform:scale(0.7)"/>{{radio.name}}
- </label>
- </radio-group>
- <checkbox-group @change="checkboxChange" v-if="needTool==='1'" class="checkbox-group margin-top-xs">
- <label v-for="prop in detail.prop" :key="prop.id">
- <view>
- <checkbox :value="prop.id" class="cyan" style="transform:scale(0.7)" :checked="goods.props.includes(prop.id)"/>{{prop.name}}<text>¥{{prop.money}}</text>
- </view>
- </label>
- </checkbox-group>
- </view>
- <!-- 评论 -->
- <view class="comment">
- <rich-text :nodes="detail.present"></rich-text>
- </view>
- </scroll-view>
- <!-- 评价页 -->
- <scroll-view
- :style="[{height:'calc(100vh - 70px - '+ topHeader+'px)'}]"
- class="scroll-main"
- v-if="currentIndex===1">
- <view class="cu-list menu-avatar comment">
- <view class="cu-item" v-for="(comment,index) in comments" :key="index">
- <image mode="scaleToFill" :src="comment.img" class="avatar md left"></image>
- <view class="content">
- <view class="text-grey">{{comment.name}}</view>
- <view class="text-gray text-content text-df">
- {{comment.content}}
- </view>
- <view class="margin-top-sm flex justify-between">
- <view class="text-gray text-df">{{comment.date}}</view>
- <!-- <view>
- <text class="cuIcon-appreciatefill text-red"></text>
- <text class="cuIcon-messagefill text-gray margin-left-sm"></text>
- </view> -->
- </view>
- </view>
- </view>
- </view>
- </scroll-view>
- <!-- 视频页 -->
- <scroll-view
- :style="[{height:'calc(100vh - 70px - '+ topHeader+'px)'}]"
- class="scroll-main"
- v-if="currentIndex===2">
- <view class="list">
- <view class="cu-card case" v-for="(video,index) in detail.video" :key="index">
- <view class="cu-item shadow">
- <view class="image">
- <video :src="video" style="width:100%;"></video>
- </view>
- </view>
- </view>
- </view>
- </scroll-view>
- <!-- 大纲页 -->
- <scroll-view
- :scroll-y="true"
- :style="[{height:'calc(100vh - 70px - '+ topHeader+'px)'}]"
- class="scroll-main"
- v-if="currentIndex===3">
- <view class="cu-bar bg-white">
- <view class="action border-title">
- <text class="cuIcon-title text-student"></text>
- <text class="text-xl text-bold">{{tabList[cate_type].list[currentIndex]}}</text>
- </view>
- </view>
- <view class="bg-white padding-lr">
- <view class="text-content text-lg" v-for="(outline,index) in detail.out_line" :key="index">
- {{outline.course_content}}
- </view>
- </view>
- </scroll-view>
- <view class="static flex shadow">
- <view class="static-price">
- <text class="satic-label text-lg">小计:</text>
- <text class="text-price text-red text-lg">{{goods.sum_money}}</text>
- </view>
- <view class="static-choose text-ellipsis" v-if="goods.choose.length>0">(已选:{{goods.choose.join(',')}})</view>
- <view class="static-order flex align-center">
- <shop-cart :class_attend_id="attend_id"></shop-cart>
- <button class="cu-btn round bg-student text-white margin-left-xs" :class="{'disabled':carts.includes(attend_id)||!detail.enable}" @tap="addCart">报课</button>
- </view>
- </view>
- </view>
- </template>
- <script>
- import { _detail, _comments, _joinShop } from '@/api/course'
- import swiperTab from '@/components/swiper-tab.vue'
- import shopCart from '@/components/shop-cart.vue'
- import NP from 'number-precision'
- import { mapGetters } from 'vuex'
- export default {
- components: {
- swiperTab, shopCart
- },
- data() {
- return {
- topHeader: this.globalCustomBarHeight,
- swiper: {
- indicatorDots: true,
- autoplay: true,
- interval: 2000,
- duration: 500
- },
- defaultTeacher: '/static/imgs/class/logo0.png',
- attend_id: 0,
- cate_type: 0,
- currentIndex: 0,
- money: 0, // 初始金额
- comments: [], // 评论
- detail: {}, // 详情
- needTool: '1', // 需要道具
- disableBtn: false, // 避免多次重复点击
- radios: [
- { value: '1', name: '需要道具', checked: true },
- { value: '2', name: '不需要道具', checked: false }
- ],
- goods: { // 动态选中值
- props: [], // 选中值
- choose: [], // 选中名称
- sum_money: 0// 金额总计
- }, // 选中课程
- tabList: [
- {
- title: '课程详细',
- list: ['课程介绍', '课程评价', '课程视频', '课程大纲'],
- enable: '报课',
- disable: '报课',
- options: [
- { title: '周期', content: ':正在加载,请稍后', des: ':正在加载,请稍后' },
- { title: '适用年级', content: ':正在加载,请稍后', des: '' },
- { title: '课时', content: ':正在加载,请稍后', des: '' },
- { title: '单课时价', content: ':正在加载,请稍后', des: '' },
- { title: '补贴', content: ':正在加载,请稍后', des: '' },
- { title: '培养目标', content: ':正在加载,请稍后', des: '' }
- ]
- },
- {
- title: '餐饮详细',
- list: ['餐饮介绍', '餐饮评价', '餐饮视频', '每日菜谱'],
- enable: '报餐',
- disable: '报餐',
- options: [
- { title: '周期', content: ':正在加载,请稍后', des: ':正在加载,请稍后' },
- { title: '适用年级', content: ':正在加载,请稍后', des: '' },
- { title: '用餐次数', content: ':正在加载,请稍后', des: '' },
- { title: '单次价格', content: ':正在加载,请稍后', des: '' },
- { title: '补贴', content: ':正在加载,请稍后', des: '' },
- { title: '用餐介绍', content: ':正在加载,请稍后', des: '' }
- ]
- },
- {
- title: '活动详细',
- list: ['活动介绍', '活动评价', '活动视频', '活动大纲'],
- enable: '报名',
- disable: '报名',
- options: [
- { title: '周期', content: ':正在加载,请稍后', des: ':正在加载,请稍后' },
- { title: '适用年级', content: ':正在加载,请稍后', des: '' },
- { title: '活动次数', content: ':正在加载,请稍后', des: '' },
- { title: '单次价格', content: ':正在加载,请稍后', des: '' },
- { title: '补贴', content: ':正在加载,请稍后', des: '' },
- { title: '活动目标', content: ':正在加载,请稍后', des: '' }
- ]
- }
- ]
- }
- },
- computed: {
- ...mapGetters([
- 'carts'
- ])
- },
- onShow() {
- this.disableBtn = false
- },
- onLoad(option) {
- this.attend_id = Number(decodeURIComponent(option.attend_id))
- if (this.attend_id === 0) {
- uni.navigateBack()
- }
- this.get_detail()
- this.get_comments()
- },
- methods: {
- get_detail() {
- _detail({ class_attend_id: this.attend_id }).then(res => {
- this.detail = res.data
- this.money = res.data.sum_money
- const props = res.data.prop
- if (props && props.length > 0) {
- this.setDefaultGoods(props)
- } else {
- this.goods.sum_money = this.money
- }
- })
- },
- addCart() {
- if (this.disableBtn) return false
- this.disableBtn = true
- if (this.carts.includes(this.attend_id)) {
- uni.showToast({ title: '课程已存在,请勿重复添加!', icon: 'none' })
- setTimeout(() => {
- // this.disableBtn = false
- this.globalNavigateTo('classCart')
- }, 1000)
- return false
- }
- if (!this.detail.enable) {
- uni.showToast({ title: '课程已停止!', icon: 'none' })
- this.disableBtn = false
- return false
- }
- const props = this.goods.props.join(',')
- _joinShop({ class_attend_id: this.attend_id, prop: props }).then(res => {
- // this.disableBtn = false
- this.globalNavigateTo('classCart')
- })
- },
- setDefaultGoods(props) {
- this.goods.props[0] = props[0].id
- this.goods.sum_money = NP.plus(this.money, props[0].money)
- this.goods.choose[0] = props[0].name
- },
- get_comments() {
- _comments({ class_attend_id: this.attend_id }).then(res => {
- this.comemnts = res.data
- })
- },
- changeTab(index) {
- this.currentIndex = index
- },
- radioChange(e) {
- const value = e.detail.value
- this.needTool = value
- if (value === '1') {
- this.setDefaultGoods(this.detail.prop)
- } else {
- this.goods.sum_money = this.money
- this.goods.props = []
- this.goods.choose = []
- }
- },
- checkboxChange(e) {
- const values = e.detail.value
- const choose = []
- const props = []
- let money = 0
- values.forEach(item => {
- const one = this.detail.prop.find(e => e.id === Number(item))
- choose.push(one.name)
- props.push(Number(item))
- money = NP.plus(money, Number(one.money))
- })
- const sum = NP.plus(this.money, money)
- this.goods = {
- props: props,
- choose: choose,
- sum_money: sum
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .scroll-main{
- padding-top:86px;
- }
- .detail{
- padding:20rpx;
- background-color:#fff;
- &-title{
- margin-bottom:1rem;
- font-size:22px;
- }
- &-item{
- margin: 20rpx 0;
- display: flex;
- color: #999;
- &-point{
- margin-top: 7px;
- margin-right: 7px;
- border-radius: 50%;
- width: 5px;
- height: 5px;
- background: #5ecfde;
- }
- }
- &-label{
- width: 66px;
- padding-right: 6px;
- text-align: justify;
- text-align-last: justify;
- }
- &-text{
- color:#000;
- }
- }
- .teacher{
- padding:20rpx;
- background:#fff;
- font-size:14px;
- color:#999;
- &-title{
- font-size:18px;
- color:#000;
- }
- }
- .shop{
- padding:20rpx;
- background:#fff;
- }
- .checkbox-group{
- height:80px;
- overflow-y:scroll;
- border:1px solid #f5f5f5;
- }
- .comment{
- padding:20rpx;
- min-height:60px;
- }
- .static{
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- display: flex;
- background: #fff;
- height: 70px;
- align-items: center;
- padding: 0 0.8rem;
- justify-content: space-between;
- &-price{
- font-size:14px;
- }
- &-choose{
- color: #666;
- font-size: 12px;
- width: calc(100vw - 240px);
- }
- }
- </style>
|