魏超 6 лет назад
Родитель
Сommit
b9c9d832f4
100 измененных файлов: 4014 добавлений и 23 удалений
  1. Двоичные данные
      CODE/smart-community/community-common/target/classes/com/community/commom/constant/Constant.class
  2. 11
    4
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/controller/BannerController.java
  3. 20
    6
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/controller/CommunityController.java
  4. 21
    0
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/controller/UserController.java
  5. 9
    0
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/dao/ToSysRoleMapper.java
  6. 2
    1
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/CommunityServiceI.java
  7. 3
    1
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/IToBannerService.java
  8. 18
    0
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/IToSysRoleService.java
  9. 7
    0
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/IToUserService.java
  10. 9
    3
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/impl/CommunityServiceImpl.java
  11. 4
    1
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/impl/ToBannerServiceImpl.java
  12. 24
    0
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/impl/ToSysRoleServiceImpl.java
  13. 28
    0
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/impl/ToUserServerImpl.java
  14. 5
    0
      CODE/smart-community/operate-api/src/main/java/com/community/huiju/vo/ToUserVO.java
  15. 6
    0
      CODE/smart-community/operate-api/src/main/resources/mapper/ToSysRoleMapper.xml
  16. 2
    3
      CODE/smart-community/zuul/src/main/java/com/community/huiju/security/RestAuthenticationEntryPoint.java
  17. 12
    1
      CODE/smart-community/zuul/src/main/java/com/community/huiju/security/RestPreAuthenticateProvider.java
  18. 2
    2
      CODE/smart-community/zuul/src/main/java/com/community/huiju/security/RestPreAuthenticatedProcessingFilter.java
  19. 1
    1
      CODE/smart-community/zuul/src/main/resources/mapper/ToSysRoleMapper.xml
  20. 12
    0
      VUECODE/smart-operate-manage/.babelrc
  21. 14
    0
      VUECODE/smart-operate-manage/.editorconfig
  22. 3
    0
      VUECODE/smart-operate-manage/.eslintignore
  23. 196
    0
      VUECODE/smart-operate-manage/.eslintrc.js
  24. 15
    0
      VUECODE/smart-operate-manage/.gitignore
  25. 10
    0
      VUECODE/smart-operate-manage/.postcssrc.js
  26. 5
    0
      VUECODE/smart-operate-manage/.travis.yml
  27. 21
    0
      VUECODE/smart-operate-manage/LICENSE
  28. 96
    0
      VUECODE/smart-operate-manage/README-zh.md
  29. 88
    0
      VUECODE/smart-operate-manage/README.md
  30. 45
    0
      VUECODE/smart-operate-manage/build/build.js
  31. 64
    0
      VUECODE/smart-operate-manage/build/check-versions.js
  32. Двоичные данные
      VUECODE/smart-operate-manage/build/logo.png
  33. 108
    0
      VUECODE/smart-operate-manage/build/utils.js
  34. 5
    0
      VUECODE/smart-operate-manage/build/vue-loader.conf.js
  35. 107
    0
      VUECODE/smart-operate-manage/build/webpack.base.conf.js
  36. 95
    0
      VUECODE/smart-operate-manage/build/webpack.dev.conf.js
  37. 178
    0
      VUECODE/smart-operate-manage/build/webpack.prod.conf.js
  38. 8
    0
      VUECODE/smart-operate-manage/config/dev.env.js
  39. 87
    0
      VUECODE/smart-operate-manage/config/index.js
  40. 5
    0
      VUECODE/smart-operate-manage/config/prod.env.js
  41. Двоичные данные
      VUECODE/smart-operate-manage/favicon.ico
  42. 12
    0
      VUECODE/smart-operate-manage/index.html
  43. 88
    0
      VUECODE/smart-operate-manage/package.json
  44. 11
    0
      VUECODE/smart-operate-manage/src/App.vue
  45. 11
    0
      VUECODE/smart-operate-manage/src/api/banner.js
  46. 41
    0
      VUECODE/smart-operate-manage/src/api/community.js
  47. 38
    0
      VUECODE/smart-operate-manage/src/api/login.js
  48. 9
    0
      VUECODE/smart-operate-manage/src/api/table.js
  49. Двоичные данные
      VUECODE/smart-operate-manage/src/assets/404_images/404.png
  50. Двоичные данные
      VUECODE/smart-operate-manage/src/assets/404_images/404_cloud.png
  51. 61
    0
      VUECODE/smart-operate-manage/src/components/Breadcrumb/index.vue
  52. 58
    0
      VUECODE/smart-operate-manage/src/components/Hamburger/index.vue
  53. 99
    0
      VUECODE/smart-operate-manage/src/components/Pagination/index.vue
  54. 43
    0
      VUECODE/smart-operate-manage/src/components/SvgIcon/index.vue
  55. 49
    0
      VUECODE/smart-operate-manage/src/directive/clipboard/clipboard.js
  56. 13
    0
      VUECODE/smart-operate-manage/src/directive/clipboard/index.js
  57. 77
    0
      VUECODE/smart-operate-manage/src/directive/el-dragDialog/drag.js
  58. 13
    0
      VUECODE/smart-operate-manage/src/directive/el-dragDialog/index.js
  59. 13
    0
      VUECODE/smart-operate-manage/src/directive/permission/index.js
  60. 23
    0
      VUECODE/smart-operate-manage/src/directive/permission/permission.js
  61. 91
    0
      VUECODE/smart-operate-manage/src/directive/sticky.js
  62. 13
    0
      VUECODE/smart-operate-manage/src/directive/waves/index.js
  63. 26
    0
      VUECODE/smart-operate-manage/src/directive/waves/waves.css
  64. 42
    0
      VUECODE/smart-operate-manage/src/directive/waves/waves.js
  65. 9
    0
      VUECODE/smart-operate-manage/src/icons/index.js
  66. 1
    0
      VUECODE/smart-operate-manage/src/icons/svg/example.svg
  67. 1
    0
      VUECODE/smart-operate-manage/src/icons/svg/eye.svg
  68. 1
    0
      VUECODE/smart-operate-manage/src/icons/svg/form.svg
  69. 1
    0
      VUECODE/smart-operate-manage/src/icons/svg/link.svg
  70. 1
    0
      VUECODE/smart-operate-manage/src/icons/svg/nested.svg
  71. 1
    0
      VUECODE/smart-operate-manage/src/icons/svg/password.svg
  72. 1
    0
      VUECODE/smart-operate-manage/src/icons/svg/table.svg
  73. 1
    0
      VUECODE/smart-operate-manage/src/icons/svg/tree.svg
  74. 1
    0
      VUECODE/smart-operate-manage/src/icons/svg/user.svg
  75. 22
    0
      VUECODE/smart-operate-manage/src/icons/svgo.yml
  76. 27
    0
      VUECODE/smart-operate-manage/src/main.js
  77. 42
    0
      VUECODE/smart-operate-manage/src/permission.js
  78. 79
    0
      VUECODE/smart-operate-manage/src/router/index.js
  79. 9
    0
      VUECODE/smart-operate-manage/src/store/getters.js
  80. 17
    0
      VUECODE/smart-operate-manage/src/store/index.js
  81. 43
    0
      VUECODE/smart-operate-manage/src/store/modules/app.js
  82. 99
    0
      VUECODE/smart-operate-manage/src/store/modules/user.js
  83. 29
    0
      VUECODE/smart-operate-manage/src/styles/element-ui.scss
  84. 78
    0
      VUECODE/smart-operate-manage/src/styles/index.scss
  85. 27
    0
      VUECODE/smart-operate-manage/src/styles/mixin.scss
  86. 133
    0
      VUECODE/smart-operate-manage/src/styles/sidebar.scss
  87. 46
    0
      VUECODE/smart-operate-manage/src/styles/transition.scss
  88. 4
    0
      VUECODE/smart-operate-manage/src/styles/variables.scss
  89. 15
    0
      VUECODE/smart-operate-manage/src/utils/auth.js
  90. 74
    0
      VUECODE/smart-operate-manage/src/utils/index.js
  91. 73
    0
      VUECODE/smart-operate-manage/src/utils/request.js
  92. 50
    0
      VUECODE/smart-operate-manage/src/utils/scrollTo.js
  93. 38
    0
      VUECODE/smart-operate-manage/src/utils/validate.js
  94. 206
    0
      VUECODE/smart-operate-manage/src/vendor/Export2Excel.js
  95. 24
    0
      VUECODE/smart-operate-manage/src/vendor/Export2Zip.js
  96. 228
    0
      VUECODE/smart-operate-manage/src/views/404.vue
  97. 62
    0
      VUECODE/smart-operate-manage/src/views/banner/index.vue
  98. 362
    0
      VUECODE/smart-operate-manage/src/views/community/communityTable.vue
  99. 32
    0
      VUECODE/smart-operate-manage/src/views/dashboard/index.vue
  100. 0
    0
      VUECODE/smart-operate-manage/src/views/form/index.vue

Двоичные данные
CODE/smart-community/community-common/target/classes/com/community/commom/constant/Constant.class Просмотреть файл


+ 11
- 4
CODE/smart-community/operate-api/src/main/java/com/community/huiju/controller/BannerController.java Просмотреть файл

@@ -17,6 +17,9 @@ import org.springframework.web.bind.annotation.*;
17 17
 import javax.servlet.http.HttpSession;
18 18
 import javax.validation.Valid;
19 19
 
20
+/**
21
+ * @author weiximei
22
+ */
20 23
 @RestController
21 24
 @RefreshScope
22 25
 @RequestMapping("/")
@@ -79,11 +82,15 @@ public class BannerController {
79 82
             @ApiImplicitParam(paramType = "query",dataType = "String",name = "bannerTitle",value = "bannerTitle(标题)"),
80 83
             @ApiImplicitParam(paramType = "query",dataType = "Integer",name = "bannerPosition",value = "bannerPosition(Banner位)"),
81 84
             @ApiImplicitParam(paramType = "query",dataType = "String",name = "bannerDescription",value = "bannerDescription(跳转概述)"),
85
+            @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "pageNum", value = "分页第几页"),
86
+            @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "pageSize", value = "分页每页长度")
82 87
     })
83 88
     @RequestMapping(value = "/banner/list",method = RequestMethod.GET)
