xyang 2 lat temu
rodzic
commit
37751c8ed8
65 zmienionych plików z 2453 dodań i 2742 usunięć
  1. 8 0
      .env.development
  2. 9 9
      .gitignore
  3. 40 40
      Readme.md
  4. 0 4
      dist/build/mp-weixin/app.js
  5. 0 70
      dist/build/mp-weixin/app.json
  6. 0 3
      dist/build/mp-weixin/app.wxss
  7. 0 4
      dist/build/mp-weixin/common/runtime.js
  8. 0 28
      dist/build/mp-weixin/common/vendor.js
  9. 0 10
      dist/build/mp-weixin/components/cu-custom.js
  10. 0 4
      dist/build/mp-weixin/components/cu-custom.json
  11. 0 10
      dist/build/mp-weixin/components/float-tab.js
  12. 0 4
      dist/build/mp-weixin/components/float-tab.json
  13. 0 10
      dist/build/mp-weixin/components/mp-tabbar.js
  14. 0 4
      dist/build/mp-weixin/components/mp-tabbar.json
  15. 0 10
      dist/build/mp-weixin/components/page-loading.js
  16. 0 4
      dist/build/mp-weixin/components/page-loading.json
  17. 0 10
      dist/build/mp-weixin/components/shop-cart.js
  18. 0 4
      dist/build/mp-weixin/components/shop-cart.json
  19. 0 10
      dist/build/mp-weixin/components/swiper-tab.js
  20. 0 4
      dist/build/mp-weixin/components/swiper-tab.json
  21. 0 10
      dist/build/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-calendar/uni-calendar-item.js
  22. 0 4
      dist/build/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-calendar/uni-calendar-item.json
  23. 0 10
      dist/build/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-calendar/uni-calendar.js
  24. 0 6
      dist/build/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-calendar/uni-calendar.json
  25. 0 3
      dist/build/mp-weixin/pages/agreement/index.json
  26. 0 3
      dist/build/mp-weixin/pages/class/bindPhone.json
  27. 0 6
      dist/build/mp-weixin/pages/class/detail.json
  28. 0 5
      dist/build/mp-weixin/pages/class/gift.json
  29. 0 3
      dist/build/mp-weixin/pages/class/shoppingCart.json
  30. 0 10
      dist/build/mp-weixin/pages/index/components/card.js
  31. 0 4
      dist/build/mp-weixin/pages/index/components/card.json
  32. 0 10
      dist/build/mp-weixin/pages/index/components/course.js
  33. 0 4
      dist/build/mp-weixin/pages/index/components/course.json
  34. 0 6
      dist/build/mp-weixin/pages/index/index.json
  35. 0 3
      dist/build/mp-weixin/pages/login/index.json
  36. 0 3
      dist/build/mp-weixin/pages/mine/changePhone.json
  37. 0 3
      dist/build/mp-weixin/pages/mine/institution.json
  38. 0 3
      dist/build/mp-weixin/pages/mine/message.json
  39. 0 3
      dist/build/mp-weixin/pages/mine/mine.json
  40. 0 3
      dist/build/mp-weixin/pages/mine/onlineService.json
  41. 0 3
      dist/build/mp-weixin/pages/mine/parents.json
  42. 0 3
      dist/build/mp-weixin/pages/mine/setting.json
  43. 0 3
      dist/build/mp-weixin/pages/mine/teachers.json
  44. 0 3
      dist/build/mp-weixin/pages/myStudents/myStudents.json
  45. 0 5
      dist/build/mp-weixin/pages/order/index.json
  46. 0 3
      dist/build/mp-weixin/pages/studentcenter/absent.json
  47. 0 3
      dist/build/mp-weixin/pages/studentcenter/classVideo.json
  48. 0 3
      dist/build/mp-weixin/pages/studentcenter/evaluate.json
  49. 0 6
      dist/build/mp-weixin/pages/studentcenter/index.json
  50. 0 3
      dist/build/mp-weixin/pages/studentcenter/operation.json
  51. 0 3
      dist/build/mp-weixin/pages/studentcenter/signIn.json
  52. 0 3
      dist/build/mp-weixin/pages/studentcenter/works.json
  53. 0 7
      dist/build/mp-weixin/project.private.config.json
  54. 98 97
      package.json
  55. 70 66
      src/api/auth.js
  56. 122 115
      src/pages/class/bindPhone.vue
  57. 173 176
      src/pages/class/shoppingCart.vue
  58. 411 411
      src/pages/index/index.vue
  59. 121 121
      src/pages/login/index.vue
  60. 330 330
      src/pages/mine/mine.vue
  61. 86 76
      src/pages/mine/setting.vue
  62. 302 298
      src/pages/myStudents/myStudents.vue
  63. 366 360
      src/pages/studentcenter/index.vue
  64. 202 200
      src/pages/studentcenter/signIn.vue
  65. 115 100
      src/store/user.js

+ 8 - 0
.env.development

@@ -0,0 +1,8 @@
1
+NODE_ENV=development
2
+VUE_APP_BASE_URL="https://www.kehoubaike.com/api"
3
+VUE_APP_BASE_WS="wss://www.kehoubaike.com/wss"
4
+#VUE_APP_BASE_URL="https://test.kehoubaike.com/api"
5
+#VUE_APP_BASE_WS="wss://test.kehoubaike.com/wss"
6
+#VUE_APP_BASE_URL="http://192.168.0.25:8083/api.php?s="
7
+#VUE_APP_BASE_WS="ws://192.168.0.25:20004"
8
+

+ 9 - 9
.gitignore

@@ -1,9 +1,9 @@
1
-node_modules
2
-dist/
3
-.history/
4
-.env.development
5
-.idea/anpaismall.iml
6
-.idea/misc.xml
7
-.idea/modules.xml
8
-.idea/vcs.xml
9
-.idea/workspace.xml
1
+node_modules
2
+dist/
3
+.history/
4
+.env.development
5
+.idea/anpaismall.iml
6
+.idea/misc.xml
7
+.idea/modules.xml
8
+.idea/vcs.xml
9
+.idea/workspace.xml

+ 40 - 40
Readme.md

