Browse Source

no message

seamwang 2 years ago
parent
commit
4683771994

+ 179 - 176
src/common/css/common.css

@@ -1,176 +1,179 @@
1
-.u-f {
2
-	display: flex;
3
-}
4
-
5
-.u-f-a {
6
-	display: flex;
7
-	align-items: center;
8
-}
9
-
10
-.u-f-ajc {
11
-	display: flex;
12
-	align-items: center;
13
-	justify-content: center;
14
-}
15
-
16
-.u-f-ajs {
17
-	display: flex;
18
-	align-items: center;
19
-	justify-content: space-between;
20
-}
21
-
22
-.u-f-adc {
23
-	display: flex;
24
-	align-items: center;
25
-	flex-direction: column;
26
-}
27
-
28
-.blue-card-border {
29
-	border: 4px solid #E2F0FC;
30
-	border-radius: 16upx;
31
-	background: #FFFFFF;
32
-}
33
-
34
-.maxWidth {
35
-	width: 100%
36
-}
37
-@font-face {
38
-  font-family: 'iconfont';  /* Project id 3376246 */
39
-  src: url('//at.alicdn.com/t/font_3376246_nwm42j68ejq.eot?t=1651739388185'); /* IE9 */
40
-  src: url('//at.alicdn.com/t/font_3376246_nwm42j68ejq.eot?t=1651739388185#iefix') format('embedded-opentype'), /* IE6-IE8 */
41
-       url('//at.alicdn.com/t/font_3376246_nwm42j68ejq.woff2?t=1651739388185') format('woff2'),
42
-       url('//at.alicdn.com/t/font_3376246_nwm42j68ejq.woff?t=1651739388185') format('woff'),
43
-       url('//at.alicdn.com/t/font_3376246_nwm42j68ejq.ttf?t=1651739388185') format('truetype'),
44
-       url('//at.alicdn.com/t/font_3376246_nwm42j68ejq.svg?t=1651739388185#iconfont') format('svg');
45
-}
46
-.iconfont {
47
-	font-family: "iconfont" !important;
48
-	font-size: 13px;
49
-	font-style: normal;
50
-	-webkit-font-smoothing: antialiased;
51
-	-webkit-text-stroke-width: 0.2px;
52
-	-moz-osx-font-smoothing: grayscale;
53
-}
54
-
55
-.lh-30 {
56
-	line-height: 30px;
57
-}
58
-
59
-.lh-40 {
60
-	line-height: 40px;
61
-}
62
-
63
-.border-bottom {
64
-	border-bottom: 1px solid #ccc;
65
-}
66
-
67
-.item-border {
68
-	border: 1px dashed #333;
69
-}
70
-
71
-image {
72
-	object-fit: contain;
73
-}
74
-
75
-.padding-bottom-200 {
76
-	padding-bottom: 200rpx;
77
-}
78
-
79
-.cu-form-input {
80
-	flex: 1;
81
-	height: 100%;
82
-	line-height: 100%;
83
-}
84
-
85
-.top-bg-view {
86
-	width: 100%;
87
-	height: 375rpx;
88
-}
89
-
90
-.box-shadow {
91
-	box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, 0.08);
92
-}
93
-
94
-.content-bg {
95
-	position: absolute;
96
-	width: 100%;
97
-	height: 100%;
98
-	z-index: -1;
99
-}
100
-
101
-.scale-radio {
102
-	transform: scale(0.6);
103
-}
104
-.text-ellipsis{
105
-  text-overflow: ellipsis;
106
-  overflow: hidden;
107
-  white-space: nowrap;
108
-}
109
-.page{
110
-	width:100%;
111
-	background: #ededed;
112
-}
113
-input{
114
-	padding:0 30rpx;
115
-}
116
-.text-student{
117
-	color:#5fd0e4;
118
-}
119
-.bg-student{
120
-	background-color:#5fd0e4;
121
-}
122
-.text-sort{
123
-	color: #FF6600;
124
-}
125
-.point{
126
-	background: #62d5e4;
127
-	margin-top: -5px;
128
-	width: 8px;
129
-	height: 5px;
130
-	border-radius: 999em;
131
-}
132
-.header{
133
-	position: fixed;
134
-	z-index:999;
135
-  left: 0;
136
-  right: 0;
137
-  top: 0;
138
-	padding:20rpx;
139
-	background-color:#fff;
140
-}
141
-.header-title{
142
-	display:flex;
143
-	justify-content: space-between;
144
-	align-items: center;
145
-	margin-bottom:10px;
146
-	font-size:22px;
147
-	color:#000;
148
-	font-weight:bold;
149
-}
150
-.header-title-main{
151
-	text-align: center;
152
-	display: flex;
153
-	flex-direction: column;
154
-	align-items: center;
155
-	justify-content: center;
156
-}
157
-.cu-btn.disabled{
158
-	opacity: .7;
159
-}
160
-.avatar{
161
-	width:75px;
162
-	height:75px;
163
-	border-radius:50%;
164
-}
165
-.avatar.lg{
166
-	width:128rpx;
167
-	height:128rpx;
168
-}
169
-.avatar.md{
170
-	width:96rpx;
171
-	height:96rpx;
172
-}
173
-.avatar.left{
174
-	position:absolute;
175
-	left:30rpx;
176
-}
1
+.u-f {
2
+	display: flex;
3
+}
4
+
5
+.u-f-a {
6
+	display: flex;
7
+	align-items: center;
8
+}
9
+
10
+.u-f-ajc {
11
+	display: flex;
12
+	align-items: center;
13
+	justify-content: center;
14
+}
15
+
16
+.u-f-ajs {
17
+	display: flex;
18
+	align-items: center;
19
+	justify-content: space-between;
20
+}
21
+
22
+.u-f-adc {
23
+	display: flex;
24
+	align-items: center;
25
+	flex-direction: column;
26
+}
27
+
28
+.blue-card-border {
29
+	border: 4px solid #E2F0FC;
30
+	border-radius: 16upx;
31
+	background: #FFFFFF;
32
+}
33
+
34
+.maxWidth {
35
+	width: 100%
36
+}
37
+@font-face {
38
+  font-family: 'iconfont';  /* Project id 3376246 */
39
+  src: url('//at.alicdn.com/t/font_3376246_nwm42j68ejq.eot?t=1651739388185'); /* IE9 */
40
+  src: url('//at.alicdn.com/t/font_3376246_nwm42j68ejq.eot?t=1651739388185#iefix') format('embedded-opentype'), /* IE6-IE8 */
41
+       url('//at.alicdn.com/t/font_3376246_nwm42j68ejq.woff2?t=1651739388185') format('woff2'),
42
+       url('//at.alicdn.com/t/font_3376246_nwm42j68ejq.woff?t=1651739388185') format('woff'),
43
+       url('//at.alicdn.com/t/font_3376246_nwm42j68ejq.ttf?t=1651739388185') format('truetype'),
44
+       url('//at.alicdn.com/t/font_3376246_nwm42j68ejq.svg?t=1651739388185#iconfont') format('svg');
45
+}
46
+.iconfont {
47
+	font-family: "iconfont" !important;
48
+	font-size: 13px;
49
+	font-style: normal;
50
+	-webkit-font-smoothing: antialiased;
51
+	-webkit-text-stroke-width: 0.2px;
52
+	-moz-osx-font-smoothing: grayscale;
53
+}
54
+
55
+.lh-30 {
56
+	line-height: 30px;
57
+}
58
+
59
+.lh-40 {
60
+	line-height: 40px;
61
+}
62
+
63
+.border-bottom {
64
+	border-bottom: 1px solid #ccc;
65
+}
66
+
67
+.item-border {
68
+	border: 1px dashed #333;
69
+}
70
+
71
+image {
72
+	object-fit: contain;
73
+}
74
+
75
+.padding-bottom-200 {
76
+	padding-bottom: 200rpx;
77
+}
78
+
79
+.cu-form-input {
80
+	flex: 1;
81
+	height: 100%;
82
+	line-height: 100%;
83
+}
84
+
85
+.top-bg-view {
86
+	width: 100%;
87
+	height: 375rpx;
88
+}
89
+
90
+.box-shadow {
91
+	box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, 0.08);
92
+}
93
+
94
+.content-bg {
95
+	position: absolute;
96
+	width: 100%;
97
+	height: 100%;
98
+	z-index: -1;
99
+}
100
+
101
+.scale-radio {
102
+	transform: scale(0.6);
103
+}
104
+.text-ellipsis{
105
+  text-overflow: ellipsis;
106
+  overflow: hidden;
107
+  white-space: nowrap;
108
+}
109
+.page{
110
+	width:100%;
111
+	background: #ededed;
112
+}
113
+input{
114
+	padding:0 30rpx;
115
+}
116
+.text-student{
117
+	color:#5fd0e4;
118
+}
119
+.bg-student{
120
+	background-color:#5fd0e4;
121
+}
122
+.bg-normal{
123
+	background-color: #4DB8E4;
124
+}
125
+.text-sort{
126
+	color: #FF6600;
127
+}
128
+.point{
129
+	background: #62d5e4;
130
+	margin-top: -5px;
131
+	width: 8px;
132
+	height: 5px;
133
+	border-radius: 999em;
134
+}
135
+.header{
136
+	position: fixed;
137
+	z-index:999;
138
+  left: 0;
139
+  right: 0;
140
+  top: 0;
141
+	padding:20rpx;
142
+	background-color:#fff;
143
+}
144
+.header-title{
145
+	display:flex;
146
+	justify-content: space-between;
147
+	align-items: center;
148
+	margin-bottom:10px;
149
+	font-size:22px;
150
+	color:#000;
151
+	font-weight:bold;
152
+}
153
+.header-title-main{
154
+	text-align: center;
155
+	display: flex;
156
+	flex-direction: column;
157
+	align-items: center;
158
+	justify-content: center;
159
+}
160
+.cu-btn.disabled{
161
+	opacity: .7;
162
+}
163
+.avatar{
164
+	width:75px;
165
+	height:75px;
166
+	border-radius:50%;
167
+}
168
+.avatar.lg{
169
+	width:128rpx;
170
+	height:128rpx;
171
+}
172
+.avatar.md{
173
+	width:96rpx;
174
+	height:96rpx;
175
+}
176
+.avatar.left{
177
+	position:absolute;
178
+	left:30rpx;
179
+}

