浏览代码

Merge branch 'develop' of http://git.ycjcjy.com/fuxingfan/smartCommunity into develop

weiximei 6 年前
父节点
当前提交
5aad9bf894
共有 23 个文件被更改,包括 1223 次插入55 次删除
  1. 20
    6
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/controller/CommunityController.java
  2. 2
    1
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/CommunityServiceI.java
  3. 9
    3
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/impl/CommunityServiceImpl.java
  4. 4
    1
      VUECODE/smart-operate-manage/package.json
  5. 41
    0
      VUECODE/smart-operate-manage/src/api/community.js
  6. 99
    0
      VUECODE/smart-operate-manage/src/components/Pagination/index.vue
  7. 49
    0
      VUECODE/smart-operate-manage/src/directive/clipboard/clipboard.js
  8. 13
    0
      VUECODE/smart-operate-manage/src/directive/clipboard/index.js
  9. 77
    0
      VUECODE/smart-operate-manage/src/directive/el-dragDialog/drag.js
  10. 13
    0
      VUECODE/smart-operate-manage/src/directive/el-dragDialog/index.js
  11. 13
    0
      VUECODE/smart-operate-manage/src/directive/permission/index.js
  12. 23
    0
      VUECODE/smart-operate-manage/src/directive/permission/permission.js
  13. 91
    0
      VUECODE/smart-operate-manage/src/directive/sticky.js
  14. 13
    0
      VUECODE/smart-operate-manage/src/directive/waves/index.js
  15. 26
    0
      VUECODE/smart-operate-manage/src/directive/waves/waves.css
  16. 42
    0
      VUECODE/smart-operate-manage/src/directive/waves/waves.js
  17. 28
    27
      VUECODE/smart-operate-manage/src/permission.js
  18. 3
    3
      VUECODE/smart-operate-manage/src/router/index.js
  19. 50
    0
      VUECODE/smart-operate-manage/src/utils/scrollTo.js
  20. 206
    0
      VUECODE/smart-operate-manage/src/vendor/Export2Excel.js
  21. 24
    0
      VUECODE/smart-operate-manage/src/vendor/Export2Zip.js
  22. 362
    0
      VUECODE/smart-operate-manage/src/views/community/communityTable.vue
  23. 15
    14
      VUECODE/smart-operate-manage/src/views/login/index.vue

+ 20
- 6
CODE/smart-community/operate-api/src/main/java/com/community/huiju/controller/CommunityController.java 查看文件

@@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestParam;
17 17
 import org.springframework.web.bind.annotation.RestController;
18 18
 
19 19
 import java.util.List;
20
+import java.util.Map;
20 21
 
21 22
 /**
22 23
  * @author FXF
@@ -33,18 +34,31 @@ public class CommunityController {
33 34
 	
34 35
 	@ApiOperation(value = "根据搜索条件获取小区列表", notes = "根据搜索条件获取小区列表")
35 36
 	@ApiImplicitParams({
36
-			@ApiImplicitParam(paramType = "body", name = "toCommunities", dataType = "String",value =
37
-					"id:社区编号,communityName:社区名称(模糊查询), provinceId:省份id,cityId:城市id,districtId:区县id"),
37
+			@ApiImplicitParam(paramType = "query", dataType = "Integer", name = "communityId", value = "社区编号"),
38
+			@ApiImplicitParam(paramType = "query", dataType = "String", name = "communityName", value = "社区名称(模糊查询)"),
39
+			@ApiImplicitParam(paramType = "query", dataType = "integer", name = "provinceId", value = "省份id"),
40
+			@ApiImplicitParam(paramType = "query", dataType = "integer", name = "cityId", value = "城市id"),
41
+			@ApiImplicitParam(paramType = "query", dataType = "integer", name = "districtId", value = "区县id"),
38 42
 			@ApiImplicitParam(paramType = "query", dataType = "integer", name = "pageNum", value = "分页第几页"),
39 43
 			@ApiImplicitParam(paramType = "query", dataType = "integer", name = "pageSize", value = "分页每页长度")
40 44
 	})
41
-	@RequestMapping(value = "/communitys",method = RequestMethod.POST)
42
-	public ResponseBean getCommunitys(@RequestBody ToCommunities toCommunities,
45
+	@RequestMapping(value = "/communitys",method = RequestMethod.GET)
46
+	public ResponseBean getCommunitys(@RequestParam(value = "communityId", required = false) Integer communityId,
47
+	                                  @RequestParam(value = "communityName", required = false) String communityName,
48
+	                                  @RequestParam(value = "provinceId", required = false) Integer provinceId,
49
+	                                  @RequestParam(value = "cityId", required = false) Integer cityId,
50
+	                                  @RequestParam(value = "districtId", required = false) Integer districtId,
43 51
 	                                  @RequestParam(value ="pageNum",defaultValue = "1") Integer pageNum,
44 52
 	                                  @RequestParam(value ="pageSize",defaultValue = "10") Integer pageSize){
45 53
 		ResponseBean responseBean = new ResponseBean();
46
-		List<ToCommunities> communitiesList = communityService.getCommunitys(toCommunities,pageNum,pageSize);
47
-		responseBean.addSuccess(communitiesList);
54
+		ToCommunities toCommunities = new ToCommunities();
55
+		toCommunities.setId(communityId);
56
+		toCommunities.setCommunityName(communityName);
57
+		toCommunities.setProvinceId(provinceId);
58
+		toCommunities.setCityId(cityId);
59
+		toCommunities.setDistrictId(districtId);
60
+		Map<String,Object> map = communityService.getCommunitys(toCommunities,pageNum,pageSize);
61
+		responseBean.addSuccess(map);
48 62
 		return responseBean;
49 63
 	}
50 64
 	

+ 2
- 1
CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/CommunityServiceI.java 查看文件

@@ -3,6 +3,7 @@ package com.community.huiju.service;
3 3
 import com.community.huiju.model.ToCommunities;
4 4
 
5 5
 import java.util.List;
6
+import java.util.Map;
6 7
 
7 8
 public interface CommunityServiceI {
8 9
 	
@@ -13,7 +14,7 @@ public interface CommunityServiceI {
13 14
 	 * @param pageSize
14 15
 	 * @return
15 16
 	 */
16
-	List<ToCommunities> getCommunitys(ToCommunities toCommunities, Integer pageNum, Integer pageSize);
17
+	Map<String,Object> getCommunitys(ToCommunities toCommunities, Integer pageNum, Integer pageSize);
17 18
 	
