seamwang преди 2 години
родител
ревизия
3dd355f6fb
променени са 2 файла, в които са добавени 568 реда и са изтрити 560 реда
  1. 366 360
      src/pages/studentcenter/index.vue
  2. 202 200
      src/pages/studentcenter/signIn.vue

+ 366 - 360
src/pages/studentcenter/index.vue

@@ -1,360 +1,366 @@
1
-<template>
2
-  <view class="page">
3
-    <cu-custom :isBack="false"></cu-custom>
4
-		<view class="header" :style="[{top:topHeader + 'px'}]">
5
-			<view class="header-title header-switch">
6
-				<view class="header-title-main" @tap="changeTab('schedule')" :class="{'cur':type==='schedule'}">
7
-						<view class="margin-bottom-xs">日程表</view>
8
-						<view class="point"></view>
9
-				</view>
10
-				<view class="header-title-main margin-left-lg" @tap="changeTab('mine')" :class="{'cur':type==='mine'}">
11
-						<view class="margin-bottom-xs">我的</view>
12
-						<view class="point"></view>
13
-				</view>
14
-			</view>
15
-			 <view style="width:120px;" v-if="type==='mine'">
16
-				 	<swiper-tab :menuList="menuList" @changeTab="swipe" :activeTab="currentIndex"></swiper-tab>
17
-			 </view>
18
-		</view>
19
-		<!-- 日程表 -->
20
-		<view v-if="type==='schedule'">
21
-			<scroll-view scroll-y="true"
22
-			:style="[{marginTop:'56px',height:'calc(100vh - 114px - '+ topHeader+'px)'}]">
23
-			 <uni-calendar class="uni-calendar--hook" :selected="info.selected"
24
-				style="padding-top:100px;"
25
-				:showMonth="false" @change="changeDay" @monthSwitch="monthSwitch" />
26
-				<view class="cu-card margin-top-xs padding-xs">
27
-					<view class="cu-item day-info">
28
-						<view class="day-title flex justify-between solid-bottom padding text-lg">
29
-							 <view>应到上课节数:{{present.be_section_num}}节</view>
30
-							 <view>实际上课节数: {{present.actual_section_num}}节</view>
31
-						</view>
32
-						<view class="day-chart flex justify-between padding">
33
-							<view v-for="(chart,key) in attendance" :key="key" class="flex-sub">
34
-									<canvas :canvas-id="key" style="margin:0 auto;width:100%;height:80px;"></canvas>
35
-									<view style="margin-left:18px;">{{chart.title}}</view>
36
-							</view>
37
-						</view>
38
-					</view>
39
-				</view>
40
-				<view class="list margin-top-xs">
41
-					<view class="cu-card margin-top margin-bottom shadow" v-for="(item,index) in classList" :key="index">
42
-						<view class="cu-item" v-for="(mark,i) in item.mark" :key="i">
43
-							<view class="card-header flex justify-end solid-bottom">
44
-									<view class="text-student course-status">
45
-											{{mark.status_desc}}
46
-									</view>
47
-							</view>
48
-							<view class="card flex">
49
-									<view class="card-left">
50
-										<img mode="scaleToFill" :src="mark.avatar" alt="" class="card-image">
51
-									</view>
52
-									<view class="card-right margin-left-sm">
53
-										<view class="card-title">{{mark.course_name}}</view>
54
-										<view class="card-item margin-top-xs" >
55
-										 	<text class="card-text">{{mark.start_at}}</text>
56
-									  </view>
57
-										<view class="card-item margin-top-xs" >
58
-										 	<text class="card-text">{{mark.end_at}}</text>
59
-									  </view>
60
-										<view class="card-item margin-top-xs">
61
-											<button class="cu-btn round line-cyan button-hover" @tap="classOperation(mark.class_plan_id)">
62
-												{{mark.status==-1?'查看':'去上课'}}
63
-											</button>
64
-											<button class="cu-btn round line-red button-hover margin-left" @tap="askLeave(mark.class_plan_id)">去请假</button>
65
-										</view>
66
-									</view>
67
-								</view>
68
-						</view>
69
-					</view>
70
-				</view>
71
-		  </scroll-view>
72
-		</view>
73
-		<!-- 我的 -->
74
-		<view v-if="type==='mine'">
75
-			<scroll-view scroll-y="true" @scrolltolower="loadMore" class="scroll-main"
76
-			:style="[{height:'calc(100vh - 114px - '+ topHeader+'px)'}]">
77
-				<view class="list">
78
-						<view class="cu-card margin-top margin-bottom shadow" v-for="(item,index) in list" :key="index">
79
-							<view class="cu-item">
80
-								<view class="card-header flex justify-between solid-bottom">
81
-									<view v-if="item.day">{{item.day}}</view>
82
-									<view class="text-student course-status" v-if="item.status">
83
-											{{item.status}}
84
-									</view>
85
-									<view class="text-student course-status" v-if="currentIndex===1">
86
-											已完结
87
-									</view>
88
-								</view>
89
-								<view class="card flex">
90
-									<view class="card-left">
91
-										<img mode="scaleToFill" :src="item.image" alt="" class="card-image">
92
-									</view>
93
-									<view class="card-right margin-left-sm">
94
-										<view class="card-title">{{item.attend_name}}</view>
95
-										<view class="card-item margin-top-xs" >
96
-											<text class="card-label">机构:</text>
97
-										 	<text class="card-text">{{item.agency_name||'-'}}</text>
98
-									  </view>
99
-										<view class="card-item margin-top-xs" >
100
-											<text class="card-label">老师:</text>
101
-										 	<text class="card-text">{{item.teacher||'-'}}</text>
102
-									  </view>
103
-									</view>
104
-								</view>
105
-							</view>
106
-						</view>
107
-				</view>
108
-			</scroll-view>
109
-		</view>
110
-    <mp-tabbar :outerSelected="1" />
111
-  </view>
112
-</template>
113
-
114
-<script>
115
-import NP from 'number-precision'
116
-import { uniCalendar } from '@dcloudio/uni-ui'
117
-import { _nowCourse, _courseHistory, _attendance, _dateCourse } from '@/api/course'
118
-import { getDate } from '@/common/utils'
119
-import swiperTab from '@/components/swiper-tab.vue'
120
-export default {
121
-  components: {
122
-    uniCalendar, swiperTab
123
-  },
124
-  data () {
125
-    return {
126
-      topHeader: this.globalCustomBarHeight,
127
-      type: 'schedule',
128
-      menuList: ['我的', '历史'],
129
-      currentIndex: 0,
130
-      page_num: 1,
131
-      noMore: false, // 加载判断
132
-      list: [],
133
-      classList: [], // 日程表
134
-      info: { // 日历数据
135
-        year: '',
136
-        month: '',
137
-        day: '',
138
-        selected: []
139
-      },
140
-      present: {
141
-        absenteeism_num: 0,
142
-        actual_section_num: 5,
143
-        be_section_num: 5,
144
-        late_num: 0,
145
-        leave_num: 0,
146
-        normal_num: 0
147
-      }, // 实际出席情况
148
-      attendance: { // 出席统计数据
149
-        leave_num: {
150
-          title: '请假', times: 2, color: '#9bde78'
151
-        },
152
-        late_num: {
153
-          title: '正常', times: 3, color: '#e0be60'
154
-        },
155
-        normal_num: {
156
-          title: '迟到', times: 1, color: '#61d4e2'
157
-        },
158
-        absenteeism_num: {
159
-          title: '旷课', times: 0, color: '#d697eb'
160
-        }
161
-      }
162
-    }
163
-  },
164
-  onShow() {
165
-    const today = getDate(new Date(), 0)
166
-    this.info.year = today.year
167
-    this.info.month = today.month
168
-    this.info.day = today.date
169
-    this.init()
170
-  },
171
-  methods: {
172
-    init() {
173
-      if (this.type === 'mine') {
174
-        this.get_list()
175
-      } else {
176
-        this.get_attend().then(res => {
177
-          this.present = res.data
178
-          this.fix_attend(res.data)
179
-          this.drawChart()
180
-          this.get_dateCourse()
181
-        })
182
-      }
183
-    },
184
-    classOperation(id) { // 上课
185
-      this.globalNavigateTo('studentOperation', { id })
186
-    },
187
-    askLeave(id) { // 请假
188
-      this.globalNavigateTo('studentAbsent', { id })
189
-    },
190
-    loadMore() {
191
-      if (this.noMore) {
192
-        uni.showToast({ title: '没有更多了', icon: 'none' })
193
-        return false
194
-      }
195
-      this.page_num++
196
-      this.get_list()
197
-    },
198
-    get_list() {
199
-      if (this.currentIndex === 0) {
200
-        this.get_course()
201
-      } else {
202
-        this.get_history()
203
-      }
204
-    },
205
-    get_course() {
206
-      _nowCourse({ page_num: this.page_num }).then(res => {
207
-        if (this.page_num > 1) {
208
-          if (res.data.length < this.page_size) this.noMore = true
209
-          this.list = this.list.concat(res.data)
210
-        } else {
211
-          this.noMore = false
212
-          this.list = res.data
213
-        }
214
-      })
215
-    },
216
-    get_history() {
217
-      _courseHistory({ page_num: this.page_num }).then(res => {
218
-        if (this.page_num > 1) {
219
-          if (res.data.length < this.page_size) this.noMore = true
220
-          this.list = Object.assign({}, this.list, res.data)
221
-        } else {
222
-          this.noMore = false
223
-          this.list = res.data
224
-        }
225
-      })
226
-    },
227
-    drawChart() {
228
-      for (var key in this.attendance) {
229
-        this.draw(this.attendance[key], key)
230
-      }
231
-    },
232
-    changeTab(type) {
233
-      this.type = type
234
-      this.$nextTick(() => {
235
-        this.init()
236
-      })
237
-    },
238
-    swipe(index) {
239
-      this.currentIndex = index
240
-      this.page_num = 1
241
-      this.get_list()
242
-    },
243
-    changeDay(e) {
244
-      // 模拟动态打卡
245
-      // if (this.info.selected.length > 5) return
246
-      // this.info.selected.push({
247
-      //   date: e.fulldate,
248
-      //   info: '打卡'
249
-      // })
250
-    },
251
-    monthSwitch(e) {
252
-      console.log(e)
253
-    },
254
-    get_attend() { // 获取出席情况
255
-      const date = this.info.year + '-' + this.info.month
256
-      return new Promise((resolve, reject) => {
257
-        const info = _attendance({ date })
258
-        resolve(info)
259
-      })
260
-    },
261
-    fix_attend(info) { // 补充出席实际数据
262
-      Object.keys(this.attendance).forEach(key => {
263
-        this.attendance[key].times = info[key]
264
-      })
265
-    },
266
-    get_dateCourse() { // 获取对应日期数据
267
-      _dateCourse({ year: this.info.year, month: this.info.month }).then(res => {
268
-        this.classList = res.data
269
-      })
270
-    },
271
-    draw (ele, key) {
272
-      const ctx = uni.createCanvasContext(key)
273
-      const value = NP.divide(ele.times, this.present.be_section_num) * 100// 次数转化对应百分比值
274
-      const startAngle = 1.5
275
-      const endAngle = 1.5 + value * 2 / 100
276
-      // 画圆环
277
-      ctx.beginPath()
278
-      ctx.arc(34, 40, 28, 0, 2 * Math.PI)
279
-      ctx.setStrokeStyle('#EDEDED') // 弧线的颜色
280
-      ctx.setLineWidth('8') // 弧的宽度
281
-      ctx.setLineCap('round') // 线条结束端点样式 butt 平直 round 圆形 square 正方形
282
-      ctx.stroke()
283
-      // 画进度条
284
-      ctx.beginPath()
285
-      ctx.arc(34, 40, 28, startAngle * Math.PI, endAngle * Math.PI)
286
-      ctx.setStrokeStyle(ele.color)
287
-      ctx.setLineWidth('8')
288
-      ctx.setLineCap('round')
289
-      ctx.stroke()
290
-      ctx.setFontSize(14)
291
-      ctx.setFillStyle('#000') // 文字的颜色
292
-      ctx.fillText(ele.times + '次', 20, 44)
293
-      ctx.draw()
294
-    }
295
-  }
296
-}
297
-</script>
298
-
299
-<style lang="scss">
300
-@import '~@/common/css/mixin.scss';
301
-.page{
302
-	height:100vh;
303
-}
304
-.header-switch{
305
-	justify-content:start;
306
-	.header-title-main{
307
-		font-size:18px;
308
-		color:#999;
309
-		.point{
310
-			opacity: 0;
311
-		}
312
-		&.cur{
313
-			transition: font-size .3s;
314
-			font-size:24px;
315
-			color:#000;
316
-			.point{
317
-				opacity: 1;
318
-		  }
319
-		}
320
-	}
321
-}
322
-.day-info{
323
-
324
-}
325
-.scroll-main{
326
-	margin-top:78px;
327
-	padding:20rpx;
328
-}
329
-.cu-card{
330
-	.cu-item{
331
-		margin-top:10rpx;
332
-		padding:20rpx;
333
-		margin:0;
334
-	}
335
-}
336
-.card-header{
337
-	padding-bottom:10px;
338
-  @include title(10px,18px);
339
-}
340
-.card{
341
-	&-title{
342
-		font-size:16px;
343
-	}
344
-	&-image{
345
-		width:35vw;
346
-		height:25vw;
347
-		border-radius:2vw;
348
-	}
349
-	&-label{
350
-		color:#999;
351
-	}
352
-	&-text{
353
-		color:#333;
354
-	}
355
-}
356
-.course-status{
357
-	font-size:14px;
358
-	font-weight:normal;
359
-}
360
-</style>
1
+<template>
2
+  <view class="page">
3
+    <cu-custom :isBack="false"></cu-custom>
4
+		<view class="header" :style="[{top:topHeader + 'px'}]">
5
+			<view class="header-title header-switch">
6
+				<view class="header-title-main" @tap="changeTab('schedule')" :class="{'cur':type==='schedule'}">
7
+						<view class="margin-bottom-xs">日程表</view>
8
+						<view class="point"></view>
9
+				</view>
10
+				<view class="header-title-main margin-left-lg" @tap="changeTab('mine')" :class="{'cur':type==='mine'}">
11
+						<view class="margin-bottom-xs">我的</view>
12
+						<view class="point"></view>
13
+				</view>
14
+			</view>
15
+			 <view style="width:120px;" v-if="type==='mine'">
16
+				 	<swiper-tab :menuList="menuList" @changeTab="swipe" :activeTab="currentIndex"></swiper-tab>
17
+			 </view>
18
+		</view>
19
+		<!-- 日程表 -->
20
+		<view v-if="type==='schedule'">
21
+			<scroll-view scroll-y="true"
22
+			:style="[{marginTop:'56px',height:'calc(100vh - 114px - '+ topHeader+'px)'}]">
23
+			 <uni-calendar class="uni-calendar--hook" :selected="info.selected"
24
+				style="padding-top:100px;"
25
+				:showMonth="false" @change="changeDay" @monthSwitch="monthSwitch" />
26
+				<view class="cu-card margin-top-xs padding-xs">
27
+					<view class="cu-item day-info">
28
+						<view class="day-title flex justify-between solid-bottom padding text-lg">
29
+							 <view>应到上课节数:{{present.be_section_num}}节</view>
30
+							 <view>实际上课节数: {{present.actual_section_num}}节</view>
31
+						</view>
32
+						<view class="day-chart flex justify-between padding">
33
+							<view v-for="(chart,key) in attendance" :key="key" class="flex-sub">
34
+									<canvas :canvas-id="key" style="margin:0 auto;width:100%;height:80px;"></canvas>
35
+									<view style="margin-left:18px;">{{chart.title}}</view>
36
+							</view>
37
+						</view>
38
+					</view>
39
+				</view>
40
+				<view class="list margin-top-xs">
41
+					<view class="cu-card margin-top margin-bottom shadow" v-for="(item,index) in classList" :key="index">
42
+						<view class="cu-item" v-for="(mark,i) in item.mark" :key="i">
43
+							<view class="card-header flex justify-end solid-bottom">
44
+									<view class="text-student course-status">
45
+											{{mark.status_desc}}
46
+									</view>
47
+							</view>
48
+							<view class="card flex">
49
+									<view class="card-left">
50
+										<img mode="scaleToFill" :src="mark.avatar" alt="" class="card-image">
51
+									</view>
52
+									<view class="card-right margin-left-sm">
53
+										<view class="card-title">{{mark.course_name}}</view>
54
+										<view class="card-item margin-top-xs" >
55
+										 	<text class="card-text">{{mark.start_at}}</text>
56
+									  </view>
57
+										<view class="card-item margin-top-xs" >
58
+										 	<text class="card-text">{{mark.end_at}}</text>
59
+									  </view>
60
+										<view class="card-item margin-top-xs">
61
+											<button class="cu-btn round line-cyan button-hover" @tap="classOperation(mark.class_plan_id)">
62
+												{{mark.status==-1?'查看':'去上课'}}
63
+											</button>
64
+											<button class="cu-btn round line-red button-hover margin-left" @tap="askLeave(mark.class_plan_id)">去请假</button>
65
+										</view>
66
+									</view>
67
+								</view>
68
+						</view>
69
+					</view>
70
+				</view>
71
+		  </scroll-view>
72
+		</view>
73
+		<!-- 我的 -->
74
+		<view v-if="type==='mine'">
75
+			<scroll-view scroll-y="true" @scrolltolower="loadMore" class="scroll-main"
76
+			:style="[{height:'calc(100vh - 114px - '+ topHeader+'px)'}]">
77
+				<view class="list">
78
+						<view class="cu-card margin-top margin-bottom shadow" v-for="(item,index) in list" :key="index">
79
+							<view class="cu-item">
80
+								<view class="card-header flex justify-between solid-bottom">
81
+									<view v-if="item.day">{{item.day}}</view>
82
+									<view class="text-student course-status" v-if="item.status">
83
+											{{item.status}}
84
+									</view>
85
+									<view class="text-student course-status" v-if="currentIndex===1">
86
+											已完结
87
+									</view>
88
+								</view>
89
+								<view class="card flex">
90
+									<view class="card-left">
91
+										<img mode="scaleToFill" :src="item.image" alt="" class="card-image">
92
+									</view>
93
+									<view class="card-right margin-left-sm">
94
+										<view class="card-title">{{item.attend_name}}</view>
95
+										<view class="card-item margin-top-xs" >
96
+											<text class="card-label">机构:</text>
97
+										 	<text class="card-text">{{item.agency_name||'-'}}</text>
98
+									  </view>
99
+										<view class="card-item margin-top-xs" >
100
+											<text class="card-label">老师:</text>
101
+										 	<text class="card-text">{{item.teacher||'-'}}</text>
102
+									  </view>
103
+									</view>
104
+								</view>
105
+							</view>
106
+						</view>
107
+				</view>
108
+			</scroll-view>
109
+		</view>
110
+    <mp-tabbar :outerSelected="1" />
111
+  </view>
112
+</template>
113
+
114
+<script>
115
+import NP from 'number-precision'
116
+import { uniCalendar } from '@dcloudio/uni-ui'
117
+import { _nowCourse, _courseHistory, _attendance, _dateCourse } from '@/api/course'
118
+import { getDate } from '@/common/utils'
119
+import swiperTab from '@/components/swiper-tab.vue'
120
+export default {
121
+  components: {
122
+    uniCalendar, swiperTab
123
+  },
124
+  data () {
125
+    return {
126
+      topHeader: this.globalCustomBarHeight,
127
+      type: 'schedule',
128
+      menuList: ['我的', '历史'],
129
+      currentIndex: 0,
130
+      page_num: 1,
131
+      noMore: false, // 加载判断
132
+      list: [],
133
+      classList: [], // 日程表
134
+      info: { // 日历数据
135
+        year: '',
136
+        month: '',
137
+        day: '',
138
+        selected: []
139
+      },
140
+      present: {
141
+        absenteeism_num: 0,
142
+        actual_section_num: 5,
143
+        be_section_num: 5,
144
+        late_num: 0,
145
+        leave_num: 0,
146
+        normal_num: 0
147
+      }, // 实际出席情况
148
+      attendance: { // 出席统计数据
149
+        leave_num: {
150
+          title: '请假', times: 2, color: '#9bde78'
151
+        },
152
+        late_num: {
153
+          title: '正常', times: 3, color: '#e0be60'
154
+        },
155
+        normal_num: {
156
+          title: '迟到', times: 1, color: '#61d4e2'
157
+        },
158
+        absenteeism_num: {
159
+          title: '旷课', times: 0, color: '#d697eb'
160
+        }
161
+      }
162
+    }
163
+  },
164
+  onReady() {
165
+    const today = getDate(new Date(), 0)
166
+    this.info.year = today.year
167
+    this.info.month = today.month
168
+    this.info.day = today.date
169
+    this.init()
170
+  },
171
+  methods: {
172
+    init() {
173
+      if (this.type === 'mine') {
174
+        this.get_list()
175
+      } else {
176
+        this.getSehedule()
177
+      }
178
+    },
179
+    getSehedule() {
180
+      this.get_attend().then(res => {
181
+        this.present = res.data
182
+        this.fix_attend(res.data)
183
+        this.drawChart()
184
+        this.get_dateCourse()
185
+      })
186
+    },
187
+    classOperation(id) { // 上课
188
+      this.globalNavigateTo('studentOperation', { id })
189
+    },
190
+    askLeave(id) { // 请假
191
+      this.globalNavigateTo('studentAbsent', { id })
192
+    },
193
+    loadMore() {
194
+      if (this.noMore) {
195
+        uni.showToast({ title: '没有更多了', icon: 'none' })
196
+        return false
197
+      }
198
+      this.page_num++
199
+      this.get_list()
200
+    },
201
+    get_list() {
202
+      if (this.currentIndex === 0) {
203
+        this.get_course()
204
+      } else {
205
+        this.get_history()
206
+      }
207
+    },
208
+    get_course() {
209
+      _nowCourse({ page_num: this.page_num }).then(res => {
210
+        if (this.page_num > 1) {
211
+          if (res.data.length < this.page_size) this.noMore = true
212
+          this.list = this.list.concat(res.data)
213
+        } else {
214
+          this.noMore = false
215
+          this.list = res.data
216
+        }
217
+      })
218
+    },
219
+    get_history() {
220
+      _courseHistory({ page_num: this.page_num }).then(res => {
221
+        if (this.page_num > 1) {
222
+          if (res.data.length < this.page_size) this.noMore = true
223
+          this.list = Object.assign({}, this.list, res.data)
224
+        } else {
225
+          this.noMore = false
226
+          this.list = res.data
227
+        }
228
+      })
229
+    },
230
+    drawChart() {
231
+      for (var key in this.attendance) {
232
+        this.draw(this.attendance[key], key)
233
+      }
234
+    },
235
+    changeTab(type) {
236
+      this.type = type
237
+      this.$nextTick(() => {
238
+        this.init()
239
+      })
240
+    },
241
+    swipe(index) {
242
+      this.currentIndex = index
243
+      this.page_num = 1
244
+      this.get_list()
245
+    },
246
+    changeDay(e) {
247
+      this.info.day = e.date
248
+      // 模拟动态打卡
249
+      // if (this.info.selected.length > 5) return
250
+      // this.info.selected.push({
251
+      //   date: e.fulldate,
252
+      //   info: '打卡'
253
+      // })
254
+    },
255
+    monthSwitch(e) {
256
+      this.info.year = e.year
257
+      this.info.month = e.month < 10 ? '0' + e.month : e.month
258
+      this.getSehedule()
259
+    },
260
+    get_attend() { // 获取出席情况
261
+      const date = this.info.year + '-' + this.info.month
262
+      return new Promise((resolve, reject) => {
263
+        const info = _attendance({ date })
264
+        resolve(info)
265
+      })
266
+    },
267
+    fix_attend(info) { // 补充出席实际数据
268
+      Object.keys(this.attendance).forEach(key => {
269
+        this.attendance[key].times = info[key]
270
+      })
271
+    },
272
+    get_dateCourse() { // 获取对应日期数据
273
+      _dateCourse({ year: this.info.year, month: this.info.month }).then(res => {
274
+        this.classList = res.data
275
+      })
276
+    },
277
+    draw (ele, key) {
278
+      const ctx = uni.createCanvasContext(key)
279
+      const value = NP.divide(ele.times, this.present.be_section_num) * 100// 次数转化对应百分比值
280
+      const startAngle = 1.5
281
+      const endAngle = 1.5 + value * 2 / 100
282
+      // 画圆环
283
+      ctx.beginPath()
284
+      ctx.arc(34, 40, 28, 0, 2 * Math.PI)
285
+      ctx.setStrokeStyle('#EDEDED') // 弧线的颜色
286
+      ctx.setLineWidth('8') // 弧的宽度
287
+      ctx.setLineCap('round') // 线条结束端点样式 butt 平直 round 圆形 square 正方形
288
+      ctx.stroke()
289
+      // 画进度条
290
+      ctx.beginPath()
291
+      ctx.arc(34, 40, 28, startAngle * Math.PI, endAngle * Math.PI)
292
+      ctx.setStrokeStyle(ele.color)
293
+      ctx.setLineWidth('8')
294
+      ctx.setLineCap('round')
295
+      ctx.stroke()
296
+      ctx.setFontSize(14)
297
+      ctx.setFillStyle('#000') // 文字的颜色
298
+      ctx.fillText(ele.times + '次', 20, 44)
299
+      ctx.draw()
300
+    }
301
+  }
302
+}
303
+</script>
304
+
305
+<style lang="scss">
306
+@import '~@/common/css/mixin.scss';
307
+.page{
308
+	height:100vh;
309
+}
310
+.header-switch{
311
+	justify-content:start;
312
+	.header-title-main{
313
+		font-size:18px;
314
+		color:#999;
315
+		.point{
316
+			opacity: 0;
317
+		}
318
+		&.cur{
319
+			transition: font-size .3s;
320
+			font-size:24px;
321
+			color:#000;
322
+			.point{
323
+				opacity: 1;
324
+		  }
325
+		}
326
+	}
327
+}
328
+.day-info{
329
+
330
+}
331
+.scroll-main{
332
+	margin-top:78px;
333
+	padding:20rpx;
334
+}
335
+.cu-card{
336
+	.cu-item{
337
+		margin-top:10rpx;
338
+		padding:20rpx;
339
+		margin:0;
340
+	}
341
+}
342
+.card-header{
343
+	padding-bottom:10px;
344
+  @include title(10px,18px);
345
+}
346
+.card{
347
+	&-title{
348
+		font-size:16px;
349
+	}
350
+	&-image{
351
+		width:35vw;
352
+		height:25vw;
353
+		border-radius:2vw;
354
+	}
355
+	&-label{
356
+		color:#999;
357
+	}
358
+	&-text{
359
+		color:#333;
360
+	}
361
+}
362
+.course-status{
363
+	font-size:14px;
364
+	font-weight:normal;
365
+}
366
+</style>

