周立森 5 年之前
當前提交
4ad275f456
共有 24 個文件被更改,包括 2011 次插入0 次删除
  1. 22
    0
      .gitignore
  2. 10
    0
      babel.config.js
  3. 57
    0
      package.json
  4. 二進制
      public/favicon.ico
  5. 13
    0
      public/index.html
  6. 168
    0
      src/App.vue
  7. 二進制
      src/assets/logo.png
  8. 二進制
      src/assets/screen.png
  9. 94
    0
      src/config/api.js
  10. 13
    0
      src/main.js
  11. 12
    0
      src/openId.js
  12. 127
    0
      src/router.js
  13. 6
    0
      src/utils/comptype.js
  14. 6
    0
      src/utils/httpcode.js
  15. 64
    0
      src/utils/request.js
  16. 17
    0
      src/utils/uploadImage.js
  17. 9
    0
      src/utils/user.js
  18. 138
    0
      src/view/detail.vue
  19. 152
    0
      src/view/echarts/bar.vue
  20. 121
    0
      src/view/echarts/pie.vue
  21. 264
    0
      src/view/index.vue
  22. 443
    0
      src/view/list.vue
  23. 260
    0
      src/view/login.vue
  24. 15
    0
      vue.config.js

+ 22
- 0
.gitignore 查看文件

@@ -0,0 +1,22 @@
1
+.DS_Store
2
+node_modules
3
+/dist
4
+package-lock.json
5
+
6
+# local env files
7
+.env.local
8
+.env.*.local
9
+
10
+# Log files
11
+npm-debug.log*
12
+yarn-debug.log*
13
+yarn-error.log*
14
+
15
+# Editor directories and files
16
+.idea
17
+.vscode
18
+*.suo
19
+*.ntvs*
20
+*.njsproj
21
+*.sln
22
+*.sw*

+ 10
- 0
babel.config.js 查看文件

@@ -0,0 +1,10 @@
1
+module.exports = {
2
+  presets: ['@vue/app'],
3
+  plugins: [
4
+    [
5
+      'import',
6
+      { libraryName: 'vant', libraryDirectory: 'es', style: true },
7
+      'vant'
8
+    ]
9
+  ]
10
+};

+ 57
- 0
package.json 查看文件

@@ -0,0 +1,57 @@
1
+{
2
+  "name": "vant-demo",
3
+  "version": "1.0.0",
4
+  "description": "Collection of vant demos.",
5
+  "author": "neverland <chenjiahan@neverl.com>",
6
+  "license": "MIT",
7
+  "scripts": {
8
+    "serve": "vue-cli-service serve",
9
+    "build": "vue-cli-service build",
10
+    "lint": "vue-cli-service lint"
11
+  },
12
+  "dependencies": {
13
+    "axios": "^0.19.0",
14
+    "blueimp-md5": "^2.12.0",
15
+    "dayjs": "^1.8.17",
16
+    "echarts": "^4.5.0",
17
+    "nprogress": "^0.2.0",
18
+    "vant": "^2.2.0",
19
+    "vue": "^2.6.10",
20
+    "vue-echarts": "^4.0.4",
21
+    "vue-router": "^3.0.5",
22
+    "vue-cookies": "^1.5.13"
23
+  },
24
+  "devDependencies": {
25
+    "@vue/cli-plugin-babel": "^3.8.0",
26
+    "@vue/cli-plugin-eslint": "^3.8.0",
27
+    "@vue/cli-service": "^3.8.3",
28
+    "babel-plugin-import": "^1.12.0",
29
+    "less": "^3.8.1",
30
+    "less-loader": "^5.0.0",
31
+    "vue-cookies": "^1.5.13",
32
+    "vue-template-compiler": "^2.6.10"
33
+  },
34
+  "eslintConfig": {
35
+    "root": true,
36
+    "env": {
37
+      "node": true
38
+    },
39
+    "extends": [
40
+      "plugin:vue/essential",
41
+      "eslint:recommended"
42
+    ],
43
+    "rules": {},
44
+    "parserOptions": {
45
+      "parser": "babel-eslint"
46
+    }
47
+  },
48
+  "postcss": {
49
+    "plugins": {
50
+      "autoprefixer": {}
51
+    }
52
+  },
53
+  "browserslist": [
54
+    "Android >= 4.0",
55
+    "iOS >= 7"
56
+  ]
57
+}

二進制
public/favicon.ico 查看文件


+ 13
- 0
public/index.html 查看文件

@@ -0,0 +1,13 @@
1
+<!DOCTYPE html>
2
+<html>
3
+  <head>
4
+    <meta charset="utf-8">
5
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
7
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
8
+    <title>welcome</title>
9
+  </head>
10
+  <body>
11
+    <div id="app"></div>
12
+  </body>
13
+</html>

+ 168
- 0
src/App.vue 查看文件

@@ -0,0 +1,168 @@
1
+<template>
2
+  <div id="app">
3
+    <router-view />
4
+  </div>
5
+</template>
6
+
7
+
8
+<script>
9
+// import { request } from 'http'
10
+// import apis from "./config/api";
11
+// import request from "./utils/request";
12
+
13
+export default {
14
+  name: 'app',
15
+  components: {
16
+
17
+  },
18
+  data () {
19
+    return {
20
+      // list: [],
21
+    }
22
+  },
23
+  methods: {
24
+    // getDevice () {
25
+    //   request({
26
+    //     ...apis.device,
27
+    //     params: { pageNum: 1, pageSize: 999 }
28
+    //   }).then(res => {
29
+    //     // console.log("data:", res.records);
30
+    //     this.device = res.records || [];
31
+    //   });
32
+    // },
33
+
34
+    
35
+
36
+    // checkLogin () {
37
+    //   // this.$cookies.remove("oepnid")
38
+    //   request({
39
+    //     ...apis.user
40
+    //   }).then((user) => {
41
+    //     //  console.log(isLogin,'999999')
42
+    //     if (user) {
43
+    //       this.$cookies.set("oepnid", user.openid)
44
+    //       localStorage.setItem("nickname", user.nickname);
45
+    //       // islocalStorage.setItem("is", user.nickname);
46
+
47
+    //       // this.$router.push({name:'index'}); 
48
+    //     } else {
49
+    //       window.console.log("00000")
50
+    //     }
51
+
52
+    //   }).catch(() => {
53
+    //     // const isopenid = this.$cookies.isKey("oepnid")
54
+    //     window.console.log(isopenid, 'isopenid')
55
+    //     if (isopenid) {
56
+    //       const openid = this.$cookies.get("oepnid")
57
+    //       window.console.log(openid, 'openid')
58
+    //       // this.loginByOpenid(openid)
59
+    //     } else {
60
+    //       this.getOpenid()
61
+    //     }
62
+
63
+    //   })
64
+    // },
65
+
66
+    //用code获取openid
67
+    
68
+  },
69
+
70
+  created () {
71
+
72
+    // this.checkLogin()
73
+
74
+    // getOpenId().then((openid) => {
75
+    //   getUserInfo(openid).then((user) => {
76
+    //     if (user.status === 0) {
77
+    //       route.goto('xxx')
78
+    //     } else {
79
+    //       getDetail().then((list) => {
80
+    //         this.list = list
81
+    //       })
82
+    //     }
83
+    //   })
84
+    // })
85
+
86
+
87
+
88
+    // const openid = localStorage.openid
89
+    // const code = ''//取code  query里
90
+
91
+    // const coded = localStorage.code//缓存code
92
+    // if (oepnid) {
93
+    //   //登录状态
94
+
95
+    //   // const coded = localStorage.code
96
+    //   // if (coded) {
97
+    //   //   if (coded == code) {
98
+    //   //     // 跳登录
99
+    //   //   } else {
100
+    //   //     window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx18765573b7565aed&redirect_uri=" + "" + encodeURIComponent(http) + "" + "&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
101
+    //   //   }
102
+    //   // } else {
103
+    //   //   const coded = localStorage.coded
104
+    //   // }
105
+
106
+    //   // if (code)
107
+
108
+
109
+    // } else {
110
+
111
+
112
+
113
+    //   if (code) {
114
+
115
+
116
+    //     // if (新 code) {
117
+
118
+    //     // } else {
119
+
120
+
121
+    //     }
122
+
123
+
124
+    //     if (code && !coded) {
125
+    //       localStorage.coded = code
126
+    //       //传code获取oepnid
127
+
128
+    //     }
129
+    //     else if (code != coded) {
130
+    //       const http = "https://wx.jinchengjiaye.com"
131
+
132
+
133
+
134
+    //       window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx18765573b7565aed&redirect_uri=" + "" + encodeURIComponent(http) + "" + "&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
135
+    //     }else if(code == coded){
136
+    //       //传code获取oepnid
137
+    //     }
138
+    //     // if (code == coded) {
139
+    //     //    
140
+    //     // }else{
141
+
142
+    //     // }
143
+
144
+    //   } else {
145
+    //     // 获取code
146
+    //     const http = "https://wx.jinchengjiaye.com"
147
+
148
+    //     console.log(encodeURIComponent(http), '--------')
149
+
150
+    //     window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx18765573b7565aed&redirect_uri=" + "" + encodeURIComponent(http) + "" + "&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
151
+    //   }
152
+
153
+    // }
154
+    // console.log('openid', openid)
155
+  }
156
+}
157
+</script>
158
+
159
+<style>
160
+body {
161
+  font-size: 16px;
162
+  background-color: #f8f8f8;
163
+  -webkit-font-smoothing: antialiased;
164
+  text-align: center;
165
+  font-family: PingFangSC-Regular, PingFang SC;
166
+  margin: 0;
167
+}
168
+</style>

