zoukankan      html  css  js  c++  java
  • vue2-vux-fitness-project

    非常感谢那些无私开源的程序员,希望我也能够有能力像你们那样,开源很多很有意思的东西~~

    //index.html
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
        <title>fitness-app</title>
      </head>
      <body>
        <div id="app"></div>
        <!-- built files will be auto injected -->
      </body>
    </html>
    
    //App.vue
    <template>
      <div class="app" style="height:100%;">
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    export default {
      name: 'app'
    }
    </script>
    
    <style lang="less">
    @import '~vux/src/styles/reset.less';
    
    body {
      background-color: #fbf9fe;
    }
    </style>
    
    //main.js
    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    import Vue from 'vue'
    import FastClick from 'fastclick'
    import VueRouter from 'vue-router'
    import App from './App'
    
    import router from'./router/memberRouter.js'      //---------自定义的路由文件
    import Base from './assets/js/baseFun.js'         //---------自定义的公共函数和公共请求方法
    import stores from './store/store'                //---------自定义的全局变量
    import './assets/css/base.css'                    //---------引入的全局公共css
    
    FastClick.attach(document.body)
    Vue.config.productionTip = false
    
    //注册全局函数和全局常量
    Vue.prototype.baseFun=Base.baseFun;  //-----注册到vue的全局,方便各个组件和页面js调用公共函数
    Vue.prototype.baseAjax=Base.baseAjax;//-----将封装的ajax请求函数注册到vue的全局 
    
    Vue.use(VueRouter)
    
    var globalVm=new Vue({
    	router,            //-----router文件
        el: '#app',
        store:stores,          //-----全局变量
        template: '<App/>',
        components: { App }
    })
    
    //memberRouter.js路由
    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import memberHome from '@/components/memberHome'
    import activityIndex from '@/components/member/activities/activityIndex'
    import activityDetail from '@/components/member/activities/activityDetail'
    import groupCourses from '@/components/member/groupCourses/groupCourses'
    import personalCourses from '@/components/member/personalCourses/personalCourses'
    import personalCourseDetail from '@/components/member/personalCourses/personalCourseDetail'
    import mine from '@/components/member/mine/mine'
    
    Vue.use(VueRouter)
    
    const router = new VueRouter({
        mode: 'hash',
        base: __dirname,
        //路由映射map
        routes: [
            { path: '/', redirect: '/memberHome/activityIndex' },
            { path: '*', redirect: '/memberHome/activityIndex' },
    	    {
    	      path: '/memberHome',
    	      name: 'memberHome',
    	      component: memberHome,
    	      children:[
    	      	   {
    			      path: '/memberHome/activityIndex',
    			      name: 'activityIndex',
    			      component: activityIndex
    			    },
    			     {
    			      path: '/memberHome/activityDetail/:activityId',
    			      name: 'activityDetail',
    			      component: activityDetail
    			    },
    			    {
    			      path: '/memberHome/groupCourses',
    			      name: 'groupCourses',
    			      component: groupCourses
    			    },
    			    {
    			      path: '/memberHome/mine',
    			      name: 'mine',
    			      component: mine
    			    },
    			    {
    			      path: '/memberHome/personalCourses',
    			      name: 'personalCourses',
    			      component: personalCourses
    			    },
    			     {
    			      path: '/memberHome/personalCourseDetail/:courseId/:date',
    			      name: 'personalCourseDetail',
    			      component: personalCourseDetail
    			    }
    
    	      ]
    	    },
    	     
        ]
    });
    
    export default router;
    

    固定头部和下部

    //memberHome.vue
    <template>
      <div class="memberHome" style="height: 100%">
       <view-box ref="viewbox" body-padding-top="46px">
         <div class="vux-demo-header-box" slot="header">
          <!-- 插槽过来的变动的头部 -->
            <x-header :left-options="{backText: ''}" v-show="headShow">{{pageTitle}}</x-header>
         </div>
         <div v-transfer-dom class="loading-box">
            <loading :show="loading" position="absolute"></loading>
        </div>
        <!-- 中间部分固定 -->
            <router-view></router-view>
            <!-- 下部是固定部分 -->
         <tabbar v-show="footerShow">
          <tabbar-item selected link="/memberHome/newsIndex">
            <img slot="icon" src="../assets/images/icons/news_icon.png">
            <span slot="label">最新活动</span>
          </tabbar-item>
          <tabbar-item link="/memberHome/groupCourses">
            <img slot="icon" src="../assets/images/icons/group_icon.png">
            <span slot="label">团体课</span>
          </tabbar-item>
          <tabbar-item  link="/memberHome/personalCourses">
            <img slot="icon" src="../assets/images/icons/private_icon.png">
            <span slot="label">私教课</span>
          </tabbar-item>
          <tabbar-item link="/memberHome/mine">
            <img  slot="icon" src="../assets/images/icons/mine_icon.png">
            <span slot="label">我的</span>
          </tabbar-item>
        </tabbar>
        </view-box>
      </div>
    </template>
    
    <script>
      import { Tabbar,Icon,TabbarItem ,XHeader,Loading,ViewBox} from 'vux'
      import { TransferDomDirective as TransferDom } from 'vux'
    
      import {mapGetters} from 'vuex'
     
      export default {
        computed:mapGetters([
          'headShow',
          'loading',
          'footerShow',
          'pageTitle'
        ]),
        data(){
          let data={
    
          }
          return data
        },
        mounted() {
          
        },
        directives: {
            TransferDom
          },
        components: {
          Tabbar,
          TabbarItem,
          XHeader,
          Loading,
          ViewBox,
          Icon
        }
      }
    </script>
    <style>
    
    .memberHome .vux-demo-header-box {
      z-index: 100;
      position: absolute;
       100%;
      left: 0;
      top: 0;
    }
    
    .memberHome .weui-tabbar__icon img{
           auto;
          height: 90%;
    }
    
     .memberHome .weui-tabbar__item.weui-bar__item_on .weui-tabbar__label{
        color: #DD5858
    }
    
    </style>
    
    

    store中是存储状态的

    //store.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    import mutations from './mutations'
    import actions from './actions'
    
    Vue.use(Vuex);
    export default new Vuex.Store({
    	modules:{
    		mutations
    	},
    	actions
    });
    
    
    
    //data.js相当于state
    
    //是否显示头部
    export const UPDATE_HEAD='UPDATE_HEAD';
    
    //是否显示loading
    export const UPDATE_LOADING='UPDATE_LOADING';
    
    //是否显示footer
    export const UPDATE_FOOTER='UPDATE_FOOTER';
    
    //页面标题
    export const UPDATE_PAGE_TITLE='UPDATE_PAGE_TITLE';
    
    //action.js
    //import 数据 from ''	这里面可以获取数据
    import * as data from './data'
    
    export default{
    
    	UPDATE_HEAD:({commit})=>{
    		commit(data.UPDATE_HEAD);
    	},
    	UPDATE_LOADING:({commit})=>{
    		commit(data.UPDATE_LOADING);
    	},
    	UPDATE_FOOTER:({commit})=>{
    		commit(data.UPDATE_FOOTER)
    	},
    	UPDATE_PAGE_TITLE:({commit})=>{
    		commit(data.UPDATE_PAGE_TITLE)
    	}
    }
    
    
    //mutations.js
    import {
    	UPDATE_HEAD,
    	UPDATE_LOADING,
    	UPDATE_FOOTER,
    	UPDATE_PAGE_TITLE
    } from './data'
    
    const state={
    	headShow:true,
    	loading:false,
    	footerShow:true,
    	pageTitle:'首页'
    };
    
    
    const mutations={
    	/*head*/
    	[UPDATE_HEAD](state,type){
    		state.headShow=type;
    	},
    	/*loading*/
    	[UPDATE_LOADING](state,type){
    		state.loading=type;
    	},
    	/*footer*/
    	[UPDATE_FOOTER](state,type){
    		state.footerShow=type;
    	},
    	/*title*/
    	[UPDATE_PAGE_TITLE](state,type){
    		state.pageTitle=type;
    	}
    };
    
    const getters={
    	headShow(state){
    		return state.headShow;
    	},
    	loading(state){
    		return state.loading;
    	},
    	footerShow(state){
    		return state.footerShow;
    	},
    	pageTitle(state){
    		return state.pageTitle;
    	}
    };
    
    export default{
    	state,
    	mutations,
    	getters
    }
    

    //activityIndex.vue
    <template>
      <div class="activityIndex page">
        <div class="activeItem" v-for="item in itemList">
          <router-link :to="'/memberHome/activityDetail/'+item.id">
              <div class="newsImg">
                 <img src="../../../assets/images/news-img.png"/>
              </div>
              <div class='sbottom'>
                <p class="title">{{item.title}}</p>
                <p class="time-line"><span  class='time'>{{item.startDate}} - {{item.endDate}}</span> 
                <span class="view"><span class="view_icon"><img src="../../../assets/images/icons/view.png"></span>{{item.viewer || 0}}人</span></p>
              </div>
            </router-link>
        </div>
    
      </div>
    </template>
    <script>
      import { Tabbar, TabbarItem ,XHeader,XButton,XImg} from 'vux'
      export default {
        mounted() {
          this.loadLatest();
          //插入头部
          this.$store.commit('UPDATE_PAGE_TITLE', '最新活动')
        },
        data(){
          return {
            itemList:''
          }
        },
        methods:{
          loadLatest(){
            //从后端取数据
              let self=this;
              this.baseAjax({
                url:'../../../static/basicData/latestActivity.json',
                showLoading:true,
                success:function(data){
                    console.log(data)
                    self.itemList=data.returnObject
                }
              })
          }
        },
        components: {
          Tabbar,
          TabbarItem,
          XHeader,
          XButton,
          XImg
        }
      }
    
    </script>
    <style>
      
    .activityIndex .activeItem{
      margin:10px 10px 0 10px;
      position: relative;
      height: 180px;
      overflow: hidden;
      border-radius: 5px
    }
    
    .activityIndex .activeItem .sbottom{
        color: white;
        position: absolute;
        bottom: 10px;
        padding: 10px;
         85%;
    }s
    
    
    .activityIndex .activeItem .title{
      font-size: 18px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    
    .activityIndex .time-line{
      font-size: 14px;
       100%;
      height: 20px;
    }
    
    .activityIndex .activeItem .view{
      float: right;
      font-size: 14px;
    }
    
     .activityIndex .activeItem .newsImg img{
         100%;
        min-height: 180px;
     }
    
     .activityIndex  .sbottom img{
            16px;
        height: 12px;
        padding-right: 5px;
     }
    </style>
    
    
    

    //activityDetail.vue
    <template>
    	<div class="activityDetail">
    		<div class="newsImg">
                 <img src="../../../assets/images/news-img.png"/>
    		</div>
    		<div class="detail-box">
    			<div class="text-top">
    				<p class="title">{{mainData.title}}</p>
    				<div class="sDate">
    					<flexbox>
    				      <flexbox-item>发布时间:{{mainData.publishDate}}</flexbox-item>
    				      <flexbox-item>浏览量:{{mainData.viewer}}</flexbox-item>
    					</flexbox>
    				</div>
    			</div>
    			<div class="detail-text">
    				<p v-html="mainData.content">
    					{{mainData.content}}
    				</p>
    			</div>
    		</div>
    		
    	</div>
    </template>
    <script>
    	import {Flexbox, FlexboxItem,XImg} from 'vux'
    
    	export default{
    		 mounted() {
    	      this.loadDetail();
    	      this.$store.commit('UPDATE_PAGE_TITLE', '活动详情');
    
    	    },
    	    data(){
    	      return {
    	        mainData:''
    	      }
    	    },
    	    methods:{
    	    	loadDetail(){
    	    		 let self=this;
    	    		 let id=this.$route.params.activityId;
    		          this.baseAjax({
    		            url:'../../../static/basicData/activityDetail.json',
    		            showLoading:true,
    		            success:function(data){
    		                console.log('data.returnObject',data.returnObject)
    		                self.mainData=data.returnObject		 
    		            }
    		          })
    	    	}	
    	    },
    
    	    components:{
    	    	Flexbox, FlexboxItem,XImg
    	    }
    	}
    </script>
    <style>
    
     .activityDetail .newsImg{
     	height:180px;
     	overflow: hidden;
     }
    
    .activityDetail .title{
    	font-size: 16px;
    	line-height: 22px;
    }
    
    .activityDetail .detail-text{
    	color: #666;
    	padding:10px 15px;
    }
    
    .activityDetail .detail-text p{
    	text-indent: 28px;
    	font-size: 14px;
    	line-height: 22px;
    	color: #666
    }
    
     .activityDetail .newsImg img{
         100%;
        min-height: 180px;
     }
    
      .activityDetail  .sDate{
    		margin-top: 10px;
    		font-size: 12px;
    		color: #666
     }
    
      .activityDetail  .text-top{
    		border-bottom: 1px solid #eee;
    		padding: 10px 15px 15px 15px; 
     }
    
    	
    </style>
    

    //mine.vue
    <template>
      <div clas="mine">
      	<h1>我的课程</h1>
      </div>
    </template>
    

    //personalCourses.js
    //封装的日期组件
    import { Tab, TabItem,XImg,dateFormat,XButton,Flexbox, FlexboxItem,InlineCalendar,Popup} from 'vux';
    
      let cnM=['一','二','三','四','五','六','七','八','九','十','十一','十二'];
    
      // 获取一周的日期
      // 获取当前星期的星期一的日期,返回的是一个Date对象。
      function getMonDate(dd){    //config为日期 例如:2016-04-19
          let d=new Date(dd);
          let day=d.getDay();
          let date=d.getDate();
          if(day==1)
          return d;
          if(day==0)
          d.setDate(date-6);
          else
          d.setDate(date-day+1);
          return d;
      }
    
      //获取一周的日期;
      function getWeekDate(self,confg){
          let d=getMonDate(confg);
          let wkd=new Date(confg).getDay();
          self.selectIndex=wkd==0?6:wkd-1
          for(var i=0;i<7;i++){
              self.dateList[i].date = d.getDate();
              self.dateList[i].configDate=dateFormat(new Date(d), 'YYYY-MM-DD');
              d.setDate(d.getDate()+1);
         }
      }
    
      export default {
        mounted() {
          this.$store.commit('UPDATE_PAGE_TITLE', '私教课')
          getWeekDate(this,this.myd);  //加载一周数据
          this.loadCourses();    //加载课程列表
        },
        data(){
          let self=this;
          let data={
              calendarDate:"",
              dateList :[
                {week:'周一',date:'',configDate:'',limit:false},
                {week:'周二',date:'',configDate:'',limit:false},
                {week:'周三',date:'',configDate:'',limit:false},
                {week:'周四',date:'',configDate:'',limit:false},
                {week:'周五',date:'',configDate:'',limit:false},
                {week:'周六',date:'',configDate:'',limit:false},
                {week:'周日',date:'',configDate:'',limit:false}
              ],
              myd:dateFormat(new Date(), 'YYYY-MM-DD'),
              pickMonth:cnM[new Date().getMonth()],
              pickDate:new Date().getDate(),
              selectIndex:null,
              courseList:'',
              showCalendar:false,
              weeksList:['日','一','二','三','四','五','六'],
              coursesQueryData:{
                  date:dateFormat(new Date(), 'YYYY-MM-DD'),
               }
    
    
           }
    
          return data
        },
        methods:{
    
          // 获取团体课列表
          loadCourses(){
              let self=this;
              //与后端交互请求后端数据
              this.baseAjax({
                url:'../../../static/basicData/personalCourse.json',
                params:{
                  date:self.coursesQueryData.date
                },
                showLoading:true,
                success:function(data){
                  console.log(data)
                    self.courseList=data.returnObject;
                }
              })
          },
          //选择日期
          calendarChange(date){
              if(date==this.coursesQueryData.date) return;
              getWeekDate(this,date);
              this.coursesQueryData.date=date;
              this.showCalendar=false;
              this.loadCourses();
          },
    
          //日期点击事件
          dateHandler(idx){
            this.selectIndex=idx;
            this.coursesQueryData.date=this.dateList[idx].configDate;
            this.loadCourses();
          },
    
          //打开日期控件
          openCalendar(){
            this.showCalendar=true;
          }
        },
        components: {
          Tab,TabItem,XImg,XButton,Flexbox, FlexboxItem,InlineCalendar,Popup
        }
      }
    
    //src/components/member/personalCourses/personalCourses.vue
    <template>
      <div class="personalCourses">
        <div class="topDate">
           <tab :animate=false :line-width="1">
              <tab-item disabled>
                  <div class='left-calendar' @click="openCalendar()" >
                    <p class="pickDate">{{pickDate}}</p>
                    <p class="pickMonth">{{pickMonth}}月</p>
                  </div>
              </tab-item>
              <tab-item @on-item-click="dateHandler(index)" v-for="(date,index) in dateList" :key="index" v-bind:class="{'vux-tab-selected': index==selectIndex ,'vux-tab-notSelected': index!=selectIndex}">
                    <p>{{date.week}}</p>
                    <p>{{date.date}}</p>
              </tab-item>
           </tab>
        </div>
        <div class="classItems">
        	<div class="item-box" v-for="(item,index) in courseList" :key="index">
        		 <flexbox>
                       <flexbox-item :span="3">
                       		<div class="item-icon">
                       			<img src="../../../assets/images/timg.png"/>
                       		</div>
                       </flexbox-item>
                       <flexbox-item>
                       		<div class="top-name">
                       			<flexbox>
              								<flexbox-item>
              									<div>{{item.name}}</div>
              									<p class="item-desc">{{item.description}}</p>
              								</flexbox-item>
              								<flexbox-item :span="4">
                                <router-link :to="'/memberHome/personalCourseDetail/'+item.id+'/'+coursesQueryData.date" v-show="item.status==1" >
                                   <x-button mini type="warn"  action-type='button' >预约</x-button>
                                </router-link>
                                <x-button mini type="default" v-show="item.status==2"  action-type='button' >已预约</x-button>
              								</flexbox-item>
              	            </flexbox>
                                 		</div>
                                 		<div class="bottom-cer">
              		                   	<span>{{item.certification}}</span>
              		                </div>
                              </flexbox-item>
              </flexbox>
        	</div>
        </div>
    
        <div>
          <popup v-model="showCalendar">
            <inline-calendar
              @on-change="calendarChange"
              class="my-inline-calendar"
              v-model="calendarDate"
              :weeks-list="weeksList"
              >
            </inline-calendar>
          </popup>
        </div>
    
      </div>
    </template>
    <script>
      import personalCourses  from  "./js/personalCourses.js"
      export default personalCourses
    </script>
    
    <style>
      .personalCourses .vux-tab .vux-tab-item{
        line-height: 20px;
      }
      
      .personalCourses .pickDate
      {
        color:#DD5858;
        font-size: 16px;
      }
    
      .personalCourses .classItems{
         margin-top: 60px;
      }
    
      .personalCourses .left-calendar{
        margin-left:5px;
        border-radius: 5px;
        background: #eee;
      }
    
      .personalCourses .vux-tab{
        height: 46px
      }
    
      .personalCourses .activeItem img{
         100%
     }
    
     .personalCourses .activeItem{
      margin:10px 10px 0 10px;
      position: relative;
      height: 180px;
      overflow: hidden;
      border-radius: 5px
    }
    
    .personalCourses .topDate{
       position: absolute;
       top: 52px;
       z-index: 10;
        100%;
    }
    
    .personalCourses .activeItem .sbottom{
      color: white;
      position: absolute;
      bottom: 10px;
      padding:10px;
       85%
    }
    
    
    .personalCourses .activeItem .title{
      font-size: 18px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    
    .personalCourses .time-line{
      font-size: 14px;
       100%;
      height: 20px;
    }
    
    .personalCourses .activeItem .view{
      float: right;
      font-size: 14px;
    }
    
     .personalCourses .activeItem img{
         100%
     }
    
     .personalCourses .vux-tab .vux-tab-item.vux-tab-disabled {
        color: #666;
    }
    
    .personalCourses .vux-tab .vux-tab-item.vux-tab-selected{
      color:#DD5858;
      border- 3px !important;
      border-bottom: 3px solid #DD5858;
    }
    
     .personalCourses .vux-tab .vux-tab-item.vux-tab-notSelected{
          border-bottom:1px solid #eee;
          color: #666
       }
    
       .personalCourses .inline-calendar td.current > span.vux-calendar-each-date {
        background-color: #DD5858;
      }
    
       .personalCourses .inline-calendar td.is-today{
        color:#DD5858;
      }
    
      .personalCourses  .item-box .item-icon{
    		height: 60px;
    		text-align: center;
    		overflow: hidden;
      }
    
       .personalCourses  .item-box .item-icon img{
    		height: 100%;
    		border-radius: 50%
       }
    
       .personalCourses  .item-box {
       		border-bottom:1px solid #eee;
       		background: #fff;
       }
    
       .personalCourses  .top-name{
       	   border-bottom:1px solid #eee;
       	   padding: 10px 0;
       	   margin-right: 10px;
       }
    
       .personalCourses  .item-desc{
       	    font-size:12px;
       	    line-height: 20px;
       	    color: #666
       }
    
       .personalCourses .bottom-cer{
       		padding:10px 0;
       		font-size:12px;
       	    color: #666
       }
       .personalCourses .bottom-cer span{
       	    padding: 5px;
    	    border-radius: 5px;
    	    background: #eee;
    	    margin: 5px;
       }
    
       .personalCourses button.weui-btn_mini{
         65px;
        padding: 0;
    }
    
    
    </style>
    

    //personalCourseDetail.vue
    <template>
      <div class="personalCourseDetail">
    		<div class="top-box">
    			<flexbox>
                   <flexbox-item :span="3">
                   		<div class="item-icon">
                   			<img src="../../../assets/images/timg.png"/>
                   		</div>
                   </flexbox-item>
                   <flexbox-item>
                   		<div class="top-name">
    						<div class="s-name"><span>{{mainData.name}}</span><span class="name-label">私教</span></div>
    						<p class="item-desc">{{mainData.description}}</p>
                   		</div>
                   		<div class="bottom-cer">
                   			<x-icon type="ios-clock-outline" size="20" class="icon-clock"></x-icon>
                   			<p><span>{{currentDate}}</span><span>({{currentDay}})</span></p>
    	                </div>
                    </flexbox-item>
    	          </flexbox>
    		</div>
    		<div>
    			<p class="remark">上课时间(时长:1小时)</p>
    		</div>
    		<div class="time-box">
    			<div v-for="(item,index) in timeList" class="time-item" :key="index">
    				<div class="group-head" @click="item.showList=!item.showList">
    	                <flexbox>
    	                   <flexbox-item :span="2">
    	                  		 <div  v-show="index==0" class="s-icon"><x-icon type="ios-partlysunny-outline" size="30"></x-icon></div>
    	                  		 <div  v-show="index==1" class="s-icon"><x-icon type="ios-sunny-outline" size="30"></x-icon></div>
    	                  		 <div  v-show="index==2" class="s-icon"><x-icon type="ios-moon-outline" size="30"></x-icon></div>
    	                   </flexbox-item>
    	                   <flexbox-item ><div>{{item.name}}</div></flexbox-item>
    	                   <flexbox-item :span="2"><div class="arrow-icon"><x-icon type="ios-arrow-down" size="20"></x-icon></div></flexbox-item>
    	                </flexbox>
             </div>
              <div class="list-box" v-show="item.showList">
                    <div class="checker-box">
                      <checker
                          v-model="checkTime"
                          type="checkbox"
                          default-item-class="checkTime-item"
                          selected-item-class="checkTime-item-selected"
                          disabled-item-class="checkTime-item-disabled"
                          >
                            <checker-item 
                              v-for="(sitem,sindex) in item.list" 
                              :key="sindex" 
                              :value="sitem.time" 
                              :disabled="!sitem.isEnable"
                              @on-item-click="checkMyTime(index,sitem.time,sitem.isEnable)">{{sitem.time}}
                            </checker-item>
                      </checker>
                    </div>
              </div>
    			</div>
          <div class="labels">
              <div class="is-allow">可选</div>
              <div class="no-allow">不可选</div>
              <div class="is-select">已选择</div>
          </div>
          <div class="bottom-btn" v-show="showReserveBtn">
              <x-button type="warn" @click.native="makeReserve">确定预约</x-button>
          </div>
    		</div>
        <toast v-model="showSuccess" type="text" class="showSuccess" :time="2000">预约成功</toast>
        <toast v-model="showError" type="text" class="showError" :time="2000">预约失败</toast>
        <toast v-model="showMsg" type="text" class="showMsg" :time="2000">请选择1h相邻的时间段</toast>
      </div>
    </template>
    <script>
      import personalCourseDetail  from  "./js/personalCourseDetail.js"
      export default personalCourseDetail
    </script>
    
    <style>
    
    	.personalCourseDetail .top-box{
    		background: #fff
    	}
    
    	.personalCourseDetail .item-icon{
    		height: 60px;
    		text-align: center;
    		overflow: hidden;
      }
    
       .personalCourseDetail .item-icon img{
    		height: 100%;
    		border-radius: 50%
       }
    
       .personalCourseDetail  .item-box {
       		border-bottom:1px solid #eee;
       		background: #fff;
       }
    
       .personalCourseDetail  .top-name{
       	   border-bottom:1px solid #eee;
       	   padding: 10px 0 5px 0;
       	   margin-right: 10px;
       }
    
       .personalCourseDetail  .item-desc{
       	    font-size:12px;
       	    line-height: 20px;
       	    color: #666;
            clear:both;
       }
    
       .personalCourseDetail .bottom-cer{
       		padding:10px 0;
       		font-size:12px;
       	    color: #666;
       	    position :relative;
       }
    
        .personalCourseDetail .bottom-cer p{
        	padding-left: 15px;
        	line-height: 20px;
        }
    	
    	.personalCourseDetail .bottom-cer p span{
    		padding-left: 10px
    	}
    
       .personalCourseDetail .icon-clock{
       		position:absolute;
       		fill: #666;
       }
    
       .personalCourseDetail .s-icon{
     	   padding-left: 20px
       }
    
    	 .personalCourseDetail .group-head{
    		 font-size: 14px;
    		 padding-top: 5px;
         border-bottom: 1px solid #eee
    	  }
    
       .personalCourseDetail .remark{
       	 height: 40px;
       	 font-size: 14px;
       	 line-height: 40px;
         color: #666;
       	 padding-left: 20px
       }
    
        .personalCourseDetail .time-box{
       	 background: #fff;
         padding-bottom:10px
         ;
       }
    
       .personalCourseDetail .checker-box{
          margin:15px;
       }
    
        .personalCourseDetail  .time-item{
    		   border-bottom: 1px solid #eee
       }
        .personalCourseDetail  .arrow-icon{
       	  text-align: right;
       	  padding-right: 15px;
    
       }
    
       .personalCourseDetail .checkTime-item {
    	   20%;
    	  height: 32px;
    	  line-height: 32px;
    	  text-align: center;
        border: 1px solid #ccc;
    	  background-color: #fff;
        color: #000;
        box-sizing: border-box;
    	}
    	.personalCourseDetail .checkTime-item-selected {
    	  background: #333333 url(../../../assets/images/bgIcon/select-icon.png) no-repeat right bottom;
        background-size:12px 10px;
    	  color: #fff;
        border: 1px solid #333333;
        border-right:1px solid #ccc;
    
    	}
      .personalCourseDetail .checkTime-item-disabled{
          background: #DEDCDC;
      }
    
      .personalCourseDetail .bottom-btn{
          padding:20px;
      }
    
      .personalCourseDetail .labels{
          margin:5px 30px;
          height: 30px;
          line-height: 30px
      }
    
        .personalCourseDetail .labels >div{
            float:left;
            margin-right: 20px;
            font-size: 12px;
            padding-left: 20px;
    
        }
    
        .personalCourseDetail .labels .is-allow{
            background: url(../../../assets/images/bgIcon/is-allow.png) no-repeat left center ;
            background-size:12px;
        }
    
        .personalCourseDetail .labels .no-allow{
            background: url(../../../assets/images/bgIcon/no-allow.png) no-repeat left center ;
            background-size:12px;
        }
    
        .personalCourseDetail .labels .is-select{
          background: url(../../../assets/images/bgIcon/is-select.png) no-repeat left center ;
          background-size:12px;
        }
    
        .personalCourseDetail .s-name span{
            height:30px;
            line-height: 30px;
            display:block;
            float: left;
        }
    
      .personalCourseDetail .s-name .name-label{
          background: #6B106A;
          color: #fff;
          font-size: 12px;
          height:20px;
          line-height: 20px;
          margin: 5px 10px;
          padding:0 10px;
        }
    
        .personalCourseDetail  .showSuccess .weui-toast__content{
             background: url(../../../assets/images/bgIcon/success.png) no-repeat left center ;
          background-size:20px;
        }
    
        .personalCourseDetail  .showSuccess .weui-toast{
          padding-left: 10px;
        }
    
    
    </style>
    
    //personalCourseDetail.js
    
    import { XImg,XButton,Flexbox, FlexboxItem,XDialog,Checker, CheckerItem,Toast} from 'vux';
    
    export default {
    	mounted(){
    		this.loadDetail();
    		this.$store.commit('UPDATE_PAGE_TITLE', '课程预约');
    	},
    	computed:{
    		currentDay(){
    			let date=this.$route.params.date;
    			let day=new Date(date).getDay();
    			let cnM=['日','一','二','三','四','五','六'];
    			return "周"+cnM[day]
    		}
    	},
    	data(){
    		let self=this;
    		let data={
    			mainData:{},
    			showSuccess:false,
    			showError:false,
    			showMsg:false,
    			currentDate:self.$route.params.date,
    			checkTime:[],
    			activeType:0,
    			timeListArr:[[],[],[]],
    			showReserveBtn:true,
    			timeList:[
    				{name:"上午",
    				list:[],
    				showList:false
    				},
    				{name:"下午",
    				list:[],
    				showList:false
    				},
    				{name:"晚上",
    				list:[],
    				showList:false
    				}
    			]
    		}
    		return data;
    	},
    	methods:{
    		// 获取详细信息
    		loadDetail(){
    			let self=this;
    	    	let courseId=this.$route.params.courseId;
    	    	let date=this.$route.params.date;
    		          this.baseAjax({
    		            url:'../../../static/basicData/personalDetail.json',
    		            showLoading:true,
    		            params:{
    		            	courseId:courseId,
    		            	date:date
    		            },
    		            success:function(data){
    		                self.mainData=data.returnObject[0];
    		                //从后端请求的~~不同人的数据不同
    		                self.computeTimeLost(self.mainData.scheduleTime)
    
    		        }
    		    })
    		},
    		// 计算时间列表
    		computeTimeLost(list){
    			let self=this;
    			let len=list.length;
    			for(let i=0;i<len;i++){
    				let type=list[i].type-1;
    				list[i].check=false;
    				self.timeList[type].list.push(list[i]);
    				self.timeListArr[type].push(list[i].time);
    
    			}
    			console.log(self.timeList)
    		},
    		//选中时间
    		checkMyTime(idx,val,isEnable){
    			if(!isEnable) return;
    			if(this.activeType!=idx){
    				this.checkTime=[val];
    				this.activeType=idx
    			}
    			console.log(this.checkTime)
    		},
    		//预定私教课
    		makeReserve(){
    			if(!this.validateTime()) return;
    			let self=this;
    	    	let courseId=this.$route.params.courseId;
    	    	let date=this.$route.params.date;
    		          this.baseAjax({
    		            url:'../../../static/basicData/makeReserve.json',
    		            type:'get',
    		            showLoading:true,
    		            params:{
    		            	courseId:courseId,
    		            	memberId:"666",
    		            	reservedTime:self.checkTime.join(","),
    		            	trainerId:"999"
    		            },
    		            success:function(data){
    		               console.log(data)
    		               if(data.isSuccess){
    		               		self.showSuccess=true;
    		               		self.showReserveBtn=false;
    		               }else{
    		               		self.showError=true;
    		               }
    		        }
    		    })
    		},
    		//预定私教课
    		validateTime(){
    			if(!this.checkTime || this.checkTime.length!=2){
    				this.showMsg=true;
    				return false
    			}
    			let type=this.activeType;
    			let tlist=this.timeListArr[type];
    			let t1=tlist.indexOf(this.checkTime[0]);
    			let t2=tlist.indexOf(this.checkTime[1]);
    			if(Math.abs(t1-t2) !=1){
    				this.showMsg=true;
    				return false
    			}
    			return true;
    
    		}
    
    	},
    	components:{
    		XImg,XButton,Flexbox, FlexboxItem,XDialog,Checker, CheckerItem,Toast
    	}
    }
    

    //groupCourses.vue
    <template>
      <div class="groupCourses">
        <div class="topDate">
           <tab :animate=false :line-width="1">
              <tab-item disabled>
                  <div class='left-calendar' @click="openCalendar()" >
                    <p class="pickDate">{{pickDate}}</p>
                    <p class="pickMonth">{{pickMonth}}月</p>
                  </div>
              </tab-item>
              <tab-item @on-item-click="dateHandler(index)" v-for="(date,index) in dateList" :key="index" v-bind:class="{'vux-tab-selected': index==selectIndex ,'vux-tab-notSelected': index!=selectIndex}">
                    <p>{{date.week}}</p>
                    <p>{{date.date}}</p>
              </tab-item>
           </tab>
           <div class="selectGroup">
              <div class="purpose">
                  <div class="purpose-name group-head" @click="showPurpose=!showPurpose">
                    <flexbox>
                       <flexbox-item :span="2"><div class="purpose-icon"><img src="../../../assets/images/icons/purpose_icon.png"></div></flexbox-item>
                       <flexbox-item ><div>目的-{{coursesQueryData.purposeName}}</div></flexbox-item>
                       <flexbox-item :span="2"><div class="arrow-icon"><x-icon type="ios-arrow-down" size="20"></x-icon></div></flexbox-item>
                    </flexbox>
                  </div>
                  <div class="purpose-items group-items" v-show="showPurpose">
                       <p v-for="item in purposeList" @click="queryByPurpose(item)">{{item.name}}</p>
                  </div>
              </div>
              <div class="categoryName">
                  <div class="category-name group-head" @click="showCategory=!showCategory">
                    <flexbox>
                       <flexbox-item :span="2"><div class="purpose-icon"><img src="../../../assets/images/icons/category_icon.png"></div></flexbox-item>
                       <flexbox-item ><div>分类-{{coursesQueryData.categoryName}}</div></flexbox-item>
                       <flexbox-item :span="2"><div class="arrow-icon"><x-icon type="ios-arrow-down" size="20"></x-icon></div></flexbox-item>
                    </flexbox>
                  </div>
                  <div class="category-items group-items" v-show="showCategory">
                      <p v-for="item in categoryList" @click="queryByCategory(item)">{{item.name}}</p>
                  </div>
              </div>
           </div>
        </div>
        <div class="classItems">
          <div class="activeItem" v-for="(item,index) in courseList" :key="index">
              <img src="../../../assets/images/news-img.png"/>
              <div class='sbottom'>
                <p class="title">{{item.title}}</p>
                <p class="time-line"><span  class='time'>{{item.startTime}} - {{item.endTime}}</span> 
                <span class="view">{{item.viewer}}</span></p>
              </div>
              <div class="qtyProgress">
                <div class='qbar' v-bind:style="{  item.barWidth,background:item.bgColor}">
                </div>
                <div class="qty"><span>{{item.reservation}}</span> / <span>{{item.personMax}}</span></div>
              </div>
              <div class="bookBtn">
                  <x-button  mini type="warn"  action-type='button'  @click.native="makeReserve(item.id,index)">预约</x-button>
                  <!-- <x-button  mini  action-type='button' type="default">已预约</x-button> -->
              </div>
          </div>
        </div>
        <div>
          <popup v-model="showCalendar">
            <inline-calendar
              @on-change="calendarChange"
              class="my-inline-calendar"
              v-model="calendarDate"
              :weeks-list="weeksList"
              >
            </inline-calendar>
          </popup>
        </div>
        <div>
            <x-dialog v-model="showSuccess" class="d-box" @click="showSuccess=false">
                 <div @click="showSuccess=false">
                   <div class="d-icon">
                      <img src="../../../assets/images/dialog-success.png">
                   </div>
                   <p class="d-title">预约成功,记得准时签到噢!</p>
                 </div>
            </x-dialog>
            <x-dialog v-model="showSorry" class="d-box" >
                <div @click="showSorry=false">
                  <div class="d-icon">
                        <img src="../../../assets/images/dialog-sorry.png">
                     </div>
                     <p class="d-title">人数已满,下次记得早点预约噢!</p>
                </div>
            </x-dialog>
        </div>
    
      </div>
    </template>
    <script>
      import groupCourses  from  "./js/groupCourses.js"
      export default groupCourses
    </script>
    
    <style>
      .groupCourses .vux-tab .vux-tab-item{
        line-height: 20px;
      }
      
      .groupCourses .pickDate
      {
        color:#DD5858;
        font-size: 16px;
      }
    
      .groupCourses .classItems{
         margin-top: 145px;
      }
    
      .groupCourses .left-calendar{
        margin-left:5px;
        border-radius: 5px;
        background: #eee;
      }
    
      .groupCourses .vux-tab{
        height: 46px
      }
    
      .groupCourses .activeItem img{
         100%
     }
    
     .groupCourses .activeItem{
      margin:10px 10px 0 10px;
      position: relative;
      height: 180px;
      overflow: hidden;
      border-radius: 5px
    }
    
    .groupCourses .topDate{
       position: absolute;
       top: 52px;
       z-index: 10;
        100%;
    }
    
    .groupCourses .activeItem .sbottom{
      color: white;
      position: absolute;
      bottom: 10px;
      padding:10px;
       85%
    }
    
    
    .groupCourses .activeItem .title{
      font-size: 18px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    
    .groupCourses .time-line{
      font-size: 14px;
       100%;
      height: 20px;
    }
    
    .groupCourses .activeItem .view{
      float: right;
      font-size: 14px;
    }
    
     .groupCourses .activeItem img{
         100%
     }
    
     .groupCourses .vux-tab .vux-tab-item.vux-tab-disabled {
        color: #666;
    }
    
    .groupCourses .vux-tab .vux-tab-item.vux-tab-selected{
      color:#DD5858;
      border- 3px !important;
      border-bottom: 3px solid #DD5858;
    }
    .groupCourses .bookBtn{
        position: absolute;
        bottom: 20px;
        right: 20px;
    }
    .groupCourses button.weui-btn_mini{
         65px;
        padding: 0;
    }
    
    .groupCourses .selectGroup{
      background: #fff
    }
    
    .groupCourses .group-head{
        padding: 10px 0 5px 0;
        font-size: 14px;
        border-bottom: 1px solid #eee
    }
    
    .groupCourses .purpose-icon, .groupCourses .category-icon{
      text-align: right;
      padding-right: 10px
    }
    .groupCourses .purpose-icon img{
        height:20px;
     }
    
     .groupCourses .arrow-icon{
      text-align: right;
      padding-right: 15px;
     }
    
      .groupCourses .group-items{
        padding:0 30px;
        border-bottom: 1px solid #eee
     }
     .groupCourses .group-items p{
          overflow: hidden;
          text-align: center;
          font-size: 14px;
          height: 30px;
          line-height:30px;
          color: #666;
    
       }
    
     .groupCourses .vux-tab .vux-tab-item.vux-tab-notSelected{
          border-bottom:1px solid #eee;
          color: #666
       }
    
       .groupCourses .inline-calendar td.current > span.vux-calendar-each-date {
        background-color: #DD5858;
      }
    
       .groupCourses .inline-calendar td.is-today{
        color:#DD5858;
      }
    
      .groupCourses .qtyProgress{
         70px;
        position: absolute;
        top: 10px;
        left: 10px;
        border-radius: 10px;
        height: 20px;
        line-height: 20px;
        font-size: 12px;
        text-align: center;
        background: #666;
        color: #fff
      }
    
      .groupCourses .qbar{
        border-radius: 10px;
        position: absolute;
        height: 100%;
        top: 0
      }
    
      .groupCourses .qty{
        text-align: center;
         100%;
        border-radius: 10px;
        position: absolute;
        height: 100%;
        top: 0
      }
    
      .groupCourses .d-box .d-title{
          margin-bottom:15px;
      }
    
      .groupCourses .d-box  .weui-dialog{
         max- 240px;
      }
    
       .groupCourses .d-icon{
          text-align: center;
          padding:10px;
       }
    
      .groupCourses .d-icon img{
          height: 70px;
          margin:15px auto;
      }
    
    </style>
    
    //groupCourses.js
    import { Tab, TabItem,XImg,dateFormat,XButton,Flexbox, FlexboxItem,InlineCalendar,Popup,XDialog} from 'vux';
    
      let cnM=['一','二','三','四','五','六','七','八','九','十','十一','十二'];
    
      // 获取一周的日期
      // 获取当前星期的星期一的日期,返回的是一个Date对象。
      function getMonDate(dd){    //config为日期 例如:2016-04-19
          let d=new Date(dd);
          let day=d.getDay();
          let date=d.getDate();
          if(day==1)
          return d;
          if(day==0)
          d.setDate(date-6);
          else
          d.setDate(date-day+1);
          return d;
      }
    
      //获取一周的日期;
      function getWeekDate(self,confg){
          let d=getMonDate(confg);
          let wkd=new Date(confg).getDay();
          self.selectIndex=wkd==0?6:wkd-1
          for(var i=0;i<7;i++){
              self.dateList[i].date = d.getDate();
              self.dateList[i].configDate=dateFormat(new Date(d), 'YYYY-MM-DD');
              d.setDate(d.getDate()+1);
         }
      }
    
      export default {
        mounted() {
          this.$store.commit('UPDATE_PAGE_TITLE', '团体课')
          getWeekDate(this,this.myd);  //加载一周数据
          this.loadCourses();    //加载课程列表
        },
        data(){
          let self=this;
          let data={
            showSuccess:false,
            showSorry:false,
            calendarDate:"",
              dateList :[
                {week:'周一',date:'',configDate:'',limit:false},
                {week:'周二',date:'',configDate:'',limit:false},
                {week:'周三',date:'',configDate:'',limit:false},
                {week:'周四',date:'',configDate:'',limit:false},
                {week:'周五',date:'',configDate:'',limit:false},
                {week:'周六',date:'',configDate:'',limit:false},
                {week:'周日',date:'',configDate:'',limit:false}
              ],
    
               myd:dateFormat(new Date(), 'YYYY-MM-DD'),
               pickMonth:cnM[new Date().getMonth()],
               pickDate:new Date().getDate(),
               selectIndex:null,
               courseList:'',
               showCategory:false,
               showPurpose:false,
               showCalendar:false,
               categoryList:[
                 {name:'全部',id:'1009'},
                 {name:'减肥',id:'1009'},
                 {name:'增肌',id:'1009'}
               ],
              purposeList:[
                 {name:'全部',id:'1009'},
                 {name:'健身操',id:'1009'},
                 {name:'瑜伽',id:'1009'},
                 {name:'动感单车',id:'1009'}
              ],
              weeksList:['日','一','二','三','四','五','六'],
              coursesQueryData:{
                  categoryId:"ioio",
                  date:dateFormat(new Date(), 'YYYY-MM-DD'),
                  purposeId:'yuyuy',
                  categoryName:"全部",
                  purposeName:"全部"
               }
    
    
           }
    
          return data
        },
        methods:{
    
          // 获取团体课列表
          loadCourses(){
              let self=this;
              //与后端交互获取数据
              this.baseAjax({
                url:'../../../static/basicData/groupCourse.json',
                params:{
                  categoryId:self.coursesQueryData.categoryId,
                  date:self.coursesQueryData.date,
                  purposeId:self.coursesQueryData.purposeId,
                },
                showLoading:true,
                success:function(data){
                  console.log(data)
                    self.courseList=data.returnObject;
                    self.computListBar()
                }
              })
          },
          //选择日期
          calendarChange(date){
              if(date==this.coursesQueryData.date) return;
              getWeekDate(this,date);
              this.coursesQueryData.date=date;
              this.showCalendar=false;
              this.loadCourses();
          },
    
          //头部参课人数
          computListBar(){
              var self=this;
              var len=self.courseList.length;
              for(var i=0;i<len;i++){
                  var widthNo=(self.courseList[i].reservation/self.courseList[i].personMax).toFixed(2);
                  self.courseList[i].barWidth=widthNo*100+"%";
                    if(widthNo<=0.5) {
                      self.courseList[i].bgColor="#4FCC51"
                    }else if(widthNo>0.5 && widthNo!=1) {
                      self.courseList[i].bgColor="#E16F34";
                    }else if(widthNo==1){
                      self.courseList[i].bgColor="#DD5858";
                    }
                }
          },
    
          //日期点击事件
          dateHandler(idx){
            this.selectIndex=idx;
            this.coursesQueryData.date=this.dateList[idx].configDate;
            this.loadCourses();
          },
    
          //打开日期控件
          openCalendar(){
            this.showCalendar=true;
          },
          //预定团体课程
          makeReserve(id,idx){
            let self=this;
            if(self.courseList[idx].reservation==self.courseList[idx].personMax){
              self.showSorry=true;
              return;
            }
              this.baseAjax({
                url:'../../../static/basicData/makeReserve.json',
                get:"post",
                params:{
                  courseId:id,
                  memberId:"111"
                },
                showLoading:true,
                success:function(data){
                  if(data.isSuccess){
                      self.courseList[idx].reservation=self.courseList[idx].reservation+1;
                      self.showSuccess=true;
                      self.computListBar();
                  }
                }
              })
          },
          //目的筛选课程
          queryByPurpose(item){
            this.showCategory=false;
            this.showPurpose=false;
            this.coursesQueryData.purposeId=item.id;
            this.coursesQueryData.purposeName=item.name;
            this.loadCourses();
          },
          //类别筛选课程
          queryByCategory(item){
            this.showCategory=false;
            this.showPurpose=false;
            this.coursesQueryData.categoryId=item.id;
            this.coursesQueryData.categoryName=item.name;
            this.loadCourses();
          }
        },
        components: {
          Tab,TabItem,XImg,XButton,Flexbox, FlexboxItem,InlineCalendar,Popup,XDialog
        }
      }
    

    表白这位小姐姐,爱你呀谢谢你无私分享的精神鸭

  • 相关阅读:
    Webpack教程二
    Webpack教程一
    整个互联网行业都缺前端工程师?
    Sublime Text 3 搭建 React.js 开发环境
    Javascript的9张思维导图学习
    实现字体外部有描边
    CSS样式重置
    vue使用过滤器 filters:{}
    修改select的默认样式
    onmouseover和onmouseout鼠标移入移出切换图片的几种实现方法
  • 原文地址:https://www.cnblogs.com/smart-girl/p/10819272.html
Copyright © 2011-2022 走看看