+ 202 - 200
src/pages/studentcenter/signIn.vue

@@ -1,200 +1,202 @@
1
-<template>
2
-  <view class="page">
3
-		<cu-custom :isBack="true" title="上课签到"></cu-custom>
4
-		<view class="header bg-white" 	:style="[{top:topHeader + 'px'}]">
5
-			<view class="icon_title flex align-center justify-between solid-bottom">
6
-				<view class="info flex align-center justify-between">
7
-					 <image mode="scaleToFill" :src="user.avatarUrl" class="avatar lg" v-if="user.avatarUrl"></image>
8
-			  	 <view class="username">{{user.nickName}}</view>
9
-				</view>
10
-				<view style="color:#00D2E3">{{info.status_desc}}</view>
11
-    	</view>
12
-			<view class="class_info">
13
-				<view style="font-size:15px;margin-top: .6rem;">{{info.start_at}}</view>
14
-				<view class="class_title">{{info.course_name}}</view>
15
-				<view class="address flex align-center">
16
-					<image src="/static/imgs/school.png" mode="widthFix" style="width:18px;"/>
17
-					<view style="margin-left: 10px;margin-right: 20px">{{info.school_name}}</view>
18
-					<image src="/static/imgs/address.png" mode="widthFix" style="width:14px;"/>
19
-					<view style="margin-left: 10px">{{info.classroom_name}}</view>
20
-				</view>
21
-    	</view>
22
-		</view>
23
-		<view class="content">
24
-			<view class="content_title">签到说明</view>
25
-    	<view>接到学生后请“点击签到”按钮作为签到</view>
26
-			<view class="button" :style="checked?'background: #ddd':''"  hover-class="button_hover" @tap="signIn">
27
-				<view class="text" :style="checked?'color: #aaa':''"> {{checked?'已签到':'点击签到'}}</view>
28
-				<view class="pulse" v-if="!checked"></view>
29
-				<view class="pulse1" v-if="!checked"></view>
30
-    	</view>
31
-     	<view class="des_title">
32
-				<view class="line"></view>
33
-				<view>注意事项</view>
34
-				<view class="line"></view>
35
-    	</view>
36
-			<view>为确保学校每个学生的接送安全,平台特将接送学生的有关的 安全细则及注意事项重申如下,希望相关监护人及学生遵照执 行: </view>
37
-			<view>1.要遵守校规,按时到校,听从教师的教导。 </view>
38
-			<view>2.上课要自觉遵守课堂纪律,认真听讲,积极思维,好好学习。</view>
39
-		</view>
40
-	</view>
41
-</template>
42
-
43
-<script>
44
-import { _getSignIn, _toSignIn } from '@/api/course'
45
-import { mapGetters } from 'vuex'
46
-export default {
47
-  data() {
48
-    return {
49
-      topHeader: this.globalCustomBarHeight,
50
-      checked: false,
51
-      plan_id: '',
52
-      clock_in_id: '',
53
-      info: {}
54
-    }
55
-  },
56
-  computed: {
57
-    ...mapGetters([
58
-      'user'
59
-    ])
60
-  },
61
-  onLoad(options) {
62
-    const id = decodeURIComponent(options.plan_id)
63
-    if (!id) uni.navigateBack()
64
-    this.plan_id = id
65
-    this.init()
66
-  },
67
-  methods: {
68
-    init() {
69
-      _getSignIn({ plan_id: this.plan_id }).then(res => {
70
-        this.info = res.data.sign_data
71
-      })
72
-    },
73
-    signIn() {
74
-      _toSignIn({ plan_id: this.plan_id }).then(res => {
75
-        this.checked = true
76
-      })
77
-    }
78
-  }
79
-}
80
-</script>
81
-
82
-<style lang="scss" scoped>
83
-.header{
84
-  border-radius: 0 0 10px 10px;
85
-  padding: .8rem;
86
-  .icon_title{
87
-    .info{
88
-      .username{
89
-        font-size: 21px;
90
-        margin-left: 15px;
91
-      }
92
-    }
93
-  }
94
-  .class_info{
95
-    margin-left: .8rem;
96
-  }
97
-  .class_title{
98
-    font-size: 20px;
99
-    font-weight: 550;
100
-    margin-top: .6rem;
101
-  }
102
-  .address{
103
-    display: flex;
104
-    align-items: center;
105
-    color: #898E96;
106
-    font-size: 14px;
107
-    margin-top: .6rem;
108
-  }
109
-}
110
-.content{
111
-  margin-top: .8rem;
112
-  background: #fff;
113
-  color: #888;
114
-  padding: 2rem;
115
-  font-size: 14px;
116
-  .content_title{
117
-    font-size: 15px;
118
-    font-weight: 600;
119
-    color: #000;
120
-    margin-bottom: .4rem;
121
-  }
122
-  .button{
123
-    margin: 2rem auto;
124
-    width: 30vw;
125
-    height: 30vw;
126
-    border-radius: 50%;
127
-    background: #5fcfe0;
128
-    text-align: center;
129
-    line-height: 30vw;
130
-    font-size: 18px;
131
-    color: #fff;
132
-    font-weight: 600;
133
-    position: relative;
134
-    .text{
135
-			position: absolute;
136
-			top: 50%;
137
-      left: 50%;
138
-      transform: translate(-50%,-50%);
139
-		  width: 30vw;
140
-      z-index: 999;
141
-    }
142
-    .pulse{
143
-      position: absolute;
144
-      top: 0;
145
-      left: 0;
146
-      width: 30vw;
147
-      height: 30vw;
148
-      border-radius: 50%;
149
-      animation: warn1 2s linear .5s infinite;
150
-      background: #bfeff7;
151
-      z-index: 1;
152
-    }
153
-    .pulse1{
154
-      position: absolute;
155
-      top: 0;
156
-      left: 0;
157
-      width: 30vw;
158
-      height: 30vw;
159
-      border-radius: 50%;
160
-      animation: warn1 2s linear 1s infinite;
161
-      background: #76dae8;
162
-      z-index: 1;
163
-    }
164
-  }
165
-  .des_title{
166
-    display: flex;
167
-    justify-content: center;
168
-    align-items: center;
169
-    margin-bottom: 1rem;
170
-    .line{
171
-      border: 1px solid #aaa;
172
-      width: 20vw;
173
-      margin: 0 15px;
174
-    }
175
-  }
176
-}
177
-
178
-@keyframes warn1 {
179
-  0% {
180
-  transform: scale(1);
181
-  opacity: 0;
182
-  }
183
-  25% {
184
-  transform: scale(1);
185
-  opacity: .1;
186
-  }
187
-  50% {
188
-  transform: scale(1);
189
-  opacity: .3;
190
-  }
191
-  75% {
192
-  transform: scale(1.1);
193
-  opacity: .5;
194
-  }
195
-  100% {
196
-  transform: scale(1.3);
197
-  opacity: 0;
198
-  }
199
-}
200
-</style>
1
+<template>
2
+  <view class="page">
3
+		<cu-custom :isBack="true" title="上课签到"></cu-custom>
4
+		<view class="header bg-white" 	:style="[{top:topHeader + 'px'}]">
5
+			<view class="icon_title flex align-center justify-between solid-bottom">
6
+				<view class="info flex align-center justify-between">
7
+					 <image mode="scaleToFill" :src="user.avatarUrl" class="avatar lg" v-if="user.avatarUrl"></image>
8
+			  	 <view class="username">{{user.nickName}}</view>
9
+				</view>
10
+				<view style="color:#00D2E3">{{info.status_desc}}</view>
11
+    	</view>
12
+			<view class="class_info">
13
+				<view style="font-size:15px;margin-top: .6rem;">{{info.start_at}}</view>
14
+				<view class="class_title">{{info.course_name}}</view>
15
+				<view class="address flex align-center">
16
+					<image src="/static/imgs/school.png" mode="widthFix" style="width:18px;"/>
17
+					<view style="margin-left: 10px;margin-right: 20px">{{info.school_name}}</view>
18
+					<image src="/static/imgs/address.png" mode="widthFix" style="width:14px;"/>
19
+					<view style="margin-left: 10px">{{info.classroom_name}}</view>
20
+				</view>
21
+    	</view>
22
+		</view>
23
+		<view class="content">
24
+			<view class="content_title">签到说明</view>
25
+    	<view>接到学生后请“点击签到”按钮作为签到</view>
26
+			<view class="button" :style="checked?'background: #ddd':''"  hover-class="button_hover" @tap="signIn">
27
+				<view class="text" :style="checked?'color: #aaa':''"> {{checked?'已签到':'点击签到'}}</view>
28
+				<view class="pulse" v-if="!checked"></view>
29
+				<view class="pulse1" v-if="!checked"></view>
30
+    	</view>
31
+     	<view class="des_title">
32
+				<view class="line"></view>
33
+				<view>注意事项</view>
34
+				<view class="line"></view>
35
+    	</view>
36
+			<view>为确保学校每个学生的接送安全,平台特将接送学生的有关的 安全细则及注意事项重申如下,希望相关监护人及学生遵照执 行: </view>
37
+			<view>1.要遵守校规,按时到校,听从教师的教导。 </view>
38
+			<view>2.上课要自觉遵守课堂纪律,认真听讲,积极思维,好好学习。</view>
39
+		</view>
40
+	</view>
41
+</template>
42
+
43
+<script>
44
+import { _getSignIn, _toSignIn } from '@/api/course'
45
+import { mapGetters } from 'vuex'
46
+export default {
47
+  data() {
48
+    return {
49
+      topHeader: this.globalCustomBarHeight,
50
+      checked: false,
51
+      plan_id: '',
52
+      clock_in_id: '',
53
+      info: {}
54
+    }
55
+  },
56
+  computed: {
57
+    ...mapGetters([
58
+      'user'
59
+    ])
60
+  },
61
+  onLoad(options) {
62
+    const id = decodeURIComponent(options.plan_id)
63
+    if (!id) uni.navigateBack()
64
+    this.plan_id = id
65
+    this.init()
66
+  },
67
+  methods: {
68
+    init() {
69
+      _getSignIn({ plan_id: this.plan_id }).then(res => {
70
+        this.info = res.data.sign_data
71
+        this.checked = !this.info.status
72
+      })
73
+    },
74
+    signIn() {
75
+      if (this.checked) return false
76
+      _toSignIn({ clock_in_id: this.info.clock_in_id }).then(res => {
77
+        this.checked = true
78
+      })
79
+    }
80
+  }
81
+}
82
+</script>
83
+
84
+<style lang="scss" scoped>
85
+.header{
86
+  border-radius: 0 0 10px 10px;
87
+  padding: .8rem;
88
+  .icon_title{
89
+    .info{
90
+      .username{
91
+        font-size: 21px;
92
+        margin-left: 15px;
93
+      }
94
+    }
95
+  }
96
+  .class_info{
97
+    margin-left: .8rem;
98
+  }
99
+  .class_title{
100
+    font-size: 20px;
101
+    font-weight: 550;
102
+    margin-top: .6rem;
103
+  }
104
+  .address{
105
+    display: flex;
106
+    align-items: center;
107
+    color: #898E96;
108
+    font-size: 14px;
109
+    margin-top: .6rem;
110
+  }
111
+}
112
+.content{
113
+  margin-top: .8rem;
114
+  background: #fff;
115
+  color: #888;
116
+  padding: 2rem;
117
+  font-size: 14px;
118
+  .content_title{
119
+    font-size: 15px;
120
+    font-weight: 600;
121
+    color: #000;
122
+    margin-bottom: .4rem;
123
+  }
124
+  .button{
125
+    margin: 2rem auto;
126
+    width: 30vw;
127
+    height: 30vw;
128
+    border-radius: 50%;
129
+    background: #5fcfe0;
130
+    text-align: center;
131
+    line-height: 30vw;
132
+    font-size: 18px;
133
+    color: #fff;
134
+    font-weight: 600;
135
+    position: relative;
136
+    .text{
137
+			position: absolute;
138
+			top: 50%;
139
+      left: 50%;
140
+      transform: translate(-50%,-50%);
141
+		  width: 30vw;
142
+      z-index: 999;
143
+    }
144
+    .pulse{
145
+      position: absolute;
146
+      top: 0;
147
+      left: 0;
148
+      width: 30vw;
149
+      height: 30vw;
150
+      border-radius: 50%;
151
+      animation: warn1 2s linear .5s infinite;
152
+      background: #bfeff7;
153
+      z-index: 1;
154
+    }
155
+    .pulse1{
156
+      position: absolute;
157
+      top: 0;
158
+      left: 0;
159
+      width: 30vw;
160
+      height: 30vw;
161
+      border-radius: 50%;
162
+      animation: warn1 2s linear 1s infinite;
163
+      background: #76dae8;
164
+      z-index: 1;
165
+    }
166
+  }
167
+  .des_title{
168
+    display: flex;
169
+    justify-content: center;
170
+    align-items: center;
171
+    margin-bottom: 1rem;
172
+    .line{
173
+      border: 1px solid #aaa;
174
+      width: 20vw;
175
+      margin: 0 15px;
176
+    }
177
+  }
178
+}
179
+
180
+@keyframes warn1 {
181
+  0% {
182
+  transform: scale(1);
183
+  opacity: 0;
184
+  }
185
+  25% {
186
+  transform: scale(1);
187
+  opacity: .1;
188
+  }
189
+  50% {
190
+  transform: scale(1);
191
+  opacity: .3;
192
+  }
193
+  75% {
194
+  transform: scale(1.1);
195
+  opacity: .5;
196
+  }
197
+  100% {
198
+  transform: scale(1.3);
199
+  opacity: 0;
200
+  }
201
+}
202
+</style>