二進制
src/assets/logo.png 查看文件


二進制
src/assets/screen.png 查看文件


+ 94
- 0
src/config/api.js 查看文件

@@ -0,0 +1,94 @@
1
+const commPrefix = 'api'
2
+
3
+const apis = {
4
+
5
+  login:{
6
+    url: `${commPrefix}/login`,
7
+    method: 'post',
8
+   
9
+  },
10
+  loginPhone:{
11
+    url: `${commPrefix}/wx/loginPhone`,
12
+    method: 'put',
13
+   
14
+  },
15
+  getcode:{
16
+    url: `${commPrefix}/wx/captcha`,
17
+    method: 'post',
18
+   
19
+  },
20
+  
21
+  user:{
22
+    url: `${commPrefix}/user`,
23
+    method: 'get',
24
+  },
25
+  getOpenId: {
26
+
27
+    url: `${commPrefix}/wx/getOpenId`,
28
+    method: 'get',
29
+
30
+  },
31
+  // api/stats/person
32
+  // Request Method: GETapi/person
33
+  personTotal: {
34
+
35
+    url: `${commPrefix}/stats/person`,
36
+    method: 'get',
37
+    
38
+  },
39
+  barData: {
40
+    url: `${commPrefix}/stats/daily/visitinglog`,
41
+    method: 'get',
42
+  },
43
+  visitinglog: {
44
+    url: `${commPrefix}/visitinglog`,
45
+    method: 'get',
46
+  },
47
+  
48
+  person: {
49
+
50
+    url: `${commPrefix}/person`,
51
+    method: 'get',
52
+    
53
+  },
54
+  personType: {
55
+
56
+    url: `${commPrefix}/person_type`,
57
+    method: 'get',
58
+    
59
+  },
60
+  device: {
61
+  url: `${commPrefix}/device`,
62
+  method: 'get',
63
+  
64
+},
65
+
66
+loginByOpenid: {
67
+  url: `${commPrefix}/wx/loginByOpenid`,
68
+  method: 'get',
69
+  
70
+},
71
+
72
+logout: {
73
+      method: 'post',
74
+      url: `${commPrefix}/logout`
75
+    },
76
+    getUserInfo: {
77
+      method: 'get',
78
+      url: `${commPrefix}/wx/getUserInfo`
79
+    },
80
+
81
+  // api/stats/daily/visitinglog?startDate=2019-09-01T00:00:00&endDate=2019-12-05T23:59:59
82
+  // person: {
83
+    // api/person_type
84
+  //   url: `${commPrefix}/api/stats/daily/visitinglog`,
85
+  //   method: 'get',
86
+
87
+  // },
88
+  // api/stats/daily/visitinglog?startDate=2019-12-01T00:00:00&endDate=2019-12-04T23:59:59
89
+
90
+
91
+
92
+}
93
+
94
+export default apis

+ 13
- 0
src/main.js 查看文件

@@ -0,0 +1,13 @@
1
+import Vue from 'vue';
2
+import App from './App';
3
+import { router } from './router';
4
+import ECharts from 'vue-echarts'
5
+// import VueCookies from 'vue-cookies'
6
+// Vue.use(VueCookies)
7
+
8
+Vue.component('v-chart', ECharts)
9
+new Vue({
10
+  router,
11
+  el: '#app',
12
+  render: h => h(App)
13
+});

+ 12
- 0
src/openId.js 查看文件

@@ -0,0 +1,12 @@
1
+// import apis from "./config/api";
2
+// import request from "./utils/request";
3
+
4
+
5
+// function getUserInfo(){
6
+//   request({
7
+//     ...apis.getUserInfo,
8
+    
9
+//   }).then(res => {
10
+    
11
+//   });
12
+// }

+ 127
- 0
src/router.js 查看文件

@@ -0,0 +1,127 @@
1
+import Vue from 'vue';
2
+import Router from 'vue-router';
3
+import apis from "./config/api";
4
+import request from "./utils/request";
5
+import { setUser } from './utils/user';
6
+
7
+Vue.use(Router);
8
+
9
+const routes = [
10
+  {
11
+    path: '*',
12
+    redirect: '/index'
13
+  },
14
+  {
15
+    name: 'index',
16
+    component: () => import('./view/index'),
17
+    meta: {
18
+      title: '迎宾判客'
19
+    }
20
+  },
21
+  {
22
+    name: 'login',
23
+    component: () => import('./view/login'),
24
+    meta: {
25
+      title: '登录'
26
+    }
27
+  },
28
+  {
29
+    name: 'list',
30
+    component: () => import('./view/list'),
31
+    meta: {
32
+      title: '客户列表'
33
+    }
34
+  },
35
+  {
36
+    name: 'detail',
37
+    component: () => import('./view/detail'),
38
+    meta: {
39
+      title: '客户详情'
40
+    }
41
+  },
42
+  // {
43
+  //   name: 'goods',
44
+  //   component: () => import('./view/goods'),
45
+  //   meta: {
46
+  //     title: '商品详情'
47
+  //   }
48
+  // }
49
+];
50
+
51
+// function getUserInfo(){
52
+//   request({
53
+//     ...apis.getUserInfo,
54
+
55
+//   }).then(res => {
56
+
57
+//   });
58
+// }
59
+var isLogin = 0
60
+
61
+// add route path
62
+routes.forEach(route => {
63
+  route.path = route.path || '/' + (route.name || '');
64
+});
65
+
66
+const router = new Router({ routes });
67
+
68
+router.beforeEach((to, from, next) => {
69
+  const title = to.meta && to.meta.title;
70
+  if (title) {
71
+    document.title = title;
72
+  }
73
+  // debugger
74
+
75
+
76
+  if (to.name === 'login') {
77
+    next()
78
+    return
79
+  }
80
+
81
+  if (isLogin) {
82
+
83
+    next()
84
+  } else {
85
+    const openid = 'oztJW0VV0-VKiut_0nq6MfHpQ0No'
86
+    // const openid = localStorage.getItem("openid")
87
+    // window.console.log('openid,', openid)
88
+    if (openid) {
89
+      request({
90
+        ...apis.loginByOpenid,
91
+        params: { openid: openid }
92
+
93
+      }).then((user) => {
94
+//         window.console.log('user,', user)
95
+// debugger
96
+        setUser(user)
97
+
98
+        isLogin = 1
99
+        localStorage.setItem("nickname", user.nickname);
100
+        localStorage.setItem("openid", user.openid);
101
+        // console.log(user, 'user');
102
+        next()
103
+      }).catch(()=>{
104
+        if (to.name === 'login') {
105
+          next()
106
+        } else {
107
+          next({ name: 'login' })
108
+  
109
+        }
110
+      });
111
+    } else {
112
+
113
+      if (to.name === 'login') {
114
+        next()
115
+      } else {
116
+        next({ name: 'login' })
117
+
118
+      }
119
+    }
120
+    next()
121
+  }
122
+  });
123
+
124
+
125
+export {
126
+  router
127
+};