84
-    public ResponseBean getBanner(@RequestParam(value = "bannerTitle") String bannerTitle,
85
-                                  @RequestParam(value = "bannerPosition") Integer bannerPosition,
86
-                                  @RequestParam(value = "bannerDescription") String bannerDescription){
89
+    public ResponseBean getBanner(@RequestParam(value = "bannerTitle", required = false) String bannerTitle,
90
+                                  @RequestParam(value = "bannerPosition", required = false) Integer bannerPosition,
91
+                                  @RequestParam(value = "bannerDescription", required = false) String bannerDescription,
92
+                                  @RequestParam(value ="pageNum",defaultValue = "1") Integer pageNum,
93
+                                  @RequestParam(value ="pageSize",defaultValue = "10") Integer pageSize){
87 94
 
88 95
 
89 96
         ResponseBean response = new ResponseBean();
@@ -91,7 +98,7 @@ public class BannerController {
91 98
         banner.setBannerTitle(bannerTitle);
92 99
         banner.setBannerPosition(bannerPosition);
93 100
         banner.setBannerDescription(bannerDescription);
94
-        response = iToBannerService.getBanner(banner);
101
+        response = iToBannerService.getBanner(banner,pageNum,pageSize);
95 102
         return response;
96 103
     }
97 104
 

+ 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
 	

+ 21
- 0
CODE/smart-community/operate-api/src/main/java/com/community/huiju/controller/UserController.java Просмотреть файл

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
4 4
 import com.community.commom.constant.Constant;
5 5
 import com.community.commom.mode.ResponseBean;
6 6
 import com.community.commom.session.UserElement;
7
+import com.community.huiju.model.ToUser;
7 8
 import com.community.huiju.service.IToUserService;
8 9
 import com.community.huiju.vo.ToUserVO;
9 10
 import io.swagger.annotations.Api;
@@ -56,4 +57,24 @@ public class UserController {
56 57
     }
57 58
 
58 59
 
60
+    @ApiOperation(value = "获取用户信息",nickname = "获取用户信息")
61
+    @ApiImplicitParams({
62
+            @ApiImplicitParam(paramType = "header",dataType = "String",name = "X-Auth-Token",value = "Token"),
63
+    })
64
+    @RequestMapping(value = "/user/info",method = RequestMethod.GET)
65
+    public ResponseBean getInfo(HttpSession session) {
66
+        ResponseBean response = new ResponseBean();
67
+
68
+        UserElement userElement = (UserElement) session.getAttribute(Constant.WEB_USER_SESSION);
69
+        if (null == userElement) {
70
+            response.addError("请登录!");
71
+            return response;
72
+        }
73
+
74
+        response = iToUserService.getInfo(userElement.getId());
75
+
76
+        return response;
77
+    }
78
+
79
+
59 80
 }

+ 9
- 0
CODE/smart-community/operate-api/src/main/java/com/community/huiju/dao/ToSysRoleMapper.java Просмотреть файл

@@ -3,6 +3,8 @@ package com.community.huiju.dao;
3 3
 import com.community.huiju.model.ToSysRole;
4 4
 import org.apache.ibatis.annotations.Mapper;
5 5
 
6
+import java.util.List;
7
+
6 8
 @Mapper
7 9
 public interface ToSysRoleMapper {
8 10
     int deleteByPrimaryKey(Integer id);
@@ -16,4 +18,11 @@ public interface ToSysRoleMapper {
16 18
     int updateByPrimaryKeySelective(ToSysRole record);
17 19
 
18 20
     int updateByPrimaryKey(ToSysRole record);
21
+
22
+    /**
23
+     * 根据用户ID查询所有角色
24
+     * @param userId
25
+     * @return
26
+     */
27
+    List<ToSysRole> selectRoleByUserId(Integer userId);
19 28
 }

+ 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
 	 * 添加新的小区

+ 3
- 1
CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/IToBannerService.java Просмотреть файл

@@ -41,8 +41,10 @@ public interface IToBannerService {
41 41
      *
42 42
      *
43 43
      * @param banner
44
+     * @param pageNum
45
+     * @param pageSize
44 46
      * @return
45 47
      */
46
-    ResponseBean getBanner(ToBanner banner);
48
+    ResponseBean getBanner(ToBanner banner, Integer pageNum, Integer pageSize);
47 49
 
48 50
 }

+ 18
- 0
CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/IToSysRoleService.java Просмотреть файл

@@ -0,0 +1,18 @@
1
+package com.community.huiju.service;
2
+
3
+import com.community.huiju.model.ToSysRole;
4
+
5
+import java.util.List;
6
+
7
+/**
8
+ * 角色 业务
9
+ * @author weiximei
10
+ */
11
+public interface IToSysRoleService {
12
+    /**
13
+     * 根据用户ID查询所有角色
14
+     * @param userId
15
+     * @return
16
+     */
17
+    List<ToSysRole> selectRoleByUserId(Integer userId);
18
+}

+ 7
- 0
CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/IToUserService.java Просмотреть файл

@@ -16,4 +16,11 @@ public interface IToUserService {
16 16
      */
17 17
     ResponseBean login(String loginName,String code);
18 18
 
19
+    /**
20
+     * 获取用户信息
21
+     * @param userId
22
+     * @return
23
+     */
24
+    ResponseBean getInfo(Integer userId);
25
+
19 26
 }

+ 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
CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/impl/ToBannerServiceImpl.java Просмотреть файл

@@ -12,6 +12,7 @@ import com.community.huiju.model.ToCommunities;
12 12
 import com.community.huiju.model.ToUser;
13 13
 import com.community.huiju.service.IToBannerService;
14 14
 import com.community.huiju.vo.ToBannerVO;
15
+import com.github.pagehelper.PageHelper;
15 16
 import org.apache.commons.lang.StringUtils;
16 17
 import org.springframework.beans.BeanUtils;
17 18
 import org.springframework.beans.factory.annotation.Autowired;
@@ -129,11 +130,13 @@ public class ToBannerServiceImpl implements IToBannerService {
129 130
     }
130 131
 
131 132
     @Override
132
-    public ResponseBean getBanner(ToBanner banner) {
133
+    public ResponseBean getBanner(ToBanner banner,Integer pageNum, Integer pageSize) {
133 134
 
134 135
         ResponseBean response = new ResponseBean();
135 136
 
137
+        PageHelper.startPage(pageNum,pageSize);
136 138
         List<ToBanner> bannerList = toBannerMapper.selectBanner(banner);
139
+
137 140
         List<ToBannerVO> bannerVOList = bannerList.stream().map(e->{
138 141
             ToBannerVO toBannerVO = new ToBannerVO();
139 142
             BeanUtils.copyProperties(e,toBannerVO);

+ 24
- 0
CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/impl/ToSysRoleServiceImpl.java Просмотреть файл

@@ -0,0 +1,24 @@
1
+package com.community.huiju.service.impl;
2
+
3
+import com.community.huiju.dao.ToSysRoleMapper;
4
+import com.community.huiju.model.ToSysRole;
5
+import com.community.huiju.service.IToSysRoleService;
6
+import lombok.extern.slf4j.Slf4j;
7
+import org.springframework.beans.factory.annotation.Autowired;
8
+import org.springframework.stereotype.Service;
9
+
10
+import java.util.List;
11
+
12
+@Service("iToSysRoleService")
13
+@Slf4j
14
+public class ToSysRoleServiceImpl implements IToSysRoleService {
15
+
16
+    @Autowired
17
+    private ToSysRoleMapper toSysRoleMapper;
18
+
19
+    @Override
20
+    public List<ToSysRole> selectRoleByUserId(Integer userId) {
21
+
22
+        return toSysRoleMapper.selectRoleByUserId(userId);
23
+    }
24
+}

+ 28
- 0
CODE/smart-community/operate-api/src/main/java/com/community/huiju/service/impl/ToUserServerImpl.java Просмотреть файл

@@ -3,7 +3,9 @@ package com.community.huiju.service.impl;
3 3
 import com.community.commom.mode.ResponseBean;
4 4
 import com.community.commom.utils.AccountValidatorUtil;
5 5
 import com.community.huiju.common.code.cache.AppkeyCache;
6
+import com.community.huiju.dao.ToSysRoleMapper;
6 7
 import com.community.huiju.dao.ToUserMapper;
8
+import com.community.huiju.model.ToSysRole;
7 9
 import com.community.huiju.model.ToUser;
8 10
 import com.community.huiju.service.IToUserService;
9 11
 import com.community.huiju.vo.ToUserVO;
@@ -13,6 +15,8 @@ import org.springframework.beans.BeanUtils;
13 15
 import org.springframework.beans.factory.annotation.Autowired;
14 16
 import org.springframework.stereotype.Service;
15 17
 
18
+import java.util.List;
19
+
16 20
 @Service("iToUserServer")
17 21
 @Slf4j
18 22
 public class ToUserServerImpl implements IToUserService {
@@ -20,6 +24,9 @@ public class ToUserServerImpl implements IToUserService {
20 24
     @Autowired
21 25
     private ToUserMapper toUserMapper;
22 26
 
27
+    @Autowired
28
+    private ToSysRoleMapper toSysRoleMapper;
29
+
23 30
     @Override
24 31
     public ResponseBean login(String loginName, String code) {
25 32
 
@@ -52,4 +59,25 @@ public class ToUserServerImpl implements IToUserService {
52 59
         response.addSuccess(userVO);
53 60
         return response;
54 61
     }
62
+
63
+
64
+    @Override
65
+    public ResponseBean getInfo(Integer userId) {
66
+        ResponseBean response = new ResponseBean();
67
+        ToUser toUser = toUserMapper.selectByPrimaryKey(userId);
68
+        if (toUser == null) {
69
+            response.addError("用户不存在!");
70
+            return response;
71
+        }
72
+
73
+        ToUserVO toUserVO = new ToUserVO();
74
+        BeanUtils.copyProperties(toUser,toUserVO);
75
+
76
+        List<ToSysRole> sysRoleList = toSysRoleMapper.selectRoleByUserId(userId);
77
+        toUserVO.setRoles(sysRoleList);
78
+
79
+        response.addSuccess(toUserVO);
80
+
81
+        return response;
82
+    }
55 83
 }

+ 5
- 0
CODE/smart-community/operate-api/src/main/java/com/community/huiju/vo/ToUserVO.java Просмотреть файл

@@ -1,10 +1,12 @@
1 1
 package com.community.huiju.vo;
2 2
 
3
+import com.community.huiju.model.ToSysRole;
3 4
 import lombok.AllArgsConstructor;
4 5
 import lombok.Data;
5 6
 import lombok.NoArgsConstructor;
6 7
 
7 8
 import java.util.Date;
9
+import java.util.List;
8 10
 
9 11
 /**
10 12
  * @author weiximei
@@ -49,4 +51,7 @@ public class ToUserVO {
49 51
     /** 用户token **/
50 52
     private String token;
51 53
 
54
+    /** 角色 **/
55
+    private List<ToSysRole> roles;
56
+
52 57
 }

+ 6
- 0
CODE/smart-community/operate-api/src/main/resources/mapper/ToSysRoleMapper.xml Просмотреть файл

@@ -125,4 +125,10 @@
125 125
       update_date = #{updateDate,jdbcType=TIMESTAMP}
126 126
     where id = #{id,jdbcType=INTEGER}
127 127
   </update>
128
+
129
+  <select id="selectRoleByUserId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
130
+    select
131
+    role.*
132
+     from to_sys_user_role ur left join to_sys_role role on ur.role_id = role.id where ur.user_id=#{userId}
133
+  </select>
128 134
 </mapper>

+ 2
- 3
CODE/smart-community/zuul/src/main/java/com/community/huiju/security/RestAuthenticationEntryPoint.java Просмотреть файл

@@ -35,10 +35,9 @@ public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
35 35
             }else if (Status.RESPONSE_STATUS_803.getValue().equals(headerError)) {
36 36
                 result.addError(Status.RESPONSE_STATUS_803.getValue(),Status.RESPONSE_STATUS_803.getComment());
37 37
             }
38
+        } else {
39
+            result.addError(Status.RESPONSE_STATUS_888.getValue(),Status.RESPONSE_STATUS_888.getComment());
38 40
         }
39
-//        else {
40
-//            result.addError(Status.RESPONSE_STATUS_888.getValue(),Status.RESPONSE_STATUS_888.getComment());
41
-//        }
42 41
 
43 42
         try {
44 43
             //设置跨域请求 请求结果json刷到响应里

+ 12
- 1
CODE/smart-community/zuul/src/main/java/com/community/huiju/security/RestPreAuthenticateProvider.java Просмотреть файл

@@ -1,11 +1,16 @@
1 1
 package com.community.huiju.security;
2 2
 
3
+import com.community.commom.constant.Constant;
3 4
 import com.community.huiju.exception.WisdomSecurityException;
4 5
 import org.springframework.security.authentication.AuthenticationProvider;
5 6
 import org.springframework.security.core.Authentication;
6 7
 import org.springframework.security.core.AuthenticationException;
8
+import org.springframework.security.core.GrantedAuthority;
7 9
 import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
8 10
 
11
+import java.util.Collection;
12
+import java.util.List;
13
+
9 14
 /**
10 15
  * 授权过程
11 16
  *
@@ -18,7 +23,13 @@ public class RestPreAuthenticateProvider implements AuthenticationProvider {
18 23
 
19 24
 
20 25
         TokenAuthrentication tokenAuthrentication = (TokenAuthrentication) authentication.getPrincipal();
21
-        if (null != tokenAuthrentication.getAuthorities() && tokenAuthrentication.getAuthorities().size() > 0) {
26
+        Collection<GrantedAuthority> grantedAuthorityList = tokenAuthrentication.getAuthorities();
27
+        if (null != grantedAuthorityList && grantedAuthorityList.size() > 0) {
28
+             boolean isNone= grantedAuthorityList.stream().anyMatch(e->e.getAuthority().equals(Constant.ROLE_NONE));
29
+             if (isNone) {
30
+                 tokenAuthrentication.setAuthenticated(false);
31
+                 return tokenAuthrentication;
32
+             }
22 33
             tokenAuthrentication.setAuthenticated(true);
23 34
             return tokenAuthrentication;
24 35
         }

+ 2
- 2
CODE/smart-community/zuul/src/main/java/com/community/huiju/security/RestPreAuthenticatedProcessingFilter.java Просмотреть файл

@@ -57,7 +57,7 @@ public class RestPreAuthenticatedProcessingFilter extends AbstractPreAuthenticat
57 57
         // 不需要的拦截请求处理
58 58
         if (isNoneSecurity(request.getRequestURI().toString()) || "OPTIONS".equals(request.getMethod())){
59 59
             GrantedAuthority[] authorities = new GrantedAuthority[1];
60
-            GrantedAuthority roleNone = new SimpleGrantedAuthority(Constant.ROLE_NONE);
60
+            GrantedAuthority roleNone = new SimpleGrantedAuthority(Constant.ROLE_NONEUSER);
61 61
             authorities[0]=roleNone;
62 62
             grantedAuthorityList.add(authorities[0]);
63 63
             return new TokenAuthrentication(grantedAuthorityList);
@@ -89,7 +89,7 @@ public class RestPreAuthenticatedProcessingFilter extends AbstractPreAuthenticat
89 89
         }else {
90 90
             // 校验有问题后, 需要给个角色, 让流程继续下去
91 91
             GrantedAuthority[] authorities = new GrantedAuthority[1];
92
-            GrantedAuthority roleNone = new SimpleGrantedAuthority("ROLE_NONE");
92
+            GrantedAuthority roleNone = new SimpleGrantedAuthority(Constant.ROLE_NONE);
93 93
             authorities[0]=roleNone;
94 94
             grantedAuthorityList.add(authorities[0]);
95 95
         }

+ 1
- 1
CODE/smart-community/zuul/src/main/resources/mapper/ToSysRoleMapper.xml Просмотреть файл

@@ -129,7 +129,7 @@
129 129
   <select id="selectRoleByUserId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
130 130
     select
131 131
     role.*
132
-     from to_sys_user_role ur left join ta_sys_role role on ur.role_id = role.id where ur.user_id=#{userId}
132
+     from to_sys_user_role ur left join to_sys_role role on ur.role_id = role.id where ur.user_id=#{userId}
133 133
   </select>
134 134
 
135 135
 </mapper>

+ 12
- 0
VUECODE/smart-operate-manage/.babelrc Просмотреть файл

@@ -0,0 +1,12 @@
1
+{
2
+  "presets": [
3
+    ["env", {
4
+      "modules": false,
5
+      "targets": {
6
+        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
7
+      }
8
+    }],
9
+    "stage-2"
10
+  ],
11
+  "plugins":["transform-vue-jsx", "transform-runtime"]
12
+}

+ 14
- 0
VUECODE/smart-operate-manage/.editorconfig Просмотреть файл

@@ -0,0 +1,14 @@
1
+# http://editorconfig.org
2
+root = true
3
+
4
+[*]
5
+charset = utf-8
6
+indent_style = space
7
+indent_size = 2
8
+end_of_line = lf
9
+insert_final_newline = true
10
+trim_trailing_whitespace = true
11
+
12
+[*.md]
13
+insert_final_newline = false
14
+trim_trailing_whitespace = false

+ 3
- 0
VUECODE/smart-operate-manage/.eslintignore Просмотреть файл

@@ -0,0 +1,3 @@
1
+build/*.js
2
+config/*.js
3
+src/assets

+ 196
- 0
VUECODE/smart-operate-manage/.eslintrc.js Просмотреть файл

@@ -0,0 +1,196 @@
1
+module.exports = {
2
+  root: true,
3
+  parserOptions: {
4
+    parser: 'babel-eslint',
5
+    sourceType: 'module'
6
+  },
7
+  env: {
8
+    browser: true,
9
+    node: true,
10
+    es6: true,
11
+  },
12
+  extends: ['plugin:vue/recommended', 'eslint:recommended'],
13
+
14
+  // add your custom rules here
15
+  //it is base on https://github.com/vuejs/eslint-config-vue
16
+  rules: {
17
+    "vue/max-attributes-per-line": [2, {
18
+      "singleline": 10,
19
+      "multiline": {
20
+        "max": 1,
21
+        "allowFirstLine": false
22
+      }
23
+    }],
24
+    "vue/name-property-casing": ["error", "PascalCase"],
25
+    'accessor-pairs': 2,
26
+    'arrow-spacing': [2, {
27
+      'before': true,
28
+      'after': true
29
+    }],
30
+    'block-spacing': [2, 'always'],
31
+    'brace-style': [2, '1tbs', {
32
+      'allowSingleLine': true
33
+    }],
34
+    'camelcase': [0, {
35
+      'properties': 'always'
36
+    }],
37
+    'comma-dangle': [2, 'never'],
38
+    'comma-spacing': [2, {
39
+      'before': false,
40
+      'after': true
41
+    }],
42
+    'comma-style': [2, 'last'],
43
+    'constructor-super': 2,
44
+    'curly': [2, 'multi-line'],
45
+    'dot-location': [2, 'property'],
46
+    'eol-last': 2,
47
+    'eqeqeq': [2, 'allow-null'],
48
+    'generator-star-spacing': [2, {
49
+      'before': true,
50
+      'after': true
51
+    }],
52
+    'handle-callback-err': [2, '^(err|error)$'],
53
+    'indent': [2, 2, {
54
+      'SwitchCase': 1
55
+    }],
56
+    'jsx-quotes': [2, 'prefer-single'],
57
+    'key-spacing': [2, {
58
+      'beforeColon': false,
59
+      'afterColon': true
60
+    }],
61
+    'keyword-spacing': [2, {
62
+      'before': true,
63
+      'after': true
64
+    }],
65
+    'new-cap': [2, {
66
+      'newIsCap': true,
67
+      'capIsNew': false
68
+    }],
69
+    'new-parens': 2,
70
+    'no-array-constructor': 2,
71
+    'no-caller': 2,
72
+    'no-console': 'off',
73
+    'no-class-assign': 2,
74
+    'no-cond-assign': 2,
75
+    'no-const-assign': 2,
76
+    'no-control-regex': 2,
77
+    'no-delete-var': 2,
78
+    'no-dupe-args': 2,
79
+    'no-dupe-class-members': 2,
80
+    'no-dupe-keys': 2,
81
+    'no-duplicate-case': 2,
82
+    'no-empty-character-class': 2,
83
+    'no-empty-pattern': 2,
84
+    'no-eval': 2,
85
+    'no-ex-assign': 2,
86
+    'no-extend-native': 2,
87
+    'no-extra-bind': 2,
88
+    'no-extra-boolean-cast': 2,
89
+    'no-extra-parens': [2, 'functions'],
90
+    'no-fallthrough': 2,
91
+    'no-floating-decimal': 2,
92
+    'no-func-assign': 2,
93
+    'no-implied-eval': 2,
94
+    'no-inner-declarations': [2, 'functions'],
95
+    'no-invalid-regexp': 2,
96
+    'no-irregular-whitespace': 2,
97
+    'no-iterator': 2,
98
+    'no-label-var': 2,
99
+    'no-labels': [2, {
100
+      'allowLoop': false,
101
+      'allowSwitch': false
102
+    }],
103
+    'no-lone-blocks': 2,
104
+    'no-mixed-spaces-and-tabs': 2,
105
+    'no-multi-spaces': 2,
106
+    'no-multi-str': 2,
107
+    'no-multiple-empty-lines': [2, {
108
+      'max': 1
109
+    }],
110
+    'no-native-reassign': 2,
111
+    'no-negated-in-lhs': 2,
112
+    'no-new-object': 2,
113
+    'no-new-require': 2,
114
+    'no-new-symbol': 2,
115
+    'no-new-wrappers': 2,
116
+    'no-obj-calls': 2,
117
+    'no-octal': 2,
118
+    'no-octal-escape': 2,
119
+    'no-path-concat': 2,
120
+    'no-proto': 2,
121
+    'no-redeclare': 2,
122
+    'no-regex-spaces': 2,
123
+    'no-return-assign': [2, 'except-parens'],
124
+    'no-self-assign': 2,
125
+    'no-self-compare': 2,
126
+    'no-sequences': 2,
127
+    'no-shadow-restricted-names': 2,
128
+    'no-spaced-func': 2,
129
+    'no-sparse-arrays': 2,
130
+    'no-this-before-super': 2,
131
+    'no-throw-literal': 2,
132
+    'no-trailing-spaces': 2,
133
+    'no-undef': 2,
134
+    'no-undef-init': 2,
135
+    'no-unexpected-multiline': 2,
136
+    'no-unmodified-loop-condition': 2,
137
+    'no-unneeded-ternary': [2, {
138
+      'defaultAssignment': false
139
+    }],
140
+    'no-unreachable': 2,
141
+    'no-unsafe-finally': 2,
142
+    'no-unused-vars': [2, {
143
+      'vars': 'all',
144
+      'args': 'none'
145
+    }],
146
+    'no-useless-call': 2,
147
+    'no-useless-computed-key': 2,
148
+    'no-useless-constructor': 2,
149
+    'no-useless-escape': 0,
150
+    'no-whitespace-before-property': 2,
151
+    'no-with': 2,
152
+    'one-var': [2, {
153
+      'initialized': 'never'
154
+    }],
155
+    'operator-linebreak': [2, 'after', {
156
+      'overrides': {
157
+        '?': 'before',
158
+        ':': 'before'
159
+      }
160
+    }],
161
+    'padded-blocks': [2, 'never'],
162
+    'quotes': [2, 'single', {
163
+      'avoidEscape': true,
164
+      'allowTemplateLiterals': true
165
+    }],
166
+    'semi': [2, 'never'],
167
+    'semi-spacing': [2, {
168
+      'before': false,
169
+      'after': true
170
+    }],
171
+    'space-before-blocks': [2, 'always'],
172
+    'space-before-function-paren': [2, 'never'],
173
+    'space-in-parens': [2, 'never'],
174
+    'space-infix-ops': 2,
175
+    'space-unary-ops': [2, {
176
+      'words': true,
177
+      'nonwords': false
178
+    }],
179
+    'spaced-comment': [2, 'always', {
180
+      'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
181
+    }],
182
+    'template-curly-spacing': [2, 'never'],
183
+    'use-isnan': 2,
184
+    'valid-typeof': 2,
185
+    'wrap-iife': [2, 'any'],
186
+    'yield-star-spacing': [2, 'both'],
187
+    'yoda': [2, 'never'],
188
+    'prefer-const': 2,
189
+    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
190
+    'object-curly-spacing': [2, 'always', {
191
+      objectsInObjects: false
192
+    }],
193
+    'array-bracket-spacing': [2, 'never']
194
+  }
195
+}
196
+

+ 15
- 0
VUECODE/smart-operate-manage/.gitignore Просмотреть файл

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

+ 10
- 0
VUECODE/smart-operate-manage/.postcssrc.js Просмотреть файл

@@ -0,0 +1,10 @@
1
+// https://github.com/michael-ciniawsky/postcss-load-config
2
+
3
+module.exports = {
4
+  "plugins": {
5
+    "postcss-import": {},
6
+    "postcss-url": {},
7
+    // to edit target browsers: use "browserslist" field in package.json
8
+    "autoprefixer": {}
9
+  }
10
+}

+ 5
- 0
VUECODE/smart-operate-manage/.travis.yml Просмотреть файл

@@ -0,0 +1,5 @@
1
+language: node_js
2
+node_js: stable
3
+script: npm run test
4
+notifications:
5
+  email: false

+ 21
- 0
VUECODE/smart-operate-manage/LICENSE Просмотреть файл

@@ -0,0 +1,21 @@
1
+MIT License
2
+
3
+Copyright (c) 2017-present PanJiaChen
4
+
5
+Permission is hereby granted, free of charge, to any person obtaining a copy
6
+of this software and associated documentation files (the "Software"), to deal
7
+in the Software without restriction, including without limitation the rights
8
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+copies of the Software, and to permit persons to whom the Software is
10
+furnished to do so, subject to the following conditions:
11
+
12
+The above copyright notice and this permission notice shall be included in all
13
+copies or substantial portions of the Software.
14
+
15
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+SOFTWARE.

+ 96
- 0
VUECODE/smart-operate-manage/README-zh.md Просмотреть файл

@@ -0,0 +1,96 @@
1
+# vue-admin-template
2
+
3
+> 这是一个 极简的 vue admin 管理后台 它只包含了 Element UI & axios & iconfont & permission control & lint,这些搭建后台必要的东西。
4
+
5
+[线上地址](http://panjiachen.github.io/vue-admin-template)
6
+
7
+[国内访问](https://panjiachen.gitee.io/vue-admin-template)
8
+
9
+## Extra
10
+
11
+如果你想要根据用户角色来动态生成侧边栏和 router,你可以使用改分支[permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
12
+
13
+本项目基于`webpack4`开发,若还想使用`webpack3`开发,请使用该分支[webpack3](https://github.com/PanJiaChen/vue-admin-template/tree/webpack3)
14
+
15
+如果你想使用基于 vue + typescript 的管理后台, 可以看看这个项目: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (鸣谢: [@Armour](https://github.com/Armour))
16
+
17
+## 相关项目
18
+
19
+[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
20
+
21
+[electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
22
+
23
+[vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
24
+
25
+写了一个系列的教程配套文章,如何从零构建后一个完整的后台项目:
26
+
27
+- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
28
+- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
29
+- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
30
+- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板,专门针对本项目的文章,算作是一篇文档)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
31
+- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
32
+
33
+## Build Setup
34
+
35
+```bash
36
+# Clone project
37
+git clone https://github.com/PanJiaChen/vue-admin-template.git
38
+
39
+# Install dependencies
40
+npm install
41
+
42
+# 建议不要用cnpm  安装有各种诡异的bug 可以通过如下操作解决npm速度慢的问题
43
+npm install --registry=https://registry.npm.taobao.org
44
+
45
+# Serve with hot reload at localhost:9528
46
+npm run dev
47
+
48
+# Build for production with minification
49
+npm run build
50
+
51
+# Build for production and view the bundle analyzer report
52
+npm run build --report
53
+```
54
+
55
+## Demo
56
+
57
+![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
58
+
59
+### Element-Ui 使用 cdn 教程
60
+
61
+首先找到 `index.html` ([根目录下](https://github.com/PanJiaChen/vue-admin-template/blob/element-ui-cdn/index.html))
62
+
63
+引入 Element 的 css 和 js ,并且引入 vue 。因为 Element-Ui 是依赖 vue 的,所以必须在它之前引入 vue 。
64
+
65
+之后找到 [webpack.base.conf.js](https://github.com/PanJiaChen/vue-admin-template/blob/element-ui-cdn/build/webpack.base.conf.js) 加入 `externals` 让 webpack 不打包 vue 和 element
66
+
67
+```
68
+externals: {
69
+  vue: 'Vue',
70
+  'element-ui':'ELEMENT'
71
+}
72
+```
73
+
74
+之后还有一个小细节是如果你用了全局对象方式引入 vue,就不需要 手动 `Vue.use(Vuex)` ,它会自动挂载,具体见 [issue](https://github.com/vuejs/vuex/issues/731)
75
+
76
+最终你可以使用 `npm run build --report` 查看效果
77
+如图:
78
+![demo](https://panjiachen.github.io/images/element-cdn.png)
79
+
80
+**[具体代码](https://github.com/PanJiaChen/vue-admin-template/commit/746aff560932704ae821f82f10b8b2a9681d5177)**
81
+
82
+**[对应分支](https://github.com/PanJiaChen/vue-admin-template/tree/element-ui-cdn)**
83
+
84
+## Browsers support
85
+
86
+Modern browsers and Internet Explorer 10+.
87
+
88
+| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
89
+| --------- | --------- | --------- | --------- |
90
+| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
91
+
92
+## License
93
+
94
+[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
95
+
96
+Copyright (c) 2017-present PanJiaChen

+ 88
- 0
VUECODE/smart-operate-manage/README.md Просмотреть файл

@@ -0,0 +1,88 @@
1
+# vue-admin-template
2
+
3
+> A minimal vue admin template with Element UI & axios & iconfont & permission control & lint
4
+
5
+**Live demo:** http://panjiachen.github.io/vue-admin-template
6
+
7
+[中文文档](https://github.com/PanJiaChen/vue-admin-template/blob/master/README-zh.md)
8
+
9
+## Build Setup
10
+
11
+```bash
12
+# Clone project
13
+git clone https://github.com/PanJiaChen/vue-admin-template.git
14
+
15
+# Install dependencies
16
+npm install
17
+
18
+# Serve with hot reload at localhost:9528
19
+npm run dev
20
+
21
+# Build for production with minification
22
+npm run build
23
+
24
+# Build for production and view the bundle analyzer report
25
+npm run build --report
26
+```
27
+
28
+## Demo
29
+
30
+![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
31
+
32
+## Extra
33
+
34
+If you want router permission && generate menu by user roles , you can use this branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
35
+
36
+This project is based on `webpack4` development. If you want to use `webpack3` development, please use this branch [webpack3](https://github.com/PanJiaChen/vue-admin-template/tree/webpack3)
37
+
38
+For `typescript` version, you can use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
39
+
40
+## Related Project
41
+
42
+[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
43
+
44
+[electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
45
+
46
+[vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
47
+
48
+### Element-Ui using cdn tutorial
49
+
50
+First find `index.html`([root directory](https://github.com/PanJiaChen/vue-admin-template/blob/element-ui-cdn/index.html))
51
+
52
+Import css and js of `Element`, and then import vue. Because `Element` is vue-dependent, vue must be import before it.
53
+
54
+Then find [webpack.base.conf.js](https://github.com/PanJiaChen/vue-admin-template/blob/element-ui-cdn/build/webpack.base.conf.js)
55
+Add `externals` to make webpack not package vue and element.
56
+
57
+```
58
+externals: {
59
+  vue: 'Vue',
60
+  'element-ui':'ELEMENT'
61
+}
62
+```
63
+
64
+Finally there is a small detail to pay attention to that if you import vue in global, you don't need to manually `Vue.use(Vuex)`, it will be automatically mounted, see
65
+[issue](https://github.com/vuejs/vuex/issues/731)
66
+
67
+And you can use `npm run build --report` to see the effect
68
+
69
+Pictured:
70
+![demo](https://panjiachen.github.io/images/element-cdn.png)
71
+
72
+**[Detailed code](https://github.com/PanJiaChen/vue-admin-template/commit/746aff560932704ae821f82f10b8b2a9681d5177)**
73
+
74
+**[Branch](https://github.com/PanJiaChen/vue-admin-template/tree/element-ui-cdn)**
75
+
76
+## Browsers support
77
+
78
+Modern browsers and Internet Explorer 10+.
79
+
80
+| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
81
+| --------- | --------- | --------- | --------- |
82
+| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
83
+
84
+## License
85
+
86
+[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
87
+
88
+Copyright (c) 2017-present PanJiaChen

+ 45
- 0
VUECODE/smart-operate-manage/build/build.js Просмотреть файл

@@ -0,0 +1,45 @@
1
+'use strict'
2
+require('./check-versions')()
3
+
4
+process.env.NODE_ENV = 'production'
5
+
6
+const ora = require('ora')
7
+const rm = require('rimraf')
8
+const path = require('path')
9
+const chalk = require('chalk')
10
+const webpack = require('webpack')
11
+const config = require('../config')
12
+const webpackConfig = require('./webpack.prod.conf')
13
+
14
+const spinner = ora('building for production...')
15
+spinner.start()
16
+
17
+rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18
+  if (err) throw err
19
+  webpack(webpackConfig, (err, stats) => {
20
+    spinner.stop()
21
+    if (err) throw err
22
+    process.stdout.write(
23
+      stats.toString({
24
+        colors: true,
25
+        modules: false,
26
+        children: false,
27
+        chunks: false,
28
+        chunkModules: false
29
+      }) + '\n\n'
30
+    )
31
+
32
+    if (stats.hasErrors()) {
33
+      console.log(chalk.red('  Build failed with errors.\n'))
34
+      process.exit(1)
35
+    }
36
+
37
+    console.log(chalk.cyan('  Build complete.\n'))
38
+    console.log(
39
+      chalk.yellow(
40
+        '  Tip: built files are meant to be served over an HTTP server.\n' +
41
+          "  Opening index.html over file:// won't work.\n"
42
+      )
43
+    )
44
+  })
45
+})

+ 64
- 0
VUECODE/smart-operate-manage/build/check-versions.js Просмотреть файл

@@ -0,0 +1,64 @@
1
+'use strict'
2
+const chalk = require('chalk')
3
+const semver = require('semver')
4
+const packageConfig = require('../package.json')
5
+const shell = require('shelljs')
6
+
7
+function exec(cmd) {
8
+  return require('child_process')
9
+    .execSync(cmd)
10
+    .toString()
11
+    .trim()
12
+}
13
+
14
+const versionRequirements = [
15
+  {
16
+    name: 'node',
17
+    currentVersion: semver.clean(process.version),
18
+    versionRequirement: packageConfig.engines.node
19
+  }
20
+]
21
+
22
+if (shell.which('npm')) {
23
+  versionRequirements.push({
24
+    name: 'npm',
25
+    currentVersion: exec('npm --version'),
26
+    versionRequirement: packageConfig.engines.npm
27
+  })
28
+}
29
+
30
+module.exports = function() {
31
+  const warnings = []
32
+
33
+  for (let i = 0; i < versionRequirements.length; i++) {
34
+    const mod = versionRequirements[i]
35
+
36
+    if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
37
+      warnings.push(
38
+        mod.name +
39
+          ': ' +
40
+          chalk.red(mod.currentVersion) +
41
+          ' should be ' +
42
+          chalk.green(mod.versionRequirement)
43
+      )
44
+    }
45
+  }
46
+
47
+  if (warnings.length) {
48
+    console.log('')
49
+    console.log(
50
+      chalk.yellow(
51
+        'To use this template, you must update following to modules:'
52
+      )
53
+    )
54
+    console.log()
55
+
56
+    for (let i = 0; i < warnings.length; i++) {
57
+      const warning = warnings[i]
58
+      console.log('  ' + warning)
59
+    }
60
+
61
+    console.log()
62
+    process.exit(1)
63
+  }
64
+}

Двоичные данные
VUECODE/smart-operate-manage/build/logo.png Просмотреть файл


+ 108
- 0
VUECODE/smart-operate-manage/build/utils.js Просмотреть файл

@@ -0,0 +1,108 @@
1
+'use strict'
2
+const path = require('path')
3
+const config = require('../config')
4
+const MiniCssExtractPlugin = require('mini-css-extract-plugin')
5
+const packageConfig = require('../package.json')
6
+
7
+exports.assetsPath = function(_path) {
8
+  const assetsSubDirectory =
9
+    process.env.NODE_ENV === 'production'
10
+      ? config.build.assetsSubDirectory
11
+      : config.dev.assetsSubDirectory
12
+
13
+  return path.posix.join(assetsSubDirectory, _path)
14
+}
15
+
16
+exports.cssLoaders = function(options) {
17
+  options = options || {}
18
+
19
+  const cssLoader = {
20
+    loader: 'css-loader',
21
+    options: {
22
+      sourceMap: options.sourceMap
23
+    }
24
+  }
25
+
26
+  const postcssLoader = {
27
+    loader: 'postcss-loader',
28
+    options: {
29
+      sourceMap: options.sourceMap
30
+    }
31
+  }
32
+
33
+  // generate loader string to be used with extract text plugin
34
+  function generateLoaders(loader, loaderOptions) {
35
+    const loaders = []
36
+
37
+    // Extract CSS when that option is specified
38
+    // (which is the case during production build)
39
+    if (options.extract) {
40
+      loaders.push(MiniCssExtractPlugin.loader)
41
+    } else {
42
+      loaders.push('vue-style-loader')
43
+    }
44
+
45
+    loaders.push(cssLoader)
46
+
47
+    if (options.usePostCSS) {
48
+      loaders.push(postcssLoader)
49
+    }
50
+
51
+    if (loader) {
52
+      loaders.push({
53
+        loader: loader + '-loader',
54
+        options: Object.assign({}, loaderOptions, {
55
+          sourceMap: options.sourceMap
56
+        })
57
+      })
58
+    }
59
+
60
+    return loaders
61
+  }
62
+  // https://vue-loader.vuejs.org/en/configurations/extract-css.html
63
+  return {
64
+    css: generateLoaders(),
65
+    postcss: generateLoaders(),
66
+    less: generateLoaders('less'),
67
+    sass: generateLoaders('sass', {
68
+      indentedSyntax: true
69
+    }),
70
+    scss: generateLoaders('sass'),
71
+    stylus: generateLoaders('stylus'),
72
+    styl: generateLoaders('stylus')
73
+  }
74
+}
75
+
76
+// Generate loaders for standalone style files (outside of .vue)
77
+exports.styleLoaders = function(options) {
78
+  const output = []
79
+  const loaders = exports.cssLoaders(options)
80
+
81
+  for (const extension in loaders) {
82
+    const loader = loaders[extension]
83
+    output.push({
84
+      test: new RegExp('\\.' + extension + '$'),
85
+      use: loader
86
+    })
87
+  }
88
+
89
+  return output
90
+}
91
+
92
+exports.createNotifierCallback = () => {
93
+  const notifier = require('node-notifier')
94
+
95
+  return (severity, errors) => {
96
+    if (severity !== 'error') return
97
+
98
+    const error = errors[0]
99
+    const filename = error.file && error.file.split('!').pop()
100
+
101
+    notifier.notify({
102
+      title: packageConfig.name,
103
+      message: severity + ': ' + error.name,
104
+      subtitle: filename || '',
105
+      icon: path.join(__dirname, 'logo.png')
106
+    })
107
+  }
108
+}

+ 5
- 0
VUECODE/smart-operate-manage/build/vue-loader.conf.js Просмотреть файл

@@ -0,0 +1,5 @@
1
+'use strict'
2
+
3
+module.exports = {
4
+  //You can set the vue-loader configuration by yourself.
5
+}

+ 107
- 0
VUECODE/smart-operate-manage/build/webpack.base.conf.js Просмотреть файл

@@ -0,0 +1,107 @@
1
+'use strict'
2
+const path = require('path')
3
+const utils = require('./utils')
4
+const config = require('../config')
5
+const { VueLoaderPlugin } = require('vue-loader')
6
+const vueLoaderConfig = require('./vue-loader.conf')
7
+
8
+function resolve(dir) {
9
+  return path.join(__dirname, '..', dir)
10
+}
11
+
12
+const createLintingRule = () => ({
13
+  test: /\.(js|vue)$/,
14
+  loader: 'eslint-loader',
15
+  enforce: 'pre',
16
+  include: [resolve('src'), resolve('test')],
17
+  options: {
18
+    formatter: require('eslint-friendly-formatter'),
19
+    emitWarning: !config.dev.showEslintErrorsInOverlay
20
+  }
21
+})
22
+
23
+module.exports = {
24
+  context: path.resolve(__dirname, '../'),
25
+  entry: {
26
+    app: './src/main.js'
27
+  },
28
+  output: {
29
+    path: config.build.assetsRoot,
30
+    filename: '[name].js',
31
+    publicPath:
32
+      process.env.NODE_ENV === 'production'
33
+        ? config.build.assetsPublicPath
34
+        : config.dev.assetsPublicPath
35
+  },
36
+  resolve: {
37
+    extensions: ['.js', '.vue', '.json'],
38
+    alias: {
39
+      '@': resolve('src')
40
+    }
41
+  },
42
+  module: {
43
+    rules: [
44
+      ...(config.dev.useEslint ? [createLintingRule()] : []),
45
+      {
46
+        test: /\.vue$/,
47
+        loader: 'vue-loader',
48
+        options: vueLoaderConfig
49
+      },
50
+      {
51
+        test: /\.js$/,
52
+        loader: 'babel-loader',
53
+        include: [
54
+          resolve('src'),
55
+          resolve('test'),
56
+          resolve('node_modules/webpack-dev-server/client')
57
+        ]
58
+      },
59
+      {
60
+        test: /\.svg$/,
61
+        loader: 'svg-sprite-loader',
62
+        include: [resolve('src/icons')],
63
+        options: {
64
+          symbolId: 'icon-[name]'
65
+        }
66
+      },
67
+      {
68
+        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
69
+        loader: 'url-loader',
70
+        exclude: [resolve('src/icons')],
71
+        options: {
72
+          limit: 10000,
73
+          name: utils.assetsPath('img/[name].[hash:7].[ext]')
74
+        }
75
+      },
76
+      {
77
+        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
78
+        loader: 'url-loader',
79
+        options: {
80
+          limit: 10000,
81
+          name: utils.assetsPath('media/[name].[hash:7].[ext]')
82
+        }
83
+      },
84
+      {
85
+        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
86
+        loader: 'url-loader',
87
+        options: {
88
+          limit: 10000,
89
+          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
90
+        }
91
+      }
92
+    ]
93
+  },
94
+  plugins: [new VueLoaderPlugin()],
95
+  node: {
96
+    // prevent webpack from injecting useless setImmediate polyfill because Vue
97
+    // source contains it (although only uses it if it's native).
98
+    setImmediate: false,
99
+    // prevent webpack from injecting mocks to Node native modules
100
+    // that does not make sense for the client
101
+    dgram: 'empty',
102
+    fs: 'empty',
103
+    net: 'empty',
104
+    tls: 'empty',
105
+    child_process: 'empty'
106
+  }
107
+}

+ 95
- 0
VUECODE/smart-operate-manage/build/webpack.dev.conf.js Просмотреть файл

@@ -0,0 +1,95 @@
1
+'use strict'
2
+const path = require('path')
3
+const utils = require('./utils')
4
+const webpack = require('webpack')
5
+const config = require('../config')
6
+const merge = require('webpack-merge')
7
+const baseWebpackConfig = require('./webpack.base.conf')
8
+const HtmlWebpackPlugin = require('html-webpack-plugin')
9
+const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
10
+const portfinder = require('portfinder')
11
+
12
+function resolve(dir) {
13
+  return path.join(__dirname, '..', dir)
14
+}
15
+
16
+const HOST = process.env.HOST
17
+const PORT = process.env.PORT && Number(process.env.PORT)
18
+
19
+const devWebpackConfig = merge(baseWebpackConfig, {
20
+  mode: 'development',
21
+  module: {
22
+    rules: utils.styleLoaders({
23
+      sourceMap: config.dev.cssSourceMap,
24
+      usePostCSS: true
25
+    })
26
+  },
27
+  // cheap-module-eval-source-map is faster for development
28
+  devtool: config.dev.devtool,
29
+
30
+  // these devServer options should be customized in /config/index.js
31
+  devServer: {
32
+    clientLogLevel: 'warning',
33
+    historyApiFallback: true,
34
+    hot: true,
35
+    compress: true,
36
+    host: HOST || config.dev.host,
37
+    port: PORT || config.dev.port,
38
+    open: config.dev.autoOpenBrowser,
39
+    overlay: config.dev.errorOverlay
40
+      ? { warnings: false, errors: true }
41
+      : false,
42
+    publicPath: config.dev.assetsPublicPath,
43
+    proxy: config.dev.proxyTable,
44
+    quiet: true, // necessary for FriendlyErrorsPlugin
45
+    watchOptions: {
46
+      poll: config.dev.poll
47
+    }
48
+  },
49
+  plugins: [
50
+    new webpack.DefinePlugin({
51
+      'process.env': require('../config/dev.env')
52
+    }),
53
+    new webpack.HotModuleReplacementPlugin(),
54
+    // https://github.com/ampedandwired/html-webpack-plugin
55
+    new HtmlWebpackPlugin({
56
+      filename: 'index.html',
57
+      template: 'index.html',
58
+      inject: true,
59
+      favicon: resolve('favicon.ico'),
60
+      title: 'vue-admin-template'
61
+    })
62
+  ]
63
+})
64
+
65
+module.exports = new Promise((resolve, reject) => {
66
+  portfinder.basePort = process.env.PORT || config.dev.port
67
+  portfinder.getPort((err, port) => {
68
+    if (err) {
69
+      reject(err)
70
+    } else {
71
+      // publish the new Port, necessary for e2e tests
72
+      process.env.PORT = port
73
+      // add port to devServer config
74
+      devWebpackConfig.devServer.port = port
75
+
76
+      // Add FriendlyErrorsPlugin
77
+      devWebpackConfig.plugins.push(
78
+        new FriendlyErrorsPlugin({
79
+          compilationSuccessInfo: {
80
+            messages: [
81
+              `Your application is running here: http://${
82
+                devWebpackConfig.devServer.host
83
+              }:${port}`
84
+            ]
85
+          },
86
+          onErrors: config.dev.notifyOnErrors
87
+            ? utils.createNotifierCallback()
88
+            : undefined
89
+        })
90
+      )
91
+
92
+      resolve(devWebpackConfig)
93
+    }
94
+  })
95
+})

+ 178
- 0
VUECODE/smart-operate-manage/build/webpack.prod.conf.js Просмотреть файл

@@ -0,0 +1,178 @@
1
+'use strict'
2
+const path = require('path')
3
+const utils = require('./utils')
4
+const webpack = require('webpack')
5
+const config = require('../config')
6
+const merge = require('webpack-merge')
7
+const baseWebpackConfig = require('./webpack.base.conf')
8
+const CopyWebpackPlugin = require('copy-webpack-plugin')
9
+const HtmlWebpackPlugin = require('html-webpack-plugin')
10
+const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
11
+const MiniCssExtractPlugin = require('mini-css-extract-plugin')
12
+const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
13
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
14
+
15
+function resolve(dir) {
16
+  return path.join(__dirname, '..', dir)
17
+}
18
+
19
+const env = require('../config/prod.env')
20
+
21
+// For NamedChunksPlugin
22
+const seen = new Set()
23
+const nameLength = 4
24
+
25
+const webpackConfig = merge(baseWebpackConfig, {
26
+  mode: 'production',
27
+  module: {
28
+    rules: utils.styleLoaders({
29
+      sourceMap: config.build.productionSourceMap,
30
+      extract: true,
31
+      usePostCSS: true
32
+    })
33
+  },
34
+  devtool: config.build.productionSourceMap ? config.build.devtool : false,
35
+  output: {
36
+    path: config.build.assetsRoot,
37
+    filename: utils.assetsPath('js/[name].[chunkhash:8].js'),
38
+    chunkFilename: utils.assetsPath('js/[name].[chunkhash:8].js')
39
+  },
40
+  plugins: [
41
+    // http://vuejs.github.io/vue-loader/en/workflow/production.html
42
+    new webpack.DefinePlugin({
43
+      'process.env': env
44
+    }),
45
+    // extract css into its own file
46
+    new MiniCssExtractPlugin({
47
+      filename: utils.assetsPath('css/[name].[contenthash:8].css'),
48
+      chunkFilename: utils.assetsPath('css/[name].[contenthash:8].css')
49
+    }),
50
+    // generate dist index.html with correct asset hash for caching.
51
+    // you can customize output by editing /index.html
52
+    // see https://github.com/ampedandwired/html-webpack-plugin
53
+    new HtmlWebpackPlugin({
54
+      filename: config.build.index,
55
+      template: 'index.html',
56
+      inject: true,
57
+      favicon: resolve('favicon.ico'),
58
+      title: 'vue-admin-template',
59
+      minify: {
60
+        removeComments: true,
61
+        collapseWhitespace: true,
62
+        removeAttributeQuotes: true
63
+        // more options:
64
+        // https://github.com/kangax/html-minifier#options-quick-reference
65
+      }
66
+      // default sort mode uses toposort which cannot handle cyclic deps
67
+      // in certain cases, and in webpack 4, chunk order in HTML doesn't
68
+      // matter anyway
69
+    }),
70
+    new ScriptExtHtmlWebpackPlugin({
71
+      //`runtime` must same as runtimeChunk name. default is `runtime`
72
+      inline: /runtime\..*\.js$/
73
+    }),
74
+    // keep chunk.id stable when chunk has no name
75
+    new webpack.NamedChunksPlugin(chunk => {
76
+      if (chunk.name) {
77
+        return chunk.name
78
+      }
79
+      const modules = Array.from(chunk.modulesIterable)
80
+      if (modules.length > 1) {
81
+        const hash = require('hash-sum')
82
+        const joinedHash = hash(modules.map(m => m.id).join('_'))
83
+        let len = nameLength
84
+        while (seen.has(joinedHash.substr(0, len))) len++
85
+        seen.add(joinedHash.substr(0, len))
86
+        return `chunk-${joinedHash.substr(0, len)}`
87
+      } else {
88
+        return modules[0].id
89
+      }
90
+    }),
91
+    // keep module.id stable when vender modules does not change
92
+    new webpack.HashedModuleIdsPlugin(),
93
+    // copy custom static assets
94
+    new CopyWebpackPlugin([
95
+      {
96
+        from: path.resolve(__dirname, '../static'),
97
+        to: config.build.assetsSubDirectory,
98
+        ignore: ['.*']
99
+      }
100
+    ])
101
+  ],
102
+  optimization: {
103
+    splitChunks: {
104
+      chunks: 'all',
105
+      cacheGroups: {
106
+        libs: {
107
+          name: 'chunk-libs',
108
+          test: /[\\/]node_modules[\\/]/,
109
+          priority: 10,
110
+          chunks: 'initial' // 只打包初始时依赖的第三方
111
+        },
112
+        elementUI: {
113
+          name: 'chunk-elementUI', // 单独将 elementUI 拆包
114
+          priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
115
+          test: /[\\/]node_modules[\\/]element-ui[\\/]/
116
+        }
117
+      }
118
+    },
119
+    runtimeChunk: 'single',
120
+    minimizer: [
121
+      new UglifyJsPlugin({
122
+        uglifyOptions: {
123
+          mangle: {
124
+            safari10: true
125
+          }
126
+        },
127
+        sourceMap: config.build.productionSourceMap,
128
+        cache: true,
129
+        parallel: true
130
+      }),
131
+      // Compress extracted CSS. We are using this plugin so that possible
132
+      // duplicated CSS from different components can be deduped.
133
+      new OptimizeCSSAssetsPlugin()
134
+    ]
135
+  }
136
+})
137
+
138
+if (config.build.productionGzip) {
139
+  const CompressionWebpackPlugin = require('compression-webpack-plugin')
140
+
141
+  webpackConfig.plugins.push(
142
+    new CompressionWebpackPlugin({
143
+      asset: '[path].gz[query]',
144
+      algorithm: 'gzip',
145
+      test: new RegExp(
146
+        '\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
147
+      ),
148
+      threshold: 10240,
149
+      minRatio: 0.8
150
+    })
151
+  )
152
+}
153
+
154
+if (config.build.generateAnalyzerReport || config.build.bundleAnalyzerReport) {
155
+  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
156
+    .BundleAnalyzerPlugin
157
+
158
+  if (config.build.bundleAnalyzerReport) {
159
+    webpackConfig.plugins.push(
160
+      new BundleAnalyzerPlugin({
161
+        analyzerPort: 8080,
162
+        generateStatsFile: false
163
+      })
164
+    )
165
+  }
166
+
167
+  if (config.build.generateAnalyzerReport) {
168
+    webpackConfig.plugins.push(
169
+      new BundleAnalyzerPlugin({
170
+        analyzerMode: 'static',
171
+        reportFilename: 'bundle-report.html',
172
+        openAnalyzer: false
173
+      })
174
+    )
175
+  }
176
+}
177
+
178
+module.exports = webpackConfig

+ 8
- 0
VUECODE/smart-operate-manage/config/dev.env.js Просмотреть файл

@@ -0,0 +1,8 @@
1
+'use strict'
2
+const merge = require('webpack-merge')
3
+const prodEnv = require('./prod.env')
4
+
5
+module.exports = merge(prodEnv, {
6
+  NODE_ENV: '"development"',
7
+  BASE_API: '"http://localhost:8085/operate-api"',
8
+})

+ 87
- 0
VUECODE/smart-operate-manage/config/index.js Просмотреть файл

@@ -0,0 +1,87 @@
1
+'use strict'
2
+// Template version: 1.2.6
3
+// see http://vuejs-templates.github.io/webpack for documentation.
4
+
5
+const path = require('path')
6
+
7
+module.exports = {
8
+  dev: {
9
+    // Paths
10
+    assetsSubDirectory: 'static',
11
+    assetsPublicPath: '/',
12
+    proxyTable: {
13
+    },
14
+
15
+    // Various Dev Server settings
16
+    host: 'localhost', // can be overwritten by process.env.HOST
17
+    port: 9528, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
18
+    autoOpenBrowser: true,
19
+    errorOverlay: true,
20
+    notifyOnErrors: false,
21
+    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22
+
23
+    // Use Eslint Loader?
24
+    // If true, your code will be linted during bundling and
25
+    // linting errors and warnings will be shown in the console.
26
+    useEslint: true,
27
+    // If true, eslint errors and warnings will also be shown in the error overlay
28
+    // in the browser.
29
+    showEslintErrorsInOverlay: false,
30
+
31
+    /**
32
+     * Source Maps
33
+     */
34
+
35
+    // https://webpack.js.org/configuration/devtool/#development
36
+    devtool: 'cheap-source-map',
37
+
38
+    // CSS Sourcemaps off by default because relative paths are "buggy"
39
+    // with this option, according to the CSS-Loader README
40
+    // (https://github.com/webpack/css-loader#sourcemaps)
41
+    // In our experience, they generally work as expected,
42
+    // just be aware of this issue when enabling this option.
43
+    cssSourceMap: false
44
+  },
45
+
46
+  build: {
47
+    // Template for index.html
48
+    index: path.resolve(__dirname, '../dist/index.html'),
49
+
50
+    // Paths
51
+    assetsRoot: path.resolve(__dirname, '../dist'),
52
+    assetsSubDirectory: 'static',
53
+
54
+    /**
55
+     * You can set by youself according to actual condition
56
+     * You will need to set this if you plan to deploy your site under a sub path,
57
+     * for example GitHub pages. If you plan to deploy your site to https://foo.github.io/bar/,
58
+     * then assetsPublicPath should be set to "/bar/".
59
+     * In most cases please use '/' !!!
60
+     */
61
+    assetsPublicPath: '/',
62
+
63
+    /**
64
+     * Source Maps
65
+     */
66
+
67
+    productionSourceMap: false,
68
+    // https://webpack.js.org/configuration/devtool/#production
69
+    devtool: 'source-map',
70
+
71
+    // Gzip off by default as many popular static hosts such as
72
+    // Surge or Netlify already gzip all static assets for you.
73
+    // Before setting to `true`, make sure to:
74
+    // npm install --save-dev compression-webpack-plugin
75
+    productionGzip: false,
76
+    productionGzipExtensions: ['js', 'css'],
77
+
78
+    // Run the build command with an extra argument to
79
+    // View the bundle analyzer report after build finishes:
80
+    // `npm run build --report`
81
+    // Set to `true` or `false` to always turn it on or off
82
+    bundleAnalyzerReport: process.env.npm_config_report || false,
83
+
84
+    // `npm run build:prod --generate_report`
85
+    generateAnalyzerReport: process.env.npm_config_generate_report || false
86
+  }
87
+}

+ 5
- 0
VUECODE/smart-operate-manage/config/prod.env.js Просмотреть файл

@@ -0,0 +1,5 @@
1
+'use strict'
2
+module.exports = {
3
+  NODE_ENV: '"production"',
4
+  BASE_API: '"https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin"',
5
+}

Двоичные данные
VUECODE/smart-operate-manage/favicon.ico Просмотреть файл


+ 12
- 0
VUECODE/smart-operate-manage/index.html Просмотреть файл

@@ -0,0 +1,12 @@
1
+<!DOCTYPE html>
2
+<html>
3
+  <head>
4
+    <meta charset="utf-8">
5
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
6
+    <title>vue-admin-template</title>
7
+  </head>
8
+  <body>
9
+    <div id="app"></div>
10
+    <!-- built files will be auto injected -->
11
+  </body>
12
+</html>

+ 88
- 0
VUECODE/smart-operate-manage/package.json Просмотреть файл

@@ -0,0 +1,88 @@
1
+{
2
+  "name": "vue-admin-template",
3
+  "version": "3.8.0",
4
+  "license": "MIT",
5
+  "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
6
+  "author": "Pan <panfree23@gmail.com>",
7
+  "scripts": {
8
+    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9
+    "start": "npm run dev",
10
+    "build": "node build/build.js",
11
+    "build:report": "npm_config_report=true npm run build",
12
+    "lint": "eslint --ext .js,.vue src",
13
+    "test": "npm run lint",
14
+    "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
15
+  },
16
+  "dependencies": {
17
+    "axios": "0.18.0",
18
+    "element-ui": "2.4.6",
19
+    "file-saver": "^2.0.0-rc.4",
20
+    "js-cookie": "2.2.0",
21
+    "normalize.css": "7.0.0",
22
+    "nprogress": "0.2.0",
23
+    "vue": "2.5.17",
24
+    "vue-router": "3.0.1",
25
+    "vuex": "3.0.1",
26
+    "xlsx": "^0.14.0"
27
+  },
28
+  "devDependencies": {
29
+    "autoprefixer": "8.5.0",
30
+    "babel-core": "6.26.0",
31
+    "babel-eslint": "8.2.6",
32
+    "babel-helper-vue-jsx-merge-props": "2.0.3",
33
+    "babel-loader": "7.1.5",
34
+    "babel-plugin-syntax-jsx": "6.18.0",
35
+    "babel-plugin-transform-runtime": "6.23.0",
36
+    "babel-plugin-transform-vue-jsx": "3.7.0",
37
+    "babel-preset-env": "1.7.0",
38
+    "babel-preset-stage-2": "6.24.1",
39
+    "chalk": "2.4.1",
40
+    "copy-webpack-plugin": "4.5.2",
41
+    "css-loader": "1.0.0",
42
+    "eslint": "4.19.1",
43
+    "eslint-friendly-formatter": "4.0.1",
44
+    "eslint-loader": "2.0.0",
45
+    "eslint-plugin-vue": "4.7.1",
46
+    "eventsource-polyfill": "0.9.6",
47
+    "file-loader": "1.1.11",
48
+    "friendly-errors-webpack-plugin": "1.7.0",
49
+    "html-webpack-plugin": "4.0.0-alpha",
50
+    "mini-css-extract-plugin": "0.4.1",
51
+    "node-notifier": "5.2.1",
52
+    "node-sass": "^4.7.2",
53
+    "optimize-css-assets-webpack-plugin": "5.0.0",
54
+    "ora": "3.0.0",
55
+    "path-to-regexp": "2.4.0",
56
+    "portfinder": "1.0.16",
57
+    "postcss-import": "12.0.0",
58
+    "postcss-loader": "2.1.6",
59
+    "postcss-url": "7.3.2",
60
+    "rimraf": "2.6.2",
61
+    "sass-loader": "7.0.3",
62
+    "script-ext-html-webpack-plugin": "2.0.1",
63
+    "script-loader": "^0.7.2",
64
+    "semver": "5.5.0",
65
+    "shelljs": "0.8.2",
66
+    "svg-sprite-loader": "3.8.0",
67
+    "svgo": "1.0.5",
68
+    "uglifyjs-webpack-plugin": "1.2.7",
69
+    "url-loader": "1.0.1",
70
+    "vue-loader": "15.3.0",
71
+    "vue-style-loader": "4.1.2",
72
+    "vue-template-compiler": "2.5.17",
73
+    "webpack": "4.16.5",
74
+    "webpack-bundle-analyzer": "2.13.1",
75
+    "webpack-cli": "3.1.0",
76
+    "webpack-dev-server": "3.1.5",
77
+    "webpack-merge": "4.1.4"
78
+  },
79
+  "engines": {
80
+    "node": ">= 6.0.0",
81
+    "npm": ">= 3.0.0"
82
+  },
83
+  "browserslist": [
84
+    "> 1%",
85
+    "last 2 versions",
86
+    "not ie <= 8"
87
+  ]
88
+}

+ 11
- 0
VUECODE/smart-operate-manage/src/App.vue Просмотреть файл

@@ -0,0 +1,11 @@
1
+<template>
2
+  <div id="app">
3
+    <router-view/>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+export default {
9
+  name: 'App'
10
+}
11
+</script>

+ 11
- 0
VUECODE/smart-operate-manage/src/api/banner.js Просмотреть файл

@@ -0,0 +1,11 @@
1
+import request from '@/utils/request'
2
+
3
+export function getBanner(...banner) {
4
+  return request({
5
+    url: '/banner/list',
6
+    method: 'get',
7
+    params: {
8
+      ...banner
9
+    }
10
+  });
11
+}

+ 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
+}

+ 38
- 0
VUECODE/smart-operate-manage/src/api/login.js Просмотреть файл

@@ -0,0 +1,38 @@
1
+import request from '@/utils/request'
2
+
3
+export function login(username, password) {
4
+  const config = {
5
+    url: '/user/login',
6
+    method: 'post',
7
+    data: {
8
+      'loginName': username,
9
+      'code': password
10
+    }
11
+  }
12
+
13
+  return request(config)
14
+}
15
+
16
+export function getInfo(token) {
17
+  return request({
18
+    url: '/user/info',
19
+    method: 'get'
20
+    // params: { token }
21
+  })
22
+}
23
+
24
+export function logout() {
25
+  return request({
26
+    url: '/user/logout',
27
+    method: 'post'
28
+  })
29
+}
30
+
31
+// 发送验证码
32
+export function sendCode(phone) {
33
+  return request({
34
+    url: '/code/sendCode',
35
+    method: 'post',
36
+    params: { phone }
37
+  })
38
+}

+ 9
- 0
VUECODE/smart-operate-manage/src/api/table.js Просмотреть файл

@@ -0,0 +1,9 @@
1
+import request from '@/utils/request'
2
+
3
+export function getList(params) {
4
+  return request({
5
+    url: '/banner/list',
6
+    method: 'get',
7
+    params
8
+  })
9
+}

Двоичные данные
VUECODE/smart-operate-manage/src/assets/404_images/404.png Просмотреть файл


Двоичные данные
VUECODE/smart-operate-manage/src/assets/404_images/404_cloud.png Просмотреть файл


+ 61
- 0
VUECODE/smart-operate-manage/src/components/Breadcrumb/index.vue Просмотреть файл

@@ -0,0 +1,61 @@
1
+<template>
2
+  <el-breadcrumb class="app-breadcrumb" separator="/">
3
+    <transition-group name="breadcrumb">
4
+      <el-breadcrumb-item v-for="(item,index) in levelList" v-if="item.meta.title" :key="item.path">
5
+        <span v-if="item.redirect==='noredirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
6
+        <router-link v-else :to="item.redirect||item.path">{{ item.meta.title }}</router-link>
7
+      </el-breadcrumb-item>
8
+    </transition-group>
9
+  </el-breadcrumb>
10
+</template>
11
+
12
+<script>
13
+import pathToRegexp from 'path-to-regexp'
14
+
15
+export default {
16
+  data() {
17
+    return {
18
+      levelList: null
19
+    }
20
+  },
21
+  watch: {
22
+    $route() {
23
+      this.getBreadcrumb()
24
+    }
25
+  },
26
+  created() {
27
+    this.getBreadcrumb()
28
+  },
29
+  methods: {
30
+    getBreadcrumb() {
31
+      const { params } = this.$route
32
+      let matched = this.$route.matched.filter(item => {
33
+        if (item.name) {
34
+          // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
35
+          var toPath = pathToRegexp.compile(item.path)
36
+          item.path = toPath(params)
37
+          return true
38
+        }
39
+      })
40
+      const first = matched[0]
41
+      if (first && first.name !== 'dashboard') {
42
+        matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched)
43
+      }
44
+      this.levelList = matched
45
+    }
46
+  }
47
+}
48
+</script>
49
+
50
+<style rel="stylesheet/scss" lang="scss" scoped>
51
+  .app-breadcrumb.el-breadcrumb {
52
+    display: inline-block;
53
+    font-size: 14px;
54
+    line-height: 50px;
55
+    margin-left: 10px;
56
+    .no-redirect {
57
+      color: #97a8be;
58
+      cursor: text;
59
+    }
60
+  }
61
+</style>

+ 58
- 0
VUECODE/smart-operate-manage/src/components/Hamburger/index.vue Просмотреть файл

@@ -0,0 +1,58 @@
1
+<template>
2
+  <div>
3
+    <svg
4
+      :class="{'is-active':isActive}"
5
+      t="1492500959545"
6
+      class="hamburger"
7
+      style=""
8
+      viewBox="0 0 1024 1024"
9
+      version="1.1"
10
+      xmlns="http://www.w3.org/2000/svg"
11
+      p-id="1691"
12
+      xmlns:xlink="http://www.w3.org/1999/xlink"
13
+      width="64"
14
+      height="64"
15
+      @click="toggleClick">
16
+      <path
17
+        d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
18
+        p-id="1692" />
19
+      <path
20
+        d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
21
+        p-id="1693" />
22
+      <path
23
+        d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
24
+        p-id="1694" />
25
+    </svg>
26
+  </div>
27
+</template>
28
+
29
+<script>
30
+export default {
31
+  name: 'Hamburger',
32
+  props: {
33
+    isActive: {
34
+      type: Boolean,
35
+      default: false
36
+    },
37
+    toggleClick: {
38
+      type: Function,
39
+      default: null
40
+    }
41
+  }
42
+}
43
+</script>
44
+
45
+<style scoped>
46
+.hamburger {
47
+	display: inline-block;
48
+	cursor: pointer;
49
+	width: 20px;
50
+	height: 20px;
51
+	transform: rotate(90deg);
52
+	transition: .38s;
53
+	transform-origin: 50% 50%;
54
+}
55
+.hamburger.is-active {
56
+	transform: rotate(0deg);
57
+}
58
+</style>

+ 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>

+ 43
- 0
VUECODE/smart-operate-manage/src/components/SvgIcon/index.vue Просмотреть файл

@@ -0,0 +1,43 @@
1
+<template>
2
+  <svg :class="svgClass" aria-hidden="true">
3
+    <use :xlink:href="iconName"/>
4
+  </svg>
5
+</template>
6
+
7
+<script>
8
+export default {
9
+  name: 'SvgIcon',
10
+  props: {
11
+    iconClass: {
12
+      type: String,
13
+      required: true
14
+    },
15
+    className: {
16
+      type: String,
17
+      default: ''
18
+    }
19
+  },
20
+  computed: {
21
+    iconName() {
22
+      return `#icon-${this.iconClass}`
23
+    },
24
+    svgClass() {
25
+      if (this.className) {
26
+        return 'svg-icon ' + this.className
27
+      } else {
28
+        return 'svg-icon'
29
+      }
30
+    }
31
+  }
32
+}
33
+</script>
34
+
35
+<style scoped>
36
+.svg-icon {
37
+  width: 1em;
38
+  height: 1em;
39
+  vertical-align: -0.15em;
40
+  fill: currentColor;
41
+  overflow: hidden;
42
+}
43
+</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
+

+ 9
- 0
VUECODE/smart-operate-manage/src/icons/index.js Просмотреть файл

@@ -0,0 +1,9 @@
1
+import Vue from 'vue'
2
+import SvgIcon from '@/components/SvgIcon' // svg组件
3
+
4
+// register globally
5
+Vue.component('svg-icon', SvgIcon)
6
+
7
+const requireAll = requireContext => requireContext.keys().map(requireContext)
8
+const req = require.context('./svg', false, /\.svg$/)
9
+requireAll(req)

+ 1
- 0
VUECODE/smart-operate-manage/src/icons/svg/example.svg Просмотреть файл

@@ -0,0 +1 @@
1
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg>

+ 1
- 0
VUECODE/smart-operate-manage/src/icons/svg/eye.svg Просмотреть файл

@@ -0,0 +1 @@
1
+<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>

+ 1
- 0
VUECODE/smart-operate-manage/src/icons/svg/form.svg Просмотреть файл

@@ -0,0 +1 @@
1
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.068 23.784c-1.02 0-1.877-.32-2.572-.96a8.588 8.588 0 0 1-1.738-2.237 11.524 11.524 0 0 1-1.042-2.621c-.232-.895-.348-1.641-.348-2.238V0h.278c.834 0 1.622.085 2.363.256.742.17 1.645.575 2.711 1.214 1.066.64 2.363 1.535 3.892 2.686 1.53 1.15 3.453 2.664 5.77 4.54 2.502 2.045 4.494 3.771 5.977 5.178 1.483 1.406 2.618 2.6 3.406 3.58.787.98 1.274 1.812 1.46 2.494.185.682.277 1.278.277 1.79v2.046H84.068zM127.3 84.01c.278.682.464 1.535.556 2.558.093 1.023-.37 2.003-1.39 2.94-.463.427-.88.832-1.25 1.215-.372.384-.696.704-.974.96a6.69 6.69 0 0 1-.973.767l-11.816-10.741a44.331 44.331 0 0 0 1.877-1.535 31.028 31.028 0 0 1 1.737-1.406c1.112-.938 2.317-1.343 3.615-1.215 1.297.128 2.363.405 3.197.83.927.427 1.923 1.173 2.989 2.239 1.065 1.065 1.876 2.195 2.432 3.388zM78.23 95.902c2.038 0 3.752-.511 5.143-1.534l-26.969 25.83H18.037c-1.761 0-3.684-.47-5.77-1.407a24.549 24.549 0 0 1-5.838-3.709 21.373 21.373 0 0 1-4.518-5.306c-1.204-2.003-1.807-4.07-1.807-6.202V16.495c0-1.79.44-3.665 1.32-5.626A18.41 18.41 0 0 1 5.04 5.562a21.798 21.798 0 0 1 5.213-3.964C12.198.533 14.237 0 16.37 0h53.24v15.984c0 1.62.278 3.367.834 5.242a16.704 16.704 0 0 0 2.572 5.179c1.159 1.577 2.665 2.898 4.518 3.964 1.853 1.066 4.078 1.598 6.673 1.598h20.295v42.325L85.458 92.45c1.02-1.364 1.529-2.856 1.529-4.476 0-2.216-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1c-2.409 0-4.448.789-6.116 2.366-1.668 1.577-2.502 3.474-2.502 5.69 0 2.217.834 4.092 2.502 5.626 1.668 1.535 3.707 2.302 6.117 2.302h52.13zM26.1 47.951c-2.41 0-4.449.789-6.117 2.366-1.668 1.577-2.502 3.473-2.502 5.69 0 2.216.834 4.092 2.502 5.626 1.668 1.534 3.707 2.302 6.117 2.302h52.13c2.409 0 4.47-.768 6.185-2.302 1.715-1.534 2.572-3.41 2.572-5.626 0-2.217-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1zm52.407 64.063l1.807-1.663 3.476-3.196a479.75 479.75 0 0 0 4.587-4.284 500.757 500.757 0 0 1 5.004-4.667c3.985-3.666 8.48-7.758 13.485-12.276l11.677 10.741-13.485 12.404-5.004 4.603-4.587 4.22a179.46 179.46 0 0 0-3.267 3.068c-.88.853-1.367 1.322-1.46 1.407-.463.341-.973.703-1.529 1.087-.556.383-1.112.703-1.668.959-.556.256-1.413.575-2.572.959a83.5 83.5 0 0 1-3.545 1.087 72.2 72.2 0 0 1-3.475.895c-1.112.256-1.946.426-2.502.511-1.112.17-1.854.043-2.224-.383-.371-.426-.464-1.151-.278-2.174.092-.511.278-1.279.556-2.302.278-1.023.602-2.067.973-3.132l1.042-3.005c.325-.938.58-1.577.765-1.918a10.157 10.157 0 0 1 2.224-2.941z"/></svg>

+ 1
- 0
VUECODE/smart-operate-manage/src/icons/svg/link.svg Просмотреть файл

@@ -0,0 +1 @@
1
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><g><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></g></svg>

+ 1
- 0
VUECODE/smart-operate-manage/src/icons/svg/nested.svg Просмотреть файл

@@ -0,0 +1 @@
1
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg>

+ 1
- 0
VUECODE/smart-operate-manage/src/icons/svg/password.svg Просмотреть файл

@@ -0,0 +1 @@
1
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>

+ 1
- 0
VUECODE/smart-operate-manage/src/icons/svg/table.svg Просмотреть файл

@@ -0,0 +1 @@
1
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><g><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></g></svg>

+ 1
- 0
VUECODE/smart-operate-manage/src/icons/svg/tree.svg Просмотреть файл

@@ -0,0 +1 @@
1
+<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg>

+ 1
- 0
VUECODE/smart-operate-manage/src/icons/svg/user.svg Просмотреть файл

@@ -0,0 +1 @@
1
+<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg>

+ 22
- 0
VUECODE/smart-operate-manage/src/icons/svgo.yml Просмотреть файл

@@ -0,0 +1,22 @@
1
+# replace default config
2
+
3
+# multipass: true
4
+# full: true
5
+
6
+plugins:
7
+
8
+  # - name
9
+  #
10
+  # or:
11
+  # - name: false
12
+  # - name: true
13
+  #
14
+  # or:
15
+  # - name:
16
+  #     param1: 1
17
+  #     param2: 2
18
+
19
+- removeAttrs:
20
+    attrs:
21
+      - 'fill'
22
+      - 'fill-rule'

+ 27
- 0
VUECODE/smart-operate-manage/src/main.js Просмотреть файл

@@ -0,0 +1,27 @@
1
+import Vue from 'vue'
2
+
3
+import 'normalize.css/normalize.css' // A modern alternative to CSS resets
4
+
5
+import ElementUI from 'element-ui'
6
+import 'element-ui/lib/theme-chalk/index.css'
7
+import locale from 'element-ui/lib/locale/lang/en' // lang i18n
8
+
9
+import '@/styles/index.scss' // global css
10
+
11
+import App from './App'
12
+import router from './router'
13
+import store from './store'
14
+
15
+import '@/icons' // icon
16
+import '@/permission' // permission control
17
+
18
+Vue.use(ElementUI, { locale })
19
+
20
+Vue.config.productionTip = false
21
+
22
+new Vue({
23
+  el: '#app',
24
+  router,
25
+  store,
26
+  render: h => h(App)
27
+})

+ 42
- 0
VUECODE/smart-operate-manage/src/permission.js Просмотреть файл

@@ -0,0 +1,42 @@
1
+import router from './router'
2
+import store from './store'
3
+import NProgress from 'nprogress' // Progress 进度条
4
+import 'nprogress/nprogress.css'// Progress 进度条样式
5
+import { Message } from 'element-ui'
6
+import { getToken } from '@/utils/auth' // 验权
7
+
8
+const whiteList = ['/login'] // 不重定向白名单
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
+  // }
37
+  next()
38
+})
39
+
40
+router.afterEach(() => {
41
+  NProgress.done() // 结束Progress
42
+})