+ 201 - 190
src/common/utils/index.js

@@ -1,190 +1,201 @@
1
-/**
2
- * This is just a simple version of deep copy
3
- * Has a lot of edge cases bug
4
- * If you want to use a perfect deep copy, use lodash's _.cloneDeep
5
- * @param {Object} source 源数据
6
- * @returns {Object} targetObj 复制后的数据
7
- */
8
-export function deepClone (source) {
9
-  if (!source && typeof source !== 'object') {
10
-    throw new Error('error arguments', 'deepClone')
11
-  }
12
-  const targetObj = source.constructor === Array ? [] : {}
13
-  Object.keys(source).forEach(keys => {
14
-    if (source[keys] && typeof source[keys] === 'object') {
15
-      targetObj[keys] = deepClone(source[keys])
16
-    } else {
17
-      targetObj[keys] = source[keys]
18
-    }
19
-  })
20
-  return targetObj
21
-}
22
-
23
-/**
24
- * 判断val是否是空对象
25
- * @param {*} val js变量
26
- * @returns {Boolean} 返回boolean值
27
- */
28
-export const isEmpty = function (val) {
29
-  // null or undefined
30
-  if (val === null) return true
31
-
32
-  if (typeof val === 'boolean') return false
33
-
34
-  if (typeof val === 'number') return !val
35
-
36
-  if (val instanceof Error) return val.message === ''
37
-
38
-  switch (Object.prototype.toString.call(val)) {
39
-    // String or Array
40
-    case '[object String]':
41
-    case '[object Array]':
42
-      return !val.length
43
-
44
-    // Map or Set or File
45
-    case '[object File]':
46
-    case '[object Map]':
47
-    case '[object Set]': {
48
-      return !val.size
49
-    }
50
-    // Plain Object
51
-    case '[object Object]': {
52
-      return !Object.keys(val).length
53
-    }
54
-  }
55
-
56
-  return false
57
-}
58
-
59
-/**
60
- * 验证手机号
61
- * @param {*} phone 手机号
62
- * @returns {Boolean} boolean值
63
- */
64
-export function validatePhone (phone) {
65
-  const reg = /^[1]([3-9])[0-9]{9}$/
66
-  return reg.test(phone)
67
-}
68
-
69
-/**
70
- * 获取URL中的参数
71
- * @param {String} url
72
- * @returns {String} 要获取的参数name
73
- */
74
-export function getQueryString (url, name) {
75
-  const reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i')
76
-  const r = url.substr(1).match(reg)
77
-  if (r !== null) {
78
-    return r[2]
79
-  }
80
-  return null
81
-}
82
-
83
-/**
84
- * 根据对象的某个key排序
85
- * @param {*} 对象
86
- */
87
-export function sortObject (property) {
88
-  return function (obj1, obj2) {
89
-    const value1 = obj1[property]
90
-    const value2 = obj2[property]
91
-    return value1 - value2
92
-  }
93
-}
94
-/**
95
- * 根据对象的某个key倒序排序
96
- * @param {*} 对象
97
- */
98
-export function sortDescObject (property) {
99
-  return function (obj1, obj2) {
100
-    const value1 = obj1[property]
101
-    const value2 = obj2[property]
102
-    return value2 - value1
103
-  }
104
-}
105
-
106
-/**
107
- * 判断商标是否是无效的
108
- * @param {String} 商标状态
109
- * @returns {Boolean} boolean值
110
- */
111
-export function tmIsIneffective (status) {
112
-  return status === '商标无效'
113
-}
114
-
115
-/**
116
- *将json对象转化为url要拼接的字符串
117
- */
118
-export function encodeParam (link, params) {
119
-  let url = ''
120
-  if (params && Object.keys(params).length > 0) {
121
-    for (const k in params) {
122
-      const value = params[k] !== undefined ? params[k] : ''
123
-      url += '&' + k + '=' + encodeURIComponent(value)
124
-    }
125
-    url = url ? url.substring(1) : ''
126
-    if (params) {
127
-      link += (link.indexOf('?') < 0 && params ? '?' : '&') + url
128
-    }
129
-  }
130
-  return link
131
-}
132
-/**
133
- * 计算时间
134
- * @param {*} time
135
- * @param {*} cFormat
136
- */
137
-export function parseTime(time, cFormat) {
138
-  if (arguments.length === 0) {
139
-    return null
140
-  }
141
-  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
142
-  let date
143
-  if (typeof time === 'object') {
144
-    date = time
145
-  } else {
146
-    if (('' + time).length === 10) time = parseInt(time) * 1000
147
-    date = new Date(time)
148
-  }
149
-  const formatObj = {
150
-    y: date.getFullYear(),
151
-    m: date.getMonth() + 1,
152
-    d: date.getDate(),
153
-    h: date.getHours(),
154
-    i: date.getMinutes(),
155
-    s: date.getSeconds(),
156
-    a: date.getDay()
157
-  }
158
-  const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
159
-    let value = formatObj[key]
160
-    if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
161
-    if (result.length > 0 && value < 10) {
162
-      value = '0' + value
163
-    }
164
-    return value || 0
165
-  })
166
-  return timeStr
167
-}
168
-// 获取任意时间
169
-export function getDate(date, AddDayCount = 0) {
170
-  if (!date) {
171
-    date = new Date()
172
-  }
173
-  if (typeof date !== 'object') {
174
-    date = date.replace(/-/g, '/')
175
-  }
176
-  const dd = new Date(date)
177
-
178
-  dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
179
-
180
-  const y = dd.getFullYear()
181
-  const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
182
-  const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
183
-  return {
184
-    fullDate: y + '-' + m + '-' + d,
185
-    year: y,
186
-    month: m,
187
-    date: d,
188
-    day: dd.getDay()
189
-  }
190
-}
1
+/**
2
+ * This is just a simple version of deep copy
3
+ * Has a lot of edge cases bug
4
+ * If you want to use a perfect deep copy, use lodash's _.cloneDeep
5
+ * @param {Object} source 源数据
6
+ * @returns {Object} targetObj 复制后的数据
7
+ */
8
+export function deepClone (source) {
9
+  if (!source && typeof source !== 'object') {
10
+    throw new Error('error arguments', 'deepClone')
11
+  }
12
+  const targetObj = source.constructor === Array ? [] : {}
13
+  Object.keys(source).forEach(keys => {
14
+    if (source[keys] && typeof source[keys] === 'object') {
15
+      targetObj[keys] = deepClone(source[keys])
16
+    } else {
17
+      targetObj[keys] = source[keys]
18
+    }
19
+  })
20
+  return targetObj
21
+}
22
+
23
+/**
24
+ * 判断val是否是空对象
25
+ * @param {*} val js变量
26
+ * @returns {Boolean} 返回boolean值
27
+ */
28
+export const isEmpty = function (val) {
29
+  // null or undefined
30
+  if (val === null) return true
31
+
32
+  if (typeof val === 'boolean') return false
33
+
34
+  if (typeof val === 'number') return !val
35
+
36
+  if (val instanceof Error) return val.message === ''
37
+
38
+  switch (Object.prototype.toString.call(val)) {
39
+    // String or Array
40
+    case '[object String]':
41
+    case '[object Array]':
42
+      return !val.length
43
+
44
+    // Map or Set or File
45
+    case '[object File]':
46
+    case '[object Map]':
47
+    case '[object Set]': {
48
+      return !val.size
49
+    }
50
+    // Plain Object
51
+    case '[object Object]': {
52
+      return !Object.keys(val).length
53
+    }
54
+  }
55
+
56
+  return false
57
+}
58
+
59
+/**
60
+ * 验证手机号
61
+ * @param {*} phone 手机号
62
+ * @returns {Boolean} boolean值
63
+ */
64
+export function validatePhone (phone) {
65
+  const reg = /^[1]([3-9])[0-9]{9}$/
66
+  return reg.test(phone)
67
+}
68
+
69
+/**
70
+ * 获取URL中的参数
71
+ * @param {String} url
72
+ * @returns {String} 要获取的参数name
73
+ */
74
+export function getQueryString (url, name) {
75
+  const reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i')
76
+  const r = url.substr(1).match(reg)
77
+  if (r !== null) {
78
+    return r[2]
79
+  }
80
+  return null
81
+}
82
+
83
+/**
84
+ * 根据对象的某个key排序
85
+ * @param {*} 对象
86
+ */
87
+export function sortObject (property) {
88
+  return function (obj1, obj2) {
89
+    const value1 = obj1[property]
90
+    const value2 = obj2[property]
91
+    return value1 - value2
92
+  }
93
+}
94
+/**
95
+ * 根据对象的某个key倒序排序
96
+ * @param {*} 对象
97
+ */
98
+export function sortDescObject (property) {
99
+  return function (obj1, obj2) {
100
+    const value1 = obj1[property]
101
+    const value2 = obj2[property]
102
+    return value2 - value1
103
+  }
104
+}
105
+
106
+/**
107
+ * 判断商标是否是无效的
108
+ * @param {String} 商标状态
109
+ * @returns {Boolean} boolean值
110
+ */
111
+export function tmIsIneffective (status) {
112
+  return status === '商标无效'
113
+}
114
+
115
+/**
116
+ *将json对象转化为url要拼接的字符串
117
+ */
118
+export function encodeParam (link, params) {
119
+  let url = ''
120
+  if (params && Object.keys(params).length > 0) {
121
+    for (const k in params) {
122
+      const value = params[k] !== undefined ? params[k] : ''
123
+      url += '&' + k + '=' + encodeURIComponent(value)
124
+    }
125
+    url = url ? url.substring(1) : ''
126
+    if (params) {
127
+      link += (link.indexOf('?') < 0 && params ? '?' : '&') + url
128
+    }
129
+  }
130
+  return link
131
+}
132
+/**
133
+ * 计算时间
134
+ * @param {*} time
135
+ * @param {*} cFormat
136
+ */
137
+export function parseTime(time, cFormat) {
138
+  if (arguments.length === 0) {
139
+    return null
140
+  }
141
+  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
142
+  let date
143
+  if (typeof time === 'object') {
144
+    date = time
145
+  } else {
146
+    if (('' + time).length === 10) time = parseInt(time) * 1000
147
+    date = new Date(time)
148
+  }
149
+  const formatObj = {
150
+    y: date.getFullYear(),
151
+    m: date.getMonth() + 1,
152
+    d: date.getDate(),
153
+    h: date.getHours(),
154
+    i: date.getMinutes(),
155
+    s: date.getSeconds(),
156
+    a: date.getDay()
157
+  }
158
+  const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
159
+    let value = formatObj[key]
160
+    if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
161
+    if (result.length > 0 && value < 10) {
162
+      value = '0' + value
163
+    }
164
+    return value || 0
165
+  })
166
+  return timeStr
167
+}
168
+// 获取任意时间
169
+export function getDate(date, AddDayCount = 0) {
170
+  if (!date) {
171
+    date = new Date()
172
+  }
173
+  if (typeof date !== 'object') {
174
+    date = date.replace(/-/g, '/')
175
+  }
176
+  const dd = new Date(date)
177
+
178
+  dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
179
+
180
+  const y = dd.getFullYear()
181
+  const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
182
+  const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
183
+  return {
184
+    fullDate: y + '-' + m + '-' + d,
185
+    fullMonth: y + '-' + m,
186
+    year: y,
187
+    month: m,
188
+    date: d,
189
+    day: dd.getDay()
190
+  }
191
+}
192
+// 检测文件类型
193
+export function checkTypes(source, type) {
194
+  const types = {
195
+    video: ['m3u8', 'ts', 'mp4', '3gp', 'asf', 'wmv', 'avi', 'mkv', 'rmvb', 'flv', 'mp3', 'ogg', 'amr'],
196
+    imgs: ['png', 'jpg', 'jpeg']
197
+  }
198
+  if (!types[type]) return false// 不存在检测类型
199
+  const arr = source.split('.')
200
+  return types[type].includes(arr[arr.length - 1])
201
+}