+ 6
- 0
src/utils/comptype.js 查看文件

@@ -0,0 +1,6 @@
1
+export const CTYP_GROUP = 'G-';
2
+export const CTYP_SINGLE_LINE = 'single-line';
3
+export const CTYP_MULTI_LINE = 'multi-line';
4
+export const CTYP_IMAGE = 'image';
5
+export const CTYP_MAP = 'map';
6
+export const CTYP_CONTACT_FORM = `${CTYP_GROUP}contact_form`;

+ 6
- 0
src/utils/httpcode.js 查看文件

@@ -0,0 +1,6 @@
1
+export default {
2
+  HTTP_OK: 200,
3
+  HTTP_MULTIPLECHOICES: 300,
4
+  HTTP_BADREQUEST: 400,
5
+  HTTP_UNAUTHORIZED: 401
6
+}

+ 64
- 0
src/utils/request.js 查看文件

@@ -0,0 +1,64 @@
1
+import axios from 'axios'
2
+
3
+// 远程请求, 返回 promise
4
+// 参数 api 与 axios 基本一致
5
+// 增加了一个 urlData 字段, 用来设置 url path 变量值
6
+function request (params = {}) {
7
+  const { urlData, data: rawData, url: rawURL, headers = {}, ...config } = params;
8
+  const url = replaceApiParams(rawURL, urlData)
9
+  // const data = (rawData instanceof FormData) ? rawData : JSON.stringify(rawData)
10
+  const token = localStorage.getItem('x-token') || ''
11
+  const contenType = (rawData instanceof FormData) ? 'multipart/form-data' : 'application/json'
12
+  // console.log(params,url,token,contenType)
13
+  return new Promise((resolve, reject) => {
14
+    console.log('url', url)
15
+    axios({
16
+      ...config,
17
+      url,
18
+      data: rawData,
19
+      headers: {
20
+        'Content-Type': contenType,
21
+        ...headers,
22
+        'Authorization': `Bearer ${token}`,
23
+      }
24
+    }).then(({ data: res }) => {
25
+      console.log(res)
26
+      // 服务端返回包含 code, message, data 字段
27
+      const { code, data, result } = res
28
+      if (result) { resolve(result) }
29
+      // 业务处理正确则返回 200
30
+      if (code - 200 === 0) {
31
+        resolve(data)
32
+      } else {
33
+        reject(res)
34
+      }
35
+
36
+    }).catch((error) => {
37
+      console.log(error, 'error')
38
+      // 异常情况
39
+      if (error.response) {
40
+        reject({ message: error.response.statusText })
41
+      } else {
42
+        reject({ message: error.message })
43
+      }
44
+    })
45
+  })
46
+}
47
+
48
+// /a/b/:id    {id:1}   ===> /a/b/1
49
+function replaceApiParams (url, params) {
50
+  if (typeof params !== 'object') return url
51
+
52
+  return url.split('/').map((it) => {
53
+    if (it.indexOf(':') === 0) {
54
+      const theKey = it.substr(1)
55
+      return Object.prototype.hasOwnProperty.call(params, theKey)
56
+        ? params[theKey]
57
+        : it
58
+    }
59
+
60
+    return it
61
+  }).join('/')
62
+}
63
+
64
+export default request

+ 17
- 0
src/utils/uploadImage.js 查看文件

@@ -0,0 +1,17 @@
1
+import request from './request';
2
+import apis from '../config/api';
3
+
4
+export default (file) => {
5
+  return new Promise((resolve, reject) => {
6
+    const fm = new FormData()
7
+    fm.append('file', file)
8
+    request({
9
+      ...apis.file.upload,
10
+      data: fm,
11
+    }).then((data) => {
12
+      resolve(data)
13
+    }).catch((err) => {
14
+      reject(err.message || err)
15
+    })
16
+  })
17
+}

+ 9
- 0
src/utils/user.js 查看文件

@@ -0,0 +1,9 @@
1
+let user = {}
2
+
3
+export function setUser(u) {
4
+  user = u
5
+}
6
+
7
+export function getUser() {
8
+  return user
9
+}

+ 138
- 0
src/view/detail.vue 查看文件

@@ -0,0 +1,138 @@
1
+<template>
2
+  <div>
3
+    <!-- <Head></Head> -->
4
+
5
+    <van-pull-refresh v-model="isLoading" @refresh="onRefresh">
6
+      <van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
7
+        <van-cell v-for="item in data" :key="item" value="time">
8
+          <!-- 使用 title 插槽来自定义标题 -->
9
+          <template slot="title">
10
+            <div>
11
+              <div style="display:flex">
12
+                <img :src="item.avatar" class="image" @click="getImg(item.avatar)" />
13
+                <span class="custom-title">{{item.deviceName}}</span>
14
+              </div>
15
+            </div>
16
+          </template>
17
+          <div class="text">{{item.visiteDate}}</div>
18
+          <!-- <div class="text" style="color:#BB9C79" @click="getImg(image)">点击查看背景大图</div> -->
19
+        </van-cell>
20
+      </van-list>
21
+    </van-pull-refresh>
22
+  </div>
23
+</template>
24
+
25
+
26
+
27
+<script>
28
+import { PullRefresh, List, Cell, ImagePreview } from 'vant';
29
+import apis from "../config/api";
30
+import request from "../utils/request";
31
+
32
+// Vue.use(ImagePreview)
33
+
34
+export default {
35
+  name: 'detail',
36
+  components: {
37
+    [PullRefresh.name]: PullRefresh,
38
+    [List.name]: List,
39
+    [Cell.name]: Cell,
40
+
41
+
42
+  },
43
+  data () {
44
+    return {
45
+      image: "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3284481034,4167336265&fm=26&gp=0.jpg",
46
+      isLoading: false,
47
+      data:{},
48
+      list: [],
49
+      loading: false,
50
+      finished: false,
51
+      pageNavi: {
52
+        current: 1,
53
+        total: 0,
54
+        size: 10
55
+      },
56
+    }
57
+  },
58
+  methods: {
59
+    getvisitinglog () {
60
+      const personId=this.$route.query.id
61
+      // console.log('personId',personId)
62
+      request({
63
+        ...apis.visitinglog,
64
+        params: { personId:personId, pageNum: 1, pageSize: 999 }
65
+      }).then(res => {
66
+      
67
+        // console.log("data:", res);
68
+     
69
+        this.data = res.records;
70
+        this.loading = false;
71
+        if (res.size >= res.total) {
72
+          this.finished = true;
73
+        }
74
+   
75
+      });
76
+    },
77
+    onRefresh () {
78
+      setTimeout(() => {
79
+        // this.$toast('刷新成功');
80
+        this.isLoading = false;
81
+
82
+      }, 500);
83
+    },
84
+    onLoad () {
85
+      // 异步更新数据
86
+      setTimeout(() => {
87
+        for (let i = 0; i < 10; i++) {
88
+          this.list.push(this.list.length + 1);
89
+        }
90
+        // 加载状态结束
91
+        this.loading = false;
92
+
93
+        // 数据全部加载完成
94
+        if (this.list.length >= 40) {
95
+          this.finished = true;
96
+        }
97
+      }, 500);
98
+    },
99
+    getImg (image) {
100
+      ImagePreview({
101
+        images: [
102
+          image
103
+        ],
104
+        showIndex: false
105
+      });
106
+
107
+    }
108
+
109
+  },
110
+  created () {
111
+          this.getvisitinglog()
112
+  }
113
+}
114
+</script>
115
+
116
+
117
+
118
+<style lang="less" scoped>
119
+.image {
120
+  width: 32px;
121
+  height: 32px;
122
+  border-radius: 16px;
123
+  margin-right: 10px;
124
+}
125
+.custom-title {
126
+  font-size: 15px;
127
+  font-weight: 400;
128
+  color: rgba(0, 0, 0, 1);
129
+  line-height: 32px;
130
+}
131
+.text {
132
+  font-size: 12px;
133
+
134
+  font-weight: 400;
135
+  color: rgba(136, 136, 136, 1);
136
+  line-height: 17px;
137
+}
138
+</style>