+ 79
- 0
VUECODE/smart-operate-manage/src/router/index.js Просмотреть файл

@@ -0,0 +1,79 @@
1
+import Vue from 'vue'
2
+import Router from 'vue-router'
3
+
4
+// in development-env not use lazy-loading, because lazy-loading too many pages will cause webpack hot update too slow. so only in production use lazy-loading;
5
+// detail: https://panjiachen.github.io/vue-element-admin-site/#/lazy-loading
6
+
7
+Vue.use(Router)
8
+
9
+/* Layout */
10
+import Layout from '../views/layout/Layout'
11
+
12
+/**
13
+* hidden: true                   if `hidden:true` will not show in the sidebar(default is false)
14
+* alwaysShow: true               if set true, will always show the root menu, whatever its child routes length
15
+*                                if not set alwaysShow, only more than one route under the children
16
+*                                it will becomes nested mode, otherwise not show the root menu
17
+* redirect: noredirect           if `redirect:noredirect` will no redirect in the breadcrumb
18
+* name:'router-name'             the name is used by <keep-alive> (must set!!!)
19
+* meta : {
20
+    title: 'title'               the name show in submenu and breadcrumb (recommend set)
21
+    icon: 'svg-name'             the icon show in the sidebar,
22
+  }
23
+**/
24
+export const constantRouterMap = [
25
+  { path: '/login', component: () => import('@/views/login/index'), hidden: true },
26
+  { path: '/404', component: () => import('@/views/404'), hidden: true },
27
+
28
+  {
29
+    path: '/',
30
+    component: Layout,
31
+    redirect: '/dashboard',
32
+    name: 'Dashboard',
33
+    hidden: true,
34
+    children: [{
35
+      path: 'dashboard',
36
+      component: () => import('@/views/dashboard/index')
37
+    }]
38
+  },
39
+
40
+  {
41
+    path: '/community',
42
+    component: Layout,
43
+    redirect: '/conmmunity/download',
44
+    alwaysShow: true,
45
+    meta: { title: '社区数据', icon: 'zip' },
46
+    children: [
47
+      {
48
+        path: 'community',
49
+        component: () => import('@/views/community/communityTable'),
50
+        name: 'community',
51
+        meta: { title: '社区列表', icon: 'table' }
52
+      }
53
+    ]
54
+  },
55
+
56
+  {
57
+    path: '/banner',
58
+    component: Layout,
59
+    redirect: '/banner/index',
60
+    alwaysShow: true,
61
+    meta: { title: '运营数据', icon: 'zip' },
62
+    children: [
63
+      {
64
+        path: 'index',
65
+        component: () => import('@/views/banner/index'),
66
+        name: 'banner-index',
67
+        meta: { title: 'banner运营', icon: 'table' }
68
+      }
69
+    ]
70
+  },
71
+
72
+  { path: '*', redirect: '/404', hidden: true }
73
+]
74
+
75
+export default new Router({
76
+  // mode: 'history', //后端支持可开
77
+  scrollBehavior: () => ({ y: 0 }),
78
+  routes: constantRouterMap
79
+})