@@ -1,40 +1,40 @@
1
-# 使用vue-cli 创建的uni-app项目
2
-
3
-## 安装依赖包
4
-```
5
-npm install
6
-````
7
-
8
-## 编译开发版本微信小程序
9
-```
10
-npm run dev:mp-weixin
11
-```
12
-### 使用微信开发者打开dist/mp-weixin目录,即可查看效果
13
-
14
-更多指令查询package.json
15
-
16
-建议使用vscode开发
17
-
18
-提交前请先执行 ```npm run vue:lint``` 验证代码格式
19
-
20
-请求接口基本路径配置在 .env.development 与 .env.production
21
-
22
-
23
-在developer分支写的一段话
24
-
25
-项目约定文件名: 2020年5月21日17:37:41
26
-
27
-组件使用驼峰
28
-文件夹不准使用-
29
-页面文件可以使用-连接,但是最多1个-
30
-
31
-## 商标统一标准结构
32
-- 列表
33
-```j
34
-
35
-```
36
-
37
-- 单个
38
-```
39
-
40
-```
1
+# 使用vue-cli 创建的uni-app项目
2
+
3
+## 安装依赖包
4
+```
5
+npm install
6
+````
7
+
8
+## 编译开发版本微信小程序,运行测试环境
9
+```
10
+npm run dev:mp-weixin
11
+```
12
+## 打包正式环境
13
+npm run build:mp-weixin
14
+
15
+## 使用微信开发者打开dist/mp-weixin目录,即可查看效果,上传小程序dist/mp-weixin目录
16
+
17
+更多指令查询package.json
18
+
19
+建议使用vscode开发
20
+
21
+提交前请先执行 ```npm run vue:lint``` 验证代码格式
22
+
23
+请求接口基本路径配置在 .env.development 与 .env.production
24
+
25
+api统一封装后台请求,components公共组件库,common公用文件
26
+
27
+在developer分支写的一段话
28
+
29
+项目约定文件名:
30
+
31
+组件使用驼峰
32
+文件夹不准使用-
33
+页面文件可以使用-连接,但是最多1个-
34
+
35
+```
36
+
37
+- 单个
38
+```
39
+
40
+```

+ 0 - 4
dist/build/mp-weixin/app.js

@@ -1,4 +0,0 @@
1
-
2
-require('./common/runtime.js')
3
-require('./common/vendor.js')
4
-require('./common/main.js')

+ 0 - 70
dist/build/mp-weixin/app.json

@@ -1,70 +0,0 @@
1
-{
2
-  "pages": [
3
-    "pages/index/index",
4
-    "pages/class/gift",
5
-    "pages/class/detail",
6
-    "pages/class/shoppingCart",
7
-    "pages/class/bindPhone",
8
-    "pages/order/index",
9
-    "pages/myStudents/myStudents",
10
-    "pages/studentcenter/index",
11
-    "pages/studentcenter/operation",
12
-    "pages/studentcenter/signIn",
13
-    "pages/studentcenter/classVideo",
14
-    "pages/studentcenter/works",
15
-    "pages/studentcenter/evaluate",
16
-    "pages/studentcenter/absent",
17
-    "pages/mine/mine",
18
-    "pages/mine/parents",
19
-    "pages/mine/teachers",
20
-    "pages/mine/institution",
21
-    "pages/mine/setting",
22
-    "pages/mine/changePhone",
23
-    "pages/mine/message",
24
-    "pages/mine/onlineService",
25
-    "pages/login/index",
26
-    "pages/agreement/index"
27
-  ],
28
-  "subPackages": [],
29
-  "window": {
30
-    "navigationBarBackgroundColor": "#FFFFFF",
31
-    "navigationBarTitleText": "1212",
32
-    "navigationStyle": "custom",
33
-    "navigationBarTextStyle": "black",
34
-    "animationType": "slide-out-right"
35
-  },
36
-  "tabBar": {
37
-    "custom": true,
38
-    "color": "#707070",
39
-    "selectedColor": "#3390F5",
40
-    "borderStyle": "black",
41
-    "backgroundColor": "#ffffff",
42
-    "list": [
43
-      {
44
-        "pagePath": "pages/index/index",
45
-        "iconPath": "/static/imgs/tabbar/xk1.png",
46
-        "selectedIconPath": "/static/imgs/tabbar/xk.png",
47
-        "text": "选课"
48
-      },
49
-      {
50
-        "pagePath": "pages/studentcenter/index",
51
-        "iconPath": "/static/imgs/tabbar/xszx1.png",
52
-        "selectedIconPath": "/static/imgs/tabbar/xszx.png",
53
-        "text": "学生中心"
54
-      },
55
-      {
56
-        "pagePath": "pages/mine/mine",
57
-        "iconPath": "/static/imgs/tabbar/wd1.png",
58
-        "selectedIconPath": "/static/imgs/tabbar/wd.png",
59
-        "text": "我的"
60
-      }
61
-    ]
62
-  },
63
-  "usingComponents": {
64
-    "cu-custom": "/components/cu-custom",
65
-    "page-loading": "/components/page-loading",
66
-    "mp-tabbar": "/components/mp-tabbar",
67
-    "float-tab": "/components/float-tab"
68
-  },
69
-  "sitemapLocation": "sitemap.json"
70
-}

+ 0 - 3
dist/build/mp-weixin/app.wxss

@@ -1,3 +0,0 @@
1
-@import './common/main.wxss';
2
-
3
-[data-custom-hidden="true"],[bind-data-custom-hidden="true"]{display: none !important;}

Plik diff jest za duży
+ 0 - 4
dist/build/mp-weixin/common/runtime.js


Plik diff jest za duży
+ 0 - 28
dist/build/mp-weixin/common/vendor.js


Plik diff jest za duży
+ 0 - 10
dist/build/mp-weixin/components/cu-custom.js


+ 0 - 4
dist/build/mp-weixin/components/cu-custom.json

@@ -1,4 +0,0 @@
1
-{
2
-  "usingComponents": {},
3
-  "component": true
4
-}

Plik diff jest za duży
+ 0 - 10
dist/build/mp-weixin/components/float-tab.js


+ 0 - 4
dist/build/mp-weixin/components/float-tab.json

@@ -1,4 +0,0 @@
1
-{
2
-  "usingComponents": {},
3
-  "component": true
4
-}

Plik diff jest za duży
+ 0 - 10
dist/build/mp-weixin/components/mp-tabbar.js


+ 0 - 4
dist/build/mp-weixin/components/mp-tabbar.json

@@ -1,4 +0,0 @@
1
-{
2
-  "usingComponents": {},
3
-  "component": true
4
-}

Plik diff jest za duży
+ 0 - 10
dist/build/mp-weixin/components/page-loading.js


+ 0 - 4
dist/build/mp-weixin/components/page-loading.json

@@ -1,4 +0,0 @@
1
-{
2
-  "usingComponents": {},
3
-  "component": true
4
-}

Plik diff jest za duży
+ 0 - 10
dist/build/mp-weixin/components/shop-cart.js


+ 0 - 4
dist/build/mp-weixin/components/shop-cart.json

@@ -1,4 +0,0 @@
1
-{
2
-  "usingComponents": {},
3
-  "component": true
4
-}

Plik diff jest za duży
+ 0 - 10
dist/build/mp-weixin/components/swiper-tab.js


+ 0 - 4
dist/build/mp-weixin/components/swiper-tab.json

@@ -1,4 +0,0 @@
1
-{
2
-  "usingComponents": {},
3
-  "component": true
4
-}

Plik diff jest za duży
+ 0 - 10
dist/build/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-calendar/uni-calendar-item.js


+ 0 - 4
dist/build/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-calendar/uni-calendar-item.json

@@ -1,4 +0,0 @@
1
-{
2
-  "usingComponents": {},
3
-  "component": true
4
-}

Plik diff jest za duży
+ 0 - 10
dist/build/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-calendar/uni-calendar.js


+ 0 - 6
dist/build/mp-weixin/node-modules/@dcloudio/uni-ui/lib/uni-calendar/uni-calendar.json

@@ -1,6 +0,0 @@
1
-{
2
-  "component": true,
3
-  "usingComponents": {
4
-    "calendar-item": "/node-modules/@dcloudio/uni-ui/lib/uni-calendar/uni-calendar-item"
5
-  }
6
-}

+ 0 - 3
dist/build/mp-weixin/pages/agreement/index.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/class/bindPhone.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 6
dist/build/mp-weixin/pages/class/detail.json

@@ -1,6 +0,0 @@
1
-{
2
-  "usingComponents": {
3
-    "swiper-tab": "/components/swiper-tab",
4
-    "shop-cart": "/components/shop-cart"
5
-  }
6
-}

+ 0 - 5
dist/build/mp-weixin/pages/class/gift.json

@@ -1,5 +0,0 @@
1
-{
2
-  "usingComponents": {
3
-    "shop-cart": "/components/shop-cart"
4
-  }
5
-}

+ 0 - 3
dist/build/mp-weixin/pages/class/shoppingCart.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

Plik diff jest za duży
+ 0 - 10
dist/build/mp-weixin/pages/index/components/card.js


+ 0 - 4
dist/build/mp-weixin/pages/index/components/card.json

@@ -1,4 +0,0 @@
1
-{
2
-  "usingComponents": {},
3
-  "component": true
4
-}

Plik diff jest za duży
+ 0 - 10
dist/build/mp-weixin/pages/index/components/course.js


+ 0 - 4
dist/build/mp-weixin/pages/index/components/course.json

@@ -1,4 +0,0 @@
1
-{
2
-  "usingComponents": {},
3
-  "component": true
4
-}

+ 0 - 6
dist/build/mp-weixin/pages/index/index.json

@@ -1,6 +0,0 @@
1
-{
2
-  "usingComponents": {
3
-    "course": "/pages/index/components/course",
4
-    "card": "/pages/index/components/card"
5
-  }
6
-}

+ 0 - 3
dist/build/mp-weixin/pages/login/index.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/mine/changePhone.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/mine/institution.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/mine/message.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/mine/mine.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/mine/onlineService.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/mine/parents.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/mine/setting.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/mine/teachers.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/myStudents/myStudents.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 5
dist/build/mp-weixin/pages/order/index.json

@@ -1,5 +0,0 @@
1
-{
2
-  "usingComponents": {
3
-    "swiper-tab": "/components/swiper-tab"
4
-  }
5
-}

+ 0 - 3
dist/build/mp-weixin/pages/studentcenter/absent.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/studentcenter/classVideo.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/studentcenter/evaluate.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 6
dist/build/mp-weixin/pages/studentcenter/index.json

@@ -1,6 +0,0 @@
1
-{
2
-  "usingComponents": {
3
-    "uni-calendar": "/node-modules/@dcloudio/uni-ui/lib/uni-calendar/uni-calendar",
4
-    "swiper-tab": "/components/swiper-tab"
5
-  }
6
-}

+ 0 - 3
dist/build/mp-weixin/pages/studentcenter/operation.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/studentcenter/signIn.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 3
dist/build/mp-weixin/pages/studentcenter/works.json

@@ -1,3 +0,0 @@
1
-{
2
-  "usingComponents": {}
3
-}

+ 0 - 7
dist/build/mp-weixin/project.private.config.json

@@ -1,7 +0,0 @@
1
-{
2
-  "projectname": "parentTest",
3
-  "setting": {
4
-    "compileHotReLoad": true
5
-  },
6
-  "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html"
7
-}

+ 98 - 97
package.json

@@ -1,97 +1,98 @@
1
-{
2
-  "name": "uni-cli-project",
3
-  "version": "0.1.0",
4
-  "private": true,
5
-  "scripts": {
6
-    "dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize",
7
-    "build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build --minimize",
8
-    "build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
9
-    "build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
10
-    "build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
11
-    "build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
12
-    "build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
13
-    "build:mp-qq": "cross-env NODE_ENV=production UNI_PLATFORM=mp-qq vue-cli-service uni-build",
14
-    "build:mp-toutiao": "cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
15
-    "build:quickapp": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp vue-cli-service uni-build",
16
-    "dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
17
-    "dev:custom": "cross-env NODE_ENV=development uniapp-cli custom",
18
-    "dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
19
-    "dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
20
-    "dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
21
-    "dev:mp-qq": "cross-env NODE_ENV=development UNI_PLATFORM=mp-qq vue-cli-service uni-build --watch",
22
-    "dev:mp-toutiao": "cross-env NODE_ENV=development UNI_PLATFORM=mp-toutiao vue-cli-service uni-build --watch",
23
-    "dev:quickapp": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp vue-cli-service uni-build --watch",
24
-    "info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js",
25
-    "serve:quickapp": "node node_modules/@dcloudio/uni-quickapp/bin/serve.js",
26
-    "lint:fix": "eslint --ext .js,.vue src -c .eslintrc.js --fix",
27
-    "vue:lint": "vue-cli-service lint",
28
-    "vue:lintfix": "vue-cli-service lint --fix"
29
-  },
30
-  "dependencies": {
31
-    "@dcloudio/uni-ui": "^1.4.14",
32
-    "number-precision": "^1.4.0",
33
-    "vue": "^2.6.10",
34
-    "vue-class-component": "^6.3.2",
35
-    "vue-count-to": "^1.0.13",
36
-    "vue-property-decorator": "^8.5.1",
37
-    "vuex": "^3.5.1",
38
-    "vuex-class": "^0.3.2",
39
-    "vuex-module-decorators": "^0.17.0"
40
-  },
41
-  "devDependencies": {
42
-    "@dcloudio/types": "^1.0.2",
43
-    "@dcloudio/uni-app-plus": "^2.0.0-31920210514002",
44
-    "@dcloudio/uni-cli-shared": "^2.0.0-31920210514002",
45
-    "@dcloudio/uni-h5": "^2.0.0-31920210514002",
46
-    "@dcloudio/uni-helper-json": "^1.0.5",
47
-    "@dcloudio/uni-migration": "^2.0.0-31920210514002",
48
-    "@dcloudio/uni-mp-alipay": "^2.0.0-31920210514002",
49
-    "@dcloudio/uni-mp-baidu": "^2.0.0-31920210514002",
50
-    "@dcloudio/uni-mp-qq": "^2.0.0-31920210514002",
51
-    "@dcloudio/uni-mp-toutiao": "^2.0.0-31920210514002",
52
-    "@dcloudio/uni-mp-weixin": "^2.0.0-31920210514002",
53
-    "@dcloudio/uni-stat": "^2.0.0-31920210514002",
54
-    "@dcloudio/uni-template-compiler": "^2.0.0-31920210514002",
55
-    "@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.0-31920210514002",
56
-    "@dcloudio/vue-cli-plugin-uni": "^2.0.0-31920210514002",
57
-    "@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.0-31920210514002",
58
-    "@dcloudio/webpack-uni-mp-loader": "^2.0.0-31920210514002",
59
-    "@dcloudio/webpack-uni-pages-loader": "^2.0.0-31920210514002",
60
-    "@types/lodash": "^4.14.156",
61
-    "@typescript-eslint/eslint-plugin": "^3.4.0",
62
-    "@typescript-eslint/parser": "^3.4.0",
63
-    "@vue/cli-plugin-babel": "3.5.1",
64
-    "@vue/cli-plugin-typescript": "^3.5.1",
65
-    "@vue/cli-service": "^4.4.5",
66
-    "@vue/eslint-config-prettier": "^6.0.0",
67
-    "@vue/eslint-config-standard": "^5.1.2",
68
-    "@vue/eslint-config-typescript": "^5.0.2",
69
-    "babel-plugin-import": "^1.11.0",
70
-    "copy-webpack-plugin": "~5.0.0",
71
-    "cross-env": "^7.0.2",
72
-    "eslint": "^7.3.0",
73
-    "eslint-config-prettier": "^6.11.0",
74
-    "eslint-import-resolver-typescript": "^2.0.0",
75
-    "eslint-plugin-import": "^2.21.2",
76
-    "eslint-plugin-json": "^2.1.1",
77
-    "eslint-plugin-node": "^11.1.0",
78
-    "eslint-plugin-prettier": "^3.1.4",
79
-    "eslint-plugin-promise": "^4.2.1",
80
-    "eslint-plugin-standard": "^4.0.1",
81
-    "eslint-plugin-vue": "^6.2.2",
82
-    "node-sass": "^4.14.1",
83
-    "postcss-comment": "^2.0.0",
84
-    "prettier": "^2.0.5",
85
-    "sass-loader": "^8.0.2",
86
-    "sass-resources-loader": "^2.0.3",
87
-    "typescript": "^3.9.5",
88
-    "vue-template-compiler": "^2.6.10"
89
-  },
90
-  "browserslist": [
91
-    "Android >= 4",
92
-    "ios >= 8"
93
-  ],
94
-  "uni-app": {
95
-    "scripts": {}
96
-  }
97
-}
1
+{
2
+  "name": "uni-cli-project",
3
+  "version": "0.1.0",
4
+  "private": true,
5
+  "scripts": {
6
+    "dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize",
7
+    "build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build --minimize",
8
+    "build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
9
+    "build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
10
+    "build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
11
+    "build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
12
+    "build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
13
+    "build:mp-qq": "cross-env NODE_ENV=production UNI_PLATFORM=mp-qq vue-cli-service uni-build",
14
+    "build:mp-toutiao": "cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
15
+    "build:quickapp": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp vue-cli-service uni-build",
16
+    "dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
17
+    "dev:custom": "cross-env NODE_ENV=development uniapp-cli custom",
18
+    "dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
19
+    "dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
20
+    "dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
21
+    "dev:mp-qq": "cross-env NODE_ENV=development UNI_PLATFORM=mp-qq vue-cli-service uni-build --watch",
22
+    "dev:mp-toutiao": "cross-env NODE_ENV=development UNI_PLATFORM=mp-toutiao vue-cli-service uni-build --watch",
23
+    "dev:quickapp": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp vue-cli-service uni-build --watch",
24
+    "info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js",
25
+    "serve:quickapp": "node node_modules/@dcloudio/uni-quickapp/bin/serve.js",
26
+    "lint:fix": "eslint --ext .js,.vue src -c .eslintrc.js --fix",
27
+    "vue:lint": "vue-cli-service lint",
28
+    "vue:lintfix": "vue-cli-service lint --fix"
29
+  },
30
+  "dependencies": {
31
+    "@dcloudio/uni-cli-i18n": "^2.0.1-34720220422002",
32
+    "@dcloudio/uni-ui": "^1.4.14",
33
+    "number-precision": "^1.4.0",
34
+    "vue": "^2.6.10",
35
+    "vue-class-component": "^6.3.2",
36
+    "vue-count-to": "^1.0.13",
37
+    "vue-property-decorator": "^8.5.1",
38
+    "vuex": "^3.5.1",
39
+    "vuex-class": "^0.3.2",
40
+    "vuex-module-decorators": "^0.17.0"
41
+  },
42
+  "devDependencies": {
43
+    "@dcloudio/types": "^1.0.2",
44
+    "@dcloudio/uni-app-plus": "^2.0.0-31920210514002",
45
+    "@dcloudio/uni-cli-shared": "^2.0.0-31920210514002",
46
+    "@dcloudio/uni-h5": "^2.0.0-31920210514002",
47
+    "@dcloudio/uni-helper-json": "^1.0.5",
48
+    "@dcloudio/uni-migration": "^2.0.0-31920210514002",
49
+    "@dcloudio/uni-mp-alipay": "^2.0.0-31920210514002",
50
+    "@dcloudio/uni-mp-baidu": "^2.0.0-31920210514002",
51
+    "@dcloudio/uni-mp-qq": "^2.0.0-31920210514002",
52
+    "@dcloudio/uni-mp-toutiao": "^2.0.0-31920210514002",
53
+    "@dcloudio/uni-mp-weixin": "^2.0.0-31920210514002",
54
+    "@dcloudio/uni-stat": "^2.0.0-31920210514002",
55
+    "@dcloudio/uni-template-compiler": "^2.0.0-31920210514002",
56
+    "@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.0-31920210514002",
57
+    "@dcloudio/vue-cli-plugin-uni": "^2.0.0-31920210514002",
58
+    "@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.0-31920210514002",
59
+    "@dcloudio/webpack-uni-mp-loader": "^2.0.0-31920210514002",
60
+    "@dcloudio/webpack-uni-pages-loader": "^2.0.0-31920210514002",
61
+    "@types/lodash": "^4.14.156",
62
+    "@typescript-eslint/eslint-plugin": "^3.4.0",
63
+    "@typescript-eslint/parser": "^3.4.0",
64
+    "@vue/cli-plugin-babel": "3.5.1",
65
+    "@vue/cli-plugin-typescript": "^3.5.1",
66
+    "@vue/cli-service": "^4.4.5",
67
+    "@vue/eslint-config-prettier": "^6.0.0",
68
+    "@vue/eslint-config-standard": "^5.1.2",
69
+    "@vue/eslint-config-typescript": "^5.0.2",
70
+    "babel-plugin-import": "^1.11.0",
71
+    "copy-webpack-plugin": "~5.0.0",
72
+    "cross-env": "^7.0.2",
73
+    "eslint": "^7.3.0",
74
+    "eslint-config-prettier": "^6.11.0",
75
+    "eslint-import-resolver-typescript": "^2.0.0",
76
+    "eslint-plugin-import": "^2.21.2",
77
+    "eslint-plugin-json": "^2.1.1",
78
+    "eslint-plugin-node": "^11.1.0",
79
+    "eslint-plugin-prettier": "^3.1.4",
80
+    "eslint-plugin-promise": "^4.2.1",
81
+    "eslint-plugin-standard": "^4.0.1",
82
+    "eslint-plugin-vue": "^6.2.2",
83
+    "node-sass": "^4.14.1",
84
+    "postcss-comment": "^2.0.0",
85
+    "prettier": "^2.0.5",
86
+    "sass-loader": "^8.0.2",
87
+    "sass-resources-loader": "^2.0.3",
88
+    "typescript": "^3.9.5",
89
+    "vue-template-compiler": "^2.6.10"
90
+  },
91
+  "browserslist": [
92
+    "Android >= 4",
93
+    "ios >= 8"
94
+  ],
95
+  "uni-app": {
96
+    "scripts": {}
97
+  }
98
+}

+ 70 - 66
src/api/auth.js

@@ -1,66 +1,70 @@
1
-import fetch from '@/common/utils/fetch.js'
2
-
3
-// 微信登录接口,换取openid
4
-export function _login(params) {
5
-  return fetch('/parents/login/wx_login', params, 'post')
6
-}
7
-// 换取用户详细信息
8
-export function _auth(params) {
9
-  return fetch('/parents/login/wx_auth', params, 'post')
10
-}
11
-// 微信绑定用户手机
12
-export function _bindPhone(params) {
13
-  return fetch('/parents/login/wx_bindphone', params, 'post')
14
-}
15
-// 修改用户信息
16
-export function _changeUserInfo(params) {
17
-  return fetch('/parents/init/parent_msg', params, 'post')
18
-}
19
-// 获取用户信息
20
-export function _getUserInfo(params) {
21
-  return fetch('/parents/init/get_parent', params, 'post')
22
-}
23
-// 获取验证码
24
-export function _getCode(params) {
25
-  return fetch('/index/index/wx_get_code', params, 'post')
26
-}
27
-// 修改手机号
28
-export function _changePhone(params) {
29
-  return fetch('/parents/login/wx_change_phone', params, 'post')
30
-}
31
-// 初始化学生
32
-export function _getStudents(params) {
33
-  return fetch('/parents/init/get_students', params, 'post')
34
-}
35
-// 绑定学生
36
-export function _bindStudent(params) {
37
-  return fetch('/parents/init/bind_student_by_id', params, 'post')
38
-}
39
-// 解绑学生
40
-export function _unbindStudent(params) {
41
-  return fetch('/parents/init/unbindStudent', params)
42
-}
43
-// 获取接送人列表
44
-export function _getPickup(params) {
45
-  return fetch('/parents/Pickup/get_pickup', params, 'post')
46
-}
47
-// 增加授权人
48
-export function _addPickup(params) {
49
-  return fetch('/parents/Pickup/pickup_accredit', params, 'post')
50
-}
51
-// 获取老师数据
52
-export function _getTeacher(params) {
53
-  return fetch('/parents/teacher/get_teacher', params, 'post')
54
-}
55
-// 获取教育机构数据
56
-export function _getInstitution(params) {
57
-  return fetch('/parents/institution/get_institution', params, 'post')
58
-}
59
-// 获取系统通知
60
-export function _getNotice(params) {
61
-  return fetch('/parents/notice/get_notice', params, 'post')
62
-}
63
-// 获取通知详情
64
-export function _noticeDetail(params) {
65
-  return fetch('/parents/notice/get_notice_details', params, 'post')
66
-}
1
+import fetch from '@/common/utils/fetch.js'
2
+
3
+// 微信登录接口,换取openid
4
+export function _login(params) {
5
+  return fetch('/parents/login/wx_login', params, 'post')
6
+}
7
+// 换取用户详细信息
8
+export function _auth(params) {
9
+  return fetch('/parents/login/wx_auth', params, 'post')
10
+}
11
+// 微信绑定用户手机
12
+export function _bindPhone(params) {
13
+  return fetch('/parents/login/wx_bindphone', params, 'post')
14
+}
15
+// 判断绑定手机号
16
+export function _getBindPhone() {
17
+  return fetch('/parents/login/getBindMobile')
18
+}
19
+// 修改用户信息
20
+export function _changeUserInfo(params) {
21
+  return fetch('/parents/init/parent_msg', params, 'post')
22
+}
23
+// 获取用户信息
24
+export function _getUserInfo(params) {
25
+  return fetch('/parents/init/get_parent', params, 'post')
26
+}
27
+// 获取验证码
28
+export function _getCode(params) {
29
+  return fetch('/index/index/wx_get_code', params, 'post')
30
+}
31
+// 修改手机号
32
+export function _changePhone(params) {
33
+  return fetch('/parents/login/wx_change_phone', params, 'post')
34
+}
35
+// 初始化学生
36
+export function _getStudents(params) {
37
+  return fetch('/parents/init/get_students', params, 'post')
38
+}
39
+// 绑定学生
40
+export function _bindStudent(params) {
41
+  return fetch('/parents/init/bind_student_by_id', params, 'post')
42
+}
43
+// 解绑学生
44
+export function _unbindStudent(params) {
45
+  return fetch('/parents/init/unbindStudent', params)
46
+}
47
+// 获取接送人列表
48
+export function _getPickup(params) {
49
+  return fetch('/parents/Pickup/get_pickup', params, 'post')
50
+}
51
+// 增加授权人
52
+export function _addPickup(params) {
53
+  return fetch('/parents/Pickup/pickup_accredit', params, 'post')
54
+}
55
+// 获取老师数据
56
+export function _getTeacher(params) {
57
+  return fetch('/parents/teacher/get_teacher', params, 'post')
58
+}
59
+// 获取教育机构数据
60
+export function _getInstitution(params) {
61
+  return fetch('/parents/institution/get_institution', params, 'post')
62
+}
63
+// 获取系统通知
64
+export function _getNotice(params) {
65
+  return fetch('/parents/notice/get_notice', params, 'post')
66
+}
67
+// 获取通知详情
68
+export function _noticeDetail(params) {
69
+  return fetch('/parents/notice/get_notice_details', params, 'post')
70
+}

+ 122 - 115
src/pages/class/bindPhone.vue

@@ -1,115 +1,122 @@
1
-<template>
2
-	<view class="page">
3
-		<cu-custom :isBack="true"  title="绑定手机号"></cu-custom>
4
-		<view class="bind bg-white">
5
-			<view class="bind-img">
6
-					<image src="/static/imgs/phone.png" mode="widthFix" style="width:400rpx;" />
7
-			</view>
8
-			<view class="bind-text">请绑定手机号</view>
9
-			<view class="bind-tip" style="margin-top:10px;"> 为向您提供更优质的交易相关基本功能,我们将会获取您的手机号。</view>
10
-			<view class="bind-tip">
11
-			为了更好的保障个人权益,请您仔细阅读
12
-					<text style="color:#02a5b1"  class="text" @tap="goto('user')">《用户协议》</text>和
13
-					<text style="color:#02a5b1"  class="text" @tap="goto('privacy')">《隐私政策》</text>
14
-			</view>
15
-			<button class="bind-btn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">立即绑定</button>
16
-		</view>
17
-	</view>
18
-</template>
19
-
20
-<script>
21
-import { _bindPhone, _login } from '@/api/auth'
22
-import { mapGetters } from 'vuex'
23
-export default {
24
-  data() {
25
-    return {
26
-      key: '绑定手机号'
27
-    }
28
-  },
29
-  computed: {
30
-    ...mapGetters([
31
-      'token', 'session'
32
-    ])
33
-  },
34
-  methods: {
35
-    goto(type) {
36
-      this.globalNavigateTo('agreement', { type })
37
-    },
38
-    getPhoneNumber(e) {
39
-      const detail = e.detail
40
-      if (!detail.iv) {
41
-        return false
42
-      }
43
-      const _self = this
44
-      const params = {
45
-        iv: detail.iv,
46
-        encryptedData: detail.encryptedData,
47
-        token: this.token,
48
-        code: this.globalApp.code
49
-      }
50
-      uni.checkSession({
51
-        success() {
52
-          params.session = _self.session
53
-          _self.bindPhone(params)
54
-        },
55
-        fail() {
56
-          uni.login({
57
-            success: wxres => {
58
-              _login({ code: wxres.code }).then(res => {
59
-                params.session = res.data.session_key
60
-                _self.$store.dispatch('setSession', res.data.session_key)
61
-                _self.bindPhone(params)
62
-              })
63
-            }
64
-          })
65
-        }
66
-      })
67
-    },
68
-    bindPhone(params) {
69
-      _bindPhone(params).then(res => {
70
-        uni.showToast({ title: res.msg, icon: 'none' })
71
-        const token = res.data.token
72
-        this.$store.dispatch('setToken', token)
73
-        setTimeout(() => {
74
-          uni.navigateBack()
75
-        }, 800)
76
-      })
77
-    }
78
-  }
79
-}
80
-</script>
81
-
82
-<style lang="scss" scoped>
83
-.bind{
84
-  padding:30px 44rpx 10px;
85
-}
86
-.bind-img{
87
-  margin:0 auto;
88
-  text-align:center;
89
-}
90
-.bind-text{
91
-    margin-top:20px;
92
-    color:#000;
93
-    font-size:18px;
94
-    text-align:center;
95
-}
96
-.bind-tip{
97
-  font-size:14px;
98
-}
99
-.bind-btn{
100
-  margin-top: 30px;
101
-  background: #5fd0e4;
102
-  border-radius:4px;
103
-  color: #fff;
104
-  width: 100%;
105
-  padding: 0;
106
-  font-size: 14px;
107
-  display: flex;
108
-  justify-content: center;
109
-  align-items: center;
110
-  height: 10vw;
111
-}
112
-.bind-btn:hover{
113
-  background: #3f8b97;
114
-}
115
-</style>
1
+<template>
2
+	<view class="page">
3
+		<cu-custom :isBack="true"  title="绑定手机号"></cu-custom>
4
+		<view class="bind bg-white">
5
+			<view class="bind-img">
6
+					<image src="/static/imgs/phone.png" mode="widthFix" style="width:400rpx;" />
7
+			</view>
8
+			<view class="bind-text">请绑定手机号</view>
9
+			<view class="bind-tip" style="margin-top:10px;"> 为向您提供更优质的交易相关基本功能,我们将会获取您的手机号。</view>
10
+			<view class="bind-tip">
11
+			为了更好的保障个人权益,请您仔细阅读
12
+					<text style="color:#02a5b1"  class="text" @tap="goto('user')">《用户协议》</text>和
13
+					<text style="color:#02a5b1"  class="text" @tap="goto('privacy')">《隐私政策》</text>
14
+			</view>
15
+			<button class="bind-btn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">立即绑定</button>
16
+		</view>
17
+	</view>
18
+</template>
19
+
20
+<script>
21
+import { _bindPhone, _login, _getBindPhone } from '@/api/auth'
22
+import { mapGetters } from 'vuex'
23
+export default {
24
+  data() {
25
+    return {
26
+      key: '绑定手机号'
27
+    }
28
+  },
29
+  computed: {
30
+    ...mapGetters([
31
+      'token', 'session'
32
+    ])
33
+  },
34
+  methods: {
35
+    goto(type) {
36
+      this.globalNavigateTo('agreement', { type })
37
+    },
38
+    getPhoneNumber(e) {
39
+      const detail = e.detail
40
+      if (!detail.iv) {
41
+        return false
42
+      }
43
+      const _self = this
44
+      const params = {
45
+        iv: detail.iv,
46
+        encryptedData: detail.encryptedData,
47
+        token: this.token,
48
+        code: this.globalApp.code
49
+      }
50
+      uni.checkSession({
51
+        success() {
52
+          params.session = _self.session
53
+          _self.bindPhone(params)
54
+        },
55
+        fail() {
56
+          uni.login({
57
+            success: wxres => {
58
+              _login({ code: wxres.code }).then(res => {
59
+                params.session = res.data.session_key
60
+                _self.$store.dispatch('setSession', res.data.session_key)
61
+                _self.bindPhone(params)
62
+              })
63
+            }
64
+          })
65
+        }
66
+      })
67
+    },
68
+    bindPhone(params) {
69
+      _bindPhone(params).then(res => {
70
+        uni.showToast({ title: res.msg, icon: 'none' })
71
+        const token = res.data.token
72
+        this.$store.dispatch('setToken', token).then(res => {
73
+          this.getBindPhone()// 获取手机号
74
+          setTimeout(() => {
75
+            uni.navigateBack()
76
+          }, 800)
77
+        })
78
+      })
79
+    },
80
+    getBindPhone() {
81
+      _getBindPhone().then(res => {
82
+        this.$store.dispatch('setPhone', res.data.mobile)
83
+      })
84
+    }
85
+  }
86
+}
87
+</script>
88
+
89
+<style lang="scss" scoped>
90
+.bind{
91
+  padding:30px 44rpx 10px;
92
+}
93
+.bind-img{
94
+  margin:0 auto;
95
+  text-align:center;
96
+}
97
+.bind-text{
98
+    margin-top:20px;
99
+    color:#000;
100
+    font-size:18px;
101
+    text-align:center;
102
+}
103
+.bind-tip{
104
+  font-size:14px;
105
+}
106
+.bind-btn{
107
+  margin-top: 30px;
108
+  background: #5fd0e4;
109
+  border-radius:4px;
110
+  color: #fff;
111
+  width: 100%;
112
+  padding: 0;
113
+  font-size: 14px;
114
+  display: flex;
115
+  justify-content: center;
116
+  align-items: center;
117
+  height: 10vw;
118
+}
119
+.bind-btn:hover{
120
+  background: #3f8b97;
121
+}
122
+</style>

+ 173 - 176
src/pages/class/shoppingCart.vue

@@ -1,176 +1,173 @@
1
-<template>
2
-  <view class="page">
3
-		<cu-custom :isBack="true"></cu-custom>
4
-		<view class="header" :style="[{top:topHeader + 'px'}]">
5
-			<view class="header-title">
6
-				<view class="header-title-main">
7
-						<view class="margin-bottom-xs">{{title}}</view>
8
-						<view class="point"></view>
9
-				</view>
10
-			</view>
11
-		</view>
12
-			<scroll-view  scroll-y="true"
13
-			:style="[{height:'calc(100vh - 64px - '+ topHeader+'px)'}]"
14
-			class="scroll-main">
15
-				<view class="list">
16
-					<view class="cu-card margin-bottom shadow" v-for="(item,index) in list" :key="index">
17
-						<view class="cu-item">
18
-							<view class="card-header flex justify-between solid-bottom">
19
-								 <view>{{item.student_name}}</view>
20
-								 <view>
21
-									  <text class="cuIcon-delete text-red" @tap="del(item,index)"></text>
22
-								 </view>
23
-							</view>
24
-							<view class="card flex">
25
-								<view class="card-left">
26
-									<img mode="scaleToFill" :src="item.image" alt="" class="card-image">
27
-								</view>
28
-								<view class="card-right flex-sub margin-left-sm">
29
-									<view class="card-title">{{item.class_attend_name}}</view>
30
-									<view class="text-price text-student text-xl margin-top-xs">{{item.price}}</view>
31
-									<view class="card-item">
32
-										 <text class="card-label">机构:</text>
33
-										 <text class="card-text">{{item.agency_name||'-'}}</text>
34
-									</view>
35
-									<view class="card-item margin-top-xs" v-if="item.cate_type===0">
36
-										 <text class="card-label">老师:</text>
37
-										 <text class="card-text">{{item.teacher_name||'-'}}</text>
38
-									</view>
39
-									<view class="card-item margin-top-xs">
40
-										 <text class="card-label">总共:</text>
41
-										 <text class="card-text">{{item.class_total||'-'}}</text>
42
-									</view>
43
-									<view class="card-item margin-top-xs">
44
-										 <text class="card-label">时间:</text>
45
-										 <text class="card-text">{{item.week_limit||'-'}}</text>
46
-									</view>
47
-								</view>
48
-							</view>
49
-							<view class="card-footer margin-top-xs" v-if="item.prop">
50
-								<view v-for="(tag,index) in item.prop" :key="index" class="cu-tag line-red">{{tag}}</view>
51
-							</view>
52
-							<view class="card-bottom margin-top-xs">
53
-								<button @tap="pay(item)" class="cu-btn round bg-student text-white">立即下单</button>
54
-							</view>
55
-						</view>
56
-					</view>
57
-				</view>
58
-			</scroll-view>
59
-	</view>
60
-</template>
61
-
62
-<script>
63
-import { _shopList, _delShop, _createOrder } from '@/api/course'
64
-import { mapGetters } from 'vuex'
65
-import { deepClone } from '@/common/utils'
66
-import socket from '@/common/webSocket'
67
-export default {
68
-  data() {
69
-    return {
70
-      title: '购物车',
71
-      topHeader: this.globalCustomBarHeight,
72
-      isBind: false,
73
-      list: []
74
-    }
75
-  },
76
-  computed: {
77
-    ...mapGetters([
78
-      'carts'
79
-    ])
80
-  },
81
-  onLoad(option) {
82
-    this.get_list()
83
-    socket.initSocket()
84
-  },
85
-  methods: {
86
-    get_list() {
87
-      _shopList().then(res => {
88
-        this.isBind = res.isBindMobile
89
-        this.list = res.data
90
-        const carts = this.list.map(item => item.class_attend_id)
91
-        this.$store.dispatch('setCarts', carts)// 刷新购物车
92
-      })
93
-    },
94
-    del(item, index) {
95
-      const _self = this
96
-      uni.showModal({
97
-        title: '提示',
98
-        content: '确定要删除?',
99
-        cancelText: '取消',
100
-        confirmText: '确定',
101
-        success: res => {
102
-          if (res.confirm) {
103
-            _delShop({ shopping_id: item.shopping_id, student_id: item.student_id }).then(res => {
104
-              _self.get_list()
105
-            })
106
-          }
107
-        }
108
-      })
109
-    },
110
-    pay(item) {
111
-      const order = JSON.stringify([item])
112
-      let carts = deepClone(this.carts)
113
-      const index = carts.indexOf(item.class_attend_id)
114
-      carts = carts.splice(index, 1)
115
-      const isBind = this.isBind
116
-      if (!isBind) {
117
-        return this.globalNavigateTo('bindPhone')
118
-      }
119
-      _createOrder({ result: order }).then(res => {
120
-        this.socket.onMessage = message => {
121
-          if (typeof message !== 'object') {
122
-            return false
123
-          }
124
-          if (message.push_type !== 'order') {
125
-            return false
126
-          }
127
-          if (message.code === 400) {
128
-            uni.showToast({ title: message.msg, icon: 'none', duration: 2000 })
129
-            return false
130
-          }
131
-          this.$store.dispatch('setCarts', carts)
132
-          this.globalNavigateTo('order')
133
-        }
134
-      })
135
-    }
136
-  }
137
-}
138
-</script>
139
-
140
-<style lang="scss" scoped>
141
-@import '~@/common/css/mixin.scss';
142
-.scroll-main{
143
-	margin-top:64px;
144
-	padding:20rpx;
145
-}
146
-.cu-card{
147
-	.cu-item{
148
-		margin-top:10rpx;
149
-		padding:20rpx;
150
-		margin:0;
151
-	}
152
-}
153
-.card-header{
154
-	padding-bottom:10px;
155
-  @include title(10px,18px);
156
-}
157
-.card{
158
-	&-title{
159
-		font-size:16px;
160
-	}
161
-	&-image{
162
-		width:35vw;
163
-		height:35vw;
164
-		border-radius:10rpx;
165
-	}
166
-	&-label{
167
-		color:#999;
168
-	}
169
-	&-text{
170
-		color:#333;
171
-	}
172
-}
173
-.card-bottom{
174
-	text-align:right;
175
-}
176
-</style>
1
+<template>
2
+  <view class="page">
3
+		<cu-custom :isBack="true"></cu-custom>
4
+		<view class="header" :style="[{top:topHeader + 'px'}]">
5
+			<view class="header-title">
6
+				<view class="header-title-main">
7
+						<view class="margin-bottom-xs">{{title}}</view>
8
+						<view class="point"></view>
9
+				</view>
10
+			</view>
11
+		</view>
12
+			<scroll-view  scroll-y="true"
13
+			:style="[{height:'calc(100vh - 64px - '+ topHeader+'px)'}]"
14
+			class="scroll-main">
15
+				<view class="list">
16
+					<view class="cu-card margin-bottom shadow" v-for="(item,index) in list" :key="index">
17
+						<view class="cu-item">
18
+							<view class="card-header flex justify-between solid-bottom">
19
+								 <view>{{item.student_name}}</view>
20
+								 <view>
21
+									  <text class="cuIcon-delete text-red" @tap="del(item,index)"></text>
22
+								 </view>
23
+							</view>
24
+							<view class="card flex">
25
+								<view class="card-left">
26
+									<img mode="scaleToFill" :src="item.image" alt="" class="card-image">
27
+								</view>
28
+								<view class="card-right flex-sub margin-left-sm">
29
+									<view class="card-title">{{item.class_attend_name}}</view>
30
+									<view class="text-price text-student text-xl margin-top-xs">{{item.price}}</view>
31
+									<view class="card-item">
32
+										 <text class="card-label">机构:</text>
33
+										 <text class="card-text">{{item.agency_name||'-'}}</text>
34
+									</view>
35
+									<view class="card-item margin-top-xs" v-if="item.cate_type===0">
36
+										 <text class="card-label">老师:</text>
37
+										 <text class="card-text">{{item.teacher_name||'-'}}</text>
38
+									</view>
39
+									<view class="card-item margin-top-xs">
40
+										 <text class="card-label">总共:</text>
41
+										 <text class="card-text">{{item.class_total||'-'}}</text>
42
+									</view>
43
+									<view class="card-item margin-top-xs">
44
+										 <text class="card-label">时间:</text>
45
+										 <text class="card-text">{{item.week_limit||'-'}}</text>
46
+									</view>
47
+								</view>
48
+							</view>
49
+							<view class="card-footer margin-top-xs" v-if="item.prop">
50
+								<view v-for="(tag,index) in item.prop" :key="index" class="cu-tag line-red">{{tag}}</view>
51
+							</view>
52
+							<view class="card-bottom margin-top-xs">
53
+								<button @tap="pay(item)" class="cu-btn round bg-student text-white">立即下单</button>
54
+							</view>
55
+						</view>
56
+					</view>
57
+				</view>
58
+			</scroll-view>
59
+	</view>
60
+</template>
61
+
62
+<script>
63
+import { _shopList, _delShop, _createOrder } from '@/api/course'
64
+import { mapGetters } from 'vuex'
65
+import { deepClone } from '@/common/utils'
66
+import socket from '@/common/webSocket'
67
+export default {
68
+  data() {
69
+    return {
70
+      title: '购物车',
71
+      topHeader: this.globalCustomBarHeight,
72
+      list: []
73
+    }
74
+  },
75
+  computed: {
76
+    ...mapGetters([
77
+      'carts', 'phone'
78
+    ])
79
+  },
80
+  onLoad(option) {
81
+    this.get_list()
82
+    socket.initSocket()
83
+  },
84
+  methods: {
85
+    get_list() {
86
+      _shopList().then(res => {
87
+        this.list = res.data
88
+        const carts = this.list.map(item => item.class_attend_id)
89
+        this.$store.dispatch('setCarts', carts)// 刷新购物车
90
+      })
91
+    },
92
+    del(item, index) {
93
+      const _self = this
94
+      uni.showModal({
95
+        title: '提示',
96
+        content: '确定要删除?',
97
+        cancelText: '取消',
98
+        confirmText: '确定',
99
+        success: res => {
100
+          if (res.confirm) {
101
+            _delShop({ shopping_id: item.shopping_id, student_id: item.student_id }).then(res => {
102
+              _self.get_list()
103
+            })
104
+          }
105
+        }
106
+      })
107
+    },
108
+    pay(item) {
109
+      const order = JSON.stringify([item])
110
+      let carts = deepClone(this.carts)
111
+      const index = carts.indexOf(item.class_attend_id)
112
+      carts = carts.splice(index, 1)
113
+      if (!this.phone) {
114
+        return this.globalNavigateTo('bindPhone')
115
+      }
116
+      _createOrder({ result: order }).then(res => {
117
+        this.socket.onMessage = message => {
118
+          if (typeof message !== 'object') {
119
+            return false
120
+          }
121
+          if (message.push_type !== 'order') {
122
+            return false
123
+          }
124
+          if (message.code === 400) {
125
+            uni.showToast({ title: message.msg, icon: 'none', duration: 2000 })
126
+            return false
127
+          }
128
+          this.$store.dispatch('setCarts', carts)
129
+          this.globalNavigateTo('order')
130
+        }
131
+      })
132
+    }
133
+  }
134
+}
135
+</script>
136
+
137
+<style lang="scss" scoped>
138
+@import '~@/common/css/mixin.scss';
139
+.scroll-main{
140
+	margin-top:64px;
141
+	padding:20rpx;
142
+}
143
+.cu-card{
144
+	.cu-item{
145
+		margin-top:10rpx;
146
+		padding:20rpx;
147
+		margin:0;
148
+	}
149
+}
150
+.card-header{
151
+	padding-bottom:10px;
152
+  @include title(10px,18px);
153
+}
154
+.card{
155
+	&-title{
156
+		font-size:16px;
157
+	}
158
+	&-image{
159
+		width:35vw;
160
+		height:35vw;
161
+		border-radius:10rpx;
162
+	}
163
+	&-label{
164
+		color:#999;
165
+	}
166
+	&-text{
167
+		color:#333;
168
+	}
169
+}
170
+.card-bottom{
171
+	text-align:right;
172
+}
173
+</style>

+ 411 - 411
src/pages/index/index.vue

@@ -1,411 +1,411 @@
1
-
2
-<template>
3
-  <view class="page">
4
-    <cu-custom :isBack="false"></cu-custom>
5
-    <view class="header" :style="[{top:topHeader + 'px'}]">
6
-			 <view class="header-box flex justify-end">
7
-						<view class="header-title">
8
-							<view class="header-title-main">
9
-									<view class="margin-bottom-xs">选课</view>
10
-									<view class="point"></view>
11
-							</view>
12
-						</view>
13
-						<view class="header-search flex-sub">
14
-							 <view class="flex justify-between">
15
-								 	<input type="text" v-model="params.course_name" class="header-search-input flex-sub" placeholder="搜索课程" @confirm="search">
16
-							 		<text class="cuIcon-search text-gray header-search-icon" @tap="search"></text>
17
-							 </view>
18
-						</view>
19
-			 </view>
20
-		</view>
21
-		<scroll-view :scroll-y="true" :refresher-enabled="true" class="scroll-main"
22
-		:refresher-triggered="triggered"
23
-		:style="[{height:'calc(100vh - 102px - '+ topHeader+'px)'}]"
24
-		@refresherrefresh="onRefresh" @scrolltolower="loadMore">
25
-			<view class="main">
26
-				<view class="main-title">活动和餐饮</view>
27
-				<view class="flex justify-around course">
28
-					<course v-for="(item,index) in courses" :key="index"
29
-					@tap="goCourse(item.type)"
30
-					:course="item" class="course-item flex-sub margin-xs"></course>
31
-				</view>
32
-				<view class="main-title margin-top-xs">一键报班</view>
33
-				<view class="apply-class flex">
34
-					<image mode="widthFix"  @tap="goGift" src="/static/imgs/index/baoban.png" class="flex-sub apply-class-img margin-xs"/>
35
-				</view>
36
-				<view class="recommend margin-top-xs">
37
-					<view class="recommend-title">推荐课程</view>
38
-					<view class="recommend-filter margin-top-xs flex">
39
-							<view class="filter-item text-center flex-sub" @tap="sort('home')" :class="{'text-sort':sortCur==='home'}">综合</view>
40
-							<view class="filter-item text-center flex-sub" @tap="sort('sales')" :class="{'text-sort':sortCur==='sales'}">销量
41
-								<image mode="widthFix" class="sort-icon" :src="sortCur==='sales'?(sortItem.sales===0?sortIcons.up:sortIcons.down):sortIcons.no"></image>
42
-							</view>
43
-							<view class="filter-item text-center flex-sub" @tap="sort('money')" :class="{'text-sort':sortCur==='money'}">价格
44
-								<image mode="widthFix" class="sort-icon" :src="sortCur==='money'?(sortItem.money===0?sortIcons.up:sortIcons.down):sortIcons.no"></image>
45
-							</view>
46
-							<view class="filter-item text-center flex-sub">{{grade_now}}</view>
47
-							<view class="filter-item text-right flex-sub" @tap="showModal" data-target="FilterModal">筛选
48
-								<text class="cuIcon-filter text-gray"></text>
49
-							</view>
50
-					</view>
51
-					<view class="list">
52
-							<view class="cu-card" v-for="(item,index) in list" :key="index">
53
-								<view class="cu-item">
54
-									<card :item="item"></card>
55
-								</view>
56
-							</view>
57
-					</view>
58
-				</view>
59
-			</view>
60
-		</scroll-view>
61
-    <view class="cu-modal drawer-modal justify-end" :class="modalName=='FilterModal'?'show':''" @tap="hideModal">
62
-      <view class="cu-dialog basis-lg" @tap.stop=""
63
-        :style="[{top:topHeader+'px',height:'calc(100vh - ' + topHeader + 'px)'}]">
64
-					<view class="filter-title">机构筛选</view>
65
-				  <view class="btn-check-group padding-lr">
66
-						<checkbox-group @change="checkboxChange" class="flex" style="flex-wrap: wrap;" id="agency">
67
-							<label class="btn-check-label margin-top-sm padding-lr-xs text-sm text-ellipsis" :class="{'bg-cyan':params.agency.includes(item.id+'')}"
68
-								v-for="item in filters.agency" :key="item.id">
69
-								<checkbox :value="item.id"/>
70
-								{{item.name}}
71
-							</label>
72
-						</checkbox-group>
73
-        	</view>
74
-					<view class="filter-title">周期筛选</view>
75
-					<view class="btn-check-group padding-lr">
76
-						<checkbox-group @change="checkboxChange" class="flex" style="flex-wrap: wrap;" id="day">
77
-							<label class="btn-check-label margin-top-sm padding-lr-xs text-sm" :class="{'bg-cyan':params.day.includes(index+'')}"
78
-								v-for="(item,index) in filters.week" :key="index">
79
-								<checkbox :value="index"/>
80
-								{{item}}
81
-							</label>
82
-						</checkbox-group>
83
-        	</view>
84
-					<view class="filter-title">价格区间(元)</view>
85
-					<view class="btn-check-group padding-lr">
86
-						<radio-group  class="flex" style="flex-wrap: wrap;" id="price">
87
-							<label class="btn-check-label margin-top-sm padding-lr-xs text-sm" :class="{'bg-cyan':params.price===item.name}"
88
-								 v-for="item in filters.price_list" :key="item.id" @tap="radioChange(item.name)">
89
-								<radio :value="item.name"/>
90
-								{{item.name}}
91
-							</label>
92
-						</radio-group>
93
-        	</view>
94
-					<view class="padding-lr">
95
-							<button class="check-course cu-btn bg-cyan margin-tb-sm button-hover" @tap="check_course">确定</button>
96
-					</view>
97
-      </view>
98
-    </view>
99
-    <mp-tabbar :outerSelected="0" />
100
-  </view>
101
-</template>
102
-
103
-<script>
104
-import course from './components/course.vue'
105
-import card from './components/card.vue'
106
-import { _optionCourse, _filter } from '@/api/course'
107
-import { filterParams } from '@/common/utils/tool'
108
-import { mapGetters } from 'vuex'
109
-export default {
110
-  components: {
111
-    course, card
112
-  },
113
-  data () {
114
-    return {
115
-      topHeader: this.globalCustomBarHeight,
116
-      modalName: '',
117
-      triggered: false,
118
-      grade_now: '年级',
119
-      sortCur: 'home', // 当前排序
120
-      filters: {},
121
-      sortIcons: {
122
-        no: '/static/imgs/index/xiaoshou_shaixuan.png',
123
-        up: '/static/imgs/index/xiaoshou_shaixuan1.png',
124
-        down: '/static/imgs/index/xiaoshou_shaixuan2.png'
125
-      },
126
-      sortItem: {
127
-        home: 0,
128
-        sales: 0,
129
-        money: 0
130
-      },
131
-      courses: [// 排序情况
132
-        {
133
-          applying: true,
134
-          back: '/static/imgs/index/zmk.png',
135
-          background: '#5FCFE0',
136
-          ch: '选课',
137
-          en: 'Course',
138
-          type: 0
139
-        },
140
-        {
141
-          applying: true,
142
-          back: '/static/imgs/index/hdk.png',
143
-          background: '#f8be32',
144
-          ch: '活动',
145
-          en: 'Activity',
146
-          type: 2
147
-        },
148
-        {
149
-          applying: false,
150
-          back: '/static/imgs/index/zmk.png',
151
-          background: '#67d2a9',
152
-          ch: '报餐',
153
-          en: 'Catering',
154
-          type: 1
155
-        }
156
-      ],
157
-      price: [],
158
-      params: {
159
-        page_num: 1,
160
-        course_name: '',
161
-        agency: [],
162
-        day: [],
163
-        price: '',
164
-        sort: '',
165
-        list_type: 0// 0 课程,1 餐饮,2活动
166
-      },
167
-      init: { // 初始化
168
-        page_num: 1,
169
-        course_name: '',
170
-        agency: [],
171
-        day: [],
172
-        price: '',
173
-        sort: '',
174
-        list_type: 0// 0 课程,1 餐饮,2活动
175
-      },
176
-      list: [],
177
-      noMore: false, // 还有没
178
-      originList: {}
179
-    }
180
-  },
181
-  computed: {
182
-    ...mapGetters([
183
-      'kid'
184
-    ])
185
-  },
186
-  onShow() {
187
-    if (!this.kid) {
188
-      return this.globalNavigateTo('myStudents')
189
-    }
190
-    this.params = Object.assign({}, this.init)
191
-    this.get_list(true)// true初始化加载过滤项
192
-  },
193
-  methods: {
194
-    goCourse(type) {
195
-      this.params.list_type = type
196
-      this.search()
197
-    },
198
-    loadFilter() { // 加载筛选项
199
-      const params = {}
200
-      _filter(params).then(res => {
201
-        this.filters = res.data
202
-        this.courses[1].applying = this.filters.is_activity
203
-        this.courses[2].applying = this.filters.is_catering
204
-      })
205
-    },
206
-    showModal (e) {
207
-      this.modalName = e.currentTarget.dataset.target
208
-    },
209
-    hideModal (e) {
210
-      this.modalName = null
211
-    },
212
-    radioChange(v) {
213
-      if (this.params.price === v) { // 选中取消
214
-        this.params.price = null
215
-      } else { // 空则赋值
216
-        this.params.price = v
217
-      }
218
-    },
219
-    checkboxChange(e) {
220
-      const type = e.target.id
221
-      const values = e.detail.value
222
-      switch (type) {
223
-        case 'agency':
224
-          this.params.agency = values
225
-          break
226
-        case 'day':
227
-          this.params.day = values
228
-          break
229
-        case 'price':
230
-          // this.params.price = values
231
-          break
232
-        default:
233
-          console.log('error')
234
-      }
235
-    },
236
-    search() { // 搜索课程
237
-      this.params.page_num = 1
238
-      this.get_list()
239
-    },
240
-    check_course() { // 筛选课程
241
-      this.params.page_num = 1
242
-      this.get_list()
243
-      this.hideModal()
244
-    },
245
-    onRefresh() { // 下拉刷新
246
-      this.triggered = true
247
-      this.params.page_num = 1
248
-      this.params.list_type = 0
249
-      this.get_list()
250
-      setTimeout(() => {
251
-        this.triggered = false
252
-      }, 1000)
253
-    },
254
-    loadMore() {
255
-      if (this.noMore) {
256
-        uni.showToast({ title: '暂无更多课程数据', icon: 'none' })
257
-        return false
258
-      }
259
-      this.params.page_num++
260
-      this.get_list()
261
-    },
262
-    sort(type) { // 排序搜索
263
-      const sorts = {
264
-        home: 0,
265
-        sales: 0,
266
-        money: 0
267
-      }
268
-      if (type === this.sortCur) {
269
-        const sortOrder = this.sortItem[type]
270
-        sorts[type] = sortOrder > 0 ? 0 : 1
271
-      } else {
272
-        this.sortCur = type
273
-      }
274
-      const order = sorts[type] > 0 ? 'desc' : 'asc'
275
-      this.sortItem = sorts
276
-      this.params.sort = type + '_' + order
277
-      this.params.page_num = 1
278
-      this.get_list()
279
-    },
280
-    get_list(init = false) {
281
-      let params = Object.assign({}, this.params)
282
-      params = filterParams(params)
283
-      if (params.day.length > 0) {
284
-        params.day = JSON.stringify(params.day)
285
-      }
286
-      if (params.agency.length > 0) {
287
-        params.agency = JSON.stringify(params.agency)
288
-      }
289
-      _optionCourse(params).then(res => {
290
-        if (params.page_num > 1) {
291
-          if (res.data.length < this.page_size) this.noMore = true
292
-          this.list = this.list.concat(res.data)
293
-        } else {
294
-          this.noMore = false
295
-          this.list = res.data
296
-          if (this.list && this.list.length > 0) {
297
-            this.grade_now = this.list[0].grade_now
298
-          }
299
-        }
300
-        // 初始化加载过滤项
301
-        if (init) this.loadFilter()
302
-      })
303
-    },
304
-    goGift() {
305
-      this.globalNavigateTo('classGift', { package_id: 0 })
306
-    }
307
-  }
308
-}
309
-</script>
310
-
311
-<style lang="scss">
312
-@import '~@/common/css/mixin.scss';
313
-.page{
314
- height:100vh;
315
-}
316
-.scroll-main{
317
-	margin-top:54px;
318
-}
319
-.header{
320
-	position:fixed;
321
-	height:54px;
322
-	left:0;
323
-	right:0;
324
-	z-index:999;
325
-	padding:20rpx;
326
-	background:#fff;
327
-	&-box{
328
-		align-items: center;
329
-	}
330
-	&-search{
331
-		margin-left:60rpx;
332
-		align-items: center;
333
-		&-input{
334
-			background: #ededed;
335
-    	border-radius: 999em;
336
-			padding-left:30rpx;
337
-      line-height:32px;
338
-			height:32px;
339
-    	font-size: 14px;
340
-		}
341
-		&-icon{
342
-			margin:0 30rpx;
343
-			line-height:32px;
344
-			font-size:24px;
345
-		}
346
-	}
347
-}
348
-.main{
349
-	padding:20rpx;
350
-
351
-}
352
-.main-title{
353
-  font-size: 12px;
354
-  margin-bottom: 10px;
355
-  color: #999;
356
-}
357
-.search-box{
358
-	margin-left:20rpx;
359
-}
360
-.course-item{
361
-  border-radius: 10px;
362
-  color: #fff;
363
-}
364
-.recommend{
365
-	&-title{
366
-		@include title(10px,18px);
367
-	}
368
-	&-filter{
369
-		.filter-item{
370
-			position:relative;
371
-		}
372
-	}
373
-	.sort-icon{
374
-		margin-left:6rpx;
375
-		width:15rpx;
376
-	}
377
-}
378
-.btn-check-group {
379
-  checkbox {
380
-    display: none;
381
-  }
382
-	radio{
383
-		display:none;
384
-	}
385
-  label {
386
-    display: inline-block;
387
-		margin-right:10rpx;
388
-    position: relative;
389
-		padding:0 20rpx;
390
-    line-height: 30px;
391
-    border-radius: 100rpx;
392
-    flex-wrap: nowrap;
393
-    border: 1px solid #eee;
394
-  }
395
-}
396
-.filter-title{
397
-	padding-left:30rpx;
398
-	margin-top:10px;
399
-	text-align:left;
400
-	@include title(0,14px)
401
-}
402
-.check-course{
403
-	width:100%;
404
-}
405
-.cu-modal.drawer-modal .cu-dialog{
406
-	min-width:300rpx;
407
-}
408
-.cu-card>.cu-item{
409
-	margin:10rpx;
410
-}
411
-</style>
1
+
2
+<template>
3
+  <view class="page">
4
+    <cu-custom :isBack="false"></cu-custom>
5
+    <view class="header" :style="[{top:topHeader + 'px'}]">
6
+			 <view class="header-box flex justify-end">
7
+						<view class="header-title">
8
+							<view class="header-title-main">
9
+									<view class="margin-bottom-xs">选课</view>
10
+									<view class="point"></view>
11
+							</view>
12
+						</view>
13
+						<view class="header-search flex-sub">
14
+							 <view class="flex justify-between">
15
+								 	<input type="text" v-model="params.course_name" class="header-search-input flex-sub" placeholder="搜索课程" @confirm="search">
16
+							 		<text class="cuIcon-search text-gray header-search-icon" @tap="search"></text>
17
+							 </view>
18
+						</view>
19
+			 </view>
20
+		</view>
21
+		<scroll-view :scroll-y="true" :refresher-enabled="true" class="scroll-main"
22
+		:refresher-triggered="triggered"
23
+		:style="[{height:'calc(100vh - 102px - '+ topHeader+'px)'}]"
24
+		@refresherrefresh="onRefresh" @scrolltolower="loadMore">
25
+			<view class="main">
26
+				<view class="main-title">活动和餐饮</view>
27
+				<view class="flex justify-around course">
28
+					<course v-for="(item,index) in courses" :key="index"
29
+					@tap="goCourse(item.type)"
30
+					:course="item" class="course-item flex-sub margin-xs"></course>
31
+				</view>
32
+				<view class="main-title margin-top-xs">一键报班</view>
33
+				<view class="apply-class flex">
34
+					<image mode="widthFix"  @tap="goGift" src="/static/imgs/index/baoban.png" class="flex-sub apply-class-img margin-xs"/>
35
+				</view>
36
+				<view class="recommend margin-top-xs">
37
+					<view class="recommend-title">推荐课程</view>
38
+					<view class="recommend-filter margin-top-xs flex">
39
+							<view class="filter-item text-center flex-sub" @tap="sort('home')" :class="{'text-sort':sortCur==='home'}">综合</view>
40
+							<view class="filter-item text-center flex-sub" @tap="sort('sales')" :class="{'text-sort':sortCur==='sales'}">销量
41
+								<image mode="widthFix" class="sort-icon" :src="sortCur==='sales'?(sortItem.sales===0?sortIcons.up:sortIcons.down):sortIcons.no"></image>
42
+							</view>
43
+							<view class="filter-item text-center flex-sub" @tap="sort('money')" :class="{'text-sort':sortCur==='money'}">价格
44
+								<image mode="widthFix" class="sort-icon" :src="sortCur==='money'?(sortItem.money===0?sortIcons.up:sortIcons.down):sortIcons.no"></image>
45
+							</view>
46
+							<view class="filter-item text-center flex-sub">{{grade_now}}</view>
47
+							<view class="filter-item text-right flex-sub" @tap="showModal" data-target="FilterModal">筛选
48
+								<text class="cuIcon-filter text-gray"></text>
49
+							</view>
50
+					</view>
51
+					<view class="list">
52
+							<view class="cu-card" v-for="(item,index) in list" :key="index">
53
+								<view class="cu-item">
54
+									<card :item="item"></card>
55
+								</view>
56
+							</view>
57
+					</view>
58
+				</view>
59
+			</view>
60
+		</scroll-view>
61
+    <view class="cu-modal drawer-modal justify-end" :class="modalName=='FilterModal'?'show':''" @tap="hideModal">
62
+      <view class="cu-dialog basis-lg" @tap.stop=""
63
+        :style="[{top:topHeader+'px',height:'calc(100vh - ' + topHeader + 'px)'}]">
64
+					<view class="filter-title">机构筛选</view>
65
+				  <view class="btn-check-group padding-lr">
66
+						<checkbox-group @change="checkboxChange" class="flex" style="flex-wrap: wrap;" id="agency">
67
+							<label class="btn-check-label margin-top-sm padding-lr-xs text-sm text-ellipsis" :class="{'bg-cyan':params.agency.includes(item.id+'')}"
68
+								v-for="item in filters.agency" :key="item.id">
69
+								<checkbox :value="item.id"/>
70
+								{{item.name}}
71
+							</label>
72
+						</checkbox-group>
73
+        	</view>
74
+					<view class="filter-title">周期筛选</view>
75
+					<view class="btn-check-group padding-lr">
76
+						<checkbox-group @change="checkboxChange" class="flex" style="flex-wrap: wrap;" id="day">
77
+							<label class="btn-check-label margin-top-sm padding-lr-xs text-sm" :class="{'bg-cyan':params.day.includes(index+'')}"
78
+								v-for="(item,index) in filters.week" :key="index">
79
+								<checkbox :value="index"/>
80
+								{{item}}
81
+							</label>
82
+						</checkbox-group>
83
+        	</view>
84
+					<view class="filter-title">价格区间(元)</view>
85
+					<view class="btn-check-group padding-lr">
86
+						<radio-group  class="flex" style="flex-wrap: wrap;" id="price">
87
+							<label class="btn-check-label margin-top-sm padding-lr-xs text-sm" :class="{'bg-cyan':params.price===item.name}"
88
+								 v-for="item in filters.price_list" :key="item.id" @tap="radioChange(item.name)">
89
+								<radio :value="item.name"/>
90
+								{{item.name}}
91
+							</label>
92
+						</radio-group>
93
+        	</view>
94
+					<view class="padding-lr">
95
+							<button class="check-course cu-btn bg-cyan margin-tb-sm button-hover" @tap="check_course">确定</button>
96
+					</view>
97
+      </view>
98
+    </view>
99
+    <mp-tabbar :outerSelected="0" />
100
+  </view>
101
+</template>
102
+
103
+<script>
104
+import course from './components/course.vue'
105
+import card from './components/card.vue'
106
+import { _optionCourse, _filter } from '@/api/course'
107
+import { filterParams } from '@/common/utils/tool'
108
+import { mapGetters } from 'vuex'
109
+export default {
110
+  components: {
111
+    course, card
112
+  },
113
+  data () {
114
+    return {
115
+      topHeader: this.globalCustomBarHeight,
116
+      modalName: '',
117
+      triggered: false,
118
+      grade_now: '年级',
119
+      sortCur: 'home', // 当前排序
120
+      filters: {},
121
+      sortIcons: {
122
+        no: '/static/imgs/index/xiaoshou_shaixuan.png',
123
+        up: '/static/imgs/index/xiaoshou_shaixuan1.png',
124
+        down: '/static/imgs/index/xiaoshou_shaixuan2.png'
125
+      },
126
+      sortItem: {
127
+        home: 0,
128
+        sales: 0,
129
+        money: 0
130
+      },
131
+      courses: [// 排序情况
132
+        {
133
+          applying: true,
134
+          back: '/static/imgs/index/zmk.png',
135
+          background: '#5FCFE0',
136
+          ch: '选课',
137
+          en: 'Course',
138
+          type: 0
139
+        },
140
+        {
141
+          applying: true,
142
+          back: '/static/imgs/index/hdk.png',
143
+          background: '#f8be32',
144
+          ch: '活动',
145
+          en: 'Activity',
146
+          type: 2
147
+        },
148
+        {
149
+          applying: false,
150
+          back: '/static/imgs/index/zmk.png',
151
+          background: '#67d2a9',
152
+          ch: '报餐',
153
+          en: 'Catering',
154
+          type: 1
155
+        }
156
+      ],
157
+      price: [],
158
+      params: {
159
+        page_num: 1,
160
+        course_name: '',
161
+        agency: [],
162
+        day: [],
163
+        price: '',
164
+        sort: '',
165
+        list_type: 0// 0 课程,1 餐饮,2活动
166
+      },
167
+      init: { // 初始化
168
+        page_num: 1,
169
+        course_name: '',
170
+        agency: [],
171
+        day: [],
172
+        price: '',
173
+        sort: '',
174
+        list_type: 0// 0 课程,1 餐饮,2活动
175
+      },
176
+      list: [],
177
+      noMore: false, // 还有没
178
+      originList: {}
179
+    }
180
+  },
181
+  computed: {
182
+    ...mapGetters([
183
+      'kid'
184
+    ])
185
+  },
186
+  onShow() {
187
+    if (!this.kid) {
188
+      return this.globalNavigateTo('myStudents')
189
+    }
190
+    this.params = Object.assign({}, this.init)
191
+    this.get_list(true)// true初始化加载过滤项
192
+  },
193
+  methods: {
194
+    goCourse(type) {
195
+      this.params.list_type = type
196
+      this.search()
197
+    },
198
+    loadFilter() { // 加载筛选项
199
+      const params = {}
200
+      _filter(params).then(res => {
201
+        this.filters = res.data
202
+        this.courses[1].applying = this.filters.is_activity
203
+        this.courses[2].applying = this.filters.is_catering
204
+      })
205
+    },
206
+    showModal (e) {
207
+      this.modalName = e.currentTarget.dataset.target
208
+    },
209
+    hideModal (e) {
210
+      this.modalName = null
211
+    },
212
+    radioChange(v) {
213
+      if (this.params.price === v) { // 选中取消
214
+        this.params.price = null
215
+      } else { // 空则赋值
216
+        this.params.price = v
217
+      }
218
+    },
219
+    checkboxChange(e) {
220
+      const type = e.target.id
221
+      const values = e.detail.value
222
+      switch (type) {
223
+        case 'agency':
224
+          this.params.agency = values
225
+          break
226
+        case 'day':
227
+          this.params.day = values
228
+          break
229
+        case 'price':
230
+          // this.params.price = values
231
+          break
232
+        default:
233
+          console.log('error')
234
+      }
235
+    },
236
+    search() { // 搜索课程
237
+      this.params.page_num = 1
238
+      this.get_list()
239
+    },
240
+    check_course() { // 筛选课程
241
+      this.params.page_num = 1
242
+      this.get_list()
243
+      this.hideModal()
244
+    },
245
+    onRefresh() { // 下拉刷新
246
+      this.triggered = true
247
+      this.params.page_num = 1
248
+      this.params.list_type = 0
249
+      this.get_list()
250
+      setTimeout(() => {
251
+        this.triggered = false
252
+      }, 1000)
253
+    },
254
+    loadMore() {
255
+      if (this.noMore) {
256
+        uni.showToast({ title: '暂无更多课程数据', icon: 'none' })
257
+        return false
258
+      }
259
+      this.params.page_num++
260
+      this.get_list()
261
+    },
262
+    sort(type) { // 排序搜索
263
+      const sorts = {
264
+        home: 0,
265
+        sales: 0,
266
+        money: 0
267
+      }
268
+      if (type === this.sortCur) {
269
+        const sortOrder = this.sortItem[type]
270
+        sorts[type] = sortOrder > 0 ? 0 : 1
271
+      } else {
272
+        this.sortCur = type
273
+      }
274
+      const order = sorts[type] > 0 ? 'desc' : 'asc'
275
+      this.sortItem = sorts
276
+      this.params.sort = type + '_' + order
277
+      this.params.page_num = 1
278
+      this.get_list()
279
+    },
280
+    get_list(init = false) {
281
+      let params = Object.assign({}, this.params)
282
+      params = filterParams(params)
283
+      if (params.day.length > 0) {
284
+        params.day = JSON.stringify(params.day)
285
+      }
286
+      if (params.agency.length > 0) {
287
+        params.agency = JSON.stringify(params.agency)
288
+      }
289
+      _optionCourse(params).then(res => {
290
+        if (params.page_num > 1) {
291
+          if (res.data.length < this.page_size) this.noMore = true
292
+          this.list = this.list.concat(res.data)
293
+        } else {
294
+          this.noMore = false
295
+          this.list = res.data
296
+          if (this.list && this.list.length > 0) {
297
+            this.grade_now = this.list[0].grade_now
298
+          }
299
+        }
300
+        // 初始化加载过滤项
301
+        if (init) this.loadFilter()
302
+      })
303
+    },
304
+    goGift() {
305
+      this.globalNavigateTo('classGift', { package_id: 0 })
306
+    }
307
+  }
308
+}
309
+</script>
310
+
311
+<style lang="scss">
312
+@import '~@/common/css/mixin.scss';
313
+.page{
314
+ height:100vh;
315
+}
316
+.scroll-main{
317
+	margin-top:54px;
318
+}
319
+.header{
320
+	position:fixed;
321
+	height:54px;
322
+	left:0;
323
+	right:0;
324
+	z-index:999;
325
+	padding:20rpx;
326
+	background:#fff;
327
+	&-box{
328
+		align-items: center;
329
+	}
330
+	&-search{
331
+		margin-left:60rpx;
332
+		align-items: center;
333
+		&-input{
334
+			background: #ededed;
335
+    	border-radius: 999em;
336
+			padding-left:30rpx;
337
+      line-height:32px;
338
+			height:32px;
339
+    	font-size: 14px;
340
+		}
341
+		&-icon{
342
+			margin:0 30rpx;
343
+			line-height:32px;
344
+			font-size:24px;
345
+		}
346
+	}
347
+}
348
+.main{
349
+	padding:20rpx;
350
+
351
+}
352
+.main-title{
353
+  font-size: 12px;
354
+  margin-bottom: 10px;
355
+  color: #999;
356
+}
357
+.search-box{
358
+	margin-left:20rpx;
359
+}
360
+.course-item{
361
+  border-radius: 10px;
362
+  color: #fff;
363
+}
364
+.recommend{
365
+	&-title{
366
+		@include title(10px,18px);
367
+	}
368
+	&-filter{
369
+		.filter-item{
370
+			position:relative;
371
+		}
372
+	}
373
+	.sort-icon{
374
+		margin-left:6rpx;
375
+		width:15rpx;
376
+	}
377
+}
378
+.btn-check-group {
379
+  checkbox {
380
+    display: none;
381
+  }
382
+	radio{
383
+		display:none;
384
+	}
385
+  label {
386
+    display: inline-block;
387
+		margin-right:10rpx;
388
+    position: relative;
389
+		padding:0 20rpx;
390
+    line-height: 30px;
391
+    border-radius: 100rpx;
392
+    flex-wrap: nowrap;
393
+    border: 1px solid #eee;
394
+  }
395
+}
396
+.filter-title{
397
+	padding-left:30rpx;
398
+	margin-top:10px;
399
+	text-align:left;
400
+	@include title(0,14px)
401
+}
402
+.check-course{
403
+	width:100%;
404
+}
405
+.cu-modal.drawer-modal .cu-dialog{
406
+	min-width:300rpx;
407
+}
408
+.cu-card>.cu-item{
409
+	margin:10rpx;
410
+}
411
+</style>

+ 121 - 121
src/pages/login/index.vue

@@ -1,121 +1,121 @@
1
-<template>
2
-	<view class="page">
3
-		<cu-custom :isBack="false" :isHome="true">
4
-		</cu-custom>
5
-		<view class="main">
6
-			<image src="/static/imgs/login.png" class="logo"></image>
7
-			<view class="title">课后百科</view>
8
-			<view class="action margin-top-xl">
9
-						<view class="des margin-top">您尚未登录需要获取您的授权后进入</view>
10
-			      <button class="cu-btn block round bg-grey lg margin-top" @tap="back">暂不登录</button>
11
-			      <button class="cu-btn block round bg-cyan lg margin-top" @tap="login">立即登录</button>
12
-			</view>
13
-			<view class="agreement margin-top-lg">
14
-				<checkbox-group @change="agreement=!agreement" style="display:inline-block;">
15
-					<label>
16
-							<checkbox class="cyan check-agreement"></checkbox>
17
-							<text class="text">阅读并同意以下条款</text>
18
-					</label>
19
-        </checkbox-group>
20
-				<text class="text-cyan"  @tap="goto('user')">《用户协议》</text>
21
-				<text class="text-cyan" @tap="goto('privacy')">《隐私政策》</text>
22
-			</view>
23
-		</view>
24
-	</view>
25
-</template>
26
-
27
-<script>
28
-import { _login, _auth } from '@/api/auth'
29
-import socket from '@/common/webSocket'
30
-export default {
31
-  data() {
32
-    return {
33
-      agreement: false,
34
-      wxCode: ''
35
-    }
36
-  },
37
-  onLoad(options) {
38
-    uni.login({
39
-      success: wxres => {
40
-        this.wxCode = wxres.code
41
-      }
42
-    })
43
-  },
44
-  methods: {
45
-    back() {
46
-      uni.navigateBack({
47
-        delta: 0
48
-      })
49
-    },
50
-    goto(type) {
51
-      this.globalNavigateTo('agreement', { type })
52
-    },
53
-    login() {
54
-      if (!this.agreement) {
55
-        uni.showToast({ title: '请先阅读并勾选协议', icon: 'none' })
56
-        return
57
-      }
58
-      uni.getUserProfile({
59
-        desc: '用于完善会员资料',
60
-        success: res => {
61
-          this.$store.dispatch('setUser', res.userInfo)
62
-          this.flashToken(res)
63
-        }
64
-      })
65
-    },
66
-    flashToken(wxConfig) {
67
-      _login({ code: this.wxCode }).then(res => {
68
-        const { openid, session_key: session } = res.data
69
-        this.$store.dispatch('setSession', session)
70
-        const params = {
71
-          session: session,
72
-          iv: wxConfig.iv,
73
-          encryptedData: wxConfig.encryptedData,
74
-          openid: openid,
75
-          code: this.globalApp.code
76
-        }
77
-        _auth(params).then(rs => {
78
-          this.$store.dispatch('setToken', rs.data.token).then(res => {
79
-            socket.initSocket()
80
-            this.globalReLaunch('index')
81
-          })
82
-        })
83
-      })
84
-    },
85
-    getUserProfile(v) {
86
-      console.log(v)
87
-    },
88
-    getAgreement() {
89
-
90
-    }
91
-  }
92
-}
93
-</script>
94
-
95
-<style lang="scss" scoped>
96
-@import '~@/common/css/mixin.scss';
97
-.page{
98
-	background-color:#fff;
99
-}
100
-.main{
101
-	padding-top:50px;
102
-	text-align:center;
103
-}
104
-.title {
105
-	margin:12px auto;
106
-  @include title(32px, 20px);
107
-	width:80px;
108
-	border-bottom:4px solid #00d2e330;
109
-}
110
-.logo{
111
-	width:100px;
112
-	height:100px;
113
-}
114
-.action{
115
-	margin:0 auto;
116
-	width:80%;
117
-}
118
-.check-agreement{
119
-	transform: scale(0.7);
120
-}
121
-</style>
1
+<template>
2
+	<view class="page">
3
+		<cu-custom :isBack="false" :isHome="true">
4
+		</cu-custom>
5
+		<view class="main">
6
+			<image src="/static/imgs/login.png" class="logo"></image>
7
+			<view class="title">课后百科</view>
8
+			<view class="action margin-top-xl">
9
+						<view class="des margin-top">您尚未登录需要获取您的授权后进入</view>
10
+			      <button class="cu-btn block round bg-grey lg margin-top" @tap="back">暂不登录</button>
11
+			      <button class="cu-btn block round bg-cyan lg margin-top" @tap="login">立即登录</button>
12
+			</view>
13
+			<view class="agreement margin-top-lg">
14
+				<checkbox-group @change="agreement=!agreement" style="display:inline-block;">
15
+					<label>
16
+							<checkbox class="cyan check-agreement"></checkbox>
17
+							<text class="text">阅读并同意以下条款</text>
18
+					</label>
19
+        </checkbox-group>
20
+				<text class="text-cyan"  @tap="goto('user')">《用户协议》</text>
21
+				<text class="text-cyan" @tap="goto('privacy')">《隐私政策》</text>
22
+			</view>
23
+		</view>
24
+	</view>
25
+</template>
26
+
27
+<script>
28
+import { _login, _auth, _getBindPhone } from '@/api/auth'
29
+import socket from '@/common/webSocket'
30
+export default {
31
+  data() {
32
+    return {
33
+      agreement: false,
34
+      wxCode: ''
35
+    }
36
+  },
37
+  onLoad(options) {
38
+    uni.login({
39
+      success: wxres => {
40
+        this.wxCode = wxres.code
41
+      }
42
+    })
43
+  },
44
+  methods: {
45
+    back() {
46
+      uni.navigateBack({
47
+        delta: 0
48
+      })
49
+    },
50
+    goto(type) {
51
+      this.globalNavigateTo('agreement', { type })
52
+    },
53
+    login() {
54
+      if (!this.agreement) {
55
+        uni.showToast({ title: '请先阅读并勾选协议', icon: 'none' })
56
+        return
57
+      }
58
+      uni.getUserProfile({
59
+        desc: '用于完善会员资料',
60
+        success: res => {
61
+          this.$store.dispatch('setUser', res.userInfo)
62
+          this.flashToken(res)
63
+        }
64
+      })
65
+    },
66
+    flashToken(wxConfig) {
67
+      _login({ code: this.wxCode }).then(res => {
68
+        const { openid, session_key: session } = res.data
69
+        this.$store.dispatch('setSession', session)
70
+        const params = {
71
+          session: session,
72
+          iv: wxConfig.iv,
73
+          encryptedData: wxConfig.encryptedData,
74
+          openid: openid,
75
+          code: this.globalApp.code
76
+        }
77
+        _auth(params).then(rs => {
78
+          this.$store.dispatch('setToken', rs.data.token).then(res => {
79
+            socket.initSocket()
80
+            this.getBindPhone()
81
+            this.globalReLaunch('index')
82
+          })
83
+        })
84
+      })
85
+    },
86
+    getBindPhone() {
87
+      _getBindPhone().then(res => {
88
+        this.$store.dispatch('setPhone', res.data.mobile)
89
+      })
90
+    }
91
+  }
92
+}
93
+</script>
94
+
95
+<style lang="scss" scoped>
96
+@import '~@/common/css/mixin.scss';
97
+.page{
98
+	background-color:#fff;
99
+}
100
+.main{
101
+	padding-top:50px;
102
+	text-align:center;
103
+}
104
+.title {
105
+	margin:12px auto;
106
+  @include title(32px, 20px);
107
+	width:80px;
108
+	border-bottom:4px solid #00d2e330;
109
+}
110
+.logo{
111
+	width:100px;
112
+	height:100px;
113
+}
114
+.action{
115
+	margin:0 auto;
116
+	width:80%;
117
+}
118
+.check-agreement{
119
+	transform: scale(0.7);
120
+}
121
+</style>

+ 330 - 330
src/pages/mine/mine.vue

@@ -1,330 +1,330 @@
1
-<template>
2
-  <view>
3
-    <cu-custom :isBack="false"></cu-custom>
4
-    <view class="main">
5
-			<view class="main-top">
6
-				<view class="title flex justify-between">
7
-					<view>{{user.nickName||'未更新用户信息'}}</view>
8
-					<text class="cuIcon-settings lg text-gray" @tap="goto('setting')"></text>
9
-				</view>
10
-			<view class="user">
11
-			 <view class="user-info flex">
12
-				 		<image mode="scaleToFill" :src="user.avatarUrl||defaultAvatar" class="avatar"></image>
13
-						<view class="study-info">
14
-							  <view class="user-name" @tap="switchStudent">
15
-									{{ kid_info.name ? kid_info.name + '-' + kid_info.school_name  : '切换学生' }}
16
-									<!-- <image :src="isLogin?switchIcon:loginIcon" mode="aspectFit" class="switch-icon"></image> -->
17
-									<text class="iconfont margin-left-xs" style="font-size:18px;" @tap="login">{{isLogin?'&#xe600;':'&#xe716;'}}</text>
18
-								</view>
19
-								 <view class="user-learn">已学习{{info.parent_data.learn_day}}天</view>
20
-						</view>
21
-			 </view>
22
-			 <view class="user-relative flex justify-between" v-if="isLogin">
23
-				  <view v-for="(relate,index) in courseRelates" :key="index" class="course-item" :style="'background:'+relate.background"
24
-					@tap="goto(relate.page)">
25
-						 <!-- <image :src="relate.img"  mode="widthFix" class="back-img relate-img"> -->
26
-						 <text class="iconfont back-img" style="font-size:32px;">{{relate.icon}}</text>
27
-						 <view class="text-df">{{relate.name}}</view>
28
-					</view>
29
-			 </view>
30
-			 <view class="user-relative flex justify-between" v-else>
31
-				  <view class="course-item relate-item" v-for="(course,index) in courses" :key="index" :style="'background:'+course.background">
32
-						<!-- <image :src="course.img" mode="widthFix" class="back-img"> -->
33
-						<text class="iconfont back-img" style="font-size:40px;">{{course.icon}}</text>
34
-						<view class="text-lg">{{course.title}}</view>
35
-						<view class="text-xxl margin-top-xs">{{course.name}}</view>
36
-					</view>
37
-			 </view>
38
-			</view>
39
-			<view class="order">
40
-				 <view class="order-title solid-bottom">我的订单</view>
41
-				 <view class="order-info flex justify-between">
42
-					  <view v-for="(order,index) in menuList" :key="index" @tap="toOrder(index)">
43
-							  <view class="order-image">
44
-									<!-- <image :src="order.img" mode="aspectFill"></image> -->
45
-									<text class="iconfont text-student" style="font-size:32px;">{{order.icon}}</text>
46
-								</view>
47
-							  {{order.title}}
48
-							</view>
49
-				 </view>
50
-			</view>
51
-			</view>
52
-			<view class="margin cu-list box-shadow menu margin-top-lg bg-white">
53
-				<view class="cu-item arrow" @tap="goto('classCart')">
54
-					<text class="cuIcon-cart lg text-gray" style="font-size:18px;"></text>
55
-        	<view class="content margin-left-sm">
56
-          	<text class="text-black">购物车</text>
57
-        	</view>
58
-          <view class="action"></view>
59
-        </view>
60
-				<view class="cu-item arrow" @tap="goto('message')">
61
-        	<text class="cuIcon-message lg text-gray" style="font-size:18px;"></text>
62
-        	<view class="content margin-left-sm">
63
-          	<text class="text-black">消息中心</text>
64
-        	</view>
65
-          <view class="action"></view>
66
-        </view>
67
-			  <view class="cu-item arrow" @tap="goto('onlineService')">
68
-					<text class="iconfont text-gray" style="font-size:18px;">&#xe726;</text>
69
-        	<view class="content margin-left-sm">
70
-          	<text class="text-black">在线客服</text>
71
-        	</view>
72
-        </view>
73
-			</view>
74
-    </view>
75
-    <mp-tabbar :outerSelected="2" />
76
-   <view class="cu-modal drawer-modal justify-start" :class="modalName=='showStudent'?'show':''" @tap="hideModal">
77
-      <view class="cu-dialog basis-lg" @tap.stop=""
78
-        :style="[{top:topHeader+'px',height:'calc(100vh - ' + topHeader + 'px)'}]">
79
-        <view class="student-list padding-left">
80
-          <view class="student margin-top-sm" v-for="(student,index) in students" :key="index" @tap="chooseKid(student.id)">
81
-						 <view class="flex align-center">
82
-								 <image mode="scaleToFill" :src="defaultAvatar" class="avatar md"></image>
83
-								<view class="margin-left-sm">{{student.name}}</view>
84
-								<text class="cuIcon-check text-student margin-left" style="font-size:22px;" v-if="kid===student.id"></text>
85
-						 </view>
86
-						 <view class="flex">
87
-							 <view class="cu-tag line-green margin-top-xs">
88
-								{{student.school_name ? student.school_name : ''}}-{{student.grade_name}}-{{student.class_name}}
89
-								</view>
90
-						 </view>
91
-          </view>
92
-        </view>
93
-      </view>
94
-    </view>
95
-  </view>
96
-</template>
97
-
98
-<script>
99
-import { mapGetters } from 'vuex'
100
-import { _getStudents, _getUserInfo } from '@/api/auth'
101
-export default {
102
-  data () {
103
-    return {
104
-      topHeader: this.globalCustomBarHeight,
105
-      info: {},
106
-      modalName: null,
107
-      students: [],
108
-      kid_info: {}, // 当前学生
109
-      menuList: [
110
-        {
111
-          title: '全部订单',
112
-          img: '/static/imgs/mine/qbdd.png',
113
-          icon: '\ue897'
114
-        },
115
-        {
116
-          title: '待付款',
117
-          img: '/static/imgs/mine/dfk.png',
118
-          icon: '\ue896'
119
-        },
120
-        {
121
-          title: '已付款',
122
-          img: '/static/imgs/mine/yfk.png',
123
-          icon: '\ue656'
124
-        },
125
-        {
126
-          title: '退课售后',
127
-          img: '/static/imgs/mine/tksh.png',
128
-          icon: '\ue61e'
129
-        }
130
-      ],
131
-      courses: [
132
-        {
133
-          title: '启蒙教育',
134
-          name: '我的机构',
135
-          img: '/static/imgs/mine/wdjg.png',
136
-          background: '#f8be32',
137
-          icon: '\ue661'
138
-        },
139
-        {
140
-          title: '启蒙教育',
141
-          name: '我的老师',
142
-          img: '/static/imgs/mine/wdls.png',
143
-          background: '#67d2a9',
144
-          icon: '\ue603'
145
-        }
146
-      ],
147
-      courseRelates: [
148
-        {
149
-          name: '我的学生',
150
-          img: '/static/imgs/mine/wdjhr.png',
151
-          background: '#5FCFE0',
152
-          page: 'myStudents',
153
-          icon: '\ue604'
154
-        },
155
-        {
156
-          name: '我的监护人',
157
-          img: '/static/imgs/mine/wdjhr.png',
158
-          background: '#f8be32',
159
-          page: 'myParents',
160
-          icon: '\ue60a'
161
-        },
162
-        {
163
-          name: '我的老师',
164
-          img: '/static/imgs/mine/wdjg.png',
165
-          background: '#67d2a9',
166
-          page: 'myTeachers',
167
-          icon: '\ue603'
168
-        },
169
-        {
170
-          name: '我的机构',
171
-          img: '/static/imgs/mine/wdls.png',
172
-          background: '#FF676E',
173
-          page: 'myInstitution',
174
-          icon: '\ue661'
175
-        }
176
-      ],
177
-      loginIcon: '/static/imgs/mine/login.png',
178
-      switchIcon: '/static/imgs/mine/login1.png',
179
-      defaultAvatar: 'http://parent.kehoubaike.com/static/img/7f4e775d2e04234d1e1994b13146f6b.e5c47f3.png'
180
-    }
181
-  },
182
-  computed: {
183
-    ...mapGetters({
184
-      user: 'user',
185
-      isLogin: 'token',
186
-      kid: 'kid'
187
-    })
188
-  },
189
-  onShow() {
190
-    this.get_info()
191
-  },
192
-  methods: {
193
-    login() {
194
-      if (this.isLogin) return false
195
-      this.globalNavigateTo('login')
196
-    },
197
-    get_info() {
198
-      _getUserInfo().then(res => {
199
-        this.info = res.data
200
-        this.get_students()
201
-      })
202
-    },
203
-    get_students() {
204
-      _getStudents().then(res => {
205
-        if (res.data.length < 1) {
206
-          this.globalNavigateTo('myStudents')
207
-          return false
208
-        }
209
-        this.students = res.data.student_data
210
-        let kid = this.kid
211
-        if (!kid) {
212
-          kid = this.students[0].id
213
-          this.$store.dispatch('setKid', this.students[0].id)
214
-        }
215
-        this.setkidInfo(kid)
216
-      })
217
-    },
218
-    hideModal (e) {
219
-      this.modalName = null
220
-    },
221
-    setkidInfo(kid) { // 设置学生信息
222
-      this.kid_info = this.students.find(item => item.id === kid)
223
-    },
224
-    switchStudent() {
225
-      if (!this.isLogin) {
226
-        this.globalNavigateTo('login')
227
-      } else {
228
-        this.modalName = 'showStudent'
229
-      }
230
-    },
231
-    goto(page) {
232
-      if (!this.isLogin) {
233
-        this.globalNavigateTo('login')
234
-      } else {
235
-        this.globalNavigateTo(page)
236
-      }
237
-    },
238
-    toOrder(index) {
239
-      this.globalNavigateTo('order', { type: index })
240
-    },
241
-    chooseKid(id) {
242
-      uni.showModal({
243
-        title: '',
244
-        content: '确定选择该学生?',
245
-        success: res => {
246
-          if (res.confirm) {
247
-            this.$store.dispatch('setKid', id).then(res => {
248
-              this.setkidInfo(res)
249
-              this.hideModal()
250
-            })
251
-          }
252
-        }
253
-      })
254
-    }
255
-  }
256
-}
257
-</script>
258
-
259
-<style lang="scss">
260
-@import '~@/common/css/mixin.scss';
261
-.title{
262
-	@include title(10px,22px);
263
-}
264
-.main{
265
-	padding-top:10px;
266
-}
267
-.main-top{
268
-	padding:0 30rpx;
269
-}
270
-.user{
271
-
272
-}
273
-.user-info{
274
-	margin-bottom:10px;
275
-}
276
-.study-info{
277
-	margin-left:40rpx;
278
-	padding-top:6px;
279
-}
280
-.user-name{
281
-	@include title(10px,16px);
282
-}
283
-.user-learn{
284
-	margin-top:20px;
285
-}
286
-.user-relative{
287
-	width:100%;
288
-}
289
-.course-item{
290
-	position:relative;
291
-	border-radius:10px;
292
-	padding:16rpx;
293
-	width:24%;
294
-	min-height:52px;
295
-	color:#fff;
296
-}
297
-.course-item.relate-item{
298
-	width:48%;
299
-}
300
-.back-img{
301
-	position:absolute;
302
-	bottom:8px;
303
-	right:6px;
304
-	opacity: .4;
305
-}
306
-.order{
307
-	margin-top:10px;
308
-}
309
-.order-info{
310
-	padding:0 30rpx;
311
-}
312
-.order-image{
313
-	margin:10rpx auto;
314
-	width:30px;
315
-	height:30px;
316
-	image{
317
-		width:100%;
318
-		height:100%;
319
-	}
320
-}
321
-.order-title{
322
-	padding-bottom:10px;
323
-	@include title(10px,16px);
324
-}
325
-.switch-icon{
326
-	margin-left:10rpx;
327
-	width:1em;
328
-	height:1em;
329
-}
330
-</style>
1
+<template>
2
+  <view>
3
+    <cu-custom :isBack="false"></cu-custom>
4
+    <view class="main">
5
+			<view class="main-top">
6
+				<view class="title flex justify-between">
7
+					<view>{{user.nickName||'未更新用户信息'}}</view>
8
+					<text class="cuIcon-settings lg text-gray" @tap="goto('setting')"></text>
9
+				</view>
10
+			<view class="user">
11
+			 <view class="user-info flex">
12
+				 		<image mode="scaleToFill" :src="user.avatarUrl||defaultAvatar" class="avatar"></image>
13
+						<view class="study-info">
14
+							  <view class="user-name" @tap="switchStudent">
15
+									{{ kid_info.name ? kid_info.name + '-' + kid_info.school_name  : '切换学生' }}
16
+									<!-- <image :src="isLogin?switchIcon:loginIcon" mode="aspectFit" class="switch-icon"></image> -->
17
+									<text class="iconfont margin-left-xs" style="font-size:18px;" @tap="login">{{isLogin?'&#xe600;':'&#xe716;'}}</text>
18
+								</view>
19
+								 <view class="user-learn">已学习{{info.parent_data.learn_day}}天</view>
20
+						</view>
21
+			 </view>
22
+			 <view class="user-relative flex justify-between" v-if="isLogin">
23
+				  <view v-for="(relate,index) in courseRelates" :key="index" class="course-item" :style="'background:'+relate.background"
24
+					@tap="goto(relate.page)">
25
+						 <!-- <image :src="relate.img"  mode="widthFix" class="back-img relate-img"> -->
26
+						 <text class="iconfont back-img" style="font-size:32px;">{{relate.icon}}</text>
27
+						 <view class="text-df">{{relate.name}}</view>
28
+					</view>
29
+			 </view>
30
+			 <view class="user-relative flex justify-between" v-else>
31
+				  <view class="course-item relate-item" v-for="(course,index) in courses" :key="index" :style="'background:'+course.background">
32
+						<!-- <image :src="course.img" mode="widthFix" class="back-img"> -->
33
+						<text class="iconfont back-img" style="font-size:40px;">{{course.icon}}</text>
34
+						<view class="text-lg">{{course.title}}</view>
35
+						<view class="text-xxl margin-top-xs">{{course.name}}</view>
36
+					</view>
37
+			 </view>
38
+			</view>
39
+			<view class="order">
40
+				 <view class="order-title solid-bottom">我的订单</view>
41
+				 <view class="order-info flex justify-between">
42
+					  <view v-for="(order,index) in menuList" :key="index" @tap="toOrder(index)">
43
+							  <view class="order-image">
44
+									<!-- <image :src="order.img" mode="aspectFill"></image> -->
45
+									<text class="iconfont text-student" style="font-size:32px;">{{order.icon}}</text>
46
+								</view>
47
+							  {{order.title}}
48
+							</view>
49
+				 </view>
50
+			</view>
51
+			</view>
52
+			<view class="margin cu-list box-shadow menu margin-top-lg bg-white">
53
+				<view class="cu-item arrow" @tap="goto('classCart')">
54
+					<text class="cuIcon-cart lg text-gray" style="font-size:18px;"></text>
55
+        	<view class="content margin-left-sm">
56
+          	<text class="text-black">购物车</text>
57
+        	</view>
58
+          <view class="action"></view>
59
+        </view>
60
+				<view class="cu-item arrow" @tap="goto('message')">
61
+        	<text class="cuIcon-message lg text-gray" style="font-size:18px;"></text>
62
+        	<view class="content margin-left-sm">
63
+          	<text class="text-black">消息中心</text>
64
+        	</view>
65
+          <view class="action"></view>
66
+        </view>
67
+			  <view class="cu-item arrow" @tap="goto('onlineService')">
68
+					<text class="iconfont text-gray" style="font-size:18px;">&#xe726;</text>
69
+        	<view class="content margin-left-sm">
70
+          	<text class="text-black">在线客服</text>
71
+        	</view>
72
+        </view>
73
+			</view>
74
+    </view>
75
+    <mp-tabbar :outerSelected="2" />
76
+   <view class="cu-modal drawer-modal justify-start" :class="modalName=='showStudent'?'show':''" @tap="hideModal">
77
+      <scroll-view :scroll-y="true" class="cu-dialog basis-lg" @tap.stop=""
78
+        :style="[{top:topHeader+'px',height:'calc(100vh - 48px - ' + topHeader + 'px)'}]">
79
+        <view class="student-list padding-left">
80
+          <view class="student margin-top-sm" v-for="(student,index) in students" :key="index" @tap="chooseKid(student.id)">
81
+						 <view class="flex align-center">
82
+								<image mode="scaleToFill" :src="defaultAvatar" class="avatar md"></image>
83
+								<view class="margin-left-sm">{{student.name}}</view>
84
+								<text class="cuIcon-check text-student margin-left" style="font-size:22px;" v-if="kid===student.id"></text>
85
+						 </view>
86
+						 <view class="flex">
87
+							 <view class="cu-tag line-green margin-top-xs">
88
+								{{student.school_name ? student.school_name : ''}}-{{student.grade_name}}-{{student.class_name}}
89
+								</view>
90
+						 </view>
91
+          </view>
92
+        </view>
93
+      </scroll-view>
94
+    </view>
95
+  </view>
96
+</template>
97
+
98
+<script>
99
+import { mapGetters } from 'vuex'
100
+import { _getStudents, _getUserInfo } from '@/api/auth'
101
+export default {
102
+  data () {
103
+    return {
104
+      topHeader: this.globalCustomBarHeight,
105
+      info: {},
106
+      modalName: null,
107
+      students: [],
108
+      kid_info: {}, // 当前学生
109
+      menuList: [
110
+        {
111
+          title: '全部订单',
112
+          img: '/static/imgs/mine/qbdd.png',
113
+          icon: '\ue897'
114
+        },
115
+        {
116
+          title: '待付款',
117
+          img: '/static/imgs/mine/dfk.png',
118
+          icon: '\ue896'
119
+        },
120
+        {
121
+          title: '已付款',
122
+          img: '/static/imgs/mine/yfk.png',
123
+          icon: '\ue656'
124
+        },
125
+        {
126
+          title: '退课售后',
127
+          img: '/static/imgs/mine/tksh.png',
128
+          icon: '\ue61e'
129
+        }
130
+      ],
131
+      courses: [
132
+        {
133
+          title: '启蒙教育',
134
+          name: '我的机构',
135
+          img: '/static/imgs/mine/wdjg.png',
136
+          background: '#f8be32',
137
+          icon: '\ue661'
138
+        },
139
+        {
140
+          title: '启蒙教育',
141
+          name: '我的老师',
142
+          img: '/static/imgs/mine/wdls.png',
143
+          background: '#67d2a9',
144
+          icon: '\ue603'
145
+        }
146
+      ],
147
+      courseRelates: [
148
+        {
149
+          name: '我的学生',
150
+          img: '/static/imgs/mine/wdjhr.png',
151
+          background: '#5FCFE0',
152
+          page: 'myStudents',
153
+          icon: '\ue604'
154
+        },
155
+        {
156
+          name: '我的监护人',
157
+          img: '/static/imgs/mine/wdjhr.png',
158
+          background: '#f8be32',
159
+          page: 'myParents',
160
+          icon: '\ue60a'
161
+        },
162
+        {
163
+          name: '我的老师',
164
+          img: '/static/imgs/mine/wdjg.png',
165
+          background: '#67d2a9',
166
+          page: 'myTeachers',
167
+          icon: '\ue603'
168
+        },
169
+        {
170
+          name: '我的机构',
171
+          img: '/static/imgs/mine/wdls.png',
172
+          background: '#FF676E',
173
+          page: 'myInstitution',
174
+          icon: '\ue661'
175
+        }
176
+      ],
177
+      loginIcon: '/static/imgs/mine/login.png',
178
+      switchIcon: '/static/imgs/mine/login1.png',
179
+      defaultAvatar: 'http://parent.kehoubaike.com/static/img/7f4e775d2e04234d1e1994b13146f6b.e5c47f3.png'
180
+    }
181
+  },
182
+  computed: {
183
+    ...mapGetters({
184
+      user: 'user',
185
+      isLogin: 'token',
186
+      kid: 'kid'
187
+    })
188
+  },
189
+  onShow() {
190
+    this.get_info()
191
+  },
192
+  methods: {
193
+    login() {
194
+      if (this.isLogin) return false
195
+      this.globalNavigateTo('login')
196
+    },
197
+    get_info() {
198
+      _getUserInfo().then(res => {
199
+        this.info = res.data
200
+        this.get_students()
201
+      })
202
+    },
203
+    get_students() {
204
+      _getStudents().then(res => {
205
+        if (res.data.length < 1) {
206
+          this.globalNavigateTo('myStudents')
207
+          return false
208
+        }
209
+        this.students = res.data.student_data
210
+        let kid = this.kid
211
+        if (!kid) {
212
+          kid = this.students[0].id
213
+          this.$store.dispatch('setKid', this.students[0].id)
214
+        }
215
+        this.setkidInfo(kid)
216
+      })
217
+    },
218
+    hideModal (e) {
219
+      this.modalName = null
220
+    },
221
+    setkidInfo(kid) { // 设置学生信息
222
+      this.kid_info = this.students.find(item => item.id === kid)
223
+    },
224
+    switchStudent() {
225
+      if (!this.isLogin) {
226
+        this.globalNavigateTo('login')
227
+      } else {
228
+        this.modalName = 'showStudent'
229
+      }
230
+    },
231
+    goto(page) {
232
+      if (!this.isLogin) {
233
+        this.globalNavigateTo('login')
234
+      } else {
235
+        this.globalNavigateTo(page)
236
+      }
237
+    },
238
+    toOrder(index) {
239
+      this.globalNavigateTo('order', { type: index })
240
+    },
241
+    chooseKid(id) {
242
+      uni.showModal({
243
+        title: '',
244
+        content: '确定选择该学生?',
245
+        success: res => {
246
+          if (res.confirm) {
247
+            this.$store.dispatch('setKid', id).then(res => {
248
+              this.setkidInfo(res)
249
+              this.hideModal()
250
+            })
251
+          }
252
+        }
253
+      })
254
+    }
255
+  }
256
+}
257
+</script>
258
+
259
+<style lang="scss">
260
+@import '~@/common/css/mixin.scss';
261
+.title{
262
+	@include title(10px,22px);
263
+}
264
+.main{
265
+	padding-top:10px;
266
+}
267
+.main-top{
268
+	padding:0 30rpx;
269
+}
270
+.user{
271
+
272
+}
273
+.user-info{
274
+	margin-bottom:10px;
275
+}
276
+.study-info{
277
+	margin-left:40rpx;
278
+	padding-top:6px;
279
+}
280
+.user-name{
281
+	@include title(10px,16px);
282
+}
283
+.user-learn{
284
+	margin-top:20px;
285
+}
286
+.user-relative{
287
+	width:100%;
288
+}
289
+.course-item{
290
+	position:relative;
291
+	border-radius:10px;
292
+	padding:16rpx;
293
+	width:24%;
294
+	min-height:52px;
295
+	color:#fff;
296
+}
297
+.course-item.relate-item{
298
+	width:48%;
299
+}
300
+.back-img{
301
+	position:absolute;
302
+	bottom:8px;
303
+	right:6px;
304
+	opacity: .4;
305
+}
306
+.order{
307
+	margin-top:10px;
308
+}
309
+.order-info{
310
+	padding:0 30rpx;
311
+}
312
+.order-image{
313
+	margin:10rpx auto;
314
+	width:30px;
315
+	height:30px;
316
+	image{
317
+		width:100%;
318
+		height:100%;
319
+	}
320
+}
321
+.order-title{
322
+	padding-bottom:10px;
323
+	@include title(10px,16px);
324
+}
325
+.switch-icon{
326
+	margin-left:10rpx;
327
+	width:1em;
328
+	height:1em;
329
+}
330
+</style>

+ 86 - 76
src/pages/mine/setting.vue

@@ -1,76 +1,86 @@
1
-<template>
2
-	<view class="page">
3
-		<cu-custom :isBack="true" title="个人信息">
4
-		</cu-custom>
5
-		<view class="cu-list menu  bg-white">
6
-        <view class="cu-item flex justify-between">
7
-          <view class="content margin-left-sm">
8
-						<text class="text-black">头像</text>
9
-          </view>
10
-					<image mode="scaleToFill" :src="user.avatarUrl" class="avatar lg" v-if="user.avatarUrl"></image>
11
-        </view>
12
-        <view class="cu-item flex justify-between">
13
-          <view class="content margin-left-sm">
14
-            <text class="text-black">昵称</text>
15
-          </view>
16
-					<view>{{user.nickName}}</view>
17
-        </view>
18
-        <view class="cu-item flex justify-between">
19
-          <view class="content margin-left-sm">
20
-            <text class="text-black">性别</text>
21
-          </view>
22
-          <view>{{user.gender?'女':'男'}}</view>
23
-        </view>
24
-        <view class="cu-item arrow" @tap="globalNavigateTo('changePhone')">
25
-          <view class="content margin-left-sm">
26
-            <text class="text-black">手机号</text>
27
-          </view>
28
-        </view>
29
-		</view>
30
-    <view class="solids-bottom bg-white text-center padding text-red margin-top" @tap="logOut">
31
-        退出登录
32
-    </view>
33
-	</view>
34
-</template>
35
-
36
-<script>
37
-import { mapGetters } from 'vuex'
38
-export default {
39
-  data() {
40
-    return {
41
-      params: {
42
-        sex: 1
43
-      }
44
-    }
45
-  },
46
-  computed: {
47
-    ...mapGetters([
48
-      'user'
49
-    ])
50
-  },
51
-  methods: {
52
-    logOut() {
53
-      const _self = this
54
-      uni.showModal({
55
-        title: '',
56
-        content: '确认退出?',
57
-        success: function (res) {
58
-          if (res.confirm) {
59
-            _self.$store.dispatch('clear').then(res => {
60
-              _self.$nextTick(() => {
61
-                _self.globalReLaunch('index')
62
-              })
63
-            })
64
-          }
65
-        }
66
-      })
67
-    }
68
-  }
69
-}
70
-</script>
71
-
72
-<style lang="scss" scoped>
73
-.page{
74
-	height:100vh;
75
-}
76
-</style>
1
+<template>
2
+	<view class="page">
3
+		<cu-custom :isBack="true" title="个人信息">
4
+		</cu-custom>
5
+		<view class="cu-list menu  bg-white">
6
+        <view class="cu-item flex justify-between">
7
+          <view class="content margin-left-sm">
8
+						<text class="text-black">头像</text>
9
+          </view>
10
+					<image mode="scaleToFill" :src="user.avatarUrl" class="avatar lg" v-if="user.avatarUrl"></image>
11
+        </view>
12
+        <view class="cu-item flex justify-between">
13
+          <view class="content margin-left-sm">
14
+            <text class="text-black">昵称</text>
15
+          </view>
16
+					<view>{{user.nickName}}</view>
17
+        </view>
18
+        <view class="cu-item flex justify-between">
19
+          <view class="content margin-left-sm">
20
+            <text class="text-black">性别</text>
21
+          </view>
22
+          <view>{{user.gender?'女':'男'}}</view>
23
+        </view>
24
+        <view class="cu-item" :class="phone?'':'arrow'" @tap="toBind">
25
+          <view class="content margin-left-sm">
26
+            <text class="text-black">手机号</text>
27
+          </view>
28
+					<view>{{phone|hideIdCard(3,4)}}</view>
29
+        </view>
30
+		</view>
31
+    <view class="solids-bottom bg-white text-center padding text-red margin-top" @tap="logOut">
32
+        退出登录
33
+    </view>
34
+	</view>
35
+</template>
36
+
37
+<script>
38
+import { mapGetters } from 'vuex'
39
+import { hideIdCard } from '@/common/utils/filter'
40
+export default {
41
+  data() {
42
+    return {
43
+      params: {
44
+        sex: 1
45
+      }
46
+    }
47
+  },
48
+  computed: {
49
+    ...mapGetters([
50
+      'user', 'phone'
51
+    ])
52
+  },
53
+  filters: {
54
+    hideIdCard
55
+  },
56
+  methods: {
57
+    logOut() {
58
+      const _self = this
59
+      uni.showModal({
60
+        title: '',
61
+        content: '确认退出?',
62
+        success: function (res) {
63
+          if (res.confirm) {
64
+            _self.$store.dispatch('clear').then(res => {
65
+              _self.$nextTick(() => {
66
+                _self.globalReLaunch('index')
67
+              })
68
+            })
69
+          }
70
+        }
71
+      })
72
+    },
73
+    toBind() {
74
+      if (!this.phone) {
75
+        this.globalNavigateTo('bindPhone')
76
+      }
77
+    }
78
+  }
79
+}
80
+</script>
81
+
82
+<style lang="scss" scoped>
83
+.page{
84
+	height:100vh;
85
+}
86
+</style>

+ 302 - 298
src/pages/myStudents/myStudents.vue

@@ -1,298 +1,302 @@
1
-<template>
2
-	<view class="page">
3
-		<cu-custom :isBack="false" :isHome="true">
4
-			 <view slot="content">我的学生</view>
5
-		</cu-custom>
6
-		<scroll-view>
7
-			<view class="cu-card case no-card">
8
-				<view class="cu-item shadow">
9
-					<view class="image">
10
-      			<image src="/static/imgs/mine/img.png" mode="widthFix"></image>
11
-						 <view class="image-tag">应趣教育 课后百科</view>
12
-					</view>
13
-				</view>
14
-			</view>
15
-			  <view class="cu-card">
16
-					 <view class="cu-item shadow">
17
-						  <view class="students-title flex justify-between align-center">
18
-								 <view class="text-lg">学生列表</view>
19
-								 <view class="text-xs text-grey">
20
-									 <text class="text-red">点击选择,左滑删除,右侧添加</text>
21
-									 <text class="cuIcon-roundaddfill text-cyan margin-left-xl add-icon"
22
-									 @tap="showModal" data-target="ChooseModal"
23
-									 ></text>
24
-								 </view>
25
-							</view>
26
-							<view class="cu-list menu-avatar">
27
-									<view class="cu-item" :class="moveModel=='move-box-'+ index?'move-cur':''"
28
-									v-for="(item,index) in result.student_data" :key="index"
29
-									@touchstart="ListTouchStart" @touchmove="ListTouchMove"
30
-									@touchend="ListTouchEnd" :data-target="'move-box-' + index"
31
-									@tap="chooseKid(item.id)">
32
-									 <image mode="scaleToFill" :src="defaultAvatar" class="avatar md left"></image>
33
-										<view class="content">
34
-											<view>{{item.name}}</view>
35
-											<view class="text-gray">{{item.school_name}}-{{item.grade_name}}-{{item.class_name}}</view>
36
-										</view>
37
-										<view class="action">
38
-											<text class="cuIcon-check text-student font-check" v-if="item.id===kid"></text>
39
-										</view>
40
-										<view class="move student-move">
41
-											<view class="bg-red" @tap.stop="unbind(item.id)">删除</view>
42
-										</view>
43
-									</view>
44
-							</view>
45
-					 </view>
46
-				</view>
47
-		</scroll-view>
48
-		<!-- 选择学生列表 -->
49
-		<view class="cu-modal" :class="modalName=='showStudents'?'show':''" @tap="hideModal">
50
-			<view class="cu-dialog bg-student" @tap.stop=''>
51
-				<view class="padding text-left modal-body radius-student">
52
-					<view class="cu-list menu-avatar">
53
-							<view class="cu-item"  v-for="(item,index) in chooseList" :key="index" @tap="save(item.id)">
54
-								<view class="cu-inner" :class="{'checked':item.id===selectKid}">
55
-									<image mode="scaleToFill" :src="defaultAvatar" class="avatar md left"></image>
56
-									<view class="content">
57
-											<view>{{item.name}}</view>
58
-											<view class="text-gray">{{item.school_name}}-{{item.grade_name}}-{{item.class_name}}</view>
59
-									</view>
60
-								</view>
61
-						</view>
62
-					</view>
63
-				</view>
64
-			</view>
65
-		</view>
66
-		<!--添加学生-->
67
-    <view class="cu-modal" :class="modalName=='ChooseModal'?'show':''" @tap="hideModal">
68
-      <view class="cu-dialog bg-student" @tap.stop=''>
69
-        <view class="cu-bar justify-around">
70
-          <view class="content modal-title">添加学生</view>
71
-        </view>
72
-        <view class="padding-xl text-left modal-body">
73
-				  <view>
74
-            <input type="text"  v-model.trim="student.student_name" placeholder="请输入学生名字" class="student-input text-black text-lg">
75
-          </view>
76
-					<view class="margin-top" v-if="student.student_name">
77
-            <input type="text"  v-model.trim="student.school_name" placeholder="请输入学校名称" class="student-input text-black text-lg">
78
-          </view>
79
-					<view class="margin-top">
80
-						 <button class="student-input text-student text-left" @tap="get_students">获取学生</button>
81
-					</view>
82
-        </view>
83
-        <view class="cu-bar modal-footer">
84
-          <view class="action"></view>
85
-        </view>
86
-      </view>
87
-    </view>
88
-	</view>
89
-</template>
90
-
91
-<script>
92
-import { _getStudents, _bindStudent, _unbindStudent } from '@/api/auth'
93
-import { _shopList } from '@/api/course'
94
-import { mapGetters } from 'vuex'
95
-export default {
96
-  data() {
97
-    return {
98
-      showAdd: false,
99
-      modalName: null,
100
-      selectKid: 0,
101
-      student: {
102
-        student_name: '',
103
-        school_name: ''
104
-      },
105
-      result: null,
106
-      chooseList: [],
107
-      moveModel: null,
108
-      listTouchStart: 0,
109
-      listTouchDirection: null,
110
-      defaultAvatar: 'http://parent.kehoubaike.com/static/img/7f4e775d2e04234d1e1994b13146f6b.e5c47f3.png'
111
-    }
112
-  },
113
-  computed: {
114
-    ...mapGetters([
115
-      'kid'
116
-    ])
117
-  },
118
-  onLoad() {
119
-    this.get_list()
120
-  },
121
-  onShow() {
122
-    const kid = this.kid
123
-    if (kid) {
124
-      this.selectKid = kid
125
-    } else {
126
-      uni.showModal({
127
-        title: '请选择学生',
128
-        content: '请先选择一个学生',
129
-        showCancel: false,
130
-        success: res => {
131
-
132
-        }
133
-      })
134
-    }
135
-  },
136
-  methods: {
137
-    showModal(e) {
138
-      this.modalName = e.currentTarget.dataset.target
139
-    },
140
-    hideModal(e) {
141
-      this.modalName = null
142
-    },
143
-    get_list() {
144
-      _getStudents().then(res => {
145
-        this.result = res.data
146
-      })
147
-    },
148
-    get_students() {
149
-      if (!this.student.student_name) return uni.showToast({ title: '请输入学生姓名', icon: 'none' })
150
-      if (!this.student.school_name) return uni.showToast({ title: '请输入学校名称', icon: 'none' })
151
-      _getStudents(this.student).then(res => {
152
-        const students = res.data.student_data
153
-        if (students.length > 0) {
154
-          this.modalName = 'showStudents'
155
-          this.chooseList = students
156
-        } else {
157
-          uni.showToast({ title: '暂无学生信息', icon: 'none' })
158
-        }
159
-      })
160
-    },
161
-    save(id) {
162
-      this.selectKid = id
163
-      uni.showModal({
164
-        title: '确定绑定?',
165
-        success: res => {
166
-          if (res.confirm) {
167
-            _bindStudent({ student: id }).then(res => {
168
-              uni.showToast({ title: '绑定成功!' })
169
-              this.$store.dispatch('setKid', id)
170
-              this.setCarts()
171
-              this.get_list()
172
-              this.modalName = ''
173
-            })
174
-          }
175
-        }
176
-      })
177
-    },
178
-    unbind(id) {
179
-      const _self = this
180
-      uni.showModal({
181
-        title: '确定解绑?',
182
-        message: '',
183
-        success: res => {
184
-          if (res.confirm) {
185
-            _unbindStudent({ student: id }).then(res => {
186
-              if (res.code === 1) {
187
-                uni.showToast({ title: '解绑成功!' })
188
-                if (_self.kid === id) { _self.$store.dispatch('setKid', 0) }// 解绑选中学生
189
-                this.get_list()
190
-              }
191
-            })
192
-          }
193
-        }
194
-      })
195
-    },
196
-    chooseKid(id) {
197
-      uni.showModal({
198
-        title: '确定选择学生',
199
-        message: '确定选择该学生?',
200
-        success: res => {
201
-          if (res.confirm) {
202
-            this.selectKid = id
203
-            this.$store.dispatch('setKid', id)
204
-            this.setCarts()
205
-            this.globalReLaunch('index')
206
-          }
207
-        }
208
-      })
209
-    },
210
-    setCarts() { // 刷新购物车
211
-      _shopList().then(res => {
212
-        const carts = res.data.map(item => item.class_attend_id)
213
-        this.$store.dispatch('setCarts', carts)
214
-      })
215
-    },
216
-    ListTouchStart(e) {
217
-      this.listTouchStart = e.touches[0].pageX
218
-    },
219
-    ListTouchMove(e) {
220
-      this.listTouchDirection = e.touches[0].pageX - this.listTouchStart > 0 ? 'right' : 'left'
221
-    },
222
-    ListTouchEnd(e) {
223
-      if (this.listTouchDirection === 'left') {
224
-        this.moveModel = e.currentTarget.dataset.target
225
-      } else {
226
-        this.moveModel = null
227
-      }
228
-      this.listTouchDirection = null
229
-    }
230
-  }
231
-}
232
-</script>
233
-
234
-<style lang="scss" scoped>
235
-.page{
236
-	height:100vh;
237
-}
238
-.image{
239
-	padding-bottom:20px;
240
-}
241
-.image-tag{
242
-	position:absolute;
243
-	top:10px;
244
-	left:10px;
245
-	font-size:24px;
246
-	font-weight:bold;
247
-	color: #6d4f26;
248
-}
249
-.students-title{
250
-	padding:30rpx;
251
-}
252
-.add-icon{
253
-	display:inline-block;
254
-	width:40px;
255
-	height:40px;
256
-	line-height:40px;
257
-	text-align:center;
258
-	font-size:22px;
259
-}
260
-.student-input{
261
-	height:40px;
262
-	line-height:40px;
263
-	border-radius:20px;
264
-	background-color:#fff;
265
-}
266
-.radius-student{
267
-	border-radius:20rpx;
268
-}
269
-.cu-inner{
270
-	margin:10rpx;
271
-	display:flex;
272
-	align-items:center;
273
-	width:100%;
274
-}
275
-.cu-inner.checked{
276
-    background: #5fd0e4;
277
-    color: #fff;
278
-    border-radius: 20rpx;
279
-}
280
-.cu-dialog{
281
-	width:90%;
282
-}
283
-.modal-title{
284
-    font-weight: bold;
285
-    color: #516029;
286
-    font-size: 20px;
287
-}
288
-.font-check{
289
-	font-size:22px;
290
-}
291
-.cu-list>.cu-item .move.student-move{
292
-	width:130rpx;
293
-	text-align:center;
294
-}
295
-.cu-list>.cu-item.move-cur{
296
-	transform: translateX(-130rpx);
297
-}
298
-</style>
1
+<template>
2
+	<view class="page">
3
+		<cu-custom :isBack="false" :isHome="true">
4
+			 <view slot="content">我的学生</view>
5
+		</cu-custom>
6
+		<scroll-view>
7
+			<view class="cu-card case no-card">
8
+				<view class="cu-item shadow">
9
+					<view class="image">
10
+      			<image src="/static/imgs/mine/img.png" mode="widthFix"></image>
11
+						 <view class="image-tag">应趣教育 课后百科</view>
12
+					</view>
13
+				</view>
14
+			</view>
15
+			  <view class="cu-card">
16
+					 <view class="cu-item shadow">
17
+						  <view class="students-title flex justify-between align-center">
18
+								 <view class="text-lg">学生列表</view>
19
+								 <view class="text-xs text-grey">
20
+									 <text class="text-red">点击选择,左滑删除,右侧添加</text>
21
+									 <text class="cuIcon-roundaddfill text-cyan margin-left-xl add-icon"
22
+									 @tap="showModal" data-target="ChooseModal"
23
+									 ></text>
24
+								 </view>
25
+							</view>
26
+							<view class="padding-lr text-right" v-if="!phone">
27
+								  <text class="text-red text-xs">右侧点击绑定手机号,直接获取绑定学生列表</text>
28
+									<text class="cuIcon-mobile text-cyan add-icon margin-left-xl" @tap="globalNavigateTo('bindPhone')"></text>
29
+							</view>
30
+							<view class="cu-list menu-avatar">
31
+									<view class="cu-item" :class="moveModel=='move-box-'+ index?'move-cur':''"
32
+									v-for="(item,index) in result.student_data" :key="index"
33
+									@touchstart="ListTouchStart" @touchmove="ListTouchMove"
34
+									@touchend="ListTouchEnd" :data-target="'move-box-' + index"
35
+									@tap="chooseKid(item.id)">
36
+									 <image mode="scaleToFill" :src="defaultAvatar" class="avatar md left"></image>
37
+										<view class="content">
38
+											<view>{{item.name}}</view>
39
+											<view class="text-gray">{{item.school_name}}-{{item.grade_name}}-{{item.class_name}}</view>
40
+										</view>
41
+										<view class="action">
42
+											<text class="cuIcon-check text-student font-check" v-if="item.id===kid"></text>
43
+										</view>
44
+										<view class="move student-move">
45
+											<view class="bg-red" @tap.stop="unbind(item.id)">删除</view>
46
+										</view>
47
+									</view>
48
+							</view>
49
+					 </view>
50
+				</view>
51
+		</scroll-view>
52
+		<!-- 选择学生列表 -->
53
+		<view class="cu-modal" :class="modalName=='showStudents'?'show':''" @tap="hideModal">
54
+			<view class="cu-dialog bg-student" @tap.stop=''>
55
+				<view class="padding text-left modal-body radius-student">
56
+					<view class="cu-list menu-avatar">
57
+							<view class="cu-item"  v-for="(item,index) in chooseList" :key="index" @tap="save(item.id)">
58
+								<view class="cu-inner" :class="{'checked':item.id===selectKid}">
59
+									<image mode="scaleToFill" :src="defaultAvatar" class="avatar md left"></image>
60
+									<view class="content">
61
+											<view>{{item.name}}</view>
62
+											<view class="text-gray">{{item.school_name}}-{{item.grade_name}}-{{item.class_name}}</view>
63
+									</view>
64
+								</view>
65
+						</view>
66
+					</view>
67
+				</view>
68
+			</view>
69
+		</view>
70
+		<!--添加学生-->
71
+    <view class="cu-modal" :class="modalName=='ChooseModal'?'show':''" @tap="hideModal">
72
+      <view class="cu-dialog bg-student" @tap.stop=''>
73
+        <view class="cu-bar justify-around">
74
+          <view class="content modal-title">添加学生</view>
75
+        </view>
76
+        <view class="padding-xl text-left modal-body">
77
+				  <view>
78
+            <input type="text"  v-model.trim="student.student_name" placeholder="请输入学生名字" class="student-input text-black text-lg">
79
+          </view>
80
+					<view class="margin-top" v-if="student.student_name">
81
+            <input type="text"  v-model.trim="student.school_name" placeholder="请输入学校名称" class="student-input text-black text-lg">
82
+          </view>
83
+					<view class="margin-top">
84
+						 <button class="student-input text-student text-left" @tap="get_students">获取学生</button>
85
+					</view>
86
+        </view>
87
+        <view class="cu-bar modal-footer">
88
+          <view class="action"></view>
89
+        </view>
90
+      </view>
91
+    </view>
92
+	</view>
93
+</template>
94
+
95
+<script>
96
+import { _getStudents, _bindStudent, _unbindStudent } from '@/api/auth'
97
+import { _shopList } from '@/api/course'
98
+import { mapGetters } from 'vuex'
99
+export default {
100
+  data() {
101
+    return {
102
+      showAdd: false,
103
+      modalName: null,
104
+      selectKid: 0,
105
+      student: {
106
+        student_name: '',
107
+        school_name: ''
108
+      },
109
+      result: null,
110
+      chooseList: [],
111
+      moveModel: null,
112
+      listTouchStart: 0,
113
+      listTouchDirection: null,
114
+      defaultAvatar: 'http://parent.kehoubaike.com/static/img/7f4e775d2e04234d1e1994b13146f6b.e5c47f3.png'
115
+    }
116
+  },
117
+  computed: {
118
+    ...mapGetters([
119
+      'kid', 'phone'
120
+    ])
121
+  },
122
+  onLoad() {
123
+  },
124
+  onShow() {
125
+    this.get_list()
126
+    const kid = this.kid
127
+    if (kid) {
128
+      this.selectKid = kid
129
+    } else {
130
+      uni.showModal({
131
+        title: '请选择学生',
132
+        content: '请先选择一个学生',
133
+        showCancel: false,
134
+        success: res => {
135
+
136
+        }
137
+      })
138
+    }
139
+  },
140
+  methods: {
141
+    showModal(e) {
142
+      this.modalName = e.currentTarget.dataset.target
143
+    },
144
+    hideModal(e) {
145
+      this.modalName = null
146
+    },
147
+    get_list() {
148
+      _getStudents().then(res => {
149
+        this.result = res.data
150
+      })
151
+    },
152
+    get_students() {
153
+      if (!this.student.student_name) return uni.showToast({ title: '请输入学生姓名', icon: 'none' })
154
+      if (!this.student.school_name) return uni.showToast({ title: '请输入学校名称', icon: 'none' })
155
+      _getStudents(this.student).then(res => {
156
+        const students = res.data.student_data
157
+        if (students.length > 0) {
158
+          this.modalName = 'showStudents'
159
+          this.chooseList = students
160
+        } else {
161
+          uni.showToast({ title: '暂无学生信息', icon: 'none' })
162
+        }
163
+      })
164
+    },
165
+    save(id) {
166
+      this.selectKid = id
167
+      uni.showModal({
168
+        title: '确定绑定?',
169
+        success: res => {
170
+          if (res.confirm) {
171
+            _bindStudent({ student: id }).then(res => {
172
+              uni.showToast({ title: '绑定成功!' })
173
+              this.$store.dispatch('setKid', id)
174
+              this.setCarts()
175
+              this.get_list()
176
+              this.modalName = ''
177
+            })
178
+          }
179
+        }
180
+      })
181
+    },
182
+    unbind(id) {
183
+      const _self = this
184
+      uni.showModal({
185
+        title: '确定解绑?',
186
+        message: '',
187
+        success: res => {
188
+          if (res.confirm) {
189
+            _unbindStudent({ student: id }).then(res => {
190
+              if (res.code === 1) {
191
+                uni.showToast({ title: '解绑成功!' })
192
+                if (_self.kid === id) { _self.$store.dispatch('setKid', 0) }// 解绑选中学生
193
+                this.get_list()
194
+              }
195
+            })
196
+          }
197
+        }
198
+      })
199
+    },
200
+    chooseKid(id) {
201
+      uni.showModal({
202
+        title: '确定选择学生',
203
+        message: '确定选择该学生?',
204
+        success: res => {
205
+          if (res.confirm) {
206
+            this.selectKid = id
207
+            this.$store.dispatch('setKid', id)
208
+            this.setCarts()
209
+            this.globalReLaunch('index')
210
+          }
211
+        }
212
+      })
213
+    },
214
+    setCarts() { // 刷新购物车
215
+      _shopList().then(res => {
216
+        const carts = res.data.map(item => item.class_attend_id)
217
+        this.$store.dispatch('setCarts', carts)
218
+      })
219
+    },
220
+    ListTouchStart(e) {
221
+      this.listTouchStart = e.touches[0].pageX
222
+    },
223
+    ListTouchMove(e) {
224
+      this.listTouchDirection = e.touches[0].pageX - this.listTouchStart > 0 ? 'right' : 'left'
225
+    },
226
+    ListTouchEnd(e) {
227
+      if (this.listTouchDirection === 'left') {
228
+        this.moveModel = e.currentTarget.dataset.target
229
+      } else {
230
+        this.moveModel = null
231
+      }
232
+      this.listTouchDirection = null
233
+    }
234
+  }
235
+}
236
+</script>
237
+
238
+<style lang="scss" scoped>
239
+.page{
240
+	height:100vh;
241
+}
242
+.image{
243
+	padding-bottom:20px;
244
+}
245
+.image-tag{
246
+	position:absolute;
247
+	top:10px;
248
+	left:10px;
249
+	font-size:24px;
250
+	font-weight:bold;
251
+	color: #6d4f26;
252
+}
253
+.students-title{
254
+	padding:0 30rpx;
255
+}
256
+.add-icon{
257
+	display:inline-block;
258
+	width:40px;
259
+	height:40px;
260
+	line-height:40px;
261
+	text-align:center;
262
+	font-size:22px;
263
+}
264
+.student-input{
265
+	height:40px;
266
+	line-height:40px;
267
+	border-radius:20px;
268
+	background-color:#fff;
269
+}
270
+.radius-student{
271
+	border-radius:20rpx;
272
+}
273
+.cu-inner{
274
+	margin:10rpx;
275
+	display:flex;
276
+	align-items:center;
277
+	width:100%;
278
+}
279
+.cu-inner.checked{
280
+    background: #5fd0e4;
281
+    color: #fff;
282
+    border-radius: 20rpx;
283
+}
284
+.cu-dialog{
285
+	width:90%;
286
+}
287
+.modal-title{
288
+    font-weight: bold;
289
+    color: #516029;
290
+    font-size: 20px;
291
+}
292
+.font-check{
293
+	font-size:22px;
294
+}
295
+.cu-list>.cu-item .move.student-move{
296
+	width:130rpx;
297
+	text-align:center;
298
+}
299
+.cu-list>.cu-item.move-cur{
300
+	transform: translateX(-130rpx);
301
+}
302
+</style>

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

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

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

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

+ 115 - 100
src/store/user.js

@@ -1,100 +1,115 @@
1
-export default {
2
-  state: {
3
-    user: null,
4
-    token: '',
5
-    session: '',
6
-    kid: 0,
7
-    carts: []// 购物车
8
-  },
9
-  getters: {
10
-    user(state) {
11
-      return state.user || JSON.parse(uni.getStorageSync('user'))
12
-    },
13
-    kid(state) {
14
-      return state.kid || uni.getStorageSync('kid')
15
-    },
16
-    token(state) {
17
-      return state.token || uni.getStorageSync('token')
18
-    },
19
-    session(state) {
20
-      return state.session || uni.getStorageSync('session')
21
-    },
22
-    carts(state) {
23
-      return state.carts || JSON.parse(uni.getStorageSync('carts'))
24
-    }
25
-  },
26
-  mutations: {
27
-    CLEAR(state) {
28
-      state.user = null
29
-      state.token = ''
30
-      state.session = ''
31
-      state.kid = 0
32
-      state.carts = null
33
-      uni.clearStorage()
34
-    },
35
-    SET_USER(state, user) {
36
-      state.user = user
37
-      uni.setStorage({
38
-        key: 'user',
39
-        data: JSON.stringify(user)
40
-      })
41
-    },
42
-    SET_KID(state, kid) {
43
-      state.kid = kid
44
-      uni.setStorage({
45
-        key: 'kid',
46
-        data: kid
47
-      })
48
-    },
49
-    SET_TOKEN(state, token) {
50
-      state.token = token
51
-      uni.setStorage({
52
-        key: 'token',
53
-        data: token
54
-      })
55
-    },
56
-    SET_SESSION(state, session) {
57
-      state.session = session
58
-      uni.setStorage({
59
-        key: 'session',
60
-        data: session
61
-      })
62
-    },
63
-    SET_CARTS(state, carts = []) {
64
-      state.carts = carts
65
-      uni.setStorage({
66
-        key: 'carts',
67
-        data: JSON.stringify(carts)
68
-      })
69
-    }
70
-  },
71
-  actions: {
72
-    clear({ commit }) {
73
-      return new Promise((resolve, reject) => {
74
-        commit('CLEAR')
75
-        resolve(true)
76
-      })
77
-    },
78
-    setUser({ commit }, user) {
79
-      commit('SET_USER', user)
80
-    },
81
-    setKid({ commit }, kid) {
82
-      return new Promise((resolve, reject) => {
83
-        commit('SET_KID', kid)
84
-        resolve(kid)
85
-      })
86
-    },
87
-    setToken({ commit }, token) {
88
-      return new Promise((resolve, reject) => {
89
-        commit('SET_TOKEN', token)
90
-        resolve(token)
91
-      })
92
-    },
93
-    setSession({ commit }, session) {
94
-      commit('SET_SESSION', session)
95
-    },
96
-    setCarts({ commit }, carts) {
97
-      commit('SET_CARTS', carts)
98
-    }
99
-  }
100
-}
1
+export default {
2
+  state: {
3
+    user: null,
4
+    token: '',
5
+    session: '',
6
+    kid: 0,
7
+    phone: '',
8
+    carts: []// 购物车
9
+  },
10
+  getters: {
11
+    user(state) {
12
+      return state.user || JSON.parse(uni.getStorageSync('user'))
13
+    },
14
+    kid(state) {
15
+      return state.kid || uni.getStorageSync('kid')
16
+    },
17
+    phone(state) {
18
+      return state.phone || uni.getStorageSync('phone')
19
+    },
20
+    token(state) {
21
+      return state.token || uni.getStorageSync('token')
22
+    },
23
+    session(state) {
24
+      return state.session || uni.getStorageSync('session')
25
+    },
26
+    carts(state) {
27
+      return state.carts || JSON.parse(uni.getStorageSync('carts'))
28
+    }
29
+  },
30
+  mutations: {
31
+    CLEAR(state) {
32
+      state.user = null
33
+      state.token = ''
34
+      state.session = ''
35
+      state.phone = ''
36
+      state.kid = 0
37
+      state.carts = null
38
+      uni.clearStorage()
39
+    },
40
+    SET_USER(state, user) {
41
+      state.user = user
42
+      uni.setStorage({
43
+        key: 'user',
44
+        data: JSON.stringify(user)
45
+      })
46
+    },
47
+    SET_PHONE(state, phone) {
48
+      state.phone = phone
49
+      uni.setStorage({
50
+        key: 'phone',
51
+        data: phone
52
+      })
53
+    },
54
+    SET_KID(state, kid) {
55
+      state.kid = kid
56
+      uni.setStorage({
57
+        key: 'kid',
58
+        data: kid
59
+      })
60
+    },
61
+    SET_TOKEN(state, token) {
62
+      state.token = token
63
+      uni.setStorage({
64
+        key: 'token',
65
+        data: token
66
+      })
67
+    },
68
+    SET_SESSION(state, session) {
69
+      state.session = session
70
+      uni.setStorage({
71
+        key: 'session',
72
+        data: session
73
+      })
74
+    },
75
+    SET_CARTS(state, carts = []) {
76
+      state.carts = carts
77
+      uni.setStorage({
78
+        key: 'carts',
79
+        data: JSON.stringify(carts)
80
+      })
81
+    }
82
+  },
83
+  actions: {
84
+    clear({ commit }) {
85
+      return new Promise((resolve, reject) => {
86
+        commit('CLEAR')
87
+        resolve(true)
88
+      })
89
+    },
90
+    setUser({ commit }, user) {
91
+      commit('SET_USER', user)
92
+    },
93
+    setPhone({ commit }, phone) {
94
+      commit('SET_PHONE', phone)
95
+    },
96
+    setKid({ commit }, kid) {
97
+      return new Promise((resolve, reject) => {
98
+        commit('SET_KID', kid)
99
+        resolve(kid)
100
+      })
101
+    },
102
+    setToken({ commit }, token) {
103
+      return new Promise((resolve, reject) => {
104
+        commit('SET_TOKEN', token)
105
+        resolve(token)
106
+      })
107
+    },
108
+    setSession({ commit }, session) {
109
+      commit('SET_SESSION', session)
110
+    },
111
+    setCarts({ commit }, carts) {
112
+      commit('SET_CARTS', carts)
113
+    }
114
+  }
115
+}