+ 152
- 0
src/view/echarts/bar.vue 查看文件

@@ -0,0 +1,152 @@
1
+<template>
2
+  <v-chart class="x-chart" :options="options" autoresize></v-chart>
3
+</template>
4
+
5
+<script>
6
+// import 'echarts/lib/chart/bar'
7
+// import 'echarts/lib/component/tooltip'
8
+
9
+import "echarts/lib/chart/bar";
10
+import "echarts/lib/component/title";
11
+import "echarts/lib/component/dataZoom";
12
+import "echarts/lib/component/tooltip";
13
+import "echarts/lib/component/legend";
14
+export default {
15
+  components: {},
16
+
17
+  data() {
18
+    // return {
19
+    //   options: {},
20
+    return {
21
+      opts: {
22
+        color: "#FFA720",
23
+        // tooltip: {
24
+        //   formatter: (params, ticket, callback) => {
25
+        //     const { visiteDate, amount } = params.data;
26
+        //     const tip = `${visiteDate}: ${amount}`;
27
+        //     callback(ticket, tip);
28
+        //     return tip;
29
+        //   }
30
+        // },
31
+        xAxis: {
32
+          name: "日",
33
+          type: "category",
34
+
35
+          splitLine: {
36
+            show: false
37
+          },
38
+          axisTick: {
39
+            show: false,
40
+            interval: 0
41
+          },
42
+          axisLabel: {
43
+            fontsize: "8px",
44
+            interval: 0
45
+          }
46
+          // xAxis.axisLabel.interval
47
+          //       axisLabel: {    // 坐标轴标签
48
+          //   show: true,  // 是否显示
49
+          //   inside: false, // 是否朝内
50
+          //   rotate: 0, // 旋转角度
51
+          //   margin: 5, // 刻度标签与轴线之间的距离
52
+          //   color: 'red'  // 默认取轴线的颜色
53
+          // },
54
+        },
55
+        yAxis: {
56
+          name: "人/日",
57
+          splitLine: {
58
+            show: false
59
+          }
60
+        },
61
+        series: [
62
+          {
63
+            type: "bar",
64
+            // smooth: true,
65
+            encode: {
66
+              x: "visiteDate",
67
+              y: "amount"
68
+            },
69
+            barWidth: "50%"
70
+            // barMaxWidth: '10%'
71
+          }
72
+        ],
73
+        // dataZoom: [
74
+        //   {
75
+        //     type: "inside",
76
+        //     show: true,
77
+        //     start: 0,
78
+        //     end: 100
79
+        //   }
80
+        //   // {
81
+        //   //   type: 'slider',
82
+        //   //   show: true,
83
+        //   //   start: 0,
84
+        //   //   end: 100,
85
+        //   // }
86
+        // ],
87
+        dataset: {
88
+          sourceHeader: false,
89
+          dimensions: ["visiteDate", "amount"]
90
+        }
91
+      }
92
+      // }
93
+    };
94
+  },
95
+  props: ["barData"],
96
+
97
+  created() {},
98
+  computed: {
99
+    options() {
100
+      console.log(this.barData, "barData");
101
+      return {
102
+        ...this.opts,
103
+        // title: {
104
+        //   ...this.opts.title
105
+        // },
106
+        dataset: {
107
+          ...this.opts.dataset,
108
+          source: this.barData || []
109
+        }
110
+      };
111
+    }
112
+  },
113
+
114
+  mounted() {
115
+    // console.log(this.barData, "barData");
116
+    // this.options={
117
+    //     ...this.opts,
118
+    //     title: {
119
+    //       ...this.opts.title,
120
+    //     },
121
+    //     dataset: {
122
+    //       ...this.opts.dataset,
123
+    //       source: this.source || [],
124
+    //     }
125
+    // }
126
+    // this.options = {
127
+    //   color:['#FFA720'],
128
+    //   xAxis: {
129
+    //     type: 'category',
130
+    //     data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
131
+    //   },
132
+    //   yAxis: {
133
+    //     type: 'value'
134
+    //   },
135
+    //   series: [{
136
+    //     data: [120, 200, 150, 80, 70, 110, 130],
137
+    //     type: 'bar'
138
+    //   }]
139
+    // };
140
+  },
141
+
142
+  methods: {}
143
+};
144
+</script>
145
+
146
+<style lang="less">
147
+.x-chart {
148
+  margin: 0 auto;
149
+  // width: 100%;
150
+  // height: 100%;
151
+}
152
+</style>

+ 121
- 0
src/view/echarts/pie.vue 查看文件

@@ -0,0 +1,121 @@
1
+<template>
2
+  <v-chart class="x-chart" :options="options" autoresize></v-chart>
3
+</template>
4
+
5
+<script>
6
+// import 'echarts/lib/chart/bar'
7
+// import 'echarts/lib/component/tooltip'
8
+import "echarts/lib/chart/line";
9
+import "echarts/lib/chart/pie";
10
+import "echarts/lib/component/title";
11
+import "echarts/lib/component/dataZoom";
12
+import "echarts/lib/component/tooltip";
13
+import "echarts/lib/component/legend";
14
+export default {
15
+  components: {},
16
+
17
+  data() {
18
+    return {
19
+      // options: {}
20
+      // data:{}
21
+    };
22
+  },
23
+  props: ["piedata"],
24
+  created() {},
25
+
26
+  computed: {
27
+  
28
+    
29
+    // this.options = 
30
+    
31
+    options() {
32
+      let newtoday = (this.piedata.today - parseInt(this.piedata.regular))||0
33
+      let oldtoday = parseInt(this.piedata.regular)||'0'
34
+      let total = this.piedata.today||1
35
+      window.console.log('total',total)
36
+    let legendData =
37
+      [
38
+        { name: "老客户", value: parseInt(this.piedata.regular) },
39
+        { name: "新客户", value: newtoday }
40
+      ] || []
41
+    return {color: ["#BB9C79", "#FFA720"],
42
+      legend: {
43
+        orient: "vertical",
44
+        x: "right",
45
+        data: ["老客户", "新客户"],   
46
+        formatter: function(name) {
47
+          let target;
48
+          for (let i = 0; i < legendData.length; i++) {
49
+            if (legendData[i].name === name) {
50
+              target = legendData[i].value||0;
51
+            }
52
+          }
53
+          window.console.log('target',target)
54
+          var p = (((target / total) * 100).toFixed(2))||0;
55
+          window.console.log('p',p)
56
+          let arr = [
57
+            "{b|" + name + "}",
58
+            "{a|" + target + "}",
59
+            "{c|" + p + "%" + "}"
60
+          ];
61
+          return arr.join(" ");
62
+        },
63
+        textStyle: {
64
+          rich: {
65
+            a: {
66
+              fontSize: 16,
67
+              color: "#353535",
68
+              padding: 10
69
+            },
70
+            b: {
71
+              fontSize: 14,
72
+              color: "#353535"
73
+            },
74
+            c: {
75
+              fontSize: 14,
76
+              color: "#888"
77
+            }
78
+          }
79
+        }
80
+      },
81
+      series: [
82
+        {
83
+          label: {
84
+            normal: {
85
+              show: false,
86
+              position: "center"
87
+            }
88
+          },
89
+          labelLine: {
90
+                normal: {
91
+                    show: false
92
+                }
93
+            },
94
+          type: "pie",
95
+          center: ["20%", "60%"],
96
+          radius: ["34%", "52%"]
97
+        }
98
+      ],
99
+      dataset: {
100
+        id: "pie",
101
+        source: [
102
+          { name: "老客户", value: this.piedata.today },
103
+          { name: "新客户", value: this.piedata.regular }
104
+        ]
105
+      }
106
+    
107
+    }
108
+    }
109
+  },
110
+
111
+  methods: {}
112
+};
113
+</script>
114
+
115
+<style lang="less">
116
+.x-chart {
117
+  margin: 0 auto;
118
+  width: 100%;
119
+  height: 100%;
120
+}
121
+</style>