+ 9
- 0
VUECODE/smart-operate-manage/src/store/getters.js Просмотреть файл

@@ -0,0 +1,9 @@
1
+const getters = {
2
+  sidebar: state => state.app.sidebar,
3
+  device: state => state.app.device,
4
+  token: state => state.user.token,
5
+  avatar: state => state.user.avatar,
6
+  name: state => state.user.name,
7
+  roles: state => state.user.roles
8
+}
9
+export default getters

+ 17
- 0
VUECODE/smart-operate-manage/src/store/index.js Просмотреть файл

@@ -0,0 +1,17 @@
1
+import Vue from 'vue'
2
+import Vuex from 'vuex'
3
+import app from './modules/app'
4
+import user from './modules/user'
5
+import getters from './getters'
6
+
7
+Vue.use(Vuex)
8
+
9
+const store = new Vuex.Store({
10
+  modules: {
11
+    app,
12
+    user
13
+  },
14
+  getters
15
+})
16
+
17
+export default store

+ 43
- 0
VUECODE/smart-operate-manage/src/store/modules/app.js Просмотреть файл

@@ -0,0 +1,43 @@
1
+import Cookies from 'js-cookie'
2
+
3
+const app = {
4
+  state: {
5
+    sidebar: {
6
+      opened: !+Cookies.get('sidebarStatus'),
7
+      withoutAnimation: false
8
+    },
9
+    device: 'desktop'
10
+  },
11
+  mutations: {
12
+    TOGGLE_SIDEBAR: state => {
13
+      if (state.sidebar.opened) {
14
+        Cookies.set('sidebarStatus', 1)
15
+      } else {
16
+        Cookies.set('sidebarStatus', 0)
17
+      }
18
+      state.sidebar.opened = !state.sidebar.opened
19
+      state.sidebar.withoutAnimation = false
20
+    },
21
+    CLOSE_SIDEBAR: (state, withoutAnimation) => {
22
+      Cookies.set('sidebarStatus', 1)
23
+      state.sidebar.opened = false
24
+      state.sidebar.withoutAnimation = withoutAnimation
25
+    },
26
+    TOGGLE_DEVICE: (state, device) => {
27
+      state.device = device
28
+    }
29
+  },
30
+  actions: {
31
+    ToggleSideBar: ({ commit }) => {
32
+      commit('TOGGLE_SIDEBAR')
33
+    },
34
+    CloseSideBar({ commit }, { withoutAnimation }) {
35
+      commit('CLOSE_SIDEBAR', withoutAnimation)
36
+    },
37
+    ToggleDevice({ commit }, device) {
38
+      commit('TOGGLE_DEVICE', device)
39
+    }
40
+  }
41
+}
42
+
43
+export default app