+ 233 - 0
src/components/calendar.vue

@@ -0,0 +1,233 @@
1
+<template>
2
+<view class='wrap'>
3
+  <view class='header-cal'>
4
+    <view  v-for="(item,index) in date" :key="index">{{item}}<view></view>
5
+    </view>
6
+  </view>
7
+  <view class='date-box'>
8
+    <view v-for="(item,index) in dateArr"  :key="index"   @tap="calendarTap(item,index)">
9
+      <view class="date-head1" :class="[todayIndex===index ? 'operationInProgress' : (showBusiness?item.styleClass:''), {'showOverdue':item.showOverdue}]">
10
+        <view >{{item.dateNum}}</view>
11
+      </view>
12
+    </view>
13
+
14
+  </view>
15
+</view>
16
+
17
+</template>
18
+
19
+<script>
20
+export default {
21
+  props: {
22
+    year: {
23
+      type: Number,
24
+      value: 0
25
+    },
26
+    month: {
27
+      type: Number,
28
+      value: 0
29
+    },
30
+    showBusiness: { // 是否显示业务标记
31
+      type: Boolean,
32
+      default: false
33
+    }
34
+  },
35
+  data() {
36
+    return {
37
+      date: ['日', '一', '二', '三', '四', '五', '六'],
38
+      dateArr: [],
39
+      todayIndex: -1// 操作索引,默认指向当天
40
+    }
41
+  },
42
+  onLoad(options) {
43
+  },
44
+  methods: {
45
+    calendarTap(item, index) {
46
+      this.todayIndex = index
47
+      this.$emit('changeDate', item.date)
48
+    },
49
+    selCalendar(year, month) {
50
+      this.dateInit(year, month - 1)
51
+    },
52
+    setAttendance(attendance) { // 设置日历考勤
53
+      const start = this.dateArr.findIndex(item => item.dateNum)
54
+      attendance.map((item, index) => {
55
+        if (item !== 'stateless') {
56
+          const pos = start + index
57
+          const dateObj = this.dateArr[pos]
58
+          this.$set(dateObj, 'styleClass', item)
59
+          this.$set(this.dateArr, pos, dateObj)
60
+        }
61
+      })
62
+    },
63
+    dateInit(setYear, setMonth) {
64
+      // 1.获取当前时间
65
+      var date = new Date()
66
+      var currentYear = date.getFullYear() // 获取完整的年份(4位)
67
+      var currentMonth = date.getMonth() + 1 // 获取当前月份(0-11,0代表1月)
68
+      var currentDate = date.getDate() // 获取当前日(1-31)
69
+      var currentTime = '' + currentYear + (currentMonth > 9 ? currentMonth : '0' + currentMonth) + (currentDate > 9 ? currentDate : '0' + currentDate)
70
+      // 全部时间的月份都是按0~11基准,显示月份才+1
71
+      const dateArr = [] // 需要遍历的日历数组数据
72
+      let arrLen = 0 // dateArr的数组长度
73
+      const now = setYear ? new Date(setYear, setMonth) : new Date()
74
+      const year = setYear || now.getFullYear()
75
+      let nextYear = 0
76
+      const month = setMonth || now.getMonth() // 没有+1方便后面计算当月总天数
77
+      const nextMonth = (month + 1) > 11 ? 1 : (month + 1)
78
+      const startWeek = new Date(year + '/' + (month + 1) + '/' + 1).getDay() // 目标月1号对应的星期
79
+      let dayNums = new Date(year, nextMonth, 0).getDate() // 获取目标月有多少天
80
+      let obj = {}
81
+      let num = 0
82
+      let showOverdue = 0
83
+
84
+      if (month + 1 > 11) {
85
+        nextYear = year + 1
86
+        dayNums = new Date(nextYear, nextMonth, 0).getDate()
87
+      }
88
+      arrLen = startWeek + dayNums // 渲染日期格子数量包括空格子
89
+      for (let i = 0; i < arrLen; i++) {
90
+        if (i >= startWeek) {
91
+          num = i - startWeek + 1
92
+          // 计算 -- 需要渲染的过期时间
93
+          const renderingTime = '' + year + (month + 1 > 9 ? month + 1 : '0' + (month + 1)) + (num > 9 ? num : '0' + num)
94
+          if (Number(currentTime) > Number(renderingTime)) {
95
+            showOverdue = 1 // 过期
96
+          } else {
97
+            showOverdue = 0 // 有效
98
+          }
99
+          obj = {
100
+            year: year,
101
+            month: month + 1,
102
+            dateNum: num,
103
+            date: renderingTime,
104
+            showOverdue: showOverdue
105
+          }
106
+        } else {
107
+          obj = {}
108
+        }
109
+        dateArr[i] = obj
110
+      }
111
+      this.dateArr = dateArr
112
+    }
113
+  }
114
+}
115
+</script>
116
+
117
+<style lang="scss" scoped>
118
+.date-show{
119
+  position: relative;
120
+  width: 250rpx;
121
+  font-family: PingFang-SC-Regular;
122
+  font-size: 40rpx;
123
+  color: #282828;
124
+  text-align: center;
125
+  margin: 59rpx auto 10rpx;
126
+}
127
+.lt-arrow,.rt-arrow{
128
+  position: absolute;
129
+  top: 1rpx;
130
+  width: 60rpx;
131
+  height: 60rpx;
132
+}
133
+.lt-arrow image,.rt-arrow image{
134
+  width: 14rpx;
135
+  height: 26rpx;
136
+}
137
+.lt-arrow{
138
+  left: -110rpx;
139
+  transform: rotate(180deg);
140
+}
141
+.rt-arrow{
142
+  right: -100rpx;
143
+}
144
+.header-cal{
145
+  font-size: 0;
146
+  /* padding: 0 24rpx;  */
147
+}
148
+.header-cal>view{
149
+  display: inline-block;
150
+  width: 14.285%;
151
+  color: #5fd0e4;
152
+  font-size: 30rpx;
153
+  text-align: center;
154
+  /* border-bottom: 1px solid #D0D0D0;  */
155
+  padding: 39rpx 0;
156
+}
157
+.weekMark{
158
+  position: relative;
159
+}
160
+.weekMark view{
161
+  position: absolute;
162
+  bottom: 0;
163
+  left: 0;
164
+  width: 100%;
165
+  border-bottom: 1px solid #22A7F6;
166
+}
167
+.date-box{
168
+  font-size: 0;
169
+  padding: 10rpx 0;
170
+}
171
+.date-box>view{
172
+  position: relative;
173
+  display: inline-block;
174
+  width: 14.285%;
175
+  color: #020202;
176
+  font-size: 40rpx;
177
+  text-align: center;
178
+  vertical-align: middle;
179
+  margin: 15rpx 0;
180
+}
181
+.date-head1{
182
+  height: 60rpx;
183
+  line-height: 60rpx;
184
+  font-size: 26rpx;
185
+  border-radius: 12rpx;
186
+}
187
+.date-head2{
188
+  background: #20BA96;
189
+  color: #fff;
190
+  height: 60rpx;
191
+  line-height: 60rpx;
192
+  font-size: 26rpx;
193
+  border-radius: 12rpx;
194
+}
195
+.date-weight{
196
+  font-size: 22rpx;
197
+  padding: 15rpx 0;
198
+}
199
+.nowDay .date-weight{
200
+  color: #22A7F6;
201
+}
202
+/* 过期样式*/
203
+.showOverdue{
204
+  color: #5fd0e4;
205
+}
206
+/* 正在操作样式*/
207
+.operationInProgress{
208
+  background: #20BA96;
209
+  color: #fff;
210
+}
211
+/* 正常样式*/
212
+.normal{
213
+  background:  #4DB8E4;
214
+  color: #fff;
215
+}
216
+/* 异常样式*/
217
+.abnormal{
218
+  background:  #FF7361;
219
+  color: #fff;
220
+}
221
+.leave{
222
+	background:#3390F5;
223
+	color: #fff;
224
+}
225
+.late{
226
+	background:#fbbd08;
227
+	color: #fff;
228
+}
229
+.absenteeism{
230
+	background:#e54d42;
231
+	color: #fff;
232
+}
233
+</style>

