347617796@qq.com 3 years ago
parent
commit
6a16cfc0af
61 changed files with 6319 additions and 2291 deletions
  1. 1 0
      .env.development
  2. 1 0
      .env.production
  3. 417 11
      package-lock.json
  4. 2 0
      package.json
  5. 106 85
      src/api/auth.js
  6. 87 81
      src/api/websocket.js
  7. 33 18
      src/assets/css/iconfont.css
  8. 0 0
      src/assets/css/iconfont.js
  9. 28 0
      src/assets/css/iconfont.json
  10. BIN
      src/assets/css/iconfont.ttf
  11. BIN
      src/assets/css/iconfont.woff
  12. BIN
      src/assets/css/iconfont.woff2
  13. 35 0
      src/assets/css/reset.css
  14. 4 5
      src/components/EmployeeSelector.vue
  15. 268 0
      src/components/Suggest.vue
  16. 207 27
      src/components/applicationIntegrationPopup.vue
  17. 213 25
      src/components/bonusPointsPopup.vue
  18. 46 43
      src/components/examinePopup.vue
  19. 12 4
      src/components/noData.vue
  20. 1 1
      src/components/upload.vue
  21. 3 3
      src/home.vue
  22. 61 8
      src/index.vue
  23. 363 0
      src/inform.vue
  24. 12 24
      src/main.js
  25. 29 9
      src/router/index.js
  26. 17 5
      src/views/abPoint/apply_list.vue
  27. 18 5
      src/views/abPoint/award_punish.vue
  28. 4 7
      src/views/common/rewardTask.vue
  29. 4 7
      src/views/common/rewardTaskAmend.vue
  30. 4 7
      src/views/common/temporaryTask.vue
  31. 4 7
      src/views/common/temporaryTaskAmend.vue
  32. 2 2
      src/views/ranking/attendance_rating.vue
  33. 1 2
      src/views/ranking/balanceA.vue
  34. 0 1012
      src/views/ranking/custom_rank code.vue
  35. 1 1
      src/views/ranking/dept_rank.vue
  36. 3 3
      src/views/ranking/integral_event.vue
  37. 354 167
      src/views/ranking/log_rank.vue
  38. 1 2
      src/views/ranking/lotteryTicket_statistics.vue
  39. 2 2
      src/views/ranking/manager_statistics.vue
  40. 473 2
      src/views/ranking/task_rank.vue
  41. 1 2
      src/views/set/framework.vue
  42. 2 2
      src/views/set/jurisdiction.vue
  43. 2 2
      src/views/set/log.vue
  44. 7 4
      src/views/set/rule.vue
  45. 7 7
      src/views/set/systemLayout.vue
  46. 311 257
      src/views/set/voluntarilyPoint.vue
  47. 1 1
      src/views/subassembly/update_notice.vue
  48. 2 2
      src/views/task/allTask.vue
  49. 2 2
      src/views/task/get_task.vue
  50. 2 2
      src/views/task/myExamine.vue
  51. 2 2
      src/views/task/my_issue.vue
  52. 3 3
      src/views/task/my_task.vue
  53. 383 2
      src/views/welfare/conversion.vue
  54. 47 0
      src/views/welfare/flBox.vue
  55. 601 2
      src/views/welfare/flManagement.vue
  56. 0 367
      src/views/welfare/flStatistics.vue
  57. 386 0
      src/views/welfare/operatingRecord.vue
  58. 1143 2
      src/views/welfare/prize.vue
  59. 192 0
      src/views/workbench/alreadySp.vue
  60. 407 0
      src/views/workbench/approval_batch.vue
  61. 1 57
      src/views/workbench/approval_list.vue

+ 1 - 0
.env.development

@@ -1,3 +1,4 @@
 NODE_ENV="development"
 VUE_APP_BASE_API="https://test-ding.g107.com/"
 VUE_APP_APPID="50530"
+VUE_APP_WEBSCOKET="test-ding.g107.com"

+ 1 - 0
.env.production

@@ -1,5 +1,6 @@
 NODE_ENV="production"
 VUE_APP_BASE_API="https://ding.insys.g107.com/"
 VUE_APP_APPID="55493"
+VUE_APP_WEBSCOKET="ding.insys.g107.com"
 
 

+ 417 - 11
package-lock.json

@@ -1095,7 +1095,6 @@
       "version": "7.14.0",
       "resolved": "https://registry.nlark.com/@babel/runtime/download/@babel/runtime-7.14.0.tgz?cache=0&sync_timestamp=1619727414495&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.14.0.tgz",
       "integrity": "sha1-RnlLwgthLF915i3QceJN/ZXxy+Y=",
-      "dev": true,
       "requires": {
         "regenerator-runtime": "^0.13.4"
       },
@@ -1103,8 +1102,7 @@
         "regenerator-runtime": {
           "version": "0.13.7",
           "resolved": "https://registry.nlark.com/regenerator-runtime/download/regenerator-runtime-0.13.7.tgz",
-          "integrity": "sha1-ysLazIoepnX+qrrriugziYrkb1U=",
-          "dev": true
+          "integrity": "sha1-ysLazIoepnX+qrrriugziYrkb1U="
         }
       }
     },
@@ -1304,6 +1302,16 @@
       "integrity": "sha1-pTUV2yXYA4N0OBtzryC7Ty5QjYc=",
       "dev": true
     },
+    "@transloadit/prettier-bytes": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz",
+      "integrity": "sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA=="
+    },
+    "@types/esrever": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/@types/esrever/-/esrever-0.2.0.tgz",
+      "integrity": "sha512-5NI6TeGzVEy/iBcuYtcPzzIC6EqlfQ2+UZ54vT0ulq8bPNGAy8UJD+XcsAyEOcnYFUjOVWuUV+k4/rVkxt9/XQ=="
+    },
     "@types/glob": {
       "version": "7.1.3",
       "resolved": "https://registry.nlark.com/@types/glob/download/@types/glob-7.1.3.tgz?cache=0&sync_timestamp=1618847045236&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fglob%2Fdownload%2F%40types%2Fglob-7.1.3.tgz",
@@ -1344,6 +1352,53 @@
       "integrity": "sha1-FZJUFOCtLNdlv+9YhC9+JqesyyQ=",
       "dev": true
     },
+    "@uppy/companion-client": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-2.0.3.tgz",
+      "integrity": "sha512-I1baKKBpb3d//q3agRtNV3UD/sA7EecFOfoVSpMlPkFu6oQqxjSC5OFXTf3fa8X+wo4Lcutv1++3igPJ1zrgbA==",
+      "requires": {
+        "@uppy/utils": "^4.0.3",
+        "namespace-emitter": "^2.0.1"
+      }
+    },
+    "@uppy/core": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/@uppy/core/-/core-2.1.2.tgz",
+      "integrity": "sha512-w5wE2THkGxYxwxfZ/89q1s8umGNswCXmgjwUxB52faOnosvtu3BLp/hJltmWUQ6YNlsRsjrzxA5IyZ+/J3ApNQ==",
+      "requires": {
+        "@transloadit/prettier-bytes": "0.0.7",
+        "@uppy/store-default": "^2.0.2",
+        "@uppy/utils": "^4.0.3",
+        "lodash.throttle": "^4.1.1",
+        "mime-match": "^1.0.2",
+        "namespace-emitter": "^2.0.1",
+        "nanoid": "^3.1.25",
+        "preact": "^10.5.13"
+      }
+    },
+    "@uppy/store-default": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@uppy/store-default/-/store-default-2.0.2.tgz",
+      "integrity": "sha512-D9oz08EYBoc4fDotvaevd2Q7uVldS61HYFOXK20b5M/xXF/uxepapaqQnMu1DfCVsA77rhp7DMemxnWc9y8xTQ=="
+    },
+    "@uppy/utils": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-4.0.3.tgz",
+      "integrity": "sha512-LApneC8lNvTonzSJFupxzuEvKhwp/Klc1otq8t+zXpdgjLVVSuW/rJBFfdIDrmDoqSzVLQKYjMy07CmhDAWfKg==",
+      "requires": {
+        "lodash.throttle": "^4.1.1"
+      }
+    },
+    "@uppy/xhr-upload": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@uppy/xhr-upload/-/xhr-upload-2.0.5.tgz",
+      "integrity": "sha512-DkD6cRKrcI4oDmCimHAULb6rruyUt6SbH4/omhpvWILbG/mWV5vA39YLvYxCZ1FZbijJ4QkVTKEeOTLcmoljPg==",
+      "requires": {
+        "@uppy/companion-client": "^2.0.3",
+        "@uppy/utils": "^4.0.3",
+        "nanoid": "^3.1.25"
+      }
+    },
     "@vue/babel-helper-vue-jsx-merge-props": {
       "version": "1.2.1",
       "resolved": "https://registry.npm.taobao.org/@vue/babel-helper-vue-jsx-merge-props/download/@vue/babel-helper-vue-jsx-merge-props-1.2.1.tgz?cache=0&sync_timestamp=1602851386916&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-helper-vue-jsx-merge-props%2Fdownload%2F%40vue%2Fbabel-helper-vue-jsx-merge-props-1.2.1.tgz",
@@ -1810,6 +1865,103 @@
       "integrity": "sha1-trQKdiVCnSvXwigd26YB7QXcfxo=",
       "dev": true
     },
+    "@wangeditor/basic-modules": {
+      "version": "0.7.8",
+      "resolved": "https://registry.npmjs.org/@wangeditor/basic-modules/-/basic-modules-0.7.8.tgz",
+      "integrity": "sha512-i921Wm+L5YQ9Xjgmm06oje8I2/zdz1g7b2jO2+0YvlL0Fe8gyIwyev3lRLIauWUr0jy3c21erKMcd0T/0PPb0A==",
+      "requires": {
+        "is-url": "^1.2.4"
+      }
+    },
+    "@wangeditor/code-highlight": {
+      "version": "0.7.5",
+      "resolved": "https://registry.npmjs.org/@wangeditor/code-highlight/-/code-highlight-0.7.5.tgz",
+      "integrity": "sha512-+MjF1b5ab8S36IMBbVQ6vpt8EbrifUKhb/i2hf5E3YnTK/8Yaama9QyHMXW5VHK4guysMP92+HlBcApCERgGPQ==",
+      "requires": {
+        "prismjs": "^1.23.0"
+      }
+    },
+    "@wangeditor/core": {
+      "version": "0.12.3",
+      "resolved": "https://registry.npmjs.org/@wangeditor/core/-/core-0.12.3.tgz",
+      "integrity": "sha512-GNOV6DT/zNsvLR0zGEnXyb30vbp9tfY2LeQzzX+hjlkNwXPaP3FcLWWZFYGPbrGCA0O8Z2cM4b7GIcYVoAPO+Q==",
+      "requires": {
+        "event-emitter": "^0.3.5",
+        "html-void-elements": "^2.0.0",
+        "i18next": "^20.4.0",
+        "scroll-into-view-if-needed": "^2.2.28",
+        "slate-history": "^0.62.0",
+        "xml-formatter": "^2.4.0"
+      }
+    },
+    "@wangeditor/editor": {
+      "version": "0.12.3",
+      "resolved": "https://registry.npmjs.org/@wangeditor/editor/-/editor-0.12.3.tgz",
+      "integrity": "sha512-IsmgdSCLlBdm9so4b/8pQn/8ce7uy2n4yhLoFeHmHmDrNjgrytTnEJTixITcXusG4cHZkKKmyWK/ZEVCM8Jt7g==",
+      "requires": {
+        "@uppy/core": "^2.1.1",
+        "@uppy/xhr-upload": "^2.0.3",
+        "@wangeditor/basic-modules": "^0.7.8",
+        "@wangeditor/code-highlight": "^0.7.5",
+        "@wangeditor/core": "^0.12.3",
+        "@wangeditor/list-module": "^0.7.7",
+        "@wangeditor/table-module": "^0.8.5",
+        "@wangeditor/upload-image-module": "^0.7.7",
+        "@wangeditor/video-module": "^0.7.5",
+        "dom7": "^3.0.0",
+        "is-hotkey": "^0.2.0",
+        "lodash.camelcase": "^4.3.0",
+        "lodash.clonedeep": "^4.5.0",
+        "lodash.debounce": "^4.0.8",
+        "lodash.foreach": "^4.5.0",
+        "lodash.isequal": "^4.5.0",
+        "lodash.throttle": "^4.1.1",
+        "lodash.toarray": "^4.4.0",
+        "nanoid": "^3.1.30",
+        "slate": "^0.63.0",
+        "snabbdom": "^3.0.1"
+      }
+    },
+    "@wangeditor/editor-for-vue": {
+      "version": "0.6.12-1",
+      "resolved": "https://registry.npmjs.org/@wangeditor/editor-for-vue/-/editor-for-vue-0.6.12-1.tgz",
+      "integrity": "sha512-qt6pyQtE8y3m3qP+EwfiiS0fcDwpJpOjXqV976OdPUwlV4LPY8AXnGGmG12GPNOvQW3C43W8rYbUpZ8+62gEYw==",
+      "requires": {
+        "event-emitter": "^0.3.5",
+        "vue-template-compiler": "^2.6.14"
+      },
+      "dependencies": {
+        "vue-template-compiler": {
+          "version": "2.6.14",
+          "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz",
+          "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==",
+          "requires": {
+            "de-indent": "^1.0.2",
+            "he": "^1.1.0"
+          }
+        }
+      }
+    },
+    "@wangeditor/list-module": {
+      "version": "0.7.7",
+      "resolved": "https://registry.npmjs.org/@wangeditor/list-module/-/list-module-0.7.7.tgz",
+      "integrity": "sha512-lZdtg72A99m/icXfMk4vyDXMAUXRnLx4/N0SVJwVLrHBdztM1XmBw48l/XCChwxkpRC0BxbsSNE4H5iHvupWqQ=="
+    },
+    "@wangeditor/table-module": {
+      "version": "0.8.5",
+      "resolved": "https://registry.npmjs.org/@wangeditor/table-module/-/table-module-0.8.5.tgz",
+      "integrity": "sha512-KAh0dzKUNUqKHAqCTsQUHBxYoTDB76tEXEVe+NmK/lRih+bFdy2l5q83rIr5fiJqwonzEVobBZbr2mVD8I8RXQ=="
+    },
+    "@wangeditor/upload-image-module": {
+      "version": "0.7.7",
+      "resolved": "https://registry.npmjs.org/@wangeditor/upload-image-module/-/upload-image-module-0.7.7.tgz",
+      "integrity": "sha512-559lcMmRPiSTXI+mD1W/cGn+NYF4BqkCK9MoJJCT9eXD17c6+6GlJ3gNeMtYuYAHL/hlwlDUWRtSe99lG8WCYA=="
+    },
+    "@wangeditor/video-module": {
+      "version": "0.7.5",
+      "resolved": "https://registry.npmjs.org/@wangeditor/video-module/-/video-module-0.7.5.tgz",
+      "integrity": "sha512-KIgm69L+OSYvaeoQGGdVLgOV1r20ixaxI5lysvu1UCRUR26vukTIXK617CiR0Q1gueYMaU6lY9JqMyr+wExjDg=="
+    },
     "@webassemblyjs/ast": {
       "version": "1.9.0",
       "resolved": "https://registry.npm.taobao.org/@webassemblyjs/ast/download/@webassemblyjs/ast-1.9.0.tgz?cache=0&sync_timestamp=1610045499973&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fast%2Fdownload%2F%40webassemblyjs%2Fast-1.9.0.tgz",
@@ -3591,6 +3743,11 @@
         }
       }
     },
+    "compute-scroll-into-view": {
+      "version": "1.0.17",
+      "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz",
+      "integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg=="
+    },
     "concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz",
@@ -4199,6 +4356,15 @@
       "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
       "dev": true
     },
+    "d": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+      "requires": {
+        "es5-ext": "^0.10.50",
+        "type": "^1.0.1"
+      }
+    },
     "dashdash": {
       "version": "1.14.1",
       "resolved": "https://registry.npm.taobao.org/dashdash/download/dashdash-1.14.1.tgz?cache=0&sync_timestamp=1601073602368&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdashdash%2Fdownload%2Fdashdash-1.14.1.tgz",
@@ -4211,8 +4377,7 @@
     "de-indent": {
       "version": "1.0.2",
       "resolved": "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz",
-      "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=",
-      "dev": true
+      "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0="
     },
     "debug": {
       "version": "3.1.0",
@@ -4602,6 +4767,14 @@
         }
       }
     },
+    "dom7": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/dom7/-/dom7-3.0.0.tgz",
+      "integrity": "sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g==",
+      "requires": {
+        "ssr-window": "^3.0.0-alpha.1"
+      }
+    },
     "domain-browser": {
       "version": "1.2.0",
       "resolved": "https://registry.npm.taobao.org/domain-browser/download/domain-browser-1.2.0.tgz",
@@ -4874,6 +5047,35 @@
         "is-symbol": "^1.0.2"
       }
     },
+    "es5-ext": {
+      "version": "0.10.53",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+      "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+      "requires": {
+        "es6-iterator": "~2.0.3",
+        "es6-symbol": "~3.1.3",
+        "next-tick": "~1.0.0"
+      }
+    },
+    "es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+      "requires": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "es6-symbol": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+      "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+      "requires": {
+        "d": "^1.0.1",
+        "ext": "^1.1.2"
+      }
+    },
     "escalade": {
       "version": "3.1.1",
       "resolved": "https://registry.npm.taobao.org/escalade/download/escalade-3.1.1.tgz",
@@ -5171,6 +5373,11 @@
         }
       }
     },
+    "esrever": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/esrever/-/esrever-0.2.0.tgz",
+      "integrity": "sha1-lunSj08bGnZ4TNXUkOquAQ50B7g="
+    },
     "estraverse": {
       "version": "4.3.0",
       "resolved": "https://registry.npm.taobao.org/estraverse/download/estraverse-4.3.0.tgz",
@@ -5189,6 +5396,15 @@
       "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
       "dev": true
     },
+    "event-emitter": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+      "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+      "requires": {
+        "d": "1",
+        "es5-ext": "~0.10.14"
+      }
+    },
     "event-pubsub": {
       "version": "4.3.0",
       "resolved": "https://registry.npm.taobao.org/event-pubsub/download/event-pubsub-4.3.0.tgz?cache=0&sync_timestamp=1606361475552&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fevent-pubsub%2Fdownload%2Fevent-pubsub-4.3.0.tgz",
@@ -5396,6 +5612,21 @@
         }
       }
     },
+    "ext": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz",
+      "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==",
+      "requires": {
+        "type": "^2.5.0"
+      },
+      "dependencies": {
+        "type": {
+          "version": "2.5.0",
+          "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz",
+          "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw=="
+        }
+      }
+    },
     "extend": {
       "version": "3.0.2",
       "resolved": "https://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz",
@@ -5508,8 +5739,7 @@
     "fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-3.1.3.tgz?cache=0&sync_timestamp=1591599697571&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-deep-equal%2Fdownload%2Ffast-deep-equal-3.1.3.tgz",
-      "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=",
-      "dev": true
+      "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU="
     },
     "fast-glob": {
       "version": "2.2.7",
@@ -6109,8 +6339,7 @@
     "he": {
       "version": "1.2.0",
       "resolved": "https://registry.npm.taobao.org/he/download/he-1.2.0.tgz",
-      "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=",
-      "dev": true
+      "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8="
     },
     "hex-color-regex": {
       "version": "1.1.0",
@@ -6206,6 +6435,11 @@
       "integrity": "sha1-e15vfmZen7QfMAB+2eDUHpf7IUA=",
       "dev": true
     },
+    "html-void-elements": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz",
+      "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A=="
+    },
     "html-webpack-plugin": {
       "version": "3.2.0",
       "resolved": "https://registry.npm.taobao.org/html-webpack-plugin/download/html-webpack-plugin-3.2.0.tgz",
@@ -6375,6 +6609,14 @@
       "integrity": "sha1-xbHNFPUK6uCatsWf5jujOV/k36M=",
       "dev": true
     },
+    "i18next": {
+      "version": "20.6.1",
+      "resolved": "https://registry.npmjs.org/i18next/-/i18next-20.6.1.tgz",
+      "integrity": "sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==",
+      "requires": {
+        "@babel/runtime": "^7.12.0"
+      }
+    },
     "iconv-lite": {
       "version": "0.4.24",
       "resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz?cache=0&sync_timestamp=1594184264130&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ficonv-lite%2Fdownload%2Ficonv-lite-0.4.24.tgz",
@@ -6417,6 +6659,11 @@
       "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
       "dev": true
     },
+    "immer": {
+      "version": "7.0.15",
+      "resolved": "https://registry.npmjs.org/immer/-/immer-7.0.15.tgz",
+      "integrity": "sha512-yM7jo9+hvYgvdCQdqvhCNRRio0SCXc8xDPzA25SvKWa7b1WVPjLwQs1VYU5JPXjcJPTqAa5NP5dqpORGYBQ2AA=="
+    },
     "import-cwd": {
       "version": "2.1.0",
       "resolved": "https://registry.npm.taobao.org/import-cwd/download/import-cwd-2.1.0.tgz",
@@ -6879,6 +7126,11 @@
         "is-extglob": "^2.1.1"
       }
     },
+    "is-hotkey": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.2.0.tgz",
+      "integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw=="
+    },
     "is-negative-zero": {
       "version": "2.0.1",
       "resolved": "https://registry.npm.taobao.org/is-negative-zero/download/is-negative-zero-2.0.1.tgz?cache=0&sync_timestamp=1607125693555&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-negative-zero%2Fdownload%2Fis-negative-zero-2.0.1.tgz",
@@ -6999,6 +7251,11 @@
       "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
       "dev": true
     },
+    "is-url": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
+      "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww=="
+    },
     "is-windows": {
       "version": "1.0.2",
       "resolved": "https://registry.npm.taobao.org/is-windows/download/is-windows-1.0.2.tgz",
@@ -7329,11 +7586,20 @@
       "integrity": "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw=",
       "dev": true
     },
+    "lodash.camelcase": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+      "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
+    },
+    "lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
+    },
     "lodash.debounce": {
       "version": "4.0.8",
       "resolved": "https://registry.npm.taobao.org/lodash.debounce/download/lodash.debounce-4.0.8.tgz?cache=0&sync_timestamp=1571657605147&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash.debounce%2Fdownload%2Flodash.debounce-4.0.8.tgz",
-      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
-      "dev": true
+      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
     },
     "lodash.defaultsdeep": {
       "version": "4.6.1",
@@ -7341,6 +7607,16 @@
       "integrity": "sha1-US6b1yHSctlOPTpjZT+hdRZ0HKY=",
       "dev": true
     },
+    "lodash.foreach": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
+      "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM="
+    },
+    "lodash.isequal": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+      "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
+    },
     "lodash.kebabcase": {
       "version": "4.1.1",
       "resolved": "https://registry.npm.taobao.org/lodash.kebabcase/download/lodash.kebabcase-4.1.1.tgz",
@@ -7359,6 +7635,16 @@
       "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
       "dev": true
     },
+    "lodash.throttle": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+      "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
+    },
+    "lodash.toarray": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
+      "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE="
+    },
     "lodash.transform": {
       "version": "4.6.0",
       "resolved": "https://registry.npm.taobao.org/lodash.transform/download/lodash.transform-4.6.0.tgz",
@@ -7559,6 +7845,14 @@
       "integrity": "sha1-jLMT5Zll08Bc+/iYkVomevRqM1w=",
       "dev": true
     },
+    "mime-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/mime-match/-/mime-match-1.0.2.tgz",
+      "integrity": "sha1-P4fDHprxpf1IX7nbE0Qosju7e6g=",
+      "requires": {
+        "wildcard": "^1.1.0"
+      }
+    },
     "mime-types": {
       "version": "2.1.30",
       "resolved": "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.30.tgz?cache=0&sync_timestamp=1617340124913&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-types%2Fdownload%2Fmime-types-2.1.30.tgz",
@@ -7798,6 +8092,11 @@
         "thenify-all": "^1.0.0"
       }
     },
+    "namespace-emitter": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/namespace-emitter/-/namespace-emitter-2.0.1.tgz",
+      "integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g=="
+    },
     "nan": {
       "version": "2.14.2",
       "resolved": "https://registry.npm.taobao.org/nan/download/nan-2.14.2.tgz?cache=0&sync_timestamp=1602591675048&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnan%2Fdownload%2Fnan-2.14.2.tgz",
@@ -7805,6 +8104,11 @@
       "dev": true,
       "optional": true
     },
+    "nanoid": {
+      "version": "3.1.30",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz",
+      "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ=="
+    },
     "nanomatch": {
       "version": "1.2.13",
       "resolved": "https://registry.npm.taobao.org/nanomatch/download/nanomatch-1.2.13.tgz",
@@ -7842,6 +8146,11 @@
       "integrity": "sha1-tKr7k+OustgXTKU88WOrfXMIMF8=",
       "dev": true
     },
+    "next-tick": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
+    },
     "nice-try": {
       "version": "1.0.5",
       "resolved": "https://registry.npm.taobao.org/nice-try/download/nice-try-1.0.5.tgz?cache=0&sync_timestamp=1614510016909&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnice-try%2Fdownload%2Fnice-try-1.0.5.tgz",
@@ -9207,6 +9516,11 @@
         "posthtml-render": "^1.0.6"
       }
     },
+    "preact": {
+      "version": "10.5.15",
+      "resolved": "https://registry.npmjs.org/preact/-/preact-10.5.15.tgz",
+      "integrity": "sha512-5chK29n6QcJc3m1lVrKQSQ+V7K1Gb8HeQY6FViQ5AxCAEGu3DaHffWNDkC9+miZgsLvbvU9rxbV1qinGHMHzqA=="
+    },
     "prelude-ls": {
       "version": "1.1.2",
       "resolved": "https://registry.npm.taobao.org/prelude-ls/download/prelude-ls-1.1.2.tgz",
@@ -9236,6 +9550,11 @@
         "renderkid": "^2.0.4"
       }
     },
+    "prismjs": {
+      "version": "1.25.0",
+      "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.25.0.tgz",
+      "integrity": "sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg=="
+    },
     "process": {
       "version": "0.11.10",
       "resolved": "https://registry.npm.taobao.org/process/download/process-0.11.10.tgz",
@@ -9852,6 +10171,14 @@
         "raw-loader": "~0.5.1"
       }
     },
+    "scroll-into-view-if-needed": {
+      "version": "2.2.28",
+      "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.28.tgz",
+      "integrity": "sha512-8LuxJSuFVc92+0AdNv4QOxRL4Abeo1DgLnGNkn1XlaujPH/3cCFz3QI60r2VNu4obJJROzgnIUw5TKQkZvZI1w==",
+      "requires": {
+        "compute-scroll-into-view": "^1.0.17"
+      }
+    },
     "select-hose": {
       "version": "2.0.0",
       "resolved": "https://registry.npm.taobao.org/select-hose/download/select-hose-2.0.0.tgz",
@@ -10120,6 +10447,47 @@
       "integrity": "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=",
       "dev": true
     },
+    "slate": {
+      "version": "0.63.0",
+      "resolved": "https://registry.npmjs.org/slate/-/slate-0.63.0.tgz",
+      "integrity": "sha512-np24XIRsGbwVgKQR6DWLorTRQD7arUKiztCKsepBNiYtMxHqjR76i2nJA6pdGn6Vj9q88Afi9eYwCsfnzy2hBA==",
+      "requires": {
+        "@types/esrever": "^0.2.0",
+        "esrever": "^0.2.0",
+        "fast-deep-equal": "^3.1.3",
+        "immer": "^8.0.1",
+        "is-plain-object": "^3.0.0",
+        "tiny-warning": "^1.0.3"
+      },
+      "dependencies": {
+        "immer": {
+          "version": "8.0.4",
+          "resolved": "https://registry.npmjs.org/immer/-/immer-8.0.4.tgz",
+          "integrity": "sha512-jMfL18P+/6P6epANRvRk6q8t+3gGhqsJ9EuJ25AXE+9bNTYtssvzeYbEd0mXRYWCmmXSIbnlpz6vd6iJlmGGGQ=="
+        },
+        "is-plain-object": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz",
+          "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g=="
+        }
+      }
+    },
+    "slate-history": {
+      "version": "0.62.0",
+      "resolved": "https://registry.npmjs.org/slate-history/-/slate-history-0.62.0.tgz",
+      "integrity": "sha512-nE3fihtHV7kUrDO3zNb+DWzQVUg59uKCZVt0r9GafZLiHB98n0X+qqtcjFHerDPDRPkHgqM8UL4wh1jhL4WzmA==",
+      "requires": {
+        "immer": "^7.0.0",
+        "is-plain-object": "^3.0.0"
+      },
+      "dependencies": {
+        "is-plain-object": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz",
+          "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g=="
+        }
+      }
+    },
     "slice-ansi": {
       "version": "2.1.0",
       "resolved": "https://registry.npm.taobao.org/slice-ansi/download/slice-ansi-2.1.0.tgz?cache=0&sync_timestamp=1618555008681&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fslice-ansi%2Fdownload%2Fslice-ansi-2.1.0.tgz",
@@ -10139,6 +10507,11 @@
         }
       }
     },
+    "snabbdom": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.1.0.tgz",
+      "integrity": "sha512-mcmPJMMKbkkPDPeCQ5D7RzqMHlLUyjl+OxOGblsutkzDbuYijCQGBOWJInjnWZ85DtoHdElrDTjA9g85s2YQ5Q=="
+    },
     "snapdragon": {
       "version": "0.8.2",
       "resolved": "https://registry.npm.taobao.org/snapdragon/download/snapdragon-0.8.2.tgz",
@@ -10491,6 +10864,11 @@
         "tweetnacl": "~0.14.0"
       }
     },
+    "ssr-window": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-3.0.0.tgz",
+      "integrity": "sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA=="
+    },
     "ssri": {
       "version": "6.0.2",
       "resolved": "https://registry.npm.taobao.org/ssri/download/ssri-6.0.2.tgz?cache=0&sync_timestamp=1617826295004&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fssri%2Fdownload%2Fssri-6.0.2.tgz",
@@ -11217,6 +11595,11 @@
       "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
       "dev": true
     },
+    "tiny-warning": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
+      "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
+    },
     "tmp": {
       "version": "0.0.33",
       "resolved": "https://registry.npm.taobao.org/tmp/download/tmp-0.0.33.tgz?cache=0&sync_timestamp=1588178571895&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftmp%2Fdownload%2Ftmp-0.0.33.tgz",
@@ -11353,6 +11736,11 @@
       "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
       "dev": true
     },
+    "type": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
+    },
     "type-check": {
       "version": "0.3.2",
       "resolved": "https://registry.npm.taobao.org/type-check/download/type-check-0.3.2.tgz",
@@ -12641,6 +13029,11 @@
       "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
       "dev": true
     },
+    "wildcard": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-1.1.2.tgz",
+      "integrity": "sha1-pwIEUwhNjNLv5wup02liY94XEKU="
+    },
     "word-wrap": {
       "version": "1.2.3",
       "resolved": "https://registry.npm.taobao.org/word-wrap/download/word-wrap-1.2.3.tgz",
@@ -12717,6 +13110,19 @@
         "async-limiter": "~1.0.0"
       }
     },
+    "xml-formatter": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.5.1.tgz",
+      "integrity": "sha512-qJwnz5uNMs4mc7jX3UH80taCK4BHnXX91MvByple+iOS2P1eNeifGAfPnKuteyHg8pehbhTBHPBunGOQ53nKdQ==",
+      "requires": {
+        "xml-parser-xo": "^3.1.2"
+      }
+    },
+    "xml-parser-xo": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-3.1.2.tgz",
+      "integrity": "sha512-Qyttmiy305unyg1ONpArT4FPDL3J+ohXWpMI1ecopClGMw53lCRHJ4FV/fVYHFU6qfEzMV0frqSlNaLo2dw15Q=="
+    },
     "xtend": {
       "version": "4.0.2",
       "resolved": "https://registry.npm.taobao.org/xtend/download/xtend-4.0.2.tgz",

+ 2 - 0
package.json

@@ -11,6 +11,8 @@
     "analyzer": "cross-env use_analyzer=true npm run serve"
   },
   "dependencies": {
+    "@wangeditor/editor": "^0.12.3",
+    "@wangeditor/editor-for-vue": "^0.6.12-1",
     "axios": "^0.19.2",
     "core-js": "^3.6.5",
     "cross-env": "^7.0.3",

+ 106 - 85
src/api/auth.js

@@ -3,128 +3,149 @@ const UserIdKey = 'userData'
 const TypesKey = 'types'
 import Vue from 'vue'
 
+// 获取唯一标识(uid)
+export function generateUUID() {
+	var d = new Date().getTime();
+	var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+		var r = (d + Math.random() * 16) % 16 | 0;
+		d = Math.floor(d / 16);
+		return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
+	});
+	return uuid;
+};
+// 获取缓存
+export function getCache(key) {
+	return JSON.parse(localStorage.getItem(key))
+}
+// 设置缓存
+export function setCache(key, data) {
+	localStorage.setItem(key, JSON.stringify(data))
+}
+// 清除缓存
+export function removeCache(key) {
+	localStorage.removeItem(key)
+}
 
 function getClass(o) { //判断数据类型
-    return Object.prototype.toString.call(o).slice(8, -1);
+	return Object.prototype.toString.call(o).slice(8, -1);
 }
 
-function deepCopy(obj) {//深度拷贝对象
-    var result, oClass = getClass(obj);
-    if (oClass == "Object") result = {}; //判断传入的如果是对象,继续遍历
-    else if (oClass == "Array") result = []; //判断传入的如果是数组,继续遍历
-    else return obj; //如果是基本数据类型就直接返回
-    for (var i in obj) {
-        var copy = obj[i];
-        if (getClass(copy) == "Object"||getClass(copy) == "Array") result[i] = deepCopy(copy); //递归方法 ,如果对象继续变量obj[i],下一级还是对象,就obj[i][i]
-        // else if (getClass(copy) == "Array") result[i] = deepCopy(copy); //递归方法 ,如果对象继续数组obj[i],下一级还是数组,就obj[i][i]
-        else result[i] = copy; //基本数据类型则赋值给属性
-    }
-    return result;
+function deepCopy(obj) { //深度拷贝对象
+	var result, oClass = getClass(obj);
+	if (oClass == "Object") result = {}; //判断传入的如果是对象,继续遍历
+	else if (oClass == "Array") result = []; //判断传入的如果是数组,继续遍历
+	else return obj; //如果是基本数据类型就直接返回
+	for (var i in obj) {
+		var copy = obj[i];
+		if (getClass(copy) == "Object" || getClass(copy) == "Array") result[i] = deepCopy(
+		copy); //递归方法 ,如果对象继续变量obj[i],下一级还是对象,就obj[i][i]
+		// else if (getClass(copy) == "Array") result[i] = deepCopy(copy); //递归方法 ,如果对象继续数组obj[i],下一级还是数组,就obj[i][i]
+		else result[i] = copy; //基本数据类型则赋值给属性
+	}
+	return result;
 }
 
 export function openError(data) {
-    if(process.env.NODE_ENV=='production'){
-          Vue.prototype.$axios('post','/api/e',data)
-    }
+	if (process.env.NODE_ENV == 'production') {
+		Vue.prototype.$axios('post', '/api/e', data)
+	}
 }
-export function getUserData () {
-    return JSON.parse(localStorage.getItem(UserIdKey)); 
+export function getUserData() {
+	return JSON.parse(localStorage.getItem(UserIdKey));
 }
-export function setUserData (data) {
-     localStorage.setItem(UserIdKey,JSON.stringify(data))
+export function setUserData(data) {
+	localStorage.setItem(UserIdKey, JSON.stringify(data))
 }
 // 获取积分类型
-export function getTyps (id) {
-	 if(id){
-		 var arr=JSON.parse(localStorage.getItem(TypesKey));
-		 var item=arr.filter(element => {
-		       return  typeof(id)=='string'?element.code==id:element.id==id
-		 });
-		 return item[0]
-	 }else{
-		 return JSON.parse(localStorage.getItem(TypesKey));
-	 }
+export function getTyps(id) {
+	if (id) {
+		var arr = JSON.parse(localStorage.getItem(TypesKey));
+		var item = arr.filter(element => {
+			return typeof(id) == 'string' ? element.code == id : element.id == id
+		});
+		return item[0]
+	} else {
+		return JSON.parse(localStorage.getItem(TypesKey));
+	}
 }
 // 获取积分类型名称
-export function getTypsName (id) {
+export function getTypsName(id) {
 	return getTyps(id).name
 }
 // 判断是否创始人
-export function getIsCreator (key) {
-	 let is=false;
-	 getUserData().employee_detail.role_list.forEach(item=>{ 
-		 if(key==item.name){
-			 is=true;
-		 }
-	 })
-	 return is
+export function getIsCreator(key) {
+	let is = false;
+	getUserData().employee_detail.role_list.forEach(item => {
+		if (key == item.name) {
+			is = true;
+		}
+	})
+	return is
 }
 
-export function supremeAuthority () {//获取当前角色最高权限     判断是否为某项权限:this.$authoritys('dept_manager') 或 this.$supremeAuthority() == 'dept_manager'
-	if(getIsCreator('creator')){
+export function supremeAuthority() { //获取当前角色最高权限     判断是否为某项权限:this.$authoritys('dept_manager') 或 this.$supremeAuthority() == 'dept_manager'
+	if (getIsCreator('creator')) {
 		return 'creator'
-	}else if(getIsCreator('admin')){
+	} else if (getIsCreator('admin')) {
 		return 'admin'
-	}else if(getIsCreator('point_manager')){
+	} else if (getIsCreator('point_manager')) {
 		return 'point_manager'
-	}else if(getIsCreator('dept_manager')){
+	} else if (getIsCreator('dept_manager')) {
 		return 'dept_manager'
-	}else if(getIsCreator('employee')){
+	} else if (getIsCreator('employee')) {
 		return 'employee'
 	}
 }
-export function authoritys (key) {//判断是否为某项权限:this.$authoritys('dept_manager')
+export function authoritys(key) { //判断是否为某项权限:this.$authoritys('dept_manager')
 	return supremeAuthority() == key
 }
 //过滤绩效分
- function GlTypes(arr){
-	return arr.filter(function(item){
-		return item.code!='JX'
+function GlTypes(arr) {
+	return arr.filter(function(item) {
+		return item.code != 'JX'
 	})
 }
-export function setTyps (data) {
-    var arr=GlTypes(data);
-    localStorage.setItem(TypesKey,JSON.stringify(arr))
+export function setTyps(data) {
+	var arr = GlTypes(data);
+	localStorage.setItem(TypesKey, JSON.stringify(arr))
 }
 
-export function getToken () {
-    return localStorage.getItem(TokenKey)
+export function getToken() {
+	return localStorage.getItem(TokenKey)
 }
 
-export function setToken (token) {
-     localStorage.setItem(TokenKey, token)
+export function setToken(token) {
+	localStorage.setItem(TokenKey, token)
 }
 
 // 防抖
-export function _debounce (fn, delay=500) {
-    let timer = null
-    return function () {
-        let arg = arguments
-        clearTimeout(timer)
-        timer = setTimeout(() => {
-            fn.apply(this, arg)
-        }, delay)
-    }
+export function _debounce(fn, delay = 500) {
+	let timer = null
+	return function() {
+		let arg = arguments
+		clearTimeout(timer)
+		timer = setTimeout(() => {
+			fn.apply(this, arg)
+		}, delay)
+	}
 }
 // 节流
-export function _throttle(fn, interval=500) {
-  var last;
-  var timer;
-  return function() {
-    var th = this;
-    var args = arguments;
-    var now = +new Date();
-    if (last && now - last < interval) {
-      clearTimeout(timer);
-      timer = setTimeout(function() { //用户最后一次点击时间间隔小于设置时间执行
-        last = now;
-        fn.apply(th, args);
-      }, interval);
-    } else {
-      last = now;
-      fn.apply(th, args);
-    }
-  }
+export function _throttle(fn, interval = 500) {
+	var last;
+	var timer;
+	return function() {
+		var th = this;
+		var args = arguments;
+		var now = +new Date();
+		if (last && now - last < interval) {
+			clearTimeout(timer);
+			timer = setTimeout(function() { //用户最后一次点击时间间隔小于设置时间执行
+				last = now;
+				fn.apply(th, args);
+			}, interval);
+		} else {
+			last = now;
+			fn.apply(th, args);
+		}
+	}
 }
-
-

+ 87 - 81
src/api/websocket.js

@@ -1,95 +1,101 @@
-let Socket = ''
-let setIntervalWesocketPush = null
+// let wsurl = 'ws://113.99.163.45:12358'
+let wsurl='wss://' + process.env.VUE_APP_WEBSCOKET + '/ws/';
+let ws = null
+let weboscket_callback = null
+import {getToken,generateUUID } from '@/api/auth';
+import {Message} from 'element-ui'
 
-/**
- * 建立websocket连接
- * @param {string} url ws地址
- */
-export const createSocket = url => {
-  Socket && Socket.close()
-  if (!Socket) {
-    console.log('建立websocket连接')
-    Socket = new WebSocket(url)
-    Socket.onopen = onopenWS
-    Socket.onmessage = onmessageWS
-    Socket.onerror = onerrorWS
-    Socket.onclose = oncloseWS
-  } else {
-    console.log('websocket已连接')
-  }
+//获取 websocket 推送的数据
+let websocketonmessage = e => {
+	let data=JSON.parse(e.data)
+	if(data.type=="ping"){
+		if(ws){
+			ws.send('保持连接')
+		}
+	}
+	return weboscket_callback(data);
 }
 
-/**打开WS之后发送心跳 */
-const onopenWS = () => {
-  sendPing()
+// 连接成功
+let websocketonopen = () => {
+	console.log('websocket 成功')
 }
 
-/**连接失败重连 */
-const onerrorWS = () => {
-  Socket.close()
-  clearInterval(setIntervalWesocketPush)
-  console.log('连接失败重连中')
-  if (Socket.readyState !== 3) {
-    Socket = null
-    createSocket()
-  }
+// 连接失败时重新连接
+let websocketonerror = () => {
+	Message({
+		message: '服务器繁忙,请稍后再试',
+		type: 'error',
+	})
+	weboscket_callback({type:'error',msg:'服务器繁忙,请稍后再试'})
+	// initWebSocket()
 }
 
-/**WS数据接收统一处理 */
-const onmessageWS = e => {
-  window.dispatchEvent(new CustomEvent('onmessageWS', {
-    detail: {
-      data: e.data
-    }
-  }))
+// 断开链接后报错
+let websocketclose = e => {
+	if(!e.wasClean){//当网络中断时处理
+		Message({
+			message: '网络连接失败,请稍后再试',
+			type: 'error',
+		})
+		weboscket_callback({type:'break',msg:'网络连接失败,请稍后再试'})
+		closewebsocket();
+	}
 }
 
-/**
- * 发送数据但连接未建立时进行处理等待重发
- * @param {any} message 需要发送的数据
- */
-const connecting = message => {
-  setTimeout(() => {
-    if (Socket.readyState === 0) {
-      connecting(message)
-    } else {
-      Socket.send(JSON.stringify(message))
-    }
-  }, 1000)
+// 手动关闭 websocket
+let closewebsocket = () => {
+	if(ws){
+		console.log('websocket 关闭')
+		ws.close()
+		ws=null;
+	}
 }
 
-/**
- * 发送数据
- * @param {any} message 需要发送的数据
- */
-export const sendWSPush = message => {
-  if (Socket !== null && Socket.readyState === 3) {
-    Socket.close()
-    createSocket()
-  } else if (Socket.readyState === 1) {
-    Socket.send(JSON.stringify(message))
-  } else if (Socket.readyState === 0) {
-    connecting(message)
-  }
+let initWebSocket = () => {
+	//初始化 websocket
+	ws = new WebSocket(wsurl)
+	ws.onmessage = websocketonmessage
+	ws.onopen = websocketonopen
+	ws.onerror = websocketonerror
+	ws.onclose = websocketclose
 }
 
-/**断开重连 */
-const oncloseWS = () => {
-  clearInterval(setIntervalWesocketPush)
-  console.log('websocket已断开....正在尝试重连')
-  if (Socket.readyState !== 2) {
-    Socket = null
-    createSocket()
-  }
+// 发送数据
+let sendData = (data, callback) => {
+	weboscket_callback = callback
+	//  判断 data 数据类型
+	if (typeof data == 'string') {
+		data = data
+	} else {
+		data = JSON.stringify(data)
+	}
+	if(ws){//  判断 websocket 的状态
+		if (ws.readyState === ws.OPEN) {// 已经打开,可以直接发送
+			console.log("1")
+			ws.send(data)
+		} else if (ws.readyState === ws.CONNECTING) {// 正在开启状态中,则 1 秒后重新发送
+			console.log("2")
+			setTimeout(() => {
+				ws.send(data)
+			}, 2000)
+		}
+	}else {
+		// 未打开,则开启后重新调用
+		initWebSocket()
+		let wsData = {
+			type: 'auth',
+			token: getToken(),
+			machine:generateUUID()
+		};
+		sendData(wsData, callback)
+		sendData(data, callback)
+	}
+}
+
+// 导出
+export {
+	initWebSocket,
+	sendData,
+	closewebsocket
 }
-/**发送心跳
- * @param {number} time 心跳间隔毫秒 默认5000
- * @param {string} ping 心跳名称 默认字符串ping
- */
-export const sendPing = (time = 5000, ping = 'ping') => {
-  clearInterval(setIntervalWesocketPush)
-  Socket.send(ping)
-  setIntervalWesocketPush = setInterval(() => {
-    Socket.send(ping)
-  }, time)
-}

+ 33 - 18
src/assets/css/iconfont.css

@@ -1,47 +1,62 @@
 @font-face {
-  font-family: "iconfont"; /* Project id 2916418 */
-  src: url('iconfont.woff2?t=1636076701689') format('woff2'),
-       url('iconfont.woff?t=1636076701689') format('woff'),
-       url('iconfont.ttf?t=1636076701689') format('truetype');
+	font-family: "iconfont";
+	/* Project id 2916418 */
+	src: url('iconfont.woff2?t=1637991685964') format('woff2'),
+		url('iconfont.woff?t=1637991685964') format('woff'),
+		url('iconfont.ttf?t=1637991685964') format('truetype');
 }
 
 .iconfont {
-  font-family: "iconfont" !important;
-  font-size: 26px;
-  font-style: normal;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
+	font-family: "iconfont" !important;
+	font-size: 26px;
+	font-style: normal;
+	-webkit-font-smoothing: antialiased;
+	-moz-osx-font-smoothing: grayscale;
 }
-
 .titleIcon{
 	color: #99A9BF !important;
 }
 
+.icon-shezhi_jichushezhi:before {
+	content: "\e70c";
+}
+
+.icon-shezhi_jiaose:before {
+	content: "\e70f";
+}
+
+.icon-shezhi_zidongjifen:before {
+	content: "\e710";
+}
+
+.icon-shezhi_zuzhijiagou:before {
+	content: "\e711";
+}
+
 .icon-fulizhongxin:before {
-  content: "\e652";
+	content: "\e652";
 }
 
 .icon-kaoqin_kaoqinyuebaobiao:before {
-  content: "\e708";
+	content: "\e708";
 }
 
 .icon-shezhi_jifenguize:before {
-  content: "\e70d";
+	content: "\e70d";
 }
 
 .icon-PC_gongzuotai_ABfen:before {
-  content: "\e71d";
+	content: "\e71d";
 }
 
 .icon-dingdingPC_shezhi1:before {
-  content: "\e725";
+	content: "\e725";
 }
 
 .icon-dingdingPC_tongji1:before {
-  content: "\e726";
+	content: "\e726";
 }
 
 .icon-shouye:before {
-  content: "\e639";
+	content: "\e639";
 }
-

File diff suppressed because it is too large
+ 0 - 0
src/assets/css/iconfont.js


+ 28 - 0
src/assets/css/iconfont.json

@@ -5,6 +5,34 @@
   "css_prefix_text": "icon-",
   "description": "",
   "glyphs": [
+    {
+      "icon_id": "15023955",
+      "name": "设置_基础设置",
+      "font_class": "shezhi_jichushezhi",
+      "unicode": "e70c",
+      "unicode_decimal": 59148
+    },
+    {
+      "icon_id": "15023958",
+      "name": "设置_角色",
+      "font_class": "shezhi_jiaose",
+      "unicode": "e70f",
+      "unicode_decimal": 59151
+    },
+    {
+      "icon_id": "15023959",
+      "name": "设置_自动积分",
+      "font_class": "shezhi_zidongjifen",
+      "unicode": "e710",
+      "unicode_decimal": 59152
+    },
+    {
+      "icon_id": "15023960",
+      "name": "设置_组织架构",
+      "font_class": "shezhi_zuzhijiagou",
+      "unicode": "e711",
+      "unicode_decimal": 59153
+    },
     {
       "icon_id": "12097436",
       "name": "福利中心",

BIN
src/assets/css/iconfont.ttf


BIN
src/assets/css/iconfont.woff


BIN
src/assets/css/iconfont.woff2


+ 35 - 0
src/assets/css/reset.css

@@ -26,6 +26,9 @@ table { border-collapse:collapse; border-spacing:0; }
   fill: currentColor;
   overflow: hidden;
 }
+.boxMinHeight{
+  min-height: calc(100vh - 110px);
+}
 
 .el-form-item__content{
 	line-height:36px !important;
@@ -294,4 +297,36 @@ table { border-collapse:collapse; border-spacing:0; }
   white-space: initial;
   overflow: initial;
   text-overflow: initial;
+}
+/* // 滚动条样式 */
+.scroll-bar{
+  scroll-behavior: smooth
+}
+.scroll-bar::-webkit-scrollbar {
+  width: 6px;
+  height: 6px;
+}
+
+/*外层轨道。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果*/
+.scroll-bar::-webkit-scrollbar-track {
+  width: 6px;
+  background-color: #fff0;
+  -webkit-border-radius: 2em;
+  -moz-border-radius: 2em;
+  border-radius: 2em;
+
+}
+
+/*滚动条的设置*/
+.scroll-bar::-webkit-scrollbar-thumb {
+  background-color: #fff0;
+  background-clip: padding-box;
+  -webkit-border-radius: 2em;
+  -moz-border-radius: 2em;
+  border-radius: 2em;
+}
+/*滚动条移上去的背景*/
+.scroll-bar:hover::-webkit-scrollbar-thumb {
+  background-color: rgba(144, 147, 153, 0.3);
+  height: 20px;
 }

+ 4 - 5
src/components/EmployeeSelector.vue

@@ -452,12 +452,11 @@ export default {
 		}
 	},
 	created() {
-		var that = this;
-		that.checked = false;
+		this.checked = false;
 		setTimeout(() => {
-			that.get_user_list();
-			if (that.can_select_dept) {
-				that.get_dept_list();
+			this.get_user_list();
+			if (this.can_select_dept) {
+				this.get_dept_list();
 			}
 		}, 200);
 	}

+ 268 - 0
src/components/Suggest.vue

@@ -0,0 +1,268 @@
+<template>
+	<el-dialog title="添加公告" :visible.sync="visible_" :close-on-click-modal="false" :before-close="close_before" append-to-body width="640px" top="5%">
+		<el-form ref="dialogData" label-width="100px" class="form">
+			<el-form-item label="公告标题" :rules="[{ required: true, message: '请输入公告标题', trigger: 'blur' }]">
+				<el-input type="text" v-model="params.name" placeholder="请输入公告标题" maxlength="30" show-word-limit></el-input>
+			</el-form-item>
+			<div style="border: 1px solid #ccc;margin-bottom: 20px;" v-if="visible_">
+				<!-- 工具栏 -->
+				<Toolbar style="border-bottom: 1px solid #ccc" :editorId="editorId" :defaultConfig="toolbarConfig"/>
+				<!-- 编辑器 -->
+				<Editor style="height: 300px" :editorId="editorId" :defaultConfig="editorConfig" :defaultContent="getDefaultContent" @onChange="onChange" />
+			</div>
+			<el-form-item label="图片">
+				<uploadOss
+					:headers="Xtoken"
+					:action="'https://' + 'integralsys.oss-cn-shenzhen.aliyuncs.com'"
+					:show-file-list="true"
+					:file-list="img_fileList"
+					:on-success="handleFilesSuccess"
+					:on-preview="onFilePreView"
+					:before-upload="beforeUpload"
+					:on-remove="onFileRemove"
+					:limit="1"
+					:multiple="true"
+				>
+					<el-button type="primary" size="small">点击上传</el-button>
+					(最多选择1张)
+				</uploadOss>
+			</el-form-item>
+		</el-form>
+		<span slot="footer" class="dialog-footer">
+			<el-button @click="close">取 消</el-button>
+			<el-button type="primary" @click="confirm">确 定</el-button>
+		</span>
+	</el-dialog>
+</template>
+
+<script>
+import uploadOss from '@/components/upload';
+import { Editor, Toolbar, getEditor, removeEditor, createEditor } from '@wangeditor/editor-for-vue';
+import cloneDeep from 'lodash.clonedeep';
+import { getToken } from '@/api/auth';
+export default {
+	name: 'Suggest',
+	components: { uploadOss, Editor, Toolbar },
+	props: {
+		isAdd: {
+			type: Boolean,
+			default: true
+		},
+		visible: {
+			// 是否显示组件
+			type: Boolean,
+			default: false
+		},
+		detaliData:{
+			type: Object,
+			default:()=>{
+				return {}
+			}
+		}
+	},
+	data() {
+		return {
+			Xtoken: { 'X-Token': getToken() },
+			visible_: false,
+			// 建议
+			img_fileList: [], // 图片附件
+			save_loading: false,
+			params: {
+				name: '',
+				html: '',
+				content: '',
+				file_list: [],
+				// tag: ['福利']
+			},
+
+			// 富文本
+			editorId: 'wangEditor-1', // 定义一个编辑器 id ,要求:全局唯一且不变。重要!!!
+			defaultContent: [], // 编辑器的默认内容,只在初始化时使用
+			latestContent: [], // 用于存储编辑器最新的内容,onChange 时修改
+			toolbarConfig: {
+				mode: 'simple',
+				toolbarKeys: [
+					'headerSelect', // 分割线
+					'|',
+					'bold',
+					'italic',
+					'underline',
+					'through',
+					'color',
+					'bgColor',
+					'indent',
+					'justifyLeft',
+					'justifyRight',
+					'justifyCenter',
+					'justifyJustify',
+					'bulletedList',
+					'numberedList',
+					'clearStyle'
+				]
+			},
+			editorConfig: {
+				placeholder: '请输入内容...'
+			}
+		};
+	},
+	computed: {
+		// <!-- 注意,这里使用 computed 的结果 -->
+		getDefaultContent() {
+			return cloneDeep(this.defaultContent); // 深拷贝,重要!!!
+		}
+	},
+	watch: {
+		visible(val) {
+			if(!this.isAdd&&val){
+				let detaliData=this.detaliData;
+				if(detaliData.content.content){
+					this.defaultContent=JSON.parse(detaliData.content.content);
+					if(detaliData.file_list){
+						this.img_fileList=[{name:'图片',url:detaliData.file_list}]
+						this.params.file_list=[detaliData.file_list]
+					}
+					
+				}
+				this.params.name=detaliData.name
+			}
+			this.visible_ = JSON.parse(JSON.stringify(val));
+		}
+	},
+	methods: {
+		onChange(editor) {
+			this.params.content = editor.children;
+			this.params.html = editor.getHtml();
+		},
+		// 图片上传
+		beforeUpload(file) {
+			const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
+			const isLt2M = file.size / 1024 / 1024 < 2;
+			if (!isJPG) {
+				this.$message.error('上传图片只能是 jpeg|png|jpg 格式!');
+			}
+			if (!isLt2M) {
+				this.$message.error('上传图片大小不能超过 2MB!');
+			}
+			return isJPG && isLt2M;
+		},
+		onFilePreView(file) {
+			window.open(file.url, '_blank');
+		},
+		onFileRemove(file, fileList) {
+			this.img_fileList = fileList;
+			let imgs = [];
+			fileList.forEach((element, index) => {
+				imgs.push(element.url);
+			});
+			this.params.file_list = imgs;
+		},
+		handleFilesSuccess(response, file, fileList) {
+			this.img_fileList = fileList;
+			let imgs = [];
+			fileList.forEach((element, index) => {
+				imgs.push(element.url);
+			});
+			this.params.file_list = imgs;
+		},
+
+		// 确定
+		confirm() {
+			if (!this.params.name) {
+				this.$message.error('请填写标题');
+				return false;
+			}
+			this.params.content=JSON.stringify(this.params.content)
+			if(!this.isAdd){
+				this.params.id=this.detaliData.id;
+				this.$axios('post','/api/information/update',this.params).then(res => {
+						this.$message.success('发布成功');
+						this.$parent.noticeList();
+						this.close();
+				})
+			}else{
+				this.$axios('post','/api/information/create',this.params).then(res => {
+						this.$message.success('发布成功');
+						this.$parent.noticeList();
+						this.close();
+				})
+			}
+		},
+		close_before(done) {
+			this.close();
+			done();
+		},
+		close() {
+			this.img_fileList=[];
+			this.defaultContent=[];
+			this.params={
+				name: '',
+				html: '',
+				content: '',
+				file_list: [],
+			};
+			this.beforeDestroys();
+			this.$emit('update:visible', false);
+		},
+		beforeDestroys() {
+			const editor = getEditor(this.editorId);
+			if (editor == null) return;
+			editor.destroy(); // 组件销毁时,及时销毁编辑器 ,重要!!!
+			removeEditor(this.editorId);
+		}
+	},
+};
+</script>
+<style src="@wangeditor/editor/dist/css/style.css"></style>
+<style scoped="scoped" lang="scss">
+/* 表格 */
+table {
+	border-collapse: collapse;
+}
+table th,
+table td {
+	border: 1px solid #ccc;
+	min-width: 50px;
+	height: 20px;
+	text-align: left;
+}
+table th {
+	background-color: #f1f1f1;
+	text-align: center;
+}
+
+/* 代码块 */
+pre > code {
+	display: block;
+	border: 1px solid hsl(0, 0%, 91%);
+	border-radius: 4px 4px;
+	text-indent: 0;
+	background-color: #fafafa;
+	padding: 10px;
+	font-size: 14px;
+}
+
+/* 引用 */
+blockquote {
+	display: block;
+	border-left: 8px solid #d0e5f2;
+	padding: 10px 10px;
+	margin: 10px 0;
+	background-color: #f1f1f1;
+}
+
+/* 列表 */
+ul,
+ol {
+	margin: 10px 0 10px 20px;
+}
+
+/* 分割线 */
+hr {
+	display: block;
+	width: 90%;
+	margin: 20px auto;
+	border: 0;
+	height: 1px;
+	background-color: #ccc;
+}
+</style>

+ 207 - 27
src/components/applicationIntegrationPopup.vue

@@ -152,14 +152,6 @@
 		<el-dialog :title="'提交结果'" :visible.sync="error_list_show" :before-close="closeDialog2" :append-to-body="true" width="700px">
 			<el-table :data="error_list">
 				<el-table-column prop="target" label="员工"></el-table-column>
-<!-- 				<el-table-column prop="point" label="积分">
-					<template slot-scope="scope">
-						<span>
-							{{ scope.row.point }}
-							<span>{{ integralType == 2 ? 'A分' : 'B分' }}</span>
-						</span>
-					</template>
-				</el-table-column> -->
 				<el-table-column prop="status" label="处理状态">
 					<template slot-scope="scope">
 						<span :style="'color:' + (scope.row.status == 0 ? '#f70000' : '#47bf47')">{{ scope.row.status == 0 ? '申请失败' : '申请成功' }}</span>
@@ -168,6 +160,84 @@
 				<el-table-column prop="remark" label="备注信息"></el-table-column>
 			</el-table>
 		</el-dialog>
+		
+		<el-dialog title="提交结果" :visible.sync="isResult"  width="800" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
+			<div class="" v-if="!isShowError">
+				<div style="text-align: center;margin-bottom: 10px;" class="red" v-if="isShowError2">{{errorMsg}}</div>
+				<el-progress :text-inside="true" :stroke-width="24" :percentage="percentage"></el-progress>
+				<div style="margin-top: 20px;border: 1px solid #f1f1f1;">
+					<div class="flex-box-ce results" style="font-weight: 600;">
+						<div  style="border-right: 1px solid #f1f1f1;width: 50px;">序号</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">奖扣对象</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">申请内容</div>
+						<!-- <div class="flex-1" style="border-right: 1px solid #f1f1f1;">积分</div> -->
+						<div class="flex-2" >处理结果</div>
+					</div>
+					<div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
+						<div  style="border-right: 1px solid #f1f1f1;width: 50px;">{{results.length-index}}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.target }}</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.remark }}</div>
+<!-- 						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">
+						    {{ item.point>0? '+'+item.point:item.point }} 
+							<span>{{ item.task.msg.pt_id==3? 'B分':'A分' }}</span>
+						</div> -->
+						<div class="flex-2 green" v-if="item.status == 1">{{ item.msg }}</div>
+						<div class="flex-2 red" v-else>{{ item.msg }}</div>
+					</div>
+				</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;" v-show="isShowError2&&results.length!=resultList.length"><el-button type="primary" @click="isResult = false" size="small">确 定</el-button></div>
+					<div class="flex-box-end" style="margin-top: 20px;" v-show="results.length==resultList.length">
+						<el-button type="primary" @click="isResult = false" size="small">确 定</el-button>
+					</div>
+				</span>
+			</div>
+			<div v-else>
+				<div style="text-align: center;" class="red">{{errorMsg}}</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;"><el-button type="primary" @click="isResult = false" size="small">确 定</el-button></div>
+				</span>
+			</div>
+		</el-dialog>
+		
+		<!-- 缓存的奖扣 -->
+		<el-dialog title="网络中断申请列表" :visible.sync="isShowBreak"  width="800" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
+			<div>
+				<div style="margin-top: 20px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
+					<div class="flex-box-ce results" style="font-weight: 600;">
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">奖扣对象</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">分类</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">规则</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">事件内容</div>
+						<!-- <div class="flex-1" style="border-right: 1px solid #f1f1f1;">积分</div> -->
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">递交人员</div>
+					</div>
+					<div class="flex-box-ce results" v-for="(item, index) in breakList" :key="index">
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.name }}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">
+							<span v-if="item.rule_name">{{ item.rule_name }}</span>
+							<span v-else>--</span>
+						</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">
+							<span v-if="item.item_name">{{ item.item_name }}</span>
+							<span v-else>--</span>
+						</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.remark }}</div>
+<!-- 						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.point }} 
+							<span>{{ item.pt_id==3? 'B分':'A分' }}</span>
+						</div> -->
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.reviewer_name }}</div>
+					</div>
+				</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;">
+						<el-button type="primary" @click="colseBreak()" size="small">取 消</el-button>
+						<el-button type="primary" @click="submitBreak()" size="small">再次提交</el-button>
+					</div>
+				</span>
+			</div>
+		</el-dialog>
+	
 	</div>
 </template>
 
@@ -175,7 +245,7 @@
 import moment from 'moment';
 import EmployeeSelector from '@/components/EmployeeSelector';
 import uploadOss from '@/components/upload';
-
+import {setCache,getCache,removeCache} from '@/api/auth';
 export default {
 	name: 'applicationIntegration',
 	// 数据
@@ -192,6 +262,10 @@ export default {
 			type: Boolean,
 			default: false
 		},
+		isBreak: { //是否打开缓存的未完成奖扣
+			type: Boolean,
+			default: false
+		},
 		integralType: {
 			type: Number,
 			default: 0
@@ -255,18 +329,27 @@ export default {
 			btn_loading: false,
 			itemIndex: 0,
 			fullscreenLoading: false, //选择审批人时需要,获取录入对象的上级
-			LocalValObj: { id: '', name: '' } //当前录入的审批人缓存
+			LocalValObj: { id: '', name: '' } ,//当前录入的审批人缓存
+			
+			// 长连接结果
+			results: [], //提交的返回结果集合
+			isResult: false,
+			percentage: 0,
+			resultList:[],//要发送数据的集合
+			resultIndex:0,
+			isShowError:false,
+			isShowError2:false,
+			errorMsg:'服务器繁忙,请稍后再试',
+			breakList:[],
+			isShowBreak:false,
 		};
 	},
 	components: { EmployeeSelector, uploadOss },
-	created() {
-	},
 	async mounted() {
 		this.user_info = this.$getUserData();
 		var reviewerObj = await this.getLocalVal(this.user_info.id);
 		var res = reviewerObj ? reviewerObj : { id: '', name: '' };
 		this.LocalValObj = res;
-
 		this.getRuleItemData();
 		// 初始化审批人
 		if (this.LocalValObj.id) {
@@ -274,8 +357,49 @@ export default {
 			this.dialogData.items[0].reviewer_id = this.LocalValObj.id;
 			this.dialogData.items[0].approvalName = this.LocalValObj.name;
 		}
+		if(this.isBreak){
+			let data=getCache('apply_list');
+			data.forEach(item=>{
+				item.name=getCache('userList')[item.employee_id]?getCache('userList')[item.employee_id].name:'--';
+				item.reviewer_name=getCache('userList')[item.reviewer_id]?getCache('userList')[item.reviewer_id].name:'--';
+			})
+			this.breakList=data;
+			this.isShowBreak=true;
+		}
+	},
+	watch:{
+		isResult(val){
+			if(!val){
+				this.isShowError=false;
+				this.isShowBreak = false;
+				this.errorMsg='服务器繁忙,请稍后再试';
+				this.$refs['dialogData'].resetFields();
+				this.closeDialog();
+				this.closeDialog2();
+				this.$socketApi.closewebsocket();
+			}
+		}
 	},
 	methods: {
+		// 关闭缓存弹窗
+		colseBreak(){
+			this.isShowBreak = false;
+			this.breakList=[];
+			removeCache('apply_list');
+			this.closeDialog();
+			this.closeDialog2();
+		},
+		// 提交缓存申请
+		submitBreak(){
+			removeCache('apply_list');
+			this.resultList=JSON.parse(JSON.stringify(this.breakList));
+			this.resultIndex=0;
+			this.percentage=0;
+			this.results=[];
+			this.isResult=true;
+			this.opneWebSocket()
+		},
+		
 		//获取缓存起来的审批人
 		getLocalVal(id) {
 			return new Promise((resolve, reject) =>{
@@ -313,7 +437,7 @@ export default {
 			const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
 			const isLt2M = file.size / 1024 / 1024 < 1;
 			if (!isJPG) {
-				this.$message.error('上传头像图片只能是 JPG 格式!');
+				this.$message.error('上传头像图片只能是 JPEG,PNG,JPG 格式!');
 			}
 			if (!isLt2M) {
 				this.$message.error('上传头像图片大小不能超过 2MB!');
@@ -404,21 +528,20 @@ export default {
 				item.rule_item_details = ruleItemDetail;
 				item.remark = ruleItemDetail.name;
 				item.rule_id = ruleItemDetail.pid;
+				item.pt_id = ruleItemDetail.pt_id;
 				item.item_id = value[value.length - 1];
+				item.item_name = ruleItemDetail.name;
 				this.$refs.ruleItem.dropDownVisible = false;
 			}else{
 				item.rule_id = '';
+				item.pt_id="";
 				item.item_id = '';
 				item.remark =  '';
+				item.item_name =  '';
 				item.rule_item_list_value = '';
 				item.rule_item_details = { range_type: '' };
 			}	
 		},
-		// 规则分类变化关闭dewn
-		ruleChange(value) {
-			this.dialogData.items[this.itemIndex].rule_id = value[value.length - 1];
-			this.$refs.rule.dropDownVisible = false;
-		},
 		// 递归判断列表,把最后的child设为undefined
 		getTreeData(data) {
 			for (var i = 0; i < data.length; i++) {
@@ -474,13 +597,13 @@ export default {
 		},
 		// 加一条
 		addItem() {
-			if(this.dialogData.items.length==10){
-				this.$message({
-					type:"warning",
-					message: '一次只能添加10条申请'
-				});
-				return false
-			}
+			// if(this.dialogData.items.length==10){
+			// 	this.$message({
+			// 		type:"warning",
+			// 		message: '一次只能添加10条申请'
+			// 	});
+			// 	return false
+			// }
 			this.dialogData.items.push({
 				rule_switch: true,
 				rule_id: '',
@@ -558,7 +681,6 @@ export default {
 		subData(formName) {
 			this.$refs[formName].validate(valid => {
 				if (valid) {
-					this.btn_loading = true;
 					this.save();
 				}
 			});
@@ -574,6 +696,7 @@ export default {
 					rule_id: element.rule_id || 0,
 					employee_id: element.employee_id,
 					item_id: element.item_id || 0,
+					item_name: element.item_name,
 					remark: element.remark,
 					event_time: element.event_time,
 					pt_id: element.pt_id,
@@ -582,6 +705,10 @@ export default {
 					files: element.files
 				});
 			});
+			this.webSocket(data);
+			// 走长连接处理
+			return false;
+			this.btn_loading = true;
 			this.$axios('post', '/api/integral/review/apply', data)
 				.then(res => {
 					if (res.data.code == 1) {
@@ -597,6 +724,52 @@ export default {
 					});
 				});
 		},
+		webSocket(data){
+			data.items.forEach(item=>{
+				item.type='point_apply';
+				localStorage.setItem(item.employee_id, JSON.stringify({ id: item.reviewer_id, name: item.approvalName }));
+			})
+			this.resultList=data.items;
+			this.resultIndex=0;
+			this.percentage=0;
+			this.results=[];
+			this.isResult=true;
+			this.opneWebSocket()
+		},
+		opneWebSocket() {
+			let wsData=this.resultList;
+			if(wsData[this.resultIndex]){
+				this.$socketApi.sendData(wsData[this.resultIndex],this.onmessageWS)
+			}else{
+				console.log(this.results)
+			}
+			
+		},
+		onmessageWS(e){
+			if(e.type=='point_apply'){
+				this.results.push(e.result);
+				this.resultIndex++;
+				this.opneWebSocket();
+				// 进度条
+				let lng = this.resultList.length;
+				this.percentage += Math.floor(100 / lng);
+				if (lng == this.results.length) {
+					this.percentage = 100;
+				}
+			}
+			// 中途断开
+			if(e.type=='break'){
+				let wsData=this.resultList;
+				this.errorMsg=e.msg
+				setCache('apply_list',wsData.slice(this.resultIndex,wsData.length));
+				this.isShowError2 = true;
+			}
+			// 连接不上
+			if(e.type=='error'){
+				this.errorMsg=e.msg
+				this.isShowError = true;
+			}
+		},
 		// 当switch 改变了
 		switchChange(index, value) {
 			this.itemIndex = index;
@@ -638,4 +811,11 @@ export default {
 		text-overflow: initial;
 	}
 }
+.results {
+	border-bottom: 1px solid #f1f1f1;
+	text-align: center;
+}
+.results div {
+	padding: 10px;
+}
 </style>

+ 213 - 25
src/components/bonusPointsPopup.vue

@@ -30,7 +30,7 @@
 						>
 							<el-cascader
 								v-model="item.rule_list_value"
-								ref="ruleCascader"
+								:ref="'ruleCascader'+index"
 								:popper-class="'ruleClass'"
 								filterable
 								clearable
@@ -158,7 +158,7 @@
 					:isChecKedAll="false"
 					:isCreatorSelect="true"
 					:user_no_select="false"
-					:max="10"
+					:max="30"
 					:employee_list="manage_scope"
 					:selected="employee_selected"
 					@confirm="move_employee_confirm"
@@ -189,6 +189,85 @@
 				<el-table-column prop="remark" label="备注信息"></el-table-column>
 			</el-table>
 		</el-dialog>
+	
+		<el-dialog title="提交结果" :visible.sync="isResult"  width="800" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
+			<div v-if="!isShowError">
+				<div style="text-align: center;margin-bottom: 10px;" class="red" v-if="isShowError2">{{errorMsg}}</div>
+				<el-progress :text-inside="true" :stroke-width="24" :percentage="percentage"></el-progress>
+				<div style="margin-top: 20px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
+					<div class="flex-box-ce results" style="font-weight: 600;">
+						<div style="border-right: 1px solid #f1f1f1;width: 50px;">序号</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">奖扣对象</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">事件内容</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">积分</div>
+						<div class="flex-2" >处理结果</div>
+					</div>
+					<div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
+						<div style="border-right: 1px solid #f1f1f1;width: 50px;">{{results.length-index}}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.target }}</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.task.msg.remark }}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">
+							{{ item.point>0? '+'+item.point:item.point }} 
+							<span>{{ item.task.msg.pt_id==3? 'B分':'A分' }}</span>
+						</div>
+						<div class="flex-2" v-if="item.status == 1">
+							<span v-if="item.msg=='奖扣成功'" class="green">{{ item.msg }}</span>
+							<span v-else class="blue">{{ item.msg }}</span>	
+						</div>
+						<div class="flex-2 red" v-else>{{ item.msg }}</div>
+					</div>
+				</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;" v-show="isShowError2&&results.length!=resultList.length"><el-button type="primary" @click="isResult = false" size="small">确 定</el-button></div>
+					<div class="flex-box-end" style="margin-top: 20px;" v-show="results.length==resultList.length"><el-button type="primary" @click="isResult = false" size="small">确 定</el-button></div>
+				</span>
+			</div>
+			<div v-else>
+				<div style="text-align: center;" class="red">{{errorMsg}}</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;"><el-button type="primary" @click="isResult = false" size="small">确 定</el-button></div>
+				</span>
+			</div>
+		</el-dialog>
+		<!-- 缓存的奖扣 -->
+		<el-dialog title="网络中断奖扣列表" :visible.sync="isShowBreak"  width="800" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
+			<div>
+				<div style="margin-top: 20px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
+					<div class="flex-box-ce results" style="font-weight: 600;">
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">奖扣对象</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">分类</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">规则</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">事件内容</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">积分</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">递交人员</div>
+					</div>
+					<div class="flex-box-ce results" v-for="(item, index) in breakList" :key="index">
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.name }}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">
+							<span v-if="item.rule_name">{{ item.rule_name }}</span>
+							<span v-else>--</span>
+						</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">
+							<span v-if="item.item_name">{{ item.item_name }}</span>
+							<span v-else>--</span>
+						</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.remark }}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.point }} 
+							<span>{{ item.pt_id==3? 'B分':'A分' }}</span>
+						</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.reviewer_name }}</div>
+					</div>
+				</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;">
+						<el-button type="primary" @click="colseBreak()" size="small">取 消</el-button>
+						<el-button type="primary" @click="submitBreak()" size="small">再次提交</el-button>
+					</div>
+				</span>
+			</div>
+		</el-dialog>
+		
+		
 	</div>
 </template>
 
@@ -196,7 +275,7 @@
 import moment from 'moment';
 import EmployeeSelector from '@/components/EmployeeSelector.vue';
 import upload from '@/components/upload';
-
+import {setCache,getCache,removeCache} from '@/api/auth';
 export default {
 	name: 'bonusPointsForm',
 	// 数据
@@ -213,6 +292,10 @@ export default {
 			type: Boolean,
 			default: false
 		},
+		isBreak: { //是否打开缓存的未完成奖扣
+			type: Boolean,
+			default: false
+		},
 		refresh: {
 			type: String,
 			default: ''
@@ -291,11 +374,32 @@ export default {
 
 			// 错误提示
 			error_list: [], //错误信息数组
-			error_list_show: false //错误信息弹窗
+			error_list_show: false ,//错误信息弹窗
+			
+			// 长连接结果
+			results: [], //提交的返回结果集合
+			isResult: false,
+			percentage: 0,
+			resultList:[],//要发送数据的集合
+			resultIndex:0,
+			isShowError:false,
+			isShowError2:false,
+			errorMsg:'服务器繁忙,请稍后再试',
+			breakList:[],
+			isShowBreak:false,
 		};
 	},
 	components: { EmployeeSelector, upload },
 	watch: {
+		isBreak(){
+			let data=getCache('award_punish').obj;
+			data.forEach(item=>{
+				item.name=getCache('userList')[item.employee_id]?getCache('userList')[item.employee_id].name:'--';
+				item.reviewer_name=getCache('userList')[item.reviewer_id]?getCache('userList')[item.reviewer_id].name:'--';
+			})
+			this.breakList=data;
+			this.isShowBreak=true;
+		},
 		integralType(val) {
 			this.dialogData.items[0].pt_id = val;
 			this.ptid = val;
@@ -307,7 +411,18 @@ export default {
 				this.employeeName = '';
 				this.employee_selected = { dept: [], employee: [] };
 			}
-		}
+		},
+		isResult(val){
+			if(!val){
+				this.isShowError = false;
+				this.isShowBreak = false;
+				this.$refs['dialogData'].resetFields();
+				this.$emit('update:refresh',this.$moment().format().valueOf());
+				this.closePopup();
+				this.errorMsg='服务器繁忙,请稍后再试';
+				this.$socketApi.closewebsocket();
+			}
+		},
 	},
 	mounted() {
 		var that = this;
@@ -317,6 +432,24 @@ export default {
 		});
 	},
 	methods: {
+		// 关闭缓存弹窗
+		colseBreak(){
+			this.isShowBreak = false;
+			this.breakList=[];
+			removeCache('award_punish');
+			this.$emit('update:refresh',this.$moment().format().valueOf());
+			this.closePopup();
+		},
+		// 提交缓存奖扣
+		submitBreak(){
+			removeCache('award_punish');
+			this.resultList=JSON.parse(JSON.stringify(this.breakList));
+			this.resultIndex=0;
+			this.percentage=0;
+			this.results=[];
+			this.isResult=true;
+			this.opneWebSocket()
+		},
 		getUserDetail(func) {
 			this.$axios('get', '/api/employee/detail').then(res => {
 				this.$setUserData(res.data.data.user);
@@ -338,7 +471,7 @@ export default {
 			const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
 			const isLt2M = file.size / 1024 / 1024 < 1;
 			if (!isJPG) {
-				this.$message.error('上传头像图片只能是 JPG 格式!');
+				this.$message.error('上传头像图片只能是 JPEG,PNG,JPG 格式!');
 			}
 			if (!isLt2M) {
 				this.$message.error('上传头像图片大小不能超过 2MB!');
@@ -367,11 +500,7 @@ export default {
 
 		// 没有人员提示
 		noPersonnelListTips() {
-			// if(this.employee_list.length>0){
 			this.show_employee_selector = true;
-			// }else{
-			// 	this.$message.error('您没有管理范围,请联系管理员');
-			// }
 		},
 		// 当switch 改变了
 		switchChange(index, value) {
@@ -462,19 +591,20 @@ export default {
 			const item = this.dialogData.items[this.itemIndex];
 			if (value.length > 0) {
 				const user_info = this.$getUserData();
+				let ruleCascader='ruleCascader'+this.itemIndex;
 				user_info.point_config.point_limit.forEach(element => {
 					if (this.ptid == this.integralType) {
 						item.max = element.point * 1;
 						item.min = element.point * -1;
 					}
 				});
-				this.$refs.ruleCascader.forEach(element => {
-					element.dropDownVisible = false;
-				});
+				this.$refs.[ruleCascader][0].dropDownVisible = false;
 				item.rule_id = value[value.length - 1];
+				item.rule_name = this.$refs.[ruleCascader][0].getCheckedNodes()[0].label;
 			} else {
 				item.rule_id = '';
 				item.rule_list_value = '';
+				item.rule_name='';
 			}
 		},
 		// 递归判断列表,把最后的child设为undefined
@@ -513,7 +643,6 @@ export default {
 				});
 				return false;
 			}
-
 			this.dialogData.items.push({
 				rule_switch: true,
 				rule_id: '',
@@ -612,6 +741,8 @@ export default {
 							remark: element.remark,
 							event_time: element.event_time,
 							pt_id: this.ptid,
+							rule_name:element.rule_name,
+							item_name:element.rule_item_details.name,
 							reviewer_id: element.reviewer_id || 0,
 							files: element.files
 						});
@@ -644,7 +775,9 @@ export default {
 								event_time: element.event_time,
 								pt_id: this.ptid,
 								reviewer_id: element.reviewer_id || 0,
-								files: element.files
+								files: element.files,
+								rule_name:element.rule_name,
+								item_name:element.rule_item_details.name,
 							});
 						} else {
 							this.$message.error('第' + (index + 1) + '条输入积分分值超出权限,请选择审批人递交');
@@ -656,12 +789,14 @@ export default {
 				this.btn_loading = false;
 				return false;
 			}
+			this.webSocket(data);
+			// 走长连接处理
+			return false
 			this.btn_loading = true;
 			this.$axios('post', this.integralType === 1 ? '' : this.integralType === 2 ? '/api/integral/review/a/entry' : '/api/integral/point/entry', data)
 				.then(res => {
 					if (res.data.code == 1) {
-						var is = true,
-							msg;
+						var is = true,msg;
 						if (this.integralType == '3') {
 							res.data.data.list.forEach(item => {
 								if (item.status != 1) {
@@ -683,17 +818,10 @@ export default {
 							});
 							this.$refs['dialogData'].resetFields();
 							this.$emit('update:visible', false);
-							this.$emit(
-								'update:refresh',
-								this.$moment()
-									.format()
-									.valueOf()
-							);
-							// this.$message.success(res.data.msg);
+							this.$emit('update:refresh',this.$moment().format().valueOf());
 							this.closePopup();
 							this.error_list = res.data.data.list;
 							this.error_list_show = true;
-						} else {
 						}
 					}
 				})
@@ -701,6 +829,59 @@ export default {
 					this.btn_loading = false;
 				});
 		},
+		webSocket(data){
+			let {members,items}=data;
+			let arr=[];
+			members.forEach(item=>{
+				items.forEach(item2=>{
+					item2.type = this.integralType === 2?'pea':'peb';
+					item2.employee_id=item;
+					arr.push(JSON.parse(JSON.stringify(item2)))
+				})
+			})
+			this.resultList=arr;
+			this.resultIndex=0;
+			this.percentage=0;
+			this.results=[];
+			this.isResult=true;
+			this.opneWebSocket()
+		},
+		opneWebSocket() {
+			let wsData=this.resultList;
+			if(wsData[this.resultIndex]&&!this.isShowError){
+				this.$socketApi.sendData(wsData[this.resultIndex],this.onmessageWS)
+			}
+		},
+		onmessageWS(e){
+			if(e.type=='peb'||e.type=='pea'){
+				this.results.unshift(e.result);
+				this.resultIndex++;
+				this.opneWebSocket();
+				// 进度条
+				let lng = this.resultList.length;
+				this.percentage += Math.floor(100 / lng);
+				if (lng == this.results.length) {
+					this.percentage = 100;
+				}
+			}
+			// 中途断开
+			if(e.type=='break'){
+				let wsData=this.resultList;
+				this.errorMsg=e.msg
+				let data={
+					type:this.integralType,
+					obj:wsData.slice(this.resultIndex,wsData.length)
+				}
+				setCache('award_punish',data);
+				this.isShowError2 = true;
+			}
+			// 连接不上
+			if(e.type=='error'){
+				this.errorMsg=e.msg
+				this.isShowError = true;
+			}
+			
+		},
 		// 选择审核人
 		approval_confirm(data) {
 			const item = this.dialogData.items[this.itemIndex];
@@ -766,4 +947,11 @@ export default {
 		text-overflow: initial;
 	}
 }
+.results {
+	border-bottom: 1px solid #f1f1f1;
+	text-align: center;
+}
+.results div {
+	padding: 10px;
+}
 </style>

+ 46 - 43
src/components/examinePopup.vue

@@ -27,6 +27,10 @@
 							</template>
 						</el-col>
 					</el-row>
+					<el-row :gutter="10" v-if="detail_info.pt_id">
+						<el-col :span="4">积分类型</el-col>
+						<el-col :span="20" class="blue">{{ detail_info.pt_id == 3 ? 'B分' : detail_info.pt_id == 2 ? 'A分' : detail_info.pt_id == 1 ? '绩效分' : '' }}</el-col>
+					</el-row>
 					<el-row :gutter="10" v-for="(item, index) in detail_info.detail" :key="index">
 						<el-col :span="4">{{ item.key }}</el-col>
 						<el-col :span="20" v-if="item.key == '附件' || item.key == '完成附件' || item.key == '工作附件'">
@@ -40,10 +44,10 @@
 						</el-col>
 						<el-col :span="20" v-else>{{ item.value }}</el-col>
 					</el-row>
-				    <el-row :gutter="10" v-if="detail_info.files != null && detail_info.files > 0">
-					 <el-col :span="4">图片</el-col>
-					 <el-col :span="20"><el-image style="width: 100px; height: 100px" :src="detail_info.files[0]" :preview-src-list="detail_info.files"></el-image></el-col>
-				    </el-row>
+					<el-row :gutter="10" v-if="detail_info.files != null && detail_info.files > 0">
+						<el-col :span="4">图片</el-col>
+						<el-col :span="20"><el-image style="width: 100px; height: 100px" :src="detail_info.files[0]" :preview-src-list="detail_info.files"></el-image></el-col>
+					</el-row>
 
 					<div v-show="detail_info.item_name != ''">
 						<p class="row_title">
@@ -61,19 +65,23 @@
 						<el-row>
 							<el-col :span="4">规则积分</el-col>
 							<el-col :span="20">
-								<span v-show="detail_info.point > 0">+</span>
-								{{ detail_info.point }} {{ detail_info.pt_id == 3 ? 'B分' : detail_info.pt_id == 2 ? 'A分' : detail_info.pt_id == 1 ? '绩效分' : '' }}
+								<template v-if="detail_info.item_range_type == 1">
+									<span v-if="detail_info.item_max_point > 0">+</span>
+									{{ detail_info.item_max_point }}{{ detail_info.pt_id == 3 ? 'B分' : detail_info.pt_id == 2 ? 'A分' : detail_info.pt_id == 1 ? '绩效分' : '' }}
+								</template>
+								<template v-else>
+									{{ detail_info.item_min_point }}~{{ detail_info.item_max_point
+									}}{{ detail_info.pt_id == 3 ? 'B分' : detail_info.pt_id == 2 ? 'A分' : detail_info.pt_id == 1 ? '绩效分' : '' }}
+								</template>
 							</el-col>
 						</el-row>
 					</div>
 
-					<div v-show="detail_info.process">
-						<Steps :process="detail_info.process"></Steps>	
-					</div>
+					<div v-show="detail_info.process"><Steps :process="detail_info.process"></Steps></div>
 				</div>
-				
-				<div class="detailBut" >
-					<div style="text-align: right;padding-top:20px" v-if="detail_info.status == 0&&detail_info.reviewer_id==$getUserData().id">
+
+				<div class="detailBut">
+					<div style="text-align: right;padding-top:20px" v-if="detail_info.status == 0 && detail_info.reviewer_id == $getUserData().id">
 						<el-button v-if="detail_info.pt_id == 1" @click="closeDetail">取消</el-button>
 						<el-button v-else @click="rejectBtn">驳回</el-button>
 						<el-button type="primary" @click="adoptBtn">通过</el-button>
@@ -83,7 +91,6 @@
 						<el-button type="primary" @click="revokeApproval">撤回审批</el-button>
 					</div>
 				</div>
-				
 			</div>
 		</el-drawer>
 
@@ -106,9 +113,7 @@
 		<el-dialog title="审批通过" :visible.sync="adoptShow" width="571px" :before-close="adoptClose">
 			<el-form :model="adoptForm" ref="adoptForm" label-width="80px" v-loading="determinedBy">
 				<template v-if="detail_info.source_type != 4">
-					<el-form-item label="指定规则" v-if="!detail_info.rule_id && !detail_info.item_id">
-						<el-switch v-model="adoptForm.ruleOrItem"></el-switch>
-					</el-form-item>
+					<el-form-item label="指定规则" v-if="!detail_info.rule_id && !detail_info.item_id"><el-switch v-model="adoptForm.ruleOrItem"></el-switch></el-form-item>
 					<el-form-item
 						label="分类"
 						v-show="(detail_info.rule_id && !detail_info.item_id) || !adoptForm.ruleOrItem"
@@ -143,7 +148,7 @@
 							:popper-class="'itemClass'"
 							v-model="adoptForm.item_id"
 							:options="item_list"
-							:props="{value: 'id',label: 'name',children: 'child'}"
+							:props="{ value: 'id', label: 'name', children: 'child' }"
 							ref="ruleItem"
 							clearable
 							filterable
@@ -152,8 +157,6 @@
 							placeholder="请选择规则细则"
 						></el-cascader>
 					</el-form-item>
-					
-					
 				</template>
 				<el-form-item label="规则积分" v-show="detail_info.item_id">
 					{{
@@ -210,7 +213,7 @@
 				</el-form-item>
 				<div style="padding-left: 80px">奖票用于优秀表现和重要事项的表彰</div>
 				<el-form-item label="发放奖票"><el-switch v-model="adoptForm.switch"></el-switch></el-form-item>
-				<el-form-item label="递交审批" v-if="$getUserData().is_creator==0">
+				<el-form-item label="递交审批" v-if="$getUserData().is_creator == 0">
 					<el-row>
 						<el-col :span="18">
 							<el-input auto-complete="off" v-model="manager" placeholder="请选择上级递交审批"></el-input>
@@ -251,7 +254,7 @@
 
 <script>
 import EmployeeSelector from '@/components/EmployeeSelector';
-import Steps from '@/components/Steps'; 
+import Steps from '@/components/Steps';
 export default {
 	name: 'examinePopup',
 	data() {
@@ -301,7 +304,7 @@ export default {
 			employee_not_select: [],
 			manager_selected: { dept: [], employee: [] },
 			show_employee_selector: false,
-			flatteningIntegralRules:{}
+			flatteningIntegralRules: {}
 		};
 	},
 	props: {
@@ -324,7 +327,7 @@ export default {
 		},
 		show(val) {
 			if (val) {
-				this.detail_info= {rule_id: ''};
+				this.detail_info = { rule_id: '' };
 				this.getDetail();
 			}
 		},
@@ -344,18 +347,18 @@ export default {
 			}
 		}
 	},
-	components: { EmployeeSelector,Steps },
+	components: { EmployeeSelector, Steps },
 	mounted() {
 		this.getRuleItem();
 		this.getRuleItemTree();
 		this.employee_lists = this.$getUserData().employee_detail.superior_list;
 	},
 	methods: {
-		guol(data){
-			if(data.rule_id || data.item_id){
-				return true
-			}else{
-				return false
+		guol(data) {
+			if (data.rule_id || data.item_id) {
+				return true;
+			} else {
+				return false;
 			}
 		},
 		submitApproval(name) {
@@ -366,7 +369,7 @@ export default {
 			done();
 		},
 		cascaderItemIdChange(val) {
-			if(val.length>0){
+			if (val.length > 0) {
 				let datas = null;
 				this.flatteningIntegralRules.forEach(element => {
 					if (element.id == val[val.length - 1]) {
@@ -388,7 +391,7 @@ export default {
 				this.rangeType.rule_rangeType_name = datas.name;
 				this.adoptForm.point = datas.min_point;
 				this.adoptForm.rule_id = datas.rule_id;
-			}else{
+			} else {
 				this.rangeType = {
 					rule_range_type: 0,
 					rule_min_point: 0,
@@ -645,11 +648,11 @@ export default {
 					self.adoptForm.switch ? (data.ticket_count = 1) : (data.ticket_count = 0);
 					if (this.detail_info.item_range_type == 1) {
 						data.point = self.adoptForm.point;
-					// 	if (self.awardPoints === 1) {
-					// 		data.point = self.adoptForm.point;
-					// 	} else {
-					// 		data.point = self.adoptForm.point * -1;
-					// 	}
+						// 	if (self.awardPoints === 1) {
+						// 		data.point = self.adoptForm.point;
+						// 	} else {
+						// 		data.point = self.adoptForm.point * -1;
+						// 	}
 					}
 
 					if (data.rule_id == '' || data.rule_id == null) {
@@ -724,13 +727,13 @@ label {
 
 .detailBut {
 	border-top: 1px solid rgb(248, 248, 248);
-    width: 100%;
-    position: absolute;
-    bottom: 0px;
-    right: 0;
-    padding: 0 20px 10px 0;
-    z-index: 1;
-    background-color: #fff;
+	width: 100%;
+	position: absolute;
+	bottom: 0px;
+	right: 0;
+	padding: 0 20px 10px 0;
+	z-index: 1;
+	background-color: #fff;
 }
 .detail_popup {
 	padding: 20px;

+ 12 - 4
src/components/noData.vue

@@ -1,8 +1,8 @@
 <template>
     <div class="flex-box-v flex-v-zhu">
-      <img src="../assets/image/nodata.png" style="width: 266px;height: 182px;margin: 30px auto;">
-      <div class="fontColorF" v-if="!isSolt">{{content}}</div>
-        <slot></slot>
+      <img src="../assets/image/nodata.png"  :style="{ width: imgW, height: imgH }" style="margin: 30px auto;">
+      <div class="fontColorF"  style="text-align: center;line-height: 28px;" v-if="!isSolt">{{content}}</div>
+      <slot></slot>
     </div>
 </template>
 <!-- content:为提示内容  -->
@@ -19,7 +19,15 @@
       isSolt:{
         type:Boolean,
         default:false
-      }
+      },
+	  imgW:{
+	     type:String,
+	     default:'266px'
+	  },
+	  imgH:{
+	     type:String,
+	     default:'182px'
+	  },
     },
     data(){
       return{

+ 1 - 1
src/components/upload.vue

@@ -142,7 +142,7 @@
         })
       },
       _onExceed(files, fileList){
-        this.$message.warning(`当前限制选择 ${this.limit} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
+        this.$message.warning(`最多选择 ${this.limit} 个文件`)
       },
       _onSuccess(response, file, fileList) {
         this.onSuccess(response, file, fileList)

+ 3 - 3
src/home.vue

@@ -417,7 +417,7 @@
 				<el-row>
 					<div class="right-all-style" v-loading="announLoad" style="background:#fff;padding: 20px 20px 20px 20px;">
 						<div style="display:flex;justify-content: space-between;">
-							<span class="title">系统公告</span>
+							<span class="title">系统通知</span>
 							<span v-if="announcement.title" @click="$router.push({ path: '/update_notice' })" class="announcementc" style="font-size:13px;">查看详情</span>
 						</div>
 						<div v-if="announcement.title" class="announs">
@@ -426,14 +426,14 @@
 						</div>
 						<div v-else class="nopoint_box">
 							<div class="noimg"></div>
-							<span class="title1" style="padding-bottom:10px;">暂无系统公告</span>
+							<span class="title1" style="padding-bottom:10px;">暂无系统通知</span>
 						</div>
 					</div>
 				</el-row>
 			</el-col>
 		</el-row>
 		<div class="updateNotice">
-			<el-dialog title="系统公告" :visible.sync="updateVisible" width="500px" top="20vh" :before-close="updateClose">
+			<el-dialog title="系统通知" :visible.sync="updateVisible" width="500px" top="20vh" :before-close="updateClose">
 				<b style="font-size:16px;margin:0 0 10px 0;display: inline-block;">{{ announcement.title }}</b>
 				<div class="announDetails" style="padding:0 0 0 0" v-html="announcement.focus"></div>
 				<span slot="footer" class="dialog-footer"><el-button @click="$router.push({ path: '/update_notice' })" type="primary" round>查看详情</el-button></span>

+ 61 - 8
src/index.vue

@@ -1,13 +1,29 @@
 <template>
 	<el-container class="box-all" v-loading="loading">
 		<el-header>
-			<div class="flex-box" style="height: 60px;">
+			<div class="flex-box" style="height: 60px;min-width: 1200px;">
 				<div class="logo-box flex-box flex-center-center" @click="openHome()">
 					<img src="./assets/image/logo.png" class="logo" />
 					<div>功道云积分制</div>
 				</div>
-				<div class="flex-1 hea-right flex-box flex-v-ce" v-if="info.name">
-					<div class="name flex-1">{{ info.name }}</div>
+				
+				<div class="flex-1 hea-right flex-box flex-v-ce" >
+					<div class="name" style="min-width: 200px;">{{ info.name }}</div>
+					<div class="flex-1 flex-box-ce font-flex-word" style="cursor: pointer;padding: 0 20px;">
+						<template v-if="$supremeAuthority()=='dept_manager'||$supremeAuthority()=='employee'">
+							<template v-if="information.name">
+								<img src="./assets/image/tz.png" style="width: 18px;height: 18px;"/>
+								<span style="max-width: 500px;padding-left: 10px;" class="font-flex-word"  @click="$router.push({path:'inform'})">{{information.name}}</span>
+							</template>
+						</template>
+						<div v-else  class="flex-box-ce" >
+							<img src="./assets/image/tz.png" style="width: 18px;height: 18px;"/>
+							<template v-if="information.name">
+								<span style="max-width: 500px;padding-left: 10px;" class="font-flex-word"  @click="$router.push({path:'inform'})">{{information.name}}</span>
+							</template>
+							<span v-else style="padding: 0 10px;cursor: pointer;color: #606266;"  @click="$router.push({path:'inform'})">暂无公告,点击此处添加公告</span>
+						</div>
+					</div>
 					<div class="flex-box flex-v-ce">
 						<div>
 							您当前为
@@ -50,7 +66,7 @@
 			</el-aside>
 			<el-main>
 				<router-view />
-				<div class="fontColorF" style="text-align: center;margin: 20px 0;">Copyright © 2021 广东功道云数字科技有限公司 All Rights Reserved</div>
+				<div class="fontColorF" style="text-align: center;margin: 10px 0;">Copyright © 2021 广东功道云数字科技有限公司 All Rights Reserved</div>
 			</el-main>
 		</el-container>
 		<!-- 续费升级 -->
@@ -100,6 +116,8 @@
 </template>
 
 <script>
+import { createSocket,sendWSPush,sendPing } from './api/websocket'
+import { removeCache } from './api/auth'
 export default {
 	data() {
 		return {
@@ -113,7 +131,8 @@ export default {
 			isShowWn: true,
 			isTz: false,
 			direction: 'rtl',
-			corpMessage: {} //企业套餐信息
+			corpMessage: {} ,//企业套餐信息
+			information:{name:''},
 		};
 	},
 	watch: {
@@ -129,12 +148,16 @@ export default {
 					});
 				}
 			});
+			if(localStorage.getItem('inform')){
+				this.getInform()
+				removeCache('inform')
+			}
 		}
 	},
 	created() {
-		console.log("123")
 		this.initRouter();
 		this.getEmployee()//缓存人员列表
+		this.getInform();
 	},
 	mounted() {
 		this.getTypes();
@@ -159,6 +182,35 @@ export default {
 		});
 	},
 	methods: {
+		openWebSocket(){
+			// 接收消息
+			const getsocketData = e => {  // 创建接收消息函数
+			  const data = e && e.detail.data
+			  console.log(data)
+			}
+			// 注册监听事件
+			window.addEventListener('onmessageWS', getsocketData)
+			
+			// 在需要的时候卸载监听事件,比如离开页面
+			window.removeEventListener('onmessageWS', getsocketData)
+		},
+		getInform(){
+			let params = {
+				page: 1,
+				page_size: 1
+			};
+			this.$axios('get', '/api/information/index', params).then(res => {
+				if (res.data.code == 1) {
+					let data= res.data.data;
+					if(data[0]){
+						this.information=data[0]
+					}else{
+						this.information={name:''};
+					}
+					
+				}
+			});
+		},
 		initRouter() {
 			this.routers = [
 				{ name: '首页', children: this.returnRoutersArr('home'), icon: 'icon-shouye' },
@@ -169,13 +221,14 @@ export default {
 			];
 			//this.$authoritys('权限名') 判断权限
 			if (this.$authoritys('creator') || this.$authoritys('admin') || this.$authoritys('point_manager') || this.$authoritys('dept_manager')) {
-				this.routers.splice(3, 0, { name: '工作台', children: this.returnRoutersArr('workbench'), icon: 'icon-shezhi_jifenguize' });
+				this.routers.splice(3, 0, { name: '审批', children: this.returnRoutersArr('workbench'), icon: 'icon-shezhi_jifenguize' });
 			}
 			if (this.$authoritys('creator') || this.$authoritys('admin') || this.$authoritys('point_manager')) {
 				this.routers.push({ name: '设置', children: this.returnRoutersArr('set'), icon: 'icon-dingdingPC_shezhi1' });
 			}
 			//this.returnRoutersArr('set',true) 加true表示不限制路由
 			this.routers_one = this.returnRoutersArr('set', true);
+			console.log(this.routers_one)
 			this.userData = this.$getUserData();
 			if (this.$route.path != '/home') {
 				//当刷新页面是控制左边导航栏的选中
@@ -280,7 +333,7 @@ export default {
 };
 </script>
 
-<style scoped="scoped" lang="scss">
+<style scoped="scoped" lang="scss">	
 .wn-box {
 	padding: 20px 0;
 }

+ 363 - 0
src/inform.vue

@@ -0,0 +1,363 @@
+<template>
+	<div class="box boxMinHeight">
+		<header class="header flex-box-ce">
+			<div class="header-title flex-1" >
+				<div class="flex-box-ce" style="cursor: pointer;width: 200px;"  @click="$router.go(-1)">
+					<i class="el-icon-arrow-left fontColorF"></i>
+					<div class="text fontColorB font-flex-word">公告列表</div>
+				</div>
+			</div>
+			<el-button type="primary" size="small" @click="app()" v-if="$supremeAuthority()!='dept_manager'&&$supremeAuthority()!='employee'">添加</el-button>
+		</header>
+		<div class="main flex-box">
+			<div class="main-left scroll-bar">
+				<div
+					v-for="(item, index) in announcement"
+					:key="index"
+					class="font-flex-word"
+					:class="item.id == articleOne.id ? 'active' : ''"
+					@click="dept_click(item)"
+					style="height: 56px;line-height: 56px;padding: 0 10px;border-bottom: 1px solid #f1f1f1;"
+				>
+					{{ item.name }}
+				</div>
+				<noData v-show="announcement.length == 0" content="暂无数据" imgW="60%" imgH="auto" isSolt>
+					<el-button type="primary" size="small" style="margin-right: 20px;" @click="app()" v-if="$supremeAuthority()!='dept_manager'&&$supremeAuthority()!='employee'">添加</el-button>
+				</noData>
+			</div>
+			<div class="main-right flex-1" v-loading="noticeLoad">
+				<div class="title" style="position: relative;" v-if="announcement.length>0">
+					<span class="fontColorF" style="position: absolute;"> {{ articleOne.create_time ? articleOne.create_time : '' }} {{articleOne.employee_name}}发布</span>
+					<div style="font-size: 18px;padding-right: 10px;text-align: center;">{{ articleOne.name ? articleOne.name : '' }}</div>
+					<div style="position: absolute;right:20px;top:0px" v-if="$supremeAuthority()!='dept_manager'&&$supremeAuthority()!='employee'">
+						<el-button type="danger" plain size="small" @click="deteleItem">删除</el-button>
+						<el-button type="primary" plain size="small" @click="compile">编辑</el-button>
+					</div>
+				</div>
+				<div class="RuleRight scroll-bar">
+					<template v-if="aAtripOfDetails">
+						<div v-html="aAtripOfDetails"></div>
+						<el-image  :src="detaliData.file_list" style="margin-top: 20px;" :preview-src-list="[detaliData.file_list]" v-if="detaliData.file_list"/>
+					</template>
+					<noData v-else></noData>
+				</div>
+			</div>
+		</div>
+		<Suggest :visible.sync="isShowJy"  :detaliData="detaliData" :isAdd="isAdd"></Suggest>
+	</div>
+</template>
+
+<script>
+import { setCache } from '@/api/auth';
+import Suggest from '@/components/Suggest';
+export default {
+	components: { Suggest },
+	name: 'update_notice',
+	data() {
+		return {
+			articleOne: {},
+			announcement: [],
+			noticeLoad: false,
+			defaultProps: {
+				label: 'name'
+			},
+			aAtripOfDetails: '',
+			isShowJy: false,
+			detaliData:{},
+			isAdd:true,
+		};
+	},
+	created() {
+		setCache('inform', true);
+		this.noticeList();
+	},
+	methods: {
+		deteleItem() {
+			this.$confirm('此操作将永久删除该公告, 是否删除?', '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				this.$axios('POST', '/api/information/delete', {id:this.articleOne.id}).then(res => {
+					if (res.data.code == 1) {
+						this.$message.success("已删除")
+						this.noticeList();
+					}
+				});
+			}).catch(() => {});
+		},
+		compile() {
+			this.isAdd=false
+			this.isShowJy = true;
+		},
+		app() {
+			this.isAdd=true
+			this.isShowJy = true;
+		},
+		noticeList() {
+			this.articleOne={};
+			let params = {
+				page: 1,
+				page_size: 2000
+			};
+			this.$axios('get', '/api/information/index', params).then(res => {
+				if (res.data.code == 1) {
+					let list = res.data.data;
+					this.$nextTick(() => {
+						if (list[0]) {
+							this.articleOne = list[0];
+							this.announcement = list;
+						}else{
+							this.announcement = [];
+						}
+						this.noticeDetails();
+					});
+				}
+			});
+		},
+		noticeDetails() {
+			if (!this.articleOne.id) {
+				return false;
+			}
+			this.noticeLoad = true;
+			this.aAtripOfDetails='';
+			this.$axios('get', '/api/information/info', { id: this.articleOne.id })
+				.then(res => {
+					if (res.data.code == 1) {
+						this.aAtripOfDetails = res.data.data.content.html;
+						this.detaliData=res.data.data;
+					}
+				})
+				.finally(() => {
+					this.noticeLoad = false;
+				});
+		},
+		dept_click(item) {
+			this.articleOne = item;
+			this.noticeDetails();
+		}
+	}
+};
+</script>
+
+<style scoped lang="scss">
+.active {
+	color: #26a2ff;
+	background-color: #ecf5ff;
+}
+
+/* 表格 */
+table {
+	border-collapse: collapse;
+}
+table th,
+table td {
+	border: 1px solid #ccc;
+	min-width: 50px;
+	height: 20px;
+	text-align: left;
+}
+table th {
+	background-color: #f1f1f1;
+	text-align: center;
+}
+
+/* 代码块 */
+pre > code {
+	display: block;
+	border: 1px solid hsl(0, 0%, 91%);
+	border-radius: 4px 4px;
+	text-indent: 0;
+	background-color: #fafafa;
+	padding: 10px;
+	font-size: 14px;
+}
+
+/* 引用 */
+blockquote {
+	display: block;
+	border-left: 8px solid #d0e5f2;
+	padding: 10px 10px;
+	margin: 10px 0;
+	background-color: #f1f1f1;
+}
+
+/* 列表 */
+ul,
+ol {
+	margin: 10px 0 10px 20px;
+}
+::v-deep p{
+	    margin-block-start: 1em;
+	    margin-block-end: 1em;
+}
+
+/* 分割线 */
+hr {
+	display: block;
+	width: 90%;
+	margin: 20px auto;
+	border: 0;
+	height: 1px;
+	background-color: #ccc;
+}
+.header {
+	border-bottom: 1px solid #f1f1f1;
+	padding-bottom: 10px;
+	padding-right: 20px;
+}
+.header-title {
+	box-sizing: border-box;
+	position: relative;
+	width: 200px;
+}
+.el-icon-arrow-left {
+	font-size: 20px;
+}
+.header-title:hover .el-icon-arrow-left {
+	background-color: #f5f7fa;
+	color: #222;
+}
+.text {
+	font-size: 16px;
+	padding-left: 30px;
+}
+.text::before {
+	position: absolute;
+	content: '';
+	width: 1px;
+	height: 60px;
+	background-color: #ebebeb;
+	left: 34px;
+	top: 50%;
+	margin-top: -18px;
+}
+.title {
+	background-color: #fff;
+	height: 56px;
+	line-height: 56px;
+	border-bottom: 1px solid #f1f1f1;
+}
+.RuleRight {
+	height: 690px;
+	overflow-y: auto;
+	position: relative;
+}
+::v-deep .el-tree--highlight-current {
+	.el-tree-node {
+		border-bottom: 1px #f0f0f0 solid;
+	}
+	.el-tree-node__content {
+		background-color: #fff;
+		height: 56px;
+		line-height: 56px;
+	}
+	.is-current {
+		.el-tree-node__content {
+			.el-icon-caret-right {
+				// color:#409EFF !important;
+			}
+			.el-tree-node__label {
+				color: #409eff !important;
+			}
+		}
+		.el-tree-node__children {
+			.el-icon-caret-right {
+				color: #c0c4cc !important;
+			}
+			.el-tree-node__label {
+				color: #606266 !important;
+			}
+		}
+	}
+}
+.tabs ::v-deep.el-badge__content.is-fixed {
+	position: absolute;
+	top: 50%;
+	right: -2px;
+}
+.box {
+	padding: 20px;
+	font-size: 14px;
+	position: relative;
+	background-color: #fff;
+}
+.main {
+	margin-top: 30px;
+}
+/* bug: 我在flex布局的元素中使用了elementui的table组件,饿了么的table上会被加一个动态的宽度, 当第一次改变flex元素宽度的时候。table的动态宽度会变化,第二次和以后就不会变化了。*/
+/* 给使用flex的元素加上 overflow-x:hidden */
+.main-right {
+	margin-left: 20px;
+	overflow-x: hidden;
+}
+.main-left {
+	width: 200px;
+	border-radius: 3px;
+	box-sizing: border-box;
+	// padding-right: 20px;
+	max-height: 700px;
+	overflow: auto;
+}
+.main-left::after {
+	position: absolute;
+	content: '';
+	width: 1px;
+	height: auto;
+	left: 220px;
+	top: 0;
+	bottom: 0;
+	background-color: #f1f1f1;
+}
+::v-deep .has-gutter {
+	display: none;
+}
+.li {
+	height: 53px;
+	line-height: 53px;
+	padding: 0 20px;
+	border-bottom: 1px solid #f1f1f1;
+	color: #777777;
+	width: 100%;
+}
+.li:hover {
+	background-color: #f5f7fa;
+}
+.li:hover .el-icon-more {
+	display: block;
+}
+.index-name {
+	width: 170px;
+}
+.ul {
+	max-height: calc(100vh - 230px);
+	overflow: auto;
+	width: 200px;
+}
+.isActiveLi {
+	background-color: #f5f7fa;
+	color: #409eff !important;
+	position: relative;
+}
+.isActiveLi::after {
+	width: 3px;
+	content: ' ';
+	background-color: #409eff;
+	left: 0;
+	bottom: 0;
+	top: 0;
+	position: absolute;
+}
+.item {
+	font-size: 14px;
+	cursor: pointer;
+	padding: 8px;
+	border-bottom: 1px solid #e8e8e8;
+}
+.item:hover {
+	background-color: #f5f7fa;
+}
+.content {
+	padding: 0 10px;
+}
+</style>

+ 12 - 24
src/main.js

@@ -13,50 +13,38 @@ import service from './api/axios'
 import echarts from 'echarts'
 import NProgress from 'nprogress';
 import 'nprogress/nprogress.css'
-import { getToken, setToken,getUserData,setUserData,getTyps,setTyps,getIsCreator,supremeAuthority,authoritys,getTypsName} from './api/auth';
-// import { createSocket,sendWSPush,sendPing } from './api/websocket'
+import { getToken, setToken,getUserData,setUserData,getTyps,setTyps,getIsCreator,supremeAuthority,authoritys,getTypsName,generateUUID} from './api/auth';
+import * as socketApi from './api/websocket'
 
 // 头像
 import userImage from '@/components/UserImage'
+import noData from '@/components/noData'
 Vue.component('userImage', userImage)
+Vue.component('noData', noData)
 Vue.use(ElementUI);
 if (process.env.NODE_ENV === 'development') {
-  // new VConsole()
+  new VConsole()
 }
-
 Vue.prototype.$echarts = echarts
-Vue.prototype.$dd=dd;
+Vue.prototype.$dd = dd;
 Vue.prototype.$getToken = getToken
 Vue.prototype.$setToken = setToken
 Vue.prototype.$getUserData = getUserData
 Vue.prototype.$setUserData = setUserData
 Vue.prototype.$getTyps = getTyps
 Vue.prototype.$setTyps = setTyps
-Vue.prototype.$getTypsName=getTypsName
+Vue.prototype.$getTypsName = getTypsName
 Vue.prototype.$getIsCreator = getIsCreator
 Vue.prototype.$supremeAuthority = supremeAuthority
 Vue.prototype.$authoritys = authoritys
 Vue.prototype.$moment = moment
-Vue.prototype.$appId=process.env.VUE_APP_APPID
-// 长连接
-
-// 接收消息
-// const getsocketData = e => {  // 创建接收消息函数
-//   const data = e && e.detail.data
-//   console.log(data)
-// }
-// // 注册监听事件
-// window.addEventListener('onmessageWS', getsocketData)
-
-// // 在需要的时候卸载监听事件,比如离开页面
-// window.removeEventListener('onmessageWS', getsocketData)
+Vue.prototype.$appId = process.env.VUE_APP_APPID
+Vue.prototype.$socketApi = socketApi   //长连接
+Vue.prototype.$generateUUID = generateUUID   //长连接
 
-
-Vue.prototype.$http= service;
-//Vue函数添加一个原型属性$axios 指向axios,这样vue实例或组件中不用再去重复引用Axios 直接用this.$axios就能执行axios 方法
+Vue.prototype.$http = service;
 var CancelToken = axios.CancelToken;
-Vue.$httpRequestList=[];
-
+Vue.$httpRequestList = [];
 Vue.prototype.$axios = (type, url, data,heaStr) => {
 	if(url!='/api/ding/login'&& url!='/api/integral/types'){
 	    var Accept='';

+ 29 - 9
src/router/index.js

@@ -24,6 +24,15 @@ const routes = [{
 					groupCode: 'home',
 				}
 			},
+			{
+				path: '/inform',
+				name: '通知',
+				component: () => import( /* webpackChunkName: "award_punish" */'@/inform'),
+				meta: {
+					icon: 'icon-shezhi_zuzhijiagou',
+					groupCode: 'home',
+				}
+			},
 			{
 				path: '/award_punish',
 				name: '我奖扣的',
@@ -302,7 +311,7 @@ const routes = [{
 			},
 			{
 				path: '/approval_list',
-				name: '审批',
+				name: '待我审批',
 				component: () => import( /* webpackChunkName: "approval_list" */
 					'@/views/workbench/approval_list.vue'),
 				meta: {
@@ -311,18 +320,29 @@ const routes = [{
 				}
 			},
 			{
-				path: '/flManagement',
-				name: '功勋点管理',
-				component: () => import( /* webpackChunkName: "approval_list" */'@/views/welfare/flManagement.vue'),
+				path: '/approval_batch',
+				name: '批量审批',
+				component: () => import( /* webpackChunkName: "approval_batch" */
+					'@/views/workbench/approval_batch.vue'),
 				meta: {
 					icon: 'icon-shezhi_gongdaolbiao',
-					groupCode: 'welfare',
+					groupCode: 'workbench',
+				}
+			},
+			{
+				path: '/alreadySp',
+				name: '已审批',
+				component: () => import( /* webpackChunkName: "alreadySp" */
+					'@/views/workbench/alreadySp.vue'),
+				meta: {
+					icon: 'icon-shezhi_gongdaolbiao',
+					groupCode: 'workbench',
 				}
 			},
 			{
-				path: '/flStatistics',
-				name: '功勋点统计',
-				component: () => import( /* webpackChunkName: "approval_list" */'@/views/welfare/flStatistics.vue'),
+				path: '/flBox',
+				name: '功勋点管理',
+				component: () => import( /* webpackChunkName: "flBox" */'@/views/welfare/flBox.vue'),
 				meta: {
 					icon: 'icon-shezhi_gongdaolbiao',
 					groupCode: 'welfare',
@@ -330,7 +350,7 @@ const routes = [{
 			},
 			{
 				path: '/prize',
-				name: '奖清单',
+				name: '奖清单',
 				component: () => import( /* webpackChunkName: "approval_list" */'@/views/welfare/prize.vue'),
 				meta: {
 					icon: 'icon-shezhi_gongdaolbiao',

+ 17 - 5
src/views/abPoint/apply_list.vue

@@ -1,8 +1,8 @@
 <template>
 	<div class="all padding-20">
 		<el-tabs v-model="tabs">
-			<el-tab-pane label="申请通过" name="complete"></el-tab-pane>
 			<el-tab-pane label="待审批" name="waiting"></el-tab-pane>
+			<el-tab-pane label="申请通过" name="complete"></el-tab-pane>
 			<el-tab-pane label="被驳回" name="refuse"></el-tab-pane>
 		</el-tabs>
 
@@ -172,7 +172,7 @@
 			</div>
 		</el-drawer>
 
-		<applicationIntegrationPopup title="申请积分" :ruleOnoff="ruleOnoff" :visible.sync="dialogVisible" v-if="dialogVisible"></applicationIntegrationPopup>
+		<applicationIntegrationPopup title="申请积分" :isBreak="isBreak" :ruleOnoff="ruleOnoff" :visible.sync="dialogVisible" v-if="dialogVisible"></applicationIntegrationPopup>
 	</div>
 </template>
 
@@ -181,17 +181,18 @@ import moment from 'moment';
 import EmployeeSelector from '@/components/EmployeeSelector.vue';
 import applicationIntegrationPopup from '@/components/applicationIntegrationPopup';
 import Steps from '@/components/Steps'; 
+import {getToken,getCache } from '@/api/auth';
 export default {
 	data() {
 		return {
 			ruleOnoff: false,
-			tabs: 'complete',
+			tabs: 'waiting',
 			dataList: [],
 			table_loading: false,
 			detailShow: false,
 			detail_loading: false,
 			formData: {
-				type: 'complete',
+				type: 'waiting',
 				pt_id: 0,
 				page: 1,
 				page_size: 10,
@@ -206,7 +207,9 @@ export default {
 			itemIndex: 0,
 			selectId: '',
 			userId: '',
-			cx_loading: false
+			cx_loading: false,
+			
+			isBreak:false,//是否打开缓存的未完成奖扣
 		};
 	},
 	components: {
@@ -228,6 +231,15 @@ export default {
 		this.cheakAx()
 		this.userId = this.$getUserData().id;
 		this.get_list();
+		setTimeout(() => {
+			let apply_list=getCache('apply_list')
+			if(apply_list&&apply_list.length>0){
+				this.isBreak=true;
+				this.dialogVisible=true;
+			}else{
+				this.isBreak=false;
+			}
+		}, 1000)
 	},
 	methods: {
 		cheakAx() {

+ 18 - 5
src/views/abPoint/award_punish.vue

@@ -9,6 +9,7 @@
 			<el-col :span="12">
 				<el-button type="primary" @click="point_b">奖扣B分</el-button>
 				<el-button type="primary" @click="point_a" plain>奖扣A分</el-button>
+				<!-- <div class="red">未成功提交列表</div> -->
 			</el-col>
 			<el-col :span="6" :offset="6">
 				<el-input v-model="keyword" placeholder="输入同事姓名/内容" @keyup.enter.native="getData">
@@ -20,7 +21,7 @@
 		<el-table v-if="tabs == 'success'" res="table1" :data="dataList" stripe fit v-loading="table_loading" @row-click="open_detail">
 			<el-table-column label="姓名" prop="employee_id" align="left">
 				<template slot-scope="scope">
-					<div class="flex-box flex-contet-conter">
+					<div class="flex-box flex-contet-conter" >
 						<userImage :img_url="scope.row.employee_img_url" :user_name="scope.row.employee_name" width="50px" height="50px"></userImage>
 						<span style="margin-left: 10px; line-height: 50px;">{{ scope.row.employee_name }}</span>
 					</div>
@@ -237,8 +238,8 @@
 			</div>
 		</el-drawer>
 
-		<bonusPointsPopup :title="popuTitle" :visible.sync="popupVisible" :ruleOnoff="ruleOnoff" :refresh.sync="refreshData" :integralType.sync="integralType">
-			<div style="position: relative;top: -20px;left: 80px;" class="yellow">最多只能选择10人</div>
+		<bonusPointsPopup :isBreak="isBreak" :title="popuTitle" :visible.sync="popupVisible" :ruleOnoff="ruleOnoff" :refresh.sync="refreshData" :integralType.sync="integralType">
+			<div style="position: relative;top: -20px;left: 80px;" class="yellow">最多只能选择30人</div>
 		</bonusPointsPopup>
 	</div>
 </template>
@@ -246,9 +247,10 @@
 <script>
 import EmployeeSelector from '@/components/EmployeeSelector.vue';
 import moment from 'moment';
-import noData from '@/components/noData';
+
 import bonusPointsPopup from '@/components/bonusPointsPopup';
 import Steps from '@/components/Steps'; 
+import {getToken,getCache } from '@/api/auth';
 export default {
 	data() {
 		return {
@@ -279,18 +281,29 @@ export default {
 			userId:'',
 			cx_loading:false,
 			selectId:'',//打开详情ID
+			
+			// 长连接
+			isBreak:false,//是否打开缓存的未完成奖扣
 		};
 	},
 	components: {
 		EmployeeSelector,
 		bonusPointsPopup,
-		noData,
 		Steps
 	},
 	mounted() {
 		this.cheakAx()
 		this.userId=this.$getUserData().id
 		this.getData()
+		setTimeout(() => {
+			let award_punish=getCache('award_punish')
+			if(award_punish&&award_punish.obj.length>0){
+				this.isBreak=true;
+				award_punish.type==3? this.point_b():this.point_a()
+			}else{
+				this.isBreak=false;
+			}
+		}, 1000)
 	},
 	watch: {
 		tabs(val) {

+ 4 - 7
src/views/common/rewardTask.vue

@@ -28,13 +28,10 @@
 					
 					
 					<el-form-item label="指定规则">
-						  <el-radio-group v-model="isSelectType">
-						    <el-radio :label="true">分类</el-radio>
-						    <el-radio :label="false">规则</el-radio>
-						  </el-radio-group>
+						 <el-switch  v-model="isSelectType"></el-switch>
 					</el-form-item>
 					<!-- 选择分类 -->
-					<el-form-item class="test_cascader_id" label="选择分类"	v-if="isSelectType"
+					<el-form-item class="test_cascader_id" label="选择分类"	v-if="!isSelectType"
 						prop="rule_value"
 						:rules="[{ required: true, message: '请选择规则分类', trigger: 'blur' }]"
 					>
@@ -270,7 +267,7 @@ export default {
 	},
 	data() {
 		return {
-			isSelectType:true,//是否选择分类
+			isSelectType:false,//是否选择分类
 			//图片附件
 			Xtoken: { 'X-Token': this.$getToken() },
 			fileList: [],
@@ -668,7 +665,7 @@ export default {
 			const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
 			const isLt2M = file.size / 1024 / 1024 < 1;
 			if (!isJPG) {
-				this.$message.error('上传头像图片只能是 JPG 格式!');
+				this.$message.error('上传头像图片只能是 JPEG,PNG,JPG 格式!');
 			}
 			if (!isLt2M) {
 				this.$message.error('上传头像图片大小不能超过 2MB!');

+ 4 - 7
src/views/common/rewardTaskAmend.vue

@@ -18,13 +18,10 @@
 					</el-form-item>
 					
 					<el-form-item label="指定规则">
-						  <el-radio-group v-model="isSelectType" @change="isSelectTypeC">
-						    <el-radio :label="true">分类</el-radio>
-						    <el-radio :label="false">规则</el-radio>
-						  </el-radio-group>
+						 <el-switch  v-model="isSelectType"></el-switch>
 					</el-form-item>
 					<!-- 选择分类 -->
-					<el-form-item class="test_cascader_id" label="选择分类"	v-if="isSelectType"
+					<el-form-item class="test_cascader_id" label="选择分类"	v-if="!isSelectType"
 						prop="rule_value"
 						:rules="[{ required: true, message: '请选择规则分类', trigger: 'blur' }]"
 					>
@@ -222,7 +219,7 @@ export default {
 	},
 	data() {
 		return {
-			isSelectType:true,//是否选择分类
+			isSelectType:false,//是否选择分类
 			//图片附件
 			Xtoken: { 'X-Token': this.$getToken() },
 			fileList: [],
@@ -497,7 +494,7 @@ export default {
 			const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
 			const isLt2M = file.size / 1024 / 1024 < 1;
 			if (!isJPG) {
-				this.$message.error('上传头像图片只能是 JPG 格式!');
+				this.$message.error('上传头像图片只能是 JPEG,PNG,JPG 格式!');
 			}
 			if (!isLt2M) {
 				this.$message.error('上传头像图片大小不能超过 2MB!');

+ 4 - 7
src/views/common/temporaryTask.vue

@@ -19,13 +19,10 @@
 					</el-form-item>
 					
 					<el-form-item label="指定规则">
-						  <el-radio-group v-model="isSelectType">
-						    <el-radio :label="true">分类</el-radio>
-						    <el-radio :label="false">规则</el-radio>
-						  </el-radio-group>
+						 <el-switch  v-model="isSelectType"></el-switch>
 					</el-form-item>
 					<!-- 选择分类 -->
-					<el-form-item class="test_cascader_id" label="选择分类"	v-if="isSelectType"
+					<el-form-item class="test_cascader_id" label="选择分类"	v-if="!isSelectType"
 						prop="rule_value"
 						:rules="[{ required: true, message: '请选择规则分类', trigger: 'blur' }]"
 					>
@@ -253,7 +250,7 @@ export default {
 	},
 	data() {
 		return {
-			isSelectType:true,//是否选择分类
+			isSelectType:false,//是否选择分类
 			//图片附件
 			Xtoken: { 'X-Token': this.$getToken() },
 			fileList: [],
@@ -475,7 +472,7 @@ export default {
 			const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
 			const isLt2M = file.size / 1024 / 1024 < 1;
 			if (!isJPG) {
-				this.$message.error('上传头像图片只能是 JPG 格式!');
+				this.$message.error('上传头像图片只能是 JPEG,PNG,JPG 格式!');
 			}
 			if (!isLt2M) {
 				this.$message.error('上传头像图片大小不能超过 2MB!');

+ 4 - 7
src/views/common/temporaryTaskAmend.vue

@@ -12,13 +12,10 @@
 						<el-input type="textarea" rows="3" maxlength="20" show-word-limit v-model="formData.task_name" placeholder="请输入任务内容(限20字)"></el-input>
 					</el-form-item>
 					<el-form-item label="指定规则">
-						  <el-radio-group v-model="isSelectType" @change="isSelectTypeC">
-						    <el-radio :label="true">分类</el-radio>
-						    <el-radio :label="false">规则</el-radio>
-						  </el-radio-group>
+						 <el-switch  v-model="isSelectType"></el-switch>
 					</el-form-item>
 					<!-- 选择分类 -->
-					<el-form-item class="test_cascader_id" label="选择分类"	v-if="isSelectType"
+					<el-form-item class="test_cascader_id" label="选择分类"	v-if="!isSelectType"
 						prop="rule_value"
 						:rules="[{ required: true, message: '请选择规则分类', trigger: 'blur' }]"
 					>
@@ -229,7 +226,7 @@ export default {
 	data() {
 		return {
 			//图片附件
-			isSelectType:true,//是否选择分类
+			isSelectType:false,//是否选择分类
 			
 			Xtoken: { 'X-Token': this.$getToken() },
 			fileList: [],
@@ -635,7 +632,7 @@ export default {
 			const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
 			const isLt2M = file.size / 1024 / 1024 < 1;
 			if (!isJPG) {
-				this.$message.error('上传头像图片只能是 JPG 格式!');
+				this.$message.error('上传头像图片只能是 JPEG,PNG,JPG 格式!');
 			}
 			if (!isLt2M) {
 				this.$message.error('上传头像图片大小不能超过 2MB!');

+ 2 - 2
src/views/ranking/attendance_rating.vue

@@ -148,7 +148,7 @@
 	</div>
 </template>
 <script>
-import noData from '@/components/noData';
+
 export default {
 	data() {
 		return {
@@ -258,7 +258,7 @@ export default {
 			}
 		};
 	},
-	components: { noData },
+	
 	watch:{
 		isUpdate(val){
 			if(!val){

+ 1 - 2
src/views/ranking/balanceA.vue

@@ -95,7 +95,7 @@
   </div>
 </template>
 <script>
-import noData from '@/components/noData';
+
 export default {
   data() {
     return {
@@ -135,7 +135,6 @@ export default {
       val == 'balanceA' ? this.getList() : this.getLog();
     }
   },
-  components: {noData},
   methods: {
     resetForm(formName) {
       this.clearAPointShow = false;

+ 0 - 1012
src/views/ranking/custom_rank code.vue

@@ -1,1012 +0,0 @@
-<template>
-	<div class="all-box">
-		<div class="all">
-			<div class="flex-box" v-loading="groups_loading">
-				<div class="terr-left">
-					<el-button v-if="employeeOrdept" size="medium" @click="addGroup" type="primary">新建分组</el-button>
-					<el-menu default-active="0" class="el-menu-vertical-demo" style="border: none" v-if="groups_list.length > 0">
-						<el-menu-item
-							style="height: 47px;line-height: 47px;"
-							:index="index.toString()"
-							class="font-flex-word"
-							v-for="(item, index) in groups_list"
-							:key="index"
-							@click="open_right(item)"
-							v-show="item.code !== 'employee'"
-						>
-							<i class="el-icon-document-copy"></i>
-							<span slot="title">{{ item.name }}</span>
-						</el-menu-item>
-					</el-menu>
-					<div v-else style="text-align: center;margin-top: 10%;" class="fontColorF">
-						<img src="@/assets/image/nodata.png" style="width: 180px;height: 120px;margin: 30px auto;" />
-						还没有自定义分组
-					</div>
-				</div>
-				<div class="terr-right border-right flex-1" v-loading="table_loading">
-					<div class="listData" v-if="table_list.length > 0">
-						<div class="flex-box">
-							<div class="flex-box flex-v-ce margin-bottom">
-								<div class="groupsName">
-									{{ groups_info.name }}
-									<span class="blue">({{ total }}人)</span>
-								</div>
-								<el-button v-if="employeeOrdept" @click="editGroup" size="medium">编辑</el-button>
-							</div>
-						</div>
-						<el-form :model="params" :inline="true" ref="params">
-							<el-form-item label="月份" label-width="40px" v-if="newGroupForm.date_interval == 1">
-								<el-date-picker v-model="time.month" type="month" :clearable="false" placeholder="请选择月份" value-format="yyyy-MM"></el-date-picker>
-							</el-form-item>
-
-							<el-form-item label="年份" label-width="40px" v-if="newGroupForm.date_interval == 3">
-								<el-date-picker v-model="time.year" type="year" :clearable="false" placeholder="请选择年份" value-format="yyyy"></el-date-picker>
-							</el-form-item>
-							<el-form-item label="季度" label-width="40px" v-if="newGroupForm.date_interval == 2">
-								<Season :defaultHint="true" :isActive="true" class="date-picker-width" @confirm="export_quarter_confirm"></Season>
-							</el-form-item>
-
-							<el-form-item><el-checkbox v-model="sort" size="medium" label="由低到高" border></el-checkbox></el-form-item>
-						</el-form>
-						<!-- 表格 -->
-						<el-table :data="table_list" style="width: 100%">
-							<el-table-column label="名次" width="80" align="center">
-								<template slot-scope="scope">
-									<img v-if="scope.row.rank === 1" src="@/assets/image/statistics_NO1.png" alt="" />
-									<img v-if="scope.row.rank === 2" src="@/assets/image/statistics_NO2.png" alt="" />
-									<img v-if="scope.row.rank === 3" src="@/assets/image/statistics_NO3.png" alt="" />
-									<span v-if="scope.row.rank > 3">{{ scope.row.rank }}</span>
-								</template>
-							</el-table-column>
-							<el-table-column label="姓名" align="left">
-								<template slot-scope="scope">
-									<div class="flex-box">
-										<userImage  :user_name="scope.row.name" :img_url="scope.row.img_url" width="50px" height="50px"></userImage>
-										<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.name }}</span>
-									</div>
-								</template>
-							</el-table-column>
-							<el-table-column label="B分" align="left" prop="point"></el-table-column>
-							<template slot="empty">
-								<noData></noData>
-							</template>
-						</el-table>
-						<center style="padding: 20px 0;">
-							<el-pagination
-								background
-								@size-change="handleSizeChange"
-								@current-change="handleCurrentChange"
-								:page-sizes="[10, 20, 50, 100]"
-								layout="total, sizes, prev, pager, next"
-								:page-size="params.page_size"
-								:current-page="params.page"
-								:total="total"
-							></el-pagination>
-						</center>
-					</div>
-					<div v-else style="margin-top: 10%;">
-						<noData :isSolt="true">
-							<template v-slot:default>
-								<div style="text-align: center;">
-									还没有分组
-									<span v-if="employeeOrdept">,</span>
-									<span v-if="employeeOrdept" style="color:#26A2FF;cursor:pointer" @click="addGroup">去添加 >></span>
-								</div>
-							</template>
-						</noData>
-					</div>
-				</div>
-			</div>
-		</div>
-		<!-- 新增编辑分组 -->
-		<el-dialog :title="popupType ? '新增分组' : '编辑分组'" width="660px" top="5%" :visible.sync="groupShow" @close="resetForm('newGroupForm')" :close-on-click-modal="false">
-			<el-form ref="newGroupForm" :model="newGroupForm" :rules="rules" label-width="85px" @submit.native.prevent>
-				<el-form-item label="分组名称" prop="group_name">
-					<el-input v-model="newGroupForm.group_name" placeholder="请输入分组名称" :clearable="true"></el-input>
-				</el-form-item>
-				<el-form-item label="分组成员">
-					<el-input v-model="employeeNames" placeholder="全部成员"></el-input>
-					<div @click="isEmployeeShow = true" style="height:36px; position: absolute; top: 0; right: 0; left: 0; bottom: 0; z-index: 9;cursor:pointer"></div>
-					<el-dialog title="选择人员" width="700px" :visible.sync="isEmployeeShow" append-to-body :before-close="handleClose">
-						<EmployeeSelector
-							v-if="isEmployeeShow"
-							ref="Employee"
-							:user_no_select="false"
-							:selected="employees_selected"
-							:close_clear_data="true"
-							@confirm="move_employee_confirm"
-						/>
-						<span slot="footer" class="dialog-footer">
-							<el-button @click="isEmployeeShow = false">取 消</el-button>
-							<el-button type="primary" @click="submitEmployee()">确 定</el-button>
-						</span>
-					</el-dialog>
-				</el-form-item>
-				<el-form-item label="积分规则">
-					<el-input v-model="newGroupFormRules" placeholder="全部规则分类"></el-input>
-					<div @click="ruleDialogTableVisibles" style="height:36px; position: absolute; top: 0; right: 0; left: 0; bottom: 0; z-index: 9;cursor:pointer"></div>
-					<div style="margin-bottom:12px;">
-						<span style="font-size:13px;color:#8a8a8a;position: absolute; top: 30px; left: 0;">{{ ruleHint }}</span>
-					</div>
-					<el-dialog title="选择规则" width="800px" :visible.sync="ruleDialogTableVisible" append-to-body :before-close="handleClose">
-						<div style="display:flex;position: relative;width:100%;height:40px">
-							<span style="position: absolute;line-height:40px;left:20px">已选:{{ valuesOrLength.length }}条</span>
-							<el-input type="text" class="search" style="position: absolute;right:20px;width:20%" placeholder="输入关键字搜索" v-model.trim="keyword" />
-						</div>
-						<el-row class="architecture">
-							<el-col :span="8" class="RuleLeft" style="height:500px">
-								<div class="rule_class_box">
-									<el-tree
-										ref="menum"
-										class="cate-tree"
-										node-key="id"
-										:accordion="true"
-										:highlight-current="true"
-										:data="rule_trees"
-										:default-expand-all="false"
-										:props="defaultProps"
-										:expand-on-click-node="false"
-										@node-click="handleNodeClick"
-									>
-										<div content="tree" v-if="!data.dis" v-show="rule_trees.length != 0" slot-scope="{ node, data }">
-											<span class="name">{{ data.name }}</span>
-										</div>
-									</el-tree>
-								</div>
-							</el-col>
-							<el-col :span="16" class="RuleRight" v-loading="tableLoadingRule" style="height:500px;overflow-y:auto">
-								<el-table
-									ref="multipleTable"
-									:data="tableData_rule"
-									tooltip-effect="dark"
-									style="width: 100%;cursor:pointer"
-									@select="onTableSelect"
-									@select-all="selectAll"
-									@cell-click="clicktable"
-								>
-									<el-table-column type="selection" width="55"></el-table-column>
-									<el-table-column prop="remark" :label="'全选'" show-overflow-tooltip></el-table-column>
-								</el-table>
-							</el-col>
-						</el-row>
-						<span slot="footer" class="dialog-footer">
-							<el-button @click="ruleDialogTableVisible = false">取 消</el-button>
-							<el-button type="primary" @click="ruleDialogTableVisibleQD">确 定</el-button>
-						</span>
-					</el-dialog>
-				</el-form-item>
-
-				<el-form-item label="统计周期" label-width="85px" prop="date_interval" :show-message="false">
-					<el-select v-model="newGroupForm.date_interval" placeholder="请选择周期">
-						<el-option v-for="item in options_time" :key="item.value" :label="item.label" :value="item.value"></el-option>
-					</el-select>
-				</el-form-item>
-			</el-form>
-			<div class="flex-box flex-v-ce">
-				<el-button type="danger" v-if="!popupType" :disabled="delLoad" :loading="delLoad" @click="delItem">删除</el-button>
-				<div class="flex-1"></div>
-				<el-button @click="resetForm('newGroupForm')">取 消</el-button>
-				<el-button type="primary" :loading="saveLoad" :disabled="saveLoad" @click="subGroupForm('newGroupForm')">确 定</el-button>
-			</div>
-		</el-dialog>
-	</div>
-</template>
-
-<script>
-import EmployeeSelector from '@/components/EmployeeSelector.vue';
-import noData from '@/components/noData';
-import moment from 'moment';
-var selecteds = [];
-let selectionID = [];
-export default {
-	components: { EmployeeSelector, noData },
-	data() {
-		return {
-			page: 1,
-			page_size: 10,
-			total: null,
-			tips_show: false,
-			groups_list: [],
-			groups_loading: false,
-			table_loading: false,
-			table_list: [],
-			time: {
-				year: moment().format('YYYY'), //年
-				quarter: moment().format('YYYYQ'), //季度
-				month: moment().format('YYYY-MM') //月
-			},
-			groups_info: {
-				name: '',
-				employees: []
-			},
-			//
-			params: {
-				page: 1,
-				page_size: 10,
-				group_id: '',
-				// month: moment().format('YYYY-MM'),
-				sort: 'asc'
-				// rule_id: '',
-			},
-			rule_trees: [],
-			clickItem: null,
-			groupShow: false,
-			rules: {
-				group_name: [{ required: true, message: '请输入分组名称', trigger: 'blur' }, { min: 2, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }],
-				date_interval: [{ required: true, message: '请选择周期', trigger: 'change' }]
-			},
-			newGroupForm: {
-				group_name: '',
-				employees: [],
-				items: [],
-				date_interval: '1'
-			},
-			saveLoad: false,
-			delLoad: false,
-			show_employee_selector: false,
-			employee_not_select: [],
-			employees_selected: { employee: [], dept: [] },
-			props: { checkStrictly: true, value: 'id', label: 'name', children: 'child' },
-			sort: false,
-
-			popupType: false,
-
-			// 添加分组(第二期内容添加)
-			ruleDialogTableVisible: false,
-			defaultProps: {
-				children: 'child',
-				label: 'name'
-			},
-			tableLoadingRule: false,
-			tableData_rule: [],
-			options_time_value: '',
-			options_time: [
-				{
-					value: '1',
-					label: '月度'
-				},
-				{
-					value: '2',
-					label: '季度'
-				},
-				{
-					value: '3',
-					label: '年度'
-				}
-			],
-			newGroupFormRules: '',
-			ruleHint: '统计所有积分(基础分和工龄分除外)',
-			valuesOrLength: [],
-			keyword: '',
-			treedata: [],
-			isEmployeeShow: false,
-			employeeNames: '',
-			employeeOrdept: !this.$authoritys('employee') && !this.$authoritys('dept_manager')
-		};
-	},
-	created() {
-		this.getRuleList();
-		this.get_groups_list(true);
-	},
-	watch: {
-		'params.rule_id'() {
-			this.$refs.rule.dropDownVisible = false;
-		},
-
-		'time.month'(val, old_val) {
-			this.time.month = val;
-			this.params.page = 1;
-			this.open_right(this.clickItem);
-		},
-		'time.year'(val, old_val) {
-			this.time.year = val;
-			this.params.page = 1;
-			this.open_right(this.clickItem);
-		},
-		sort(val) {
-			this.params.page = 1;
-			val ? (this.params.sort = 'desc') : (this.params.sort = 'asc');
-			this.open_right(this.clickItem);
-		},
-		keyword() {
-			//函数节流
-			if (this.timer) {
-				clearTimeout(this.timer);
-			}
-			//清空 全部
-			if (!this.keyword) {
-				this.tableData_rule = this.tableData_rule2;
-				this.ifPitchOnChild(this.tableData_rule, selecteds);
-				return;
-			}
-			this.timer = setTimeout(() => {
-				const result = [];
-				this.tableData_rule2.forEach(val => {
-					if (val.remark.indexOf(this.keyword) > -1) {
-						result.push(val);
-					}
-				});
-				this.tableData_rule = result;
-				this.ifPitchOnChild(this.tableData_rule, selecteds);
-			}, 100);
-		}
-	},
-	mounted() {},
-	methods: {
-		// 第二期内容
-
-		//
-		submitEmployee() {
-			this.$refs.Employee.confirm(); //调用组件的confirm();
-		},
-		//点击规则弹出窗口
-		ruleDialogTableVisibles() {
-			this.tableLoadingRule = true;
-			selecteds = this.valuesOrLength;
-			//点击弹出窗口并展示所有数据
-			let tableData_r = [];
-			for (let i in this.itemList) {
-				for (let a in this.itemList[i]) {
-					tableData_r.push(this.itemList[i][a]);
-				}
-			}
-			this.tableData_rule2 = tableData_r; //赋予筛选数据
-			this.tableData_rule = tableData_r;
-			this.ruleDialogTableVisible = true;
-			this.ifPitchOnChild(this.tableData_rule, selecteds);
-		},
-
-		//规则弹窗确定
-		ruleDialogTableVisibleQD() {
-			let valuesLengths = [];
-			for (let i in selecteds) {
-				valuesLengths.push(selecteds[i]);
-			}
-			this.valuesOrLength = valuesLengths;
-			this.newGroupForm.items = this.valuesOrLength;
-			if (this.valuesOrLength.length >= 1) {
-				this.newGroupFormRules = this.valuesOrLength.length + '条规则';
-				this.ruleHint = '统计已选规则的积分(只选分类不指定规则的积分除外)';
-			} else {
-				this.newGroupFormRules = '';
-				this.ruleHint = '统计所有积分(基础分和工龄分除外)';
-			}
-			this.ruleDialogTableVisible = false;
-		},
-		//点击某行
-		clicktable(row, column, cell, event) {
-			let selectedsif = false;
-			for (let i in selecteds) {
-				if (row.id == selecteds[i]) {
-					selectedsif = true;
-					selecteds.splice(i, 1);
-					this.toggleSelection([row], false);
-				}
-			}
-			if (selectedsif == false) {
-				selecteds.push(row.id);
-				this.ifPitchOnChild(this.tableData_rule, selecteds);
-			}
-		},
-		//全选
-		selectAll(selection) {
-			for (let i in selection) {
-				selectionID.push(selection[i].id);
-			}
-			let tableData_rules = []; //当前分页id
-			for (let i in this.tableData_rule) {
-				tableData_rules.push(this.tableData_rule[i].id);
-			}
-			selectionID = [...new Set(selectionID)];
-			if (selection.length == 0) {
-				//全不选
-				var diff = [];
-				var tmp = tableData_rules;
-				selectionID.forEach(function(val1, i) {
-					if (tableData_rules.indexOf(val1) < 0) {
-						diff.push(val1);
-					} else {
-						tmp.splice(tmp.indexOf(val1), 1);
-					}
-				});
-				selectionID = diff.concat(tmp);
-			}
-			selecteds = [...new Set(selectionID)];
-			this.valuesOrLength = selecteds;
-		},
-		onTableSelect(rows, row) {
-			let selected = rows.length && rows.indexOf(row) !== -1;
-			if (selected) {
-				selecteds.push(row.id);
-			} else {
-				for (let i in selecteds) {
-					if (row.id == selecteds[i]) {
-						selecteds.splice(i, 1);
-					}
-				}
-			}
-		},
-		//关闭
-		handleClose(done) {
-			done();
-		},
-		// 选择时间-季度
-		export_quarter_confirm(val) {
-			this.time.quarter = val;
-			this.params.page = 1;
-			this.open_right(this.clickItem);
-		},
-		//此方法:拿到当前点击规则分类的所有子节点ID,(为了包含子分类 规则)
-		menuIdInit(menus) {
-			var _this = this;
-			var _menu = menus;
-			var menuId = [];
-			var len = _menu.length;
-			for (var i = 0; i < len; i++) {
-				var item = _menu[i];
-				if (item.child && item.child.length != 0) {
-					var child = item.child;
-					for (var j = 0; j < child.length; j++) {
-						_menu[len + j] = child[j];
-					}
-					len = _menu.length;
-				}
-				menuId.push(item.id);
-			}
-			return menuId;
-		},
-		//点击规则分类
-		handleNodeClick(data) {
-			let dataArr = this.menuIdInit([data]); //调用方法
-			this.tableLoadingRule = true;
-			this.keyword = ''; //切换规则重置搜索框
-			let tableData_r = [];
-			for (let i in this.itemList) {
-				for (let a in this.itemList[i]) {
-					for (let x in dataArr) {
-						if (dataArr[x] == this.itemList[i][a].rule_id) {
-							tableData_r.push(this.itemList[i][a]);
-						}
-					}
-				}
-			}
-			this.tableData_rule2 = tableData_r; //赋予筛选数据
-			this.tableData_rule = tableData_r;
-			this.ifPitchOnChild(this.tableData_rule, selecteds);
-		},
-		ifPitchOnChild(item, indexID) {
-			let pitchOnChild = [];
-			for (let i in item) {
-				for (let a in indexID) {
-					//判断外层的值相不相等
-					if (indexID[a] == item[i].id) {
-						pitchOnChild.push(item[i]);
-					}
-				}
-			}
-			this.toggleSelection(pitchOnChild, true);
-		},
-		//默认选中
-		toggleSelection(rows, selected) {
-			if (rows) {
-				this.$nextTick(() => {
-					rows.forEach(row => {
-						this.$refs.multipleTable.toggleRowSelection(row, selected);
-					});
-				});
-			} else {
-				this.$refs.multipleTable.clearSelection();
-			}
-			setTimeout(() => {
-				//给遮到层,让默认选中的有缓冲时间
-				this.tableLoadingRule = false;
-			}, 300);
-		},
-
-		// 提交表单
-		subGroupForm(formName) {
-			this.$refs[formName].validate(valid => {
-				if (valid) {
-					this.saveFun();
-				}
-			});
-		},
-		//获取分组详情
-		getGroupDetail(func) {
-			this.$axios('get', '/api/integral/statistics/groups/info', { group_id: this.groups_info.id }).then(res => {
-				func(res.data.data);
-			});
-		},
-		//编辑
-		editGroup() {
-			var that = this;
-			this.getGroupDetail(function(res) {
-				that.groups_info = res;
-				// 分组名称
-				that.newGroupForm.group_name = res.name;
-
-				// 规则
-				that.newGroupForm.items = [];
-				for (let i in res.items) {
-					that.newGroupForm.items.push(res.items[i].id);
-				}
-				that.valuesOrLength = that.newGroupForm.items;
-				if (that.valuesOrLength.length >= 1) {
-					that.newGroupFormRules = that.valuesOrLength.length + '条规则';
-					that.ruleHint = '统计已选规则的积分(只选分类不指定规则的积分除外)';
-				} else {
-					that.newGroupFormRules = '';
-					that.ruleHint = '统计所有积分(基础分和工龄分除外)';
-				}
-
-				// 统计周期
-				that.newGroupForm.date_interval = String(res.date_interval);
-				that.options_time_value = res.date_interval == 1 ? '月度' : res.date_interval == 2 ? '季度' : res.date_interval == 3 ? '年度' : '';
-
-				// 分组人员
-				that.newGroupForm.employees = [];
-				that.employeeNames = '';
-				res.employees.forEach(element => {
-					that.newGroupForm.employees.push(element.id);
-					that.employeeNames += element.name + ',';
-				});
-				that.employees_selected.employee = res.employees;
-
-				that.popupType = false;
-				that.groupShow = true;
-			});
-		},
-		//添加编辑组
-		saveFun() {
-			this.saveLoad = true;
-			var url = this.popupType ? '/api/integral/statistics/groups/create' : '/api/integral/statistics/groups';
-			this.newGroupForm.group_id = this.groups_info.id;
-			// return;
-			var obj = {
-				//为编辑时
-				name: this.newGroupForm.group_name,
-				id: this.popupType ? '' : this.groups_info.id,
-				employees: this.newGroupForm.employees
-			};
-			this.$axios('post', url, this.newGroupForm)
-				.then(res => {
-					if (res.data.code == 1) {
-						this.$message.success(res.data.msg);
-						if (!this.popupType) {
-							//为编辑时
-							this.groups_info = obj;
-						}
-						if (this.groups_list.length == 0) {
-							this.get_groups_list(true);
-						} else {
-							this.get_groups_list();
-						}
-						this.resetForm('newGroupForm');
-					} else {
-						this.saveLoad = false;
-						this.$message.error(res.data.msg);
-					}
-				})
-				.finally(() => {
-					this.saveLoad = false;
-				});
-		},
-		// 重置表单
-		resetForm(formName) {
-			this.$refs[formName].resetFields();
-			this.newGroupForm.employees = [];
-			this.employee_not_select = [];
-			this.employeeNames = '';
-			this.employees_selected = { employee: [], dept: [] };
-			this.groupShow = false;
-		},
-		// 新增分组
-		addGroup() {
-			this.employee_not_select = [];
-			this.newGroupFormRules = '';
-			this.employees_selected = { employee: [], dept: [] };
-			this.newGroupForm = {
-				group_name: '',
-				employees: [],
-				items: [],
-				date_interval: '1'
-			};
-			this.groupShow = true;
-			this.popupType = true;
-		},
-		// 删除分组
-		delItem() {
-			this.$confirm('确定要删除当前分组吗?, 是否继续?', '删除分组', {
-				confirmButtonText: '确定',
-				cancelButtonText: '取消',
-				type: 'warning'
-			}).then(() => {
-				let data = { group_id: this.groups_info.id };
-				this.delLoad = true;
-				this.$axios('post', '/api/integral/statistics/groups/drop', data)
-					.then(res => {
-						if (res.data.code == 1) {
-							this.$message.success(res.data.msg);
-							this.groupShow = false;
-							this.get_groups_list(true);
-						} else {
-							this.$message.error(res.data.msg);
-						}
-					})
-					.finally(() => {
-						this.delLoad = false;
-					});
-			});
-		},
-
-		// 选人组件提交
-		move_employee_confirm(data) {
-			this.employeeNames = '';
-			this.newGroupForm.employees = [];
-			var employee = data.employee;
-			if (employee.length > 0) {
-				employee.forEach(item => {
-					this.employeeNames += item.name + ',';
-					this.newGroupForm.employees.push(item.id);
-				});
-			} else {
-				this.newGroupForm.employees = [];
-			}
-			this.employees_selected.employee = employee;
-			this.isEmployeeShow = false;
-		},
-		// 递归判断列表,把最后的children设为undefined
-		getTreeData(data) {
-			for (var i = 0; i < data.length; i++) {
-				if (data[i].child.length < 1) {
-					// children若为空数组,则将children设为undefined
-					data[i].child = undefined;
-				} else {
-					// children若不为空数组,则继续 递归调用 本方法
-					this.getTreeData(data[i].child);
-				}
-			}
-			return data;
-		},
-		//获取规则
-		getRuleList() {
-			this.$axios('get', '/api/integral/rule/trees', { cycle_type: 1 }).then(res => {
-				this.rule_trees = this.getTreeData(res.data.data.rule_tree || []);
-				this.itemList = res.data.data.item_list; //规则
-			});
-		},
-		// 规则分类改变之后请求数据
-		rule_null(val) {
-			this.params.rule_id = val.length == 0 ? '' : val[val.length - 1];
-			this.$nextTick(() => {
-				this.page = 1;
-				this.open_right();
-			});
-		},
-		//获取初始化数据
-		get_groups_list(isAdd) {
-			this.groups_loading = true;
-			this.$axios('get', '/api/integral/statistics/groups')
-				.then(res => {
-					if (res.data.code == 1) {
-						let lists = res.data.data.list;
-						if (this.$authoritys('employee')) {
-							//员工权限只能查看包含自己的
-							let user = this.$getUserData().id;
-							let data = [];
-							lists.forEach(item => {
-								if (item.employees.length == 0) {
-									data.push(item);
-								} else {
-									if (item.employees.indexOf(user.toString()) != -1) {
-										data.push(item);
-									}
-								}
-							});
-							this.groups_list = data;
-						} else {
-							this.groups_list = lists;
-						}
-						if (this.groups_list[0]) {
-							isAdd ? this.open_right(this.groups_list[0]) : this.open_right();
-						} else {
-							this.table_list = [];
-						}
-					}
-				})
-				.finally(() => {
-					this.groups_loading = false;
-				});
-		},
-		// 打开右边列表
-		open_right(item) {
-			this.table_loading = true;
-			this.clickItem = item;
-			if (!item) {
-				this.table_loading = false;
-				return false;
-			}
-			let data = JSON.parse(JSON.stringify(this.params));
-			data.rule ? '' : delete data.rule;
-			data.group_id = item.id;
-			let months;
-			if (this.newGroupForm.date_interval == '1') {
-				months = this.time.month.replace('-', '');
-			}
-			data.date =
-				this.newGroupForm.date_interval == '1'
-					? months
-					: this.newGroupForm.date_interval == '2'
-					? this.time.quarter
-					: this.newGroupForm.date_interval == '3'
-					? this.time.year
-					: '';
-			// var data={};
-			// if(item){
-			// 	this.groups_info=item;
-			// 	data={
-			// 		group_id: item.id,
-			// 		month: this.params.month,
-			// 		sort: this.params.sort,
-			// 		rule_id: this.params.rule_id,
-			// 		pt_id: 3,
-			// 	}
-			// }else{
-			// 	data={
-			// 		group_id: this.groups_info.id,
-			// 		month: this.params.month,
-			// 		sort: this.params.sort,
-			// 		rule_id: this.params.rule_id,
-			// 		pt_id: 3,
-			// 	}
-			// }
-
-			// this.$axios('get','/api/integral/statistics/groups/rank',data).then((res) => {
-			// 	if (res.data.code == 1) {
-			// 			this.table_list = res.data.data.list
-			// 			this.total = res.data.data.total
-			// 	}else{
-			// 	  this.$message.error(res.data.data.msg)
-			// 	}
-			// }).finally(() => {
-			//     this.table_loading = false
-			// })
-			this.$axios('get', '/api/integral/statistics/groups/rank', data)
-				.then(res => {
-					if (res.data.code == 1) {
-						this.table_list = res.data.data.list;
-						this.total = res.data.data.total;
-						// this.lastUpdateTime = res.data.data.update_time;
-					} else {
-						this.$message.error(res.data.data.msg);
-					}
-				})
-				.finally(() => {
-					this.table_loading = false;
-				});
-			// this.$axios('get','/api/integral/statistics/ranking',data,'v2').then((res) => {
-			// 	if (res.data.code == 1) {
-			// 			this.table_list = res.data.data.list
-			// 			this.total = res.data.data.total
-			// 	}else{
-			// 	this.$message.error(res.data.data.msg)
-			// 	}
-			// }).finally(() => {
-			// 	this.table_loading = false
-			// })
-		},
-		// 页码变更
-		handleCurrentChange(val) {
-			this.params.page = val;
-			this.open_right(this.groups_info);
-		},
-		handleSizeChange(val) {
-			this.params.page_size = val;
-			this.open_right(this.groups_info);
-		}
-	}
-};
-</script>
-
-<style scoped lang="scss">
-.architecture {
-	display: flex;
-	text-align: center;
-	padding-left: 0px;
-	background-color: #fff;
-	width: 100%;
-	overflow: hidden;
-	cursor: default;
-	min-height: calc(60vh - 160px);
-}
-.architecture .RuleLine {
-	display: table-cell;
-	width: 1px;
-	min-height: 600px;
-	background: hsl(0, 2%, 76%);
-}
-.architecture .RuleLeft {
-	display: block;
-	text-align: center;
-	padding: 20px 10px;
-	border-right: none;
-	overflow-y: auto;
-	overflow-x: none;
-}
-/*滚动条的宽度*/
-
-.architecture .RuleLeft::-webkit-scrollbar {
-	width: 9px;
-	height: 9px;
-}
-.architecture .RuleRight::-webkit-scrollbar {
-	width: 9px;
-	height: 9px;
-}
-
-/*外层轨道。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果*/
-
-.architecture .RuleLeft::-webkit-scrollbar-track {
-	width: 6px;
-	background-color: #fff0;
-	-webkit-border-radius: 2em;
-	-moz-border-radius: 2em;
-	border-radius: 2em;
-}
-.architecture .RuleRight::-webkit-scrollbar-track {
-	width: 6px;
-	background-color: #fff0;
-	-webkit-border-radius: 2em;
-	-moz-border-radius: 2em;
-	border-radius: 2em;
-}
-
-/*滚动条的设置*/
-
-.architecture .RuleLeft::-webkit-scrollbar-thumb {
-	background-color: #fff0;
-	background-clip: padding-box;
-	min-height: 28px;
-	-webkit-border-radius: 2em;
-	-moz-border-radius: 2em;
-	border-radius: 2em;
-}
-.architecture .RuleRight::-webkit-scrollbar-thumb {
-	background-color: #fff0;
-	background-clip: padding-box;
-	min-height: 28px;
-	-webkit-border-radius: 2em;
-	-moz-border-radius: 2em;
-	border-radius: 2em;
-}
-/*滚动条移上去的背景*/
-
-.architecture .RuleLeft:hover::-webkit-scrollbar-thumb {
-	overflow-x: none;
-	background-color: rgba(144, 147, 153, 0.3);
-}
-.architecture .RuleRight:hover::-webkit-scrollbar-thumb {
-	background-color: rgba(115, 118, 124, 0.3);
-}
-
-.architecture .RuleLeft .company_name {
-	position: relative;
-	display: block;
-	font-family: 'Microsoft YaHei';
-	text-align: left;
-	padding: 15px 28px 17px;
-	cursor: pointer;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-	border-bottom: 1px #f8f8f8 solid;
-}
-.architecture .RuleLeft .company_name img {
-	position: relative;
-	display: inline-block;
-	top: 2px;
-	width: 18px;
-	height: 18px;
-	margin-right: 4px;
-}
-.architecture .RuleLeft ::v-deep .el-button {
-	margin-bottom: 16px !important;
-}
-.architecture .RuleRight {
-	position: relative;
-	display: table-cell;
-	text-align: left;
-	padding: 20px;
-}
-.architecture .RuleRight .title span .sapn {
-	display: inline-block;
-	vertical-align: middle;
-	max-width: 600px;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-}
-.architecture .RuleRight:after {
-	content: ' ';
-	position: absolute;
-	top: 0;
-	left: 0;
-	bottom: 0;
-	width: 1px;
-	background: #ebeef5;
-}
-.architecture .RuleRight .list_box {
-	width: 100%;
-	background: #fff;
-}
-.architecture .RuleRight .list_box ::v-deep table {
-	font-family: 'Microsoft YaHei';
-	width: 100% !important;
-}
-::v-deep .el-radio .el-radio__label {
-	display: none;
-}
-.tips {
-	background: #dcdfe6;
-	border-radius: 50%;
-	width: 14px;
-	height: 14px;
-	color: #fff;
-	display: inline-block;
-	font-size: 12px;
-	line-height: 14px;
-	text-align: center;
-}
-.groupsName {
-	font-size: 18px;
-	margin-right: 20px;
-}
-.groupsName span {
-	margin-left: 5px;
-}
-
-.user_text {
-	font-size: 12px;
-}
-.cursor_pointer {
-	cursor: pointer;
-}
-.terr-left button {
-	margin: 0 auto;
-	display: block;
-	margin-bottom: 20px;
-}
-::v-deep .el-menu-item {
-	padding: 0 10px !important;
-}
-.rule_class_box {
-	::v-deep .el-tree-node {
-		border-bottom: 1px #f8f8f8 solid;
-	}
-	::v-deep .el-tree-node__content {
-		padding: 10px 0;
-		// border-bottom: 1px #f8f8f8 solid;
-	}
-	::v-deep .el-tree-node__content:hover {
-		background: #ecf5ff;
-		border-radius: 4px;
-	}
-	::v-deep .is-current .el-tree-node__content .el-icon-caret-right {
-		color: #409eff !important;
-	}
-	::v-deep .is-current .el-tree-node__content .el-tree-node__label {
-		color: #409eff !important;
-	}
-	::v-deep .is-current .el-tree-node__children .el-icon-caret-right {
-		color: #c0c4cc !important;
-	}
-	::v-deep .is-current .el-tree-node__children .el-tree-node__label {
-		color: #606266 !important;
-	}
-	::v-deep .el-tree-node__label {
-		overflow: hidden;
-		text-overflow: ellipsis;
-		white-space: nowrap;
-	}
-}
-</style>

+ 1 - 1
src/views/ranking/dept_rank.vue

@@ -69,7 +69,7 @@
 					  ></el-cascader>-->
 				</el-form-item>
 				<el-form-item label="谁不参与排名">
-					<el-select v-model="formData.exclusion" size="medium" multiple filterable collapse-tags placeholder="请选择员工">
+					<el-select v-model="formData.exclusion" size="medium" clearable multiple filterable collapse-tags placeholder="请选择员工">
 						<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
 					</el-select>
 				</el-form-item>

+ 3 - 3
src/views/ranking/integral_event.vue

@@ -70,7 +70,7 @@
 			
 			<!-- 表格 -->
 			<div>
-				<el-table :data="list" style="width: 100%" v-loading="loading" @row-click="open_detail" @selection-change="deleteEvents">
+				<el-table :data="list" style="width: 100%;cursor: pointer;" v-loading="loading" @row-click="open_detail" @selection-change="deleteEvents">
 					<el-table-column v-if="employeeOrdept" type="selection" width="55"></el-table-column>
 					<el-table-column prop="employee_name" label="姓名" align="left" min-width="125px">
 						<template slot-scope="scope">
@@ -357,7 +357,7 @@
 	</div>
 </template>
 <script>
-import noData from '@/components/noData';
+
 import Steps from '@/components/Steps';
 import toLead from '@/components/toLead';
 export default {
@@ -422,7 +422,7 @@ export default {
 			]
 		};
 	},
-	components: { noData, Steps, toLead },
+	components: {Steps, toLead },
 	mounted() {
 		this.deriveRestrict()
 		this.getDepartment();

+ 354 - 167
src/views/ranking/log_rank.vue

@@ -1,35 +1,94 @@
 <template>
 	<div>
-		<div class="all" v-loading="attendload">
+		<div class="all">
 			<div>
 				<el-form :inline="true">
-					<el-form-item label="人员">
-						<el-select v-model="formData.employeeID" size="medium" multiple filterable collapse-tags placeholder="请选择员工">
-							<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
+					<el-form-item label="时间">
+						<el-select size="medium" v-model="time_type" placeholder="请选择分类" style="width: 100px;">
+							<el-option v-for="item in time_types" :key="item.label" :label="item.label" :value="item.value"></el-option>
 						</el-select>
 					</el-form-item>
-
-					<el-form-item label="时间">
+					<el-form-item>
 						<el-date-picker
-							style="width:290px"
-							class="first-element-btn"
-							:clearable="false"
-							v-model="time_range"
+							size="medium"
+							v-show="time_type == '1' || time_type == '月份'"
+							v-model="formData.month"
+							class="date-picker-width"
+							type="month"
+							value-format="yyyy-MM"
+							placeholder="选择月份排名"
+						></el-date-picker>
+						<el-date-picker
+							size="medium"
+							v-show="time_type == '2'"
+							v-model="formData.year"
+							class="date-picker-width"
+							type="year"
+							value-format="yyyy"
+							placeholder="选择年份排名"
+						></el-date-picker>
+						<season v-if="time_type == '3'" :isActive="true" class="date-picker-width" @confirm="export_quarter_confirm"></season>
+						<el-date-picker
+							size="medium"
+							v-show="time_type == '4'"
+							class="date-picker-width"
+							v-model="formData.time_range"
 							type="daterange"
+							format="yyyy 年 MM 月 dd 日"
 							value-format="yyyy-MM-dd"
 							range-separator="至"
 							start-placeholder="开始日期"
 							end-placeholder="结束日期"
-							:picker-options="instantPickerOptions"
-							@change="onFilterChanged"
 						></el-date-picker>
 					</el-form-item>
+					<el-form-item label="部门">
+						<el-cascader
+							size="medium"
+							class="date-picker-width"
+							v-model="dept_name"
+							:options="dept_tree"
+							:props="{ checkStrictly: true, value: 'id', label: 'name', children: '_child' }"
+							ref="dept"
+							clearable
+							filterable
+							placeholder="全公司"
+						></el-cascader>
+					</el-form-item>
+<!-- 					<el-form-item label="谁不参与排名">
+						<el-select v-model="formData.exclusion" size="medium" multiple filterable clearable collapse-tags placeholder="请选择员工">
+							<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item> -->
+<!-- 					<el-form-item label="规则分类">
+						<el-cascader
+							size="medium"
+							class="date-picker-width"
+							v-model="rule_id"
+							:options="rule_trees"
+							:props="props2"
+							ref="rule_id"
+							clearable
+							placeholder="请选择规则分类"
+						></el-cascader>
+					</el-form-item>
+					<el-form-item label="积分分类">
+						<el-select class="date-picker-width" size="medium" v-model="formData.pt_id" placeholder="请选择积分分类">
+							<el-option v-for="item in point_types" :key="item.name" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item> -->
+	<!-- 				<el-form-item label="人员">
+						<el-select size="medium" v-model="formData.position" style="width:150px" placeholder="请选择">
+							<el-option v-for="item in positions" :key="item.age" :label="item.name" :value="item.age"></el-option>
+						</el-select>
+					</el-form-item> -->
 					<el-form-item>
-						<el-button type="primary" plain @click="exportRanking">导出排名</el-button>
+						<el-checkbox v-model="sort" size="medium" label="排名由低到高" border></el-checkbox>
+						<!-- <el-button type="primary" size="medium" @click="selectBtn" style="margin-left:20px">查询</el-button> -->
 					</el-form-item>
+					<el-form-item><el-button type="primary" size="medium" plain @click="dialogVisible = true">导出排名</el-button></el-form-item>
 				</el-form>
 			</div>
-			<el-table :data="all_integral_list" style="width: 100%" v-loading="loading">
+			<el-table :data="list" style="width: 100%" v-loading="loading">
 				<el-table-column label="名次" width="100" align="center">
 					<template slot-scope="scope">
 						<img v-if="scope.row.rank === 1" src="@/assets/image/statistics_NO1.png" alt />
@@ -41,224 +100,357 @@
 				<el-table-column label="姓名" align="left">
 					<template slot-scope="scope">
 						<div style="display:flex;">
-							<userImage :user_name="scope.row.name" :img_url="scope.row.img_url" width="50px" height="50px"></userImage>
-							<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.name }}</span>
+							<userImage :user_name="scope.row.employee_name" :img_url="scope.row.employee_img_url" width="50px" height="50px"></userImage>
+							<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.employee_name }}</span>
 						</div>
 					</template>
 				</el-table-column>
-				<el-table-column prop="point" label="B分" align="left">
+				<el-table-column prop="point" label="日志分" align="left">
 					<template slot-scope="scope">
 						<b style="font-size:15px;color:#909399">{{ scope.row.point }}</b>
 					</template>
 				</el-table-column>
 				<template slot="empty">
-					<noData :content="checkingInGroup.length == 0 ? '请先开启钉钉考勤' : '暂无数据'"></noData>
+					<noData></noData>
 				</template>
 			</el-table>
 			<center style="padding: 20px 0;">
 				<el-pagination
 					background
-					@size-change="handleSizeChange1"
+					@size-change="handleSizeChange"
 					@current-change="handleCurrentChange"
 					:current-page="formData.page"
 					:page-sizes="[10, 20, 50, 100]"
 					layout="total, sizes, prev, pager, next"
-					:page-size="pageLimit1"
+					:page-size="formData.page_size"
 					:total="total"
 				></el-pagination>
 			</center>
-		</div>
+		
 		<!-- 导出弹窗 -->
-		<el-dialog title="导出排名" :visible.sync="dialogVisible" width="730px">
-			<div style="font-size:15px;margin:20px 0 20px 0;">系统将按以下已选条件导出对应的排名报表</div>
-			<div v-loading="exportLoad">
-				<el-form :inline="true">
-					<el-form-item label="考勤组">
-						<el-select v-model="exportData.group_id" @change="selectgroupId" filterable :clearable="false" placeholder="请选择考勤组">
-							<el-option v-for="item in checkingInGroup" :key="item.id" :label="item.name" :value="item.id"></el-option>
-						</el-select>
-					</el-form-item>
-
-					<el-form-item label="排名类型">
-						<el-select v-model="exportData.event_type" style="width:150px" placeholder="请选择">
-							<el-option v-for="(item, index) in event_type" :key="index" :label="item.name" :value="item.id"></el-option>
-						</el-select>
-					</el-form-item>
-
+		<el-dialog title="导出排名" :visible.sync="dialogVisible" width="730px" top="10%">
+			<div style="font-size:15px;margin-bottom: 20px;">系统将按以下已选条件导出对应的排名报表</div>
+			<el-form :inline="true">
+				<div class="picker_er">
 					<el-form-item label="时间">
 						<el-date-picker
-							class="first-element-btn"
-							:clearable="false"
-							v-model="exportTime_range"
+							v-model="Dc_Data.value1"
 							type="daterange"
-							value-format="yyyy-MM-dd"
+							size="medium"
+							value-format="timestamp"
 							range-separator="至"
 							start-placeholder="开始日期"
 							end-placeholder="结束日期"
-							:picker-options="instantPickerOptions"
 						></el-date-picker>
 					</el-form-item>
-				</el-form>
-				<span class="dialog-footer" style="display:flex;justify-content: flex-end;">
-					<el-button @click="dialogVisible = false">取 消</el-button>
-					<el-button type="primary" @click="exportExcel">导 出</el-button>
-				</span>
-			</div>
+<!-- 					<el-form-item label="人员" style="margin-left:30px">
+						<el-select size="medium" v-model="Dc_Data.DC_position" style="width:150px" placeholder="请选择">
+							<el-option v-for="item in positions" :key="item.id" :label="item.name" :value="item.age"></el-option>
+						</el-select>
+					</el-form-item> -->
+				</div>
+				<el-form-item label="部门">
+					<el-cascader
+						class="date-picker-width cascader_bm"
+						v-model="Dc_Data.dept_name"
+						:options="dept_tree"
+						:props="{ checkStrictly: true, value: 'id', label: 'name', children: '_child' }"
+						ref="dept2"
+						size="medium"
+						clearable
+						filterable
+						placeholder="全公司"
+					></el-cascader>
+				</el-form-item>
+<!-- 				<el-form-item label="积分分类">
+					<el-select  style="width: 80px;" size="medium" v-model="Dc_Data.pt_id" placeholder="请选择积分分类">
+						<el-option v-for="item in point_types" :key="item.name" :label="item.name" :value="item.id"></el-option>
+					</el-select>
+				</el-form-item>
+				<el-form-item label="规则分类" style="margin-left:20px">
+					<el-cascader
+						class="date-picker-width"
+						@change="ruleInquiredialog"
+						v-model="rule_ids"
+						:options="rule_trees"
+						:props="props"
+						size="medium"
+						ref="derive"
+						clearable
+						collapse-tags
+						placeholder="请选择规则分类"
+					></el-cascader>
+				</el-form-item> -->
+			</el-form>
+			<span slot="footer" class="dialog-footer">
+				<el-button @click="dialogVisible = false" size="medium">取 消</el-button>
+				<el-button type="primary" @click="exportExcel" size="medium">导 出</el-button>
+			</span>
 		</el-dialog>
+		</div>
 	</div>
 </template>
 <script>
-import noData from '@/components/noData';
+import season from '@/components/season';
 export default {
+	components: { season },
 	data() {
 		return {
+			// 导出
+			Dc_Data: {
+				//导出数据
+				value1: '', //时间
+				DC_position: '全部', //人员
+				dept_name: [], //部门
+				rule_id: [] ,//规则
+				pt_id: 3,
+			},
+			rule_ids: null,
+			
 			employee_map: JSON.parse(localStorage.getItem('SET_EMPLOYEE_MAP')),
-			exportLoad: false,
-			dialogVisible: false,
-			checkingInGroup: [],
-			time_range:[],
 			total: 0,
-			dept_tree: [],
+			time_types: [{ label: '月份', value: '1' }, { label: '季度', value: '3' }, { label: '年份', value: '2' }, { label: '自定义', value: '4' }],
+			time_type: '1',
 			dept_name: [],
-			pageLimit1: 10,
+			dept_tree: [],
+			point_types: [],
+			point_type: [],
+			rule_trees: null,
+			rule_id: null,
+			props: { value: 'id', label: 'name', children: 'child', multiple: true },
+			props2: { value: 'id', label: 'name', children: 'child', checkStrictly: true },
+			positions: [{age: 'all', name: '全部' }, { age: 'manager', name: '管理者' }, {age: 'employee', name: '员工' }],
 			formData: {
-				employeeID:'',
-				group_id: '',
+				position:'all',
+				exclusion:[],
+				sort: 'DESC',
+				pt_id: 3,
+				year: '',
+				month: this.$moment().format('YYYY-MM'),
+				quarter: '',
+				time_range: [],
+				dept_id: '0',
 				page: 1,
+				rule_id:'',
 				page_size: 10,
-				event_type: 0
+				source_type: '10'
 			},
-			attendload: false,
+			sort: false,
 			loading: false,
-			all_integral_list: [],
-			instantPickerOptions: {
-				shortcuts: [
-					{
-						text: '本周',
-						onClick(picker) {
-							const now = new Date();
-							const start = new Date();
-							start.setTime(now.getTime() - (now.getDay() - 1) * 24 * 60 * 60 * 1000);
-							now.setTime(start.getTime() + 6 * 24 * 60 * 60 * 1000 - 1000);
-							picker.$emit('pick', [start, now]);
-						}
-					},
-					{
-						text: '上周',
-						onClick(picker) {
-							const end = new Date();
-							const start = new Date();
-							start.setTime(start.getTime() - (start.getDay() + 6) * 3600 * 1000 * 24);
-							end.setTime(start.getTime() + 6 * 24 * 60 * 60 * 1000 - 1000);
-							picker.$emit('pick', [start, end]);
-						}
-					},
-					{
-						text: '本月',
-						onClick(picker) {
-							const now = new Date();
-							const startDate = new Date(now.getFullYear(), now.getMonth(), 1);
-							const endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0);
-							picker.$emit('pick', [startDate, endDate]);
-						}
-					},
-					{
-						text: '上月',
-						onClick(picker) {
-							const now = new Date();
-							const startDate = new Date(now.getFullYear() - (now.getMonth() > 0 ? 0 : 1), (now.getMonth() + 11) % 12, 1);
-							const endDate = new Date(now.getFullYear(), now.getMonth(), 0);
-							picker.$emit('pick', [startDate, endDate]);
-						}
-					}
-				]
-			},
-			exportData: {
-				group_id: '',
-				event_type: 0
-			},
+			list: [],
+			dialogVisible:false,
 		};
 	},
-	components: { noData },
-	watch: {
 
+	watch: {
+		'formData.month'(){
+			this.formData.page = 1;
+			this.get_list();
+		},
+		'formData.year'(){
+			this.formData.page = 1;
+			this.get_list();
+		},
+		'formData.time_range'(){
+			this.formData.page = 1;
+			this.get_list();
+		},
+		sort(val) {
+			if (val) {
+				this.formData.sort = 'ASC';
+			} else {
+				this.formData.sort = 'DESC';
+			}
+		},
+		dept_name(val) {
+			if (val.length !== 0) {
+				this.formData.dept_id = val[val.length - 1];
+			} else {
+				this.formData.dept_id = 0;
+			}
+			this.$nextTick(() => {
+				this.$refs.dept.dropDownVisible = false;
+				// this.getEmployeeList();
+			});
+			this.formData.page = 1;
+			this.get_list();
+			
+		},
+		rule_id(val) {
+			if(val.length==0){
+				this.formData.rule_id='';
+				return false
+			}
+			if(val.length==1){
+				this.formData.rule_id=(val).toString()
+			}else{
+				this.formData.rule_id=(val[val.length-1]).toString()
+			}
+			this.$refs.rule_id.dropDownVisible = false;
+		}
+	},
+	created() {
+		this.point_types = this.$getTyps();
+		this.getDepartment();
+		this.getEmployeeList();
+		this.get_rule_tree();
 	},
 	mounted() {
-		this.getEmployeeList()
+		this.get_list();
 	},
 	methods: {
-		getEmployeeList() {
-			this.$axios('get', '/api/employee/list', {}).then(res => {
-				if (res.data.code == 1) {
-					this.employee_map = res.data.data.list;
+		ruleInquiredialog() {
+			this.ruleUtif('derive');
+		},
+		ruleUtif(rule) {
+			let ruleList = this.$refs[rule].getCheckedNodes();
+			let ruleId = [];
+			ruleList.forEach(item => {
+				ruleId.push(item.value);
+			});
+			if (rule == 'ruleinquire') {
+				this.formData.rule_id = ruleId;
+			} else {
+				this.Dc_Data.rule_id = ruleId;
+			}
+			this.$nextTick(() => {
+				if (this.$refs[rule].presentTags[1]) {
+					this.$refs[rule].presentTags[1].text = '+ ' + (ruleId.length - 1).toString();
+				} else {
+					if (ruleId.length > 1) {
+						let list = {
+							closable: false,
+							key: -1,
+							text: '+ ' + (ruleId.length - 1).toString()
+						};
+						this.$refs[rule].presentTags[1] = list;
+					}
 				}
 			});
 		},
-		exportRanking() {
-			if (this.checkingInGroup.length > 0) {
-				this.exportData.group_id = this.checkingInGroup[0].id;
+		// 查询
+		selectBtn() {
+			this.formData.page = 1;
+			this.get_list();
+		},
+		// 获取积分规则
+		get_rule_tree() {
+			this.$axios('get', '/api/integral/rule/trees', { cycle_type: '1' }).then(res => {
+				this.rule_trees = this.getRuleTreeData(res.data.data.rule_tree);
+			});
+		},
+		// 规则递归 children
+		getRuleTreeData(data) {
+			for (var i = 0; i < data.length; i++) {
+				if (data[i].child.length < 1) {
+					// children若为空数组,则将children设为undefined
+					data[i].child = undefined;
+				} else {
+					// children若不为空数组,则继续 递归调用 本方法
+					this.getRuleTreeData(data[i].child);
+				}
 			}
-			this.dialogVisible = true;
+			return data;
 		},
-		exportExcel() {
-			window.open(
-				process.env.VUE_APP_BASE_API +
-					'api/download/groups_ranking/export?start_date=' +
-					this.exportTime_range[0] +
-					'&end_date=' +
-					this.exportTime_range[1] +
-					'&page=' +
-					1 +
-					'&page_size=' +
-					2000 +
-					'&group_id=' +
-					this.exportData.group_id +
-					'&event_type=' +
-					this.exportData.event_type +
-					'&employee_id=' +
-					this.$getUserData().id,
-				'_blank'
-			);
+		// 递归判断列表,把最后的children设为undefined
+		getTreeData(data) {
+			for (var i = 0; i < data.length; i++) {
+				data[i].obj = { id: data[i].id, name: data[i].name };
+				if (data[i]._child.length < 1) {
+					// children若为空数组,则将children设为undefined
+					data[i]._child = undefined;
+				} else {
+					// children若不为空数组,则继续 递归调用 本方法
+					this.getTreeData(data[i]._child);
+				}
+			}
+			return data;
 		},
-		selectgroupId() {
-			this.get_all_integral();
+		//获取部门
+		getDepartment() {
+			this.$axios('get', '/api/department/tree').then(res => {
+				this.dept_tree = this.getTreeData(res.data.data.list);
+			});
 		},
-		onFilterChanged() {
-			this.get_all_integral();
+		// 选择时间
+		export_quarter_confirm(val) {
+			this.formData.quarter = val;
+			this.formData.page = 1;
+			this.get_list();
 		},
-		//分页
-		handleSizeChange1(val) {
-			this.pageLimit1 = val;
-			this.formData.page_size = this.pageLimit1;
-			this.get_all_integral();
+		getEmployeeList() {
+			this.$axios('get', '/api/employee/list', { dept_id: this.formData.dept_id }).then(res => {
+				if (res.data.code == 1) {
+					this.employee_map = res.data.data.list;
+				}
+			});
 		},
+		exportExcel() {
+			//人员
+			this.Dc_Data.DC_position =
+				this.Dc_Data.DC_position == 'manager' ? 'manager' : this.Dc_Data.DC_position == 'employee' ? 'employee' : this.Dc_Data.DC_position == '全部' ? 'all' : 'all';
+			//部门
+			let dept_name;
+			for (let i in this.Dc_Data.dept_name) {
+				dept_name = this.Dc_Data.dept_name[i];
+			}
+			this.Dc_Data.dept_name = dept_name;
+			let data = '';
+			if (this.Dc_Data.value1) {
+				data += '&start_date=' + this.$moment(this.Dc_Data.value1[0]).format('YYYY-MM-DD');
+				data += '&end_date=' +  this.$moment(this.Dc_Data.value1[1]).format('YYYY-MM-DD');
+			}
+			data += '&position=' + this.Dc_Data.DC_position;
+			this.Dc_Data.dept_name > 0 ? (data += '&dept_id=' + this.Dc_Data.dept_name) : (data += '&dept_id=0');
+			if (this.Dc_Data.rule_id.length > 0) {
+				data += '&rule_id=' + this.Dc_Data.rule_id;
+			}
+			data += '&source_type=10';
+			let url=process.env.VUE_APP_BASE_API + 'api/download/ranking/v2?pt_id=' + this.Dc_Data.pt_id + '&employee_id=' + this.$getUserData().id + data;
+			window.open(url, '_blank');
+			this.dialogVisible = false;
+		},
+		// 页面变更
 		handleCurrentChange(val) {
 			this.formData.page = val;
-			this.get_all_integral();
+			this.get_list();
+		},
+		handleSizeChange(val) {
+			this.formData.page = 1;
+			this.formData.page_size = val;
+			this.get_list();
 		},
 		//请求数据
-		get_all_integral() {
-			let self = this;
-			self.loading = true;
+		get_list() {
 			let data = {
-				group_id: this.formData.group_id,
+				sort: this.formData.sort,
+				pt_id: this.formData.pt_id,
+				dept_id: this.formData.dept_id,
 				page: this.formData.page,
 				page_size: this.formData.page_size,
-				event_type: this.formData.event_type
+				exclusion:this.formData.exclusion.toString(),
+				source_type: '10',
+				position:this.formData.position,
+				rule_id:this.formData.rule_id,
 			};
-			data.start_date = this.time_range[0];
-			data.end_date = this.time_range[1];
-			this.$axios('post', '/api/ad/rank', data)
+			if (this.time_type == 1) {
+				data.month = this.formData.month;
+			} else if (this.time_type == 2) {
+				data.year = this.formData.year;
+			} else if (this.time_type == 3) {
+				data.quarter = this.formData.quarter;
+			} else if (this.time_type == 4) {
+				data.start_date = this.formData.time_range[0];
+				data.end_date = this.formData.time_range[1];
+			}
+			this.loading = true;
+			this.$axios('get', '/api/integral/statistics/ranking', data, 'v2')
 				.then(res => {
-					if (res.data.code == 1) {
-						self.all_integral_list = res.data.data.list;
-						this.total = res.data.data.total;
-					} else {
-						self.$message.error(res.data.data.msg);
-					}
+					this.list = res.data.data.list;
+					this.total = res.data.data.total;
 				})
 				.finally(() => {
-					self.loading = false;
+					this.loading = false;
 				});
 		}
 	}
@@ -270,7 +462,7 @@ export default {
 	width: auto;
 }
 .date-picker-width {
-	width: 145px !important;
+	width: 100% !important;
 }
 .search ::v-deep .el-input-group__append:active {
 	background: #26a2ff;
@@ -279,8 +471,3 @@ export default {
 	color: #fff;
 }
 </style>
-<style lang="scss" scoped>
-::v-deep .el-dialog__body {
-	padding: 0px 20px 30px;
-}
-</style>

+ 1 - 2
src/views/ranking/lotteryTicket_statistics.vue

@@ -102,7 +102,7 @@
   </div>
 </template>
 <script>
-import noData from '@/components/noData';
+
 export default {
   data() {
     return {
@@ -122,7 +122,6 @@ export default {
       pageLimit1: 10
     };
   },
-  components: {noData},
   watch: {
     "formData.month"(val, old_val) {
       this.formData.page = 1;

+ 2 - 2
src/views/ranking/manager_statistics.vue

@@ -161,7 +161,7 @@
 					<div class="flex-box-end">
 						<span class="yellow">*管理者奖扣任务均为B分,对A分不做要求*</span>
 					</div>
-					<el-table :data="list" style="width: 100%" v-loading="loading" @row-click="open_detail">
+					<el-table :data="list" style="width: 100%;cursor: pointer;" v-loading="loading" @row-click="open_detail">
 						<el-table-column label="管理者">
 							<template slot-scope="scope">
 								<div class="flex-box flex-v-ce">
@@ -223,7 +223,7 @@
 									<div class="dataItem">
 										<p class="point">{{ personalData.task.ratio.ratio }}:1</p>
 										<p>奖扣比例</p>
-										<p class="target">目标>{{ personalData.task.ratio.target_ratio }}:1</p>
+										<p class="target">目标{{ personalData.task.ratio.target_ratio }}:1</p>
 									</div>
 								</el-col>
 								<el-col :span="5">

+ 473 - 2
src/views/ranking/task_rank.vue

@@ -1,8 +1,479 @@
 <template>
+	<div>
+		<div class="all">
+			<div>
+				<el-form :inline="true">
+					<el-form-item label="时间">
+						<el-select size="medium" v-model="time_type" placeholder="请选择分类" style="width: 100px;">
+							<el-option v-for="item in time_types" :key="item.label" :label="item.label" :value="item.value"></el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item>
+						<el-date-picker
+							size="medium"
+							v-show="time_type == '1' || time_type == '月份'"
+							v-model="formData.month"
+							class="date-picker-width"
+							type="month"
+							value-format="yyyy-MM"
+							placeholder="选择月份排名"
+						></el-date-picker>
+						<el-date-picker
+							size="medium"
+							v-show="time_type == '2'"
+							v-model="formData.year"
+							class="date-picker-width"
+							type="year"
+							value-format="yyyy"
+							placeholder="选择年份排名"
+						></el-date-picker>
+						<season v-if="time_type == '3'" :isActive="true" class="date-picker-width" @confirm="export_quarter_confirm"></season>
+						<el-date-picker
+							size="medium"
+							v-show="time_type == '4'"
+							class="date-picker-width"
+							v-model="formData.time_range"
+							type="daterange"
+							format="yyyy 年 MM 月 dd 日"
+							value-format="yyyy-MM-dd"
+							range-separator="至"
+							start-placeholder="开始日期"
+							end-placeholder="结束日期"
+						></el-date-picker>
+					</el-form-item>
+					<el-form-item label="部门">
+						<el-cascader
+							size="medium"
+							class="date-picker-width"
+							v-model="dept_name"
+							:options="dept_tree"
+							:props="{ checkStrictly: true, value: 'id', label: 'name', children: '_child' }"
+							ref="dept"
+							clearable
+							filterable
+							placeholder="全公司"
+						></el-cascader>
+					</el-form-item>
+<!-- 					<el-form-item label="谁不参与排名">
+						<el-select v-model="formData.exclusion" size="medium" multiple filterable clearable collapse-tags placeholder="请选择员工">
+							<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item> -->
+<!-- 					<el-form-item label="规则分类">
+						<el-cascader
+							size="medium"
+							class="date-picker-width"
+							v-model="rule_id"
+							:options="rule_trees"
+							:props="props2"
+							ref="rule_id"
+							clearable
+							placeholder="请选择规则分类"
+						></el-cascader>
+					</el-form-item> -->
+					<el-form-item label="积分类型">
+						<el-select class="date-picker-width" size="medium" v-model="formData.pt_id" placeholder="请选择积分类型">
+							<el-option v-for="item in point_types" :key="item.name" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item>
+<!-- 					<el-form-item label="人员">
+						<el-select size="medium" v-model="formData.position" style="width:150px" placeholder="请选择">
+							<el-option v-for="item in positions" :key="item.age" :label="item.name" :value="item.age"></el-option>
+						</el-select>
+					</el-form-item> -->
+					<el-form-item>
+						<el-checkbox v-model="sort" size="medium" label="排名由低到高" border></el-checkbox>
+						<!-- <el-button type="primary" size="medium" @click="selectBtn" style="margin-left:20px">查询</el-button> -->
+					</el-form-item>
+					<el-form-item><el-button type="primary" size="medium" plain @click="dialogVisible = true">导出排名</el-button></el-form-item>
+				</el-form>
+			</div>
+			<el-table :data="list" style="width: 100%" v-loading="loading">
+				<el-table-column label="名次" width="100" align="center">
+					<template slot-scope="scope">
+						<img v-if="scope.row.rank === 1" src="@/assets/image/statistics_NO1.png" alt />
+						<img v-if="scope.row.rank === 2" src="@/assets/image/statistics_NO2.png" alt />
+						<img v-if="scope.row.rank === 3" src="@/assets/image/statistics_NO3.png" alt />
+						<span v-if="scope.row.rank > 3">{{ scope.row.rank }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column label="姓名" align="left">
+					<template slot-scope="scope">
+						<div style="display:flex;">
+							<userImage :user_name="scope.row.employee_name" :img_url="scope.row.employee_img_url" width="50px" height="50px"></userImage>
+							<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.employee_name }}</span>
+						</div>
+					</template>
+				</el-table-column>
+				<el-table-column prop="point" label="任务分" align="left">
+					<template slot-scope="scope">
+						<b style="font-size:15px;color:#909399">{{ scope.row.point }}</b>
+					</template>
+				</el-table-column>
+				<template slot="empty">
+					<noData></noData>
+				</template>
+			</el-table>
+			<center style="padding: 20px 0;">
+				<el-pagination
+					background
+					@size-change="handleSizeChange"
+					@current-change="handleCurrentChange"
+					:current-page="formData.page"
+					:page-sizes="[10, 20, 50, 100]"
+					layout="total, sizes, prev, pager, next"
+					:page-size="formData.page_size"
+					:total="total"
+				></el-pagination>
+			</center>
+		
+		<!-- 导出弹窗 -->
+		<el-dialog title="导出排名" :visible.sync="dialogVisible" width="730px" top="10%">
+			<div style="font-size:15px;margin-bottom: 20px;">系统将按以下已选条件导出对应的排名报表</div>
+			<el-form :inline="true">
+				<div class="picker_er">
+					<el-form-item label="时间">
+						<el-date-picker
+							v-model="Dc_Data.value1"
+							type="daterange"
+							size="medium"
+							value-format="timestamp"
+							range-separator="至"
+							start-placeholder="开始日期"
+							end-placeholder="结束日期"
+						></el-date-picker>
+					</el-form-item>
+		
+<!-- 					<el-form-item label="人员" style="margin-left:30px">
+						<el-select size="medium" v-model="Dc_Data.DC_position" style="width:150px" placeholder="请选择">
+							<el-option v-for="item in positions" :key="item.id" :label="item.name" :value="item.age"></el-option>
+						</el-select>
+					</el-form-item> -->
+				</div>
+				<el-form-item label="部门">
+					<el-cascader
+						class="date-picker-width cascader_bm"
+						v-model="Dc_Data.dept_name"
+						:options="dept_tree"
+						:props="{ checkStrictly: true, value: 'id', label: 'name', children: '_child' }"
+						ref="dept2"
+						size="medium"
+						clearable
+						filterable
+						placeholder="全公司"
+					></el-cascader>
+				</el-form-item>
+				<el-form-item label="积分类型">
+					<el-select  style="width: 80px;" size="medium" v-model="Dc_Data.pt_id" placeholder="请选择积分类型">
+						<el-option v-for="item in point_types" :key="item.name" :label="item.name" :value="item.id"></el-option>
+					</el-select>
+				</el-form-item>
+<!-- 				<el-form-item label="规则分类" style="margin-left:20px">
+					<el-cascader
+						class="date-picker-width"
+						@change="ruleInquiredialog"
+						v-model="rule_ids"
+						:options="rule_trees"
+						:props="props"
+						size="medium"
+						ref="derive"
+						clearable
+						collapse-tags
+						placeholder="请选择规则分类"
+					></el-cascader>
+				</el-form-item> -->
+			</el-form>
+			<span slot="footer" class="dialog-footer">
+				<el-button @click="dialogVisible = false" size="medium">取 消</el-button>
+				<el-button type="primary" @click="exportExcel" size="medium">导 出</el-button>
+			</span>
+		</el-dialog>
+		</div>
+	</div>
 </template>
-
 <script>
+import season from '@/components/season';
+export default {
+	components: { season },
+	name:'task_rank',
+	data() {
+		return {
+			// 导出
+			Dc_Data: {
+				//导出数据
+				value1: '', //时间
+				DC_position: '全部', //人员
+				dept_name: [], //部门
+				rule_id: [] ,//规则
+				pt_id: 3,
+			},
+			rule_ids: null,
+			
+			employee_map: JSON.parse(localStorage.getItem('SET_EMPLOYEE_MAP')),
+			total: 0,
+			time_types: [{ label: '月份', value: '1' }, { label: '季度', value: '3' }, { label: '年份', value: '2' }, { label: '自定义', value: '4' }],
+			time_type: '1',
+			dept_name: [],
+			dept_tree: [],
+			point_types: [],
+			point_type: [],
+			rule_trees: null,
+			rule_id: null,
+			props: { value: 'id', label: 'name', children: 'child', multiple: true },
+			props2: { value: 'id', label: 'name', children: 'child', checkStrictly: true },
+			positions: [{age: 'all', name: '全部' }, { age: 'manager', name: '管理者' }, {age: 'employee', name: '员工' }],
+			formData: {
+				position:'all',
+				exclusion:[],
+				sort: 'DESC',
+				pt_id: 3,
+				year: '',
+				month: this.$moment().format('YYYY-MM'),
+				quarter: '',
+				time_range: [],
+				dept_id: '0',
+				page: 1,
+				rule_id:'',
+				page_size: 10,
+				source_type: '2'
+			},
+			sort: false,
+			loading: false,
+			list: [],
+			dialogVisible:false,
+
+		};
+	},
+
+	watch: {
+		'formData.pt_id'(){
+			this.formData.page = 1;
+			this.get_list();
+		},
+		'formData.month'(){
+			this.formData.page = 1;
+			this.get_list();
+		},
+		'formData.year'(){
+			this.formData.page = 1;
+			this.get_list();
+		},
+		'formData.time_range'(){
+			this.formData.page = 1;
+			this.get_list();
+		},
+		sort(val) {
+			if (val) {
+				this.formData.sort = 'ASC';
+			} else {
+				this.formData.sort = 'DESC';
+			}
+		},
+		dept_name(val) {
+			if (val.length !== 0) {
+				this.formData.dept_id = val[val.length - 1];
+			} else {
+				this.formData.dept_id = 0;
+			}
+			this.$nextTick(() => {
+				this.$refs.dept.dropDownVisible = false;
+				// this.getEmployeeList();
+			});
+			this.formData.page = 1;
+			this.get_list();
+		},
+		rule_id(val) {
+			if(val.length==0){
+				this.formData.rule_id='';
+				return false
+			}
+			if(val.length==1){
+				this.formData.rule_id=(val).toString()
+			}else{
+				this.formData.rule_id=(val[val.length-1]).toString()
+			}
+			this.$refs.rule_id.dropDownVisible = false;
+		}
+	},
+	created() {
+		this.point_types = this.$getTyps();
+		this.getDepartment();
+		this.getEmployeeList();
+		this.get_rule_tree();
+	},
+	mounted() {
+		this.get_list();
+	},
+	methods: {
+		ruleInquiredialog() {
+			this.ruleUtif('derive');
+		},
+		ruleUtif(rule) {
+			let ruleList = this.$refs[rule].getCheckedNodes();
+			let ruleId = [];
+			ruleList.forEach(item => {
+				ruleId.push(item.value);
+			});
+			if (rule == 'ruleinquire') {
+				this.formData.rule_id = ruleId;
+			} else {
+				this.Dc_Data.rule_id = ruleId;
+			}
+			this.$nextTick(() => {
+				if (this.$refs[rule].presentTags[1]) {
+					this.$refs[rule].presentTags[1].text = '+ ' + (ruleId.length - 1).toString();
+				} else {
+					if (ruleId.length > 1) {
+						let list = {
+							closable: false,
+							key: -1,
+							text: '+ ' + (ruleId.length - 1).toString()
+						};
+						this.$refs[rule].presentTags[1] = list;
+					}
+				}
+			});
+		},
+		// 查询
+		selectBtn() {
+			this.formData.page = 1;
+			this.get_list();
+		},
+		// 获取积分规则
+		get_rule_tree() {
+			this.$axios('get', '/api/integral/rule/trees', { cycle_type: '1' }).then(res => {
+				this.rule_trees = this.getRuleTreeData(res.data.data.rule_tree);
+			});
+		},
+		// 规则递归 children
+		getRuleTreeData(data) {
+			for (var i = 0; i < data.length; i++) {
+				if (data[i].child.length < 1) {
+					// children若为空数组,则将children设为undefined
+					data[i].child = undefined;
+				} else {
+					// children若不为空数组,则继续 递归调用 本方法
+					this.getRuleTreeData(data[i].child);
+				}
+			}
+			return data;
+		},
+		// 递归判断列表,把最后的children设为undefined
+		getTreeData(data) {
+			for (var i = 0; i < data.length; i++) {
+				data[i].obj = { id: data[i].id, name: data[i].name };
+				if (data[i]._child.length < 1) {
+					// children若为空数组,则将children设为undefined
+					data[i]._child = undefined;
+				} else {
+					// children若不为空数组,则继续 递归调用 本方法
+					this.getTreeData(data[i]._child);
+				}
+			}
+			return data;
+		},
+		//获取部门
+		getDepartment() {
+			this.$axios('get', '/api/department/tree').then(res => {
+				this.dept_tree = this.getTreeData(res.data.data.list);
+			});
+		},
+		// 选择时间
+		export_quarter_confirm(val) {
+			this.formData.quarter = val;
+			this.formData.page = 1;
+			this.get_list();
+		},
+		getEmployeeList() {
+			this.$axios('get', '/api/employee/list', { dept_id: this.formData.dept_id }).then(res => {
+				if (res.data.code == 1) {
+					this.employee_map = res.data.data.list;
+				}
+			});
+		},
+		exportExcel() {
+			//人员
+			this.Dc_Data.DC_position =
+				this.Dc_Data.DC_position == 'manager' ? 'manager' : this.Dc_Data.DC_position == 'employee' ? 'employee' : this.Dc_Data.DC_position == '全部' ? 'all' : 'all';
+			//部门
+			let dept_name;
+			for (let i in this.Dc_Data.dept_name) {
+				dept_name = this.Dc_Data.dept_name[i];
+			}
+			this.Dc_Data.dept_name = dept_name;
+			let data = '';
+			if (this.Dc_Data.value1) {
+				data += '&start_date=' + this.$moment(this.Dc_Data.value1[0]).format('YYYY-MM-DD');
+				data += '&end_date=' +  this.$moment(this.Dc_Data.value1[1]).format('YYYY-MM-DD');
+			}
+			data += '&position=' + this.Dc_Data.DC_position;
+			this.Dc_Data.dept_name > 0 ? (data += '&dept_id=' + this.Dc_Data.dept_name) : (data += '&dept_id=0');
+			if (this.Dc_Data.rule_id.length > 0) {
+				data += '&rule_id=' + this.Dc_Data.rule_id;
+			}
+			data += '&source_type=2';
+			let url=process.env.VUE_APP_BASE_API + 'api/download/ranking/v2?pt_id=' + this.Dc_Data.pt_id + '&employee_id=' + this.$getUserData().id + data;
+			window.open(url, '_blank');
+			this.dialogVisible = false;
+		},
+		// 页面变更
+		handleCurrentChange(val) {
+			this.formData.page = val;
+			this.get_list();
+		},
+		handleSizeChange(val) {
+			this.formData.page = 1;
+			this.formData.page_size = val;
+			this.get_list();
+		},
+		//请求数据
+		get_list() {
+			let data = {
+				sort: this.formData.sort,
+				pt_id: this.formData.pt_id,
+				dept_id: this.formData.dept_id,
+				page: this.formData.page,
+				page_size: this.formData.page_size,
+				exclusion:this.formData.exclusion.toString(),
+				source_type: '2',
+				position:this.formData.position,
+				rule_id:this.formData.rule_id,
+			};
+			if (this.time_type == 1) {
+				data.month = this.formData.month;
+			} else if (this.time_type == 2) {
+				data.year = this.formData.year;
+			} else if (this.time_type == 3) {
+				data.quarter = this.formData.quarter;
+			} else if (this.time_type == 4) {
+				data.start_date = this.formData.time_range[0];
+				data.end_date = this.formData.time_range[1];
+			}
+			this.loading = true;
+			this.$axios('get', '/api/integral/statistics/ranking', data, 'v2')
+				.then(res => {
+					this.list = res.data.data.list;
+					this.total = res.data.data.total;
+				})
+				.finally(() => {
+					this.loading = false;
+				});
+		}
+	}
+};
 </script>
 
-<style>
+<style scoped>
+.el-date-editor.el-input {
+	width: auto;
+}
+.date-picker-width {
+	width: 100% !important;
+}
+.search ::v-deep .el-input-group__append:active {
+	background: #26a2ff;
+}
+.search ::v-deep .el-input-group__append:active .el-icon-search {
+	color: #fff;
+}
 </style>

+ 1 - 2
src/views/set/framework.vue

@@ -278,7 +278,7 @@
 </template>
 
 <script>
-import noData from '@/components/noData';
+
 import EmployeeSelector from '@/components/EmployeeSelector.vue';
 import {_debounce} from '@/api/auth';
 export default {
@@ -354,7 +354,6 @@ export default {
 		};
 	},
 	components: {
-		noData,
 		EmployeeSelector
 	},
 	watch: {

+ 2 - 2
src/views/set/jurisdiction.vue

@@ -720,7 +720,7 @@
 
 <script>
 import EmployeeSelector from '@/components/EmployeeSelector.vue';
-import noData from '@/components/noData';
+
 import toLead from '@/components/toLead';
 const minimum = (rule, value, callback) => {
 	if (value < 0) {
@@ -856,7 +856,7 @@ export default {
 			toleadResult: {}
 		};
 	},
-	components: { EmployeeSelector, noData, toLead },
+	components: { EmployeeSelector, toLead },
 	created() {
 		this.get_role_list();
 		// 判断是否是创始人

+ 2 - 2
src/views/set/log.vue

@@ -131,9 +131,9 @@
 </template>
 
 <script>
-import noData from '@/components/noData';
+
 export default {
-	components: { noData },
+	
 	data() {
 		return {
 			loading: false,

+ 7 - 4
src/views/set/rule.vue

@@ -17,7 +17,7 @@
 						<div class="name">{{ selectItem.name }}</div>
 						<el-button size="medium" plain v-if="selectItem.id" @click="edit_class">编辑</el-button>
 					</div>
-					<div class="flex-box ruleSearch" style="">
+					<div class="flex-box ruleSearch">
 						<div class="flex-box btns flex-v-ce">
 							<el-button size="small" @click="del_item" type="danger" plain>批量删除</el-button>
 							<el-button size="small" @click="add_rule" type="primary">添加规则</el-button>
@@ -55,7 +55,8 @@
 						</el-table-column>
 						<el-table-column prop="remark" label="操作" align="center">
 							<template slot-scope="scope">
-								<div @click.stop="ruleQRcode(scope.row)"><span class="lookQrcode">查看二维码</span></div>
+								<span @click.stop="ruleQRcode(scope.row)" class="lookQrcode">查看二维码</span>
+								<span class="blue" style="padding-left: 10px;cursor: pointer;">编辑</span>
 							</template>
 						</el-table-column>
 						<template slot="empty">
@@ -246,7 +247,7 @@
 </template>
 
 <script>
-import noData from '@/components/noData';
+
 import QRCode from 'qrcodejs2';
 import toLead from '@/components/toLead';
 export default {
@@ -369,7 +370,6 @@ export default {
 		};
 	},
 	components: {
-		noData,
 		toLead
 	},
 	watch: {
@@ -1060,6 +1060,9 @@ export default {
 
 <style scoped lang="scss">
 $red: #f56c6c;
+::v-deep .el-table__row{
+	cursor: pointer;
+}
 .select_width .el-select {
 	width: 80px;
 	background-color: #fff;

+ 7 - 7
src/views/set/systemLayout.vue

@@ -127,15 +127,16 @@
 				</center>
 			</el-tab-pane>
 		</el-tabs>
-
-		<el-button type="primary" class="save pop-up" v-if="activeName == 'first' || activeName == 'second'" @click="saveFirst(activeName)">保存</el-button>
+		<div class="pop-up">
+			<el-button type="primary" class="save" v-if="activeName == 'first' || activeName == 'second'" @click="saveFirst(activeName)">保存</el-button>
+		</div>
 		<el-dialog title="系统审批流程" :visible.sync="dialogVisible" width="770px" top="3vh" :before-close="handleClose">
 			<svg-icon icon-class="approval_process" style="font-size:730px;" />
 		</el-dialog>
 	</div>
 </template>
 <script>
-import noData from '@/components/noData';
+
 export default {
 	data() {
 		return {
@@ -174,9 +175,6 @@ export default {
 			},
 		};
 	},
-	components: {
-		noData
-	},
 	mounted() {
 		this.cheakAx('first');
 	},
@@ -337,8 +335,10 @@ export default {
 }
 .pop-up{
   position: sticky;
-  bottom: 0px;
+  bottom: -10px;
   z-index: 999;
+  padding: 10px 0;
+  background-color: #fff;
 }
 .tab-container ::v-deep .el-tabs__item {
 	font-size: 16px;

+ 311 - 257
src/views/set/voluntarilyPoint.vue

@@ -6,23 +6,29 @@
 		<div class="all">
 			<div class="flex-box">
 				<div class="terr-left">
-					<div><el-button size="medium" @click="add_grouping()"   type="primary">新增加分组</el-button></div>
-					<div><el-button size="medium" @click="add_rules_detail"   type="primary">新增加分项</el-button></div>
+					<div><el-button size="medium" @click="add_grouping()" type="primary">新增加分组</el-button></div>
+					<div><el-button size="medium" @click="add_rules_detail" type="primary">新增加分项</el-button></div>
 
 					<!-- 循环分组 -->
 					<el-col :span="24" style="padding-right: 0;" v-loading="rule_trees_load">
-						<el-menu :default-active='default_active' class="rule_name" :unique-opened="true">
+						<el-menu :default-active="default_active" class="rule_name" :unique-opened="true">
 							<el-submenu :index="index.toString()" :key="index" v-for="(item, index) in rule_list">
 								<template slot="title">
-									<div style="width: 80%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap; height: 47px;line-height: 47px;" >
+									<div style="width: 80%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap; height: 47px;line-height: 47px;">
 										<i class="el-icon-edit-outline title_top" @click.stop="edit_grouping(item)"></i>
 										<span class="title_top">{{ item.name }}</span>
 									</div>
 								</template>
-								<el-menu-item  :key="index2" :index="returnIndex(index,index2)" v-for="(data, index2) in item.child" @click="open_rights(data)" style="height: 47px;line-height: 47px;">
-										<div style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap">
-											<span slot="title">{{ data.remark }}</span>
-										</div>
+								<el-menu-item
+									:key="index2"
+									:index="returnIndex(index, index2)"
+									v-for="(data, index2) in item.child"
+									@click="open_rights(data)"
+									style="height: 47px;line-height: 47px;"
+								>
+									<div style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap">
+										<span slot="title">{{ data.remark }}</span>
+									</div>
 								</el-menu-item>
 							</el-submenu>
 						</el-menu>
@@ -30,10 +36,12 @@
 				</div>
 
 				<div class="terr-right border-right flex-1">
-					<el-col :span="24" v-show="rule_list.length == 0 || isShowAdd"  style="text-align: center;margin: 0 auto;position: relative;top: 30%;">
+					<el-col :span="24" v-show="rule_list.length == 0 || isShowAdd" style="text-align: center;margin: 0 auto;position: relative;top: 30%;">
 						<p><img src="@/assets/image/nodata_default.png" width="200px" alt="" /></p>
 						<p style="color: #909399;">
-							还没有<span v-if="rule_list.length == 0">加分组和</span>加分项
+							还没有
+							<span v-if="rule_list.length == 0">加分组和</span>
+							加分项
 						</p>
 						<p style="color: #909399;">
 							<span v-if="rule_list.length == 0">先</span>
@@ -43,8 +51,8 @@
 							<span style="color: #26A2FF;cursor:pointer" @click="add_rules_detail">【新增加分项】</span>
 						</p>
 					</el-col>
-					
-					<el-col v-if="!isShowAdd&&right_rules_detail.remark">
+
+					<el-col v-if="!isShowAdd && right_rules_detail.remark">
 						<el-row>
 							<el-col :span="24" style="font-size:20px;color:#303133;line-height:36px;">
 								{{ right_rules_detail.remark }}
@@ -55,22 +63,22 @@
 						<div class="flex-box btns flex-v-ce">
 							<div class="flex-1">
 								<el-button size="small" @click="del_item" type="danger" plain>批量移除</el-button>
-								<el-button size="small" type="primary" @click="add_employee_show=true">添加人员</el-button>
+								<el-button size="small" type="primary" @click="add_employee_show = true">添加人员</el-button>
 								<el-button size="small" type="primary" plain @click="toleadShw = true">导入自动积分</el-button>
 							</div>
 							<div>
 								<el-select size="small" v-model="employee_id" filterable clearable placeholder="请输入或选择人员">
-								  <el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
+									<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
 								</el-select>
 							</div>
 						</div>
-						<el-table  ref="multipleTable"	:data="table_list"	tooltip-effect="dark"  style="width: 100%;margin-top:20px;"  @selection-change="handleSelectionChange">
+						<el-table ref="multipleTable" :data="table_list" tooltip-effect="dark" style="width: 100%;margin-top:20px;" @selection-change="handleSelectionChange">
 							<el-table-column type="selection" width="45"></el-table-column>
 							<el-table-column label="姓名">
 								<template slot-scope="scope">
 									<div style="display:flex">
 										<span class="fl">
-											<userImage	
+											<userImage
 												width="50px"
 												height="50px"
 												:user_name="scope.row.employee.name"
@@ -85,7 +93,7 @@
 							<el-table-column prop="cycle_remark" label="加分周期"></el-table-column>
 							<el-table-column prop="update_time" label="更新时间">
 								<template slot-scope="scope">
-									<div>{{getUpdate(scope.row.update_time)}}</div>
+									<div>{{ getUpdate(scope.row.update_time) }}</div>
 								</template>
 							</el-table-column>
 							<template slot="empty">
@@ -115,11 +123,21 @@
 			<el-dialog :close-on-click-modal="false" :title="grouping_type ? '编辑加分组' : '新增加分组'" :visible.sync="dialogVisible" width="40%">
 				<el-form :model="numberValidateForm" ref="numberValidateForm" label-width="100px" class="demo-ruleForm">
 					<el-form-item label="加分组名称" prop="name" :rules="[{ required: true, message: '请输入加分组名称' }]">
-						<el-input type="age" v-model="numberValidateForm.name"  placeholder="请输入加分组名称"></el-input>
+						<el-input type="age" v-model="numberValidateForm.name" placeholder="请输入加分组名称"></el-input>
 					</el-form-item>
 				</el-form>
 				<span slot="footer" class="dialog-footer" style=" overflow: hidden;">
-					<el-button class="fl" type="danger" v-show="grouping_type" @click="del_grouping(numberValidateForm)" style="float:left"  :loading="disabled" :disabled="disabled">删除</el-button>
+					<el-button
+						class="fl"
+						type="danger"
+						v-show="grouping_type"
+						@click="del_grouping(numberValidateForm)"
+						style="float:left"
+						:loading="disabled"
+						:disabled="disabled"
+					>
+						删除
+					</el-button>
 					<el-button @click="dialogVisible = false">取 消</el-button>
 					<el-button type="primary" @click="submitForm('numberValidateForm')" :loading="disabled" :disabled="disabled">确 定</el-button>
 				</span>
@@ -129,7 +147,7 @@
 			<el-dialog :title="rules_detail_title ? '编辑加分项' : '新增加分项'" :visible.sync="dialogFormVisible" width="500px">
 				<el-form :model="rules_detail_form" ref="rules_detail_form" :rules="rules_rules" label-width="120px">
 					<el-form-item label="加分项名称" :label-width="formLabelWidth" prop="remark">
-						<el-input v-model="rules_detail_form.remark" placeholder="请输入加分项名称" ></el-input>
+						<el-input v-model="rules_detail_form.remark" placeholder="请输入加分项名称"></el-input>
 					</el-form-item>
 					<el-form-item label="加分组" :label-width="formLabelWidth" prop="rule_id">
 						<el-select v-model="rules_detail_form.rule_id" style="width: 100%;" placeholder="请选择加分组">
@@ -146,14 +164,32 @@
 					</el-form-item>
 					<!-- <el-form-item label="是否与考勤挂钩" prop="is_attendance"><el-switch v-model="is_attendance"></el-switch></el-form-item> -->
 					<div style="overflow: hidden;">
-						<el-button type="danger" v-show="rules_detail_title" class="fl" @click="del_rules_detail(rules_detail_form)" style="float:left" :loading="disabled" :disabled="disabled">
+						<el-button
+							type="danger"
+							v-show="rules_detail_title"
+							class="fl"
+							@click="del_rules_detail(rules_detail_form)"
+							style="float:left"
+							:loading="disabled"
+							:disabled="disabled"
+						>
 							删除
 						</el-button>
 
-						<el-button v-if="rules_detail_title" class="fr" type="primary" @click="editRule('rules_detail_form')" style="float:right" :loading="disabled" :disabled="disabled">
+						<el-button
+							v-if="rules_detail_title"
+							class="fr"
+							type="primary"
+							@click="editRule('rules_detail_form')"
+							style="float:right"
+							:loading="disabled"
+							:disabled="disabled"
+						>
+							确 定
+						</el-button>
+						<el-button v-else class="fr" type="primary" @click="editRule('rules_detail_form')" style="float:right" :loading="disabled" :disabled="disabled">
 							确 定
 						</el-button>
-						<el-button v-else class="fr" type="primary" @click="editRule('rules_detail_form')" style="float:right" :loading="disabled" :disabled="disabled">确 定</el-button>
 						<el-button class="fr" @click="rules_detail_close('rules_detail_form')" style="float:right">取 消</el-button>
 					</div>
 				</el-form>
@@ -170,7 +206,7 @@
 						<EmployeeSelector
 							v-if="add_employee_show"
 							:max="add_employee_max"
-							:user_no_select="false" 
+							:user_no_select="false"
 							@confirm="add_employee_confirm"
 							ref="Employee"
 						></EmployeeSelector>
@@ -181,7 +217,7 @@
 					</el-form-item>
 				</el-form>
 			</el-dialog>
-		
+
 			<!-- 导入规则 -->
 			<!-- <el-dialog title="导入自动积分" :visible.sync="import_rules_show" width="500px" @before-close="close_import">
 			  <el-row>
@@ -223,37 +259,37 @@
 				<template slot="1">
 					<el-row v-if="nowIndex == 1">
 						<el-col :span="12">
-						<div style="text-align: center;line-height: 34px;">
-							<p>1、导出模板,填写好规则</p>
-							<p><img src="../../assets/image/rules_mould.png" alt="" /></p>
-							<p>规则表</p>
-							<p>
-							<a target="_blank" :href="publicBASE_API + '/api/download/point_auto'"><el-button type="primary" >下载模板</el-button></a>
-							</p>
-						</div>
+							<div style="text-align: center;line-height: 34px;">
+								<p>1、导出模板,填写好规则</p>
+								<p><img src="../../assets/image/rules_mould.png" alt="" /></p>
+								<p>规则表</p>
+								<p>
+									<a target="_blank" :href="publicBASE_API + '/api/download/point_auto'"><el-button type="primary">下载模板</el-button></a>
+								</p>
+							</div>
 						</el-col>
 						<el-col :span="12">
-						<div style="text-align: center;line-height: 34px;">
-							<p>2、上传填好的规则表</p>
-							<p><img src="../../assets/image/rules_mould1.png" alt="" /></p>
-							<p>仅支持xls、xlsx格式文件</p>
-							<el-upload
-							class="upload-demo"
-							:headers="ATOKEN"
-							:data="{ type: 'auto_integral' }"
-							ref="upload"
-							:limit="1"
-							:action="action"
-							:on-remove="handleRemove"
-							:on-success="handleSuccess"
-							:before-upload="beforeFilesUpload"
-							:file-list="fileList"
-							:on-progress="handleOnthecross"
-							>
-							<el-button slot="trigger" type="primary">选取文件</el-button>
-							</el-upload>
-							<!-- <p><el-button type="primary" @click="submitUpload" :loading="save_loading" v-show="import_btn_show" block>导入</el-button></p> -->
-						</div>
+							<div style="text-align: center;line-height: 34px;">
+								<p>2、上传填好的规则表</p>
+								<p><img src="../../assets/image/rules_mould1.png" alt="" /></p>
+								<p>仅支持xls、xlsx格式文件</p>
+								<el-upload
+									class="upload-demo"
+									:headers="ATOKEN"
+									:data="{ type: 'auto_integral' }"
+									ref="upload"
+									:limit="1"
+									:action="action"
+									:on-remove="handleRemove"
+									:on-success="handleSuccess"
+									:before-upload="beforeFilesUpload"
+									:file-list="fileList"
+									:on-progress="handleOnthecross"
+								>
+									<el-button slot="trigger" type="primary">选取文件</el-button>
+								</el-upload>
+								<!-- <p><el-button type="primary" @click="submitUpload" :loading="save_loading" v-show="import_btn_show" block>导入</el-button></p> -->
+							</div>
 						</el-col>
 					</el-row>
 				</template>
@@ -264,13 +300,13 @@
 
 <script>
 import EmployeeSelector from '@/components/EmployeeSelector';
-import noData from '@/components/noData';
+
 import toLead from '@/components/toLead';
 export default {
 	data() {
 		return {
-			pd_tianjia:false,
-			default_active:'0-0',
+			pd_tianjia: false,
+			default_active: '0-0',
 			table_list: [],
 			tips_show: false,
 			rule_trees_load: false,
@@ -285,8 +321,8 @@ export default {
 			add_employee_form: {
 				employee_ids: []
 			},
-			
-			isShowAdd:false,
+
+			isShowAdd: false,
 			del_arr: {
 				ids: []
 			},
@@ -378,16 +414,16 @@ export default {
 			action: process.env.VUE_APP_BASE_API + 'api/integral/auto/import',
 			publicBASE_API: process.env.VUE_APP_BASE_API,
 			save_loading: false,
-			ATOKEN: { 'A-TOKEN': this.$getToken(),'Accept':'application/vnd.test.v2+json' },
+			ATOKEN: { 'A-TOKEN': this.$getToken(), Accept: 'application/vnd.test.v2+json' },
 			import_btn_show: false,
 			fileList: [],
 			file: null,
 			import_rules_show: false, //导出弹窗
-			
-			keyword:'',
-			employee_map:[],
-			employee_id:'',
-			selectData:{},
+
+			keyword: '',
+			employee_map: [],
+			employee_id: '',
+			selectData: {},
 			//导入相关
 			toleadShw: false,
 			nowIndex: 1,
@@ -396,18 +432,17 @@ export default {
 	},
 	components: {
 		EmployeeSelector,
-		noData,
 		toLead
 	},
 	created() {
 		this.getEmployee();
 	},
-	watch:{
-		toleadShw(val){
-			if(val) this.nowIndex = 1
+	watch: {
+		toleadShw(val) {
+			if (val) this.nowIndex = 1;
 		},
-		employee_id(val){
-			this.page=1;
+		employee_id(val) {
+			this.page = 1;
 			this.open_right(this.selectData);
 		}
 	},
@@ -422,123 +457,121 @@ export default {
 	methods: {
 		//获取员工列表
 		getEmployee() {
-			this.$axios('get', '/api/employee/index', { dept_id: 0, keywords: '', page: 1, page_size: 3000,is_official:1 })
+			this.$axios('get', '/api/employee/index', { dept_id: 0, keywords: '', page: 1, page_size: 3000, is_official: 1 })
 				.then(res => {
 					let list = res.data.data.list;
 					this.employee_map = list;
 				})
 				.finally(err => {});
 		},
-		getUpdate(date){
-			return this.$moment.unix(date).format('YYYY-MM-DD HH:mm:ss')
+		getUpdate(date) {
+			return this.$moment.unix(date).format('YYYY-MM-DD HH:mm:ss');
 		},
 		// 搜索
-		onFilterChanged(){
-			
-		},
+		onFilterChanged() {},
 		close_import() {
-		  this.import_rules_show = false;
-		  this.import_btn_show = false;
-		  this.$refs.upload.clearFiles();
+			this.import_rules_show = false;
+			this.import_btn_show = false;
+			this.$refs.upload.clearFiles();
 		},
 		submitUpload() {
-		  this.save_loading = true;
-		  let params = {
-		    file: this.file
-		  };
-		  this.$axios('post', '/api/integral/auto/import', params)
-		    .then(res => {
-		      if (res.data.code == 1) {
-		        // this.import_rules_show = false;
-		        this.close_import(); //成功之后关闭并清除选中的文件
-		        this.$message.success({ message: res.data.msg });
-		        this.get_rule_trees();
-		      } else {
-		        this.$message({ type: 'error', message: res.data.msg });
-		      }
-		    })
-		    .catch(() => {})
-		    .finally(() => {
-		      this.save_loading = false;
-		    });
+			this.save_loading = true;
+			let params = {
+				file: this.file
+			};
+			this.$axios('post', '/api/integral/auto/import', params)
+				.then(res => {
+					if (res.data.code == 1) {
+						// this.import_rules_show = false;
+						this.close_import(); //成功之后关闭并清除选中的文件
+						this.$message.success({ message: res.data.msg });
+						this.get_rule_trees();
+					} else {
+						this.$message({ type: 'error', message: res.data.msg });
+					}
+				})
+				.catch(() => {})
+				.finally(() => {
+					this.save_loading = false;
+				});
 		},
 		//导入
 		beforeFilesUpload(file) {
-		  const $ext_list = ['xlsx', 'xls'];
-		  let len = file.name.split('.').length - 1;
-		  const $ext_name = file.name.split('.')[len];
-		  if ($ext_list.indexOf($ext_name) != -1) {
-		  } else {
-			this.toleadResult.id = 0
-			this.toleadResult.name = '文件格式上传错误,仅支持上传xlsx,xls)'
-			this.nowIndex = 3
-		    // this.$message.warning('文件格式上传错误,仅支持上传xlsx,xls)');
-		    return false;
-		  }
+			const $ext_list = ['xlsx', 'xls'];
+			let len = file.name.split('.').length - 1;
+			const $ext_name = file.name.split('.')[len];
+			if ($ext_list.indexOf($ext_name) != -1) {
+			} else {
+				this.toleadResult.id = 0;
+				this.toleadResult.name = '文件格式上传错误,仅支持上传xlsx,xls)';
+				this.nowIndex = 3;
+				// this.$message.warning('文件格式上传错误,仅支持上传xlsx,xls)');
+				return false;
+			}
 		},
-		tealConfirm(){
-			this.page=1;
+		tealConfirm() {
+			this.page = 1;
 			this.open_right(this.selectData);
 		},
-		handleOnthecross(event, file, fileList){
-			this.nowIndex = 2
+		handleOnthecross(event, file, fileList) {
+			this.nowIndex = 2;
 		},
 		handleSuccess(response) {
-			if(response.code == 1){
-				response.data.id = 1
-			}else{
-				response.data.id = 0
-				response.data.name = response.msg
+			if (response.code == 1) {
+				response.data.id = 1;
+			} else {
+				response.data.id = 0;
+				response.data.name = response.msg;
+			}
+			this.toleadResult = response.data;
+			this.nowIndex = 3;
+			return;
+			if (response.code == 1) {
+				if (response.data.length > 0) {
+					var htmls = response.data;
+					var str = "<div class='red'></div>";
+					htmls.forEach(item => {
+						str += `<div>${item.errors}</div>`;
+					});
+					this.close_import();
+					this.$notify.error({
+						title: '导入错误',
+						dangerouslyUseHTMLString: true,
+						message: str,
+						duration: 0,
+						offset: 50,
+						customClass: 'notifyBox'
+					});
+				} else {
+					this.file = response.data;
+					this.$message.success({ message: response.msg });
+					this.close_import();
+					this.page = 1;
+					this.open_right(this.selectData);
+				}
+			} else {
+				this.$message.error({ message: response.msg });
+				this.close_import();
 			}
-			this.toleadResult = response.data
-			this.nowIndex = 3
-			return
-		  if (response.code == 1) {
-		  	if (response.data.length > 0) {
-		  		var htmls = response.data;
-		  		var str = "<div class='red'></div>";
-		  		htmls.forEach(item => {
-		  			str += `<div>${item.errors}</div>`;
-		  		});
-		  		this.close_import();
-		  		this.$notify.error({
-		  			title: '导入错误',
-		  			dangerouslyUseHTMLString: true,
-		  			message: str,
-		  			duration: 0,
-		  			offset: 50,
-		  			customClass: 'notifyBox'
-		  		});
-		  	} else {
-		  		this.file = response.data;
-		  		this.$message.success({ message: response.msg });
-		  		this.close_import();
-				this.page=1;
-				this.open_right(this.selectData);
-		  	}
-		  }else{
-			  this.$message.error({ message: response.msg });
-			  this.close_import();
-		  }
 		},
 		handleRemove(file, fileList) {
-		  if (fileList !== null && fileList.length != 0) {
-		    this.import_btn_show = true;
-		  } else {
-		    this.import_btn_show = false;
-		  }
+			if (fileList !== null && fileList.length != 0) {
+				this.import_btn_show = true;
+			} else {
+				this.import_btn_show = false;
+			}
 		},
 
-		returnIndex(str,str2){
-			return str+"-"+str2;
+		returnIndex(str, str2) {
+			return str + '-' + str2;
 		},
 		handleCurrentChange(val) {
 			this.page = val;
 			this.open_right();
 		},
-		open_rights(data){
-			this.page=1;
-			this.selectData=data;
+		open_rights(data) {
+			this.page = 1;
+			this.selectData = data;
 			this.open_right(data);
 		},
 		// 组建
@@ -555,7 +588,7 @@ export default {
 		add_employee_close() {
 			this.add_employee_show = false;
 		},
-		
+
 		// 添加成员点击完成
 		sub_add_employee(form) {
 			let self = this;
@@ -581,7 +614,8 @@ export default {
 					} else {
 						this.disabled = true;
 						self.staff_loading = true;
-						self.$axios('post','/api/integral/auto/add',data).then(res => {
+						self.$axios('post', '/api/integral/auto/add', data)
+							.then(res => {
 								if (res.data.code == 1) {
 									self.$message.success('此次操作成功' + res.data.data.success + '条,失败' + res.data.data.error + '条,已经存在的' + res.data.data.exist + '条');
 									self.open_right();
@@ -616,7 +650,8 @@ export default {
 					cancelButtonText: '取消',
 					type: 'warning'
 				}).then(() => {
-					self.$axios('post','/api/integral/auto/delete/many',self.del_arr).then(res => {
+					self.$axios('post', '/api/integral/auto/delete/many', self.del_arr)
+						.then(res => {
 							if (res.data.code == 1) {
 								self.$message.success(res.data.msg);
 								// 判断当页的总数与选中的数量是否相等,如果相等,此页就无数据,就请求上一页的数据
@@ -626,7 +661,7 @@ export default {
 										this.page = this.page - 1;
 									}
 								}
-								self.open_right();	
+								self.open_right();
 							} else {
 								self.$message.error(res.data.msg);
 							}
@@ -646,7 +681,7 @@ export default {
 		},
 		//新增加分项
 		add_rules_detail() {
-			this.rules_detail_form={
+			this.rules_detail_form = {
 				rule_id: '',
 				range_type: '1',
 				prize_type: '1',
@@ -655,7 +690,7 @@ export default {
 				is_attendance: '0',
 				cycle_type: '2',
 				pt_id: '3'
-			}
+			};
 			this.dialogFormVisible = true;
 			this.rules_detail_title = false;
 		},
@@ -671,7 +706,7 @@ export default {
 			} else {
 				self.rules_detail_form.item_id = self.rules_detail_form.id;
 				data = self.rules_detail_form;
-				data.sync=2;
+				data.sync = 2;
 			}
 			self.$refs[form].validate(valid => {
 				if (valid) {
@@ -681,26 +716,31 @@ export default {
 					// } else {
 					// 	self.rules_detail_form.is_attendance = 0;
 					// }
-					var url=this.rules_detail_title ? 'api/integral/rule/items/edit' : '/api/integral/rule/items';
-					self.$axios('post',url,data).then(res => {
+					var url = this.rules_detail_title ? 'api/integral/rule/items/edit' : '/api/integral/rule/items';
+					self.$axios('post', url, data)
+						.then(res => {
 							// setTimeout(() => {
 							// 	this.is_attendance = false;
 							// }, 300);
 							if (res.data.code == 1) {
 								self.$message.success(res.data.msg);
 								self.rules_detail_show = false;
-								if (this.rules_detail_title) {//当为编辑时
-									 if(self.rules_detail_form.rule_id!=self.right_rules_detail.rule_id){//当编辑规则修改了上级时
+								if (this.rules_detail_title) {
+									//当为编辑时
+									if (self.rules_detail_form.rule_id != self.right_rules_detail.rule_id) {
+										//当编辑规则修改了上级时
 										self.get_role_lists(true);
-									 }else{//正常编辑
-										 self.get_role_lists();
-										 self.right_rules_detail.remark=data.remark;
-										 self.right_rules_detail.min_point=data.min_point;
-									 }	 
-								}else{//当为添加时
-									self.add_employee_id = res.data.data.item_id;//规则ID
-									self.add_rulse_id = self.rules_detail_form.rule_id;//分类ID
-									self.get_role_lists(true,true);
+									} else {
+										//正常编辑
+										self.get_role_lists();
+										self.right_rules_detail.remark = data.remark;
+										self.right_rules_detail.min_point = data.min_point;
+									}
+								} else {
+									//当为添加时
+									self.add_employee_id = res.data.data.item_id; //规则ID
+									self.add_rulse_id = self.rules_detail_form.rule_id; //分类ID
+									self.get_role_lists(true, true);
 									setTimeout(() => {
 										self.add_employee_show = true;
 									}, 600);
@@ -708,7 +748,8 @@ export default {
 							} else {
 								self.$message.error(res.data.msg);
 							}
-						}).finally(() => {
+						})
+						.finally(() => {
 							this.dialogFormVisible = false;
 							self.disabled = false;
 						});
@@ -724,37 +765,38 @@ export default {
 			this.$refs[form].resetFields();
 		},
 		//获取右边表格数据
-		open_right(data,updata) {
+		open_right(data, updata) {
 			let self = this;
 			self.table_loading = true;
-			this.isShowAdd=false;
-			if (data&&!updata) {
+			this.isShowAdd = false;
+			if (data && !updata) {
 				self.add_employee_id = data.id;
 				self.add_rulse_id = data.rule_id;
-				self.right_rules_detail = data;	
-				
-			}else if(updata){
-				self.right_rules_detail = data;	
-			}else{
+				self.right_rules_detail = data;
+			} else if (updata) {
+				self.right_rules_detail = data;
+			} else {
 				self.add_employee_id = self.right_rules_detail.id;
 				self.add_rulse_id = self.right_rules_detail.rule_id;
 			}
 			var params = {
-					item_id: self.add_employee_id || '',
-					employee_id: self.employee_id || '',
-					page: self.page,
-					page_size: Number(this.pagesize)
+				item_id: self.add_employee_id || '',
+				employee_id: self.employee_id || '',
+				page: self.page,
+				page_size: Number(this.pagesize)
 			};
-			self.$axios('get','/api/integral/auto/list', params).then(res => {
+			self.$axios('get', '/api/integral/auto/list', params)
+				.then(res => {
 					if (res.data.code == 1) {
 						self.table_list = res.data.data.list || [];
 						self.total = res.data.data.total;
 					} else {
 						self.$message.error(res.data.msg);
 					}
-			}).finally(() => {
-				self.table_loading = false;
-			});
+				})
+				.finally(() => {
+					self.table_loading = false;
+				});
 		},
 
 		//  编辑规则
@@ -772,7 +814,8 @@ export default {
 				type: 'warning'
 			}).then(() => {
 				this.disabled = true;
-				this.$axios('post','/api/integral/rule/items/destroy',{item_ids:JSON.stringify([item.id])}).then(res => {
+				this.$axios('post', '/api/integral/rule/items/destroy', { item_ids: JSON.stringify([item.id]) })
+					.then(res => {
 						if (res.data.code == 1) {
 							this.$message.success('删除成功');
 							this.rules_detail_show = false;
@@ -781,18 +824,19 @@ export default {
 							this.$message.error(res.data.msg);
 							this.get_role_lists();
 						}
-					}).finally(() => {
-							this.dialogFormVisible = false;
-							this.disabled = false;
+					})
+					.finally(() => {
+						this.dialogFormVisible = false;
+						this.disabled = false;
 					});
 			});
 		},
 
 		//新增加分组展示不同渲染
 		add_grouping() {
-			this.numberValidateForm={
-				name:''
-			}
+			this.numberValidateForm = {
+				name: ''
+			};
 			this.dialogVisible = true;
 			this.grouping_type = false;
 		},
@@ -812,13 +856,15 @@ export default {
 								name: this.numberValidateForm.name
 						  };
 					this.disabled = true;
-					var url=this.grouping_type ? '/api/integral/rule/edit' : '/api/integral/rule';
-					this.$axios('post',url,data).then(res => {
+					var url = this.grouping_type ? '/api/integral/rule/edit' : '/api/integral/rule';
+					this.$axios('post', url, data)
+						.then(res => {
 							if (res.data.code == '1') {
 								this.get_role_lists();
 								this.$message.success(this.grouping_type ? '修改积分规则' : res.data.msg);
 							}
-						}).finally(() => {
+						})
+						.finally(() => {
 							this.dialogVisible = false;
 							this.disabled = false;
 						});
@@ -839,63 +885,71 @@ export default {
 				confirmButtonText: '确定',
 				cancelButtonText: '取消',
 				type: 'warning'
-			}).then(() => {
-				this.disabled = true;
-				this.$axios('post','/api/integral/rule/destroy',{rule_id: item.id}).then(res => {
-					if (res.data.code == 1) {
-						this.get_role_lists();
-						this.$message.success('删除成功');
-					}
-				}).finally(()=>{
-					this.dialogVisible = false;
-					this.disabled = false;
+			})
+				.then(() => {
+					this.disabled = true;
+					this.$axios('post', '/api/integral/rule/destroy', { rule_id: item.id })
+						.then(res => {
+							if (res.data.code == 1) {
+								this.get_role_lists();
+								this.$message.success('删除成功');
+							}
+						})
+						.finally(() => {
+							this.dialogVisible = false;
+							this.disabled = false;
+						});
+				})
+				.catch(() => {
+					setTimeout(() => {
+						this.dialogVisible = false;
+					}, 300);
 				});
-			}).catch(() => {
-				setTimeout(() => {
-					this.dialogVisible = false;
-				}, 300);
-			});
 		},
 		// 获取初始化数据
-		get_role_lists(is,noUpdata) {
+		get_role_lists(is, noUpdata) {
 			this.table_loading = true;
 			this.rule_trees_load = true;
-			this.$axios('get','/api/integral/rule/trees', {cycle_type: '2'}).then(res => {
-					var	rule_list = res.data.data.rule_tree||[];
-					var	item_list = res.data.data.item_list||[];
-					var itemListAll=[];
+			this.$axios('get', '/api/integral/rule/trees', { cycle_type: '2' })
+				.then(res => {
+					var rule_list = res.data.data.rule_tree || [];
+					var item_list = res.data.data.item_list || [];
+					var itemListAll = [];
 					for (let i in item_list) {
-					  for (let k in item_list[i]) {
-						itemListAll.push(item_list[i][k])
-					  }
+						for (let k in item_list[i]) {
+							itemListAll.push(item_list[i][k]);
+						}
 					}
-					rule_list.map(item=>{
-						item.child=itemListAll.filter((item2)=>{return item2.rule_id==item.id});
-					})
-					this.rule_list=rule_list;
-					this.item_list=itemListAll;
-					if(is){
-						this.default_active="";
-						if(rule_list[0].child[0]){
-							this.right_rules_detail={};
-							this.table_list=[];
-							this.page=1;
-							this.selectData=rule_list[0].child[0];
-							this.open_right(rule_list[0].child[0],noUpdata);
-							setTimeout(()=>{
-								this.default_active = '0-0'
-							},500)
-						}else{
-							this.right_rules_detail={};
-							this.isShowAdd=true;
+					rule_list.map(item => {
+						item.child = itemListAll.filter(item2 => {
+							return item2.rule_id == item.id;
+						});
+					});
+					this.rule_list = rule_list;
+					this.item_list = itemListAll;
+					if (is) {
+						this.default_active = '';
+						if (rule_list[0].child[0]) {
+							this.right_rules_detail = {};
+							this.table_list = [];
+							this.page = 1;
+							this.selectData = rule_list[0].child[0];
+							this.open_right(rule_list[0].child[0], noUpdata);
+							setTimeout(() => {
+								this.default_active = '0-0';
+							}, 500);
+						} else {
+							this.right_rules_detail = {};
+							this.isShowAdd = true;
 						}
 					}
-			}).finally(err=>{
-				setTimeout(()=>{
-					this.rule_trees_load = false;
-					this.table_loading = false;
-				},700)
-			});
+				})
+				.finally(err => {
+					setTimeout(() => {
+						this.rule_trees_load = false;
+						this.table_loading = false;
+					}, 700);
+				});
 		}
 	}
 };
@@ -936,8 +990,8 @@ export default {
 	// }
 }
 ::v-deep .el-submenu__title {
-    height: 47px !important;
-    line-height: 47px !important;
+	height: 47px !important;
+	line-height: 47px !important;
 }
 .rule_list {
 	position: relative;
@@ -961,7 +1015,7 @@ export default {
 		margin-right: 20px;
 	}
 
-	.btns{
+	.btns {
 		padding-top: 20px;
 	}
 }

+ 1 - 1
src/views/subassembly/update_notice.vue

@@ -2,7 +2,7 @@
     <div class="integral_statistics_box" v-loading="noticeLoad">
         <el-row>
 			<el-col :span="24" style="height:60px;line-height:60px;">
-				<el-col :span="6" style="color:#9e9d9d;padding-left:25px;max-width: 280px;">系统公告列表</el-col>
+				<el-col :span="6" style="color:#9e9d9d;padding-left:25px;max-width: 280px;">系统通知列表</el-col>
 				<el-col :span="18" style="padding-left:30px;">
 					<span style="font-size:16px;">{{articleOne.title?articleOne.title:''}}</span>
 					<span style="font-size:15px;margin-left:25px;color:#9e9d9d">{{articleOne.publish_time?articleOne.publish_time:''}}</span>

+ 2 - 2
src/views/task/allTask.vue

@@ -130,7 +130,7 @@
 </template>
 
 <script>
-import noData from '@/components/noData';
+
 import examinePopup from '@/components/examinePopup.vue';
 import taskDetailsPopup from '@/views/common/taskDetailsPopup'
 import {_debounce} from '@/api/auth';
@@ -173,7 +173,7 @@ export default {
 			detailShow:false,
 		};
 	},
-	components: { taskDetailsPopup, noData,examinePopup },
+	components: { taskDetailsPopup,examinePopup },
 	watch: {
 		'formData.content': {
 		  deep: true,

+ 2 - 2
src/views/task/get_task.vue

@@ -204,7 +204,7 @@
 </template>
 
 <script>
-import noData from '@/components/noData';
+
 export default {
 	name: 'get_task',
 	data() {
@@ -230,7 +230,7 @@ export default {
 	mounted() {
 		this.get_list();
 	},
-	components: { noData },
+	
 	watch: {
 		active(val) {
 			this.list = [];

+ 2 - 2
src/views/task/myExamine.vue

@@ -103,7 +103,7 @@
 </template>
 
 <script>
-import noData from '@/components/noData';
+
 import examinePopup from '@/components/examinePopup.vue';
 import taskDetailsPopup from '@/views/common/taskDetailsPopup'
 
@@ -144,7 +144,7 @@ export default {
 			detailShow:false,
 		};
 	},
-	components: { taskDetailsPopup, noData,examinePopup },
+	components: { taskDetailsPopup,examinePopup },
 	watch: {
 		'formData.pt_id'(val) {
 			this.formData.page = 1;

+ 2 - 2
src/views/task/my_issue.vue

@@ -291,7 +291,7 @@
 </template>
 
 <script>
-import noData from '@/components/noData';
+
 import temporaryTask from '@/views/common/temporaryTask';
 import temporaryTaskAmend from '@/views/common/temporaryTaskAmend';
 import rewardTask from '@/views/common/rewardTask';
@@ -357,7 +357,7 @@ export default {
 			employee_map: [] //人员列表
 		};
 	},
-	components: { noData, temporaryTask, rewardTask, rewardTaskAmend, temporaryTaskAmend, taskDetailsPopup, repeatTaskDetailsPopup, rewardTaskDetailsPopup },
+	components: {temporaryTask, rewardTask, rewardTaskAmend, temporaryTaskAmend, taskDetailsPopup, repeatTaskDetailsPopup, rewardTaskDetailsPopup },
 	watch: {
 		status(val) {
 			this.formData.executor_id = '';

+ 3 - 3
src/views/task/my_task.vue

@@ -152,7 +152,7 @@
 </template>
 
 <script>
-import noData from '@/components/noData';
+
 import taskDetailsPopup from '@/views/common/taskDetailsPopup'
 import upload from '@/components/upload';
 
@@ -192,7 +192,7 @@ export default {
 			showRewardTaskDetailsPopup: false
 		};
 	},
-	components: { taskDetailsPopup, noData, upload },
+	components: { taskDetailsPopup, upload },
 	watch: {
 		'formData.pt_id'(val) {
 			this.formData.page = 1
@@ -248,7 +248,7 @@ export default {
 			const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
 			const isLt2M = file.size / 1024 / 1024 < 1;
 			if (!isJPG) {
-				this.$message.error('上传头像图片只能是 JPG 格式!');
+				this.$message.error('上传头像图片只能是 JPEG,PNG,JPG 格式!');
 			}
 			if (!isLt2M) {
 				this.$message.error('上传头像图片大小不能超过 2MB!');

+ 383 - 2
src/views/welfare/conversion.vue

@@ -1,8 +1,389 @@
 <template>
-</template>
+	<div>
+		<div class="all" style="padding: 20px;" v-loading="attendload">
+			<div>
+				<el-form :inline="true">
+					<el-button type="primary" size="medium">批量发放</el-button>
+					<el-form-item label="兑换码">
+						<el-input placeholder="奖品搜索" size="medium" style="width: 200px;margin: 0 10px;" v-model="formData.event_type" clearable></el-input>
+					</el-form-item>
+					<el-form-item label="人员">
+						<el-select v-model="select_employee_id" size="medium" filterable placeholder="请输入或选择人员" clearable>
+							<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item label="状态">
+						<el-select v-model="formData.event_type" size="medium" @change="selectgroupId" style="width:110px" placeholder="请选择">
+							<el-option v-for="(item, index) in event_type" :key="index" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item label="时间">
+						<el-date-picker
+							size="medium"
+							style="width:290px"
+							class="first-element-btn"
+							:clearable="false"
+							v-model="time_range"
+							type="daterange"
+							value-format="yyyy-MM-dd"
+							range-separator="至"
+							start-placeholder="开始日期"
+							end-placeholder="结束日期"
+							:picker-options="instantPickerOptions"
+							@change="onFilterChanged"
+						></el-date-picker>
+					</el-form-item>
+					<el-form-item><el-button type="primary" plain @click="exportRanking">导出排名</el-button></el-form-item>
+				</el-form>
+			</div>
+			<el-table :data="all_integral_list" style="width: 100%" v-loading="loading">
+				<el-table-column type="selection"></el-table-column>
+				<el-table-column label="姓名" align="left">
+					<template slot-scope="scope">
+						<div style="display:flex;">
+							<userImage :user_name="scope.row.name" :img_url="scope.row.img_url" width="50px" height="50px"></userImage>
+							<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.name }}</span>
+						</div>
+					</template>
+				</el-table-column>
+				<el-table-column prop="point" label="奖品名称" align="center"></el-table-column>
+				<el-table-column prop="point" label="数量" align="center"></el-table-column>
+				<el-table-column prop="point" label="总价" align="center"></el-table-column>
+				<el-table-column prop="point" label="兑换时间" align="center"></el-table-column>
+				<el-table-column prop="point" label="兑换码" align="center"></el-table-column>
+				<el-table-column prop="point" label="发放时间" align="center"></el-table-column>
+				<el-table-column prop="point" label="状态" align="center"></el-table-column>
+				<el-table-column prop="point" label="操作" align="left">
+					<template slot-scope="scope">
+						<el-link type="primary">主要链接</el-link>
+						<el-link type="primary">主要链接</el-link>
+						<el-link type="primary">主要链接</el-link>
+					</template>
+				</el-table-column>
+
+				<template slot="empty">
+					<noData :content="checkingInGroup.length == 0 ? '请先开启钉钉考勤' : '暂无数据'"></noData>
+				</template>
+			</el-table>
+			<center style="padding: 20px 0;">
+				<el-pagination
+					background
+					@size-change="handleSizeChange1"
+					@current-change="handleCurrentChange"
+					:current-page="formData.page"
+					:page-sizes="[10, 20, 50, 100]"
+					layout="total, sizes, prev, pager, next"
+					:page-size="pageLimit1"
+					:total="total"
+				></el-pagination>
+			</center>
+		</div>
+		<!-- 导出弹窗 -->
+		<el-dialog title="导出排名" :visible.sync="dialogVisible" width="730px">
+			<div style="font-size:15px;margin:20px 0 20px 0;">系统将按以下已选条件导出对应的排名报表</div>
+			<div v-loading="exportLoad">
+				<el-form :inline="true">
+					<el-form-item label="考勤组">
+						<el-select v-model="exportData.group_id" @change="selectgroupId" filterable :clearable="false" placeholder="请选择考勤组">
+							<el-option v-for="item in checkingInGroup" :key="item.id" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item>
+
+					<el-form-item label="排名类型">
+						<el-select v-model="exportData.event_type" style="width:150px" placeholder="请选择">
+							<el-option v-for="(item, index) in event_type" :key="index" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item>
 
+					<el-form-item label="时间">
+						<el-date-picker
+							class="first-element-btn"
+							:clearable="false"
+							v-model="exportTime_range"
+							type="daterange"
+							value-format="yyyy-MM-dd"
+							range-separator="至"
+							start-placeholder="开始日期"
+							end-placeholder="结束日期"
+							:picker-options="instantPickerOptions"
+						></el-date-picker>
+					</el-form-item>
+				</el-form>
+				<span class="dialog-footer" style="display:flex;justify-content: flex-end;">
+					<el-button @click="dialogVisible = false">取 消</el-button>
+					<el-button type="primary" @click="exportExcel">导 出</el-button>
+				</span>
+			</div>
+		</el-dialog>
+	</div>
+</template>
 <script>
+export default {
+	data() {
+		return {
+			// 设置只能选择当前日期及之后的日期
+			pickerOptions: {
+				disabledDate(time) {
+					return time.getTime() > Date.now() - 8.64e7; //如果没有后面的-8.64e7就是不可以选择今天的
+				}
+			},
+			exportLoad: false,
+			dialogVisible: false,
+			checkingInGroup: [],
+			employee_map: [],
+			select_employee_id: '',
+			event_type: [
+				{ id: 0, name: '总分' },
+				{ id: 1, name: '迟到' },
+				{ id: 2, name: '早退' },
+				{ id: 6, name: '准时打卡' },
+				{ id: 20, name: '上班缺卡' },
+				{ id: 21, name: '下班缺卡' },
+				{ id: 16, name: '加班 ' },
+				{ id: 10, name: '缺勤' }
+			],
+			attendload: false,
+			loading: false,
+			all_integral_list: null,
+			Month_range: this.$moment().format('YYYY-MM'),
+			time_range: [
+				this.$moment()
+					.startOf('month')
+					.format('YYYY-MM-DD'),
+				this.$moment()
+					.endOf('month')
+					.format('YYYY-MM-DD')
+			],
+			formData: {
+				group_id: '',
+				// date_type: 3,
+				page: 1,
+				page_size: 10,
+				event_type: 0
+			},
+			exportMonth_range: this.$moment().format('YYYY-MM'),
+			exportTime_range: [
+				this.$moment()
+					.startOf('month')
+					.format('YYYY-MM-DD'),
+				this.$moment()
+					.endOf('month')
+					.format('YYYY-MM-DD')
+			],
+			exportData: {
+				group_id: '',
+				event_type: 0
+			},
+			total: 0,
+			dept_tree: [],
+			dept_name: [],
+			pageLimit1: 10,
+			instantPickerOptions: {
+				shortcuts: [
+					{
+						text: '本周',
+						onClick(picker) {
+							const now = new Date();
+							const start = new Date();
+							start.setTime(now.getTime() - (now.getDay() - 1) * 24 * 60 * 60 * 1000);
+							now.setTime(start.getTime() + 6 * 24 * 60 * 60 * 1000 - 1000);
+							picker.$emit('pick', [start, now]);
+						}
+					},
+					{
+						text: '上周',
+						onClick(picker) {
+							const end = new Date();
+							const start = new Date();
+							start.setTime(start.getTime() - (start.getDay() + 6) * 3600 * 1000 * 24);
+							end.setTime(start.getTime() + 6 * 24 * 60 * 60 * 1000 - 1000);
+							picker.$emit('pick', [start, end]);
+						}
+					},
+					{
+						text: '本月',
+						onClick(picker) {
+							const now = new Date();
+							const startDate = new Date(now.getFullYear(), now.getMonth(), 1);
+							const endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0);
+							picker.$emit('pick', [startDate, endDate]);
+						}
+					},
+					{
+						text: '上月',
+						onClick(picker) {
+							const now = new Date();
+							const startDate = new Date(now.getFullYear() - (now.getMonth() > 0 ? 0 : 1), (now.getMonth() + 11) % 12, 1);
+							const endDate = new Date(now.getFullYear(), now.getMonth(), 0);
+							picker.$emit('pick', [startDate, endDate]);
+						}
+					}
+				]
+			},
+			// 更新考勤数据
+			isUpdate: false,
+			update: {
+				type: 'daily',
+				target_date: '',
+				target_month: ''
+			}
+		};
+	},
+
+	watch: {
+		isUpdate(val) {
+			if (!val) {
+				this.update = {
+					type: 'daily',
+					target_date: '',
+					target_month: ''
+				};
+			}
+		}
+	},
+	created() {
+		this.employee_map = JSON.parse(localStorage.getItem('userList'));
+	},
+	mounted() {
+		this.checkingIn_group(); //考勤组
+	},
+	methods: {
+		saveUpdate() {
+			let update = this.update;
+			let data = { type: update.type };
+			if (update.type == 'daily') {
+				if (!update.target_date) {
+					this.$message.error('请选择日期');
+					return false;
+				}
+				data.target_date = update.target_date;
+			} else {
+				if (!update.target_month) {
+					this.$message.error('请选择月份');
+					return false;
+				}
+				data.target_month = update.target_month;
+			}
+			this.$axios('post', '/api/ding/ad_sync', data).then(res => {
+				if (res.data.code == 1) {
+					this.$message.success('已更新');
+					this.isUpdate = false;
+				}
+			});
+		},
+		exportRanking() {
+			if (this.checkingInGroup.length > 0) {
+				this.exportData.group_id = this.checkingInGroup[0].id;
+			}
+			this.dialogVisible = true;
+		},
+		exportExcel() {
+			window.open(
+				process.env.VUE_APP_BASE_API +
+					'api/download/groups_ranking/export?start_date=' +
+					this.exportTime_range[0] +
+					'&end_date=' +
+					this.exportTime_range[1] +
+					'&page=' +
+					1 +
+					'&page_size=' +
+					2000 +
+					'&group_id=' +
+					this.exportData.group_id +
+					'&event_type=' +
+					this.exportData.event_type +
+					'&employee_id=' +
+					this.$getUserData().id,
+				'_blank'
+			);
+		},
+		selectgroupId() {
+			this.get_all_integral();
+		},
+		onFilterChanged() {
+			this.get_all_integral();
+		},
+		//分页
+		handleSizeChange1(val) {
+			this.pageLimit1 = val;
+			this.formData.page_size = this.pageLimit1;
+			this.get_all_integral();
+		},
+		handleCurrentChange(val) {
+			this.formData.page = val;
+			this.get_all_integral();
+		},
+		//请求数据
+		checkingIn_group() {
+			this.attendload = true;
+			let self = this;
+			let params = {
+				page: 1,
+				page_size: 2000
+			};
+			this.$axios('get', '/api/ad/groups', params)
+				.then(res => {
+					if (res.data.code == 1) {
+						let list = res.data.data.list;
+						let datas = [];
+						for (let key in list) {
+							let obj = {};
+							obj.id = key;
+							obj.name = list[key];
+							datas.push(obj);
+						}
+						this.checkingInGroup = datas;
+						this.formData.group_id = datas[0].id;
+					}
+				})
+				.finally(() => {
+					this.get_all_integral();
+					this.attendload = false;
+				});
+		},
+		//请求数据
+		get_all_integral() {
+			let self = this;
+			self.loading = true;
+			let data = {
+				group_id: this.formData.group_id,
+				page: this.formData.page,
+				page_size: this.formData.page_size,
+				event_type: this.formData.event_type
+			};
+			data.start_date = this.time_range[0];
+			data.end_date = this.time_range[1];
+			this.$axios('post', '/api/ad/rank', data)
+				.then(res => {
+					if (res.data.code == 1) {
+						self.all_integral_list = res.data.data.list;
+						this.total = res.data.data.total;
+					} else {
+						self.$message.error(res.data.data.msg);
+					}
+				})
+				.finally(() => {
+					self.loading = false;
+				});
+		}
+	}
+};
 </script>
 
-<style>
+<style scoped lang="scss">
+.el-date-editor.el-input {
+	width: auto;
+}
+.date-picker-width {
+	width: 145px !important;
+}
+.search ::v-deep .el-input-group__append:active {
+	background: #26a2ff;
+}
+.search ::v-deep .el-input-group__append:active .el-icon-search {
+	color: #fff;
+}
+::v-deep .el-dialog__body {
+	padding: 0px 20px 30px;
+}
 </style>

+ 47 - 0
src/views/welfare/flBox.vue

@@ -0,0 +1,47 @@
+<template>
+	<div style="background-color: #fff;padding: 20px;" class="boxMinHeight">
+		<el-tabs v-model="activeName" @tab-click="handleClick">
+			<el-tab-pane label="功勋点管理" name="1">
+				<flManagement></flManagement>
+			</el-tab-pane>
+			<el-tab-pane label="操作记录" name="2">
+				<operatingRecord></operatingRecord>
+			</el-tab-pane>
+		</el-tabs>
+	</div>
+</template>
+<script>
+import operatingRecord from '@/views/welfare/operatingRecord';
+import flManagement from '@/views/welfare/flManagement';
+export default {
+	name: 'flBox',
+	components: { operatingRecord,flManagement },
+	data() {
+		return {
+			activeName: '1',
+		};
+	},
+	watch: {
+		dept_name(val) {
+			if (val.length !== 0) {
+				this.formData.dept_id = val[val.length - 1];
+			} else {
+				this.formData.dept_id = '0';
+			}
+			this.formData.page = 1;
+			this.$nextTick(() => {
+				this.$refs.dept.dropDownVisible = false;
+				this.get_list();
+			});
+		}
+	},
+	methods: {
+		handleClick() {},
+	},
+	created() {
+	}
+};
+</script>
+<style scoped lang="scss">
+
+</style>

+ 601 - 2
src/views/welfare/flManagement.vue

@@ -1,8 +1,607 @@
 <template>
-</template>
+	<div>
+		<div class="all">
+			<div class="flex-box-ce flex-d-wrap" style="margin-top: 16px;">
+				<div class="flex-box" style="margin-bottom: 10px;">
+					<el-button type="primary" size="medium" @click="openCz(1)" style="margin-left: 10px;" plain>发放功勋点</el-button>
+					<el-button type="warning" size="medium" @click="openCz(2)" style="margin-left: 10px;" plain>回收功勋点</el-button>
+					<el-button type="success" size="medium" @click="openCz(3)" style="margin-left: 10px;" plain>转换功勋点</el-button>
+				</div>
+				<div class="flex-box-end flex-v-ce" style="font-size: 16px;margin-left: 10px;margin-bottom: 10px;">
+					<span>当前转换比例</span>
+					<span class="blue" style="padding: 0 10px;font-weight: 600;">1 : 10</span>
+					<i class="el-icon-edit" style="font-size: 16px;" @click="isZh = true"></i>
+				</div>
+				<div class="flex-1"></div>
+				<div class="flex-box-ce" style="margin-bottom: 10px;">
+					<div class="label">部门</div>
+					<el-cascader
+						size="medium"
+						class="date-picker-width"
+						v-model="dept_name"
+						:options="dept_tree"
+						:props="{ checkStrictly: true, value: 'id', label: 'name', children: '_child' }"
+						ref="dept"
+						clearable
+						filterable
+						placeholder="全公司"
+					></el-cascader>
+				</div>
+				<div class="flex-box-ce" style="margin-bottom: 10px;">
+					<div class="label">人员</div>
+					<el-select v-model="select_employee_id" size="medium" filterable placeholder="请输入或选择人员" clearable>
+						<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
+					</el-select>
+				</div>
+			</div>
+
+			<el-table :data="list" style="width: 100%" v-loading="loading" @selection-change="deleteEvents">
+				<el-table-column label="姓名" align="center" prop="point">
+					<template slot-scope="scope">
+						<div class="flex-box">
+							<userImage :user_name="scope.row.employee_name" :img_url="scope.row.employee_img_url" width="50px" height="50px"></userImage>
+							<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.employee_name }}</span>
+						</div>
+					</template>
+				</el-table-column>
+				<el-table-column label="部门" align="center" prop="point"></el-table-column>
+				<el-table-column label="累计B分" align="center" prop="point"></el-table-column>
+				<el-table-column label="当前可转B分" align="center" prop="point">
+					<template slot="header" slot-scope="scope">
+					  <el-tooltip effect="dark" placement="top-start">
+					    <div slot="content">
+					      <div style="margin-bottom: 10px;">说明</div>
+					      <div style="padding-left: 20px;">
+							  1、可转B分余额,来自员工在企业内所得的累计B分(包含基础分和工龄分)			        <br />
+							  2、员工可以通过获得更多的累计B分,来增加可转B分余额的收入			        <br />
+							  3、回收功勋点不会增加可转B分余额			        <br />
+							  4、转换成功勋点后,余额将被扣除
+					      </div>
+					    </div>
+					    <span>
+					      <span>当前可转B分</span>
+					      <i class="el-icon-warning"></i>
+					    </span>
+					  </el-tooltip>
+					</template>
+					
+				</el-table-column>
+				<el-table-column label="转换后可得功勋点" align="center" prop="point"></el-table-column>
+				<el-table-column label="现有功勋点" align="center" prop="point"></el-table-column>
+				<el-table-column label="操作">
+					<template slot-scope="scope">
+						<el-link type="primary" @click="moreMessage(scope.row.id)" :underline="false" style="padding-right: 10px;">个人明显</el-link>
+						<el-dropdown @command="handleCommand">
+							<el-button size="mini">
+								管理
+								<i class="el-icon-arrow-down el-icon--right"></i>
+							</el-button>
+							<el-dropdown-menu slot="dropdown">
+								<el-dropdown-item :command="{id:scope.row.employee_id,name:'1'}">发放</el-dropdown-item>
+								<el-dropdown-item :command="{id:scope.row.employee_id,name:'2'}">回收</el-dropdown-item>
+								<el-dropdown-item :command="{id:scope.row.employee_id,name:'3'}">转换</el-dropdown-item>
+							</el-dropdown-menu>
+						</el-dropdown>
+					</template>
+				</el-table-column>
+				<template slot="empty">
+					<div class="nopoint_box">
+						<div class="noimg noperson"></div>
+						<span class="title">没有对应的数据</span>
+					</div>
+				</template>
+			</el-table>
 
+			<center style="padding: 20px 0;">
+				<el-pagination
+					background
+					@size-change="handleSizeChange"
+					@current-change="handleCurrentChange"
+					:current-page="formData.page"
+					:page-sizes="[10, 20, 50, 100]"
+					layout="total, sizes, prev, pager, next"
+					:page-size="pageLimit"
+					:total="total"
+				></el-pagination>
+			</center>
+		</div>
+		<!-- 转换设置 -->
+		<el-dialog title="转换设置" :visible.sync="isZh" width="500px" top="10%">
+			<div class="flex-box-ce" style="margin-bottom: 20px;">
+				<span class="yellow flex-1">B分转换功勋点将按以下比列进行转换</span>
+				<span style="cursor: pointer;" class="blue" @click="innerVisible = true">查看转换历史</span>
+			</div>
+			<div class="flex-box-ce flex-center-center" style="margin-bottom: 10px;font-size: 16px;">
+				<span>转换比例 1:</span>
+			    <el-input type="text" class="width-250" v-model="zhNum" placeholder="请输入比例" @input="[zhNum=zhNum.replace(/[^\d]/g,'')]"/>
+			</div>
+			<div style="text-align: center;"><i class="el-icon-d-arrow-left fontColorT" style="font-size: 30px;transform: rotate(-90deg);"></i></div>
+			<div style="text-align: center;font-size: 22px;margin: 10px 0 30px 0;">
+				1 B分 =
+				<span class="blue">{{ zhNum }}</span>
+				功勋点
+			</div>
+			<span slot="footer" class="dialog-footer">
+				<el-button @click="isZh = false" size="medium">取 消</el-button>
+				<el-button type="primary" @click="exportExcel" size="medium">确 定</el-button>
+			</span>
+			<el-dialog width="500px" title="历史转换比例记录" :visible.sync="innerVisible" append-to-body>
+				<div style="max-height: 400px;overflow-y: auto;" class="scroll-bar">
+					<div v-for="(item, index) in innerList" :key="index" style="padding-bottom: 16px;">
+						<span class="green">{{ item.name }}</span>
+						在{{ item.date }} 修改转换比列为
+						<span class="blue">{{ item.num }}</span>
+					</div>
+				</div>
+				<span slot="footer" class="dialog-footer"><el-button @click="innerVisible = false" size="medium">关 闭</el-button></span>
+			</el-dialog>
+		</el-dialog>
+		<!-- 发放/回收/转换 -->
+		<el-dialog :title="czText + '功勋点'" :visible.sync="isCz" width="500px" top="10%">
+			<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="120px">
+				<el-form-item :label="czText+'对象'" prop="employee_ids" v-if="isEmployee">
+					<div class="border flex-box-ce">
+						<div class="flex-1" v-if="Administrator.length == 0">请选择人员</div>
+						<div v-else style="width: 180px;" class="font-flex-word">
+							<span v-for="(item, index) in Administrator" :key="index">
+								<i v-if="index != 0">,</i>
+								{{ item.name }}
+							</span>
+						</div>
+						<span v-if="Administrator.length > 0" class="blue">{{ Administrator.length }}人</span>
+						<i class="el-icon-arrow-down icon-right" v-else></i>
+						<div @click="openAdministrator()" class="inputDc"></div>
+					</div>
+				</el-form-item>
+				<el-form-item :label="czText+'数值'" prop="zhNum">
+					<el-input type="text" class="width-250" placeholder="请输入功勋点" v-model="ruleForm.zhNum" @input="[ruleForm.zhNum=ruleForm.zhNum.replace(/[^\d]/g,'')]"/>
+				</el-form-item>
+				<el-form-item label="备注原因:" prop="content">
+					<el-input
+						type="textarea"
+						v-model="ruleForm.content"
+						placeholder="请输入原因"
+						class="width-250"
+						:autosize="{ minRows: 3, maxRows: 6 }"
+						show-word-limit
+						maxlength="100"
+					></el-input>
+				</el-form-item>
+			</el-form>
+			<span slot="footer" class="dialog-footer">
+				<el-button @click="isCz = false" size="medium">取 消</el-button>
+				<el-button type="primary" @click="submit('ruleForm')" size="medium">确 定</el-button>
+			</span>
+		</el-dialog>
+		<el-dialog title="选择人员" width="640px" :visible.sync="isChecks" append-to-body>
+			<EmployeeSelector ref="members" v-if="isChecks" :selected="selected" @confirm="employeeConfirm" />
+			<span slot="footer" class="dialog-footer">
+				<el-button @click="isChecks = false">取 消</el-button>
+				<el-button type="primary" @click="$refs.members.confirm()">确 定</el-button>
+			</span>
+		</el-dialog>
+		<!-- 个人明细 -->
+		<el-dialog title="个人明细" width="700px" :visible.sync="isDetail" top="5%">
+			<div class="flex-box-ce">
+				<div class="titled" v-for="(item,index) in detailData" :key="index">
+					<div class="num" :class="item.num>0? 'blue':'red'">{{item.num}}</div>
+					<div class="fontColorF">{{item.name}}</div>
+				</div>
+			</div>
+			<div class="flex-box-end " style="margin-bottom: 10px;">
+				<el-button type="primary" plain size="small">导出个人明细</el-button>
+			</div>
+			<el-table :data="[]" style="width: 100%" border v-loading="loading">
+				<el-table-column label="姓名" align="left" prop="point"></el-table-column>
+				<el-table-column label="部门" align="center" prop="point"></el-table-column>
+				<el-table-column label="功勋点" align="center" prop="point"></el-table-column>
+				<el-table-column label="描述" align="center" prop="point"></el-table-column>
+				<el-table-column label="时间" align="center" prop="point"></el-table-column>
+				<template slot="empty">
+					<noData></noData>
+				</template>
+			</el-table>
+			<center style="padding-top: 20px;">
+					  <el-pagination
+					   background
+						@current-change="handleCurrentChange2"
+						layout="prev, pager, next"
+						:total="total">
+					  </el-pagination>
+			</center>
+			<span slot="footer" class="dialog-footer">
+				<el-button @click="isDetail = false">取 消</el-button>
+				<el-button type="primary">确 定</el-button>
+			</span>
+		</el-dialog>
+	</div>
+</template>
 <script>
+import EmployeeSelector from '@/components/EmployeeSelector';
+export default {
+	name: 'flManagement',
+	components: { EmployeeSelector },
+	data() {
+		return {
+			activeName: '1',
+			select_employee_id: '',
+			employee_map: [],
+			dept_name: [],
+			dept_tree: [],
+			loading: false,
+			formData: {
+				dept_id: '0',
+				sort: 'DESC',
+				page: 1,
+				page_size: 10,
+				pt_id: 3,
+				type: 'all'
+			},
+			list: null,
+			pageLimit: 10,
+			total: null,
+			isZh: false,
+			zhNum:1,
+			positions: [{ id: 0, age: 'all', name: '全部' }, { id: 1, age: 'manager', name: '管理者' }, { id: 2, age: 'employee', name: '员工' }],
+			Dc_Data: {
+				//导出数据
+				value1: '', //时间
+				DC_position: '全部', //人员
+				dept_name: [] //部门
+			},
+			innerVisible: false,
+			innerList: [
+				{ name: '阿松大阿松大', date: '2020-20-1', num: '1:30' },
+				{ name: '阿松大阿松大', date: '2020-20-1', num: '1:30' },
+				{ name: '阿松大阿松大', date: '2020-20-1', num: '1:30' },
+				{ name: '阿松大阿松大', date: '2020-20-1', num: '1:30' }
+			],
+
+			// 发放/回收/转换
+			Administrator: [],
+			isChecks: false,
+			selected: { dept: [], employee: [] },
+			ruleForm: {
+				content: '',
+				zhNum: '', 
+				employee_ids: []
+			},
+			rules: {
+				zhNum: [{ required: true, message: '请输入数值', trigger: 'blur' }],
+				employee_ids: [{ required: true, message: '请选择被考核人员', trigger: 'change' }]
+			},
+			czText: '发放',
+			isCz: false,
+			isEmployee:true,
+			
+			// 个人明显
+			isDetail:false,
+			detailData:[
+				{name:'现有功勋点',num:1000},
+				{name:'管理员发放',num:254},
+				{name:'B分转换',num:20},
+				{name:'同事点赞',num:166},
+				{name:'兑换奖品',num:-100},
+				{name:'被回收',num:-25}
+			]
+		};
+	},
+	watch: {
+		isCz(val){
+			if(!val){
+				this.ruleForm={
+				content: '',
+				zhNum: '', 
+				employee_ids:[]
+				};
+				this.isEmployee=true;
+				this.Administrator= [];
+				this.selected={ dept: [], employee: [] };
+			}
+		},
+		dept_name(val) {
+			if (val.length !== 0) {
+				this.formData.dept_id = val[val.length - 1];
+			} else {
+				this.formData.dept_id = '0';
+			}
+			this.formData.page = 1;
+			this.$nextTick(() => {
+				this.$refs.dept.dropDownVisible = false;
+				this.get_list();
+			});
+		}
+	},
+	methods: {
+		moreMessage(){
+			this.isDetail=true;
+		},
+		handleCommand(e){
+			this.ruleForm.employee_ids.push(e.id);
+			this.isEmployee=false;
+			this.openCz(Number(e.name))
+		},
+		submit(str){
+			this.$refs[str].validate((valid) => {
+			  if (valid) {
+				console.log(this.ruleForm)
+			  } else {
+				console.log('error submit!!');
+				return false;
+			  }
+			});
+			this.isCz=true;   
+		},
+		keyupEvent(str){
+			this.ruleForm.zhNum=this.ruleForm.zhNum.replace(/^(0+)|[^\d]+/g,'')
+		},
+		openCz(index) {
+			switch (index) {
+				case 1:
+					this.czText = '发放';
+					break;
+				case 2:
+					this.czText = '回收';
+					break;
+				case 3:
+					this.czText = '转换';
+					break;
+			}
+			this.isCz=true;
+		},
+		// 选择录入对象
+		employeeConfirm(e) {
+			this.ruleForm.employee_ids = e.employee.map(item=>{
+				return item.id
+			})
+			this.selected.employee = e.employee.length > 0 ? e.employee : [];
+			this.Administrator = e.employee.length > 0 ? e.employee : [];
+			this.isChecks = false;
+		},
+		openAdministrator() {
+			this.isChecks = true;
+		},
+		handleClick() {
+			
+		},
+		deleteEvents(selection) {
+			let listId = [];
+			selection.forEach(item => {
+				listId.push(item.id);
+			});
+			this.selectionID = listId;
+		},
+		exportExcel() {},
+		handleCurrentChange2(val) {
+			this.formData.page = val;
+			this.get_list();
+		},
+		// 页面变更
+		handleCurrentChange(val) {
+			this.formData.page = val;
+			this.get_list();
+		},
+		handleSizeChange(val) {
+			this.pageLimit = val;
+			this.formData.page_size = this.pageLimit;
+			this.get_list();
+		},
+		//获取部门
+		getDepartment() {
+			this.$axios('get', '/api/department/tree').then(res => {
+				this.dept_tree = this.getTreeData(res.data.data.list);
+			});
+		},
+		get_list() {
+			this.loading = true;
+			this.$axios('get', '/api/integral/statistics/ranking', this.formData, 'v2')
+				.then(res => {
+					if (res.data.code == 1) {
+						this.list = res.data.data.list;
+						this.total = res.data.data.total;
+					} else {
+						this.$message.error(res.data.data.msg);
+					}
+				})
+				.finally(() => {
+					this.loading = false;
+				});
+		},
+		// 递归判断列表,把最后的children设为undefined
+		getTreeData(data) {
+			for (var i = 0; i < data.length; i++) {
+				if (data[i]._child.length < 1) {
+					// children若为空数组,则将children设为undefined
+					data[i]._child = undefined;
+				} else {
+					// children若不为空数组,则继续 递归调用 本方法
+					this.getTreeData(data[i]._child);
+				}
+			}
+			return data;
+		}
+	},
+	created() {
+		this.getDepartment();
+		this.employee_map = JSON.parse(localStorage.getItem('userList'));
+	},
+	mounted() {
+		this.tips_show = JSON.parse(localStorage.getItem('total_rank_tips')) ? false : true;
+		this.get_list();
+	}
+};
 </script>
+<style scoped lang="scss">
+.titled{
+	width: 110px;
+	text-align: left;
+	margin-bottom: 20px;
+	color: #606266;
+	font-size: 14px;	
+	// border-right: 1px solid #f1f1f1;
+	padding: 0 10px;
+}
+.titled .num{
+	font-size: 16px;
+	font-weight: 600;
+	margin-bottom: 10px;
+}
+.border {
+	-webkit-appearance: none;
+	background-color: #fff;
+	background-image: none;
+	border-radius: 4px;
+	border: 1px solid #dcdfe6;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+	color: #c0c4cf;
+	font-size: inherit;
+	height: auto;
+	outline: 0;
+	padding: 0 15px;
+	width: 250px;
+	position: relative;
+	cursor: pointer;
+}
+.border .font-flex-word {
+	color: #606266;
+}
+.el-icon-edit {
+	position: relative;
+	cursor: pointer;
+}
+.el-icon-edit::after {
+	content: '';
+	position: absolute;
+	left: -5px;
+	top: -5px;
+	bottom: -5px;
+	right: -5px;
+}
+.label {
+	width: 40px;
+	text-align: right;
+	padding: 0 10px;
+}
+.search_box {
+	::v-deep button:active {
+		background: #26a2ff;
+	}
+	::v-deep button:active .el-icon-search {
+		color: #fff;
+	}
+}
+.date-picker-width {
+	width: 100% !important;
+}
+.nopoint_box {
+	display: inline-block;
+	text-align: center;
+	width: 100%;
+	margin-bottom: 10px;
+}
+.noimg {
+	display: inline-block;
+	width: 110px;
+	height: 110px;
+	margin: 22px auto 16px;
+	background-size: 99%;
+}
+.noperson {
+	display: inline-block;
+	width: 110px;
+	height: 110px;
+	line-height: none;
+	margin: 22px auto 16px;
+	background-size: 99%;
+}
+.title {
+	display: block;
+	text-align: center;
+	font-size: 12px !important;
+	line-height: 30px;
+	color: #909399 !important;
+	padding: 0;
+}
+.nopoint_box a {
+	color: #26a2ff;
+}
+.chart_content {
+	.chart-legend__wrap {
+		text-align: right;
+		padding: 20px;
+		padding-right: 50px;
+		& .chart-legend__pink {
+			position: relative;
+			padding-left: 12px;
+			padding-right: 5px;
+			&:after {
+				content: '';
+				position: absolute;
+				margin-top: -2px;
+				top: 35%;
+				left: 0;
+				width: 8px;
+				height: 8px;
+				background: #f56c6c;
+				border-radius: 100%;
+			}
+		}
 
-<style>
+		& .chart-legend__green {
+			position: relative;
+			padding-left: 12px;
+			&:after {
+				content: '';
+				position: absolute;
+				margin-top: -2px;
+				top: 35%;
+				left: 0;
+				width: 8px;
+				height: 8px;
+				background: #53b87f;
+				border-radius: 100%;
+			}
+		}
+	}
+}
+.drawer_title {
+	font-size: 18px;
+	padding: 20px;
+}
+.manager_statistics_box {
+	background-color: #ffffff;
+	padding: 20px;
+	min-height: calc(100vh - 160px);
+	::v-deep .el-row .el-checkbox .el-checkbox__label {
+		line-height: 20px;
+	}
+}
+.diy_tip_bg {
+	background: #f5f6f9;
+	overflow: hidden;
+	.diy-tip {
+		margin-bottom: 15px;
+		border: 1px solid #67c23a;
+		padding: 20px 16px;
+		p {
+			color: #67c23a !important;
+			font-size: 14px;
+			margin: 0 !important;
+			padding: 4px 0;
+		}
+	}
+}
+.width-250{
+	width: 250px;
+}
+.inputDc {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 0;
+  z-index: 9;
+  cursor: pointer;
+}
 </style>

+ 0 - 367
src/views/welfare/flStatistics.vue

@@ -1,367 +0,0 @@
-<template>
-	<div>
-		<div class="diy_tip_bg" v-show="tips_show">
-			<el-alert class="diy-tip" @close="tips_close" type="success" description><p>排名包含初始分和工龄分</p></el-alert>
-		</div>
-		<div class="all padding-20">
-			<el-form :inline="true">
-				<el-form-item label="部门">
-					<el-cascader
-						size="medium"
-						class="date-picker-width"
-						v-model="dept_name"
-						:options="dept_tree"
-						:props="{ checkStrictly: true, value: 'id', label: 'name', children: '_child' }"
-						ref="dept"
-						clearable
-						filterable
-						placeholder="全公司"
-					></el-cascader>
-				</el-form-item>
-				<el-form-item label="人员">
-					<el-select v-model="select_employee_id" filterable placeholder="请输入或选择人员" clearable>
-						<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
-					</el-select>
-				</el-form-item>
-				<el-form-item>
-					<el-button type="primary" size="medium" @click="dialogVisible = true" style="margin-left: 10px;" plain>导出排名</el-button>
-				</el-form-item>
-			</el-form>
-
-			<el-table :data="list" style="width: 100%" v-loading="loading" @selection-change="deleteEvents">
-				<el-table-column type="selection" width="55"></el-table-column>
-				<el-table-column label="姓名" align="left">
-					<template slot-scope="scope">
-						<div class="flex-box">
-							<userImage :user_name="scope.row.employee_name" :img_url="scope.row.employee_img_url" width="50px" height="50px"></userImage>
-							<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.employee_name }}</span>
-						</div>
-					</template>
-				</el-table-column>
-				<el-table-column label="部门" width="80" align="center"></el-table-column>
-				<el-table-column label="累计B分" align="left" prop="point"></el-table-column>
-				<template slot="empty">
-					<div class="nopoint_box">
-						<div class="noimg noperson"></div>
-						<span class="title">没有对应的数据</span>
-					</div>
-				</template>
-			</el-table>
-
-			<center style="padding: 20px 0;">
-				<el-pagination
-					background
-					@size-change="handleSizeChange"
-					@current-change="handleCurrentChange"
-					:current-page="formData.page"
-					:page-sizes="[10, 20, 50, 100]"
-					layout="total, sizes, prev, pager, next"
-					:page-size="pageLimit"
-					:total="total"
-				></el-pagination>
-			</center>
-		</div>
-
-		<!-- 导出弹窗 -->
-		<el-dialog title="导出排名" :visible.sync="dialogVisible" width="730px" top="10%">
-			<span style="font-size:15px">系统将按以下已选条件导出对应的排名报表</span>
-			<el-form :inline="true">
-				<div class="picker_er">
-					<el-form-item label="时间">
-						<el-date-picker
-							v-model="Dc_Data.value1"
-							type="daterange"
-							size="medium"
-							value-format="yyyy-MM-dd"
-							format="yyyy-MM-dd"
-							range-separator="至"
-							start-placeholder="开始日期"
-							end-placeholder="结束日期"
-						></el-date-picker>
-					</el-form-item>
-
-					<el-form-item label="人员" style="margin-left:30px">
-						<el-select size="medium" v-model="Dc_Data.DC_position" style="width:150px" placeholder="请选择">
-							<el-option v-for="item in positions" :key="item.id" :label="item.name" :value="item.age"></el-option>
-						</el-select>
-					</el-form-item>
-				</div>
-				<el-form-item label="部门">
-					<el-cascader
-						class="date-picker-width cascader_bm"
-						v-model="Dc_Data.dept_name"
-						:options="dept_tree"
-						:props="{ checkStrictly: true, value: 'id', label: 'name', children: '_child' }"
-						ref="dept2"
-						size="medium"
-						clearable
-						filterable
-						placeholder="全公司"
-					></el-cascader>
-				</el-form-item>
-			</el-form>
-			<span slot="footer" class="dialog-footer">
-				<el-button @click="dialogVisible = false" size="medium">取 消</el-button>
-				<el-button type="primary" @click="exportExcel" size="medium">导 出</el-button>
-			</span>
-		</el-dialog>
-	</div>
-</template>
-<script>
-export default {
-	name:'flStatistics',
-	data() {
-		return {
-			select_employee_id:'',
-			employee_map:[],
-			dept_name: [],
-			dept_tree: [],
-			loading: false,
-			formData: {
-				dept_id: '0',
-				sort: 'DESC',
-				page: 1,
-				page_size: 10,
-				pt_id: 3,
-				type: 'all'
-			},
-			list: null,
-			pageLimit: 10,
-			total: null,
-			tips_show: false,
-			dialogVisible: false,
-			positions: [{ id: 0, age: 'all', name: '全部' }, { id: 1, age: 'manager', name: '管理者' }, { id: 2, age: 'employee', name: '员工' }],
-			Dc_Data: {
-				//导出数据
-				value1: '', //时间
-				DC_position: '全部', //人员
-				dept_name: [] //部门
-			}
-		};
-	},
-	watch: {
-		dept_name(val) {
-			if (val.length !== 0) {
-				this.formData.dept_id = val[val.length - 1];
-			} else {
-				this.formData.dept_id = '0';
-			}
-			this.formData.page = 1;
-			this.$nextTick(() => {
-				this.$refs.dept.dropDownVisible = false;
-				this.get_list();
-			});
-		}
-	},
-	methods: {
-		deleteEvents(selection) {
-			let listId = [];
-			selection.forEach(item => {
-				listId.push(item.id);
-			});
-			this.selectionID = listId;
-		},
-		exportExcel() {
-			//人员
-			this.Dc_Data.DC_position =
-				this.Dc_Data.DC_position == 'manager' ? 'manager' : this.Dc_Data.DC_position == 'employee' ? 'employee' : this.Dc_Data.DC_position == '全部' ? 'all' : 'all';
-			//部门
-			let dept_name;
-			for (let i in this.Dc_Data.dept_name) {
-				dept_name = this.Dc_Data.dept_name[i];
-			}
-			this.Dc_Data.dept_name = dept_name;
-			//规则
-			let rule_id = [];
-			for (let i in this.Dc_Data.rule_id) {
-				for (let a in this.Dc_Data.rule_id[i]) {
-					rule_id.push(this.Dc_Data.rule_id[i][a]);
-				}
-			}
-			this.Dc_Data.rule_id = rule_id;
-			let data = '';
-			if (this.Dc_Data.value1) {
-				data += '&start_date=' + this.Dc_Data.value1[0];
-				data += '&end_date=' + this.Dc_Data.value1[1];
-			}
-			data += '&position=' + this.Dc_Data.DC_position;
-			this.Dc_Data.dept_name > 0 ? (data += '&dept_id=' + this.Dc_Data.dept_name) : (data += '&dept_id=0');
-			if (this.Dc_Data.rule_id.length > 0) {
-				data += '&rule_id=' + this.Dc_Data.rule_id;
-			}
-
-			window.open(process.env.VUE_APP_BASE_API + 'api/download/ranking/v2?pt_id=3&type=all&employee_id=' + this.$getUserData().id + data, '_blank');
-			this.dialogVisible = false;
-		},
-		// 提示信息
-		tips_close() {
-			localStorage.setItem('total_rank_tips', 'true');
-			this.tips_show = false;
-		},
-		// 页面变更
-		handleCurrentChange(val) {
-			this.formData.page = val;
-			this.get_list();
-		},
-		handleSizeChange(val) {
-			this.pageLimit = val;
-			this.formData.page_size = this.pageLimit;
-			this.get_list();
-		},
-		//获取部门
-		getDepartment() {
-			this.$axios('get', '/api/department/tree').then(res => {
-				this.dept_tree = this.getTreeData(res.data.data.list);
-			});
-		},
-		get_list() {
-			this.loading = true;
-			this.$axios('get', '/api/integral/statistics/ranking', this.formData, 'v2')
-				.then(res => {
-					if (res.data.code == 1) {
-						this.list = res.data.data.list;
-						this.total = res.data.data.total;
-					} else {
-						this.$message.error(res.data.data.msg);
-					}
-				})
-				.finally(() => {
-					this.loading = false;
-				});
-		},
-		// 递归判断列表,把最后的children设为undefined
-		getTreeData(data) {
-			for (var i = 0; i < data.length; i++) {
-				if (data[i]._child.length < 1) {
-					// children若为空数组,则将children设为undefined
-					data[i]._child = undefined;
-				} else {
-					// children若不为空数组,则继续 递归调用 本方法
-					this.getTreeData(data[i]._child);
-				}
-			}
-			return data;
-		}
-	},
-	created() {
-		this.getDepartment();
-		this.employee_map=JSON.parse(localStorage.getItem('userList'))
-	},
-	mounted() {
-		this.tips_show = JSON.parse(localStorage.getItem('total_rank_tips')) ? false : true;
-		this.get_list();
-	}
-};
-</script>
-<style scoped lang="scss">
-.search_box {
-	::v-deep button:active {
-		background: #26a2ff;
-	}
-	::v-deep button:active .el-icon-search {
-		color: #fff;
-	}
-}
-.date-picker-width {
-	width: 100% !important;
-}
-.nopoint_box {
-	display: inline-block;
-	text-align: center;
-	width: 100%;
-	margin-bottom: 10px;
-}
-.noimg {
-	display: inline-block;
-	width: 110px;
-	height: 110px;
-	margin: 22px auto 16px;
-	background-size: 99%;
-}
-.noperson {
-	display: inline-block;
-	width: 110px;
-	height: 110px;
-	line-height: none;
-	margin: 22px auto 16px;
-	// background: url("@/assets/image/rules_mould.png") no-repeat center;
-	background-size: 99%;
-}
-.title {
-	display: block;
-	text-align: center;
-	font-size: 12px !important;
-	line-height: 30px;
-	color: #909399 !important;
-	padding: 0;
-}
-.nopoint_box a {
-	color: #26a2ff;
-}
-.chart_content {
-	.chart-legend__wrap {
-		text-align: right;
-		padding: 20px;
-		padding-right: 50px;
-		& .chart-legend__pink {
-			position: relative;
-			padding-left: 12px;
-			padding-right: 5px;
-			&:after {
-				content: '';
-				position: absolute;
-				margin-top: -2px;
-				top: 35%;
-				left: 0;
-				width: 8px;
-				height: 8px;
-				background: #f56c6c;
-				border-radius: 100%;
-			}
-		}
-
-		& .chart-legend__green {
-			position: relative;
-			padding-left: 12px;
-			&:after {
-				content: '';
-				position: absolute;
-				margin-top: -2px;
-				top: 35%;
-				left: 0;
-				width: 8px;
-				height: 8px;
-				background: #53b87f;
-				border-radius: 100%;
-			}
-		}
-	}
-}
-.drawer_title {
-	font-size: 18px;
-	padding: 20px;
-}
-.manager_statistics_box {
-	background-color: #ffffff;
-	padding: 20px;
-	min-height: calc(100vh - 160px);
-	::v-deep .el-row .el-checkbox .el-checkbox__label {
-		line-height: 20px;
-	}
-}
-.diy_tip_bg {
-	background: #f5f6f9;
-	overflow: hidden;
-	.diy-tip {
-		margin-bottom: 15px;
-		border: 1px solid #67c23a;
-		padding: 20px 16px;
-		p {
-			color: #67c23a !important;
-			font-size: 14px;
-			margin: 0 !important;
-			padding: 4px 0;
-		}
-	}
-}
-</style>

+ 386 - 0
src/views/welfare/operatingRecord.vue

@@ -0,0 +1,386 @@
+<template>
+	<div>
+		<div class="all" v-loading="attendload">
+			<div>
+				<el-form :inline="true">
+					<el-form-item label="人员">
+						<el-select v-model="select_employee_id" size="medium" filterable placeholder="请输入或选择人员" clearable>
+							<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item label="排名类型">
+						<el-select v-model="formData.event_type" size="medium" @change="selectgroupId" style="width:110px" placeholder="请选择">
+							<el-option v-for="(item, index) in event_type" :key="index" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item label="时间">
+						<el-date-picker
+							size="medium"
+							style="width:290px"
+							class="first-element-btn"
+							:clearable="false"
+							v-model="time_range"
+							type="daterange"
+							value-format="yyyy-MM-dd"
+							range-separator="至"
+							start-placeholder="开始日期"
+							end-placeholder="结束日期"
+							:picker-options="instantPickerOptions"
+							@change="onFilterChanged"
+						></el-date-picker>
+					</el-form-item>
+					<el-form-item>
+						<el-button type="primary" plain @click="exportRanking">导出排名</el-button>
+					</el-form-item>
+				</el-form>
+			</div>
+			<el-table :data="all_integral_list" style="width: 100%" v-loading="loading">
+				<el-table-column label="名次" width="100" align="center">
+					<template slot-scope="scope">
+						<img v-if="scope.row.rank === 1" src="@/assets/image/statistics_NO1.png" alt />
+						<img v-if="scope.row.rank === 2" src="@/assets/image/statistics_NO2.png" alt />
+						<img v-if="scope.row.rank === 3" src="@/assets/image/statistics_NO3.png" alt />
+						<span v-if="scope.row.rank > 3">{{ scope.row.rank }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column label="姓名" align="left">
+					<template slot-scope="scope">
+						<div style="display:flex;">
+							<userImage :user_name="scope.row.name" :img_url="scope.row.img_url" width="50px" height="50px"></userImage>
+							<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.name }}</span>
+						</div>
+					</template>
+				</el-table-column>
+				<el-table-column prop="point" label="B分" align="left">
+					<template slot-scope="scope">
+						<b style="font-size:15px;color:#909399">{{ scope.row.point }}</b>
+					</template>
+				</el-table-column>
+				<template slot="empty">
+					<noData :content="checkingInGroup.length == 0 ? '请先开启钉钉考勤' : '暂无数据'"></noData>
+				</template>
+			</el-table>
+			<center style="padding: 20px 0;">
+				<el-pagination
+					background
+					@size-change="handleSizeChange1"
+					@current-change="handleCurrentChange"
+					:current-page="formData.page"
+					:page-sizes="[10, 20, 50, 100]"
+					layout="total, sizes, prev, pager, next"
+					:page-size="pageLimit1"
+					:total="total"
+				></el-pagination>
+			</center>
+		</div>
+		<!-- 导出弹窗 -->
+		<el-dialog title="导出排名" :visible.sync="dialogVisible" width="730px">
+			<div style="font-size:15px;margin:20px 0 20px 0;">系统将按以下已选条件导出对应的排名报表</div>
+			<div v-loading="exportLoad">
+				<el-form :inline="true">
+					<el-form-item label="考勤组">
+						<el-select v-model="exportData.group_id" @change="selectgroupId" filterable :clearable="false" placeholder="请选择考勤组">
+							<el-option v-for="item in checkingInGroup" :key="item.id" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item>
+
+					<el-form-item label="排名类型">
+						<el-select v-model="exportData.event_type" style="width:150px" placeholder="请选择">
+							<el-option v-for="(item, index) in event_type" :key="index" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item>
+
+					<el-form-item label="时间">
+						<el-date-picker
+							class="first-element-btn"
+							:clearable="false"
+							v-model="exportTime_range"
+							type="daterange"
+							value-format="yyyy-MM-dd"
+							range-separator="至"
+							start-placeholder="开始日期"
+							end-placeholder="结束日期"
+							:picker-options="instantPickerOptions"
+						></el-date-picker>
+					</el-form-item>
+				</el-form>
+				<span class="dialog-footer" style="display:flex;justify-content: flex-end;">
+					<el-button @click="dialogVisible = false">取 消</el-button>
+					<el-button type="primary" @click="exportExcel">导 出</el-button>
+				</span>
+			</div>
+		</el-dialog>
+	</div>
+</template>
+<script>
+export default {
+	data() {
+		return {
+			// 设置只能选择当前日期及之后的日期
+			pickerOptions: {
+				disabledDate(time) {
+					return time.getTime() > Date.now() - 8.64e7; //如果没有后面的-8.64e7就是不可以选择今天的
+				}
+			},
+			exportLoad: false,
+			dialogVisible: false,
+			checkingInGroup: [],
+			employee_map:[],
+			select_employee_id:'',
+			event_type: [
+				{ id: 0, name: '总分' },
+				{ id: 1, name: '迟到' },
+				{ id: 2, name: '早退' },
+				{ id: 6, name: '准时打卡' },
+				{ id: 20, name: '上班缺卡' },
+				{ id: 21, name: '下班缺卡' },
+				{ id: 16, name: '加班 ' },
+				{ id: 10, name: '缺勤' }
+			],
+			attendload: false,
+			loading: false,
+			all_integral_list: null,
+			Month_range: this.$moment().format('YYYY-MM'),
+			time_range: [
+				this.$moment()
+					.startOf('month')
+					.format('YYYY-MM-DD'),
+				this.$moment()
+					.endOf('month')
+					.format('YYYY-MM-DD')
+			],
+			formData: {
+				group_id: '',
+				// date_type: 3,
+				page: 1,
+				page_size: 10,
+				event_type: 0
+			},
+			exportMonth_range: this.$moment().format('YYYY-MM'),
+			exportTime_range: [
+				this.$moment()
+					.startOf('month')
+					.format('YYYY-MM-DD'),
+				this.$moment()
+					.endOf('month')
+					.format('YYYY-MM-DD')
+			],
+			exportData: {
+				group_id: '',
+				event_type: 0
+			},
+			total: 0,
+			dept_tree: [],
+			dept_name: [],
+			pageLimit1: 10,
+			instantPickerOptions: {
+				shortcuts: [
+					{
+						text: '本周',
+						onClick(picker) {
+							const now = new Date();
+							const start = new Date();
+							start.setTime(now.getTime() - (now.getDay() - 1) * 24 * 60 * 60 * 1000);
+							now.setTime(start.getTime() + 6 * 24 * 60 * 60 * 1000 - 1000);
+							picker.$emit('pick', [start, now]);
+						}
+					},
+					{
+						text: '上周',
+						onClick(picker) {
+							const end = new Date();
+							const start = new Date();
+							start.setTime(start.getTime() - (start.getDay() + 6) * 3600 * 1000 * 24);
+							end.setTime(start.getTime() + 6 * 24 * 60 * 60 * 1000 - 1000);
+							picker.$emit('pick', [start, end]);
+						}
+					},
+					{
+						text: '本月',
+						onClick(picker) {
+							const now = new Date();
+							const startDate = new Date(now.getFullYear(), now.getMonth(), 1);
+							const endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0);
+							picker.$emit('pick', [startDate, endDate]);
+						}
+					},
+					{
+						text: '上月',
+						onClick(picker) {
+							const now = new Date();
+							const startDate = new Date(now.getFullYear() - (now.getMonth() > 0 ? 0 : 1), (now.getMonth() + 11) % 12, 1);
+							const endDate = new Date(now.getFullYear(), now.getMonth(), 0);
+							picker.$emit('pick', [startDate, endDate]);
+						}
+					}
+				]
+			},
+			// 更新考勤数据
+			isUpdate: false,
+			update: {
+				type: 'daily',
+				target_date: '',
+				target_month: ''
+			}
+		};
+	},
+
+	watch: {
+		isUpdate(val) {
+			if (!val) {
+				this.update = {
+					type: 'daily',
+					target_date: '',
+					target_month: ''
+				};
+			}
+		}
+	},
+	created() {
+		this.employee_map = JSON.parse(localStorage.getItem('userList'));
+	},
+	mounted() {
+		this.checkingIn_group(); //考勤组
+	},
+	methods: {
+		saveUpdate() {
+			let update = this.update;
+			let data = { type: update.type };
+			if (update.type == 'daily') {
+				if (!update.target_date) {
+					this.$message.error('请选择日期');
+					return false;
+				}
+				data.target_date = update.target_date;
+			} else {
+				if (!update.target_month) {
+					this.$message.error('请选择月份');
+					return false;
+				}
+				data.target_month = update.target_month;
+			}
+			this.$axios('post', '/api/ding/ad_sync', data).then(res => {
+				if (res.data.code == 1) {
+					this.$message.success('已更新');
+					this.isUpdate = false;
+				}
+			});
+		},
+		exportRanking() {
+			if (this.checkingInGroup.length > 0) {
+				this.exportData.group_id = this.checkingInGroup[0].id;
+			}
+			this.dialogVisible = true;
+		},
+		exportExcel() {
+			window.open(
+				process.env.VUE_APP_BASE_API +
+					'api/download/groups_ranking/export?start_date=' +
+					this.exportTime_range[0] +
+					'&end_date=' +
+					this.exportTime_range[1] +
+					'&page=' +
+					1 +
+					'&page_size=' +
+					2000 +
+					'&group_id=' +
+					this.exportData.group_id +
+					'&event_type=' +
+					this.exportData.event_type +
+					'&employee_id=' +
+					this.$getUserData().id,
+				'_blank'
+			);
+		},
+		selectgroupId() {
+			this.get_all_integral();
+		},
+		onFilterChanged() {
+			this.get_all_integral();
+		},
+		//分页
+		handleSizeChange1(val) {
+			this.pageLimit1 = val;
+			this.formData.page_size = this.pageLimit1;
+			this.get_all_integral();
+		},
+		handleCurrentChange(val) {
+			this.formData.page = val;
+			this.get_all_integral();
+		},
+		//请求数据
+		checkingIn_group() {
+			this.attendload = true;
+			let self = this;
+			let params = {
+				page: 1,
+				page_size: 2000
+			};
+			this.$axios('get', '/api/ad/groups', params)
+				.then(res => {
+					if (res.data.code == 1) {
+						let list = res.data.data.list;
+						let datas = [];
+						for (let key in list) {
+							let obj = {};
+							obj.id = key;
+							obj.name = list[key];
+							datas.push(obj);
+						}
+						this.checkingInGroup = datas;
+						this.formData.group_id = datas[0].id;
+					}
+				})
+				.finally(() => {
+					this.get_all_integral();
+					this.attendload = false;
+				});
+		},
+		//请求数据
+		get_all_integral() {
+			let self = this;
+			self.loading = true;
+			let data = {
+				group_id: this.formData.group_id,
+				page: this.formData.page,
+				page_size: this.formData.page_size,
+				event_type: this.formData.event_type
+			};
+			data.start_date = this.time_range[0];
+			data.end_date = this.time_range[1];
+			this.$axios('post', '/api/ad/rank', data)
+				.then(res => {
+					if (res.data.code == 1) {
+						self.all_integral_list = res.data.data.list;
+						this.total = res.data.data.total;
+					} else {
+						self.$message.error(res.data.data.msg);
+					}
+				})
+				.finally(() => {
+					self.loading = false;
+				});
+		}
+	}
+};
+</script>
+
+<style scoped>
+.el-date-editor.el-input {
+	width: auto;
+}
+.date-picker-width {
+	width: 145px !important;
+}
+.search ::v-deep .el-input-group__append:active {
+	background: #26a2ff;
+}
+.search ::v-deep .el-input-group__append:active .el-icon-search {
+	color: #fff;
+}
+</style>
+<style lang="scss" scoped>
+::v-deep .el-dialog__body {
+	padding: 0px 20px 30px;
+}
+</style>

+ 1143 - 2
src/views/welfare/prize.vue

@@ -1,8 +1,1149 @@
 <template>
-</template>
+	<div class="all-box">
+		<div class="all">
+			<div class="flex-box">
+				<div class="flex-box" v-loading="item_loading">
+					<div class="terr-left">
+						<div style="text-align: center; padding: 10px 0;">
+							<el-button type="primary" @click="addGroup" :disabled="table_loading" v-if="employeeOrdept">添加分类</el-button>
+						</div>
+						<el-menu v-if="groups_list.length > 0" default-active="0" class="el-menu-vertical-demo elMenuCustomRule_Z">
+							<el-menu-item v-for="(item, index) in groups_list" :key="index" :index="index.toString()" @click="getGroupsInfo(item)">
+								<i class="el-icon-document-copy"></i>
+								<span slot="title">{{ item.name }}</span>
+							</el-menu-item>
+						</el-menu>
+						<div v-else style="text-align: center;margin-top: 10%;" class="fontColorF">
+							<img src="@/assets/image/nodata.png" style="width: 180px;height: 120px;margin: 30px auto;" />
+							<div>还没有自定义分类</div>
+						</div>
+					</div>
+				</div>
+				<div class="listData flex-1 " v-loading="table_loading">
+					<el-row style="margin-bottom: 10px;" v-if="groups_list.length != 0">
+						<el-col :span="24" class="groups_name">
+							<div class="flex-box flex-v-ce margin-bottom">
+								<div class="groupsName">
+									{{ groups_info.name }}
+									<span class="blue" v-if="total > 0">({{ total }}人)</span>
+								</div>
+								<el-button @click="editGroup" v-if="employeeOrdept" size="medium" style="margin-left:15px;">编辑</el-button>
+							</div>
+						</el-col>
+					</el-row>
+					<el-form :model="params" :inline="true" ref="params" style="margin-bottom: 20px;">
+						<div class="flex-box-ce">
+							<div class="flex-1">
+								<el-button type="primary" @click="isPrizeShow=true" size="medium">新增奖品</el-button>
+								<el-button type="success" plain @click="exportExcel" size="medium">批量上架</el-button>
+								<el-button type="danger" plain @click="exportExcel" size="medium">批量下架</el-button>
+								<el-button type="primary" @click="exportExcel" size="medium">导 出</el-button>
+							</div>
+							<el-input placeholder="奖品搜索" size="medium" style="width: 200px;margin: 0 10px;" v-model="params.group_id" clearable></el-input>
+						</div>
+					</el-form>
+
+					<el-table :data="table_list" style="width: 100%">
+						<el-table-column label="名次" width="80" align="center">
+							<template slot-scope="scope">
+								<img v-if="scope.row.rank === 1" src="@/assets/image/statistics_NO1.png" alt="" />
+								<img v-if="scope.row.rank === 2" src="@/assets/image/statistics_NO2.png" alt="" />
+								<img v-if="scope.row.rank === 3" src="@/assets/image/statistics_NO3.png" alt="" />
+								<span v-if="scope.row.rank > 3">{{ scope.row.rank }}</span>
+							</template>
+						</el-table-column>
+						<el-table-column label="姓名" align="left">
+							<template slot-scope="scope">
+								<div class="flex-box">
+									<userImage :user_name="scope.row.name" :img_url="scope.row.img_url" width="50px" height="50px"></userImage>
+									<span style="line-height: 50px; padding-left: 10px;">{{ scope.row.name }}</span>
+								</div>
+							</template>
+						</el-table-column>
+						<el-table-column label="B分" align="left" prop="point"></el-table-column>
+						<template slot="empty">
+							<div class="nopoint_box">
+								<div class="noimg noperson"></div>
+								<span class="title">没有对应的数据</span>
+							</div>
+						</template>
+					</el-table>
+
+					<center style="padding: 20px 0;">
+						<el-pagination
+							background
+							@size-change="handleSizeChange"
+							@current-change="handleCurrentChange"
+							:page-sizes="[10, 20, 50, 100]"
+							layout="total, sizes, prev, pager, next"
+							:page-size="params.page_size"
+							:current-page="params.page"
+							:total="total"
+						></el-pagination>
+					</center>
+				</div>
+			</div>
+		</div>
 
+		<!-- 新增分类 -->
+		<el-dialog :title="popupType ? '新增分类' : '编辑分类'" width="460px" :visible.sync="groupShow" :close-on-click-modal="false">
+			<el-form ref="newGroupForm" v-loading="loading" :model="newGroupForm" :rules="rules" label-width="85px" @submit.native.prevent>
+				<el-form-item label="分类名称" prop="group_name">
+					<el-input v-model="newGroupForm.group_name" placeholder="请输入分类名称" auto-complete="off"></el-input>
+				</el-form-item>
+			</el-form>
+			<div slot="footer" class="dialog-footer flex-v-ce flex-box">
+				<el-button type="danger" v-if="!popupType" :loading="delLoad" @click="delItem">删除</el-button>
+				<div class="flex-1"></div>
+				<el-button @click="resetForm('newGroupForm')">取 消</el-button>
+				<el-button type="primary" :loading="saveLoad" @click="subGroupForm('newGroupForm')">确 定</el-button>
+			</div>
+		</el-dialog>
+		
+		<!-- 新增分类 -->
+		<el-dialog :title="popupType ? '奖品添加' : '奖品编辑'" width="550px" top="5vh" :visible.sync="isPrizeShow" :close-on-click-modal="false">
+			<el-form ref="newGroupForm" v-loading="loading" :model="newGroupForm" :rules="rules" label-width="110px" @submit.native.prevent>
+				<el-form-item label="所属分类" prop="group_name">
+					<el-input v-model="newGroupForm.group_name" placeholder="请输入分类名称" auto-complete="off"></el-input>
+				</el-form-item>
+				<el-form-item label="名称" prop="group_name">
+					<el-input v-model="newGroupForm.group_name" placeholder="请输入名称" auto-complete="off" maxlength="30" show-word-limit></el-input>
+				</el-form-item>
+				<el-form-item label="展示图片">
+					<div class="flex-box">
+						<upload
+							:headers="Xtoken"
+							:action="'https://integralsys.oss-cn-shenzhen.aliyuncs.com'"
+							:on-success="handleFilesSuccess"
+							:before-upload="beforeUpload"
+						>
+						  <img v-if="imageUrl" :src="imageUrl" class="avatar">
+						  <i v-else class="el-icon-plus avatar-uploader-icon" style="border: 1px solid #f1f1f1;border-radius: 5px;"></i>
+						</upload>
+						<el-button style="margin-left: 20px;height: 30px;" size="small" type="danger" plain v-if="imageUrl">删除</el-button>
+					</div>
+				</el-form-item>
+				<el-form-item label="价格(功勋点)" prop="group_name">
+					<el-input v-model="newGroupForm.group_name" placeholder="请输入价格" auto-complete="off"></el-input>
+				</el-form-item>
+				<el-form-item label="库存" prop="group_name">
+					<el-input v-model="newGroupForm.group_name" placeholder="不填默认为无限" auto-complete="off"></el-input>
+				</el-form-item>
+				<el-form-item label="奖品描述" prop="group_name">
+					<el-input v-model="newGroupForm.group_name" placeholder="请输入奖品描述" type="textarea" rows="4" maxlength="200" show-word-limit></el-input>
+				</el-form-item>
+				<el-form-item label="是否上架" prop="group_name">
+					    <el-radio-group v-model="newGroupForm.group_name">
+					      <el-radio label="线上品牌商赞助"></el-radio>
+					      <el-radio label="线下场地免费"></el-radio>
+					    </el-radio-group>
+				</el-form-item>
+			</el-form>
+			<div slot="footer" class="dialog-footer flex-v-ce flex-box">
+				<el-button type="danger" v-if="!popupType" :loading="delLoad" @click="delItem">删除</el-button>
+				<div class="flex-1"></div>
+				<el-button @click="isPrizeShow=false">取 消</el-button>
+				<el-button type="primary" :loading="saveLoad" @click="subGroupForm('newGroupForm')">确 定</el-button>
+			</div>
+		</el-dialog>
+		
+	</div>
+</template>
 <script>
+import EmployeeSelector from '@/components/EmployeeSelector.vue';
+import moment from 'moment';
+import Season from '@/components/season';
+import upload from '@/components/upload';
+// let valuesLengths = []
+var selecteds = [];
+let selectionID = [];
+//节流
+const delay = (function() {
+	let timer = 0;
+	return function(callback, ms) {
+		clearTimeout(timer);
+		timer = setTimeout(callback.ms);
+	};
+})();
+export default {
+	data() {
+		return {
+			// 
+			isPrizeShow:false, 
+			Xtoken: { 'X-Token': this.$getToken() },
+			fileList:[],
+			imageUrl: '',
+			
+			
+			isEmployeeShow: false,
+			ruleHint: '',
+			employeeOrdept: !this.$authoritys('employee') && !this.$authoritys('dept_manager'),
+			lastUpdateTime: '',
+			tableLoadingRule: false, //规则细则加载
+			keyword: '',
+			values_no: [],
+			backups: [], //备份
+			valuesLength: [],
+			multipleSelection: [],
+			valuesOrLength: [],
+			itemList: {},
+			ruleTrees: [], //所有规则列表
+			tableData_rule: [],
+			defaultExpand: false,
+			defaultProps: {
+				children: 'child',
+				label: 'name'
+			},
+			treedata: [],
+
+			ruleDialogTableVisible: false, //编辑-规则-弹出框
+			loading: false,
+
+			popupType: false,
+			item_loading: false,
+			table_loading: false,
+			groups_info_loading: false,
+			groups_info: {
+				name: '',
+				employees: []
+			},
+			groups_list: [], //左边分类
+			table_list: [],
+			total: null,
+			time: {
+				year: moment().format('YYYY'), //年
+				quarter: moment().format('YYYYQ'), //季度
+				month: moment().format('YYYY-MM') //月
+			},
+			params: {
+				page: 1,
+				page_size: 10,
+				group_id: '',
+				sort: 'asc',
+				rule: '',
+				pt_id: 3
+			},
+			rule_trees: [],
+			clickItem: null,
+			groupShow: false,
+			rules: {
+				group_name: [{ required: true, message: '请输入分类名称', trigger: 'blur' }, { min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }]
+			},
+			newGroupForm: {
+				group_name: '',
+				employees: [],
+				items: [],
+				date_interval: '1'
+			},
+			newGroupFormRules: '',
+			saveLoad: false,
+			delLoad: false,
+			show_employee_selector: false,
+			employee_not_select: [],
+			employees_selected: { employee: [], dept: [] },
+			employees: '',
+			props: { value: 'id', label: 'name', children: 'child', multiple: true, checkStrictly: true }, //
+			sort: false
+		};
+	},
+	watch: {
+		'time.month'(val, old_val) {
+			this.time.month = val;
+			this.params.page = 1;
+			this.open_right(this.clickItem);
+		},
+		'time.year'(val, old_val) {
+			this.time.year = val;
+			this.params.page = 1;
+			this.open_right(this.clickItem);
+		},
+		sort(val) {
+			this.params.page = 1;
+			val ? (this.params.sort = 'desc') : (this.params.sort = 'asc');
+			this.open_right(this.clickItem);
+		},
+		keyword() {
+			//函数节流
+			if (this.timer) {
+				clearTimeout(this.timer);
+			}
+			//清空 全部
+			if (!this.keyword) {
+				this.tableData_rule = this.tableData_rule2;
+				this.ifPitchOnChild(this.tableData_rule, selecteds);
+				return;
+			}
+			this.timer = setTimeout(() => {
+				const result = [];
+				this.tableData_rule2.forEach(val => {
+					if (val.remark.indexOf(this.keyword) > -1) {
+						result.push(val);
+					}
+				});
+				this.tableData_rule = result;
+				this.ifPitchOnChild(this.tableData_rule, selecteds);
+			}, 100);
+		}
+	},
+	components: { EmployeeSelector, Season,upload },
+	methods: {
+		beforeUpload(file) {
+			const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
+			const isLt2M = file.size / 1024 / 1024 < 1;
+			if (!isJPG) {
+				this.$message.error('上传头像图片只能是 JPEG,PNG,JPG 格式!');
+			}
+			if (!isLt2M) {
+				this.$message.error('上传头像图片大小不能超过 2MB!');
+			}
+			return isJPG && isLt2M;
+		},
+		handleFilesSuccess(response, file, fileList) {
+			this.fileList = fileList;
+			this.imageUrl = response.url;
+			console.log(fileList)
+			// this.dialogData.items[this.itemIndex].files = [];
+			// fileList.forEach((element, index) => {
+			// 	this.dialogData.items[this.itemIndex].files.push(element.url);
+			// });
+		},
+		
+		
+		exportExcel() {
+			let months;
+			if (this.newGroupForm.date_interval == '1') {
+				months = this.time.month.replace('-', '');
+			}
+			let data = {
+				group_id: this.clickItem.id,
+				date: '',
+				sort: this.sort ? 'desc' : 'asc',
+				employee_id: this.$getUserData().id
+			};
+			data.date =
+				this.newGroupForm.date_interval == '1'
+					? months
+					: this.newGroupForm.date_interval == '2'
+					? this.time.quarter
+					: this.newGroupForm.date_interval == '3'
+					? this.time.year
+					: '';
+			let str = '&group_id=' + data.group_id + '&date=' + data.date + '&sort=' + data.sort;
+			window.open(process.env.VUE_APP_BASE_API + 'api/download/groups_export?employee_id=' + this.$getUserData().id + str, '_blank');
+		},
+		submitEmployee() {
+			this.$refs.Employee.confirm(); //调用组件的confirm();
+		},
+		//点击某行
+		clicktable(row, column, cell, event) {
+			let selectedsif = false;
+			for (let i in selecteds) {
+				if (row.id == selecteds[i]) {
+					selectedsif = true;
+					selecteds.splice(i, 1);
+					this.toggleSelection([row], false);
+				}
+			}
+			if (selectedsif == false) {
+				selecteds.push(row.id);
+				this.ifPitchOnChild(this.tableData_rule, selecteds);
+			}
+		},
+		//全选
+		selectAll(selection) {
+			for (let i in selection) {
+				selectionID.push(selection[i].id);
+			}
+			let tableData_rules = []; //当前分页id
+			for (let i in this.tableData_rule) {
+				tableData_rules.push(this.tableData_rule[i].id);
+			}
+			selectionID = [...new Set(selectionID)];
+			if (selection.length == 0) {
+				//全不选
+				//判断差值
+				var diff = [];
+				var tmp = tableData_rules;
+				selectionID.forEach(function(val1, i) {
+					if (tableData_rules.indexOf(val1) < 0) {
+						diff.push(val1);
+					} else {
+						tmp.splice(tmp.indexOf(val1), 1);
+					}
+				});
+				selectionID = diff.concat(tmp);
+			} else {
+				//全选
+			}
+			selecteds = [...new Set(selectionID)];
+			this.valuesOrLength = selecteds;
+		},
+		// 递归判断列表,把最后的children设为undefined
+		getTreeData(data) {
+			for (var i = 0; i < data.length; i++) {
+				if (data[i].child.length < 1) {
+					// children若为空数组,则将children设为undefined
+					data[i].child = undefined;
+				} else {
+					// children若不为空数组,则继续 递归调用 本方法
+					this.getTreeData(data[i].child);
+				}
+			}
+			return data;
+		},
+		//获取规则
+		get_rule_trees() {
+			this.$axios('get', '/api/integral/rule/trees', { cycle_type: 1 }).then(res => {
+				this.treedata = this.getTreeData(res.data.data.rule_tree || []);
+				this.itemList = res.data.data.item_list; //规则
+			});
+		},
+		//点击规则弹出窗口
+		ruleDialogTableVisibles() {
+			this.tableLoadingRule = true;
+			selecteds = this.valuesOrLength;
+			//点击弹出窗口并展示所有数据
+			let tableData_r = [];
+			for (let i in this.itemList) {
+				for (let a in this.itemList[i]) {
+					tableData_r.push(this.itemList[i][a]);
+				}
+			}
+			this.tableData_rule2 = tableData_r; //赋予筛选数据
+			this.tableData_rule = tableData_r;
+			this.ruleDialogTableVisible = true;
+			this.ifPitchOnChild(this.tableData_rule, selecteds);
+		},
+		recursion(data, arr) {
+			for (let i in data.child) {
+				if (data.child.length != 0) {
+					arr.push(data.id);
+				} else {
+					arr.push(data.id);
+				}
+			}
+			return [...new Set(arr)];
+		},
+
+		//此方法:拿到当前点击规则分类的所有子节点ID,(为了包含子分类 规则)
+		menuIdInit(menus) {
+			var _this = this;
+			var _menu = menus;
+			var menuId = [];
+			var len = _menu.length;
+			for (var i = 0; i < len; i++) {
+				var item = _menu[i];
+				if (item.child && item.child.length != 0) {
+					var child = item.child;
+					for (var j = 0; j < child.length; j++) {
+						_menu[len + j] = child[j];
+					}
+					len = _menu.length;
+				}
+				menuId.push(item.id);
+			}
+			return menuId;
+		},
+		//点击规则分类
+		handleNodeClick(data) {
+			let dataArr = this.menuIdInit([data]); //调用方法
+			this.tableLoadingRule = true;
+			this.keyword = ''; //切换规则重置搜索框
+			let tableData_r = [];
+			for (let i in this.itemList) {
+				for (let a in this.itemList[i]) {
+					for (let x in dataArr) {
+						if (dataArr[x] == this.itemList[i][a].rule_id) {
+							tableData_r.push(this.itemList[i][a]);
+						}
+					}
+				}
+			}
+			this.tableData_rule2 = tableData_r; //赋予筛选数据
+			this.tableData_rule = tableData_r;
+			this.ifPitchOnChild(this.tableData_rule, selecteds);
+		},
+		ifPitchOnChild(item, indexID) {
+			let pitchOnChild = [];
+			for (let i in item) {
+				for (let a in indexID) {
+					//判断外层的值相不相等
+					if (indexID[a] == item[i].id) {
+						pitchOnChild.push(item[i]);
+					}
+				}
+			}
+			this.toggleSelection(pitchOnChild, true);
+		},
+		//默认选中
+		toggleSelection(rows, selected) {
+			if (rows) {
+				this.$nextTick(() => {
+					rows.forEach(row => {
+						this.$refs.multipleTable.toggleRowSelection(row, selected);
+					});
+				});
+			} else {
+				this.$refs.multipleTable.clearSelection();
+			}
+			setTimeout(() => {
+				//给遮到层,让默认选中的有缓冲时间
+				this.tableLoadingRule = false;
+			}, 300);
+		},
+		onTableSelect(rows, row) {
+			let selected = rows.length && rows.indexOf(row) !== -1;
+			if (selected) {
+				selecteds.push(row.id);
+			} else {
+				for (let i in selecteds) {
+					if (row.id == selecteds[i]) {
+						selecteds.splice(i, 1);
+					}
+				}
+			}
+		},
+		//规则弹窗选中时
+		handleSelectionChange(val) {},
+		//关闭回调
+		closeNone() {
+			selecteds = [];
+		},
+		//规则弹窗确定
+		ruleDialogTableVisibleQD() {
+			let valuesLengths = [];
+			for (let i in selecteds) {
+				valuesLengths.push(selecteds[i]);
+			}
+			// valuesLengths = selecteds
+			this.valuesOrLength = valuesLengths;
+			this.newGroupForm.items = this.valuesOrLength;
+			if (this.valuesOrLength.length >= 1) {
+				this.newGroupFormRules = this.valuesOrLength.length + '条规则';
+				this.ruleHint = '统计已选规则的积分(只选分类不指定规则的积分除外)';
+			} else {
+				this.newGroupFormRules = '';
+				this.ruleHint = '统计所有积分(基础分和工龄分除外)';
+			}
+			this.ruleDialogTableVisible = false;
+		},
+		//关闭
+		handleClose(done) {
+			done();
+		},
+		// 选择时间-季度
+		export_quarter_confirm(val) {
+			this.time.quarter = val;
+			this.params.page = 1;
+			this.open_right(this.clickItem);
+		},
+		// 树型菜单点击筛选
+		getRuletableData_rule(data) {
+			let tableData_ruleP = [];
+			for (let i in data) {
+			}
+			return data;
+		},
+		getRuleTreeDatas(data) {
+			let dates = [];
+			for (let i in data) {
+				if (data[i].child == undefined) {
+					dates.push(data[i]);
+				} else {
+					this.getRuleTreeData(data[i].child);
+				}
+			}
+			return dates;
+		},
+
+		//点击编辑
+		editGroup() {
+			this.groupShow = true;
+			this.popupType = false;
+			this.getGroupsInfo(this.clickItem, true);
+		},
+		// 获取分类信息
+		getGroupsInfo(item, ifs) {
+			let self = this;
+			if (!item) {
+				return false;
+			}
+			if (!ifs) {
+				self.table_loading = true;
+				this.params.page = 1;
+			}
+			this.loading = true;
+			self.$axios('get', '/api/integral/statistics/groups/info', { group_id: item.id })
+				.then(res => {
+					if (res.data.code == 1) {
+						// 规则ID
+						let itemsBjRule_ID = [];
+						for (let i in res.data.data.items) {
+							itemsBjRule_ID.push(res.data.data.items[i].id);
+						}
+						this.valuesOrLength = itemsBjRule_ID;
+						if (this.valuesOrLength.length >= 1) {
+							this.newGroupFormRules = this.valuesOrLength.length + '条规则';
+							this.ruleHint = '统计已选规则的积分(只选分类不指定规则的积分除外)';
+						} else {
+							this.newGroupFormRules = '';
+							this.ruleHint = '统计所有积分(基础分和工龄分除外)';
+						}
+						this.newGroupForm.date_interval = res.data.data.date_interval;
+						self.groups_info = res.data.data;
+						self.newGroupForm.employees = [];
+						self.employees = '';
+						self.employees_selected.employee = res.data.data.employees;
+						res.data.data.employees.forEach(element => {
+							self.newGroupForm.employees.push(element.id);
+							self.employees += element.name + ',';
+						});
+						self.newGroupForm.group_name = res.data.data.name;
+						this.loading = false;
+						if (!ifs) {
+							this.open_right(item, true);
+						}
+					} else {
+						self.$message.error(res.data.data.msg);
+						this.loading = false;
+					}
+				})
+				.catch(() => {
+					if (!ifs) {
+						self.table_loading = false;
+					}
+				})
+				.finally(() => {
+					this.loading = false;
+				});
+		},
+		// 规则分类改变之后请求数据
+		rule_null(val) {
+			let ruleNullId = [];
+			for (let i in val) {
+				for (let a in val[i]) {
+					ruleNullId.push(val[i][a]);
+				}
+			}
+		},
+		// 选人组件提交
+		move_employee_confirm(data) {
+			this.newGroupForm.employees = [];
+			this.employees = '';
+			this.employees_selected = data;
+			if (data.employee !== null && data.employee.length != 0) {
+				data.employee.forEach(element => {
+					this.newGroupForm.employees.push(element.id);
+					this.employees += element.name + ',';
+				});
+			}
+			this.isEmployeeShow = false;
+		},
+		// 删除分类
+		delItem() {
+			let self = this;
+			this.$confirm('确定要删除当前分类吗?, 是否继续?', '删除分类', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				let data = { group_id: self.clickItem.id };
+				self.delLoad = true;
+				self.$axios('post', '/api/integral/statistics/groups/drop', data)
+					.then(res => {
+						if (res.data.code == 1) {
+							self.$message.success(res.data.msg);
+							self.groupShow = false;
+							self.getGroupsList();
+						} else {
+							self.$message.error(res.data.msg);
+						}
+					})
+					.finally(() => {
+						self.delLoad = false;
+					});
+			});
+		},
+		// 提交表单
+		subGroupForm(formName) {
+			this.$refs[formName].validate(valid => {
+				if (valid) {
+					this.saveFun();
+				}
+			});
+		},
+		saveFun() {
+			let self = this;
+			self.saveLoad = true;
+			let data = JSON.parse(JSON.stringify(self.newGroupForm));
+			if (!self.popupType) {
+				data.group_id = self.clickItem.id;
+			}
+			if (data.items.length == 0) {
+				data.items = this.valuesOrLength;
+			}
+			self.$axios('POST', this.popupType ? '/api/integral/statistics/groups/create' : '/api/integral/statistics/groups', data)
+				.then(res => {
+					if (res.data.code == 1) {
+						if (self.popupType) {
+							self.popupType = false;
+							this.getGroupsList();
+						} else {
+							self.getGroupsList(self.clickItem.id); //传入当前ID.为了修改后页面不切换
+						}
+						self.$message.success(res.data.msg);
+						const resData = res.data.data;
+						self.groups_list.push({
+							id: resData.id,
+							employees: resData.employees,
+							name: name
+						}); //左边分类
+						self.groupShow = false;
+						this.employees = '';
+						this.employee_not_select = [];
+						this.employees_selected = { employee: [], dept: [] };
+					} else {
+						self.$message.error(res.data.msg);
+					}
+				})
+				.finally(() => {
+					setTimeout(() => {
+						self.saveLoad = false;
+					}, 500);
+				});
+		},
+		// 重置表单
+		resetForm(formName) {
+			this.$refs[formName].resetFields();
+			this.newGroupForm.employees = [];
+			this.employees = '';
+			this.employee_not_select = [];
+			this.employees_selected = { employee: [], dept: [] };
+			this.groupShow = false;
+		},
+		// 新增分类
+		addGroup() {
+			//规则
+			this.groupShow = true;
+			this.popupType = true;
+			this.employees = '';
+			this.employee_not_select = [];
+			this.employees_selected = { employee: [], dept: [] };
+			this.newGroupForm = {
+				group_name: '',
+				employees: [],
+				rules: [],
+				items: [],
+				date_interval: '1'
+			};
+			this.ruleHint = '统计所有积分(基础分和工龄分除外)';
+		},
+		// 页码变更
+		handleCurrentChange(val) {
+			this.params.page = val;
+			this.open_right(this.clickItem);
+		},
+		handleSizeChange(val) {
+			this.params.page_size = val;
+			this.open_right(this.clickItem);
+		},
+		open_right(item, tim) {
+			if (tim) {
+				this.time = {
+					year: moment().format('YYYY'), //年
+					quarter: moment().format('YYYYQ'), //季度
+					month: moment().format('YYYY-MM') //月
+				};
+				if (this.$refs.Seasons) {
+					if (this.newGroupForm.date_interval == 2) {
+						this.$refs.Seasons.choseQuarter = '';
+					}
+				}
+			}
+			this.valuesOrLength = [];
+			let self = this;
+			self.table_loading = true;
+			self.clickItem = item;
+			if (!item) {
+				self.table_loading = false;
+				return false;
+			}
+			let data = JSON.parse(JSON.stringify(self.params));
+			data.rule ? '' : delete data.rule;
+			// data.date ? "" : delete data.month;
+			data.group_id = item.id;
+			let months;
+			if (this.newGroupForm.date_interval == '1') {
+				months = this.time.month.replace('-', '');
+			}
+			data.date =
+				this.newGroupForm.date_interval == '1'
+					? months
+					: this.newGroupForm.date_interval == '2'
+					? this.time.quarter
+					: this.newGroupForm.date_interval == '3'
+					? this.time.year
+					: '';
+			self.$axios('get', '/api/integral/statistics/groups/rank', data)
+				.then(res => {
+					if (res.data.code == 1) {
+						self.table_list = res.data.data.list;
+						self.total = res.data.data.total;
+						self.lastUpdateTime = res.data.data.update_time;
+					} else {
+						self.$message.error(res.data.data.msg);
+					}
+				})
+				.finally(() => {
+					self.table_loading = false;
+				});
+		},
+		// 获取分类列表
+		getGroupsList(atPresent, isload) {
+			let self = this;
+			self.item_loading = true;
+			self.$axios('get', '/api/integral/statistics/groups')
+				.then(res => {
+					if (res.data.code == 1) {
+						// self.groups_list = res.data.data.list;//获取所有
+						let lists = res.data.data.list;
+						if (this.$authoritys('employee')) {
+							//员工权限只能查看包含自己的
+							let user = this.$getUserData().id;
+							let data = [];
+							lists.forEach(item => {
+								if (item.employees.length == 0) {
+									data.push(item);
+								} else {
+									if (item.employees.indexOf(user.toString()) != -1) {
+										data.push(item);
+									}
+								}
+							});
+							this.$nextTick(() => {
+								this.groups_list = data;
+							});
+						} else {
+							this.$nextTick(() => {
+								this.groups_list = lists;
+							});
+						}
+
+						self.$nextTick(() => {
+							if (atPresent) {
+								for (let i in self.groups_list) {
+									if (atPresent == self.groups_list[i].id) {
+										self.getGroupsInfo(self.groups_list[i]);
+									}
+								}
+							} else {
+								if (!isload) {
+									self.open_right(self.groups_list[0]);
+								}
+								self.getGroupsInfo(self.groups_list[0]);
+							}
+						});
+					} else {
+						self.$message.error(res.data.data.msg);
+					}
+				})
+				.finally(() => {
+					self.item_loading = false;
+				});
+		}
+	},
+	mounted() {
+		this.get_rule_trees();
+		this.getGroupsList(false, true); //避免首次进入调用两次open_right()方法,加上true判断
+	}
+};
 </script>
+<style scoped lang="scss">
+  .avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  .avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+  }
+  .avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 178px;
+    line-height: 178px;
+    text-align: center;
+  }
+  .avatar {
+    width: 178px;
+    height: 178px;
+    display: block;
+  }	
+	
+	
+::v-deep .itemClass .el-cascader-menu .el-cascader-menu__wrap li.el-cascader-node {
+	height: auto;
+	max-width: 500px;
+	.el-cascader-node__label {
+		white-space: initial;
+		overflow: initial;
+		text-overflow: initial;
+	}
+}
+.listData {
+	position: relative;
+	display: table-cell;
+	margin: 0 !important;
+	padding: 20px;
+	min-height: 600px;
+	&::after {
+		content: ' ';
+		position: absolute;
+		top: 0;
+		left: 0;
+		bottom: 0;
+		width: 1px;
+		background: #ebeef5;
+	}
+	& .groups_name {
+		display: block;
+		font-size: 20px;
+		color: rgb(48, 49, 51);
+		vertical-align: middle;
+	}
+}
+::v-deep .el-menu-item {
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+	&.is-active {
+		background-color: #ecf5ff;
+	}
+}
+
+.architecture {
+	display: flex;
+	text-align: center;
+	// margin-top:20px;
+	padding-left: 0px;
+	background-color: #fff;
+	width: 100%;
+	overflow: hidden;
+	cursor: default;
+	min-height: calc(60vh - 160px);
+}
+.architecture .RuleLine {
+	display: table-cell;
+	width: 1px;
+	min-height: 600px;
+	background: hsl(0, 2%, 76%);
+}
+.architecture .RuleLeft {
+	display: block;
+	text-align: center;
+	padding: 20px 10px;
+	border-right: none;
+	overflow-y: auto;
+	overflow-x: none;
+}
+/*滚动条的宽度*/
+
+.architecture .RuleLeft::-webkit-scrollbar {
+	width: 9px;
+	height: 9px;
+}
+.architecture .RuleRight::-webkit-scrollbar {
+	width: 9px;
+	height: 9px;
+}
+
+/*外层轨道。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果*/
+
+.architecture .RuleLeft::-webkit-scrollbar-track {
+	width: 6px;
+	background-color: #fff0;
+	-webkit-border-radius: 2em;
+	-moz-border-radius: 2em;
+	border-radius: 2em;
+}
+.architecture .RuleRight::-webkit-scrollbar-track {
+	width: 6px;
+	background-color: #fff0;
+	-webkit-border-radius: 2em;
+	-moz-border-radius: 2em;
+	border-radius: 2em;
+}
+
+/*滚动条的设置*/
+
+.architecture .RuleLeft::-webkit-scrollbar-thumb {
+	background-color: #fff0;
+	background-clip: padding-box;
+	min-height: 28px;
+	-webkit-border-radius: 2em;
+	-moz-border-radius: 2em;
+	border-radius: 2em;
+}
+.architecture .RuleRight::-webkit-scrollbar-thumb {
+	background-color: #fff0;
+	background-clip: padding-box;
+	min-height: 28px;
+	-webkit-border-radius: 2em;
+	-moz-border-radius: 2em;
+	border-radius: 2em;
+}
+/*滚动条移上去的背景*/
+
+.architecture .RuleLeft:hover::-webkit-scrollbar-thumb {
+	overflow-x: none;
+	background-color: rgba(144, 147, 153, 0.3);
+}
+.architecture .RuleRight:hover::-webkit-scrollbar-thumb {
+	background-color: rgba(115, 118, 124, 0.3);
+}
+
+.architecture .RuleLeft .company_name {
+	position: relative;
+	display: block;
+	font-family: 'Microsoft YaHei';
+	text-align: left;
+	padding: 15px 28px 17px;
+	cursor: pointer;
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+	border-bottom: 1px #f8f8f8 solid;
+}
+.architecture .RuleLeft .company_name img {
+	position: relative;
+	display: inline-block;
+	top: 2px;
+	width: 18px;
+	height: 18px;
+	margin-right: 4px;
+}
+.architecture .RuleLeft ::v-deep .el-button {
+	margin-bottom: 16px !important;
+}
+.architecture .RuleRight {
+	position: relative;
+	display: table-cell;
+	text-align: left;
+	padding: 20px;
+}
+.architecture .RuleRight .title span .sapn {
+	display: inline-block;
+	vertical-align: middle;
+	max-width: 600px;
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+}
+.architecture .RuleRight:after {
+	content: ' ';
+	position: absolute;
+	top: 0;
+	left: 0;
+	bottom: 0;
+	width: 1px;
+	background: #ebeef5;
+}
+.architecture .RuleRight .list_box {
+	width: 100%;
+	background: #fff;
+}
+.architecture .RuleRight .list_box ::v-deep table {
+	font-family: 'Microsoft YaHei';
+	width: 100% !important;
+	/*max-width:1920px; */
+}
+.architecture .department_box {
+}
+.architecture .department_box ::v-deep .el-tree-node {
+	display: block;
+	text-align: center;
+}
+.architecture .department_box ::v-deep .el-tree-node__content {
+	// padding-left:24px !important;
+	height: auto !important;
+}
+
+.architecture .department_box ::v-deep .el-tree-node .el-icon-caret-right {
+	display: inline-block;
+	color: #909399;
+	font-size: 16px;
+	padding: 6px 8px;
+}
+.architecture .department_box ::v-deep .el-tree-node .el-icon-caret-right.is-leaf {
+	color: transparent;
+	cursor: default;
+}
+.architecture .department_box ::v-deep .el-tree-node .custom-tree-node img {
+	margin-top: 0px;
+	width: 20px;
+}
+.architecture .department_box ::v-deep .el-tree-node .custom-tree-node span {
+}
+.architecture .department_box ::v-deep .el-tree-node__content {
+	padding: 12px 0;
+	border-bottom: 1px #f8f8f8 solid;
+}
+.architecture .department_box ::v-deep .el-tree-node__content:hover {
+	background: #ecf5ff;
+	border-radius: 4px;
+}
+.architecture .department_box ::v-deep .is-focusable .is-current {
+	border-radius: 4px;
+}
+.architecture .department_box ::v-deep .is-focusable .is-current .name {
+	color: #409eff;
+	font-weight: normal;
+	transition: 0.35s ease-in-out;
+}
+
+.elMenuCustomRule_Z {
+	overflow-y: auto;
+	border: none;
+	//   height: 980px;
+}
+// 滚动条样式
+.elMenuCustomRule_Z::-webkit-scrollbar {
+	width: 9px;
+	height: 9px;
+}
+.elMenuCustomRule_Z::-webkit-scrollbar-track {
+	width: 6px;
+	background-color: #fff0;
+	-webkit-border-radius: 2em;
+	-moz-border-radius: 2em;
+	border-radius: 2em;
+}
+/*滚动条的设置*/
+.elMenuCustomRule_Z::-webkit-scrollbar-thumb {
+	background-color: #fff0;
+	background-clip: padding-box;
+	min-height: 28px;
+	-webkit-border-radius: 2em;
+	-moz-border-radius: 2em;
+	border-radius: 2em;
+}
+/*滚动条移上去的背景*/
+.elMenuCustomRule_Z:hover::-webkit-scrollbar-thumb {
+	background-color: rgba(144, 147, 153, 0.3);
+}
+
+::v-deep .el-table .cell {
+	//让规则不隐藏
+	overflow: inherit;
+	white-space: normal;
+}
 
-<style>
+.terr-left button {
+	margin: 0 auto;
+	display: block;
+	margin-bottom: 20px;
+}
 </style>

+ 192 - 0
src/views/workbench/alreadySp.vue

@@ -0,0 +1,192 @@
+<template>
+	<div>
+		<div class="all padding-20">
+			<el-form ref="formData" :inline="true" :model="formData" label-width="80px">
+				<el-form-item label="工作类型">
+				  <el-select v-model="formData.source_type" placeholder="请选择排序">
+				    <el-option v-for="item in sourceList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+				  </el-select>
+				</el-form-item>
+				<el-form-item label="积分类型">
+					<el-select v-model="formData.pt_id" placeholder="请选择排序">
+						<el-option v-for="item in point_types" :key="item.id" :label="item.name" :value="item.id"></el-option>
+					</el-select>
+				</el-form-item>
+				<el-select v-model="formData.target_id" filterable clearable placeholder="请输入或选择人员">
+				  <el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
+				</el-select>
+			</el-form>
+			<div>
+				<el-table :data="list" style="cursor: pointer;" v-loading="loading" class="listTable" @row-click="openDetail">
+					<el-table-column label="审批标题" prop="task_name">
+						<template slot-scope="scope">
+							<div class="flex-box flex-v-ce">
+								<userImage width="50px" height="50px" :id="scope.row.employee_id" :user_name="scope.row.employee_name"></userImage>
+								<div style="margin-left: 5px;">
+									<span class="tableTitle" v-show="scope.row.source_type == 1">{{ scope.row.employee_name }}的积分任务</span>
+									<span class="tableTitle" v-show="scope.row.source_type == 2">{{ scope.row.employee_name }}的积分申请</span>
+									<span class="tableTitle" v-show="scope.row.source_type == 3">{{ scope.row.employee_name }}的积分录入</span>
+									<span class="tableTitle" v-show="scope.row.source_type == 4">{{ scope.row.employee_name }}的绩效工作</span>
+								</div>
+							</div>
+						</template>
+					</el-table-column>
+					<el-table-column label="审批内容" prop="remark.rule">
+						<template slot-scope="scope">
+							<span class="font-flex-word" style="max-width: 200px;">{{ scope.row.remark.customize || scope.row.remark.rule }}</span>
+						</template>
+					</el-table-column>
+					<el-table-column label="时间" prop="event_time" width="150"></el-table-column>
+					<el-table-column label="积分" prop="review_point" width="120">
+						<template slot-scope="scope">
+							<span v-show="scope.row.review_point < 0" class="green">
+								{{ scope.row.review_point }}
+								<span>{{ $getTypsName(scope.row.pt_id) }}</span>
+							</span>
+							<span class="red" v-show="scope.row.review_point >= 0">
+								+{{ scope.row.review_point }}
+								<span>{{ $getTypsName(scope.row.pt_id) }}</span>
+							</span>
+						</template>
+					</el-table-column>
+					<el-table-column label="状态" prop="status" width="80">
+						<template slot-scope="scope">
+							<span v-show="scope.row.status == 1" class="green">审批通过</span>
+							<span v-show="scope.row.status == 2" class="red">审批驳回</span>
+						</template>
+					</el-table-column>
+					<template slot="empty">
+						<div class="nopoint_box">
+							<div class="noimg noperson"></div>
+							<span class="title">没有对应的数据</span>
+						</div>
+					</template>
+				</el-table>
+			</div>
+
+			<center style="padding: 20px 0;">
+				<el-pagination
+					background
+					@size-change="handleSizeChange"
+					@current-change="handleCurrentChange"
+					:current-page="formData.page"
+					:page-sizes="[10, 20, 30, 40, 50, 100]"
+					layout="total, sizes, prev, pager, next"
+					:page-size="formData.page_size"
+					:total="total"
+				></el-pagination>
+			</center>
+		</div>
+		<examinePopup :title="'审核详情'" :id="detail_id" :show.sync="detailShow"></examinePopup>
+	</div>
+</template>
+
+<script>
+import examinePopup from '@/components/examinePopup.vue';
+
+export default {
+	data() {
+		return {
+			formData: {
+				type: 'reviewed',
+				source_type: '0',
+				target_id:null,
+				pt_id: 0,
+				page_size: 10,
+				page: 1
+			},
+			total: null,
+			list: null,
+			loading: false,
+			point_types: null,
+			detailShow: false,
+			detail_id: null,
+			employee_map: JSON.parse(localStorage.getItem("userList")),
+			sourceList: [{ name: '全部', id: '0' }, { name: '积分任务', id: '1' }, { name: '积分申请', id: '2' }, { name: '积分录入', id: '3' }]
+		};
+	},
+	watch: {
+		'formData.pt_id'() {
+			this.formData.page = 1;
+			this.getSpList();
+		},
+		'formData.source_type'() {
+		  this.formData.page = 1;
+		  this.getSpList();
+		},
+		'formData.target_id'(val) {
+		  if(!val){
+		    this.formData.target_id = null;
+		  }
+		  this.formData.page = 1;
+		  this.getSpList();
+		}
+	},
+	components: { examinePopup },
+	mounted() {
+		this.getSpList();
+		this.point_types = this.getPointTypes();
+	},
+	methods: {
+		openDetail(item) {
+			this.detail_id = item.id;
+			this.detailShow = true;
+		},
+		getTypes() {
+			var arr = this.$getTyps();
+			return arr.filter(function(item) {
+				return item.code != 'JX';
+			});
+		},
+		// 获取积分类型
+		getPointTypes() {
+			let point = this.getTypes();
+			point.unshift({ code: 'all', id: 0, name: '全部' });
+			return point;
+		},
+		// 页码变更
+		handleCurrentChange(val) {
+			this.formData.page = val;
+			this.getSpList();
+		},
+		handleSizeChange(val) {
+			this.formData.page_size = val;
+			this.getSpList();
+		},
+		getSpList() {
+			let self = this;
+			self.loading = true;
+			let params = JSON.parse(JSON.stringify(this.formData));
+			self.$axios('get', '/api/integral/review/list', params)
+				.then(res => {
+					if (res.data.code == 1) {
+						self.list = res.data.data.list;
+						self.total = res.data.data.total;
+					}
+				})
+				.finally(e => {
+					self.loading = false;
+				});
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.box {
+	min-height: calc(100vh - 140px);
+	width: 100%;
+	background-color: #fff;
+	padding: 20px;
+	& .listTable {
+		& .tableTitle {
+			line-height: 50px;
+			padding-left: 10px;
+		}
+	}
+}
+.popperSPBOX {
+	max-width: calc(100vh - 400px);
+	background-color: #fff;
+}
+</style>

+ 407 - 0
src/views/workbench/approval_batch.vue

@@ -0,0 +1,407 @@
+<template>
+	<div>
+		<div class="diy_tip_bg">
+			<el-alert class="diy-tip" type="success" @close="tips_close" v-if="tips_show">
+				<p style="font-size: 14px;">批量审批仅支持快速处理任务审批和已指定规则的积分审批,其余情况的审批单请到【待我审批】处理
+				  </br>权限分不足时,请进入【审批详情】→【通过】→【递交审批】给上级
+				</p>
+			</el-alert>
+		</div>
+		<div class="all padding-20">
+			<div>
+				<el-form :inline="true">
+					<el-form-item label="执行人">
+						<el-select v-model="target_id" filterable collapse-tags clearable placeholder="请输入/选择员工">
+							<el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item><el-input v-model="formData.keyword" placeholder="请输入审批内容" clearable></el-input></el-form-item>
+				</el-form>
+				<div>
+					<el-button type="primary" plain @click="pass">批量通过</el-button>
+					<el-button type="danger" plain @click="reject">批量驳回</el-button>
+				</div>
+			</div>
+			<el-table :data="list" style="width: 100%;cursor: pointer;"  v-loading="loading" @selection-change="deleteEvents" @row-click="openDetail">
+				<el-table-column width="50" type="selection"></el-table-column>
+					<el-table-column label="审批标题" prop="task_name">
+						<template slot-scope="scope">
+							<div class="flex-box flex-v-ce">
+								<userImage width="50px" height="50px"  :id="scope.row.employee_id" :user_name="scope.row.employee_name"></userImage>
+								<div style="margin-left: 5px;">
+									<span class="tableTitle" v-show="scope.row.source_type == 1">{{ scope.row.employee_name }}的积分任务</span>
+									<span class="tableTitle" v-show="scope.row.source_type == 2">{{ scope.row.employee_name }}的积分申请</span>
+									<span class="tableTitle" v-show="scope.row.source_type == 3">{{ scope.row.employee_name }}的积分录入</span>
+									<span class="tableTitle" v-show="scope.row.source_type == 4">{{ scope.row.employee_name }}的绩效工作</span>
+								</div>
+							</div>
+						</template>
+					</el-table-column>
+				<el-table-column prop="point" label="积分" align="center">
+					<template slot-scope="scope">
+						<span class="red" v-if="scope.row.point > 0">+{{ scope.row.point }}{{$getTyps(scope.row.pt_id).name}}</span>
+						<span class="green" v-else>{{ scope.row.point }}{{$getTyps(scope.row.pt_id).name}}</span>
+					</template>
+				</el-table-column>
+				<el-table-column label="审批内容" prop="remark" min-width="200">
+					<template slot-scope="scope">
+						<span class="font-flex-word">{{ scope.row.remark.customize || scope.row.remark.rule }}</span>
+					</template>
+				</el-table-column>
+				<el-table-column label="时间" prop="event_time" width="150"></el-table-column>
+				<el-table-column prop="remark" label="操作" align="center">
+					<template slot-scope="scope">
+						<span class="blue" style="cursor: pointer;">审批</span>
+					</template>
+				</el-table-column>
+				<template slot="empty">
+					<noData></noData>
+				</template>
+			</el-table>
+			<center style="padding: 20px 0;">
+				<el-pagination
+					background
+					@size-change="handleSizeChange"
+					@current-change="handleCurrentChange"
+					:current-page="formData.page"
+					:page-sizes="[10, 20, 50, 100]"
+					layout="total, sizes, prev, pager, next"
+					:page-size="formData.page_size"
+					:total="total"
+				></el-pagination>
+			</center>
+		</div>
+		<examinePopup :title="'审核详情'" :id="detail_id" :show.sync="detailShow"></examinePopup>
+		<el-dialog title="审批驳回" :visible.sync="rejectShow" width="520px">
+			<div style="text-align: center;margin-bottom: 10px;" class="fontColorB">已选中{{selectionID.length}}条审批单,确认全部驳回吗?</div>
+			<el-form :model="rejectForm" ref="rejectForm" label-width="80px" style="margin-top: 20px;">
+				<el-form-item
+					label="审批意见"
+					prop="remark"
+					:rules="[{ required: true, message: '请输入审批意见', trigger: 'blur' }, { min: 3, max: 50, message: '长度在 3 到 50 个字符', trigger: 'blur' }]"
+				>
+					<el-input type="textarea" :rows="4" v-model="rejectForm.remark" placeholder="请输入审批意见(限50字)"></el-input>
+				</el-form-item>
+				<el-form-item style="text-align: right; margin-bottom: 0">
+					<el-button @click="rejectShow = false">取消</el-button>
+					<el-button type="primary" @click="confirmReject()">确认驳回</el-button>
+				</el-form-item>
+			</el-form>
+		</el-dialog>
+		<!-- 审批结果 -->
+		<el-dialog title="提交结果" :visible.sync="isResult"  width="800" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false">
+			<div v-if="!isShowError">
+				<el-progress :text-inside="true" :stroke-width="24" :percentage="percentage"></el-progress>
+				<div style="margin-top: 20px;border: 1px solid #f1f1f1;">
+					<div class="flex-box-ce results" style="font-weight: 600;">
+						<div  style="border-right: 1px solid #f1f1f1;width: 50px;">序号</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">奖扣对象</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">审批内容</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">积分</div>
+						<div class="flex-2" >处理结果</div>
+					</div>
+					<div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
+						<div  style="border-right: 1px solid #f1f1f1;width: 50px;">{{results.length-index}}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.name }}</div>
+						<div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.remark.customize || item.remark.rule }}</div>
+						<div class="flex-1" style="border-right: 1px solid #f1f1f1;">
+						    {{ item.point>0? '+'+item.point:item.point }} 
+							<span>{{ item.pt_id==3? 'B分':'A分' }}</span>
+						</div>
+						<div class="flex-2 green" v-if="item.status == 1">{{ item.msg }}</div>
+						<div class="flex-2 red" v-else>{{ item.msg }}</div>
+					</div>
+				</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;" v-show="results.length==resultList.length"><el-button type="primary" @click="isResult = false" size="small">确 定</el-button></div>
+				</span>
+			</div>
+			<div v-else>
+				<div style="text-align: center;" class="red">服务器繁忙,请稍后再试</div>
+				<span slot="footer">
+					<div class="flex-box-end" style="margin-top: 20px;"><el-button type="primary" @click="isResult = false" size="small">确 定</el-button></div>
+				</span>
+			</div>
+		</el-dialog>
+	</div>
+</template>
+<script>
+import examinePopup from '@/components/examinePopup.vue';
+import { _debounce, getToken } from '@/api/auth';
+var setIntervalWesocketPush = null;
+export default {
+	components: { examinePopup },
+	data() {
+		return {
+			detailShow: false,
+			detail_id: null,
+			employee_map: JSON.parse(localStorage.getItem('SET_EMPLOYEE_MAP')),
+			total: 0,
+			target_id: '',
+			formData: {
+				target_id: '',
+				type: 'waiting',
+				keyword: '',
+				batch: 1,
+				page: 1,
+				pt_id: '0',
+				page_size: 10,
+				source_type: '0'
+			},
+			loading: false,
+			list: [],
+			selectionID: [],
+			rejectShow: false,
+			rejectForm: {
+				remark: ''
+			},
+			// 长连接结果
+			results: [], //提交的返回结果集合
+			isResult: false,
+			percentage: 0,
+			resultList:[],//要发送数据的集合
+			resultIndex:0,
+			isShowError:false,
+			tips_show: false,
+		};
+	},
+	watch: {
+		isResult(val) {
+			if (!val) {
+				this.isShowError = false;
+				this.percentage = 0;
+				this.results = [];
+				this.selectionItems = [];
+				this.getSpList();
+				this.$socketApi.closewebsocket();
+			}
+		},
+		target_id(val) {
+			this.formData.page = 1;
+			this.formData.target_id = val;
+			this.getSpList();
+		},
+		'formData.keyword': {
+			deep: true,
+			handler: _debounce(function(val) {
+				this.formData.page = 1;
+				this.getSpList();
+			}, 1000)
+		},
+		rejectShow(val) {
+			if (!val) {
+				this.rejectForm.remark = '';
+			}
+		}
+	},
+	created() {
+		this.getEmployeeList();
+	},
+	mounted() {
+		if (localStorage.getItem('voluntarilyPoint')) {
+			this.tips_show = false;
+		} else {
+			this.tips_show = true;
+		}
+		this.getSpList();
+	},
+	// beforeDestroy() {
+	// 	// 关闭连接
+	// 	this.$socketApi.closewebsocket();
+	// },
+	methods: {
+		// 关闭提示语
+		tips_close() {
+			localStorage.setItem('voluntarilyPoint', 'true');
+			this.tips_show = false;
+		},
+		// 详情
+		openDetail(item) {
+			this.detail_id = item.id;
+			this.detailShow = true;
+		},
+		// 确定驳回
+		confirmReject() {
+			if (!this.rejectForm.remark) {
+				this.$message.error('请输入审批意见');
+				return false;
+			}
+			this.rejectShow = false;
+			this.webSocket(false);
+		},
+		//驳回
+		reject() {
+			if (this.selectionID.length == 0) {
+				this.$message.error('请选择审批单');
+				return false;
+			}
+			this.rejectShow = true;
+		},
+		//通过
+		pass() {
+			if (this.selectionID.length == 0) {
+				this.$message.error('请选择审批单');
+				return false;
+			}
+			this.$confirm(`已选中${this.selectionID.length}条审批单,确认全部通过?`, '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			})
+			.then(() => {
+				this.webSocket(true);
+			}).catch(() => {});
+		},
+		webSocket(is){
+			let arr=[];
+			let wsData;
+			this.selectionID.forEach(item => {
+				if(is){
+					wsData = {
+						type: 'review',
+						action: 'complete',
+						review_id: item
+					};
+				}else{
+					wsData = {
+						type: 'review',
+						action: 'refuse',
+						review_id: item,
+						remark: this.rejectForm.remark
+					};
+				}
+				arr.push(wsData);
+			});
+			this.resultList=arr;
+			this.resultIndex=0;
+			this.percentage=0;
+			this.results=[];
+			this.isResult=true;
+			this.opneWebSocket()
+		},
+		opneWebSocket() {
+			let wsData=this.resultList;
+			if(wsData[this.resultIndex]){
+				this.$socketApi.sendData(wsData[this.resultIndex],this.onmessageWS)
+			}else{
+				// console.log(this.results)
+			}
+		},
+		onmessageWS(e){
+			if(e.type=='review'){
+				let item=this.selectionItems[this.resultIndex];
+				// console.log(item);
+				let result=e.result;
+				result.name=item.employee_name
+				result.remark=item.remark
+				result.point=item.point
+				result.pt_id=e.pt_id
+				this.results.push(e.result);
+				
+				this.resultIndex++;
+				this.opneWebSocket();
+				// 进度条
+				let lng = this.resultList.length;
+				this.percentage += Math.floor(100 / lng);
+				if (lng == this.results.length) {
+					this.percentage = 100;
+				}
+			}
+			if(e.type=='error'||e.type=='break'){
+				this.isShowError = true;
+			}
+		},
+		searchFun() {
+			this.dataList = [];
+			this.total = 0;
+			this.formData.page = 1;
+			this.getSpList();
+		},
+		deleteEvents(selection) {
+			this.selectionItems = selection;
+			this.selectionID = selection.map(item => {
+				return item.id;
+			});
+		},
+		getEmployeeList() {
+			this.$axios('get', '/api/employee/list', {}).then(res => {
+				if (res.data.code == 1) {
+					this.employee_map = res.data.data.list;
+				}
+			});
+		},
+		exportExcel() {
+			window.open();
+		},
+		// 页面变更
+		handleCurrentChange(val) {
+			this.formData.page = val;
+			this.getSpList();
+		},
+		handleSizeChange(val) {
+			this.formData.page = 1;
+			this.formData.page_size = val;
+			this.getSpList();
+		},
+		//请求数据
+		getSpList() {
+			this.loading = true;
+			if (!this.formData.target_id) {
+				delete this.formData.target_id;
+			}
+			this.$axios('get', '/api/integral/review/list', this.formData)
+				.then(res => {
+					this.list = res.data.data.list;
+					this.total = res.data.data.total;
+					if(this.formData.page!=1&&this.list.length==0){
+						this.formData.page = 1;
+						this.getSpList();
+					}
+				})
+				.finally(() => {
+					this.loading = false;
+				});
+		}
+	}
+};
+</script>
+
+<style scoped>
+.results {
+	border-bottom: 1px solid #f1f1f1;
+	text-align: center;
+}
+.results div {
+	padding: 10px;
+}
+.el-date-editor.el-input {
+	width: auto;
+}
+.date-picker-width {
+	width: 145px !important;
+}
+.search ::v-deep .el-input-group__append:active {
+	background: #26a2ff;
+}
+.search ::v-deep .el-input-group__append:active .el-icon-search {
+	color: #fff;
+}
+.diy_tip_bg {
+	background: #f5f6f9;
+	overflow: hidden;
+	.diy-tip {
+		margin-bottom: 15px;
+		border: 1px solid #67c23a;
+		padding: 20px 16px;
+		p {
+			color: #67c23a !important;
+			font-size: 16px;
+			margin: 0 !important;
+			padding: 4px 0;
+		}
+	}
+}
+::v-deep .el-dialog__body {
+	padding: 0px 20px 30px;
+}
+</style>

+ 1 - 57
src/views/workbench/approval_list.vue

@@ -1,9 +1,6 @@
 <template>
 	<div>
 		<div class="all padding-20">
-			<el-tabs v-model="formData.type">
-				<el-tab-pane v-for="(item, index) in tabsOption" :key="index" :label="item.label" :name="item.name"></el-tab-pane>
-			</el-tabs>
 
 			<el-form ref="formData" :inline="true" :model="formData" label-width="80px">
 				<el-form-item label="工作类型">
@@ -21,7 +18,7 @@
 				</el-select>
 			</el-form>
 
-			<div v-if="formData.type == 'waiting'">
+			<div>
 				<el-table :data="list" style="cursor: pointer;" v-loading="loading" class="listTable" @row-click="openDetail">
 					<el-table-column label="审批标题" prop="task_name">
 						<template slot-scope="scope">
@@ -56,54 +53,6 @@
 				</el-table>
 			</div>
 
-			<div v-if="formData.type == 'reviewed'">
-				<el-table :data="list" style="cursor: pointer;" v-loading="loading" class="listTable" @row-click="openDetail">
-					<el-table-column label="审批标题" prop="task_name">
-						<template slot-scope="scope">
-							<div class="flex-box flex-v-ce">
-								<userImage width="50px" height="50px" :id="scope.row.employee_id" :user_name="scope.row.employee_name"></userImage>
-								<div style="margin-left: 5px;">
-									<span class="tableTitle" v-show="scope.row.source_type == 1">{{ scope.row.employee_name }}的积分任务</span>
-									<span class="tableTitle" v-show="scope.row.source_type == 2">{{ scope.row.employee_name }}的积分申请</span>
-									<span class="tableTitle" v-show="scope.row.source_type == 3">{{ scope.row.employee_name }}的积分录入</span>
-									<span class="tableTitle" v-show="scope.row.source_type == 4">{{ scope.row.employee_name }}的绩效工作</span>
-								</div>
-							</div>
-						</template>
-					</el-table-column>
-					<el-table-column label="审批内容" prop="remark.rule">
-						<template slot-scope="scope">
-							<span class="font-flex-word" style="max-width: 200px;">{{ scope.row.remark.customize || scope.row.remark.rule }}</span>
-						</template>
-					</el-table-column>
-					<el-table-column label="时间" prop="event_time" width="150"></el-table-column>
-					<el-table-column label="积分" prop="review_point" width="120">
-						<template slot-scope="scope">
-							<span v-show="scope.row.review_point < 0" class="green">
-								{{ scope.row.review_point }}
-								<span>{{ $getTypsName(scope.row.pt_id) }}</span>
-							</span>
-							<span class="red" v-show="scope.row.review_point >= 0">
-								+{{ scope.row.review_point }}
-								<span>{{ $getTypsName(scope.row.pt_id) }}</span>
-							</span>
-						</template>
-					</el-table-column>
-					<el-table-column label="状态" prop="status" width="80">
-						<template slot-scope="scope">
-							<span v-show="scope.row.status == 1" class="green">审批通过</span>
-							<span v-show="scope.row.status == 2" class="red">审批驳回</span>
-						</template>
-					</el-table-column>
-					<template slot="empty">
-						<div class="nopoint_box">
-							<div class="noimg noperson"></div>
-							<span class="title">没有对应的数据</span>
-						</div>
-					</template>
-				</el-table>
-			</div>
-
 			<center style="padding: 20px 0;">
 				<el-pagination
 					background
@@ -139,7 +88,6 @@ export default {
 			list: null,
 			loading: false,
 			point_types: null,
-			tabsOption: [{ label: '待我审批', name: 'waiting' }, { label: '我已审批', name: 'reviewed' }],
 			detailShow: false,
 			detail_id: null,
 			employee_map: JSON.parse(localStorage.getItem("userList")),
@@ -147,10 +95,6 @@ export default {
 		};
 	},
 	watch: {
-		'formData.type'() {
-			this.formData.page = 1;
-			this.getSpList();
-		},
 		'formData.pt_id'() {
 			this.formData.page = 1;
 			this.getSpList();

Some files were not shown because too many files changed in this diff