7 Commits d46bfb934e ... 859fa17ff8

Author SHA1 Message Date
  seamwang 859fa17ff8 Merge branch 'master' into dev_seam_intelligent 1 year ago
  seamwang f92ae6281c no message 1 year ago
  seamwang 892d8dba35 no message 1 year ago
  seamwang 5b00e0734f no message 1 year ago
  seamwang 56ffd847c5 Merge branch 'master' into dev_seam_intelligent 1 year ago
  seamwang fa1f4f0845 Merge branch 'master' into dev_seam_intelligent 2 years ago
  seamwang e1e4e90b07 no message 2 years ago

+ 5 - 1
src/api/course.js

@@ -112,10 +112,14 @@ export function _commentDetail (params) {
112 112
 export function _leaveType (params) {
113 113
 	return fetch('/teacher/leave/get_leave_type', params)
114 114
 }
115
-// 申请请假 parents/schedule/student_leave
115
+// 申请请假
116 116
 export function _askLeave (params) {
117 117
 	return fetch('/parents/schedule/student_leave', params)
118 118
 }
119
+//获取学生课程档案
120
+export function _getStudentFiles (params) {
121
+	return fetch('/parents/courseFiles/get_list', params)
122
+}
119 123
 //获取年级
120 124
 export function _getGrades () {
121 125
 	return fetch('/parents/init/get_grades')

+ 44 - 43
src/common/commonMethods.js

@@ -2,55 +2,56 @@
2 2
 import urlMap from '@/common/urlMap'
3 3
 
4 4
 const encodeParam = function (params) {
5
-  let url = ''
6
-  for (const k in params) {
7
-    const value = params[k] !== undefined ? params[k] : ''
8
-    url += '&' + k + '=' + encodeURIComponent(value)
9
-  }
10
-  return url ? url.substring(1) : ''
5
+	let url = ''
6
+	for (const k in params) {
7
+		const value = params[k] !== undefined ? params[k] : ''
8
+		url += '&' + k + '=' + encodeURIComponent(value)
9
+	}
10
+	return url ? url.substring(1) : ''
11 11
 }
12 12
 
13 13
 const routerToFail = function (err) {
14
-  console.log(err, '跳转新页面失败')
14
+	console.log(err, '跳转新页面失败')
15 15
 }
16 16
 
17 17
 const commonMethods = {
18
-  /**
19
-   * 保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面
20
-   * 页面跳转路径有层级限制,不能无限制跳转新页面
21
-   * @param {*} type 路径唯一类型
22
-   * @param {*} params 路径参数
23
-   * @returns {*} null
24
-   */
25
-  globalNavigateTo: function (type, params) {
26
-    if (urlMap.has(type)) {
27
-      let url = urlMap.get(type)
28
-      if (params) {
29
-        url += (url.indexOf('?') < 0 && params ? '?' : '&') + encodeParam(params)
30
-      }
31
-      uni.navigateTo({ url, fail: routerToFail })
32
-    }
33
-  },
34
-  // 关闭当前页面,跳转到应用内的某个页面
35
-  globalRedirectTo: function (type, params) {
36
-    if (urlMap.has(type)) {
37
-      let url = urlMap.get(type)
38
-      if (params) {
39
-        url += (url.indexOf('?') < 0 && params ? '?' : '&') + encodeParam(params)
40
-      }
41
-      uni.redirectTo({ url, fail: routerToFail })
42
-    }
43
-  },
44
-  // 关闭所有页面,打开应用内的某个页面
45
-  globalReLaunch: function (type, params) {
46
-    if (urlMap.has(type)) {
47
-      let url = urlMap.get(type)
48
-      if (params) {
49
-        url += (url.indexOf('?') < 0 && params ? '?' : '&') + encodeParam(params)
50
-      }
51
-      uni.reLaunch({ url, fail: routerToFail })
52
-    }
53
-  }
18
+	encodeParam,
19
+	/**
20
+	 * 保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面
21
+	 * 页面跳转路径有层级限制,不能无限制跳转新页面
22
+	 * @param {*} type 路径唯一类型
23
+	 * @param {*} params 路径参数
24
+	 * @returns {*} null
25
+	 */
26
+	globalNavigateTo: function (type, params) {
27
+		if (urlMap.has(type)) {
28
+			let url = urlMap.get(type)
29
+			if (params) {
30
+				url += (url.indexOf('?') < 0 && params ? '?' : '&') + encodeParam(params)
31
+			}
32
+			uni.navigateTo({ url, fail: routerToFail })
33
+		}
34
+	},
35
+	// 关闭当前页面,跳转到应用内的某个页面
36
+	globalRedirectTo: function (type, params) {
37
+		if (urlMap.has(type)) {
38
+			let url = urlMap.get(type)
39
+			if (params) {
40
+				url += (url.indexOf('?') < 0 && params ? '?' : '&') + encodeParam(params)
41
+			}
42
+			uni.redirectTo({ url, fail: routerToFail })
43
+		}
44
+	},
45
+	// 关闭所有页面,打开应用内的某个页面
46
+	globalReLaunch: function (type, params) {
47
+		if (urlMap.has(type)) {
48
+			let url = urlMap.get(type)
49
+			if (params) {
50
+				url += (url.indexOf('?') < 0 && params ? '?' : '&') + encodeParam(params)
51
+			}
52
+			uni.reLaunch({ url, fail: routerToFail })
53
+		}
54
+	}
54 55
 }
55 56
 
56 57
 export default commonMethods

+ 11 - 0
src/common/css/common.css

@@ -122,6 +122,13 @@ input{
122 122
 .bg-student{
123 123
 	background-color:#5fd0e4;
124 124
 }
125
+.bg-teacher{
126
+	background-color:#37CAA0;
127
+}
128
+.bg-light-green{
129
+	color:#fff;
130
+	background-color:#09e294;
131
+}
125 132
 .bg-normal{
126 133
 	background-color: #4DB8E4;
127 134
 }
@@ -172,6 +179,10 @@ input{
172 179
 	width:128rpx;
173 180
 	height:128rpx;
174 181
 }
182
+.avatar.xl{
183
+	width:180rpx;
184
+	height:180rpx;
185
+}
175 186
 .avatar.md{
176 187
 	width:96rpx;
177 188
 	height:96rpx;

+ 2 - 0
src/common/urlMap.js

@@ -25,5 +25,7 @@ urlMap.set('classCart', '/pages/class/shoppingCart')
25 25
 urlMap.set('bindPhone', '/pages/class/bindPhone')
26 26
 urlMap.set('order', '/pages/order/index')
27 27
 urlMap.set('agreement', '/pages/agreement/index')
28
+urlMap.set('courseFiles', '/pages/mine/courseFiles')
29
+urlMap.set('fileDetail', '/pages/mine/fileDetail')
28 30
 
29 31
 export default urlMap

+ 105 - 0
src/components/star-rating.vue

@@ -0,0 +1,105 @@
1
+<template>
2
+  <view class="star-rating">
3
+    <view class="star-rating-box" @touchstart="fun" @touchmove.stop.prevent="fun">
4
+      <image v-for="(item, i) in max" :key="i" class="icon-start" :src="(i + 1) | getSrc(score)" mode=""></image>
5
+    </view>
6
+    <text class="star-rating-title">{{ title }}</text>
7
+  </view>
8
+</template>
9
+
10
+<script>
11
+export default {
12
+  name: 'star-rating',
13
+  data() {
14
+    return {
15
+      iconStartSrcList: [
16
+        '/static/imgs/star-rating/delivery_icon_star_empty.png',
17
+        '/static/imgs/star-rating/delivery_icon_star_disable.png',
18
+        '/static/imgs/star-rating/delivery_icon_star_active.png'
19
+      ],
20
+      title: '',
21
+      width: 0
22
+    }
23
+  },
24
+  props: {
25
+    max: {
26
+      type: Number,
27
+      default: 5
28
+    },
29
+    name: {
30
+      type: String,
31
+      default: ''
32
+    },
33
+    score: {
34
+      type: Number,
35
+      default: 0
36
+    }
37
+  },
38
+  methods: {
39
+    fun(e) {
40
+      let score = Math.ceil(((e.changedTouches[0].pageX - e.currentTarget.offsetLeft) / this.width) * 5)
41
+      if (score >= 5) score = 5
42
+      if (score <= 0) score = 0
43
+      this.$emit('changeScore', {
44
+        name: this.name,
45
+        score
46
+      })
47
+    },
48
+    getDescBox() {
49
+      uni
50
+        .createSelectorQuery()
51
+        .in(this)
52
+        .select('.star-rating-box')
53
+        .boundingClientRect(result => {
54
+          if (result) {
55
+            this.width = result.width
56
+          } else {
57
+            this.getDescBox()
58
+          }
59
+        })
60
+        .exec()
61
+    }
62
+  },
63
+  mounted() {
64
+    this.$nextTick(() => {
65
+      this.getDescBox()
66
+    })
67
+  },
68
+  filters: {
69
+    getSrc: function (i, score) {
70
+      if (score == 0) return '/static/imgs/star-rating/delivery_icon_star_empty.png'
71
+      if (score < i) return '/static/imgs/star-rating/delivery_icon_star_disable.png'
72
+      if (score >= i) return '/static/imgs/star-rating/delivery_icon_star_active.png'
73
+    }
74
+  },
75
+  watch: {
76
+    score(val) {
77
+      if (val == 0) this.title = ''
78
+      if (val == 1) this.title = '非常差'
79
+      if (val == 2) this.title = '差'
80
+      if (val == 3) this.title = '一般'
81
+      if (val == 4) this.title = '满意'
82
+      if (val == 5) this.title = '非常满意'
83
+    }
84
+  }
85
+}
86
+</script>
87
+
88
+<style lang="scss">
89
+.star-rating {
90
+  display: flex;
91
+  align-items: center;
92
+
93
+  .icon-start {
94
+    width: 30rpx;
95
+    height: 30rpx;
96
+    margin: 0 6rpx;
97
+  }
98
+
99
+  .star-rating-title {
100
+    padding-left: 30rpx;
101
+    color: #999;
102
+    font-size: 24rpx;
103
+  }
104
+}
105
+</style>

+ 9 - 1
src/pages.json

@@ -95,11 +95,19 @@
95 95
     {
96 96
       "path": "pages/agreement/index",
97 97
       "style": {}
98
+    },
99
+    {
100
+      "path": "pages/mine/courseFiles",
101
+      "style": {}
102
+    },
103
+    {
104
+      "path": "pages/mine/fileDetail",
105
+      "style": {}
98 106
     }
99 107
   ],
100 108
   "globalStyle": {
101 109
     "navigationBarBackgroundColor": "#FFFFFF",
102
-    "navigationBarTitleText": "1212",
110
+    "navigationBarTitleText": "课后百科",
103 111
     "navigationStyle": "custom",
104 112
     "navigationBarTextStyle": "black",
105 113
     "animationType": "slide-out-right"

+ 59 - 65
src/pages/class/detail.vue

@@ -1,22 +1,20 @@
1 1
 <template>
2 2
   <view class="page">
3 3
     <cu-custom :isBack="true"></cu-custom>
4
-    <view class="header" :style="[{top:topHeader + 'px'}]">
4
+    <view class="header" :style="[{ top: topHeader + 'px' }]">
5 5
       <view class="header-title">
6 6
         <view class="header-title-main">
7
-          <view class="margin-bottom-xs">{{tabList[cate_type].title}}</view>
7
+          <view class="margin-bottom-xs">{{ tabList[cate_type].title }}</view>
8 8
           <view class="point"></view>
9 9
         </view>
10 10
       </view>
11 11
       <swiper-tab :menuList="tabList[cate_type].list" @changeTab="changeTab"></swiper-tab>
12 12
     </view>
13
-    <scroll-view v-if="currentIndex===0" :scroll-y="true" :style="[{height:'calc(100vh - 70px - '+ topHeader+'px)'}]"
14
-      class="scroll-main">
13
+    <scroll-view v-if="currentIndex === 0" :scroll-y="true" :style="[{ height: 'calc(100vh - 70px - ' + topHeader + 'px)' }]" class="scroll-main">
15 14
       <view class="content">
16 15
         <view class="course-img">
17
-          <swiper class="swiper" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay"
18
-            :interval="swiper.interval" :duration="swiper.duration">
19
-            <swiper-item v-for="(item,index) in detail.image" :key="index">
16
+          <swiper class="swiper" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval" :duration="swiper.duration">
17
+            <swiper-item v-for="(item, index) in detail.image" :key="index">
20 18
               <view class="swiper-item">
21 19
                 <image :src="item" mode="widthFix"></image>
22 20
               </view>
@@ -25,66 +23,67 @@
25 23
         </view>
26 24
         <!-- 详情 -->
27 25
         <view class="detail">
28
-          <view class="detail-title">{{detail.name}}</view>
26
+          <view class="detail-title">{{ detail.name }}</view>
29 27
           <view class="detail-item">
30 28
             <view class="detail-item-point"></view>
31 29
             <view class="detail-label">周期</view>
32
-            <view class="detail-text">{{detail.period}}<text class="text-gray">({{detail.time[0]}})</text></view>
30
+            <view class="detail-text"
31
+              >{{ detail.period }}<text class="text-gray">({{ detail.time[0] }})</text></view
32
+            >
33 33
           </view>
34 34
           <view class="detail-item">
35 35
             <view class="detail-item-point"></view>
36 36
             <view class="detail-label">适用年级</view>
37
-            <view class="detail-text">{{detail.grade}}年级通用</view>
37
+            <view class="detail-text">{{ detail.grade }}年级通用</view>
38 38
           </view>
39 39
           <view class="detail-item">
40 40
             <view class="detail-item-point"></view>
41 41
             <view class="detail-label">课时</view>
42
-            <view class="detail-text">{{detail.class_total}}课时</view>
42
+            <view class="detail-text">{{ detail.class_total }}课时</view>
43 43
           </view>
44 44
           <view class="detail-item">
45 45
             <view class="detail-item-point"></view>
46 46
             <view class="detail-label">单课时价</view>
47
-            <view class="detail-text">¥{{detail.single_money}}</view>
47
+            <view class="detail-text">¥{{ detail.single_money }}</view>
48 48
           </view>
49 49
           <view class="detail-item">
50 50
             <view class="detail-item-point"></view>
51 51
             <view class="detail-label">补贴</view>
52
-            <view class="detail-text">¥{{detail.subsidy}}/节课</view>
52
+            <view class="detail-text">¥{{ detail.subsidy }}/节课</view>
53 53
           </view>
54 54
           <view class="detail-item">
55 55
             <view class="detail-item-point"></view>
56 56
             <view class="detail-label">培养目标</view>
57
-            <view class="detail-text">{{detail.tenet}}</view>
57
+            <view class="detail-text">{{ detail.tenet }}</view>
58 58
           </view>
59 59
         </view>
60 60
       </view>
61 61
       <!-- 老师介绍 -->
62
-      <view class="teacher flex margin-top-sm shadow" v-if="cate_type===0">
62
+      <view class="teacher flex margin-top-sm shadow" v-if="cate_type === 0">
63 63
         <image mode="scaleToFill" :src="defaultTeacher" class="avatar lg"></image>
64 64
         <view class="flex-sub margin-left">
65
-          <view class="teacher-title">{{detail.teachers.username||''}}老师授课</view>
66
-          <view class="teacher-item">毕业于{{detail.teachers.agency_name||''}}</view>
67
-          <view class="teacher-item">所属机构:{{detail.teachers.orz||''}}</view>
65
+          <view class="teacher-title">{{ detail.teachers.username || '' }}老师授课</view>
66
+          <view class="teacher-item">毕业于{{ detail.teachers.agency_name || '' }}</view>
67
+          <view class="teacher-item">所属机构:{{ detail.teachers.orz || '' }}</view>
68 68
           <view class="teacher-exp flex">
69
-            <view class="exp-item">{{detail.teachers.honor||''}}</view>
70
-            <view class="exp-item">{{detail.teachers.introduce||''}}</view>
69
+            <view class="exp-item">{{ detail.teachers.honor || '' }}</view>
70
+            <view class="exp-item">{{ detail.teachers.introduce || '' }}</view>
71 71
           </view>
72 72
         </view>
73 73
       </view>
74 74
       <!-- 道具选择 -->
75
-      <view class="shop margin-top-sm shadow" v-if="detail.prop&&detail.prop.length>0">
75
+      <view class="shop margin-top-sm shadow" v-if="detail.prop && detail.prop.length > 0">
76 76
         <view class="shop-title">请选择课程所需要的道具</view>
77 77
         <radio-group @change="radioChange" class="margin-top-xs">
78 78
           <label v-for="radio in radios" :key="radio.value" class="tool-choose margin-right-sm">
79
-            <radio :value="radio.value" class="cyan" :checked="radio.checked" style="transform:scale(0.7)" />
80
-            {{radio.name}}
79
+            <radio :value="radio.value" class="cyan" :checked="radio.checked" style="transform: scale(0.7);" />
80
+            {{ radio.name }}
81 81
           </label>
82 82
         </radio-group>
83
-        <checkbox-group @change="checkboxChange" v-if="needTool==='1'" class="checkbox-group margin-top-xs">
83
+        <checkbox-group @change="checkboxChange" v-if="needTool === '1'" class="checkbox-group margin-top-xs">
84 84
           <label v-for="prop in detail.prop" :key="prop.id">
85 85
             <view class="tool-choose-item">
86
-              <checkbox :value="prop.id" class="cyan" style="transform:scale(0.7)"
87
-                :checked="goods.props.includes(prop.id)" />{{prop.name}}<text>¥{{prop.money}}</text>
86
+              <checkbox :value="prop.id" class="cyan" style="transform: scale(0.7);" :checked="goods.props.includes(prop.id)" />{{ prop.name }}<text>¥{{ prop.money }}</text>
88 87
             </view>
89 88
           </label>
90 89
         </checkbox-group>
@@ -95,18 +94,17 @@
95 94
       </view>
96 95
     </scroll-view>
97 96
     <!-- 评价页 -->
98
-    <scroll-view :style="[{height:'calc(100vh - 70px - '+ topHeader+'px)'}]" class="scroll-main"
99
-      v-if="currentIndex===1">
97
+    <scroll-view :style="[{ height: 'calc(100vh - 70px - ' + topHeader + 'px)' }]" class="scroll-main" v-if="currentIndex === 1">
100 98
       <view class="cu-list menu-avatar comment">
101
-        <view class="cu-item" v-for="(comment,index) in comments" :key="index">
99
+        <view class="cu-item" v-for="(comment, index) in comments" :key="index">
102 100
           <image mode="scaleToFill" :src="comment.img" class="avatar md left"></image>
103 101
           <view class="content">
104
-            <view class="text-grey">{{comment.name}}</view>
102
+            <view class="text-grey">{{ comment.name }}</view>
105 103
             <view class="text-gray text-content text-df">
106
-              {{comment.content}}
104
+              {{ comment.content }}
107 105
             </view>
108 106
             <view class="margin-top-sm flex justify-between">
109
-              <view class="text-gray text-df">{{comment.date}}</view>
107
+              <view class="text-gray text-df">{{ comment.date }}</view>
110 108
               <!-- <view>
111 109
 									<text class="cuIcon-appreciatefill text-red"></text>
112 110
 									<text class="cuIcon-messagefill text-gray margin-left-sm"></text>
@@ -117,44 +115,40 @@
117 115
       </view>
118 116
     </scroll-view>
119 117
     <!-- 视频页 -->
120
-    <scroll-view :style="[{height:'calc(100vh - 70px - '+ topHeader+'px)'}]" class="scroll-main"
121
-      v-if="currentIndex===2">
118
+    <scroll-view :style="[{ height: 'calc(100vh - 70px - ' + topHeader + 'px)' }]" class="scroll-main" v-if="currentIndex === 2">
122 119
       <view class="list">
123
-        <view class="cu-card case" v-for="(video,index) in detail.video" :key="index">
120
+        <view class="cu-card case" v-for="(video, index) in detail.video" :key="index">
124 121
           <view class="cu-item shadow">
125 122
             <view class="image">
126
-              <video :src="video" style="width:100%;"></video>
123
+              <video :src="video" style="width: 100%;"></video>
127 124
             </view>
128 125
           </view>
129 126
         </view>
130 127
       </view>
131 128
     </scroll-view>
132 129
     <!-- 大纲页 -->
133
-    <scroll-view :scroll-y="true" :style="[{height:'calc(100vh - 70px - '+ topHeader+'px)'}]" class="scroll-main"
134
-      v-if="currentIndex===3">
130
+    <scroll-view :scroll-y="true" :style="[{ height: 'calc(100vh - 70px - ' + topHeader + 'px)' }]" class="scroll-main" v-if="currentIndex === 3">
135 131
       <view class="cu-bar bg-white">
136 132
         <view class="action border-title">
137 133
           <text class="cuIcon-title text-student"></text>
138
-          <text class="text-xl text-bold">{{tabList[cate_type].list[currentIndex]}}</text>
134
+          <text class="text-xl text-bold">{{ tabList[cate_type].list[currentIndex] }}</text>
139 135
         </view>
140 136
       </view>
141 137
       <view class="bg-white padding-lr">
142
-        <view class="text-content text-lg" v-for="(outline,index) in detail.out_line" :key="index">
143
-          {{outline.course_content}}
138
+        <view class="text-content text-lg" v-for="(outline, index) in detail.out_line" :key="index">
139
+          {{ outline.course_content }}
144 140
         </view>
145 141
       </view>
146 142
     </scroll-view>
147 143
     <view class="static flex shadow">
148 144
       <view class="static-price">
149 145
         <text class="satic-label text-lg">小计:</text>
150
-        <text class="text-price text-red text-lg">{{goods.sum_money}}</text>
146
+        <text class="text-price text-red text-lg">{{ goods.sum_money }}</text>
151 147
       </view>
152
-      <view class="static-choose text-ellipsis" v-if="goods.choose.length>0">(已选:{{goods.choose.join(',')}})</view>
148
+      <view class="static-choose text-ellipsis" v-if="goods.choose.length > 0">(已选:{{ goods.choose.join(',') }})</view>
153 149
       <view class="static-order flex align-center">
154
-        <shop-cart :class_attend_id="attend_id" :disableBtn="disableBtn" @changeDisableBtn="changeDisableBtn">
155
-        </shop-cart>
156
-        <button class="cu-btn round bg-student text-white margin-left-xs"
157
-          :class="{'disabled':carts.includes(attend_id)||!detail.enable}" @tap="addCart">报课</button>
150
+        <shop-cart :class_attend_id="attend_id" :disableBtn="disableBtn" @changeDisableBtn="changeDisableBtn"> </shop-cart>
151
+        <button class="cu-btn round bg-student text-white margin-left-xs" :class="{ disabled: carts.includes(attend_id) || !detail.enable }" @tap="addCart">报课</button>
158 152
       </view>
159 153
     </view>
160 154
   </view>
@@ -168,9 +162,10 @@ import NP from 'number-precision'
168 162
 import { mapGetters } from 'vuex'
169 163
 export default {
170 164
   components: {
171
-    swiperTab, shopCart
165
+    swiperTab,
166
+    shopCart
172 167
   },
173
-  data () {
168
+  data() {
174 169
     return {
175 170
       topHeader: this.globalCustomBarHeight,
176 171
       swiper: {
@@ -192,10 +187,11 @@ export default {
192 187
         { value: '1', name: '需要道具', checked: true },
193 188
         { value: '2', name: '不需要道具', checked: false }
194 189
       ],
195
-      goods: { // 动态选中值
190
+      goods: {
191
+        // 动态选中值
196 192
         props: [], // 选中值
197 193
         choose: [], // 选中名称
198
-        sum_money: 0// 金额总计
194
+        sum_money: 0 // 金额总计
199 195
       }, // 选中课程
200 196
       tabList: [
201 197
         {
@@ -244,12 +240,10 @@ export default {
244 240
     }
245 241
   },
246 242
   computed: {
247
-    ...mapGetters([
248
-      'carts'
249
-    ])
243
+    ...mapGetters(['carts'])
250 244
   },
251 245
   // 配置分享
252
-  onShareAppMessage (res) {
246
+  onShareAppMessage(res) {
253 247
     if (res.from === 'button') {
254 248
       // 来自页面内分享按钮
255 249
       console.log(res.target)
@@ -259,10 +253,10 @@ export default {
259 253
       path: `/pages/class/detail?attend_id=${this.attend_id}`
260 254
     }
261 255
   },
262
-  onShow () {
256
+  onShow() {
263 257
     this.disableBtn = false
264 258
   },
265
-  onLoad (option) {
259
+  onLoad(option) {
266 260
     this.attend_id = Number(decodeURIComponent(option.attend_id))
267 261
     if (this.attend_id === 0) {
268 262
       uni.navigateBack()
@@ -271,7 +265,7 @@ export default {
271 265
     this.get_comments()
272 266
   },
273 267
   methods: {
274
-    get_detail () {
268
+    get_detail() {
275 269
       _detail({ class_attend_id: this.attend_id }).then(res => {
276 270
         this.detail = res.data
277 271
         this.money = res.data.sum_money
@@ -283,10 +277,10 @@ export default {
283 277
         }
284 278
       })
285 279
     },
286
-    changeDisableBtn () {
280
+    changeDisableBtn() {
287 281
       this.disableBtn = true
288 282
     },
289
-    addCart () {
283
+    addCart() {
290 284
       if (this.disableBtn) return false
291 285
       this.disableBtn = true
292 286
       if (!this.detail.enable) {
@@ -303,20 +297,20 @@ export default {
303 297
         }
304 298
       })
305 299
     },
306
-    setDefaultGoods (props) {
300
+    setDefaultGoods(props) {
307 301
       this.goods.props[0] = props[0].id
308 302
       this.goods.sum_money = NP.plus(this.money, props[0].money)
309 303
       this.goods.choose[0] = props[0].name
310 304
     },
311
-    get_comments () {
305
+    get_comments() {
312 306
       _comments({ class_attend_id: this.attend_id }).then(res => {
313 307
         this.comemnts = res.data
314 308
       })
315 309
     },
316
-    changeTab (index) {
310
+    changeTab(index) {
317 311
       this.currentIndex = index
318 312
     },
319
-    radioChange (e) {
313
+    radioChange(e) {
320 314
       const value = e.detail.value
321 315
       this.needTool = value
322 316
       if (value === '1') {
@@ -327,7 +321,7 @@ export default {
327 321
         this.goods.choose = []
328 322
       }
329 323
     },
330
-    checkboxChange (e) {
324
+    checkboxChange(e) {
331 325
       const values = e.detail.value
332 326
       const choose = []
333 327
       const props = []

+ 130 - 64
src/pages/class/gift.vue

@@ -1,91 +1,125 @@
1 1
 <template>
2
-  <view class="page">
2
+  <view class="page" style="background-color: #fff;">
3 3
     <cu-custom :isBack="true" title="智能报课"></cu-custom>
4
-    <view class="steps padding-tb">
4
+    <view class="steps solid-bottom flex justify-between">
5
+      <!-- <view class="text-center"><text class="text-red">点击切换下一步</text></view>
5 6
       <view class="cu-steps">
6 7
         <view class="cu-item" :class="index > cur ? '' : 'text-student'" v-for="(item, index) in numList" :key="index" @tap="changeStep(index)">
7 8
           <text class="num" :data-index="index + 1"></text> {{ item.name }}
8 9
         </view>
9
-      </view>
10
+      </view> -->
11
+      <view v-for="(item, index) in stepList" :key="index" class="step flex-sub text-center" :class="{ cur: cur === index }" @tap="changeStep(index)">{{ item.name }}</view>
10 12
     </view>
11
-    <view class="main bg-white" :style="[{ height: 'calc(100vh - 92px - ' + topHeader + 'px)' }]">
13
+    <view class="main" :style="[{ height: 'calc(100vh - 40px - ' + topHeader + 'px)' }]">
12 14
       <swiper @change="swipeChange" :current="cur" class="swipe">
13 15
         <swiper-item @touchmove.stop>
14 16
           <view class="btn-check-group padding">
15 17
             <checkbox-group @change="checkboxChange" class="flex justify-between" style="flex-wrap: wrap;" id="week">
16
-              <label class="btn-check-label margin" :class="{ 'bg-cyan': params.week.includes(item.key + '') }" v-for="item in days" :key="item.key">
18
+              <label class="btn-check-label margin" :class="{ 'bg-light-green': params.week.includes(item.key + '') }" v-for="item in days" :key="item.key">
17 19
                 <checkbox :value="item.key" />
18 20
                 {{ item.value }}
19 21
               </label>
20 22
             </checkbox-group>
21 23
           </view>
24
+          <view class="flex next-step padding-lr" style="width: 100%;">
25
+            <button class="cu-btn round lg bg-light-green flex-sub" @tap="changeStep(1)">下一步</button>
26
+          </view>
22 27
         </swiper-item>
23 28
         <swiper-item @touchmove.stop>
24 29
           <view class="btn-check-group padding">
25
-            <checkbox-group @change="checkboxChange" class="flex justify-between" style="flex-wrap: wrap;" id="hobby">
26
-              <label class="btn-check-label margin" :class="{ 'bg-cyan': params.hobby.includes(item.id + '') }" v-for="item in interests" :key="item.id">
27
-                <checkbox :value="item.id" />
28
-                {{ item.name }}
29
-              </label>
30
-            </checkbox-group>
31 30
             <view class="margin">
32
-              <input v-model="params.hobbyOther" placeholder="输入其它兴趣内容(选填)" class="margin-top input-border" />
31
+              <input v-model="params.hobbyOther" placeholder="输入兴趣内容  如:画画" class="margin-top input-border" />
33 32
             </view>
33
+            <view class="interests">
34
+              <img src="/static/imgs/intelligent-bg.png" mode="widthFix" alt="" />
35
+              <checkbox-group @change="checkboxChange" id="hobby">
36
+                <view v-for="(item, index) in interests" :key="item.id" :style="[{ top: index * 80 + 'rpx', left: (index % 2) * 320 + index * 40 + 'rpx' }]" class="interest">
37
+                  <label
38
+                    class="btn-check-label margin"
39
+                    :style="{
40
+                      color: params.hobby.includes(item.id + '') ? '#fff' : '#000',
41
+                      backgroundColor: params.hobby.includes(item.id + '') ? colors[index % 4] : '#f0f0f0'
42
+                    }"
43
+                  >
44
+                    <checkbox :value="item.id" />
45
+                    {{ item.name }}
46
+                  </label>
47
+                  <text class="cuIcon-title" :style="[{ color: colors[index % 4] }]"></text>
48
+                </view>
49
+              </checkbox-group>
50
+            </view>
51
+          </view>
52
+          <view class="flex next-step padding-lr" style="width: 100%;">
53
+            <button class="cu-btn round lg bg-light-green flex-sub margin-right-sm" @tap="changeStep(0)">上一步</button>
54
+            <button class="cu-btn round lg bg-light-green flex-sub" @tap="changeStep(2)">下一步</button>
34 55
           </view>
35 56
         </swiper-item>
36 57
         <swiper-item>
37
-          <view class="VerticalBox">
38
-            <scroll-view class="VerticalNav nav" scroll-y scroll-with-animation :scroll-top="verticalNavTop" :style="'height:calc(100vh - 70px - 90px - ' + topHeader + 'px)'">
39
-              <view class="cu-item" :class="index == tabCur ? 'text-green cur' : ''" v-for="(item, index) in attends" :key="index" @tap="TabSelect" :data-id="index">
40
-                {{ weekList[index] }}
41
-              </view>
42
-            </scroll-view>
43
-            <scroll-view
44
-              class="VerticalMain padding-sm"
45
-              scroll-y
46
-              scroll-with-animation
47
-              :style="'height:calc(100vh - 70px - 90px - ' + topHeader + 'px)'"
48
-              :scroll-into-view="'main-' + mainCur"
49
-              @scroll="VerticalMain"
50
-            >
51
-              <radio-group @change="changeClass" style="width: 100%;" v-for="(attend, i) in attends" :key="i">
52
-                <view class="cu-item bg-white padding margin-bottom-sm" v-for="(item, index) in attend.list" v-show="i == mainCur" :key="index" :id="'main-' + index">
53
-                  <view class="cu-bar solid-bottom">
54
-                    <view>
55
-                      <label>
56
-                        <view class="flex justify-between align-center">
57
-                          <view
58
-                            ><text>{{ item.attend_name }}</text></view
59
-                          >
58
+          <view v-if="attends.length === 0" class="padding text-center text-lg">
59
+            没有找到相关课程!
60
+          </view>
61
+          <view v-else>
62
+            <view class="VerticalBox">
63
+              <scroll-view class="VerticalNav nav" scroll-y scroll-with-animation :scroll-top="verticalNavTop" :style="'height:calc(100vh - 70px - 40px - ' + topHeader + 'px)'">
64
+                <view class="cu-item" :class="index == tabCur ? 'text-green cur' : ''" v-for="(item, index) in attends" :key="index" @tap="TabSelect" :data-id="index">
65
+                  {{ weekList[index] }}
66
+                </view>
67
+              </scroll-view>
68
+              <scroll-view
69
+                class="VerticalMain padding-sm"
70
+                scroll-y
71
+                scroll-with-animation
72
+                :style="'height:calc(100vh - 70px - 40px - ' + topHeader + 'px)'"
73
+                :scroll-into-view="'main-' + mainCur"
74
+                @scroll="VerticalMain"
75
+              >
76
+                <radio-group @change="changeClass" style="width: 100%;" v-for="(attend, i) in attends" :key="i">
77
+                  <view class="cu-item bg-white padding margin-bottom-sm" v-for="(item, index) in attend.list" v-show="i == mainCur" :key="index" :id="'main-' + index">
78
+                    <view class="cu-bar solid-bottom">
79
+                      <view>
80
+                        <label>
81
+                          <view class="flex justify-between align-center">
82
+                            <view
83
+                              ><text>{{ item.attend_name }}</text></view
84
+                            >
85
+                            <view>
86
+                              <radio :value="item.class_attend_id" :checked="checked.includes(item.class_attend_id)" class="cyan" style="transform: scale(0.7);" />
87
+                            </view>
88
+                          </view>
89
+                        </label>
90
+                      </view>
91
+                    </view>
92
+                    <view v-if="item.prop.length > 0">
93
+                      <checkbox-group class="checkbox-group margin-top-xs" :data-id="item.class_attend_id" @change="propChange">
94
+                        <label v-for="prop in item.prop" :key="prop.id">
60 95
                           <view>
61
-                            <radio :value="item.class_attend_id" :checked="checked.includes(item.class_attend_id)" class="cyan" style="transform: scale(0.7);" />
96
+                            <checkbox
97
+                              :value="prop.id"
98
+                              class="cyan"
99
+                              :checked="checked_props[mainCur].class_attend_id === item.class_attend_id && checked_props[mainCur].prop.includes(prop.id + '')"
100
+                              style="transform: scale(0.7);"
101
+                            />{{ prop.name }}<text>¥{{ prop.money }}</text>
62 102
                           </view>
63
-                        </view>
64
-                      </label>
103
+                        </label>
104
+                      </checkbox-group>
65 105
                     </view>
66 106
                   </view>
67
-                  <view v-if="item.prop.length > 0">
68
-                    <checkbox-group class="checkbox-group margin-top-xs" :data-id="item.class_attend_id" @change="propChange">
69
-                      <label v-for="prop in item.prop" :key="prop.id">
70
-                        <view>
71
-                          <checkbox
72
-                            :value="prop.id"
73
-                            class="cyan"
74
-                            :checked="checked_props[mainCur].class_attend_id === item.class_attend_id && checked_props[mainCur].prop.includes(prop.id + '')"
75
-                            style="transform: scale(0.7);"
76
-                          />{{ prop.name }}<text>¥{{ prop.money }}</text>
77
-                        </view>
78
-                      </label>
79
-                    </checkbox-group>
80
-                  </view>
107
+                </radio-group>
108
+              </scroll-view>
109
+            </view>
110
+            <view class="static shadow">
111
+              <view class="flex justify-between" style="width: 100%;">
112
+                <view>
113
+                  <button class="cu-btn round line-grey" @tap="changeStep(1)">
114
+                    <text class="cuIcon-back lg margin-right-sm"></text>
115
+                    重选
116
+                  </button>
81 117
                 </view>
82
-              </radio-group>
83
-            </scroll-view>
84
-          </view>
85
-          <view class="static shadow">
86
-            <view class="static-order flex">
87
-              <shop-cart :class_attend_id="attend_id" @changeDisableBtn="changeDisableBtn"></shop-cart>
88
-              <button class="cu-btn round bg-student text-white margin-left-xs" @tap="addCart">报课</button>
118
+                <view class="static-order flex">
119
+                  <shop-cart :class_attend_id="attend_id" @changeDisableBtn="changeDisableBtn"></shop-cart>
120
+                  <button class="cu-btn round bg-student text-white margin-left-xs" @tap="addCart">报课</button>
121
+                </view>
122
+              </view>
89 123
             </view>
90 124
           </view>
91 125
         </swiper-item>
@@ -105,7 +139,7 @@ export default {
105 139
   data() {
106 140
     return {
107 141
       topHeader: this.globalCustomBarHeight,
108
-      numList: [
142
+      stepList: [
109 143
         {
110 144
           name: '选周期'
111 145
         },
@@ -130,6 +164,7 @@ export default {
130 164
       tabCur: 0,
131 165
       mainCur: 0,
132 166
       verticalNavTop: 0,
167
+      colors: ['#0CAAF4', '#082FCC', '#FDC534', '#09E294'],
133 168
       checked: [], // 选中
134 169
       checked_props: [], // 选中工具
135 170
       attend_id: 0, // 添加成功课程
@@ -170,8 +205,12 @@ export default {
170 205
       params.hobby = params.hobby.join(',')
171 206
       _intelligentCourses(params).then(res => {
172 207
         this.attends = res.data
208
+        this.checked = [] //初始化选项
173 209
         Object.keys(this.attends).forEach(item => {
174
-          this.$set(this.checked_props, item, { prop: [] })
210
+          const class_attend_id = this.attends[item].list[0].class_attend_id
211
+          const prop = this.attends[item].list[0].prop.length > 0 ? [this.attends[item].list[0].prop[0].id + ''] : []
212
+          this.$set(this.checked, item, class_attend_id)
213
+          this.$set(this.checked_props, item, { class_attend_id: class_attend_id, prop: prop })
175 214
         })
176 215
         this.weekList = this.attends.map(item => item.week)
177 216
       })
@@ -217,6 +256,7 @@ export default {
217 256
       this.checked[this.mainCur] = value
218 257
       this.$set(this.checked, this.mainCur, value)
219 258
       this.$set(this.checked_props, this.mainCur, { class_attend_id: value, prop: [] })
259
+      console.log(this.checked_props)
220 260
     },
221 261
     propChange(e) {
222 262
       const parentId = e.target.dataset.id
@@ -271,6 +311,32 @@ export default {
271 311
     height: 100%;
272 312
   }
273 313
 }
314
+.step {
315
+  position: relative;
316
+  padding: 10px 0;
317
+  &.cur {
318
+    color: #09e294;
319
+    &:before {
320
+      content: '';
321
+      position: absolute;
322
+      bottom: 0;
323
+      background-color: #09e294;
324
+      width: 30px;
325
+      height: 2px;
326
+      transform: translateX(25%);
327
+    }
328
+  }
329
+}
330
+.interests {
331
+  position: relative;
332
+  .interest {
333
+    position: absolute;
334
+  }
335
+}
336
+.next-step {
337
+  position: fixed;
338
+  bottom: 60px;
339
+}
274 340
 .btn-check-group {
275 341
   checkbox {
276 342
     display: none;
@@ -282,8 +348,8 @@ export default {
282 348
     display: inline-block;
283 349
     margin-right: 10rpx;
284 350
     position: relative;
285
-    padding: 10rpx 30rpx;
286
-    line-height: 30px;
351
+    padding: 10rpx 40rpx;
352
+    // line-height: 30px;
287 353
     border-radius: 100rpx;
288 354
     flex-wrap: nowrap;
289 355
     border: 1px solid #eee;
@@ -312,7 +378,7 @@ export default {
312 378
   height: 70px;
313 379
   align-items: center;
314 380
   padding: 0 0.8rem;
315
-  justify-content: flex-end;
381
+  // justify-content: flex-end;
316 382
 }
317 383
 .fixed {
318 384
   position: fixed;

+ 16 - 11
src/pages/index/components/card.vue

@@ -1,16 +1,20 @@
1 1
 <template>
2 2
   <view class="card flex" @tap="goDetail(item)">
3
-    <view class=card-left>
4
-      <img mode="aspectFill" :src="item.image" alt="">
3
+    <view class="card-left">
4
+      <img mode="aspectFill" :src="item.image" alt="" />
5 5
     </view>
6 6
     <view class="card-right flex-sub">
7
-      <view class="card-title flex justify-between"><text>{{item.attend_name}}</text><text
8
-          class="text-student text-light">¥{{item.money}}</text></view>
9
-      <view class="text-gray text-sm"><text>{{item.day}}</text></view>
10
-      <view class="text-gray text-sm">{{item.grade_desc}}</view>
7
+      <view class="card-title flex justify-between"
8
+        ><text>{{ item.attend_name }}</text
9
+        ><text class="text-student text-light">¥{{ item.money }}</text></view
10
+      >
11
+      <view class="text-gray text-sm"
12
+        ><text>{{ item.day }}</text></view
13
+      >
14
+      <view class="text-gray text-sm">{{ item.grade_desc }}</view>
11 15
       <view class="margin-top-sm">
12
-        <button class="cu-btn round  bg-student text-white button-hover" v-if="item.enable">报课</button>
13
-        <button class="cu-btn round  bg-grey button-hover text-white disabled" v-else>停止</button>
16
+        <button class="cu-btn round bg-student text-white button-hover" v-if="item.enable">报课</button>
17
+        <button class="cu-btn round bg-grey button-hover text-white disabled" v-else>停止</button>
14 18
       </view>
15 19
     </view>
16 20
   </view>
@@ -21,18 +25,19 @@ export default {
21 25
   props: {
22 26
     item: {
23 27
       type: Object,
24
-      default () {
28
+      default() {
25 29
         return {}
26 30
       }
27 31
     }
28 32
   },
29
-  data () {
33
+  data() {
30 34
     return {
31 35
       key: 1212
32 36
     }
33 37
   },
34 38
   methods: {
35
-    goDetail (item) {
39
+    goDetail(item) {
40
+      console.log(111)
36 41
       if (!item.enable) {
37 42
         uni.showToast({ title: '课程已停止!', icon: 'none' })
38 43
         return false

+ 91 - 69
src/pages/index/index.vue

@@ -1,8 +1,7 @@
1
-
2 1
 <template>
3 2
   <view class="page">
4 3
     <cu-custom :isBack="false"></cu-custom>
5
-    <view class="header" :style="[{top:topHeader + 'px'}]">
4
+    <view class="header" :style="[{ top: topHeader + 'px' }]">
6 5
       <view class="header-box flex justify-end">
7 6
         <view class="header-title">
8 7
           <view class="header-title-main">
@@ -12,49 +11,50 @@
12 11
         </view>
13 12
         <view class="header-search flex-sub">
14 13
           <view class="flex justify-between">
15
-            <input type="text" v-model="params.course_name" class="header-search-input flex-sub" placeholder="搜索课程"
16
-              @confirm="search">
14
+            <input type="text" v-model="params.course_name" class="header-search-input flex-sub" placeholder="搜索课程" @confirm="search" />
17 15
             <text class="cuIcon-search text-gray header-search-icon" @tap="search"></text>
18 16
           </view>
19 17
         </view>
20 18
       </view>
21 19
     </view>
22
-    <scroll-view :scroll-y="true" :refresher-enabled="true" class="scroll-main" :refresher-triggered="triggered"
23
-      :style="[{height:'calc(100vh - 102px - '+ topHeader+'px)'}]" @refresherrefresh="onRefresh"
24
-      @scrolltolower="loadMore">
20
+    <scroll-view
21
+      :scroll-y="true"
22
+      :refresher-enabled="true"
23
+      class="scroll-main"
24
+      :refresher-triggered="triggered"
25
+      :style="[{ height: 'calc(100vh - 102px - ' + topHeader + 'px)' }]"
26
+      @refresherrefresh="onRefresh"
27
+      @scrolltolower="loadMore"
28
+    >
25 29
       <view class="main">
26 30
         <view class="main-title">活动和餐饮</view>
27 31
         <view class="flex justify-around course">
28
-          <course v-for="(item,index) in courses" :key="index" @tap="goCourse(item.type)" :course="item"
29
-            class="course-item flex-sub margin-xs"></course>
32
+          <course v-for="(item, index) in courses" :key="index" @tap="goCourse(item.type)" :course="item" class="course-item flex-sub margin-xs"></course>
30 33
         </view>
31 34
         <view class="main-title margin-top-xs">一键报班</view>
32 35
         <view class="apply-class flex">
33
-          <image mode="widthFix" @tap="goGift" src="/static/imgs/index/baoban.png"
34
-            class="flex-sub apply-class-img margin-xs" />
36
+          <image mode="widthFix" @tap="goGift" src="/static/imgs/index/baoban.png" class="flex-sub apply-class-img margin-xs" />
35 37
         </view>
36 38
         <view class="recommend margin-top-xs">
37 39
           <view class="recommend-title">推荐课程</view>
38 40
           <view class="recommend-filter margin-top-xs flex">
39
-            <view class="filter-item text-center flex-sub" @tap="sort('home')" :class="{'text-sort':sortCur==='home'}">
40
-              综合</view>
41
-            <view class="filter-item text-center flex-sub" @tap="sort('sales')"
42
-              :class="{'text-sort':sortCur==='sales'}">销量
43
-              <image mode="widthFix" class="sort-icon"
44
-                :src="sortCur==='sales'?(sortItem.sales===0?sortIcons.up:sortIcons.down):sortIcons.no"></image>
41
+            <view class="filter-item text-center flex-sub" @tap="sort('home')" :class="{ 'text-sort': sortCur === 'home' }"> 综合</view>
42
+            <view class="filter-item text-center flex-sub" @tap="sort('sales')" :class="{ 'text-sort': sortCur === 'sales' }"
43
+              >销量
44
+              <image mode="widthFix" class="sort-icon" :src="sortCur === 'sales' ? (sortItem.sales === 0 ? sortIcons.up : sortIcons.down) : sortIcons.no"></image>
45 45
             </view>
46
-            <view class="filter-item text-center flex-sub" @tap="sort('money')"
47
-              :class="{'text-sort':sortCur==='money'}">价格
48
-              <image mode="widthFix" class="sort-icon"
49
-                :src="sortCur==='money'?(sortItem.money===0?sortIcons.up:sortIcons.down):sortIcons.no"></image>
46
+            <view class="filter-item text-center flex-sub" @tap="sort('money')" :class="{ 'text-sort': sortCur === 'money' }"
47
+              >价格
48
+              <image mode="widthFix" class="sort-icon" :src="sortCur === 'money' ? (sortItem.money === 0 ? sortIcons.up : sortIcons.down) : sortIcons.no"></image>
50 49
             </view>
51
-            <view class="filter-item text-center flex-sub">{{grade_now}}</view>
52
-            <view class="filter-item text-right flex-sub" @tap="showModal" data-target="FilterModal">筛选
50
+            <view class="filter-item text-center flex-sub">{{ grade_now }}</view>
51
+            <view class="filter-item text-right flex-sub" @tap="showModal" data-target="FilterModal"
52
+              >筛选
53 53
               <text class="cuIcon-filter text-gray"></text>
54 54
             </view>
55 55
           </view>
56 56
           <view class="list">
57
-            <view class="cu-card" v-for="(item,index) in list" :key="index">
57
+            <view class="cu-card" v-for="(item, index) in list" :key="index">
58 58
               <view class="cu-item">
59 59
                 <card :item="item"></card>
60 60
               </view>
@@ -63,9 +63,8 @@
63 63
         </view>
64 64
       </view>
65 65
     </scroll-view>
66
-    <view class="cu-modal drawer-modal justify-end" :class="modalName=='FilterModal'?'show':''" @tap="hideModal">
67
-      <view class="cu-dialog basis-lg" @tap.stop=""
68
-        :style="[{top:topHeader+'px',height:'calc(100vh - ' + topHeader + 'px)'}]">
66
+    <view class="cu-modal drawer-modal justify-end" :class="modalName == 'FilterModal' ? 'show' : ''" @tap="hideModal">
67
+      <view class="cu-dialog basis-lg" @tap.stop="" :style="[{ top: topHeader + 'px', height: 'calc(100vh - ' + topHeader + 'px)' }]">
69 68
         <view class="filter-title">机构筛选</view>
70 69
         <view class="btn-check-group padding-lr">
71 70
           <!-- <checkbox-group @change="checkboxChange" class="flex" style="flex-wrap: wrap;" id="agency">
@@ -76,22 +75,30 @@
76 75
 							</label>
77 76
 						</checkbox-group> -->
78 77
           <radio-group class="flex" style="flex-wrap: wrap;" id="agency">
79
-            <label class="btn-check-label margin-top-sm padding-lr-xs text-sm text-ellipsis"
80
-              :class="{'bg-cyan':params.agency.includes(item.id)}" v-for="item in filters.agency" :key="item.id"
81
-              @tap="radioChange('agency',item.id)">
78
+            <label
79
+              class="btn-check-label margin-top-sm padding-lr-xs text-sm text-ellipsis"
80
+              :class="{ 'bg-cyan': params.agency.includes(item.id) }"
81
+              v-for="item in filters.agency"
82
+              :key="item.id"
83
+              @tap="radioChange('agency', item.id)"
84
+            >
82 85
               <radio :value="item.id" />
83
-              {{item.name}}
86
+              {{ item.name }}
84 87
             </label>
85 88
           </radio-group>
86 89
         </view>
87 90
         <view class="filter-title">分类筛选</view>
88 91
         <view class="btn-check-group padding-lr">
89 92
           <radio-group class="flex" style="flex-wrap: wrap;" id="category">
90
-            <label class="btn-check-label margin-top-sm padding-lr-xs text-sm text-ellipsis"
91
-              :class="{'bg-cyan':params.category.includes(item.id)}" v-for="item in filters.category" :key="item.id"
92
-              @tap="radioChange('category',item.id)">
93
+            <label
94
+              class="btn-check-label margin-top-sm padding-lr-xs text-sm text-ellipsis"
95
+              :class="{ 'bg-cyan': params.category.includes(item.id) }"
96
+              v-for="item in filters.category"
97
+              :key="item.id"
98
+              @tap="radioChange('category', item.id)"
99
+            >
93 100
               <radio :value="item.id" />
94
-              {{item.name}}
101
+              {{ item.name }}
95 102
             </label>
96 103
           </radio-group>
97 104
         </view>
@@ -105,22 +112,30 @@
105 112
 							</label>
106 113
 						</checkbox-group> -->
107 114
           <radio-group class="flex" style="flex-wrap: wrap;" id="day">
108
-            <label class="btn-check-label margin-top-sm padding-lr-xs text-sm"
109
-              :class="{'bg-cyan':params.day.includes(index+'')}" v-for="(item,index) in filters.week" :key="index"
110
-              @tap="radioChange('day',index)">
115
+            <label
116
+              class="btn-check-label margin-top-sm padding-lr-xs text-sm"
117
+              :class="{ 'bg-cyan': params.day.includes(index + '') }"
118
+              v-for="(item, index) in filters.week"
119
+              :key="index"
120
+              @tap="radioChange('day', index)"
121
+            >
111 122
               <radio :value="index" />
112
-              {{item}}
123
+              {{ item }}
113 124
             </label>
114 125
           </radio-group>
115 126
         </view>
116 127
         <view class="filter-title">价格区间(元)</view>
117 128
         <view class="btn-check-group padding-lr">
118 129
           <radio-group class="flex" style="flex-wrap: wrap;" id="price">
119
-            <label class="btn-check-label margin-top-sm padding-lr-xs text-sm"
120
-              :class="{'bg-cyan':params.price===item.name}" v-for="item in filters.price_list" :key="item.id"
121
-              @tap="radioChange('price',item.name)">
130
+            <label
131
+              class="btn-check-label margin-top-sm padding-lr-xs text-sm"
132
+              :class="{ 'bg-cyan': params.price === item.name }"
133
+              v-for="item in filters.price_list"
134
+              :key="item.id"
135
+              @tap="radioChange('price', item.name)"
136
+            >
122 137
               <radio :value="item.name" />
123
-              {{item.name}}
138
+              {{ item.name }}
124 139
             </label>
125 140
           </radio-group>
126 141
         </view>
@@ -142,9 +157,10 @@ import { deepClone } from '@/common/utils'
142 157
 import { mapGetters } from 'vuex'
143 158
 export default {
144 159
   components: {
145
-    course, card
160
+    course,
161
+    card
146 162
   },
147
-  data () {
163
+  data() {
148 164
     return {
149 165
       topHeader: this.globalCustomBarHeight,
150 166
       modalName: '',
@@ -162,7 +178,8 @@ export default {
162 178
         sales: 0,
163 179
         money: 0
164 180
       },
165
-      courses: [// 排序情况
181
+      courses: [
182
+        // 排序情况
166 183
         {
167 184
           applying: true,
168 185
           back: '/static/imgs/index/zmk.png',
@@ -197,9 +214,10 @@ export default {
197 214
         category: [],
198 215
         price: '',
199 216
         sort: '',
200
-        list_type: 0// 0 课程,1 餐饮,2活动
217
+        list_type: 0 // 0 课程,1 餐饮,2活动
201 218
       },
202
-      init: { // 初始化
219
+      init: {
220
+        // 初始化
203 221
         page_num: 1,
204 222
         course_name: '',
205 223
         agency: [],
@@ -207,7 +225,7 @@ export default {
207 225
         category: [],
208 226
         price: '',
209 227
         sort: '',
210
-        list_type: 0// 0 课程,1 餐饮,2活动
228
+        list_type: 0 // 0 课程,1 餐饮,2活动
211 229
       },
212 230
       list: [],
213 231
       noMore: false, // 还有没
@@ -215,11 +233,9 @@ export default {
215 233
     }
216 234
   },
217 235
   computed: {
218
-    ...mapGetters([
219
-      'kid', 'token'
220
-    ])
236
+    ...mapGetters(['kid', 'token'])
221 237
   },
222
-  onShow () {
238
+  onShow() {
223 239
     // 登录后才进入后续操作
224 240
     this.checkLogin().then(res => {
225 241
       if (res) {
@@ -227,14 +243,15 @@ export default {
227 243
           return this.globalNavigateTo('myStudents')
228 244
         }
229 245
         this.params = Object.assign({}, this.init)
230
-        this.get_list(true)// true初始化加载过滤项
246
+        this.get_list(true) // true初始化加载过滤项
231 247
       }
232 248
     })
233 249
   },
234 250
   methods: {
235
-    checkLogin () {
251
+    checkLogin() {
236 252
       return new Promise((resolve, reject) => {
237
-        if (this.token) { // 跳转至登录页
253
+        if (this.token) {
254
+          // 跳转至登录页
238 255
           resolve(true)
239 256
         } else {
240 257
           uni.showModal({
@@ -250,11 +267,12 @@ export default {
250 267
         }
251 268
       })
252 269
     },
253
-    goCourse (type) {
270
+    goCourse(type) {
254 271
       this.params.list_type = type
255 272
       this.search()
256 273
     },
257
-    loadFilter () { // 加载筛选项
274
+    loadFilter() {
275
+      // 加载筛选项
258 276
       const params = {}
259 277
       _filter(params).then(res => {
260 278
         this.filters = res.data
@@ -262,13 +280,13 @@ export default {
262 280
         this.courses[2].applying = this.filters.is_catering
263 281
       })
264 282
     },
265
-    showModal (e) {
283
+    showModal(e) {
266 284
       this.modalName = e.currentTarget.dataset.target
267 285
     },
268
-    hideModal (e) {
286
+    hideModal(e) {
269 287
       this.modalName = null
270 288
     },
271
-    radioChange (type, v) {
289
+    radioChange(type, v) {
272 290
       switch (type) {
273 291
         case 'agency':
274 292
           this.params.agency = this.params.agency[0] === v ? [] : [v]
@@ -286,7 +304,7 @@ export default {
286 304
           console.log('error')
287 305
       }
288 306
     },
289
-    checkboxChange (e) {
307
+    checkboxChange(e) {
290 308
       const type = e.target.id
291 309
       const values = e.detail.value
292 310
       switch (type) {
@@ -303,16 +321,19 @@ export default {
303 321
           console.log('error')
304 322
       }
305 323
     },
306
-    search () { // 搜索课程
324
+    search() {
325
+      // 搜索课程
307 326
       this.params.page_num = 1
308 327
       this.get_list()
309 328
     },
310
-    check_course () { // 筛选课程
329
+    check_course() {
330
+      // 筛选课程
311 331
       this.params.page_num = 1
312 332
       this.get_list()
313 333
       this.hideModal()
314 334
     },
315
-    onRefresh () { // 下拉刷新
335
+    onRefresh() {
336
+      // 下拉刷新
316 337
       this.triggered = true
317 338
       this.params.page_num = 1
318 339
       this.params.list_type = 0
@@ -321,7 +342,7 @@ export default {
321 342
         this.triggered = false
322 343
       }, 1000)
323 344
     },
324
-    loadMore () {
345
+    loadMore() {
325 346
       if (this.noMore) {
326 347
         uni.showToast({ title: '暂无更多课程数据', icon: 'none' })
327 348
         return false
@@ -329,7 +350,8 @@ export default {
329 350
       this.params.page_num++
330 351
       this.get_list()
331 352
     },
332
-    sort (type) { // 排序搜索
353
+    sort(type) {
354
+      // 排序搜索
333 355
       const sorts = {
334 356
         home: 0,
335 357
         sales: 0,
@@ -347,7 +369,7 @@ export default {
347 369
       this.params.page_num = 1
348 370
       this.get_list()
349 371
     },
350
-    get_list (init = false) {
372
+    get_list(init = false) {
351 373
       let params = deepClone(this.params)
352 374
       params = filterParams(params)
353 375
       if (params.day.length > 0) {
@@ -380,7 +402,7 @@ export default {
380 402
         if (init) this.loadFilter()
381 403
       })
382 404
     },
383
-    goGift () {
405
+    goGift() {
384 406
       this.globalNavigateTo('classGift', { package_id: 0 })
385 407
     }
386 408
   }

+ 56 - 0
src/pages/mine/courseFiles.vue

@@ -0,0 +1,56 @@
1
+<template>
2
+  <view class="page">
3
+    <cu-custom :isBack="true" title="课程档案"></cu-custom>
4
+    <view class="cu-list box-shadow menu">
5
+      <view class="cu-item arrow margin-top-xs" v-for="file in list" :key="file.id" @tap="goto('fileDetail', file)">
6
+        <view class="content margin-left-sm">
7
+          <view>{{ file.course_name }}</view>
8
+          <star-rating name="serviceNum" :score="file.level" :max="file.max_level"></star-rating>
9
+        </view>
10
+      </view>
11
+    </view>
12
+  </view>
13
+</template>
14
+
15
+<script>
16
+import { _getStudentFiles } from '@/api/course'
17
+import starRating from '@/components/star-rating.vue'
18
+export default {
19
+  components: {
20
+    starRating
21
+  },
22
+  data() {
23
+    return {
24
+      key: '课程档案',
25
+      params: {
26
+        page: 1
27
+      },
28
+      list: [],
29
+      ability: []
30
+    }
31
+  },
32
+  onLoad() {
33
+    this.get_list()
34
+  },
35
+  methods: {
36
+    get_list() {
37
+      _getStudentFiles(this.params).then(res => {
38
+        this.list = res.data.list
39
+        this.ability = res.data.ability
40
+      })
41
+    },
42
+    goto(page, file) {
43
+      const ability = this.ability.filter(item => {
44
+        if (file.ability_total[item.id]) {
45
+          this.$set(item, 'score', file.ability_total[item.id])
46
+          return true
47
+        }
48
+      })
49
+      this.$set(file, 'ability', ability)
50
+      this.globalNavigateTo(page, { file: JSON.stringify(file) })
51
+    }
52
+  }
53
+}
54
+</script>
55
+
56
+<style lang="scss" scoped></style>

+ 166 - 0
src/pages/mine/fileDetail.vue

@@ -0,0 +1,166 @@
1
+<template>
2
+  <view class="page">
3
+    <cu-custom :isBack="true" :title="key"></cu-custom>
4
+    <view class="card margin-sm padding-sm bg-white shadow">
5
+      <view class="text-center">
6
+        <image mode="scaleToFill" :src="student_avatar" class="avatar xl student-avatar"></image>
7
+      </view>
8
+      <view class="part">
9
+        <view class="title text-student">考核总评</view>
10
+        <view class="content margin-top">
11
+          <canvas
12
+            canvas-id="ability"
13
+            id="ability"
14
+            class="charts"
15
+            @touchstart="touchStart"
16
+            @touchmove="touchMove"
17
+            @touchend="touchEnd"
18
+            @error="error"
19
+            :style="{
20
+              width: cWidth * pixelRatio + 'px',
21
+              height: cHeight * pixelRatio + 'px',
22
+              transform: 'scale(' + 1 / pixelRatio + ')',
23
+              'margin-left': (-cWidth * (pixelRatio - 1)) / 2 + 'px',
24
+              'margin-top': (-cHeight * (pixelRatio - 1)) / 2 + 'px'
25
+            }"
26
+          ></canvas>
27
+        </view>
28
+      </view>
29
+      <view class="part">
30
+        <view class="title text-student">学期总评</view>
31
+        <view class="content margin-top">{{ file.term_summary }}</view>
32
+      </view>
33
+      <view class="part">
34
+        <view class="title text-student">下期预告</view>
35
+        <view class="content margin-top">{{ file.next_forecast }}</view>
36
+      </view>
37
+    </view>
38
+  </view>
39
+</template>
40
+
41
+<script>
42
+import UCharts from '@/components/u-charts/u-charts.js'
43
+var canvases = {}
44
+export default {
45
+  data() {
46
+    return {
47
+      key: '学生总评',
48
+      file: {},
49
+      pixelRatio: 1,
50
+      cWidth: '',
51
+      cHeight: '',
52
+      student_avatar: 'http://parent.kehoubaike.com/static/img/7f4e775d2e04234d1e1994b13146f6b.e5c47f3.png'
53
+    }
54
+  },
55
+  // 配置分享
56
+  onShareAppMessage(res) {
57
+    if (res.from === 'button') {
58
+      // 来自页面内分享按钮
59
+      console.log(res.target)
60
+    }
61
+    return {
62
+      title: '结业报告',
63
+      path: `/pages/mine/fileDetail?shareFile=${JSON.stringify(this.file)}`
64
+    }
65
+  },
66
+  onLoad(options) {
67
+    //跳转参数
68
+    if (options.file) {
69
+      this.file = JSON.parse(decodeURIComponent(options.file))
70
+    }
71
+    //分享页参数
72
+    if (options.shareFile) {
73
+      this.file = JSON.parse(options.shareFile)
74
+    }
75
+    this.cWidth = uni.upx2px(800) - 60
76
+    this.cHeight = uni.upx2px(400) // 图表配置
77
+    this.init()
78
+  },
79
+  methods: {
80
+    init() {
81
+      const ability = {
82
+        categories: this.file.ability.map(item => item.name),
83
+        series: [
84
+          {
85
+            name: '评分',
86
+            data: this.file.ability.map(item => item.score)
87
+          }
88
+        ]
89
+      }
90
+      this.showRadar('ability', ability)
91
+    },
92
+    showRadar(canvasId, chartData) {
93
+      canvases[canvasId] = new UCharts({
94
+        canvasId: canvasId,
95
+        type: 'radar',
96
+        legend: { show: true },
97
+        fontSize: 11,
98
+        width: 300,
99
+        height: this.cHeight * this.pixelRatio,
100
+        pixelRatio: this.pixelRatio,
101
+        animation: true,
102
+        categories: chartData.categories,
103
+        series: chartData.series
104
+      })
105
+    },
106
+    touchStart(e) {
107
+      const canvasId = e.target.id
108
+      canvases[canvasId].showToolTip(e, {
109
+        format: function (item, category) {
110
+          return category ? category + ' ' + item.name + ':' + item.data : item.name + ':' + item.data
111
+        }
112
+      })
113
+      // canvases[canvasId].scrollStart(e)
114
+    },
115
+    touchMove(e) {
116
+      // const canvasId = e.target.id
117
+      // canvases[canvasId].scroll(e)
118
+    },
119
+    touchEnd(e) {
120
+      // const canvasId = e.target.id
121
+      // canvases[canvasId].scrollEnd(e)
122
+    }
123
+  }
124
+}
125
+</script>
126
+
127
+<style lang="scss" scoped>
128
+.page {
129
+  background-color: #f3fffa;
130
+  min-height: 100vh;
131
+}
132
+.card {
133
+  margin-top: 90rpx;
134
+  border-radius: 10px;
135
+}
136
+.title {
137
+  position: relative;
138
+  text-align: center;
139
+  &:before {
140
+    position: absolute;
141
+    top: 50%;
142
+    transform: translateY(-50%);
143
+    left: 0;
144
+    content: '';
145
+    width: 32%;
146
+    height: 2px;
147
+    border-bottom: 1px solid #5fd0e4;
148
+  }
149
+  &:after {
150
+    position: absolute;
151
+    top: 50%;
152
+    transform: translateY(-50%);
153
+    right: 0;
154
+    content: '';
155
+    width: 32%;
156
+    height: 2px;
157
+    border-bottom: 1px solid #5fd0e4;
158
+  }
159
+}
160
+.content {
161
+  min-height: 120px;
162
+}
163
+.student-avatar {
164
+  transform: translateY(-50%);
165
+}
166
+</style>

+ 7 - 7
src/pages/mine/message.vue

@@ -3,14 +3,14 @@
3 3
     <cu-custom :isBack="true" title="消息中心"></cu-custom>
4 4
     <view class="cu-list box-shadow menu">
5 5
       <view class="cu-item arrow margin-top-xs" v-for="message in list" :key="message.id">
6
-        <text class="cuIcon-notice lg text-gray" style="font-size:18px;"></text>
6
+        <text class="cuIcon-notice lg text-gray" style="font-size: 18px;"></text>
7 7
         <view class="content margin-left-sm">
8 8
           <view>系统通知</view>
9
-          <text class="text-black">{{message.title}}</text>
9
+          <text class="text-black">{{ message.title }}</text>
10 10
         </view>
11 11
       </view>
12 12
       <view class="cu-item arrow margin-top-xs" @tap="report">
13
-        <text class="cuIcon-notice lg text-gray" style="font-size:18px;"></text>
13
+        <text class="cuIcon-notice lg text-gray" style="font-size: 18px;"></text>
14 14
         <view class="content margin-left-sm">
15 15
           <text class="text-black">学生综合素质报告</text>
16 16
         </view>
@@ -22,19 +22,19 @@
22 22
 <script>
23 23
 import { _getNotice } from '@/api/auth'
24 24
 export default {
25
-  data () {
25
+  data() {
26 26
     return {
27 27
       list: []
28 28
     }
29 29
   },
30
-  onLoad () {
30
+  onLoad() {
31 31
     this.get_list()
32 32
   },
33 33
   methods: {
34
-    report () {
34
+    report() {
35 35
       uni.showToast({ title: '学期末才能领取对应的学生综合素质报告,敬请期待!', icon: 'none', duration: 2000 })
36 36
     },
37
-    get_list () {
37
+    get_list() {
38 38
       _getNotice().then(res => {
39 39
         this.list = res.data.notice_data
40 40
       })

+ 44 - 43
src/pages/mine/mine.vue

@@ -4,69 +4,74 @@
4 4
     <view class="main">
5 5
       <view class="main-top">
6 6
         <view class="title flex justify-between">
7
-          <view>{{user.nickName||'未更新用户信息'}}</view>
7
+          <view>{{ user.nickName || '未更新用户信息' }}</view>
8 8
           <text class="cuIcon-settings lg text-gray" @tap="goto('setting')"></text>
9 9
         </view>
10 10
         <view class="user">
11 11
           <view class="user-info flex">
12
-            <image mode="scaleToFill" :src="user.avatarUrl||defaultAvatar" class="avatar"></image>
12
+            <image mode="scaleToFill" :src="user.avatarUrl || defaultAvatar" class="avatar"></image>
13 13
             <view class="study-info">
14
-              <view class="user-name" @tap="switchStudent" v-if="isLogin&&user.nickName">
14
+              <view class="user-name" @tap="switchStudent" v-if="isLogin && user.nickName">
15 15
                 {{ kid_info.name + '-' + kid_info.school_name }}
16
-                <text class="iconfont margin-left-xs" style="font-size:18px;">&#xe600;</text>
16
+                <text class="iconfont margin-left-xs" style="font-size: 18px;">&#xe600;</text>
17 17
               </view>
18 18
               <view class="user-name" @tap="login" v-else>
19 19
                 切换学生
20
-                <text class="iconfont margin-left-xs" style="font-size:18px;">&#xe716;</text>
20
+                <text class="iconfont margin-left-xs" style="font-size: 18px;">&#xe716;</text>
21 21
               </view>
22
-              <view class="user-learn">已学习{{info.parent_data.learn_day}}天</view>
22
+              <view class="user-learn">已学习{{ info.parent_data.learn_day }}天</view>
23 23
             </view>
24 24
           </view>
25 25
           <view class="user-relative flex justify-between" v-if="isLogin">
26
-            <view v-for="(relate,index) in courseRelates" :key="index" class="course-item"
27
-              :style="'background:'+relate.background" @tap="goto(relate.page)">
28
-              <text class="iconfont back-img" style="font-size:32px;">{{relate.icon}}</text>
29
-              <view class="text-df">{{relate.name}}</view>
26
+            <view v-for="(relate, index) in courseRelates" :key="index" class="course-item" :style="'background:' + relate.background" @tap="goto(relate.page)">
27
+              <text class="iconfont back-img" style="font-size: 32px;">{{ relate.icon }}</text>
28
+              <view class="text-df">{{ relate.name }}</view>
30 29
             </view>
31 30
           </view>
32 31
           <view class="user-relative flex justify-between" v-else>
33
-            <view class="course-item relate-item" v-for="(course,index) in courses" :key="index"
34
-              :style="'background:'+course.background">
35
-              <text class="iconfont back-img" style="font-size:40px;">{{course.icon}}</text>
36
-              <view class="text-lg">{{course.title}}</view>
37
-              <view class="text-xxl margin-top-xs">{{course.name}}</view>
32
+            <view class="course-item relate-item" v-for="(course, index) in courses" :key="index" :style="'background:' + course.background">
33
+              <text class="iconfont back-img" style="font-size: 40px;">{{ course.icon }}</text>
34
+              <view class="text-lg">{{ course.title }}</view>
35
+              <view class="text-xxl margin-top-xs">{{ course.name }}</view>
38 36
             </view>
39 37
           </view>
40 38
         </view>
41 39
         <view class="order">
42 40
           <view class="order-title solid-bottom">我的订单</view>
43 41
           <view class="order-info flex justify-between">
44
-            <view v-for="(order,index) in menuList" :key="index" @tap="toOrder(index)">
42
+            <view v-for="(order, index) in menuList" :key="index" @tap="toOrder(index)">
45 43
               <view class="order-image">
46
-                <text class="iconfont text-student" style="font-size:32px;">{{order.icon}}</text>
44
+                <text class="iconfont text-student" style="font-size: 32px;">{{ order.icon }}</text>
47 45
               </view>
48
-              {{order.title}}
46
+              {{ order.title }}
49 47
             </view>
50 48
           </view>
51 49
         </view>
52 50
       </view>
53 51
       <view class="margin cu-list box-shadow menu margin-top-lg bg-white">
54 52
         <view class="cu-item arrow" @tap="goto('classCart')">
55
-          <text class="cuIcon-cart lg text-gray" style="font-size:18px;"></text>
53
+          <text class="cuIcon-cart lg text-gray" style="font-size: 18px;"></text>
56 54
           <view class="content margin-left-sm">
57 55
             <text class="text-black">购物车</text>
58 56
           </view>
59 57
           <view class="action"></view>
60 58
         </view>
61 59
         <view class="cu-item arrow" @tap="goto('message')">
62
-          <text class="cuIcon-message lg text-gray" style="font-size:18px;"></text>
60
+          <text class="cuIcon-message lg text-gray" style="font-size: 18px;"></text>
63 61
           <view class="content margin-left-sm">
64 62
             <text class="text-black">消息中心</text>
65 63
           </view>
66 64
           <view class="action"></view>
67 65
         </view>
66
+        <view class="cu-item arrow" @tap="goto('courseFiles')">
67
+          <text class="cuIcon-file lg text-gray" style="font-size: 18px;"></text>
68
+          <view class="content margin-left-sm">
69
+            <text class="text-black">课程档案</text>
70
+          </view>
71
+          <view class="action"></view>
72
+        </view>
68 73
         <view class="cu-item arrow" @tap="goto('onlineService')">
69
-          <text class="iconfont text-gray" style="font-size:18px;">&#xe726;</text>
74
+          <text class="iconfont text-gray" style="font-size: 18px;">&#xe726;</text>
70 75
           <view class="content margin-left-sm">
71 76
             <text class="text-black">在线客服</text>
72 77
           </view>
@@ -74,22 +79,17 @@
74 79
       </view>
75 80
     </view>
76 81
     <mp-tabbar :outerSelected="2" />
77
-    <view class="cu-modal drawer-modal justify-start" :class="modalName=='showStudent'?'show':''" @tap="hideModal">
78
-      <scroll-view :scroll-y="true" class="cu-dialog basis-lg" @tap.stop=""
79
-        :style="[{top:topHeader+'px',height:'calc(100vh - 48px - ' + topHeader + 'px)'}]">
82
+    <view class="cu-modal drawer-modal justify-start" :class="modalName == 'showStudent' ? 'show' : ''" @tap="hideModal">
83
+      <scroll-view :scroll-y="true" class="cu-dialog basis-lg" @tap.stop="" :style="[{ top: topHeader + 'px', height: 'calc(100vh - 48px - ' + topHeader + 'px)' }]">
80 84
         <view class="student-list padding-left">
81
-          <view class="student margin-top-sm" v-for="(student,index) in students" :key="index"
82
-            @tap="chooseKid(student.id)">
85
+          <view class="student margin-top-sm" v-for="(student, index) in students" :key="index" @tap="chooseKid(student.id)">
83 86
             <view class="flex align-center">
84 87
               <image mode="scaleToFill" :src="defaultAvatar" class="avatar md"></image>
85
-              <view class="margin-left-sm">{{student.name}}</view>
86
-              <text class="cuIcon-check text-student margin-left" style="font-size:22px;"
87
-                v-if="kid===student.id"></text>
88
+              <view class="margin-left-sm">{{ student.name }}</view>
89
+              <text class="cuIcon-check text-student margin-left" style="font-size: 22px;" v-if="kid === student.id"></text>
88 90
             </view>
89 91
             <view class="flex">
90
-              <view class="cu-tag line-green margin-top-xs">
91
-                {{student.school_name ? student.school_name : ''}}-{{student.grade_name}}-{{student.class_name}}
92
-              </view>
92
+              <view class="cu-tag line-green margin-top-xs"> {{ student.school_name ? student.school_name : '' }}-{{ student.grade_name }}-{{ student.class_name }} </view>
93 93
             </view>
94 94
           </view>
95 95
         </view>
@@ -102,7 +102,7 @@
102 102
 import { mapGetters } from 'vuex'
103 103
 import { _getStudents, _getUserInfo } from '@/api/auth'
104 104
 export default {
105
-  data () {
105
+  data() {
106 106
     return {
107 107
       topHeader: this.globalCustomBarHeight,
108 108
       info: {},
@@ -189,20 +189,20 @@ export default {
189 189
       kid: 'kid'
190 190
     })
191 191
   },
192
-  onShow () {
192
+  onShow() {
193 193
     this.get_info()
194 194
   },
195 195
   methods: {
196
-    login () {
196
+    login() {
197 197
       this.globalNavigateTo('login')
198 198
     },
199
-    get_info () {
199
+    get_info() {
200 200
       _getUserInfo().then(res => {
201 201
         this.info = res.data
202 202
         this.get_students()
203 203
       })
204 204
     },
205
-    get_students () {
205
+    get_students() {
206 206
       _getStudents().then(res => {
207 207
         if (res.data.length < 1) {
208 208
           this.globalNavigateTo('myStudents')
@@ -217,26 +217,27 @@ export default {
217 217
         this.setkidInfo(kid)
218 218
       })
219 219
     },
220
-    hideModal (e) {
220
+    hideModal(e) {
221 221
       this.modalName = null
222 222
     },
223
-    setkidInfo (kid) { // 设置学生信息
223
+    setkidInfo(kid) {
224
+      // 设置学生信息
224 225
       this.kid_info = this.students.find(item => item.id === kid)
225 226
     },
226
-    switchStudent () {
227
+    switchStudent() {
227 228
       this.modalName = 'showStudent'
228 229
     },
229
-    goto (page) {
230
+    goto(page) {
230 231
       if (!this.isLogin) {
231 232
         this.globalNavigateTo('login')
232 233
       } else {
233 234
         this.globalNavigateTo(page)
234 235
       }
235 236
     },
236
-    toOrder (index) {
237
+    toOrder(index) {
237 238
       this.globalNavigateTo('order', { type: index })
238 239
     },
239
-    chooseKid (id) {
240
+    chooseKid(id) {
240 241
       uni.showModal({
241 242
         title: '',
242 243
         content: '确定选择该学生?',

+ 156 - 15
src/pages/studentcenter/works.vue

@@ -3,7 +3,7 @@
3 3
     <cu-custom :isBack="true" title="课堂作品"></cu-custom>
4 4
     <scroll-view scroll-y="true" :style="[{ height: 'calc(100vh - ' + topHeader + 'px)' }]">
5 5
       <view class="content">
6
-        <view class="course-img">
6
+        <view class="course-img padding-sm">
7 7
           <swiper class="swiper" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval" :duration="swiper.duration">
8 8
             <swiper-item v-for="(item, index) in detail.course_data.image" :key="index">
9 9
               <view class="swiper-item">
@@ -12,34 +12,90 @@
12 12
             </swiper-item>
13 13
           </swiper>
14 14
         </view>
15
-        <view>
16
-          <view class="title margin-top-sm">课堂作品</view>
17
-          <view class="list" v-if="detail.student_comment_data">
18
-            <view class="cu-card case" v-for="(item, index) in detail.student_comment_data.data" :key="index">
19
-              <view class="cu-item shadow">
20
-                <view class="image">
21
-                  <view v-for="(img, i) in item.images" :key="i">
22
-                    <image :src="img" v-if="checkTypes(img, 'imgs')" mode="aspectFit" style="width: 100%;"></image>
23
-                    <video :src="img" v-if="checkTypes(img, 'video')" style="width: 100%;"></video>
24
-                  </view>
25
-                  <view class="margin-bottom-xs">老师点评:{{ detail.teach_review_data.data[0].msg }}</view>
15
+        <!-- 课堂作品 -->
16
+        <view class="cu-card" v-if="detail.student_comment_data.data">
17
+          <view class="cu-item">
18
+            <view class="card-head bg-student text-center text-white text-lg padding-sm">课堂作品 </view>
19
+            <view class="card-main padding-sm">
20
+              <view class="cu-card case" v-for="(item, index) in detail.student_comment_data.data" :key="index">
21
+                <view v-for="(img, i) in item.images" :key="i">
22
+                  <image class="upload-item solid" :src="img" mode="aspectFit" v-if="checkTypes(img, 'imgs')" @tap="viewImage" :data-url="img"></image>
23
+                  <video
24
+                    class="upload-item solid"
25
+                    :src="img"
26
+                    v-if="checkTypes(img, 'video')"
27
+                    :autoplay="true"
28
+                    :controls="false"
29
+                    :show-fullscreen-btn="false"
30
+                    @tap="viewVideo"
31
+                    :data-url="img"
32
+                    data-target="videoModal"
33
+                  ></video>
26 34
                 </view>
27 35
               </view>
28 36
             </view>
29 37
           </view>
30 38
         </view>
39
+        <!-- 能力分析 -->
40
+        <view class="cu-card" v-if="detail.student_comment_data.ability">
41
+          <view class="cu-item">
42
+            <view class="card-head bg-student text-center text-white text-lg padding-sm">能力分析 </view>
43
+            <view class="card-main padding-sm">
44
+              <canvas
45
+                canvas-id="ability"
46
+                id="ability"
47
+                class="charts"
48
+                @touchstart="touchStart"
49
+                @touchmove="touchMove"
50
+                @touchend="touchEnd"
51
+                @error="error"
52
+                :style="{
53
+                  width: cWidth * pixelRatio + 'px',
54
+                  height: cHeight * pixelRatio + 'px',
55
+                  transform: 'scale(' + 1 / pixelRatio + ')',
56
+                  'margin-left': (-cWidth * (pixelRatio - 1)) / 2 + 'px',
57
+                  'margin-top': (-cHeight * (pixelRatio - 1)) / 2 + 'px'
58
+                }"
59
+              ></canvas>
60
+            </view>
61
+          </view>
62
+        </view>
63
+        <!-- 课堂评价 -->
64
+        <view class="cu-card" v-if="detail.teach_review_data.data">
65
+          <view class="cu-item">
66
+            <view class="card-head bg-student text-center text-white text-lg padding-sm">课堂评价 </view>
67
+            <view class="card-main padding-sm" style="min-height: 100px;">
68
+              <view class="margin-bottom-xs">老师点评:{{ detail.teach_review_data.data[0].msg }}</view>
69
+            </view>
70
+          </view>
71
+        </view>
31 72
       </view>
32 73
     </scroll-view>
74
+    <!-- 视频预览 -->
75
+    <view class="cu-modal" :class="modalName == 'videoModal' ? 'show' : ''" @tap="hideModal">
76
+      <view class="cu-dialog" @tap.stop="">
77
+        <video class="bg-img" :src="videoUrl" :autoplay="true" :controls="true" :show-fullscreen-btn="false" style="height: 200px;"></video>
78
+      </view>
79
+    </view>
33 80
   </view>
34 81
 </template>
35 82
 
36 83
 <script>
37 84
 import { checkTypes } from '@/common/utils/index'
85
+import UCharts from '@/components/u-charts/u-charts.js'
86
+var canvases = {}
38 87
 export default {
39 88
   data() {
40 89
     return {
41 90
       topHeader: this.globalCustomBarHeight,
42
-      detail: {},
91
+      modalName: null,
92
+      pixelRatio: 1,
93
+      isShare: false,
94
+      cWidth: '',
95
+      cHeight: '',
96
+      detail: {
97
+        student_comment_data: {}
98
+      },
43 99
       swiper: {
44 100
         indicatorDots: true,
45 101
         autoplay: true,
@@ -48,13 +104,92 @@ export default {
48 104
       }
49 105
     }
50 106
   },
51
-  onLoad() {
107
+  // 配置分享
108
+  onShareAppMessage(res) {
109
+    if (res.from === 'button') {
110
+      // 来自页面内分享按钮
111
+      console.log(res.target)
112
+    }
113
+    return {
114
+      title: '课程作品',
115
+      path: `/pages/studentcenter/works?detail=${JSON.stringify(this.detail)}`
116
+    }
117
+  },
118
+  onLoad(options) {
119
+    if (options.detail) {
120
+      this.detail = JSON.parse(options.detail)
121
+      this.ifShare = true
122
+    }
123
+    this.cWidth = uni.upx2px(800) - 60
124
+    this.cHeight = uni.upx2px(400) // 图表配置
52 125
     this.init()
53 126
   },
54 127
   methods: {
55 128
     checkTypes,
56 129
     init() {
57
-      this.detail = JSON.parse(uni.getStorageSync('daily_class'))
130
+      //分享的页面直接读取分享数据,跳过
131
+      if (!this.ifShare) {
132
+        this.detail = JSON.parse(uni.getStorageSync('daily_class'))
133
+        //匹配能力对应分数
134
+        if (!this.detail.student_comment_data.ability) return false
135
+        this.detail.student_comment_data.ability.map(item => {
136
+          this.$set(item, 'score', this.detail.student_comment_data.ability_score[item.id])
137
+        })
138
+      }
139
+      const ability = {
140
+        categories: this.detail.student_comment_data.ability.map(item => item.name),
141
+        series: [
142
+          {
143
+            name: '评分',
144
+            data: this.detail.student_comment_data.ability.map(item => item.score)
145
+          }
146
+        ]
147
+      }
148
+      this.showRadar('ability', ability)
149
+    },
150
+    viewImage(e) {
151
+      uni.previewImage({
152
+        urls: [e.currentTarget.dataset.url],
153
+        current: e.currentTarget.dataset.url
154
+      })
155
+    },
156
+    viewVideo(e) {
157
+      this.modalName = e.currentTarget.dataset.target
158
+      this.videoUrl = e.currentTarget.dataset.url
159
+    },
160
+    hideModal(e) {
161
+      this.modalName = null
162
+    },
163
+    showRadar(canvasId, chartData) {
164
+      canvases[canvasId] = new UCharts({
165
+        canvasId: canvasId,
166
+        type: 'radar',
167
+        legend: { show: true },
168
+        fontSize: 11,
169
+        width: 300,
170
+        height: this.cHeight * this.pixelRatio,
171
+        pixelRatio: this.pixelRatio,
172
+        animation: true,
173
+        categories: chartData.categories,
174
+        series: chartData.series
175
+      })
176
+    },
177
+    touchStart(e) {
178
+      const canvasId = e.target.id
179
+      canvases[canvasId].showToolTip(e, {
180
+        format: function (item, category) {
181
+          return category ? category + ' ' + item.name + ':' + item.data : item.name + ':' + item.data
182
+        }
183
+      })
184
+      // canvases[canvasId].scrollStart(e)
185
+    },
186
+    touchMove(e) {
187
+      // const canvasId = e.target.id
188
+      // canvases[canvasId].scroll(e)
189
+    },
190
+    touchEnd(e) {
191
+      // const canvasId = e.target.id
192
+      // canvases[canvasId].scrollEnd(e)
58 193
     }
59 194
   }
60 195
 }
@@ -63,5 +198,11 @@ export default {
63 198
 <style lang="scss" scoped>
64 199
 .page {
65 200
   height: 100vh;
201
+  background-color: #f3fffa;
202
+}
203
+.upload-item {
204
+  margin-right: 20rpx;
205
+  width: 200rpx;
206
+  height: 200rpx;
66 207
 }
67 208
 </style>

BIN
src/static/imgs/intelligent-bg.png


BIN
src/static/imgs/star-rating/delivery_icon_star_active.png


BIN
src/static/imgs/star-rating/delivery_icon_star_disable.png


BIN
src/static/imgs/star-rating/delivery_icon_star_empty.png