+ 264
- 0
src/view/index.vue 查看文件

@@ -0,0 +1,264 @@
1
+<template>
2
+  <div>
3
+    <!-- <Head></Head> -->
4
+    <div class="main">
5
+      <van-cell style="background:none;padding: 0;">
6
+        <div >{{user.nickname}},欢迎使用迎宾判客!</div>
7
+      </van-cell>
8
+
9
+      <van-row class="recording">
10
+        <van-col span="12" class="text-left">
11
+          <router-link :to="{name:'list'}">
12
+            
13
+            <div class="number">{{data.total}}</div>
14
+            <div class="title">总到访客户数</div>
15
+          </router-link>
16
+        </van-col>
17
+        <div class="line"></div>
18
+        <van-col span="12" @click="todaylist" class="text-right">
19
+          <div class="number">{{data.today}}</div>
20
+          <div class="title">今日到访数</div>
21
+        </van-col>
22
+      </van-row>
23
+
24
+      <div class="pie">
25
+        <span class="title">今日到访</span>
26
+        <pie :piedata="data"></pie>
27
+      </div>
28
+      <div class="bar">
29
+        <span class="title">日到访统计</span>
30
+        <bar :barData="barData"></bar>
31
+      </div>
32
+    </div>
33
+  </div>
34
+</template>
35
+
36
+
37
+
38
+<script>
39
+import { Row, Col, Cell, CellGroup } from "vant";
40
+import pie from "./echarts/pie";
41
+import bar from "./echarts/bar";
42
+import apis from "../config/api";
43
+import request from "../utils/request";
44
+import md5 from "blueimp-md5";
45
+import dayjs from "dayjs";
46
+import { getUser } from '../utils/user';
47
+// import index from "./index";
48
+
49
+export default {
50
+  name: "index",
51
+  components: {
52
+    [Row.name]: Row,
53
+    [Col.name]: Col,
54
+
55
+    [Cell.name]: Cell,
56
+    [CellGroup.name]: CellGroup,
57
+    pie,
58
+    bar
59
+  },
60
+  data() {
61
+    return {
62
+      name: "xxx",
63
+      data: {},
64
+      barData: {},
65
+      formdata: {
66
+        username: "admin",
67
+        password: md5("admin")
68
+      },
69
+      startDate: dayjs().subtract(7, "day"),
70
+      // startDate:dayjs().subract(7,'day').toDate(),
71
+      endDate: new dayjs(),
72
+      status: false,
73
+      user: {},
74
+    };
75
+  },
76
+  methods: {
77
+    login() {
78
+      
79
+      
80
+      
81
+      // if (!status) {
82
+      //   const ft = new window.FormData();
83
+      //   Object.keys(this.formdata).forEach(k => {
84
+      //     ft.append(k, this.formdata[k]);
85
+      //   });
86
+      //   console.log(ft, "ft");
87
+      //   request({
88
+      //     ...apis.login,
89
+      //     data: ft
90
+      //     // params: { pageNum: 1, pageSize: 18 }
91
+      //   }).then(res => {
92
+      //     // this.data = res[0];
93
+      //   });
94
+      // } else {
95
+      //   request({
96
+      //     ...apis.user
97
+      //   }).then(res => {
98
+      //     // this.data = res[0];
99
+      //   });
100
+      // }
101
+    },
102
+    getcode() {
103
+      request({
104
+        ...apis.getcode
105
+        // params: { pageNum: 1, pageSize: 18 }
106
+      }).then(res => {
107
+        this.data = res[0];
108
+      });
109
+    },
110
+    total() {
111
+      request({
112
+        ...apis.personTotal
113
+        // params: { pageNum: 1, pageSize: 18 }
114
+      }).then(res => {
115
+        this.data = res[0];
116
+      });
117
+    },
118
+    
119
+    getBarData() {
120
+      // console.log(
121
+      //   this.startDate.format("YYYY-MM-DDTHH:mm:ss"),
122
+      //   this.endDate.format("YYYY-MM-DDTHH:mm:ss"),
123
+      //   "data"
124
+      // );
125
+      request({
126
+        ...apis.barData,
127
+        params: {
128
+          startDate: this.startDate.format("YYYY-MM-DDTHH:mm:ss"),
129
+          endDate: this.endDate.format("YYYY-MM-DDTHH:mm:ss")
130
+        }
131
+      }).then(res => {
132
+        // this.barData = res;
133
+        let data = [];
134
+        res.map(
135
+          (item, index) => (
136
+            // item.visiteDate = item.visiteDate.format("MM.DD"),
137
+            (data[index] = {
138
+              amount: item.amount,
139
+              visiteDate: dayjs(item.visiteDate).format("DD")
140
+            })
141
+            //  dayjs('1995-12-25')
142
+            // console.log("item", dayjs(item.visiteDate).format("MM.DD"))
143
+          )
144
+        );
145
+        this.barData = data;
146
+        // console.log("res", res);
147
+      });
148
+    },
149
+    todaylist(){
150
+      this.$router.push({name:'list',query:{time:'today'}}); 
151
+    },
152
+
153
+    logout(){
154
+      request({
155
+        ...apis.logout
156
+        // params: { pageNum: 1, pageSize: 18 }
157
+      }).then(res => {
158
+        // console.log("logout");
159
+        localStorage.getItem("nickname")
160
+        localStorage.setItem("openid",'');
161
+      });
162
+    }
163
+  },
164
+  created() {
165
+    this.name = localStorage.getItem("nickname")
166
+    
167
+    // this.login();
168
+    this.total();
169
+    this.getBarData();
170
+    // api/stats/daily/visitinglog
171
+  },
172
+  mounted() {
173
+    
174
+    this.user = getUser()
175
+  }
176
+};
177
+</script>
178
+
179
+
180
+
181
+<style lang="less" scoped>
182
+.main {
183
+  padding: 5px 15px 5px 15px;
184
+}
185
+.user {
186
+  float: left;
187
+
188
+  font-size: 12px;
189
+  font-family: PingFangSC-Regular, PingFang SC;
190
+  font-weight: 400;
191
+  color: rgba(136, 136, 136, 1);
192
+  line-height: 17px;
193
+}
194
+.recording {
195
+  height: 69px;
196
+
197
+  background: rgba(255, 255, 255, 1);
198
+  box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.12);
199
+  border-radius: 4px;
200
+  /* margin: 15px 0; */
201
+  margin-top: 15px;
202
+  padding: 20px;
203
+  .text-left {
204
+    height: 69px;
205
+    border-right: 2px solid rgba(242, 242, 242, 1);
206
+  }
207
+  .text-right {
208
+    height: 69px;
209
+    border-left: 2px solid rgba(242, 242, 242, 1);
210
+  }
211
+
212
+  .number {
213
+    height: 45px;
214
+    font-size: 32px;
215
+    font-weight: 500;
216
+    color: rgba(255, 167, 32, 1);
217
+    line-height: 45px;
218
+  }
219
+  .title {
220
+    font-size: 17px;
221
+    font-weight: 400;
222
+    color: rgba(53, 53, 53, 1);
223
+    line-height: 24px;
224
+  }
225
+  //   .line{
226
+  //     width:4px;
227
+  // height:69px;
228
+  // background:rgba(242,242,242,1);
229
+  //   }
230
+}
231
+.pie {
232
+  height: 44.5vw;
233
+  background: rgba(255, 255, 255, 1);
234
+  box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.12);
235
+  border-radius: 4px;
236
+  margin-top: 15px;
237
+  padding: 10px;
238
+  .title {
239
+    float: left;
240
+    font-size: 17px;
241
+
242
+    font-weight: 500;
243
+    color: rgba(187, 156, 121, 1);
244
+    line-height: 24px;
245
+  }
246
+}
247
+
248
+.bar {
249
+  height: 65.4vw;
250
+  background: rgba(255, 255, 255, 1);
251
+  box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.12);
252
+  border-radius: 4px;
253
+  margin-top: 15px;
254
+  padding: 10px;
255
+  .title {
256
+    float: left;
257
+    font-size: 17px;
258
+
259
+    font-weight: 500;
260
+    color: rgba(187, 156, 121, 1);
261
+    line-height: 24px;
262
+  }
263
+}
264
+</style>