+ 99
- 0
VUECODE/smart-operate-manage/src/store/modules/user.js Просмотреть файл

@@ -0,0 +1,99 @@
1
+import { login, logout, getInfo, sendCode } from '@/api/login'
2
+import { getToken, setToken, removeToken } from '@/utils/auth'
3
+
4
+const user = {
5
+  state: {
6
+    token: getToken(),
7
+    name: '',
8
+    avatar: '',
9
+    roles: []
10
+  },
11
+
12
+  mutations: {
13
+    SET_TOKEN: (state, token) => {
14
+      state.token = token
15
+    },
16
+    SET_NAME: (state, name) => {
17
+      state.name = name
18
+    },
19
+    SET_AVATAR: (state, avatar) => {
20
+      state.avatar = avatar
21
+    },
22
+    SET_ROLES: (state, roles) => {
23
+      state.roles = roles
24
+    }
25
+  },
26
+
27
+  actions: {
28
+    // 登录
29
+    Login({ commit }, userInfo) {
30
+      const username = userInfo.username.trim()
31
+      return new Promise((resolve, reject) => {
32
+        login(username, userInfo.password).then(response => {
33
+          const data = response.data
34
+          setToken(data.token)
35
+          commit('SET_TOKEN', data.token)
36
+          resolve()
37
+        }).catch(error => {
38
+          reject(error)
39
+        })
40
+      })
41
+    },
42
+
43
+    // 获取用户信息
44
+    GetInfo({ commit, state }) {
45
+      return new Promise((resolve, reject) => {
46
+        getInfo(state.token).then(response => {
47
+          const data = response.data
48
+          if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
49
+            commit('SET_ROLES', data.roles)
50
+          } else {
51
+            reject('getInfo: roles must be a non-null array !')
52
+          }
53
+          commit('SET_NAME', data.userName)
54
+          commit('SET_AVATAR', data.avatar)
55
+          resolve(response)
56
+        }).catch(error => {
57
+          reject(error)
58
+        })
59
+      })
60
+    },
61
+
62
+    // 发送验证码
63
+    SendCode({ commit, state }, userName) {
64
+      return new Promise((resolve, reject) => {
65
+        sendCode(userName).then(response => {
66
+          const data = response.message
67
+          resolve(data)
68
+        }).catch(error => {
69
+          reject(error)
70
+        })
71
+      })
72
+    },
73
+
74
+    // 登出
75
+    LogOut({ commit, state }) {
76
+      return new Promise((resolve, reject) => {
77
+        logout(state.token).then(() => {
78
+          commit('SET_TOKEN', '')
79
+          commit('SET_ROLES', [])
80
+          removeToken()
81
+          resolve()
82
+        }).catch(error => {
83
+          reject(error)
84
+        })
85
+      })
86
+    },
87
+
88
+    // 前端 登出
89
+    FedLogOut({ commit }) {
90
+      return new Promise(resolve => {
91
+        commit('SET_TOKEN', '')
92
+        removeToken()
93
+        resolve()
94
+      })
95
+    }
96
+  }
97
+}
98
+
99
+export default user