18 19
 	/**
19 20
 	 * 添加新的小区

+ 9
- 3
CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/impl/CommunityServiceImpl.java 查看文件

@@ -8,13 +8,16 @@ import com.community.huiju.model.ToCommunities;
8 8
 import com.community.huiju.model.TpUser;
9 9
 import com.community.huiju.model.TpUserCommunity;
10 10
 import com.community.huiju.service.CommunityServiceI;
11
+import com.github.pagehelper.Page;
11 12
 import com.github.pagehelper.PageHelper;
12 13
 import org.springframework.beans.factory.annotation.Autowired;
13 14
 import org.springframework.stereotype.Service;
14 15
 import org.springframework.transaction.annotation.Transactional;
15 16
 
16 17
 import java.util.Date;
18
+import java.util.HashMap;
17 19
 import java.util.List;
20
+import java.util.Map;
18 21
 
19 22
 /**
20 23
  * @author FXF
@@ -41,12 +44,15 @@ public class CommunityServiceImpl implements CommunityServiceI {
41 44
 	 * @return
42 45
 	 */
43 46
 	@Override
44
-	public List<ToCommunities> getCommunitys(ToCommunities toCommunities, Integer pageNum, Integer pageSize) {
47
+	public Map<String,Object> getCommunitys(ToCommunities toCommunities, Integer pageNum, Integer pageSize) {
45 48
 		//使用分页插件
46
-		PageHelper.startPage(pageNum, pageSize);
49
+		Page page = PageHelper.startPage(pageNum, pageSize);
47 50
 		//获取数据
48 51
 		List<ToCommunities> list = toCommunitiesMapper.selectByCommunityName(toCommunities);
49
-		return list;
52
+		Map<String,Object> map = new HashMap<>();
53
+		map.put("items",list);
54
+		map.put("total",page.getTotal());
55
+		return map;
50 56
 	}
51 57
 	
52 58
 	@Override

+ 4
- 1
VUECODE/smart-operate-manage/package.json 查看文件

@@ -16,12 +16,14 @@
16 16
   "dependencies": {
17 17
     "axios": "0.18.0",
18 18
     "element-ui": "2.4.6",
19
+    "file-saver": "^2.0.0-rc.4",
19 20
     "js-cookie": "2.2.0",
20 21
     "normalize.css": "7.0.0",
21 22
     "nprogress": "0.2.0",
22 23
     "vue": "2.5.17",
23 24
     "vue-router": "3.0.1",
24
-    "vuex": "3.0.1"
25
+    "vuex": "3.0.1",
26
+    "xlsx": "^0.14.0"
25 27
   },
26 28
   "devDependencies": {
27 29
     "autoprefixer": "8.5.0",
@@ -58,6 +60,7 @@
58 60
     "rimraf": "2.6.2",
59 61
     "sass-loader": "7.0.3",
60 62
     "script-ext-html-webpack-plugin": "2.0.1",
63
+    "script-loader": "^0.7.2",
61 64
     "semver": "5.5.0",
62 65
     "shelljs": "0.8.2",
63 66
     "svg-sprite-loader": "3.8.0",

+ 41
- 0
VUECODE/smart-operate-manage/src/api/community.js 查看文件

@@ -0,0 +1,41 @@
1
+import request from '@/utils/request'
2
+
3
+export function fetchList(query) {
4
+  return request({
5
+    url: '/communitys',
6
+    method: 'get',
7
+    params: query
8
+  })
9
+}
10
+
11
+export function fetchArticle(id) {
12
+  return request({
13
+    url: '/article/detail',
14
+    method: 'get',
15
+    params: { id }
16
+  })
17
+}
18
+
19
+export function fetchPv(pv) {
20
+  return request({
21
+    url: '/article/pv',
22
+    method: 'get',
23
+    params: { pv }
24
+  })
25
+}
26
+
27
+export function createArticle(data) {
28
+  return request({
29
+    url: '/article/create',
30
+    method: 'post',
31
+    data
32
+  })
33
+}
34
+
35
+export function updateArticle(data) {
36
+  return request({
37
+    url: '/article/update',
38
+    method: 'post',
39
+    data
40
+  })
41
+}

+ 99
- 0
VUECODE/smart-operate-manage/src/components/Pagination/index.vue 查看文件

@@ -0,0 +1,99 @@
1
+<template>
2
+  <div :class="{'hidden':hidden}" class="pagination-container">
3
+    <el-pagination
4
+      :background="background"
5
+      :current-page.sync="currentPage"
6
+      :page-size.sync="pageSize"
7
+      :layout="layout"
8
+      :total="total"
9
+      v-bind="$attrs"
10
+      @size-change="handleSizeChange"
11
+      @current-change="handleCurrentChange"/>
12
+  </div>
13
+</template>
14
+
15
+<script>
16
+import { scrollTo } from '@/utils/scrollTo'
17
+
18
+export default {
19
+  name: 'Pagination',
20
+  props: {
21
+    total: {
22
+      required: true,
23
+      type: Number
24
+    },
25
+    page: {
26
+      type: Number,
27
+      default: 1
28
+    },
29
+    limit: {
30
+      type: Number,
31
+      default: 20
32
+    },
33
+    pageSizes: {
34
+      type: Array,
35
+      default() {
36
+        return [10, 20, 30, 50]
37
+      }
38
+    },
39
+    layout: {
40
+      type: String,
41
+      default: 'total, sizes, prev, pager, next, jumper'
42
+    },
43
+    background: {
44
+      type: Boolean,
45
+      default: true
46
+    },
47
+    autoScroll: {
48
+      type: Boolean,
49
+      default: true
50
+    },
51
+    hidden: {
52
+      type: Boolean,
53
+      default: false
54
+    }
55
+  },
56
+  computed: {
57
+    currentPage: {
58
+      get() {
59
+        return this.page
60
+      },
61
+      set(val) {
62
+        this.$emit('update:page', val)
63
+      }
64
+    },
65
+    pageSize: {
66
+      get() {
67
+        return this.limit
68
+      },
69
+      set(val) {
70
+        this.$emit('update:limit', val)
71
+      }
72
+    }
73
+  },
74
+  methods: {
75
+    handleSizeChange(val) {
76
+      this.$emit('pagination', { page: this.currentPage, limit: val })
77
+      if (this.autoScroll) {
78
+        scrollTo(0, 800)
79
+      }
80
+    },
81
+    handleCurrentChange(val) {
82
+      this.$emit('pagination', { page: val, limit: this.pageSize })
83
+      if (this.autoScroll) {
84
+        scrollTo(0, 800)
85
+      }
86
+    }
87
+  }
88
+}
89
+</script>
90
+
91
+<style scoped>
92
+.pagination-container {
93
+  background: #fff;
94
+  padding: 32px 16px;
95
+}
96
+.pagination-container.hidden {
97
+  display: none;
98
+}
99
+</style>

+ 49
- 0
VUECODE/smart-operate-manage/src/directive/clipboard/clipboard.js 查看文件

@@ -0,0 +1,49 @@
1
+// Inspired by https://github.com/Inndy/vue-clipboard2
2
+const Clipboard = require('clipboard')
3
+if (!Clipboard) {
4
+  throw new Error('you should npm install `clipboard` --save at first ')
5
+}
6
+
7
+export default {
8
+  bind(el, binding) {
9
+    if (binding.arg === 'success') {
10
+      el._v_clipboard_success = binding.value
11
+    } else if (binding.arg === 'error') {
12
+      el._v_clipboard_error = binding.value
13
+    } else {
14
+      const clipboard = new Clipboard(el, {
15
+        text() { return binding.value },
16
+        action() { return binding.arg === 'cut' ? 'cut' : 'copy' }
17
+      })
18
+      clipboard.on('success', e => {
19
+        const callback = el._v_clipboard_success
20
+        callback && callback(e) // eslint-disable-line
21
+      })
22
+      clipboard.on('error', e => {
23
+        const callback = el._v_clipboard_error
24
+        callback && callback(e) // eslint-disable-line
25
+      })
26
+      el._v_clipboard = clipboard
27
+    }
28
+  },
29
+  update(el, binding) {
30
+    if (binding.arg === 'success') {
31
+      el._v_clipboard_success = binding.value
32
+    } else if (binding.arg === 'error') {
33
+      el._v_clipboard_error = binding.value
34
+    } else {
35
+      el._v_clipboard.text = function() { return binding.value }
36
+      el._v_clipboard.action = function() { return binding.arg === 'cut' ? 'cut' : 'copy' }
37
+    }
38
+  },
39
+  unbind(el, binding) {
40
+    if (binding.arg === 'success') {
41
+      delete el._v_clipboard_success
42
+    } else if (binding.arg === 'error') {
43
+      delete el._v_clipboard_error
44
+    } else {
45
+      el._v_clipboard.destroy()
46
+      delete el._v_clipboard
47
+    }
48
+  }
49
+}

+ 13
- 0
VUECODE/smart-operate-manage/src/directive/clipboard/index.js 查看文件

@@ -0,0 +1,13 @@
1
+import Clipboard from './clipboard'
2
+
3
+const install = function(Vue) {
4
+  Vue.directive('Clipboard', Clipboard)
5
+}
6
+
7
+if (window.Vue) {
8
+  window.clipboard = Clipboard
9
+  Vue.use(install); // eslint-disable-line
10
+}
11
+
12
+Clipboard.install = install
13
+export default Clipboard

+ 77
- 0
VUECODE/smart-operate-manage/src/directive/el-dragDialog/drag.js 查看文件

@@ -0,0 +1,77 @@
1
+export default{
2
+  bind(el, binding, vnode) {
3
+    const dialogHeaderEl = el.querySelector('.el-dialog__header')
4
+    const dragDom = el.querySelector('.el-dialog')
5
+    dialogHeaderEl.style.cssText += ';cursor:move;'
6
+    dragDom.style.cssText += ';top:0px;'
7
+
8
+    // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
9
+    const getStyle = (function() {
10
+      if (window.document.currentStyle) {
11
+        return (dom, attr) => dom.currentStyle[attr]
12
+      } else {
13
+        return (dom, attr) => getComputedStyle(dom, false)[attr]
14
+      }
15
+    })()
16
+
17
+    dialogHeaderEl.onmousedown = (e) => {
18
+      // 鼠标按下,计算当前元素距离可视区的距离
19
+      const disX = e.clientX - dialogHeaderEl.offsetLeft
20
+      const disY = e.clientY - dialogHeaderEl.offsetTop
21
+
22
+      const dragDomWidth = dragDom.offsetWidth
23
+      const dragDomHeight = dragDom.offsetHeight
24
+
25
+      const screenWidth = document.body.clientWidth
26
+      const screenHeight = document.body.clientHeight
27
+
28
+      const minDragDomLeft = dragDom.offsetLeft
29
+      const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth
30
+
31
+      const minDragDomTop = dragDom.offsetTop
32
+      const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight
33
+
34
+      // 获取到的值带px 正则匹配替换
35
+      let styL = getStyle(dragDom, 'left')
36
+      let styT = getStyle(dragDom, 'top')
37
+
38
+      if (styL.includes('%')) {
39
+        styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100)
40
+        styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100)
41
+      } else {
42
+        styL = +styL.replace(/\px/g, '')
43
+        styT = +styT.replace(/\px/g, '')
44
+      }
45
+
46
+      document.onmousemove = function(e) {
47
+        // 通过事件委托,计算移动的距离
48
+        let left = e.clientX - disX
49
+        let top = e.clientY - disY
50
+
51
+        // 边界处理
52
+        if (-(left) > minDragDomLeft) {
53
+          left = -minDragDomLeft
54
+        } else if (left > maxDragDomLeft) {
55
+          left = maxDragDomLeft
56
+        }
57
+
58
+        if (-(top) > minDragDomTop) {
59
+          top = -minDragDomTop
60
+        } else if (top > maxDragDomTop) {
61
+          top = maxDragDomTop
62
+        }
63
+
64
+        // 移动当前元素
65
+        dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`
66
+
67
+        // emit onDrag event
68
+        vnode.child.$emit('dragDialog')
69
+      }
70
+
71
+      document.onmouseup = function(e) {
72
+        document.onmousemove = null
73
+        document.onmouseup = null
74
+      }
75
+    }
76
+  }
77
+}

+ 13
- 0
VUECODE/smart-operate-manage/src/directive/el-dragDialog/index.js 查看文件

@@ -0,0 +1,13 @@
1
+import drag from './drag'
2
+
3
+const install = function(Vue) {
4
+  Vue.directive('el-drag-dialog', drag)
5
+}
6
+
7
+if (window.Vue) {
8
+  window['el-drag-dialog'] = drag
9
+  Vue.use(install); // eslint-disable-line
10
+}
11
+
12
+drag.install = install
13
+export default drag

+ 13
- 0
VUECODE/smart-operate-manage/src/directive/permission/index.js 查看文件

@@ -0,0 +1,13 @@
1
+import permission from './permission'
2
+
3
+const install = function(Vue) {
4
+  Vue.directive('permission', permission)
5
+}
6
+
7
+if (window.Vue) {
8
+  window['permission'] = permission
9
+  Vue.use(install); // eslint-disable-line
10
+}
11
+
12
+permission.install = install
13
+export default permission

+ 23
- 0
VUECODE/smart-operate-manage/src/directive/permission/permission.js 查看文件

@@ -0,0 +1,23 @@
1
+
2
+import store from '@/store'
3
+
4
+export default{
5
+  inserted(el, binding, vnode) {
6
+    const { value } = binding
7
+    const roles = store.getters && store.getters.roles
8
+
9
+    if (value && value instanceof Array && value.length > 0) {
10
+      const permissionRoles = value
11
+
12
+      const hasPermission = roles.some(role => {
13
+        return permissionRoles.includes(role)
14
+      })
15
+
16
+      if (!hasPermission) {
17
+        el.parentNode && el.parentNode.removeChild(el)
18
+      }
19
+    } else {
20
+      throw new Error(`need roles! Like v-permission="['admin','editor']"`)
21
+    }
22
+  }
23
+}

+ 91
- 0
VUECODE/smart-operate-manage/src/directive/sticky.js 查看文件

@@ -0,0 +1,91 @@
1
+const vueSticky = {}
2
+let listenAction
3
+vueSticky.install = Vue => {
4
+  Vue.directive('sticky', {
5
+    inserted(el, binding) {
6
+      const params = binding.value || {}
7
+      const stickyTop = params.stickyTop || 0
8
+      const zIndex = params.zIndex || 1000
9
+      const elStyle = el.style
10
+
11
+      elStyle.position = '-webkit-sticky'
12
+      elStyle.position = 'sticky'
13
+      // if the browser support css sticky(Currently Safari, Firefox and Chrome Canary)
14
+      // if (~elStyle.position.indexOf('sticky')) {
15
+      //     elStyle.top = `${stickyTop}px`;
16
+      //     elStyle.zIndex = zIndex;
17
+      //     return
18
+      // }
19
+      const elHeight = el.getBoundingClientRect().height
20
+      const elWidth = el.getBoundingClientRect().width
21
+      elStyle.cssText = `top: ${stickyTop}px; z-index: ${zIndex}`
22
+
23
+      const parentElm = el.parentNode || document.documentElement
24
+      const placeholder = document.createElement('div')
25
+      placeholder.style.display = 'none'
26
+      placeholder.style.width = `${elWidth}px`
27
+      placeholder.style.height = `${elHeight}px`
28
+      parentElm.insertBefore(placeholder, el)
29
+
30
+      let active = false
31
+
32
+      const getScroll = (target, top) => {
33
+        const prop = top ? 'pageYOffset' : 'pageXOffset'
34
+        const method = top ? 'scrollTop' : 'scrollLeft'
35
+        let ret = target[prop]
36
+        if (typeof ret !== 'number') {
37
+          ret = window.document.documentElement[method]
38
+        }
39
+        return ret
40
+      }
41
+
42
+      const sticky = () => {
43
+        if (active) {
44
+          return
45
+        }
46
+        if (!elStyle.height) {
47
+          elStyle.height = `${el.offsetHeight}px`
48
+        }
49
+
50
+        elStyle.position = 'fixed'
51
+        elStyle.width = `${elWidth}px`
52
+        placeholder.style.display = 'inline-block'
53
+        active = true
54
+      }
55
+
56
+      const reset = () => {
57
+        if (!active) {
58
+          return
59
+        }
60
+
61
+        elStyle.position = ''
62
+        placeholder.style.display = 'none'
63
+        active = false
64
+      }
65
+
66
+      const check = () => {
67
+        const scrollTop = getScroll(window, true)
68
+        const offsetTop = el.getBoundingClientRect().top
69
+        if (offsetTop < stickyTop) {
70
+          sticky()
71
+        } else {
72
+          if (scrollTop < elHeight + stickyTop) {
73
+            reset()
74
+          }
75
+        }
76
+      }
77
+      listenAction = () => {
78
+        check()
79
+      }
80
+
81
+      window.addEventListener('scroll', listenAction)
82
+    },
83
+
84
+    unbind() {
85
+      window.removeEventListener('scroll', listenAction)
86
+    }
87
+  })
88
+}
89
+
90
+export default vueSticky
91
+

+ 13
- 0
VUECODE/smart-operate-manage/src/directive/waves/index.js 查看文件

@@ -0,0 +1,13 @@
1
+import waves from './waves'
2
+
3
+const install = function(Vue) {
4
+  Vue.directive('waves', waves)
5
+}
6
+
7
+if (window.Vue) {
8
+  window.waves = waves
9
+  Vue.use(install); // eslint-disable-line
10
+}
11
+
12
+waves.install = install
13
+export default waves

+ 26
- 0
VUECODE/smart-operate-manage/src/directive/waves/waves.css 查看文件

@@ -0,0 +1,26 @@
1
+.waves-ripple {
2
+    position: absolute;
3
+    border-radius: 100%;
4
+    background-color: rgba(0, 0, 0, 0.15);
5
+    background-clip: padding-box;
6
+    pointer-events: none;
7
+    -webkit-user-select: none;
8
+    -moz-user-select: none;
9
+    -ms-user-select: none;
10
+    user-select: none;
11
+    -webkit-transform: scale(0);
12
+    -ms-transform: scale(0);
13
+    transform: scale(0);
14
+    opacity: 1;
15
+}
16
+
17
+.waves-ripple.z-active {
18
+    opacity: 0;
19
+    -webkit-transform: scale(2);
20
+    -ms-transform: scale(2);
21
+    transform: scale(2);
22
+    -webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
23
+    transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
24
+    transition: opacity 1.2s ease-out, transform 0.6s ease-out;
25
+    transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
26
+}

+ 42
- 0
VUECODE/smart-operate-manage/src/directive/waves/waves.js 查看文件

@@ -0,0 +1,42 @@
1
+import './waves.css'
2
+
3
+export default{
4
+  bind(el, binding) {
5
+    el.addEventListener('click', e => {
6
+      const customOpts = Object.assign({}, binding.value)
7
+      const opts = Object.assign({
8
+        ele: el, // 波纹作用元素
9
+        type: 'hit', // hit 点击位置扩散 center中心点扩展
10
+        color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
11
+      }, customOpts)
12
+      const target = opts.ele
13
+      if (target) {
14
+        target.style.position = 'relative'
15
+        target.style.overflow = 'hidden'
16
+        const rect = target.getBoundingClientRect()
17
+        let ripple = target.querySelector('.waves-ripple')
18
+        if (!ripple) {
19
+          ripple = document.createElement('span')
20
+          ripple.className = 'waves-ripple'
21
+          ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px'
22
+          target.appendChild(ripple)
23
+        } else {
24
+          ripple.className = 'waves-ripple'
25
+        }
26
+        switch (opts.type) {
27
+          case 'center':
28
+            ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px'
29
+            ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px'
30
+            break
31
+          default:
32
+            ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.documentElement.scrollTop || document.body.scrollTop) + 'px'
33
+            ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.documentElement.scrollLeft || document.body.scrollLeft) + 'px'
34
+        }
35
+        ripple.style.backgroundColor = opts.color
36
+        ripple.className = 'waves-ripple z-active'
37
+        return false
38
+      }
39
+    }, false)
40
+  }
41
+}
42
+

+ 28
- 27
VUECODE/smart-operate-manage/src/permission.js 查看文件

@@ -7,33 +7,34 @@ import { getToken } from '@/utils/auth' // 验权
7 7
 
8 8
 const whiteList = ['/login'] // 不重定向白名单
9 9
 router.beforeEach((to, from, next) => {
10
-  NProgress.start()
11
-  if (getToken()) {
12
-    if (to.path === '/login') {
13
-      next({ path: '/' })
14
-      NProgress.done() // if current page is dashboard will not trigger	afterEach hook, so manually handle it
15
-    } else {
16
-      if (store.getters.roles.length === 0) {
17
-        store.dispatch('GetInfo').then(res => { // 拉取用户信息
18
-          next()
19
-        }).catch((err) => {
20
-          store.dispatch('FedLogOut').then(() => {
21
-            Message.error(err || 'Verification failed, please login again')
22
-            next({ path: '/' })
23
-          })
24
-        })
25
-      } else {
26
-        next()
27
-      }
28
-    }
29
-  } else {
30
-    if (whiteList.indexOf(to.path) !== -1) {
31
-      next()
32
-    } else {
33
-      next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
34
-      NProgress.done()
35
-    }
36
-  }
10
+  // NProgress.start()
11
+  // if (getToken()) {
12
+  //   if (to.path === '/login') {
13
+  //     next({ path: '/' })
14
+  //     NProgress.done() // if current page is dashboard will not trigger	afterEach hook, so manually handle it
15
+  //   } else {
16
+  //     if (store.getters.roles.length === 0) {
17
+  //       store.dispatch('GetInfo').then(res => { // 拉取用户信息
18
+  //         next()
19
+  //       }).catch((err) => {
20
+  //         store.dispatch('FedLogOut').then(() => {
21
+  //           Message.error(err || 'Verification failed, please login again')
22
+  //           next({ path: '/' })
23
+  //         })
24
+  //       })
25
+  //     } else {
26
+  //       next()
27
+  //     }
28
+  //   }
29
+  // } else {
30
+  //   if (whiteList.indexOf(to.path) !== -1) {
31
+  //     next()
32
+  //   } else {
33
+  //     next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
34
+  //     NProgress.done()
35
+  //   }
36
+  // }
37
+  next()
37 38
 })
38 39
 
39 40
 router.afterEach(() => {

+ 3
- 3
VUECODE/smart-operate-manage/src/router/index.js 查看文件

@@ -45,9 +45,9 @@ export const constantRouterMap = [
45 45
     meta: { title: '社区数据', icon: 'zip' },
46 46
     children: [
47 47
       {
48
-        path: 'download',
49
-        component: () => import('@/views/table/index'),
50
-        name: 'ExportZip',
48
+        path: 'community',
49
+        component: () => import('@/views/community/communityTable'),
50
+        name: 'community',
51 51
         meta: { title: '社区列表', icon: 'table' }
52 52
       }
53 53
     ]

+ 50
- 0
VUECODE/smart-operate-manage/src/utils/scrollTo.js 查看文件

@@ -0,0 +1,50 @@
1
+Math.easeInOutQuad = function(t, b, c, d) {
2
+  t /= d / 2
3
+  if (t < 1) {
4
+    return c / 2 * t * t + b
5
+  }
6
+  t--
7
+  return -c / 2 * (t * (t - 2) - 1) + b
8
+}
9
+
10
+// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
11
+var requestAnimFrame = (function() {
12
+  return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
13
+})()
14
+
15
+// because it's so fucking difficult to detect the scrolling element, just move them all
16
+function move(amount) {
17
+  document.documentElement.scrollTop = amount
18
+  document.body.parentNode.scrollTop = amount
19
+  document.body.scrollTop = amount
20
+}
21
+
22
+function position() {
23
+  return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
24
+}
25
+
26
+export function scrollTo(to, duration, callback) {
27
+  const start = position()
28
+  const change = to - start
29
+  const increment = 20
30
+  let currentTime = 0
31
+  duration = (typeof (duration) === 'undefined') ? 500 : duration
32
+  var animateScroll = function() {
33
+    // increment the time
34
+    currentTime += increment
35
+    // find the value with the quadratic in-out easing function
36
+    var val = Math.easeInOutQuad(currentTime, start, change, duration)
37
+    // move the document.body
38
+    move(val)
39
+    // do the animation unless its over
40
+    if (currentTime < duration) {
41
+      requestAnimFrame(animateScroll)
42
+    } else {
43
+      if (callback && typeof (callback) === 'function') {
44
+        // the animation is done so lets callback
45
+        callback()
46
+      }
47
+    }
48
+  }
49
+  animateScroll()
50
+}

+ 206
- 0
VUECODE/smart-operate-manage/src/vendor/Export2Excel.js 查看文件

@@ -0,0 +1,206 @@
1
+/* eslint-disable */
2
+require('script-loader!file-saver');
3
+import XLSX from 'xlsx'
4
+
5
+function generateArray(table) {
6
+  var out = [];
7
+  var rows = table.querySelectorAll('tr');
8
+  var ranges = [];
9
+  for (var R = 0; R < rows.length; ++R) {
10
+    var outRow = [];
11
+    var row = rows[R];
12
+    var columns = row.querySelectorAll('td');
13
+    for (var C = 0; C < columns.length; ++C) {
14
+      var cell = columns[C];
15
+      var colspan = cell.getAttribute('colspan');
16
+      var rowspan = cell.getAttribute('rowspan');
17
+      var cellValue = cell.innerText;
18
+      if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
19
+
20
+      //Skip ranges
21
+      ranges.forEach(function (range) {
22
+        if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
23
+          for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
24
+        }
25
+      });
26
+
27
+      //Handle Row Span
28
+      if (rowspan || colspan) {
29
+        rowspan = rowspan || 1;
30
+        colspan = colspan || 1;
31
+        ranges.push({
32
+          s: {
33
+            r: R,
34
+            c: outRow.length
35
+          },
36
+          e: {
37
+            r: R + rowspan - 1,
38
+            c: outRow.length + colspan - 1
39
+          }
40
+        });
41
+      };
42
+
43
+      //Handle Value
44
+      outRow.push(cellValue !== "" ? cellValue : null);
45
+
46
+      //Handle Colspan
47
+      if (colspan)
48
+        for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
49
+    }
50
+    out.push(outRow);
51
+  }
52
+  return [out, ranges];
53
+};
54
+
55
+function datenum(v, date1904) {
56
+  if (date1904) v += 1462;
57
+  var epoch = Date.parse(v);
58
+  return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
59
+}
60
+
61
+function sheet_from_array_of_arrays(data, opts) {
62
+  var ws = {};
63
+  var range = {
64
+    s: {
65
+      c: 10000000,
66
+      r: 10000000
67
+    },
68
+    e: {
69
+      c: 0,
70
+      r: 0
71
+    }
72
+  };
73
+  for (var R = 0; R != data.length; ++R) {
74
+    for (var C = 0; C != data[R].length; ++C) {
75
+      if (range.s.r > R) range.s.r = R;
76
+      if (range.s.c > C) range.s.c = C;
77
+      if (range.e.r < R) range.e.r = R;
78
+      if (range.e.c < C) range.e.c = C;
79
+      var cell = {
80
+        v: data[R][C]
81
+      };
82
+      if (cell.v == null) continue;
83
+      var cell_ref = XLSX.utils.encode_cell({
84
+        c: C,
85
+        r: R
86
+      });
87
+
88
+      if (typeof cell.v === 'number') cell.t = 'n';
89
+      else if (typeof cell.v === 'boolean') cell.t = 'b';
90
+      else if (cell.v instanceof Date) {
91
+        cell.t = 'n';
92
+        cell.z = XLSX.SSF._table[14];
93
+        cell.v = datenum(cell.v);
94
+      } else cell.t = 's';
95
+
96
+      ws[cell_ref] = cell;
97
+    }
98
+  }
99
+  if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
100
+  return ws;
101
+}
102
+
103
+function Workbook() {
104
+  if (!(this instanceof Workbook)) return new Workbook();
105
+  this.SheetNames = [];
106
+  this.Sheets = {};
107
+}
108
+
109
+function s2ab(s) {
110
+  var buf = new ArrayBuffer(s.length);
111
+  var view = new Uint8Array(buf);
112
+  for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
113
+  return buf;
114
+}
115
+
116
+export function export_table_to_excel(id) {
117
+  var theTable = document.getElementById(id);
118
+  var oo = generateArray(theTable);
119
+  var ranges = oo[1];
120
+
121
+  /* original data */
122
+  var data = oo[0];
123
+  var ws_name = "SheetJS";
124
+
125
+  var wb = new Workbook(),
126
+    ws = sheet_from_array_of_arrays(data);
127
+
128
+  /* add ranges to worksheet */
129
+  // ws['!cols'] = ['apple', 'banan'];
130
+  ws['!merges'] = ranges;
131
+
132
+  /* add worksheet to workbook */
133
+  wb.SheetNames.push(ws_name);
134
+  wb.Sheets[ws_name] = ws;
135
+
136
+  var wbout = XLSX.write(wb, {
137
+    bookType: 'xlsx',
138
+    bookSST: false,
139
+    type: 'binary'
140
+  });
141
+
142
+  saveAs(new Blob([s2ab(wbout)], {
143
+    type: "application/octet-stream"
144
+  }), "test.xlsx")
145
+}
146
+
147
+export function export_json_to_excel({
148
+  header,
149
+  data,
150
+  filename,
151
+  autoWidth = true,
152
+  bookType=  'xlsx'
153
+} = {}) {
154
+  /* original data */
155
+  filename = filename || 'excel-list'
156
+  data = [...data]
157
+  data.unshift(header);
158
+  var ws_name = "SheetJS";
159
+  var wb = new Workbook(),
160
+    ws = sheet_from_array_of_arrays(data);
161
+
162
+  if (autoWidth) {
163
+    /*设置worksheet每列的最大宽度*/
164
+    const colWidth = data.map(row => row.map(val => {
165
+      /*先判断是否为null/undefined*/
166
+      if (val == null) {
167
+        return {
168
+          'wch': 10
169
+        };
170
+      }
171
+      /*再判断是否为中文*/
172
+      else if (val.toString().charCodeAt(0) > 255) {
173
+        return {
174
+          'wch': val.toString().length * 2
175
+        };
176
+      } else {
177
+        return {
178
+          'wch': val.toString().length
179
+        };
180
+      }
181
+    }))
182
+    /*以第一行为初始值*/
183
+    let result = colWidth[0];
184
+    for (let i = 1; i < colWidth.length; i++) {
185
+      for (let j = 0; j < colWidth[i].length; j++) {
186
+        if (result[j]['wch'] < colWidth[i][j]['wch']) {
187
+          result[j]['wch'] = colWidth[i][j]['wch'];
188
+        }
189
+      }
190
+    }
191
+    ws['!cols'] = result;
192
+  }
193
+
194
+  /* add worksheet to workbook */
195
+  wb.SheetNames.push(ws_name);
196
+  wb.Sheets[ws_name] = ws;
197
+
198
+  var wbout = XLSX.write(wb, {
199
+    bookType: bookType,
200
+    bookSST: false,
201
+    type: 'binary'
202
+  });
203
+  saveAs(new Blob([s2ab(wbout)], {
204
+    type: "application/octet-stream"
205
+  }), `${filename}.${bookType}`);
206
+}

+ 24
- 0
VUECODE/smart-operate-manage/src/vendor/Export2Zip.js 查看文件

@@ -0,0 +1,24 @@
1
+/* eslint-disable */
2
+require('script-loader!file-saver');
3
+import JSZip from 'jszip'
4
+
5
+export function export_txt_to_zip(th, jsonData, txtName, zipName) {
6
+  const zip = new JSZip()
7
+  const txt_name = txtName || 'file'
8
+  const zip_name = zipName || 'file'
9
+  const data = jsonData
10
+  let txtData = `${th}\r\n`
11
+  data.forEach((row) => {
12
+    let tempStr = ''
13
+    tempStr = row.toString()
14
+    txtData += `${tempStr}\r\n`
15
+  })
16
+  zip.file(`${txt_name}.txt`, txtData)
17
+  zip.generateAsync({
18
+    type: "blob"
19
+  }).then((blob) => {
20
+    saveAs(blob, `${zip_name}.zip`)
21
+  }, (err) => {
22
+    alert('导出失败')
23
+  })
24
+}

+ 362
- 0
VUECODE/smart-operate-manage/src/views/community/communityTable.vue 查看文件

@@ -0,0 +1,362 @@
1
+<template>
2
+  <div class="app-container">
3
+    <div class="filter-container">
4
+      <el-input :placeholder="$t('table.title')" v-model="listQuery.title" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter"/>
5
+      <el-select v-model="listQuery.importance" :placeholder="$t('table.importance')" clearable style="width: 90px" class="filter-item">
6
+        <el-option v-for="item in importanceOptions" :key="item" :label="item" :value="item"/>
7
+      </el-select>
8
+      <el-select v-model="listQuery.type" :placeholder="$t('table.type')" clearable class="filter-item" style="width: 130px">
9
+        <el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name+'('+item.key+')'" :value="item.key"/>
10
+      </el-select>
11
+      <el-select v-model="listQuery.sort" style="width: 140px" class="filter-item" @change="handleFilter">
12
+        <el-option v-for="item in sortOptions" :key="item.key" :label="item.label" :value="item.key"/>
13
+      </el-select>
14
+      <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">{{ $t('table.search') }}</el-button>
15
+      <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">{{ $t('table.add') }}</el-button>
16
+      <el-button v-waves :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">{{ $t('table.export') }}</el-button>
17
+      <el-checkbox v-model="showReviewer" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">{{ $t('table.reviewer') }}</el-checkbox>
18
+    </div>
19
+
20
+    <el-table
21
+      v-loading="listLoading"
22
+      :key="tableKey"
23
+      :data="list"
24
+      border
25
+      fit
26
+      highlight-current-row
27
+      style="width: 100%;"
28
+      @sort-change="sortChange">
29
+      <el-table-column :label="$t('table.id')" prop="id" sortable="custom" align="center" width="65">
30
+        <template slot-scope="scope">
31
+          <span>{{ scope.row.id }}</span>
32
+        </template>
33
+      </el-table-column>
34
+      <el-table-column :label="$t('table.date')" width="150px" align="center">
35
+        <template slot-scope="scope">
36
+          <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
37
+        </template>
38
+      </el-table-column>
39
+      <el-table-column :label="$t('table.title')" min-width="150px">
40
+        <template slot-scope="scope">
41
+          <span class="link-type" @click="handleUpdate(scope.row)">{{ scope.row.title }}</span>
42
+          <el-tag>{{ scope.row.type | typeFilter }}</el-tag>
43
+        </template>
44
+      </el-table-column>
45
+      <el-table-column :label="$t('table.author')" width="110px" align="center">
46
+        <template slot-scope="scope">
47
+          <span>{{ scope.row.author }}</span>
48
+        </template>
49
+      </el-table-column>
50
+      <el-table-column v-if="showReviewer" :label="$t('table.reviewer')" width="110px" align="center">
51
+        <template slot-scope="scope">
52
+          <span style="color:red;">{{ scope.row.reviewer }}</span>
53
+        </template>
54
+      </el-table-column>
55
+      <el-table-column :label="$t('table.importance')" width="80px">
56
+        <template slot-scope="scope">
57
+          <svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="meta-item__icon"/>
58
+        </template>
59
+      </el-table-column>
60
+      <el-table-column :label="$t('table.readings')" align="center" width="95">
61
+        <template slot-scope="scope">
62
+          <span v-if="scope.row.pageviews" class="link-type" @click="handleFetchPv(scope.row.pageviews)">{{ scope.row.pageviews }}</span>
63
+          <span v-else>0</span>
64
+        </template>
65
+      </el-table-column>
66
+      <el-table-column :label="$t('table.status')" class-name="status-col" width="100">
67
+        <template slot-scope="scope">
68
+          <el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
69
+        </template>
70
+      </el-table-column>
71
+      <el-table-column :label="$t('table.actions')" align="center" width="230" class-name="small-padding fixed-width">
72
+        <template slot-scope="scope">
73
+          <el-button type="primary" size="mini" @click="handleUpdate(scope.row)">{{ $t('table.edit') }}</el-button>
74
+          <el-button v-if="scope.row.status!='published'" size="mini" type="success" @click="handleModifyStatus(scope.row,'published')">{{ $t('table.publish') }}
75
+          </el-button>
76
+          <el-button v-if="scope.row.status!='draft'" size="mini" @click="handleModifyStatus(scope.row,'draft')">{{ $t('table.draft') }}
77
+          </el-button>
78
+          <el-button v-if="scope.row.status!='deleted'" size="mini" type="danger" @click="handleModifyStatus(scope.row,'deleted')">{{ $t('table.delete') }}
79
+          </el-button>
80
+        </template>
81
+      </el-table-column>
82
+    </el-table>
83
+
84
+    <pagination v-show="total>0" :total="total" :pageNum.sync="listQuery.pageNum" :pageSize.sync="listQuery.pageSize" @pagination="getList" />
85
+
86
+    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
87
+      <el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="70px" style="width: 400px; margin-left:50px;">
88
+        <el-form-item :label="$t('table.type')" prop="type">
89
+          <el-select v-model="temp.type" class="filter-item" placeholder="Please select">
90
+            <el-option v-for="item in calendarTypeOptions" :key="item.key" :label="item.display_name" :value="item.key"/>
91
+          </el-select>
92
+        </el-form-item>
93
+        <el-form-item :label="$t('table.date')" prop="timestamp">
94
+          <el-date-picker v-model="temp.timestamp" type="datetime" placeholder="Please pick a date"/>
95
+        </el-form-item>
96
+        <el-form-item :label="$t('table.title')" prop="title">
97
+          <el-input v-model="temp.title"/>
98
+        </el-form-item>
99
+        <el-form-item :label="$t('table.status')">
100
+          <el-select v-model="temp.status" class="filter-item" placeholder="Please select">
101
+            <el-option v-for="item in statusOptions" :key="item" :label="item" :value="item"/>
102
+          </el-select>
103
+        </el-form-item>
104
+        <el-form-item :label="$t('table.importance')">
105
+          <el-rate v-model="temp.importance" :colors="['#99A9BF', '#F7BA2A', '#FF9900']" :max="3" style="margin-top:8px;"/>
106
+        </el-form-item>
107
+        <el-form-item :label="$t('table.remark')">
108
+          <el-input :autosize="{ minRows: 2, maxRows: 4}" v-model="temp.remark" type="textarea" placeholder="Please input"/>
109
+        </el-form-item>
110
+      </el-form>
111
+      <div slot="footer" class="dialog-footer">
112
+        <el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
113
+        <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">{{ $t('table.confirm') }}</el-button>
114
+      </div>
115
+    </el-dialog>
116
+
117
+    <el-dialog :visible.sync="dialogPvVisible" title="Reading statistics">
118
+      <el-table :data="pvData" border fit highlight-current-row style="width: 100%">
119
+        <el-table-column prop="key" label="Channel"/>
120
+        <el-table-column prop="pv" label="Pv"/>
121
+      </el-table>
122
+      <span slot="footer" class="dialog-footer">
123
+        <el-button type="primary" @click="dialogPvVisible = false">{{ $t('table.confirm') }}</el-button>
124
+      </span>
125
+    </el-dialog>
126
+
127
+  </div>
128
+</template>
129
+
130
+<script>
131
+import { fetchList, fetchPv, createArticle, updateArticle } from '@/api/community'
132
+import waves from '@/directive/waves' // Waves directive
133
+import { parseTime } from '@/utils'
134
+import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
135
+
136
+const calendarTypeOptions = [
137
+  { key: 'CN', display_name: 'China' },
138
+  { key: 'US', display_name: 'USA' },
139
+  { key: 'JP', display_name: 'Japan' },
140
+  { key: 'EU', display_name: 'Eurozone' }
141
+]
142
+
143
+// arr to obj ,such as { CN : "China", US : "USA" }
144
+const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
145
+  acc[cur.key] = cur.display_name
146
+  return acc
147
+}, {})
148
+
149
+export default {
150
+  name: 'ComplexTable',
151
+  components: { Pagination },
152
+  directives: { waves },
153
+  filters: {
154
+    statusFilter(status) {
155
+      const statusMap = {
156
+        published: 'success',
157
+        draft: 'info',
158
+        deleted: 'danger'
159
+      }
160
+      return statusMap[status]
161
+    },
162
+    typeFilter(type) {
163
+      return calendarTypeKeyValue[type]
164
+    }
165
+  },
166
+  data() {
167
+    return {
168
+      tableKey: 0,
169
+      list: null,
170
+      total: 0,
171
+      listLoading: true,
172
+      listQuery: {
173
+        pageNum: 1,
174
+        pageSize: 20,
175
+        importance: undefined,
176
+        title: undefined,
177
+        type: undefined,
178
+        sort: undefined
179
+      },
180
+      importanceOptions: [1, 2, 3],
181
+      calendarTypeOptions,
182
+      sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
183
+      statusOptions: ['published', 'draft', 'deleted'],
184
+      showReviewer: false,
185
+      temp: {
186
+        id: undefined,
187
+        importance: 1,
188
+        remark: '',
189
+        timestamp: new Date(),
190
+        title: '',
191
+        type: '',
192
+        status: 'published'
193
+      },
194
+      dialogFormVisible: false,
195
+      dialogStatus: '',
196
+      textMap: {
197
+        update: 'Edit',
198
+        create: 'Create'
199
+      },
200
+      dialogPvVisible: false,
201
+      pvData: [],
202
+      rules: {
203
+        type: [{ required: true, message: 'type is required', trigger: 'change' }],
204
+        timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
205
+        title: [{ required: true, message: 'title is required', trigger: 'blur' }]
206
+      },
207
+      downloadLoading: false
208
+    }
209
+  },
210
+  created() {
211
+    this.getList()
212
+  },
213
+  methods: {
214
+    getList() {
215
+      this.listLoading = true
216
+      fetchList(this.listQuery).then(response => {
217
+        this.list = response.data.items
218
+        this.total = response.data.total
219
+
220
+        // Just to simulate the time of the request
221
+        setTimeout(() => {
222
+          this.listLoading = false
223
+        }, 1.5 * 1000)
224
+      })
225
+    },
226
+    handleFilter() {
227
+      this.listQuery.pageNum = 1
228
+      this.getList()
229
+    },
230
+    handleModifyStatus(row, status) {
231
+      this.$message({
232
+        message: '操作成功',
233
+        type: 'success'
234
+      })
235
+      row.status = status
236
+    },
237
+    sortChange(data) {
238
+      const { prop, order } = data
239
+      if (prop === 'id') {
240
+        this.sortByID(order)
241
+      }
242
+    },
243
+    sortByID(order) {
244
+      if (order === 'ascending') {
245
+        this.listQuery.sort = '+id'
246
+      } else {
247
+        this.listQuery.sort = '-id'
248
+      }
249
+      this.handleFilter()
250
+    },
251
+    resetTemp() {
252
+      this.temp = {
253
+        id: undefined,
254
+        importance: 1,
255
+        remark: '',
256
+        timestamp: new Date(),
257
+        title: '',
258
+        status: 'published',
259
+        type: ''
260
+      }
261
+    },
262
+    handleCreate() {
263
+      this.resetTemp()
264
+      this.dialogStatus = 'create'
265
+      this.dialogFormVisible = true
266
+      this.$nextTick(() => {
267
+        this.$refs['dataForm'].clearValidate()
268
+      })
269
+    },
270
+    createData() {
271
+      this.$refs['dataForm'].validate((valid) => {
272
+        if (valid) {
273
+          this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
274
+          this.temp.author = 'vue-element-admin'
275
+          createArticle(this.temp).then(() => {
276
+            this.list.unshift(this.temp)
277
+            this.dialogFormVisible = false
278
+            this.$notify({
279
+              title: '成功',
280
+              message: '创建成功',
281
+              type: 'success',
282
+              duration: 2000
283
+            })
284
+          })
285
+        }
286
+      })
287
+    },
288
+    handleUpdate(row) {
289
+      this.temp = Object.assign({}, row) // copy obj
290
+      this.temp.timestamp = new Date(this.temp.timestamp)
291
+      this.dialogStatus = 'update'
292
+      this.dialogFormVisible = true
293
+      this.$nextTick(() => {
294
+        this.$refs['dataForm'].clearValidate()
295
+      })
296
+    },
297
+    updateData() {
298
+      this.$refs['dataForm'].validate((valid) => {
299
+        if (valid) {
300
+          const tempData = Object.assign({}, this.temp)
301
+          tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
302
+          updateArticle(tempData).then(() => {
303
+            for (const v of this.list) {
304
+              if (v.id === this.temp.id) {
305
+                const index = this.list.indexOf(v)
306
+                this.list.splice(index, 1, this.temp)
307
+                break
308
+              }
309
+            }
310
+            this.dialogFormVisible = false
311
+            this.$notify({
312
+              title: '成功',
313
+              message: '更新成功',
314
+              type: 'success',
315
+              duration: 2000
316
+            })
317
+          })
318
+        }
319
+      })
320
+    },
321
+    handleDelete(row) {
322
+      this.$notify({
323
+        title: '成功',
324
+        message: '删除成功',
325
+        type: 'success',
326
+        duration: 2000
327
+      })
328
+      const index = this.list.indexOf(row)
329
+      this.list.splice(index, 1)
330
+    },
331
+    handleFetchPv(pv) {
332
+      fetchPv(pv).then(response => {
333
+        this.pvData = response.data.pvData
334
+        this.dialogPvVisible = true
335
+      })
336
+    },
337
+    handleDownload() {
338
+      this.downloadLoading = true
339
+      import('@/vendor/Export2Excel').then(excel => {
340
+        const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
341
+        const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
342
+        const data = this.formatJson(filterVal, this.list)
343
+        excel.export_json_to_excel({
344
+          header: tHeader,
345
+          data,
346
+          filename: 'table-list'
347
+        })
348
+        this.downloadLoading = false
349
+      })
350
+    },
351
+    formatJson(filterVal, jsonData) {
352
+      return jsonData.map(v => filterVal.map(j => {
353
+        if (j === 'timestamp') {
354
+          return parseTime(v[j])
355
+        } else {
356
+          return v[j]
357
+        }
358
+      }))
359
+    }
360
+  }
361
+}
362
+</script>

+ 15
- 14
VUECODE/smart-operate-manage/src/views/login/index.vue 查看文件

@@ -70,20 +70,21 @@ export default {
70 70
   },
71 71
   methods: {
72 72
     handleLogin() {
73
-      this.$refs.loginForm.validate(valid => {
74
-        if (valid) {
75
-          this.loading = true
76
-          this.$store.dispatch('Login', this.loginForm).then(() => {
77
-            this.loading = false
78
-            this.$router.push({ path: this.redirect || '/' })
79
-          }).catch(() => {
80
-            this.loading = false
81
-          })
82
-        } else {
83
-          console.log('error submit!!')
84
-          return false
85
-        }
86
-      })
73
+      // this.$refs.loginForm.validate(valid => {
74
+      //   if (valid) {
75
+      //     this.loading = true
76
+      //     this.$store.dispatch('Login', this.loginForm).then(() => {
77
+      //       this.loading = false
78
+      //       this.$router.push({ path: this.redirect || '/' })
79
+      //     }).catch(() => {
80
+      //       this.loading = false
81
+      //     })
82
+      //   } else {
83
+      //     console.log('error submit!!')
84
+      //     return false
85
+      //   }
86
+      // })
87
+      this.$router.push({ path: this.redirect || '/' })
87 88
     },
88 89
     sendCode() {
89 90
       this.$store.dispatch('SendCode', this.loginForm.username).then((res) => {