Browse Source

no message

seamwang 1 year ago
parent
commit
4cd8f092ef
6 changed files with 164 additions and 17956 deletions
  1. 31 17893
      package-lock.json
  2. 1 0
      package.json
  3. 6 2
      src/api/course.js
  4. 8 22
      src/components/calendar.vue
  5. 1 1
      src/pages/class/detail.vue
  6. 117 38
      src/pages/class/gift.vue

File diff suppressed because it is too large
+ 31 - 17893
package-lock.json


+ 1 - 0
package.json

@@ -31,6 +31,7 @@
31
     "@dcloudio/uni-cli-i18n": "^2.0.1-34720220422002",
31
     "@dcloudio/uni-cli-i18n": "^2.0.1-34720220422002",
32
     "@dcloudio/uni-ui": "^1.4.14",
32
     "@dcloudio/uni-ui": "^1.4.14",
33
     "number-precision": "^1.4.0",
33
     "number-precision": "^1.4.0",
34
+    "regenerator-runtime": "^0.13.11",
34
     "vue": "^2.6.10",
35
     "vue": "^2.6.10",
35
     "vue-class-component": "^6.3.2",
36
     "vue-class-component": "^6.3.2",
36
     "vue-count-to": "^1.0.13",
37
     "vue-count-to": "^1.0.13",

+ 6 - 2
src/api/course.js

@@ -9,8 +9,8 @@ export function _intelligentDates () {
9
 	return fetch('/parents/Intelligent/getLigentDate')
9
 	return fetch('/parents/Intelligent/getLigentDate')
10
 }
10
 }
11
 //智能报课获取兴趣
11
 //智能报课获取兴趣
12
-export function _intelligentInterests () {
13
-	return fetch('/parents/Intelligent/getLigentCategory')
12
+export function _intelligentInterests (params) {
13
+	return fetch('/parents/Intelligent/getLigentCategory', params)
14
 }
14
 }
15
 //智能报课关键词检索
15
 //智能报课关键词检索