+ 29
- 0
VUECODE/smart-operate-manage/src/styles/element-ui.scss Просмотреть файл

@@ -0,0 +1,29 @@
1
+ //to reset element-ui default css
2
+.el-upload {
3
+  input[type="file"] {
4
+    display: none !important;
5
+  }
6
+}
7
+
8
+.el-upload__input {
9
+  display: none;
10
+}
11
+
12
+//暂时性解决diolag 问题 https://github.com/ElemeFE/element/issues/2461
13
+.el-dialog {
14
+  transform: none;
15
+  left: 0;
16
+  position: relative;
17
+  margin: 0 auto;
18
+}
19
+
20
+//element ui upload
21
+.upload-container {
22
+  .el-upload {
23
+    width: 100%;
24
+    .el-upload-dragger {
25
+      width: 100%;
26
+      height: 200px;
27
+    }
28
+  }
29
+}

+ 78
- 0
VUECODE/smart-operate-manage/src/styles/index.scss Просмотреть файл

@@ -0,0 +1,78 @@
1
+@import './variables.scss';
2
+@import './mixin.scss';
3
+@import './transition.scss';
4
+@import './element-ui.scss';
5
+@import './sidebar.scss';
6
+
7
+body {
8
+  height: 100%;
9
+  -moz-osx-font-smoothing: grayscale;
10
+  -webkit-font-smoothing: antialiased;
11
+  text-rendering: optimizeLegibility;
12
+  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
13
+}
14
+
15
+label {
16
+  font-weight: 700;
17
+}
18
+
19
+html {
20
+  height: 100%;
21
+  box-sizing: border-box;
22
+}
23
+
24
+#app{
25
+  height: 100%;
26
+}
27
+
28
+*,
29
+*:before,
30
+*:after {
31
+  box-sizing: inherit;
32
+}
33
+
34
+a,
35
+a:focus,
36
+a:hover {
37
+  cursor: pointer;
38
+  color: inherit;
39
+  outline: none;
40
+  text-decoration: none;
41
+}
42
+
43
+div:focus{
44
+  outline: none;
45
+ }
46
+
47
+a:focus,
48
+a:active {
49
+  outline: none;
50
+}
51
+
52
+a,
53
+a:focus,
54
+a:hover {
55
+  cursor: pointer;
56
+  color: inherit;
57
+  text-decoration: none;
58
+}
59
+
60
+.clearfix {
61
+  &:after {
62
+    visibility: hidden;
63
+    display: block;
64
+    font-size: 0;
65
+    content: " ";
66
+    clear: both;
67
+    height: 0;
68
+  }
69
+}
70
+
71
+//main-container全局样式
72
+.app-main{
73
+  min-height: 100%
74
+}
75
+
76
+.app-container {
77
+  padding: 20px;
78
+}