+ 443
- 0
src/view/list.vue 查看文件

@@ -0,0 +1,443 @@
1
+<template>
2
+  <div>
3
+    <!-- <Head></Head> -->
4
+    <!-- <div  class="list-header" @click="show = true">
5
+      精准筛选
6
+      <img src="../assets/screen.png" width="12px" height="12px" />
7
+    </div>-->
8
+
9
+    <van-dropdown-menu  :close-on-click-outside="false">
10
+      <van-dropdown-item v-model="show"  title="精准筛选" ref="item" >
11
+        <div class="filter">
12
+          <div class="role">用户分类</div>
13
+          <div>
14
+            <van-row gutter="20">
15
+              <van-col span="6">
16
+                <van-button class="typebtn" :class="{act:thisbtn==''}" type="default" @click="() =>changetypeName()">全部</van-button>
17
+              </van-col>
18
+              <van-col span="6" v-for="item in personType" :key="item.typeId">
19
+                <van-button class="typebtn" type="default" :class="{act:thisbtn==item.typeId}" @click="() => changetypeName(item.typeId)">{{item.typeName}}</van-button>
20
+              </van-col>
21
+            </van-row>
22
+
23
+            <div class="role">最后到访时间</div>
24
+            <van-row gutter="20">
25
+              <van-col span="12">
26
+                <van-field class="timeInput" @click="showPopupbegin" :value="filterData.beginDate||'开始时间'" disabled />
27
+              </van-col>
28
+              <van-col span="12">
29
+                <van-field class="timeInput" @click="showPopupend" :value="filterData.endDate||'结束时间'" disabled />
30
+              </van-col>
31
+            </van-row>
32
+          </div>
33
+          <van-row>
34
+            <van-col span="12">
35
+              <van-button class="menubtn" block type="info" @click="reast">重置</van-button>
36
+            </van-col>
37
+            <van-col span="12">
38
+              <van-button class="menubtn act" c block type="info" @click="onConfirm">完成</van-button>
39
+            </van-col>
40
+          </van-row>
41
+        </div>
42
+      </van-dropdown-item>
43
+    </van-dropdown-menu>
44
+    <van-popup v-model="showTimebegin" position="bottom">
45
+      <van-datetime-picker v-model="beginDate1" type="datetime" :min-date="minDate"
46
+  :max-date="maxDate" @confirm="beginDate" cancel />
47
+    </van-popup>
48
+
49
+    <van-popup v-model="showTimeend" position="bottom">
50
+      <van-datetime-picker v-model="endDate1" type="datetime" :min-date="minDate"
51
+  :max-date="maxDate" @confirm="endDate" cancel />
52
+    </van-popup>
53
+
54
+    <van-pull-refresh v-model="isLoading" @refresh="onRefresh" id="my-container">
55
+      <van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
56
+        <van-cell v-for="item in data " :key="item.typeId" class="text" :value="format(item.lastVisiteDate)" @click="todetail(item)">
57
+          <!--  :key="item"使用 title 插槽来自定义标题 @click="getImg(item.avatar)"-->
58
+          <template slot="title">
59
+            <div style="display:flex">
60
+              <div style="display: inline-grid;">
61
+                <img :src="item.avatar" class="image" />
62
+                <span style="float: left;">{{getPersonTypeName(item.typeId)}}</span>
63
+              </div>
64
+              <span class="custom-title">{{getDeviceName(item.lastVisiteDevice)}}</span>
65
+            </div>
66
+          </template>
67
+        </van-cell>
68
+      </van-list>
69
+    </van-pull-refresh>
70
+  </div>
71
+</template>
72
+
73
+
74
+
75
+<script>
76
+import {
77
+  Row,
78
+  Col,
79
+  PullRefresh,
80
+  List,
81
+  Cell,
82
+  ImagePreview,
83
+  Popup,
84
+  DropdownMenu,
85
+  DropdownItem,
86
+  DatetimePicker,
87
+  field
88
+} from "vant";
89
+import apis from "../config/api";
90
+import request from "../utils/request";
91
+import dayjs from "dayjs";
92
+
93
+export default {
94
+  name: "list",
95
+  components: {
96
+    [Row.name]: Row,
97
+    [Col.name]: Col,
98
+    [PullRefresh.name]: PullRefresh,
99
+    [List.name]: List,
100
+    [Cell.name]: Cell,
101
+    [Popup.name]: Popup,
102
+    [DropdownMenu.name]: DropdownMenu,
103
+    [DropdownItem.name]: DropdownItem,
104
+    [DatetimePicker.name]: DatetimePicker,
105
+    [field.name]: field
106
+  },
107
+  data () {
108
+    return {
109
+      filterData: {
110
+        beginDate: null,
111
+        endDate: null,
112
+        typeName: ""
113
+      },
114
+      menushow:false,
115
+      pageNavi: {
116
+        current: 1,
117
+        total: 0,
118
+        size: 10
119
+      },
120
+      beginDate1:'',
121
+      endDate1:'',
122
+      data: {},
123
+      image:
124
+        "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3284481034,4167336265&fm=26&gp=0.jpg",
125
+      isLoading: false,
126
+      list: [],
127
+      loading: false,
128
+      finished: false,
129
+      show: false,
130
+      showTime: false,
131
+      showTimebegin: false,
132
+      showTimeend: false,
133
+      value: 0,
134
+      switch1: false,
135
+      switch2: false,
136
+
137
+      minHour: 10,
138
+      maxHour: 20,
139
+      minDate: new Date(2018, 1, 1),
140
+      maxDate: new Date(2025, 1, 1),
141
+      // currentDate: new Date(),
142
+
143
+      device: {},
144
+      personType: [],
145
+      thisbtn: ''
146
+    };
147
+  },
148
+  methods: {
149
+    // personList (typeId, page) {
150
+    //   return new Promise(resolve => {
151
+    //     const post = this.getSelectVal()
152
+    //     this.getPersonList({
153
+    //       ...post,
154
+    //       typeId,
155
+    //       pageSize: this.pageNavi.size,
156
+    //       pageNum: page,
157
+    //     }).then(data => {
158
+    //       const { pageNavi } = data
159
+    //       this.pageNavi = pageNavi
160
+
161
+    //       resolve(data)
162
+    //     })
163
+    //   })
164
+    // },
165
+    getList () {
166
+      const post = this.getSelectVal();
167
+      const pageNavi = this.pageNavi || {};
168
+      console.log(post, "post");
169
+      request({
170
+        ...apis.person,
171
+        params: { ...post, pageSize: pageNavi.size || 10, pageNum: 1 }
172
+      }).then(res => {
173
+        // console.log("data:", res);
174
+        // const { pageNavi } = res;
175
+        // this.pageNavi = pageNavi
176
+        // console.log(pageNavi, "respageNavi");
177
+        this.data = res.records;
178
+        this.loading = false;
179
+        if (res.size >= res.total) {
180
+          this.finished = true;
181
+        }
182
+      });
183
+    },
184
+    getDevice () {
185
+      request({
186
+        ...apis.device,
187
+        params: { pageNum: 1, pageSize: 999 }
188
+      }).then(res => {
189
+        // console.log("data:", res.records);
190
+        this.device = res.records || [];
191
+      });
192
+    },
193
+    getDeviceName (id) {
194
+      // console.log(this.device, "this.device");
195
+      return (
196
+        ((this.device || []).filter(x => x.deviceId === id) || [])[0] || {}
197
+      ).deviceName;
198
+    },
199
+    getPersonTypeName (id) {
200
+      // console.log(this.personType, "this.personType");
201
+      return (
202
+        ((this.personType || []).filter(x => x.typeId === id) || [])[0] || {}
203
+      ).typeName;
204
+    },
205
+    beginDate () {
206
+      // const data = e
207
+      //   .getValues()
208
+      //   .toString()
209
+      //   .replace(/,/g, "");
210
+//  showPopupbegin () {
211
+//       this.showTimebegin = true;
212
+//     },
213
+//     showPopupend () {
214
+//       this.showTimeend = true;
215
+//     },
216
+      this.filterData.beginDate = dayjs(this.beginDate1).format("YYYY-MM-DD HH:mm");
217
+            this.showTimebegin = false;
218
+    },
219
+    endDate () {
220
+      // const data = e
221
+      //   .getValues()
222
+      //   .toString()
223
+      //   .replace(/,/g, "");
224
+
225
+      this.filterData.endDate = dayjs(this.endDate1).format("YYYY-MM-DD HH:mm");
226
+      this.showTimeend = false
227
+    },
228
+    getPersonType () {
229
+      request({
230
+        ...apis.personType,
231
+        params: { pageNum: 1, pageSize: 999 }
232
+      }).then(res => {
233
+        this.personType = res.records || [];
234
+      });
235
+    },
236
+    changetypeName (id) {
237
+      console.log(id, "changetypeName");
238
+     
239
+      this.thisbtn = id
240
+      this.filterData.typeName = id ? id : "";
241
+    },
242
+    todetail (item) {
243
+      // console.log(this.device, "device");
244
+
245
+      this.$router.push({ name: "detail", query: { id: item.personId } });
246
+    },
247
+  
248
+    getSelectVal () {
249
+      const bdt = this.filterData.beginDate
250
+        ? dayjs(this.filterData.beginDate).format("YYYY-MM-DDTHH:mm:ss")
251
+        : "";
252
+      const edt = this.filterData.endDate
253
+        ? dayjs(this.filterData.endDate).format("YYYY-MM-DDTHH:mm:ss")
254
+        : "";
255
+      // console.log(bdt, edt);
256
+      return {
257
+        beginDate: bdt,
258
+        endDate: edt,
259
+        typeId: this.filterData.typeName
260
+      };
261
+    },
262
+    search () {
263
+      this.getList();
264
+    },
265
+    init () {
266
+      this.getList();
267
+    },
268
+    onRefresh () {
269
+      setTimeout(() => {
270
+        // this.$toast('刷新成功');z
271
+        // this.getList();
272
+        this.isLoading = false;
273
+      }, 500);
274
+    },
275
+    onLoad () {
276
+      // 异步更新数据
277
+      setTimeout(() => {
278
+        this.pageNavi.size = this.pageNavi.size + 10;
279
+
280
+        this.getList();
281
+
282
+        // 加载状态结束
283
+
284
+        // 数据全部加载完成
285
+      }, 500);
286
+    },
287
+    getImg (image) {
288
+      ImagePreview({
289
+        images: [image],
290
+        showIndex: false
291
+      });
292
+    },
293
+    getContainer () {
294
+      return document.querySelector(".my-container");
295
+    },
296
+    reast () {
297
+this.filterData = {
298
+        beginDate: null,
299
+        endDate: null,
300
+        typeName: ""
301
+      },
302
+        this.thisbtn = ''
303
+    },
304
+    onConfirm () {
305
+      this.$refs.item.toggle();
306
+      
307
+      this.getList();
308
+    
309
+    },
310
+
311
+    onConfirmTime () {
312
+      this.showTime = false;
313
+    },
314
+    showPopupbegin () {
315
+      this.showTimebegin = true;
316
+    },
317
+    showPopupend () {
318
+      this.showTimeend = true;
319
+    },
320
+    format (time) {
321
+      return dayjs(time).format("YYYY-MM-DDHH:mm");
322
+    }
323
+  },
324
+
325
+  created () {
326
+    const time = this.$route.query.time
327
+    if (time == 'today') {
328
+      this.filterData = {
329
+        beginDate: dayjs(new Date(new Date(new Date().toLocaleDateString()).getTime())).format("YYYY-MM-DD HH:mm"),
330
+        endDate: dayjs(new Date()).format("YYYY-MM-DD HH:mm"),
331
+
332
+      }
333
+
334
+      // console.log(filterData, 'todat')
335
+    }
336
+
337
+
338
+
339
+    this.init();
340
+    this.getPersonType();
341
+    this.getDevice();
342
+  }
343
+};
344
+</script>
345
+
346
+
347
+
348
+<style lang="less" scoped>
349
+.list-header {
350
+  text-align: right;
351
+  height: 30px;
352
+  background: rgba(187, 156, 121, 1);
353
+
354
+  font-size: 12px;
355
+
356
+  font-weight: 400;
357
+  color: rgba(255, 255, 255, 1);
358
+  line-height: 30px;
359
+  padding: 0 15px;
360
+  img {
361
+    width: 12px;
362
+    height: 12px;
363
+    margin-left: 5px;
364
+  }
365
+}
366
+.image {
367
+  width: 32px;
368
+  height: 32px;
369
+  border-radius: 16px;
370
+  // margin-right: 10px;
371
+}
372
+.custom-title {
373
+  font-size: 15px;
374
+  font-weight: 400;
375
+  color: rgba(0, 0, 0, 1);
376
+  line-height: 32px;
377
+  margin-left: 10px;
378
+}
379
+.text {
380
+  font-size: 12px;
381
+
382
+  font-weight: 400;
383
+  color: rgba(136, 136, 136, 1);
384
+  line-height: 32px;
385
+}
386
+
387
+.filter {
388
+  padding: 20px;
389
+  .role {
390
+    float: left;
391
+    font-size: 16px;
392
+    text-align: justify;
393
+    font-weight: 400;
394
+    color: rgba(53, 53, 53, 1);
395
+    line-height: 22px;
396
+    width: 100%;
397
+    margin-bottom: 10px;
398
+  }
399
+  .typebtn {
400
+    width: 100%;
401
+    display: inline-block;
402
+    background: rgba(242, 242, 242, 1);
403
+    border-radius: 2px;
404
+    margin-bottom: 20px;
405
+    line-height: 32px;
406
+  }
407
+  .menubtn {
408
+    width: 100%;
409
+    display: inline-block;
410
+    background: rgba(242, 242, 242, 1);
411
+    border-radius: 4px 0px 0px 4px;
412
+    line-height: 40px;
413
+    color: rgba(53, 53, 53, 1);
414
+    font-size: 17px;
415
+  }
416
+}
417
+
418
+.timeInput {
419
+  padding: 0;
420
+  width: 100%;
421
+  display: inline-block;
422
+  background: rgba(242, 242, 242, 1);
423
+  font-size: 12px;
424
+
425
+  color: rgba(136, 136, 136, 1);
426
+  line-height: 32px;
427
+  margin-bottom: 20px;
428
+}
429
+.act {
430
+  background: rgba(187, 156, 121, 1) !important;
431
+  color: rgba(255, 255, 255, 1) !important;
432
+}
433
+
434
+// .van-picker__toolbar {
435
+//   display: none;
436
+// }
437
+</style>
438
+
439
+<style >
440
+/* .van-picker__toolbar {
441
+  display: none;
442
+} */
443
+</style>