16
 export function _intelligentGetKeys (params) {
16
 export function _intelligentGetKeys (params) {
@@ -136,3 +136,7 @@ export function _getClasses (params) {
136
 export function _fixStudent (params) {
136
 export function _fixStudent (params) {
137
 	return fetch('/parents/student/update', params)
137
 	return fetch('/parents/student/update', params)
138
 }
138
 }
139
+//检索冲突
140
+export function _checkConflict (params) {
141
+	return fetch('/parents/Intelligent/conflictcheck', params)
142
+}

+ 8 - 22
src/components/calendar.vue

@@ -7,7 +7,7 @@
7
       <view v-for="(item, index) in dateArr" :key="index" @tap="calendarTap(item, index)">
7
       <view v-for="(item, index) in dateArr" :key="index" @tap="calendarTap(item, index)">
8
         <view
8
         <view
9
           class="date-head1"
9
           class="date-head1"
10
-          :class="[todayIndex === index ? 'operationInProgress' : showBusiness ? item.styleClass : '', { showOverdue: item.showOverdue, 'date-class': item.dateClass }]"
10
+          :class="[todayIndex === index ? 'operationInProgress' : '', showBusiness ? item.styleClass : '', { showOverdue: item.showOverdue, 'date-class': item.dateClass }]"
11
         >
11
         >
12
           <view>{{ item.dateNum }}</view>
12
           <view>{{ item.dateNum }}</view>
13
         </view>
13
         </view>
@@ -100,6 +100,8 @@ export default {
100
           const renderingTime = '' + year + (month + 1 > 9 ? month + 1 : '0' + (month + 1)) + (num > 9 ? num : '0' + num)
100
           const renderingTime = '' + year + (month + 1 > 9 ? month + 1 : '0' + (month + 1)) + (num > 9 ? num : '0' + num)
101
           if (Number(currentTime) > Number(renderingTime)) {
101
           if (Number(currentTime) > Number(renderingTime)) {
102
             showOverdue = 1 // 过期
102
             showOverdue = 1 // 过期
103
+          } else if (Number(currentTime) == Number(renderingTime)) {
104
+            this.todayIndex = i
103
           } else {
105
           } else {
104
             showOverdue = 0 // 有效
106
             showOverdue = 0 // 有效
105
           }
107
           }
@@ -152,7 +154,6 @@ export default {
152
 }
154
 }
153
 .header-cal {
155
 .header-cal {
154
   font-size: 0;
156
   font-size: 0;
155
-  /* padding: 0 24rpx;  */
156
 }
157
 }
157
 .header-cal > view {
158
 .header-cal > view {
158
   display: inline-block;
159
   display: inline-block;
@@ -160,7 +161,6 @@ export default {
160
   color: #5fd0e4;
161
   color: #5fd0e4;
161
   font-size: 30rpx;
162
   font-size: 30rpx;
162
   text-align: center;
163
   text-align: center;
163
-  /* border-bottom: 1px solid #D0D0D0;  */
164
   padding: 39rpx 0;
164
   padding: 39rpx 0;
165
 }
165
 }
166
 .weekMark {
166
 .weekMark {
@@ -213,36 +213,26 @@ export default {
213
 .nowDay .date-weight {
213
 .nowDay .date-weight {
214
   color: #22a7f6;
214
   color: #22a7f6;
215
 }
215
 }
216
-/* 过期样式*/
217
-.showOverdue {
218
-  color: #5fd0e4;
219
-}
220
 /* 正在操作样式*/
216
 /* 正在操作样式*/
221
 .operationInProgress {
217
 .operationInProgress {
222
-  // background: #20ba96;
223
-  // color: #fff;
224
   color: #20ba96;
218
   color: #20ba96;
225
 }
219
 }
226
 /* 正常样式*/
220
 /* 正常样式*/
227
 .normal {
221
 .normal {
228
-  // background: #4db8e4;
229
-  // color: #fff;
230
   &:after {
222
   &:after {
231
     content: '';
223
     content: '';
232
     position: absolute;
224
     position: absolute;
233
     bottom: 0;
225
     bottom: 0;
234
     right: 0;
226
     right: 0;
235
-    width: 0;
236
-    height: 0;
237
-    border-color: #39b54a transparent;
238
-    border-width: 0 0 12px 12px;
239
-    border-style: solid;
227
+    width: 6px;
228
+    height: 10px;
229
+    border-bottom: 2px solid #39b54a;
230
+    border-right: 2px solid #39b54a;
231
+    transform: rotate(45deg);
240
   }
232
   }
241
 }
233
 }
242
 /* 异常样式*/
234
 /* 异常样式*/
243
 .abnormal {
235
 .abnormal {
244
-  // background: #ff7361;
245
-  // color: #fff;
246
   &:after {
236
   &:after {
247
     content: '';
237
     content: '';
248
     position: absolute;
238
     position: absolute;
@@ -256,8 +246,6 @@ export default {
256
   }
246
   }
257
 }
247
 }
258
 .leave {
248
 .leave {
259
-  // background: #3390f5;
260
-  // color: #fff;
261
   &:after {
249
   &:after {
262
     content: '';
250
     content: '';
263
     position: absolute;
251
     position: absolute;
@@ -271,8 +259,6 @@ export default {
271
   }
259
   }
272
 }
260
 }
273
 .late {
261
 .late {
274
-  // background: #fbbd08;
275
-  // color: #fff;
276
   &:after {
262
   &:after {
277
     content: '';
263
     content: '';
278
     position: absolute;
264
     position: absolute;

+ 1 - 1
src/pages/class/detail.vue

@@ -72,7 +72,7 @@
72
         </view>
72
         </view>
73
       </view>
73
       </view>
74
       <!-- 道具选择 -->
74
       <!-- 道具选择 -->
75
-      <view class="shop margin-top-sm shadow" v-if="detail.prop && detail.prop.length > 0">
75
+      <view class="shop margin-top-sm shadow" v-if="detail.prop && detail.prop.length > 0 && !detail.prop[0].required">
76
         <view class="shop-title">请选择课程所需要的道具</view>
76
         <view class="shop-title">请选择课程所需要的道具</view>
77
         <radio-group @change="radioChange" class="margin-top-xs">
77
         <radio-group @change="radioChange" class="margin-top-xs">
78
           <label v-for="radio in radios" :key="radio.value" class="tool-choose margin-right-sm">
78
           <label v-for="radio in radios" :key="radio.value" class="tool-choose margin-right-sm">

+ 117 - 38
src/pages/class/gift.vue

@@ -34,7 +34,7 @@
34
               </view>
34
               </view>
35
               <view class="margin-top-sm">
35
               <view class="margin-top-sm">
36
                 <view v-for="(h, i) in params.hobbyOther" :key="i" class="hobby"
36
                 <view v-for="(h, i) in params.hobbyOther" :key="i" class="hobby"
37
-                  >{{ h }}
37
+                  >{{ i + 1 }}.{{ h }}
38
                   <text class="cuIcon-close del-hobby text-red" @tap="delHobby(h)"></text>
38
                   <text class="cuIcon-close del-hobby text-red" @tap="delHobby(h)"></text>
39
                 </view>
39
                 </view>
40
               </view>
40
               </view>
@@ -95,9 +95,9 @@
95
                               >
95
                               >
96
                               <view>
96
                               <view>
97
                                 <checkbox
97
                                 <checkbox
98
-                                  :disabled="course.status == 0"
99
                                   :value="course.class_attend_id"
98
                                   :value="course.class_attend_id"
100
-                                  :checked="checked.includes(course.class_attend_id)"
99
+                                  :disabled="course.status == 0"
100
+                                  :checked="checked[i].includes(course.class_attend_id)"
101
                                   class="round cyan"
101
                                   class="round cyan"
102
                                   style="transform: scale(0.7);"
102
                                   style="transform: scale(0.7);"
103
                                 />
103
                                 />
@@ -111,11 +111,13 @@
111
                           <label v-for="prop in course.prop" :key="prop.id">
111
                           <label v-for="prop in course.prop" :key="prop.id">
112
                             <view>
112
                             <view>
113
                               <checkbox
113
                               <checkbox
114
+                                :checked="
115
+                                  checked_props[i][c] ? checked_props[i][c].class_attend_id === course.class_attend_id && checked_props[i][c].prop.includes(prop.id) : false
116
+                                "
114
                                 :disabled="course.status == 0"
117
                                 :disabled="course.status == 0"
115
                                 :value="prop.id"
118
                                 :value="prop.id"
116
                                 class="cyan"
119
                                 class="cyan"
117
                                 style="transform: scale(0.7);"
120
                                 style="transform: scale(0.7);"
118
-                                :checked="checked_props[i].class_attend_id === course.class_attend_id && checked_props[i].prop.includes(prop.id)"
119
                               />{{ prop.name }}<text>¥{{ prop.money }}</text>
121
                               />{{ prop.name }}<text>¥{{ prop.money }}</text>
120
                             </view>
122
                             </view>
121
                           </label>
123
                           </label>
@@ -135,7 +137,6 @@
135
                   </button>
137
                   </button>
136
                 </view>
138
                 </view>
137
                 <view class="static-order flex">
139
                 <view class="static-order flex">
138
-                  <shop-cart :class_attend_id="attend_id" @changeDisableBtn="changeDisableBtn"></shop-cart>
139
                   <button class="cu-btn round bg-student text-white margin-left-xs" @tap="addCart">报课</button>
140
                   <button class="cu-btn round bg-student text-white margin-left-xs" @tap="addCart">报课</button>
140
                 </view>
141
                 </view>
141
               </view>
142
               </view>
@@ -148,13 +149,10 @@
148
 </template>
149
 </template>
149
 
150
 
150
 <script>
151
 <script>
151
-import { _intelligentDates, _intelligentInterests, _intelligentCourses, _intelligentGetKeys, _joinShops } from '@/api/course'
152
-import shopCart from '@/components/shop-cart.vue'
152
+import { _intelligentDates, _intelligentInterests, _intelligentCourses, _intelligentGetKeys, _joinShops, _checkConflict } from '@/api/course'
153
 import { mapGetters } from 'vuex'
153
 import { mapGetters } from 'vuex'
154
+import socket from '@/common/webSocket'
154
 export default {
155
 export default {
155
-  components: {
156
-    shopCart
157
-  },
158
   data() {
156
   data() {
159
     return {
157
     return {
160
       topHeader: this.globalCustomBarHeight,
158
       topHeader: this.globalCustomBarHeight,
@@ -189,13 +187,15 @@ export default {
189
       colors: ['#0CAAF4', '#082FCC', '#FDC534', '#09E294'],
187
       colors: ['#0CAAF4', '#082FCC', '#FDC534', '#09E294'],
190
       checked: [], // 选中
188
       checked: [], // 选中
191
       checked_props: [], // 选中工具
189
       checked_props: [], // 选中工具
190
+      checkedIds: [], //已选中选项
191
+      conflictIds: [], //冲突选项
192
       attend_id: 0, // 添加成功课程
192
       attend_id: 0, // 添加成功课程
193
       disableBtn: false, // 避免多次重复点击
193
       disableBtn: false, // 避免多次重复点击
194
       action: 'stopmove'
194
       action: 'stopmove'
195
     }
195
     }
196
   },
196
   },
197
   computed: {
197
   computed: {
198
-    ...mapGetters(['kid'])
198
+    ...mapGetters(['kid', 'ifConnectOrder'])
199
   },
199
   },
200
   onLoad(options) {
200
   onLoad(options) {
201
     const id = decodeURIComponent(options.package_id)
201
     const id = decodeURIComponent(options.package_id)
@@ -209,19 +209,36 @@ export default {
209
   methods: {
209
   methods: {
210
     init() {
210
     init() {
211
       this.getDateConfig()
211
       this.getDateConfig()
212
-      this.getHobbyConfig()
212
+      socket.initSocket()
213
     },
213
     },
214
     getDateConfig() {
214
     getDateConfig() {
215
       _intelligentDates().then(res => {
215
       _intelligentDates().then(res => {
216
         this.days = res.data
216
         this.days = res.data
217
       })
217
       })
218
     },
218
     },
219
+    checkConflict(id) {
220
+      return new Promise((resolve, reject) => {
221
+        if (this.checkedIds.length < 1) {
222
+          resolve(false)
223
+          return
224
+        }
225
+        const params = {
226
+          checked: id,
227
+          ids: this.checkedIds.join(',')
228
+        }
229
+        _checkConflict(params).then(res => {
230
+          this.checkedIds = res.data.checked_list.map(item => item.class_attend_id)
231
+          this.conflictIds = res.data.conflict_list.map(item => item.class_attend_id)
232
+          resolve(res.data.checked_res)
233
+        })
234
+      })
235
+    },
219
     getHobbyConfig() {
236
     getHobbyConfig() {
220
-      _intelligentInterests().then(res => {
221
-        // this.interests = res.data
237
+      const params = { week: this.params.week.join(',') }
238
+      _intelligentInterests(params).then(res => {
222
         const choose = res.data[res.data.length - 1]
239
         const choose = res.data[res.data.length - 1]
223
         this.params.hobby = [choose.id]
240
         this.params.hobby = [choose.id]
224
-        this.keys = [...new Set(choose.names)].filter(e => e)
241
+        this.keys = [...new Set(Object.values(choose.names))].filter(e => e)
225
         if (this.interests.length < 1) this.interests = this.keys.slice(0, 5)
242
         if (this.interests.length < 1) this.interests = this.keys.slice(0, 5)
226
       })
243
       })
227
     },
244
     },
@@ -239,6 +256,7 @@ export default {
239
       const params = { week: this.params.week.join(','), student_id: this.kid, keywords: key }
256
       const params = { week: this.params.week.join(','), student_id: this.kid, keywords: key }
240
       _intelligentGetKeys(params).then(res => {
257
       _intelligentGetKeys(params).then(res => {
241
         if (res.data.length < 1) {
258
         if (res.data.length < 1) {
259
+          this.params.hobbyOther = this.params.hobbyOther.filter(k => k != key)
242
           uni.showToast({
260
           uni.showToast({
243
             title: '未找到相关课程',
261
             title: '未找到相关课程',
244
             icon: 'none',
262
             icon: 'none',
@@ -257,17 +275,25 @@ export default {
257
         this.checked = [] //初始化选项
275
         this.checked = [] //初始化选项
258
         if (this.attends.length > 0) {
276
         if (this.attends.length > 0) {
259
           this.attends.map((course, index) => {
277
           this.attends.map((course, index) => {
260
-            //过滤不能报课的
261
             const list = course.list
278
             const list = course.list
262
             const item = list[0]
279
             const item = list[0]
263
             const class_attend_id = item.status > 0 ? item.class_attend_id : null
280
             const class_attend_id = item.status > 0 ? item.class_attend_id : null
264
-            this.$set(this.checked, index, class_attend_id)
281
+            this.$set(this.checked, index, [class_attend_id])
265
             const prop = item.prop.length > 0 ? [item.prop[0].id] : []
282
             const prop = item.prop.length > 0 ? [item.prop[0].id] : []
266
-            this.$set(this.checked_props, index, { class_attend_id: class_attend_id, prop: prop })
283
+            this.$set(this.checked_props, index, [{ class_attend_id: class_attend_id, prop: prop }])
267
           })
284
           })
285
+          this.checkedIds = this.getCheckedIds()
268
         }
286
         }
269
       })
287
       })
270
     },
288
     },
289
+    getCheckedIds() {
290
+      //获取默认选择集合
291
+      let arr = []
292
+      this.checked.forEach(v => {
293
+        arr = arr.concat(v)
294
+      })
295
+      return arr.filter(e => e)
296
+    },
271
     delHobby(key) {
297
     delHobby(key) {
272
       this.params.hobbyOther = this.params.hobbyOther.filter(item => item != key)
298
       this.params.hobbyOther = this.params.hobbyOther.filter(item => item != key)
273
     },
299
     },
@@ -307,6 +333,9 @@ export default {
307
         uni.showToast({ title: '请先选择兴趣', icon: 'none' })
333
         uni.showToast({ title: '请先选择兴趣', icon: 'none' })
308
         return false
334
         return false
309
       }
335
       }
336
+      if (index === 1) {
337
+        this.getHobbyConfig()
338
+      }
310
       const step = Math.abs(index - this.cur)
339
       const step = Math.abs(index - this.cur)
311
       if (step > 1) return false
340
       if (step > 1) return false
312
       this.cur = index
341
       this.cur = index
@@ -320,27 +349,61 @@ export default {
320
     changeDisableBtn() {
349
     changeDisableBtn() {
321
       this.disableBtn = true
350
       this.disableBtn = true
322
     },
351
     },
323
-    classChange(course, i) {
352
+    async classChange(course, i) {
353
+      //失效课程点击无效
324
       if (course.status == 0) {
354
       if (course.status == 0) {
325
         return false
355
         return false
326
       }
356
       }
327
       const class_attend_id = course.class_attend_id
357
       const class_attend_id = course.class_attend_id
328
-      if (this.checked.includes(class_attend_id)) {
329
-        this.$set(this.checked, i, null)
330
-        this.$set(this.checked_props, i, { class_attend_id: null, prop: [] })
358
+      if (this.checked[i].includes(class_attend_id)) {
359
+        this.batchCancel([class_attend_id])
331
       } else {
360
       } else {
332
-        this.$set(this.checked, i, class_attend_id)
333
-        this.$set(this.checked_props, i, { class_attend_id: class_attend_id, prop: [] })
361
+        //判断课程冲突
362
+        const pass = await this.checkConflict(course.class_attend_id)
363
+        if (pass) {
364
+          //冲突取消之前选择
365
+          uni.showToast({ title: '存在课程时间冲突,已取消冲突课程!', icon: 'none', duration: 2000 })
366
+          this.batchCancel(this.conflictIds)
367
+        }
368
+        this.batchChoose(class_attend_id, [])
334
       }
369
       }
335
     },
370
     },
336
-    propChange(e, i) {
371
+    async propChange(e, i) {
337
       const parentId = e.target.dataset.id
372
       const parentId = e.target.dataset.id
338
       const values = e.detail.value.map(item => Number(item))
373
       const values = e.detail.value.map(item => Number(item))
339
-      if (values.length > 0 && !this.checked.includes(parentId)) {
340
-        this.$set(this.checked, i, parentId)
374
+      if (values.length > 0 && !this.checked[i].includes(parentId)) {
375
+        //判断课程冲突
376
+        const pass = await this.checkConflict(parentId)
377
+        if (pass) {
378
+          //冲突取消之前选择
379
+          uni.showToast({ title: '存在课程时间冲突,已取消冲突课程!', icon: 'none', duration: 2000 })
380
+          this.batchCancel(this.conflictIds)
381
+        }
341
       }
382
       }
342
-      const item = { class_attend_id: parentId, prop: values }
343
-      this.$set(this.checked_props, i, item)
383
+      this.batchChoose(parentId, values)
384
+    },
385
+    batchCancel(ids) {
386
+      if (ids.length < 1) return false
387
+      this.checked.forEach((e, i) => {
388
+        const f = e.findIndex(c => ids.includes(c))
389
+        if (f >= 0) {
390
+          this.$set(this.checked[i], f, null)
391
+          this.$set(this.checked_props[i], f, { class_attend_id: null, prop: [] })
392
+        }
393
+      })
394
+    },
395
+    batchChoose(id, props) {
396
+      this.attends.map((course, i) => {
397
+        const list = course.list
398
+        const c = list.findIndex(e => e.class_attend_id == id)
399
+        if (c >= 0) {
400
+          const choose = list[c]
401
+          this.$set(this.checked[i], c, choose.class_attend_id)
402
+          //道具选择
403
+          const items = props.length > 0 ? props : choose.prop.length > 0 ? [choose.prop[0].id] : []
404
+          this.$set(this.checked_props[i], c, { class_attend_id: choose.class_attend_id, prop: items })
405
+        }
406
+      })
344
     },
407
     },
345
     TabSelect(e) {
408
     TabSelect(e) {
346
       this.tabCur = e.currentTarget.dataset.id
409
       this.tabCur = e.currentTarget.dataset.id
@@ -348,10 +411,22 @@ export default {
348
       this.verticalNavTop = (e.currentTarget.dataset.id - 1) * 50
411
       this.verticalNavTop = (e.currentTarget.dataset.id - 1) * 50
349
     },
412
     },
350
     addCart() {
413
     addCart() {
351
-      if (this.disableBtn) return false
414
+      uni.showLoading({
415
+        mask: true,
416
+        title: '加载中...'
417
+      })
418
+      //合并选中项
419
+      let arr = []
420
+      this.checked_props.forEach(v => {
421
+        arr = arr.concat(v)
422
+      })
423
+      if (this.disableBtn) {
424
+        uni.hideLoading()
425
+        return false
426
+      }
352
       this.disableBtn = true
427
       this.disableBtn = true
353
       const _self = this
428
       const _self = this
354
-      const list = this.checked_props
429
+      const list = arr
355
         .filter(item => item.class_attend_id)
430
         .filter(item => item.class_attend_id)
356
         .map(item => {
431
         .map(item => {
357
           return {
432
           return {
@@ -361,13 +436,22 @@ export default {
361
           }
436
           }
362
         })
437
         })
363
       if (list.length < 1) {
438
       if (list.length < 1) {
439
+        uni.hideLoading()
364
         uni.showToast({ title: '请先选择课程', icon: 'none' })
440
         uni.showToast({ title: '请先选择课程', icon: 'none' })
365
         this.disableBtn = false
441
         this.disableBtn = false
366
         return false
442
         return false
367
       }
443
       }
368
       _joinShops({ list }).then(res => {
444
       _joinShops({ list }).then(res => {
369
         if (res.code === 1) {
445
         if (res.code === 1) {
370
-          _self.globalNavigateTo('classCart')
446
+          setTimeout(() => {
447
+            if (!this.ifConnectOrder) {
448
+              // socket非正常状态
449
+              uni.hideLoading()
450
+              this.globalNavigateTo('order', { type: 1 })
451
+            }
452
+            this.disableBtn = false
453
+            this.$store.dispatch('setConnect', false)
454
+          }, 3000)
371
         } else {
455
         } else {
372
           this.disableBtn = false
456
           this.disableBtn = false
373
         }
457
         }
@@ -405,12 +489,7 @@ export default {
405
 .hobby {
489
 .hobby {
406
   position: relative;
490
   position: relative;
407
   display: inline-block;
491
   display: inline-block;
408
-  margin-left: 20rpx;
409
-  padding: 10rpx 40rpx;
410
-  border-radius: 100rpx;
411
-  border: 1px solid #eee;
412
-  color: #fff;
413
-  background-color: #09e294;
492
+  margin-left: 30rpx;
414
   .del-hobby {
493
   .del-hobby {
415
     position: absolute;
494
     position: absolute;
416
     top: -6rpx;
495
     top: -6rpx;