+ 2 - 2
src/pages/class/shoppingCart.vue

@@ -85,7 +85,7 @@ export default {
85 85
     get_list() {
86 86
       _shopList().then(res => {
87 87
         this.list = res.data
88
-        const carts = this.list.map(item => Number(item.class_attend_id))
88
+        const carts = this.list.map(item => item.class_attend_id)
89 89
         this.$store.dispatch('setCarts', carts)// 刷新购物车
90 90
       })
91 91
     },
@@ -108,7 +108,7 @@ export default {
108 108
     pay(item) {
109 109
       const order = JSON.stringify([item])
110 110
       let carts = deepClone(this.carts)
111
-      const index = carts.indexOf(Number(item.class_attend_id))
111
+      const index = carts.indexOf(item.class_attend_id)
112 112
       carts = carts.splice(index, 1)
113 113
       if (!this.phone) {
114 114
         return this.globalNavigateTo('bindPhone')

+ 227 - 228
src/pages/mine/parents.vue

@@ -1,228 +1,227 @@
1
-<template>
2
-	<view class="page">
3
-		<cu-custom :isBack="true" title="授权接送">
4
-		</cu-custom>
5
-		<scroll-view>
6
-			<view class="cu-card case no-card">
7
-				<view class="cu-item shadow">
8
-					<view class="image">
9
-      			<image src="/static/imgs/mine/img.png" mode="widthFix"></image>
10
-						 <view class="image-tag">应趣教育 课后百科</view>
11
-					</view>
12
-				</view>
13
-			</view>
14
-			<view class="cu-card">
15
-					<view class="cu-item shadhow">
16
-						  <view class="students-title flex justify-between align-center">
17
-								 <view class="text-lg">监护人列表</view>
18
-								 <view class="text-xs text-grey">
19
-									 <text class="cuIcon-roundaddfill text-cyan margin-left-xl add-icon"
20
-									 @tap="showModal" data-target="ChooseModal"
21
-									 ></text>
22
-								 </view>
23
-							</view>
24
-							<view class="cu-list menu-avatar">
25
-									<view class="cu-item" v-for="parent in parents" :key="parent.id">
26
-										<image mode="scaleToFill" :src="parent.avatar||defaultAvatar" class="avatar md left"></image>
27
-										<view class="content">
28
-											<view>{{parent.username}}</view>
29
-											<view class="text-gray">{{parent.mobile}}</view>
30
-										</view>
31
-									</view>
32
-							</view>
33
-					 </view>
34
-			</view>
35
-		</scroll-view>
36
-		<!-- 添加授权人 -->
37
-    <view class="cu-modal" :class="modalName=='ChooseModal'?'show':''" @tap="hideModal">
38
-      <view class="cu-dialog bg-student" @tap.stop=''>
39
-        <view class="cu-bar justify-around">
40
-          <view class="content modal-title">添加授权人</view>
41
-        </view>
42
-        <view class="padding-xl text-left modal-body">
43
-				  <view>
44
-            <input type="text"  v-model.trim="params.username" placeholder="请输入授权人姓名" class="student-input text-black text-lg">
45
-          </view>
46
-					<view class="margin-top">
47
-            <input type="text"  v-model.trim="params.mobile"
48
-						@input="changePhone"
49
-						 placeholder="请输入授权人手机号" class="student-input text-black text-lg">
50
-          </view>
51
-					<view class="margin-top auth-item">
52
-            <input type="text"  v-model.trim="params.captcha" placeholder="请输入验证码" class="student-input text-black text-lg">
53
-						 <text class="auth-code text-cyan" :class="{'text-gray':disableSendMsgBtn}" :disabled="disableSendMsgBtn"
54
-            @tap="getCode">{{sendMsg}}</text>
55
-          </view>
56
-					<view class="margin-top">
57
-						 <button class="student-input text-student text-center" @tap="save">确认授权</button>
58
-					</view>
59
-        </view>
60
-        <view class="cu-bar modal-footer">
61
-          <view class="action"></view>
62
-        </view>
63
-      </view>
64
-    </view>
65
-	</view>
66
-</template>
67
-
68
-<script>
69
-import { _getPickup, _getCode, _addPickup } from '@/api/auth'
70
-import validate from '@/common/utils/ys-validate'
71
-export default {
72
-  data() {
73
-    return {
74
-      modalName: null,
75
-      parents: [],
76
-      params: {
77
-        username: '',
78
-        mobile: '',
79
-        captcha: ''
80
-      },
81
-      rules: [
82
-        { name: 'username', required: true, type: 'required', errmsg: '请输入授权人姓名' },
83
-        { name: 'mobile', required: true, type: 'phone', errmsg: '请输入正确手机号' },
84
-        { name: 'captcha', required: true, type: 'number', errmsg: '请输入正确的验证码' }
85
-      ],
86
-      sendTime: 60,
87
-      disableSendMsgBtn: true,
88
-      sendMsg: '获取验证码',
89
-      defaultAvatar: 'http://parent.kehoubaike.com/static/img/7f4e775d2e04234d1e1994b13146f6b.e5c47f3.png'
90
-    }
91
-  },
92
-  onLoad(options) {
93
-    this.get_list()
94
-  },
95
-  methods: {
96
-    showModal(e) {
97
-      this.modalName = e.currentTarget.dataset.target
98
-    },
99
-    hideModal(e) {
100
-      this.modalName = null
101
-    },
102
-    save() {
103
-      const validRes = validate.validate(this.params, this.rules)
104
-      if (!validRes.isOk) {
105
-        uni.showToast({
106
-          icon: 'none',
107
-          title: validRes.errmsg
108
-        })
109
-        return false
110
-      }
111
-      _addPickup(this.params).then(res => {
112
-        this.hideModal()
113
-        this.get_list()
114
-      })
115
-    },
116
-    changePhone(e) {
117
-      if (/^[1]([3-9])[0-9]{9}$/.test(e.detail.value)) {
118
-        this.disableSendMsgBtn = false
119
-      } else {
120
-        this.disableSendMsgBtn = true
121
-      }
122
-    },
123
-    getCode() {
124
-      console.log(111)
125
-      if (!this.disableSendMsgBtn) {
126
-        this.leftTime = this.sendTime
127
-        this.timing(this.leftTime)
128
-        _getCode({ phone: this.params.mobile }).then(res => {
129
-          uni.showToast({
130
-            title: '验证码发送成功! 请注意查收!',
131
-            duration: 3000
132
-          })
133
-        })
134
-      }
135
-    },
136
-    timing () {
137
-      this.disableSendMsgBtn = true
138
-      const temSendMsgText = this.sendMsg
139
-      this.sendMsg = this.leftTime + '秒后重试'
140
-      this.timeInterval = setInterval(() => {
141
-        this.leftTime--
142
-        this.sendMsg = this.leftTime + '秒后重试'
143
-        if (this.leftTime <= 0) {
144
-          this.sendMsg = temSendMsgText
145
-          clearInterval(this.timeInterval)
146
-          if (/^[1]([3-9])[0-9]{9}$/.test(this.form.phone)) {
147
-            this.disableSendMsgBtn = false
148
-          }
149
-        }
150
-      }, 1000)
151
-    },
152
-    get_list() {
153
-      _getPickup().then(res => {
154
-        this.parents = res.data.pickup_data
155
-      })
156
-    }
157
-  }
158
-}
159
-</script>
160
-
161
-<style lang="scss" scoped>
162
-.page{
163
-	height:100vh;
164
-}
165
-.image{
166
-	padding-bottom:20px;
167
-}
168
-.image-tag{
169
-	position:absolute;
170
-	top:10px;
171
-	left:10px;
172
-	font-size:24px;
173
-	font-weight:bold;
174
-	color: #6d4f26;
175
-}
176
-.students-title{
177
-	padding:30rpx;
178
-}
179
-.add-icon{
180
-	display:inline-block;
181
-	width:40px;
182
-	height:40px;
183
-	line-height:40px;
184
-	text-align:center;
185
-	font-size:22px;
186
-}
187
-.student-input{
188
-	height:40px;
189
-	line-height:40px;
190
-	border-radius:20px;
191
-	background-color:#fff;
192
-}
193
-.radius-student{
194
-	border-radius:20rpx;
195
-}
196
-.cu-inner{
197
-	margin:10rpx;
198
-	display:flex;
199
-	align-items:center;
200
-	width:100%;
201
-}
202
-.cu-inner.checked{
203
-    background: #5fd0e4;
204
-    color: #fff;
205
-    border-radius: 20rpx;
206
-}
207
-.cu-dialog{
208
-	width:90%;
209
-}
210
-.modal-title{
211
-    font-weight: bold;
212
-    color: #516029;
213
-    font-size: 20px;
214
-}
215
-.font-check{
216
-	font-size:22px;
217
-}
218
-.auth-item{
219
-	position:relative;
220
-}
221
-.auth-code{
222
-	position:absolute;
223
-	z-index:99;
224
-	top:10px;
225
-	right:20rpx;
226
-	font-size:14px;
227
-}
228
-</style>
1
+<template>
2
+	<view class="page">
3
+		<cu-custom :isBack="true" title="授权接送">
4
+		</cu-custom>
5
+		<scroll-view>
6
+			<view class="cu-card case no-card">
7
+				<view class="cu-item shadow">
8
+					<view class="image">
9
+      			<image src="/static/imgs/mine/img.png" mode="widthFix"></image>
10
+						 <view class="image-tag">应趣教育 课后百科</view>
11
+					</view>
12
+				</view>
13
+			</view>
14
+			<view class="cu-card">
15
+					<view class="cu-item shadhow">
16
+						  <view class="students-title flex justify-between align-center">
17
+								 <view class="text-lg">监护人列表</view>
18
+								 <view class="text-xs text-grey">
19
+									 <text class="cuIcon-roundaddfill text-cyan margin-left-xl add-icon"
20
+									 @tap="showModal" data-target="ChooseModal"
21
+									 ></text>
22
+								 </view>
23
+							</view>
24
+							<view class="cu-list menu-avatar">
25
+									<view class="cu-item" v-for="parent in parents" :key="parent.id">
26
+										<image mode="scaleToFill" :src="parent.avatar||defaultAvatar" class="avatar md left"></image>
27
+										<view class="content">
28
+											<view>{{parent.username}}</view>
29
+											<view class="text-gray">{{parent.mobile}}</view>
30
+										</view>
31
+									</view>
32
+							</view>
33
+					 </view>
34
+			</view>
35
+		</scroll-view>
36
+		<!-- 添加授权人 -->
37
+    <view class="cu-modal" :class="modalName=='ChooseModal'?'show':''" @tap="hideModal">
38
+      <view class="cu-dialog bg-student" @tap.stop=''>
39
+        <view class="cu-bar justify-around">
40
+          <view class="content modal-title">添加授权人</view>
41
+        </view>
42
+        <view class="padding-xl text-left modal-body">
43
+				  <view>
44
+            <input type="text"  v-model.trim="params.username" placeholder="请输入授权人姓名" class="student-input text-black text-lg">
45
+          </view>
46
+					<view class="margin-top">
47
+            <input type="text"  v-model.trim="params.mobile"
48
+						@input="changePhone"
49
+						 placeholder="请输入授权人手机号" class="student-input text-black text-lg">
50
+          </view>
51
+					<view class="margin-top auth-item">
52
+            <input type="text"  v-model.trim="params.captcha" placeholder="请输入验证码" class="student-input text-black text-lg">
53
+						 <text class="auth-code text-cyan" :class="{'text-gray':disableSendMsgBtn}" :disabled="disableSendMsgBtn"
54
+            @tap="getCode">{{sendMsg}}</text>
55
+          </view>
56
+					<view class="margin-top">
57
+						 <button class="student-input text-student text-center" @tap="save">确认授权</button>
58
+					</view>
59
+        </view>
60
+        <view class="cu-bar modal-footer">
61
+          <view class="action"></view>
62
+        </view>
63
+      </view>
64
+    </view>
65
+	</view>
66
+</template>
67
+
68
+<script>
69
+import { _getPickup, _getCode, _addPickup } from '@/api/auth'
70
+import validate from '@/common/utils/ys-validate'
71
+export default {
72
+  data() {
73
+    return {
74
+      modalName: null,
75
+      parents: [],
76
+      params: {
77
+        username: '',
78
+        mobile: '',
79
+        captcha: ''
80
+      },
81
+      rules: [
82
+        { name: 'username', required: true, type: 'required', errmsg: '请输入授权人姓名' },
83
+        { name: 'mobile', required: true, type: 'phone', errmsg: '请输入正确手机号' },
84
+        { name: 'captcha', required: true, type: 'number', errmsg: '请输入正确的验证码' }
85
+      ],
86
+      sendTime: 60,
87
+      disableSendMsgBtn: true,
88
+      sendMsg: '获取验证码',
89
+      defaultAvatar: 'http://parent.kehoubaike.com/static/img/7f4e775d2e04234d1e1994b13146f6b.e5c47f3.png'
90
+    }
91
+  },
92
+  onLoad(options) {
93
+    this.get_list()
94
+  },
95
+  methods: {
96
+    showModal(e) {
97
+      this.modalName = e.currentTarget.dataset.target
98
+    },
99
+    hideModal(e) {
100
+      this.modalName = null
101
+    },
102
+    save() {
103
+      const validRes = validate.validate(this.params, this.rules)
104
+      if (!validRes.isOk) {
105
+        uni.showToast({
106
+          icon: 'none',
107
+          title: validRes.errmsg
108
+        })
109
+        return false
110
+      }
111
+      _addPickup(this.params).then(res => {
112
+        this.hideModal()
113
+        this.get_list()
114
+      })
115
+    },
116
+    changePhone(e) {
117
+      if (/^[1]([3-9])[0-9]{9}$/.test(e.detail.value)) {
118
+        this.disableSendMsgBtn = false
119
+      } else {
120
+        this.disableSendMsgBtn = true
121
+      }
122
+    },
123
+    getCode() {
124
+      if (!this.disableSendMsgBtn) {
125
+        this.leftTime = this.sendTime
126
+        this.timing(this.leftTime)
127
+        _getCode({ phone: this.params.mobile }).then(res => {
128
+          uni.showToast({
129
+            title: '验证码发送成功! 请注意查收!',
130
+            duration: 3000
131
+          })
132
+        })
133
+      }
134
+    },
135
+    timing () {
136
+      this.disableSendMsgBtn = true
137
+      const temSendMsgText = this.sendMsg
138
+      this.sendMsg = this.leftTime + '秒后重试'
139
+      this.timeInterval = setInterval(() => {
140
+        this.leftTime--
141
+        this.sendMsg = this.leftTime + '秒后重试'
142
+        if (this.leftTime <= 0) {
143
+          this.sendMsg = temSendMsgText
144
+          clearInterval(this.timeInterval)
145
+          if (/^[1]([3-9])[0-9]{9}$/.test(this.form.phone)) {
146
+            this.disableSendMsgBtn = false
147
+          }
148
+        }
149
+      }, 1000)
150
+    },
151
+    get_list() {
152
+      _getPickup().then(res => {
153
+        this.parents = res.data.pickup_data
154
+      })
155
+    }
156
+  }
157
+}
158
+</script>
159
+
160
+<style lang="scss" scoped>
161
+.page{
162
+	height:100vh;
163
+}
164
+.image{
165
+	padding-bottom:20px;
166
+}
167
+.image-tag{
168
+	position:absolute;
169
+	top:10px;
170
+	left:10px;
171
+	font-size:24px;
172
+	font-weight:bold;
173
+	color: #6d4f26;
174
+}
175
+.students-title{
176
+	padding:30rpx;
177
+}
178
+.add-icon{
179
+	display:inline-block;
180
+	width:40px;
181
+	height:40px;
182
+	line-height:40px;
183
+	text-align:center;
184
+	font-size:22px;
185
+}
186
+.student-input{
187
+	height:40px;
188
+	line-height:40px;
189
+	border-radius:20px;
190
+	background-color:#fff;
191
+}
192
+.radius-student{
193
+	border-radius:20rpx;
194
+}
195
+.cu-inner{
196
+	margin:10rpx;
197
+	display:flex;
198
+	align-items:center;
199
+	width:100%;
200
+}
201
+.cu-inner.checked{
202
+    background: #5fd0e4;
203
+    color: #fff;
204
+    border-radius: 20rpx;
205
+}
206
+.cu-dialog{
207
+	width:90%;
208
+}
209
+.modal-title{
210
+    font-weight: bold;
211
+    color: #516029;
212
+    font-size: 20px;
213
+}
214
+.font-check{
215
+	font-size:22px;
216
+}
217
+.auth-item{
218
+	position:relative;
219
+}
220
+.auth-code{
221
+	position:absolute;
222
+	z-index:99;
223
+	top:10px;
224
+	right:20rpx;
225
+	font-size:14px;
226
+}
227
+</style>

+ 1 - 1
src/pages/myStudents/myStudents.vue

@@ -213,7 +213,7 @@ export default {
213 213
     },
214 214
     setCarts() { // 刷新购物车
215 215
       _shopList().then(res => {
216
-        const carts = res.data.map(item => Number(item.class_attend_id))
216
+        const carts = res.data.map(item => item.class_attend_id)
217 217
         this.$store.dispatch('setCarts', carts)
218 218
       })
219 219
     },

+ 68 - 64
src/pages/studentcenter/classVideo.vue

@@ -1,64 +1,68 @@
1
-<template>
2
-  <view class="page">
3
-		<cu-custom :isBack="true" title="课堂视频"></cu-custom>
4
-		<scroll-view scroll-y="true"
5
-			:style="[{height:'calc(100vh - '+ topHeader+'px)'}]">
6
-			<view class="content">
7
-				<view class="course-img">
8
-					<swiper class="swiper" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval" :duration="swiper.duration">
9
-						<swiper-item v-for="(item,index) in detail.course_data.image" :key="index">
10
-							<view class="swiper-item">
11
-								  <image :src="item" mode="widthFix"></image>
12
-							</view>
13
-						</swiper-item>
14
-					</swiper>
15
-				</view>
16
-				<view>
17
-					<view class="title flex align-center">
18
-						<text class="iconfont" style="font-size:24px;">&#xe76d;</text>课堂视频
19
-					</view>
20
-					<view class="list">
21
-						<view class="cu-card case" v-for="(video,index) in detail.moments_data.data" :key="index">
22
-							<view class="cu-item shadow">
23
-								<view class="image">
24
-									<video :src="video" style="width:100%;"></video>
25
-								</view>
26
-							</view>
27
-						</view>
28
-					</view>
29
-				</view>
30
-			</view>
31
-		</scroll-view>
32
-	</view>
33
-</template>
34
-
35
-<script>
36
-export default {
37
-  data() {
38
-    return {
39
-      topHeader: this.globalCustomBarHeight,
40
-      detail: {},
41
-      swiper: {
42
-        indicatorDots: true,
43
-        autoplay: true,
44
-        interval: 2000,
45
-        duration: 500
46
-      }
47
-    }
48
-  },
49
-  onLoad() {
50
-    this.init()
51
-  },
52
-  methods: {
53
-    init() {
54
-      this.detail = JSON.parse(uni.getStorageSync('daily_class'))
55
-    }
56
-  }
57
-}
58
-</script>
59
-
60
-<style lang="scss" scoped>
61
-.page{
62
-	height:100vh;
63
-}
64
-</style>
1
+<template>
2
+  <view class="page">
3
+		<cu-custom :isBack="true" title="课堂视频"></cu-custom>
4
+		<scroll-view scroll-y="true"
5
+			:style="[{height:'calc(100vh - '+ topHeader+'px)'}]">
6
+			<view class="content">
7
+				<view class="course-img">
8
+					<swiper class="swiper" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval" :duration="swiper.duration">
9
+						<swiper-item v-for="(item,index) in detail.course_data.image" :key="index">
10
+							<view class="swiper-item">
11
+								  <image :src="item" mode="widthFix"></image>
12
+							</view>
13
+						</swiper-item>
14
+					</swiper>
15
+				</view>
16
+				<view>
17
+					<view class="title flex align-center">
18
+						<text class="iconfont" style="font-size:24px;">&#xe76d;</text>课堂视频
19
+					</view>
20
+					<view class="list" v-if='detail.moments_data'>
21
+						<view class="cu-card case" v-for="(video,index) in detail.moments_data.data" :key="index">
22
+							<view class="cu-item shadow">
23
+								<view class="image">
24
+									<image :src="video.images" v-if="checkTypes(video.images,'imgs')" style="width:100%;"></image>
25
+									<video :src="video.images" v-if="checkTypes(video.images,'video')" style="width:100%;"></video>
26
+									<view class="padding-xs">{{video.content}}</view>
27
+								</view>
28
+							</view>
29
+						</view>
30
+					</view>
31
+				</view>
32
+			</view>
33
+		</scroll-view>
34
+	</view>
35
+</template>
36
+
37
+<script>
38
+import { checkTypes } from '@/common/utils/index'
39
+export default {
40
+  data() {
41
+    return {
42
+      topHeader: this.globalCustomBarHeight,
43
+      detail: {},
44
+      swiper: {
45
+        indicatorDots: true,
46
+        autoplay: true,
47
+        interval: 2000,
48
+        duration: 500
49
+      }
50
+    }
51
+  },
52
+  onLoad() {
53
+    this.init()
54
+  },
55
+  methods: {
56
+    checkTypes,
57
+    init() {
58
+      this.detail = JSON.parse(uni.getStorageSync('daily_class'))
59
+    }
60
+  }
61
+}
62
+</script>
63
+
64
+<style lang="scss" scoped>
65
+.page{
66
+	height:100vh;
67
+}
68
+</style>

+ 6 - 4
src/pages/studentcenter/evaluate.vue

@@ -13,7 +13,7 @@
13 13
 			</view>
14 14
 		</view>
15 15
 		<view class="comment bg-white margin-top padding-lr padding-tb-lg">
16
-			<view>请评价(已对班主任匿名,请放心评价)</view>
16
+			<view>请评价</view>
17 17
 			<view class="flex text-center margin-top" style="padding-left:80rpx;">
18 18
 					<view class="flex-sub">
19 19
 						<img src="/static/imgs/class/satisfaction.png" mode="widthFix" style="width:70px;">
@@ -74,9 +74,11 @@ export default {
74 74
   methods: {
75 75
     init() {
76 76
       _commentDetail({ plan_id: this.params.plan_id }).then(res => {
77
-        this.teacher = res.teacher_data
78
-        this.params.teacher_id = this.teacher ? this.teacher.teacher_id : 'undefined'
79
-        this.satisfaction = res.satisfaction_data
77
+        this.teacher = res.data.teacher_data
78
+        this.params.teacher_id = this.teacher.teacher_id
79
+        this.satisfaction = res.data.satisfaction_data
80
+        this.params.statisfaction = this.satisfaction.satisfaction
81
+        this.params.agency_statisfaction = this.satisfaction.agency_satisfaction
80 82
       })
81 83
     },
82 84
     evaluate(type, value) { // 评价

+ 73 - 27
src/pages/studentcenter/index.vue

@@ -20,9 +20,40 @@
20 20
 		<view v-if="type==='schedule'">
21 21
 			<scroll-view scroll-y="true"
22 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" />
23
+				<view class="calendar padding-tb solid-bottom bg-white">
24
+					<view class="calendar-header flex justify-between padding-lr-sm">
25
+							<view>
26
+									<picker mode="date" :value="info.chooseDate" :fields="info.fields"
27
+											@change="bindDateChange"
28
+											:start="info.start" :end="info.end">
29
+												<view class="picker text-student text-xl">
30
+													{{info.chooseDate}}
31
+													<text class="cuIcon-right lg"></text>
32
+												</view>
33
+										</picker>
34
+							</view>
35
+							<view>
36
+								共{{present.attendance_data.length}}天
37
+							</view>
38
+					</view>
39
+					<view class="calendar-main">
40
+						<calendar :year="year" :month="month"  :showBusiness="true" @changeDate="chooseDay" ref="calendar"></calendar>
41
+					</view>
42
+					<view class="calendar-marks flex justify-end padding-lr-sm">
43
+							<view class="margin-left-sm">
44
+								<view class="cu-tag bg-blue margin-right-sm"></view><text class="text-sm">请假</text>
45
+							</view>
46
+							<view class="margin-left-sm">
47
+								<view class="cu-tag bg-yellow margin-right-sm"></view><text class="text-sm">迟到</text>
48
+							</view>
49
+							<view class="margin-left-sm">
50
+								<view class="cu-tag bg-normal margin-right-sm"></view><text class="text-sm">正常</text>
51
+							</view>
52
+							<view class="margin-left-sm">
53
+								<view class="cu-tag bg-red margin-right-sm"></view><text class="text-sm">旷课</text>
54
+							</view>
55
+					</view>
56
+				</view>
26 57
 				<view class="cu-card margin-top-xs padding-xs">
27 58
 					<view class="cu-item day-info">
28 59
 						<view class="day-title flex justify-between solid-bottom padding text-lg">
@@ -113,13 +144,13 @@
113 144
 
114 145
 <script>
115 146
 import NP from 'number-precision'
116
-import { uniCalendar } from '@dcloudio/uni-ui'
147
+import calendar from '@/components/calendar.vue'
117 148
 import { _nowCourse, _courseHistory, _attendance, _dateCourse } from '@/api/course'
118 149
 import { getDate } from '@/common/utils'
119 150
 import swiperTab from '@/components/swiper-tab.vue'
120 151
 export default {
121 152
   components: {
122
-    uniCalendar, swiperTab
153
+    swiperTab, calendar
123 154
   },
124 155
   data () {
125 156
     return {
@@ -130,14 +161,19 @@ export default {
130 161
       page_num: 1,
131 162
       noMore: false, // 加载判断
132 163
       list: [],
133
-      classList: [], // 日程表
164
+      classList: [], // 日程表当天
165
+      courses: [], // 日程表全部
134 166
       info: { // 日历数据
167
+        chooseDate: '', // 选中日期
135 168
         year: '',
136 169
         month: '',
137 170
         day: '',
138
-        selected: []
171
+        fields: 'month',
172
+        start: '',
173
+        end: ''
139 174
       },
140 175
       present: {
176
+        attendance_data: [],
141 177
         absenteeism_num: 0,
142 178
         actual_section_num: 5,
143 179
         be_section_num: 5,
@@ -147,16 +183,16 @@ export default {
147 183
       }, // 实际出席情况
148 184
       attendance: { // 出席统计数据
149 185
         leave_num: {
150
-          title: '请假', times: 2, color: '#9bde78'
151
-        },
152
-        normal_num: {
153
-          title: '正常', times: 3, color: '#e0be60'
186
+          title: '请假', times: 2, color: '#3390F5'
154 187
         },
155 188
         late_num: {
156
-          title: '迟到', times: 1, color: '#61d4e2'
189
+          title: '迟到', times: 1, color: '#fbbd08'
190
+        },
191
+        normal_num: {
192
+          title: '正常', times: 3, color: '#4DB8E4'
157 193
         },
158 194
         absenteeism_num: {
159
-          title: '旷课', times: 0, color: '#d697eb'
195
+          title: '旷课', times: 0, color: '#e54d42'
160 196
         }
161 197
       }
162 198
     }
@@ -166,6 +202,9 @@ export default {
166 202
     this.info.year = this.info.year || today.year
167 203
     this.info.month = this.info.month || today.month
168 204
     this.info.day = this.info.day || today.date
205
+    this.info.chooseDate = this.info.chooseDate || today.fullMonth
206
+    this.info.start = (this.info.year - 1) + '-' + '01-01'
207
+    this.info.end = this.info.year + '-' + (Number(this.info.month) + 1) + '-' + this.info.day
169 208
     this.init()
170 209
   },
171 210
   methods: {
@@ -177,11 +216,13 @@ export default {
177 216
       }
178 217
     },
179 218
     getSehedule() {
219
+      this.setCalendar()
180 220
       this.get_attend().then(res => {
181 221
         this.present = res.data
182
-        this.fix_attend(res.data)
222
+        this.fix_attend(res.data)// 出席统计
223
+        this.setAttendance(res.data.attendance_data)// 日历显示出席日期
183 224
         this.drawChart()
184
-        this.get_dateCourse()
225
+        this.get_dateCourse()// 获取日期课程列表
185 226
       })
186 227
     },
187 228
     classOperation(id) { // 上课
@@ -205,6 +246,9 @@ export default {
205 246
         this.get_history()
206 247
       }
207 248
     },
249
+    chooseDay(day) {
250
+      this.classList = this.courses.filter(item => item.date.replace(/-/g, '') === day)// 匹配当天数据
251
+    },
208 252
     get_course() {
209 253
       _nowCourse({ page_num: this.page_num }).then(res => {
210 254
         if (this.page_num > 1) {
@@ -243,20 +287,21 @@ export default {
243 287
       this.page_num = 1
244 288
       this.get_list()
245 289
     },
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
290
+    bindDateChange(e) {
291
+      const value = e.detail.value
292
+      const [year, month] = value.split('-')
293
+      this.info.year = year
294
+      this.info.month = month
295
+      this.info.chooseDate = value
258 296
       this.getSehedule()
259 297
     },
298
+    setCalendar() {
299
+      this.$refs.calendar.selCalendar(this.info.year, this.info.month)
300
+    },
301
+    setAttendance(attendance) { // 补充出席情况
302
+      if (!attendance) return
303
+      this.$refs.calendar.setAttendance(attendance)
304
+    },
260 305
     get_attend() { // 获取出席情况
261 306
       const date = this.info.year + '-' + this.info.month
262 307
       return new Promise((resolve, reject) => {
@@ -272,6 +317,7 @@ export default {
272 317
     get_dateCourse() { // 获取对应日期数据
273 318
       _dateCourse({ year: this.info.year, month: this.info.month }).then(res => {
274 319
         this.classList = res.data
320
+        this.courses = res.data
275 321
       })
276 322
     },
277 323
     draw (ele, key) {

+ 168 - 168
src/pages/studentcenter/operation.vue

@@ -1,168 +1,168 @@
1
-<template>
2
-	<view class="page">
3
-		<cu-custom :isBack="true" title="课堂操作"></cu-custom>
4
-		<scroll-view scroll-y="true"
5
-			:style="[{height:'calc(100vh - '+ topHeader+'px)'}]">
6
-			<view class="content">
7
-				<view class="course-img">
8
-					<swiper class="swiper" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval" :duration="swiper.duration">
9
-						<swiper-item v-for="(item,index) in detail.course_data.image" :key="index">
10
-							<view class="swiper-item">
11
-								  <image :src="item" mode="widthFix"></image>
12
-							</view>
13
-						</swiper-item>
14
-					</swiper>
15
-				</view>
16
-				<view class="detail bg-white padding">
17
-					<view class="detail-title">{{detail.course_data.attend_name}}</view>
18
-					<view class="detail-item">
19
-						<text class="cuIcon-title text-student"></text>
20
-						<text class="text-gray">周期</text>
21
-						<text class="text-black margin-left-xs">{{detail.course_data.start_at}}</text>
22
-					</view>
23
-					<view class="detail-item flex">
24
-						<text class="text-gray" style="width:40px;"></text>
25
-						<text class="text-black margin-left-xs">{{detail.course_data.end_at}}</text>
26
-					</view>
27
-					<view class="detail-item margin-top-xs">
28
-						<text class="cuIcon-title text-student"></text>
29
-						<text class="text-gray">年级</text>
30
-						<text class="text-black margin-left-xs">{{detail.course_data.grade}}</text>
31
-					</view>
32
-				</view>
33
-				<view class="teacher flex bg-white padding margin-tb-sm">
34
-					<image mode="scaleToFill" :src="teacher_avatar" class="avatar lg"></image>
35
-					<view class="flex-sub margin-left">
36
-						 <view class="teacher-title">{{detail.teacher.username||''}}老师授课</view>
37
-						 <view class="teacher-item">所属机构:{{detail.teacher.agency_name||''}}</view>
38
-						<view class="teacher-exp flex">
39
-							 <view class="exp-item">{{detail.teacher.honor||''}}</view>
40
-							 <view class="exp-item">{{detail.teacher.introduce||''}}</view>
41
-						 </view>
42
-					</view>
43
-				</view>
44
-				<view class="cu-timeline">
45
-					<view class="cu-time">详情</view>
46
-					<view class="cu-item">
47
-						<view class="cu-content time-item flex justify-between">
48
-							<view class="time-left text-black flex-sub">评价</view>
49
-							<view class="time-right text-student" @tap="check('studentEvaluate')">
50
-								查看
51
-							</view>
52
-						</view>
53
-					</view>
54
-					<view class="cu-item">
55
-						<view class="cu-content time-item flex justify-between">
56
-							<view class="time-left text-black flex-sub">上课时间
57
-								<view>{{detail.course_data.start_at}}</view>
58
-							</view>
59
-						</view>
60
-					</view>
61
-					<view class="cu-item">
62
-						<view class="cu-content time-item flex justify-between">
63
-							<view class="time-left text-black flex-sub">课堂签到
64
-								<view>{{detail.call_status.title}}</view>
65
-							</view>
66
-						</view>
67
-					</view>
68
-					<view class="cu-item">
69
-						<view class="cu-content time-item flex justify-between">
70
-							<view class="time-left text-black flex-sub">课堂视频</view>
71
-							<view class="time-right text-student" @tap="check('studentVideo')">
72
-								查看
73
-							</view>
74
-						</view>
75
-					</view>
76
-					<view class="cu-item">
77
-						<view class="cu-content time-item flex justify-between">
78
-							<view class="time-left text-black flex-sub">课堂作品</view>
79
-							<view class="time-right text-student" @tap="check('studentWorks')">
80
-								查看
81
-							</view>
82
-						</view>
83
-					</view>
84
-					<view class="cu-item">
85
-						<view class="cu-content time-item flex justify-between">
86
-							<view class="time-left text-black flex-sub">下课时间
87
-								<view>{{detail.course_data.end_at}}</view>
88
-							</view>
89
-						</view>
90
-					</view>
91
-					<view class="cu-item">
92
-						<view class="cu-content time-item flex justify-between">
93
-							<view class="time-left text-black flex-sub">安全交接</view>
94
-							<view class="time-right text-student" @tap="check('studentSignin')">
95
-								查看
96
-							</view>
97
-						</view>
98
-					</view>
99
-				</view>
100
-			</view>
101
-		</scroll-view>
102
-	</view>
103
-</template>
104
-
105
-<script>
106
-import { _dailiClass } from '@/api/course'
107
-export default {
108
-  data() {
109
-    return {
110
-      topHeader: this.globalCustomBarHeight,
111
-      plan_id: 0,
112
-      detail: {},
113
-      swiper: {
114
-        indicatorDots: true,
115
-        autoplay: true,
116
-        interval: 2000,
117
-        duration: 500
118
-      },
119
-      teacher_avatar: '/static/imgs/class/logo0.png'
120
-    }
121
-  },
122
-  onLoad(options) {
123
-    const id = decodeURIComponent(options.id)
124
-    if (!id) uni.navigateBack()
125
-    this.plan_id = id
126
-    this.init()
127
-  },
128
-  methods: {
129
-    check(page) {
130
-      this.globalNavigateTo(page, { plan_id: this.plan_id })
131
-    },
132
-    init() {
133
-      _dailiClass({ plan_id: this.plan_id }).then(res => {
134
-        this.detail = res.data
135
-        uni.setStorage({
136
-          data: JSON.stringify(this.detail),
137
-          key: 'daily_class'
138
-        })
139
-      })
140
-    }
141
-  }
142
-}
143
-</script>
144
-
145
-<style lang="scss" scoped>
146
-@import '~@/common/css/mixin.scss';
147
-.page{
148
-	height:100vh;
149
-}
150
-.detail{
151
-	&-title{
152
-		@include title(10px,22px);
153
-	}
154
-}
155
-.teacher{
156
-	&-title{
157
-		@include title(4px,18px);
158
-	}
159
-}
160
-.time-item{
161
-	line-height:32px;
162
-	.time-left{
163
-	}
164
-	.time-right{
165
-		width:120rpx;
166
-	}
167
-}
168
-</style>
1
+<template>
2
+	<view class="page">
3
+		<cu-custom :isBack="true" title="课堂操作"></cu-custom>
4
+		<scroll-view scroll-y="true"
5
+			:style="[{height:'calc(100vh - '+ topHeader+'px)'}]">
6
+			<view class="content">
7
+				<view class="course-img">
8
+					<swiper class="swiper" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval" :duration="swiper.duration">
9
+						<swiper-item v-for="(item,index) in detail.course_data.image" :key="index">
10
+							<view class="swiper-item">
11
+								  <image :src="item" mode="widthFix"></image>
12
+							</view>
13
+						</swiper-item>
14
+					</swiper>
15
+				</view>
16
+				<view class="detail bg-white padding">
17
+					<view class="detail-title">{{detail.course_data.attend_name}}</view>
18
+					<view class="detail-item">
19
+						<text class="cuIcon-title text-student"></text>
20
+						<text class="text-gray">周期</text>
21
+						<text class="text-black margin-left-xs">{{detail.course_data.start_at}}</text>
22
+					</view>
23
+					<view class="detail-item flex">
24
+						<text class="text-gray" style="width:40px;"></text>
25
+						<text class="text-black margin-left-xs">{{detail.course_data.end_at}}</text>
26
+					</view>
27
+					<view class="detail-item margin-top-xs">
28
+						<text class="cuIcon-title text-student"></text>
29
+						<text class="text-gray">年级</text>
30
+						<text class="text-black margin-left-xs">{{detail.course_data.grade}}</text>
31
+					</view>
32
+				</view>
33
+				<view class="teacher flex bg-white padding margin-tb-sm">
34
+					<image mode="scaleToFill" :src="teacher_avatar" class="avatar lg"></image>
35
+					<view class="flex-sub margin-left">
36
+						 <view class="teacher-title">{{detail.teacher.username||''}}老师授课</view>
37
+						 <view class="teacher-item">所属机构:{{detail.teacher.agency_name||''}}</view>
38
+						<view class="teacher-exp flex">
39
+							 <view class="exp-item">{{detail.teacher.honor||''}}</view>
40
+							 <view class="exp-item">{{detail.teacher.introduce||''}}</view>
41
+						 </view>
42
+					</view>
43
+				</view>
44
+				<view class="cu-timeline">
45
+					<view class="cu-time">详情</view>
46
+					<view class="cu-item">
47
+						<view class="cu-content time-item flex justify-between">
48
+							<view class="time-left text-black flex-sub">评价</view>
49
+							<view class="time-right text-student" v-if="detail.teacher&&detail.teacher.username" @tap="check('studentEvaluate')">
50
+								查看
51
+							</view>
52
+						</view>
53
+					</view>
54
+					<view class="cu-item">
55
+						<view class="cu-content time-item flex justify-between">
56
+							<view class="time-left text-black flex-sub">上课时间
57
+								<view>{{detail.course_data.start_at}}</view>
58
+							</view>
59
+						</view>
60
+					</view>
61
+					<view class="cu-item">
62
+						<view class="cu-content time-item flex justify-between">
63
+							<view class="time-left text-black flex-sub">课堂签到
64
+								<view>{{detail.call_status.title}}</view>
65
+							</view>
66
+						</view>
67
+					</view>
68
+					<view class="cu-item">
69
+						<view class="cu-content time-item flex justify-between">
70
+							<view class="time-left text-black flex-sub">课堂视频</view>
71
+							<view class="time-right text-student" @tap="check('studentVideo')">
72
+								查看
73
+							</view>
74
+						</view>
75
+					</view>
76
+					<view class="cu-item">
77
+						<view class="cu-content time-item flex justify-between">
78
+							<view class="time-left text-black flex-sub">课堂作品</view>
79
+							<view class="time-right text-student" @tap="check('studentWorks')">
80
+								查看
81
+							</view>
82
+						</view>
83
+					</view>
84
+					<view class="cu-item">
85
+						<view class="cu-content time-item flex justify-between">
86
+							<view class="time-left text-black flex-sub">下课时间
87
+								<view>{{detail.course_data.end_at}}</view>
88
+							</view>
89
+						</view>
90
+					</view>
91
+					<view class="cu-item">
92
+						<view class="cu-content time-item flex justify-between">
93
+							<view class="time-left text-black flex-sub">安全交接</view>
94
+							<view class="time-right text-student" @tap="check('studentSignin')">
95
+								查看
96
+							</view>
97
+						</view>
98
+					</view>
99
+				</view>
100
+			</view>
101
+		</scroll-view>
102
+	</view>
103
+</template>
104
+
105
+<script>
106
+import { _dailiClass } from '@/api/course'
107
+export default {
108
+  data() {
109
+    return {
110
+      topHeader: this.globalCustomBarHeight,
111
+      plan_id: 0,
112
+      detail: {},
113
+      swiper: {
114
+        indicatorDots: true,
115
+        autoplay: true,
116
+        interval: 2000,
117
+        duration: 500
118
+      },
119
+      teacher_avatar: '/static/imgs/class/logo0.png'
120
+    }
121
+  },
122
+  onLoad(options) {
123
+    const id = decodeURIComponent(options.id)
124
+    if (!id) uni.navigateBack()
125
+    this.plan_id = id
126
+    this.init()
127
+  },
128
+  methods: {
129
+    check(page) {
130
+      this.globalNavigateTo(page, { plan_id: this.plan_id })
131
+    },
132
+    init() {
133
+      _dailiClass({ plan_id: this.plan_id }).then(res => {
134
+        this.detail = res.data
135
+        uni.setStorage({
136
+          data: JSON.stringify(this.detail),
137
+          key: 'daily_class'
138
+        })
139
+      })
140
+    }
141
+  }
142
+}
143
+</script>
144
+
145
+<style lang="scss" scoped>
146
+@import '~@/common/css/mixin.scss';
147
+.page{
148
+	height:100vh;
149
+}
150
+.detail{
151
+	&-title{
152
+		@include title(10px,22px);
153
+	}
154
+}
155
+.teacher{
156
+	&-title{
157
+		@include title(4px,18px);
158
+	}
159
+}
160
+.time-item{
161
+	line-height:32px;
162
+	.time-left{
163
+	}
164
+	.time-right{
165
+		width:120rpx;
166
+	}
167
+}
168
+</style>

+ 7 - 4
src/pages/studentcenter/signIn.vue

@@ -20,7 +20,7 @@
20 20
 				</view>
21 21
     	</view>
22 22
 		</view>
23
-		<view class="content">
23
+		<view class="content" v-if="info.status">
24 24
 			<view class="content_title">签到说明</view>
25 25
     	<view>接到学生后请“点击签到”按钮作为签到</view>
26 26
 			<view class="button" :style="checked?'background: #ddd':''"  hover-class="button_hover" @tap="signIn">
@@ -68,13 +68,15 @@ export default {
68 68
     init() {
69 69
       _getSignIn({ plan_id: this.plan_id }).then(res => {
70 70
         this.info = res.data.sign_data
71
-        this.checked = !this.info.status
71
+        this.checked = this.info.status === 1
72 72
       })
73 73
     },
74 74
     signIn() {
75 75
       if (this.checked) return false
76 76
       _toSignIn({ clock_in_id: this.info.clock_in_id }).then(res => {
77
-        this.checked = true
77
+        if (res.code === 1) {
78
+          this.checked = true
79
+        }
78 80
       })
79 81
     }
80 82
   }
@@ -83,6 +85,7 @@ export default {
83 85
 
84 86
 <style lang="scss" scoped>
85 87
 .header{
88
+	position:static;
86 89
   border-radius: 0 0 10px 10px;
87 90
   padding: .8rem;
88 91
   .icon_title{
@@ -110,7 +113,7 @@ export default {
110 113
   }
111 114
 }
112 115
 .content{
113
-  margin-top: .8rem;
116
+  margin-top: .2rem;
114 117
   background: #fff;
115 118
   color: #888;
116 119
   padding: 2rem;

+ 67 - 62
src/pages/studentcenter/works.vue

@@ -1,62 +1,67 @@
1
-<template>
2
-  <view class="page">
3
-		<cu-custom :isBack="true" title="课堂作品"></cu-custom>
4
-		<scroll-view scroll-y="true"
5
-			:style="[{height:'calc(100vh - '+ topHeader+'px)'}]">
6
-			<view class="content">
7
-				<view class="course-img">
8
-					<swiper class="swiper" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval" :duration="swiper.duration">
9
-						<swiper-item v-for="(item,index) in detail.course_data.image" :key="index">
10
-							<view class="swiper-item">
11
-								  <image :src="item" mode="widthFix"></image>
12
-							</view>
13
-						</swiper-item>
14
-					</swiper>
15
-				</view>
16
-				<view>
17
-					<view class="title">课堂作品</view>
18
-					<view class="list">
19
-						<view class="cu-card case" v-for="(item,index) in detail.student_comment_data" :key="index">
20
-							<view class="cu-item shadow">
21
-								<view class="image">
22
-									<image :src="item.images" style="width:100%;"></image>
23
-								</view>
24
-							</view>
25
-						</view>
26
-					</view>
27
-				</view>
28
-			</view>
29
-		</scroll-view>
30
-	</view>
31
-</template>
32
-
33
-<script>
34
-export default {
35
-  data() {
36
-    return {
37
-      topHeader: this.globalCustomBarHeight,
38
-      detail: {},
39
-      swiper: {
40
-        indicatorDots: true,
41
-        autoplay: true,
42
-        interval: 2000,
43
-        duration: 500
44
-      }
45
-    }
46
-  },
47
-  onLoad() {
48
-    this.init()
49
-  },
50
-  methods: {
51
-    init() {
52
-      this.detail = JSON.parse(uni.getStorageSync('daily_class'))
53
-    }
54
-  }
55
-}
56
-</script>
57
-
58
-<style lang="scss" scoped>
59
-.page{
60
-	height:100vh;
61
-}
62
-</style>
1
+<template>
2
+  <view class="page">
3
+		<cu-custom :isBack="true" title="课堂作品"></cu-custom>
4
+		<scroll-view scroll-y="true"
5
+			:style="[{height:'calc(100vh - '+ topHeader+'px)'}]">
6
+			<view class="content">
7
+				<view class="course-img">
8
+					<swiper class="swiper" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval" :duration="swiper.duration">
9
+						<swiper-item v-for="(item,index) in detail.course_data.image" :key="index">
10
+							<view class="swiper-item">
11
+								  <image :src="item" mode="widthFix"></image>
12
+							</view>
13
+						</swiper-item>
14
+					</swiper>
15
+				</view>
16
+				<view>
17
+					<view class="title margin-top-sm">课堂作品</view>
18
+					<view class="list">
19
+						<view class="cu-card case" v-for="(item,index) in detail.student_comment_data.data" :key="index">
20
+							<view class="cu-item shadow">
21
+								<view class="image">
22
+									<view v-for="(img,i) in item.images" :key="i">
23
+										 <image :src="img" v-if="checkTypes(img,'imgs')" mode="aspectFit" style="width:100%;"></image>
24
+									   <video :src="img" v-if="checkTypes(img,'video')"  style="width:100%;"></video>
25
+									</view>
26
+								</view>
27
+							</view>
28
+						</view>
29
+					</view>
30
+				</view>
31
+			</view>
32
+		</scroll-view>
33
+	</view>
34
+</template>
35
+
36
+<script>
37
+import { checkTypes } from '@/common/utils/index'
38
+export default {
39
+  data() {
40
+    return {
41
+      topHeader: this.globalCustomBarHeight,
42
+      detail: {},
43
+      swiper: {
44
+        indicatorDots: true,
45
+        autoplay: true,
46
+        interval: 2000,
47
+        duration: 500
48
+      }
49
+    }
50
+  },
51
+  onLoad() {
52
+    this.init()
53
+  },
54
+  methods: {
55
+    checkTypes,
56
+    init() {
57
+      this.detail = JSON.parse(uni.getStorageSync('daily_class'))
58
+    }
59
+  }
60
+}
61
+</script>
62
+
63
+<style lang="scss" scoped>
64
+.page{
65
+	height:100vh;
66
+}
67
+</style>

+ 8 - 6
src/store/user.js

@@ -1,6 +1,6 @@
1 1
 export default {
2 2
   state: {
3
-    user: {},
3
+    user: null,
4 4
     token: '',
5 5
     session: '',
6 6
     kid: 0,
@@ -9,7 +9,8 @@ export default {
9 9
   },
10 10
   getters: {
11 11
     user(state) {
12
-      return state.user.nickName ? state.user : JSON.parse(uni.getStorageSync('user'))
12
+      const user = uni.getStorageSync('user')
13
+      return state.user || user ? JSON.parse(user) : {}
13 14
     },
14 15
     kid(state) {
15 16
       return state.kid || uni.getStorageSync('kid')
@@ -24,12 +25,13 @@ export default {
24 25
       return state.session || uni.getStorageSync('session')
25 26
     },
26 27
     carts(state) {
27
-      return state.carts || JSON.parse(uni.getStorageSync('carts'))
28
+      const carts = uni.getStorageSync('carts')
29
+      return state.carts || carts ? JSON.parse(carts) : []
28 30
     }
29 31
   },
30 32
   mutations: {
31 33
     CLEAR(state) {
32
-      state.user = {}
34
+      state.user = null
33 35
       state.token = ''
34 36
       state.session = ''
35 37
       state.phone = ''
@@ -37,7 +39,7 @@ export default {
37 39
       state.carts = null
38 40
       uni.clearStorageSync()
39 41
     },
40
-    SET_USER(state, user = {}) {
42
+    SET_USER(state, user) {
41 43
       state.user = user
42 44
       uni.setStorage({
43 45
         key: 'user',
@@ -72,7 +74,7 @@ export default {
72 74
         data: session
73 75
       })
74 76
     },
75
-    SET_CARTS(state, carts = []) {
77
+    SET_CARTS(state, carts) {
76 78
       state.carts = carts
77 79
       uni.setStorage({
78 80
         key: 'carts',