+ 27
- 0
VUECODE/smart-operate-manage/src/styles/mixin.scss Просмотреть файл

@@ -0,0 +1,27 @@
1
+@mixin clearfix {
2
+  &:after {
3
+    content: "";
4
+    display: table;
5
+    clear: both;
6
+  }
7
+}
8
+
9
+@mixin scrollBar {
10
+  &::-webkit-scrollbar-track-piece {
11
+    background: #d3dce6;
12
+  }
13
+  &::-webkit-scrollbar {
14
+    width: 6px;
15
+  }
16
+  &::-webkit-scrollbar-thumb {
17
+    background: #99a9bf;
18
+    border-radius: 20px;
19
+  }
20
+}
21
+
22
+@mixin relative {
23
+  position: relative;
24
+  width: 100%;
25
+  height: 100%;
26
+}
27
+

+ 133
- 0
VUECODE/smart-operate-manage/src/styles/sidebar.scss Просмотреть файл

@@ -0,0 +1,133 @@
1
+#app {
2
+  // 主体区域
3
+  .main-container {
4
+    min-height: 100%;
5
+    transition: margin-left .28s;
6
+    margin-left: 180px;
7
+    position: relative;
8
+  }
9
+  // 侧边栏
10
+  .sidebar-container {
11
+    transition: width 0.28s;
12
+    width: 180px !important;
13
+    height: 100%;
14
+    position: fixed;
15
+    font-size: 0px;
16
+    top: 0;
17
+    bottom: 0;
18
+    left: 0;
19
+    z-index: 1001;
20
+    overflow: hidden;
21
+    //reset element-ui css
22
+    .horizontal-collapse-transition {
23
+      transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
24
+    }
25
+    .el-scrollbar__bar.is-vertical{
26
+      right: 0px;
27
+    }
28
+    .scrollbar-wrapper {
29
+      overflow-x: hidden!important;
30
+      .el-scrollbar__view {
31
+        height: 100%;
32
+      }
33
+    }
34
+    .is-horizontal {
35
+      display: none;
36
+    }
37
+    a {
38
+      display: inline-block;
39
+      width: 100%;
40
+      overflow: hidden;
41
+    }
42
+    .svg-icon {
43
+      margin-right: 16px;
44
+    }
45
+    .el-menu {
46
+      border: none;
47
+      height: 100%;
48
+      width: 100% !important;
49
+    }
50
+    .is-active > .el-submenu__title{
51
+      color: #f4f4f5!important;
52
+    }
53
+  }
54
+  .hideSidebar {
55
+    .sidebar-container {
56
+      width: 36px !important;
57
+    }
58
+    .main-container {
59
+      margin-left: 36px;
60
+    }
61
+    .submenu-title-noDropdown {
62
+      padding-left: 10px !important;
63
+      position: relative;
64
+      .el-tooltip {
65
+        padding: 0 10px !important;
66
+      }
67
+    }
68
+    .el-submenu {
69
+      overflow: hidden;
70
+      &>.el-submenu__title {
71
+        padding-left: 10px !important;
72
+        .el-submenu__icon-arrow {
73
+          display: none;
74
+        }
75
+      }
76
+    }
77
+    .el-menu--collapse {
78
+      .el-submenu {
79
+        &>.el-submenu__title {
80
+          &>span {
81
+            height: 0;
82
+            width: 0;
83
+            overflow: hidden;
84
+            visibility: hidden;
85
+            display: inline-block;
86
+          }
87
+        }
88
+      }
89
+    }
90
+  }
91
+  .sidebar-container .nest-menu .el-submenu>.el-submenu__title,
92
+  .sidebar-container .el-submenu .el-menu-item {
93
+    min-width: 180px !important;
94
+    background-color: $subMenuBg !important;
95
+    &:hover {
96
+      background-color: $menuHover !important;
97
+    }
98
+  }
99
+  .el-menu--collapse .el-menu .el-submenu {
100
+    min-width: 180px !important;
101
+  }
102
+
103
+  //适配移动端
104
+  .mobile {
105
+    .main-container {
106
+      margin-left: 0px;
107
+    }
108
+    .sidebar-container {
109
+      transition: transform .28s;
110
+      width: 180px !important;
111
+    }
112
+    &.hideSidebar {
113
+      .sidebar-container {
114
+        transition-duration: 0.3s;
115
+        transform: translate3d(-180px, 0, 0);
116
+      }
117
+    }
118
+  }
119
+  .withoutAnimation {
120
+    .main-container,
121
+    .sidebar-container {
122
+      transition: none;
123
+    }
124
+  }
125
+}
126
+
127
+.el-menu--vertical{
128
+  & >.el-menu{
129
+    .svg-icon{
130
+      margin-right: 16px;
131
+    }
132
+  }
133
+}

+ 46
- 0
VUECODE/smart-operate-manage/src/styles/transition.scss Просмотреть файл

@@ -0,0 +1,46 @@
1
+//globl transition css
2
+
3
+/*fade*/
4
+.fade-enter-active,
5
+.fade-leave-active {
6
+  transition: opacity 0.28s;
7
+}
8
+
9
+.fade-enter,
10
+.fade-leave-active {
11
+  opacity: 0;
12
+}
13
+
14
+/*fade-transform*/
15
+.fade-transform-leave-active,
16
+.fade-transform-enter-active {
17
+  transition: all .5s;
18
+}
19
+.fade-transform-enter {
20
+  opacity: 0;
21
+  transform: translateX(-30px);
22
+}
23
+.fade-transform-leave-to {
24
+  opacity: 0;
25
+  transform: translateX(30px);
26
+}
27
+
28
+/*fade*/
29
+.breadcrumb-enter-active,
30
+.breadcrumb-leave-active {
31
+  transition: all .5s;
32
+}
33
+
34
+.breadcrumb-enter,
35
+.breadcrumb-leave-active {
36
+  opacity: 0;
37
+  transform: translateX(20px);
38
+}
39
+
40
+.breadcrumb-move {
41
+  transition: all .5s;
42
+}
43
+
44
+.breadcrumb-leave-active {
45
+  position: absolute;
46
+}

+ 4
- 0
VUECODE/smart-operate-manage/src/styles/variables.scss Просмотреть файл

@@ -0,0 +1,4 @@
1
+//sidebar
2
+$menuBg:#304156;
3
+$subMenuBg:#1f2d3d;
4
+$menuHover:#001528;

+ 15
- 0
VUECODE/smart-operate-manage/src/utils/auth.js Просмотреть файл

@@ -0,0 +1,15 @@
1
+import Cookies from 'js-cookie'
2
+
3
+const TokenKey = 'X-Auth-Token'
4
+
5
+export function getToken() {
6
+  return Cookies.get(TokenKey)
7
+}
8
+
9
+export function setToken(token) {
10
+  return Cookies.set(TokenKey, token)
11
+}
12
+
13
+export function removeToken() {
14
+  return Cookies.remove(TokenKey)
15
+}

+ 74
- 0
VUECODE/smart-operate-manage/src/utils/index.js Просмотреть файл