+ 260
- 0
src/view/login.vue 查看文件

@@ -0,0 +1,260 @@
1
+<template>
2
+  <div class="login">
3
+    <!-- 122 -->
4
+    <div class="main">
5
+      <img src="../assets/logo.png" class="img" alt srcset />
6
+      <div class="informain">
7
+        <van-cell-group>
8
+          <van-field v-model="formdata.username" label="86+" placeholder="请输入用户名" />
9
+        </van-cell-group>
10
+        <van-cell-group>
11
+          <van-field v-model="formdata.password" label=" " placeholder="请输入验证码">
12
+            <van-button slot="button" size="small" @click="setCode" type="primary">发送验证码</van-button>
13
+          </van-field>
14
+        </van-cell-group>
15
+        <button class="btn" @click="loginPhone">立即登录</button>
16
+        <!-- <button class="btn1">立即3333登录</button> -->
17
+      </div>
18
+    </div>
19
+  </div>
20
+</template>
21
+
22
+<script>
23
+import { Field, Button } from 'vant';
24
+import request from '../utils/request'
25
+import apis from '../config/api';
26
+// import getOpenId from '../openId';
27
+
28
+export default {
29
+  name: 'login',
30
+  components: {
31
+    [Field.name]: Field,
32
+    [Button.name]: Button,
33
+  },
34
+  data () {
35
+    return {
36
+      formdata: {
37
+        username: '',
38
+        password: '',
39
+      },
40
+      openid:''
41
+    }
42
+  },
43
+  methods: {
44
+
45
+    //请求验证码
46
+    setCode () {
47
+      if (!(/^1[3456789]\d{9}$/.test(this.formdata.username))) {
48
+      
49
+      alert("请输入正确的手机号码");
50
+      return false;
51
+    }
52
+      request({
53
+        ...apis.getcode,
54
+        params: { tel: this.formdata.username }
55
+      })
56
+        .then(res => {
57
+
58
+
59
+        }).catch(()=>{
60
+          alert("请输入正确的手机号码");
61
+        })
62
+
63
+
64
+
65
+
66
+      // const http="https://wx.jinchengjiaye.com"
67
+
68
+      // // console.log(encodeURIComponent(http),'--------')
69
+
70
+      // window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx18765573b7565aed&redirect_uri=" + "" + encodeURIComponent(http) + "" + "&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
71
+      // //  request({
72
+      // //       url:'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx18765573b7565aed&redirect_uri=https%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdapter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_base&state=123#wechat_redirect',
73
+      // //     method: 'get',
74
+      // //    // params: {
75
+      // //       //   appid:'wx18765573b7565aed',
76
+      // //       // redirect_uri:'https%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdapter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60',
77
+      // //       // response_type:'code',
78
+      // //       // scope:'snsapi_base',
79
+
80
+      // //       // }
81
+      // //     })
82
+      // //       .then(res => {
83
+
84
+      // // console.log('res',res)
85
+      // //       })
86
+
87
+      // // console.log('123')
88
+      // //  request({
89
+      // //   ...apis.getOpenId,
90
+      // //   params: {code:2345}
91
+      // // })
92
+      // //   .then(res => {
93
+
94
+
95
+      // //   })
96
+    },
97
+//登录
98
+    loginPhone () {
99
+// if (!this.formdata.password) {
100
+//       // showToast("请输入正确的手机号码,请重填",3000);
101
+//       alert("请输入验证码");
102
+//       return false;
103
+//     }
104
+      request({
105
+        ...apis.loginPhone,
106
+        params: { phone:  this.formdata.username,code: this.formdata.password,openId:this.openid}
107
+      })
108
+        .then(res => {
109
+             console.log(res,'res')
110
+              this.$router.push({name: 'index'})
111
+        }).catch(()=>{
112
+          alert("请输入正确验证码");
113
+        })
114
+    },
115
+
116
+
117
+    getParmeter (variable) {
118
+      window.console.log('query', window.location.href)
119
+      let query = window.location.href.split('?')[1] || null;
120
+      window.console.log('query', query)
121
+      if (!query) { return '' }
122
+      let vars = query.split('&');
123
+      for (let i = 0; i < vars.length; i++) {
124
+        let pair = vars[i].split('=');
125
+        if (pair[0] === variable) {
126
+          return pair[1];
127
+        }
128
+      }
129
+      return '';
130
+    },
131
+
132
+    getCode () {
133
+      const http = "http://we.jinchengjiaye.com/face/"
134
+      window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx18765573b7565aed&redirect_uri=" + "" + encodeURIComponent(http) + "" + "&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
135
+    },
136
+
137
+    getOpenid () {
138
+      const  localcode= localStorage.getItem("code")
139
+
140
+      const code = this.getParmeter('code')
141
+      window.console.log('code1', code)
142
+      if (code==localcode) {
143
+        this.getCode()
144
+      } else {
145
+        localStorage.setItem("code",code);
146
+        this.getOpenId(code)
147
+
148
+      }
149
+      // 
150
+      window.console.log('code2', code)
151
+    },
152
+
153
+    getOpenId (code) {
154
+  
155
+      request({
156
+        ...apis.getOpenId,
157
+        params: { code: code }
158
+      })
159
+        .then(res => {
160
+          window.console.log(res.openid, 'res111111111')
161
+          const openid = res.openid
162
+          localStorage.setItem("openid",openid);
163
+          this.openid=openid
164
+
165
+        }).catch(()=>{
166
+          // this.getOpenid()
167
+        })
168
+    },
169
+
170
+    loginByOpenid (openid) {
171
+
172
+      request({
173
+        ...apis.loginByOpenid,
174
+        params: { openid: openid }
175
+
176
+      }).then((user) => {
177
+        window.console.log('user,', user)
178
+        this.checkLogin()
179
+      })
180
+    }
181
+   
182
+  },
183
+
184
+  created(){
185
+    
186
+    this.getOpenid()
187
+  //  this.openidlocalStorage.getItem("openid")
188
+    // this.openid = this.$cookies.get('openid')
189
+    
190
+  }
191
+
192
+
193
+}
194
+</script>
195
+
196
+<style lang="less" scoped>
197
+.login {
198
+  width: 100vw;
199
+  height: 100vh;
200
+  // padding: 30px 15px 0;
201
+}
202
+.main {
203
+  // width: 100%;
204
+  // height: 100%;
205
+  background: rgba(255, 255, 255, 1);
206
+  box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.12);
207
+  border-radius: 6px 6px 0px 0px;
208
+  margin: 30px 15px 0;
209
+  height: inherit;
210
+  width: auto;
211
+  .img {
212
+    width: 88px;
213
+    height: 77px;
214
+    position: relative;
215
+    top: 80px;
216
+  }
217
+  .informain {
218
+    position: relative;
219
+    top: 127px;
220
+  }
221
+  .btn {
222
+    position: relative;
223
+    top: 50px;
224
+    width: 88vw;
225
+    height: 47px;
226
+
227
+    background: rgba(187, 156, 121, 1);
228
+    // box-shadow:0px -4px 3px 0px rgba(149,113,72,1),0px 4px 3px 0px rgba(255,255,255,0.5);
229
+    border-radius: 6px;
230
+
231
+    font-size: 18px;
232
+
233
+    font-weight: 500;
234
+    color: rgba(255, 255, 255, 1);
235
+    line-height: 25px;
236
+    border: none;
237
+  }
238
+
239
+  .btn1 {
240
+    position: relative;
241
+    top: 90px;
242
+    width: 88vw;
243
+    height: 47px;
244
+
245
+    background: rgba(187, 156, 121, 1);
246
+    // box-shadow:0px -4px 3px 0px rgba(149,113,72,1),0px 4px 3px 0px rgba(255,255,255,0.5);
247
+    border-radius: 6px;
248
+
249
+    font-size: 18px;
250
+
251
+    font-weight: 500;
252
+    color: rgba(255, 255, 255, 1);
253
+    line-height: 25px;
254
+    border: none;
255
+  }
256
+}
257
+</style>
258
+
259
+
260
+

+ 15
- 0
vue.config.js 查看文件

@@ -0,0 +1,15 @@
1
+module.exports = {
2
+ 
3
+  publicPath: './',
4
+  devServer: {
5
+    disableHostCheck: true,
6
+    proxy:  {
7
+      '/api': {
8
+        target: 'http://localhost:8080/',
9
+        ws: true,
10
+        changeOrigin: true,
11
+        pathRewrite: {'^/api': ''}
12
+      }
13
+    }
14
+  }
15
+};