@@ -0,0 +1,74 @@
1
+/**
2
+ * Created by jiachenpan on 16/11/18.
3
+ */
4
+
5
+export function parseTime(time, cFormat) {
6
+  if (arguments.length === 0) {
7
+    return null
8
+  }
9
+  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
10
+  let date
11
+  if (typeof time === 'object') {
12
+    date = time
13
+  } else {
14
+    if (('' + time).length === 10) time = parseInt(time) * 1000
15
+    date = new Date(time)
16
+  }
17
+  const formatObj = {
18
+    y: date.getFullYear(),
19
+    m: date.getMonth() + 1,
20
+    d: date.getDate(),
21
+    h: date.getHours(),
22
+    i: date.getMinutes(),
23
+    s: date.getSeconds(),
24
+    a: date.getDay()
25
+  }
26
+  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
27
+    let value = formatObj[key]
28
+    // Note: getDay() returns 0 on Sunday
29
+    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
30
+    if (result.length > 0 && value < 10) {
31
+      value = '0' + value
32
+    }
33
+    return value || 0
34
+  })
35
+  return time_str
36
+}
37
+
38
+export function formatTime(time, option) {
39
+  time = +time * 1000
40
+  const d = new Date(time)
41
+  const now = Date.now()
42
+
43
+  const diff = (now - d) / 1000
44
+
45
+  if (diff < 30) {
46
+    return '刚刚'
47
+  } else if (diff < 3600) {
48
+    // less 1 hour
49
+    return Math.ceil(diff / 60) + '分钟前'
50
+  } else if (diff < 3600 * 24) {
51
+    return Math.ceil(diff / 3600) + '小时前'
52
+  } else if (diff < 3600 * 24 * 2) {
53
+    return '1天前'
54
+  }
55
+  if (option) {
56
+    return parseTime(time, option)
57
+  } else {
58
+    return (
59
+      d.getMonth() +
60
+      1 +
61
+      '月' +
62
+      d.getDate() +
63
+      '日' +
64
+      d.getHours() +
65
+      '时' +
66
+      d.getMinutes() +
67
+      '分'
68
+    )
69
+  }
70
+}
71
+
72
+export function isExternal(path) {
73
+  return /^(https?:|mailto:|tel:)/.test(path)
74
+}

+ 73
- 0
VUECODE/smart-operate-manage/src/utils/request.js Просмотреть файл

@@ -0,0 +1,73 @@
1
+import axios from 'axios'
2
+import { Message, MessageBox } from 'element-ui'
3
+import store from '../store'
4
+import { getToken } from '@/utils/auth'
5
+
6
+// 创建axios实例
7
+const service = axios.create({
8
+  baseURL: process.env.BASE_API, // api 的 base_url
9
+  timeout: 5000 // 请求超时时间
10
+})
11
+
12
+// request拦截器
13
+service.interceptors.request.use(
14
+  config => {
15
+    if (store.getters.token) {
16
+      config.headers['X-Auth-Token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
17
+    }
18
+    return config
19
+  },
20
+  error => {
21
+    // Do something with request error
22
+    console.log(error) // for debug
23
+    Promise.reject(error)
24
+  }
25
+)
26
+
27
+// response 拦截器
28
+service.interceptors.response.use(
29
+  response => {
30
+    /**
31
+     * code为非0是抛错
32
+     */
33
+    const res = response.data
34
+    if (res.code !== '0') {
35
+      Message({
36
+        message: res.message,
37
+        type: 'error',
38
+        duration: 5 * 1000
39
+      })
40
+
41
+      // 802:Token 身份凭证不存在; 50012:其他客户端登录了;  803:Token 过期了;
42
+      if (res.code === 802 || res.code === 50012 || res.code === 803) {
43
+        MessageBox.confirm(
44
+          '你已被登出,可以取消继续留在该页面,或者重新登录',
45
+          '确定登出',
46
+          {
47
+            confirmButtonText: '重新登录',
48
+            cancelButtonText: '取消',
49
+            type: 'warning'
50
+          }
51
+        ).then(() => {
52
+          store.dispatch('FedLogOut').then(() => {
53
+            location.reload() // 为了重新实例化vue-router对象 避免bug
54
+          })
55
+        })
56
+      }
57
+      return Promise.reject('error')
58
+    } else {
59
+      return response.data
60
+    }
61
+  },
62
+  error => {
63
+    console.log('err' + error) // for debug
64
+    Message({
65
+      message: error.message,
66
+      type: 'error',
67
+      duration: 5 * 1000
68
+    })
69
+    return Promise.reject(error)
70
+  }
71
+)
72
+
73
+export default service

+ 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
+}

+ 38
- 0
VUECODE/smart-operate-manage/src/utils/validate.js Просмотреть файл

@@ -0,0 +1,38 @@
1
+/**
2
+ * Created by jiachenpan on 16/11/18.
3
+ */
4
+/* 手机号码*/
5
+export function isvalidUsername(str) {
6
+  const reg = /^1(3|4|5|7|8)\d{9}$/
7
+  return reg.test(str)
8
+}
9
+
10
+/* 合法uri*/
11
+export function validateURL(textval) {
12
+  const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
13
+  return urlregex.test(textval)
14
+}
15
+
16
+/* 小写字母*/
17
+export function validateLowerCase(str) {
18
+  const reg = /^[a-z]+$/
19
+  return reg.test(str)
20
+}
21
+
22
+/* 大写字母*/
23
+export function validateUpperCase(str) {
24
+  const reg = /^[A-Z]+$/
25
+  return reg.test(str)
26
+}
27
+
28
+/* 大小写字母*/
29
+export function validatAlphabets(str) {
30
+  const reg = /^[A-Za-z]+$/
31
+  return reg.test(str)
32
+}
33
+
34
+/* 四位数字验证码*/
35
+export function validatCode(str) {
36
+  const reg = /^\d{4}$/
37
+  return reg.test(str)
38
+}

+ 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
+}

+ 228
- 0
VUECODE/smart-operate-manage/src/views/404.vue Просмотреть файл

@@ -0,0 +1,228 @@
1
+<template>
2
+  <div class="wscn-http404-container">
3
+    <div class="wscn-http404">
4
+      <div class="pic-404">
5
+        <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404">
6
+        <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404">
7
+        <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404">
8
+        <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404">
9
+      </div>
10
+      <div class="bullshit">
11
+        <div class="bullshit__oops">OOPS!</div>
12
+        <div class="bullshit__info">版权所有
13
+          <a class="link-type" href="https://wallstreetcn.com" target="_blank">华尔街见闻</a>
14
+        </div>
15
+        <div class="bullshit__headline">{{ message }}</div>
16
+        <div class="bullshit__info">请检查您输入的网址是否正确,请点击以下按钮返回主页或者发送错误报告</div>
17
+        <a href="" class="bullshit__return-home">返回首页</a>
18
+      </div>
19
+    </div>
20
+  </div>
21
+</template>
22
+
23
+<script>
24
+
25
+export default {
26
+  name: 'Page404',
27
+  computed: {
28
+    message() {
29
+      return '网管说这个页面你不能进......'
30
+    }
31
+  }
32
+}
33
+</script>
34
+
35
+<style rel="stylesheet/scss" lang="scss" scoped>
36
+.wscn-http404-container{
37
+  transform: translate(-50%,-50%);
38
+  position: absolute;
39
+  top: 40%;
40
+  left: 50%;
41
+}
42
+.wscn-http404 {
43
+  position: relative;
44
+  width: 1200px;
45
+  padding: 0 50px;
46
+  overflow: hidden;
47
+  .pic-404 {
48
+    position: relative;
49
+    float: left;
50
+    width: 600px;
51
+    overflow: hidden;
52
+    &__parent {
53
+      width: 100%;
54
+    }
55
+    &__child {
56
+      position: absolute;
57
+      &.left {
58
+        width: 80px;
59
+        top: 17px;
60
+        left: 220px;
61
+        opacity: 0;
62
+        animation-name: cloudLeft;
63
+        animation-duration: 2s;
64
+        animation-timing-function: linear;
65
+        animation-fill-mode: forwards;
66
+        animation-delay: 1s;
67
+      }
68
+      &.mid {
69
+        width: 46px;
70
+        top: 10px;
71
+        left: 420px;
72
+        opacity: 0;
73
+        animation-name: cloudMid;
74
+        animation-duration: 2s;
75
+        animation-timing-function: linear;
76
+        animation-fill-mode: forwards;
77
+        animation-delay: 1.2s;
78
+      }
79
+      &.right {
80
+        width: 62px;
81
+        top: 100px;
82
+        left: 500px;
83
+        opacity: 0;
84
+        animation-name: cloudRight;
85
+        animation-duration: 2s;
86
+        animation-timing-function: linear;
87
+        animation-fill-mode: forwards;
88
+        animation-delay: 1s;
89
+      }
90
+      @keyframes cloudLeft {
91
+        0% {
92
+          top: 17px;
93
+          left: 220px;
94
+          opacity: 0;
95
+        }
96
+        20% {
97
+          top: 33px;
98
+          left: 188px;
99
+          opacity: 1;
100
+        }
101
+        80% {
102
+          top: 81px;
103
+          left: 92px;
104
+          opacity: 1;
105
+        }
106
+        100% {
107
+          top: 97px;
108
+          left: 60px;
109
+          opacity: 0;
110
+        }
111
+      }
112
+      @keyframes cloudMid {
113
+        0% {
114
+          top: 10px;
115
+          left: 420px;
116
+          opacity: 0;
117
+        }
118
+        20% {
119
+          top: 40px;
120
+          left: 360px;
121
+          opacity: 1;
122
+        }
123
+        70% {
124
+          top: 130px;
125
+          left: 180px;
126
+          opacity: 1;
127
+        }
128
+        100% {
129
+          top: 160px;
130
+          left: 120px;
131
+          opacity: 0;
132
+        }
133
+      }
134
+      @keyframes cloudRight {
135
+        0% {
136
+          top: 100px;
137
+          left: 500px;
138
+          opacity: 0;
139
+        }
140
+        20% {
141
+          top: 120px;
142
+          left: 460px;
143
+          opacity: 1;
144
+        }
145
+        80% {
146
+          top: 180px;
147
+          left: 340px;
148
+          opacity: 1;
149
+        }
150
+        100% {
151
+          top: 200px;
152
+          left: 300px;
153
+          opacity: 0;
154
+        }
155
+      }
156
+    }
157
+  }
158
+  .bullshit {
159
+    position: relative;
160
+    float: left;
161
+    width: 300px;
162
+    padding: 30px 0;
163
+    overflow: hidden;
164
+    &__oops {
165
+      font-size: 32px;
166
+      font-weight: bold;
167
+      line-height: 40px;
168
+      color: #1482f0;
169
+      opacity: 0;
170
+      margin-bottom: 20px;
171
+      animation-name: slideUp;
172
+      animation-duration: 0.5s;
173
+      animation-fill-mode: forwards;
174
+    }
175
+    &__headline {
176
+      font-size: 20px;
177
+      line-height: 24px;
178
+      color: #222;
179
+      font-weight: bold;
180
+      opacity: 0;
181
+      margin-bottom: 10px;
182
+      animation-name: slideUp;
183
+      animation-duration: 0.5s;
184
+      animation-delay: 0.1s;
185
+      animation-fill-mode: forwards;
186
+    }
187
+    &__info {
188
+      font-size: 13px;
189
+      line-height: 21px;
190
+      color: grey;
191
+      opacity: 0;
192
+      margin-bottom: 30px;
193
+      animation-name: slideUp;
194
+      animation-duration: 0.5s;
195
+      animation-delay: 0.2s;
196
+      animation-fill-mode: forwards;
197
+    }
198
+    &__return-home {
199
+      display: block;
200
+      float: left;
201
+      width: 110px;
202
+      height: 36px;
203
+      background: #1482f0;
204
+      border-radius: 100px;
205
+      text-align: center;
206
+      color: #ffffff;
207
+      opacity: 0;
208
+      font-size: 14px;
209
+      line-height: 36px;
210
+      cursor: pointer;
211
+      animation-name: slideUp;
212
+      animation-duration: 0.5s;
213
+      animation-delay: 0.3s;
214
+      animation-fill-mode: forwards;
215
+    }
216
+    @keyframes slideUp {
217
+      0% {
218
+        transform: translateY(60px);
219
+        opacity: 0;
220
+      }
221
+      100% {
222
+        transform: translateY(0);
223
+        opacity: 1;
224
+      }
225
+    }
226
+  }
227
+}
228
+</style>

+ 62
- 0
VUECODE/smart-operate-manage/src/views/banner/index.vue Просмотреть файл

@@ -0,0 +1,62 @@
1
+<template>
2
+  <div class="search-header">
3
+    <el-form ref="form" :model="bannr" label-width="100px">
4
+      <el-form-item label="标题">
5
+        <el-input v-model="bannr.bannerTitle" />
6
+      </el-form-item>
7
+      <el-form-item label="跳转概述">
8
+        <el-input v-model="bannr.bannerDescription" />
9
+      </el-form-item>
10
+      <el-form-item label="适用社区">
11
+        <el-select v-model="bannr.communityId" placeholder="请选择社区">
12
+          <el-option label="智慧社区" value="shanghai" />
13
+        </el-select>
14
+      </el-form-item>
15
+      <el-form-item label="banner位置">
16
+        <el-select v-model="bannr.bannerPosition" placeholder="请选择banner位置">
17
+          <el-option label="首页banner" value="shanghai" />
18
+          <el-option label="服务员banner" value="beijing" />
19
+        </el-select>
20
+      </el-form-item>
21
+      <el-form-item>
22
+        <el-button>清空</el-button>
23
+        <el-button type="primary" @click="search">搜索</el-button>
24
+      </el-form-item>
25
+    </el-form>
26
+  </div>
27
+</template>
28
+
29
+<script>
30
+export default {
31
+  name: 'BannerIndex',
32
+  data() {
33
+    return {
34
+      bannr: {
35
+        bannerTitle: '',
36
+        bannerPosition: '',
37
+        bannerDescription: '',
38
+        communityId: '',
39
+        pageNum: '',
40
+        pageSize: ''
41
+      }
42
+    }
43
+  },
44
+  methods: {
45
+    search() {
46
+      console.log(this.bannr)
47
+    }
48
+  }
49
+}
50
+</script>
51
+
52
+<style rel="stylesheet/scss" lang="scss" scoped>
53
+.search-header {
54
+  float: left;
55
+  margin: 20px;
56
+  .el-form-item {
57
+    float: left;
58
+    margin-left: 20px;
59
+  }
60
+}
61
+</style>
62
+

+ 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>

+ 32
- 0
VUECODE/smart-operate-manage/src/views/dashboard/index.vue Просмотреть файл

@@ -0,0 +1,32 @@
1
+<template>
2
+  <div class="dashboard-container">
3
+    <div class="dashboard-text">name:{{ name }}</div>
4
+    <div class="dashboard-text">roles:<span v-for="role in roles" :key="role">{{ role }}</span></div>
5
+  </div>
6
+</template>
7
+
8
+<script>
9
+import { mapGetters } from 'vuex'
10
+
11
+export default {
12
+  name: 'Dashboard',
13
+  computed: {
14
+    ...mapGetters([
15
+      'name',
16
+      'roles'
17
+    ])
18
+  }
19
+}
20
+</script>
21
+
22
+<style rel="stylesheet/scss" lang="scss" scoped>
23
+.dashboard {
24
+  &-container {
25
+    margin: 30px;
26
+  }
27
+  &-text {
28
+    font-size: 30px;
29
+    line-height: 46px;
30
+  }
31
+}
32
+</style>

+ 0
- 0
VUECODE/smart-operate-manage/src/views/form/index.vue Просмотреть файл


Некоторые файлы не были показаны из-за большого количества измененных файлов