Explorar o código

机构学生 批量注册

dusenyao %!s(int64=2) %!d(string=hai) anos
pai
achega
fb92143f64

+ 2 - 0
.env.development

@@ -3,3 +3,5 @@ ENV = 'development'
 
 
 # base api
 # base api
 VUE_APP_BASE_API = '/api'
 VUE_APP_BASE_API = '/api'
+
+VUE_APP_FILE = '/pdf'

+ 2 - 0
.env.production

@@ -3,3 +3,5 @@ ENV = 'production'
 
 
 # base api
 # base api
 VUE_APP_BASE_API = ''
 VUE_APP_BASE_API = ''
+
+VUE_APP_FILE = ''

+ 93 - 190
package-lock.json

@@ -41,20 +41,20 @@
       "dev": true
       "dev": true
     },
     },
     "@babel/core": {
     "@babel/core": {
-      "version": "7.19.0",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/core/-/core-7.19.0.tgz",
-      "integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==",
+      "version": "7.19.1",
+      "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/core/-/core-7.19.1.tgz",
+      "integrity": "sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==",
       "dev": true,
       "dev": true,
       "requires": {
       "requires": {
         "@ampproject/remapping": "^2.1.0",
         "@ampproject/remapping": "^2.1.0",
         "@babel/code-frame": "^7.18.6",
         "@babel/code-frame": "^7.18.6",
         "@babel/generator": "^7.19.0",
         "@babel/generator": "^7.19.0",
-        "@babel/helper-compilation-targets": "^7.19.0",
+        "@babel/helper-compilation-targets": "^7.19.1",
         "@babel/helper-module-transforms": "^7.19.0",
         "@babel/helper-module-transforms": "^7.19.0",
         "@babel/helpers": "^7.19.0",
         "@babel/helpers": "^7.19.0",
-        "@babel/parser": "^7.19.0",
+        "@babel/parser": "^7.19.1",
         "@babel/template": "^7.18.10",
         "@babel/template": "^7.18.10",
-        "@babel/traverse": "^7.19.0",
+        "@babel/traverse": "^7.19.1",
         "@babel/types": "^7.19.0",
         "@babel/types": "^7.19.0",
         "convert-source-map": "^1.7.0",
         "convert-source-map": "^1.7.0",
         "debug": "^4.1.0",
         "debug": "^4.1.0",
@@ -72,10 +72,28 @@
             "@babel/highlight": "^7.18.6"
             "@babel/highlight": "^7.18.6"
           }
           }
         },
         },
+        "@babel/compat-data": {
+          "version": "7.19.1",
+          "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/compat-data/-/compat-data-7.19.1.tgz",
+          "integrity": "sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==",
+          "dev": true
+        },
+        "@babel/helper-compilation-targets": {
+          "version": "7.19.1",
+          "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz",
+          "integrity": "sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==",
+          "dev": true,
+          "requires": {
+            "@babel/compat-data": "^7.19.1",
+            "@babel/helper-validator-option": "^7.18.6",
+            "browserslist": "^4.21.3",
+            "semver": "^6.3.0"
+          }
+        },
         "@babel/helper-validator-identifier": {
         "@babel/helper-validator-identifier": {
-          "version": "7.18.6",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
-          "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==",
+          "version": "7.19.1",
+          "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+          "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
           "dev": true
           "dev": true
         },
         },
         "@babel/highlight": {
         "@babel/highlight": {
@@ -90,9 +108,9 @@
           }
           }
         },
         },
         "@babel/parser": {
         "@babel/parser": {
-          "version": "7.19.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/parser/-/parser-7.19.0.tgz",
-          "integrity": "sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==",
+          "version": "7.19.1",
+          "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/parser/-/parser-7.19.1.tgz",
+          "integrity": "sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==",
           "dev": true
           "dev": true
         },
         },
         "@babel/template": {
         "@babel/template": {
@@ -106,6 +124,24 @@
             "@babel/types": "^7.18.10"
             "@babel/types": "^7.18.10"
           }
           }
         },
         },
+        "@babel/traverse": {
+          "version": "7.19.1",
+          "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/traverse/-/traverse-7.19.1.tgz",
+          "integrity": "sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.18.6",
+            "@babel/generator": "^7.19.0",
+            "@babel/helper-environment-visitor": "^7.18.9",
+            "@babel/helper-function-name": "^7.19.0",
+            "@babel/helper-hoist-variables": "^7.18.6",
+            "@babel/helper-split-export-declaration": "^7.18.6",
+            "@babel/parser": "^7.19.1",
+            "@babel/types": "^7.19.0",
+            "debug": "^4.1.0",
+            "globals": "^11.1.0"
+          }
+        },
         "@babel/types": {
         "@babel/types": {
           "version": "7.19.0",
           "version": "7.19.0",
           "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/types/-/types-7.19.0.tgz",
           "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/types/-/types-7.19.0.tgz",
@@ -120,12 +156,12 @@
       }
       }
     },
     },
     "@babel/eslint-parser": {
     "@babel/eslint-parser": {
-      "version": "7.18.9",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/eslint-parser/-/eslint-parser-7.18.9.tgz",
-      "integrity": "sha512-KzSGpMBggz4fKbRbWLNyPVTuQr6cmCcBhOyXTw/fieOVaw5oYAwcAj4a7UKcDYCPxQq+CG1NCDZH9e2JTXquiQ==",
+      "version": "7.19.1",
+      "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz",
+      "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==",
       "dev": true,
       "dev": true,
       "requires": {
       "requires": {
-        "eslint-scope": "^5.1.1",
+        "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1",
         "eslint-visitor-keys": "^2.1.0",
         "eslint-visitor-keys": "^2.1.0",
         "semver": "^6.3.0"
         "semver": "^6.3.0"
       }
       }
@@ -823,9 +859,9 @@
           }
           }
         },
         },
         "@babel/helper-validator-identifier": {
         "@babel/helper-validator-identifier": {
-          "version": "7.18.6",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
-          "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==",
+          "version": "7.19.1",
+          "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+          "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
           "dev": true
           "dev": true
         },
         },
         "@babel/highlight": {
         "@babel/highlight": {
@@ -840,9 +876,9 @@
           }
           }
         },
         },
         "@babel/parser": {
         "@babel/parser": {
-          "version": "7.19.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/parser/-/parser-7.19.0.tgz",
-          "integrity": "sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==",
+          "version": "7.19.1",
+          "resolved": "https://repo.huaweicloud.com/repository/npm/@babel/parser/-/parser-7.19.1.tgz",
+          "integrity": "sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==",
           "dev": true
           "dev": true
         },
         },
         "@babel/template": {
         "@babel/template": {
@@ -2897,6 +2933,15 @@
       "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
       "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
       "dev": true
       "dev": true
     },
     },
+    "@nicolo-ribaudo/eslint-scope-5-internals": {
+      "version": "5.1.1-v1",
+      "resolved": "https://repo.huaweicloud.com/repository/npm/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz",
+      "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==",
+      "dev": true,
+      "requires": {
+        "eslint-scope": "5.1.1"
+      }
+    },
     "@node-ipc/js-queue": {
     "@node-ipc/js-queue": {
       "version": "2.0.3",
       "version": "2.0.3",
       "resolved": "https://repo.huaweicloud.com/repository/npm/@node-ipc/js-queue/-/js-queue-2.0.3.tgz",
       "resolved": "https://repo.huaweicloud.com/repository/npm/@node-ipc/js-queue/-/js-queue-2.0.3.tgz",
@@ -3010,9 +3055,9 @@
       "dev": true
       "dev": true
     },
     },
     "@rushstack/eslint-patch": {
     "@rushstack/eslint-patch": {
-      "version": "1.1.4",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/@rushstack/eslint-patch/-/eslint-patch-1.1.4.tgz",
-      "integrity": "sha512-LwzQKA4vzIct1zNZzBmRKI9QuNpLgTQMEjsQLf3BXuGYb3QPTP4Yjf6mkdX+X1mYttZ808QpOwAzZjv28kq7DA==",
+      "version": "1.2.0",
+      "resolved": "https://repo.huaweicloud.com/repository/npm/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz",
+      "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==",
       "dev": true
       "dev": true
     },
     },
     "@sideway/address": {
     "@sideway/address": {
@@ -5657,9 +5702,9 @@
       }
       }
     },
     },
     "core-js": {
     "core-js": {
-      "version": "3.25.1",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/core-js/-/core-js-3.25.1.tgz",
-      "integrity": "sha512-sr0FY4lnO1hkQ4gLDr24K0DGnweGO1QwSj5BpfQjpSJPdqWalja4cTps29Y/PJVG/P7FYlPDkH3hO+Tr0CvDgQ=="
+      "version": "3.25.2",
+      "resolved": "https://repo.huaweicloud.com/repository/npm/core-js/-/core-js-3.25.2.tgz",
+      "integrity": "sha512-YB4IAT1bjEfxTJ1XYy11hJAKskO+qmhuDBM8/guIfMz4JvdsAQAqvyb97zXX7JgSrfPLG5mRGFWJwJD39ruq2A=="
     },
     },
     "core-js-compat": {
     "core-js-compat": {
       "version": "3.25.0",
       "version": "3.25.0",
@@ -6749,9 +6794,9 @@
       }
       }
     },
     },
     "eslint-plugin-vue": {
     "eslint-plugin-vue": {
-      "version": "9.4.0",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-plugin-vue/-/eslint-plugin-vue-9.4.0.tgz",
-      "integrity": "sha512-Nzz2QIJ8FG+rtJaqT/7/ru5ie2XgT9KCudkbN0y3uFYhQ41nuHEaboLAiqwMcK006hZPQv/rVMRhUIwEGhIvfQ==",
+      "version": "9.5.1",
+      "resolved": "https://repo.huaweicloud.com/repository/npm/eslint-plugin-vue/-/eslint-plugin-vue-9.5.1.tgz",
+      "integrity": "sha512-Y0sL2RY7Xc9S8kNih9lbwHIDmewUg9bfas6WSzsOWRgDXhIHKxRBZYNAnVcXBFfE+bMWHUA5GLChl7TcTYUI8w==",
       "dev": true,
       "dev": true,
       "requires": {
       "requires": {
         "eslint-utils": "^3.0.0",
         "eslint-utils": "^3.0.0",
@@ -6772,15 +6817,6 @@
             "eslint-visitor-keys": "^2.0.0"
             "eslint-visitor-keys": "^2.0.0"
           }
           }
         },
         },
-        "lru-cache": {
-          "version": "6.0.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/lru-cache/-/lru-cache-6.0.0.tgz",
-          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-          "dev": true,
-          "requires": {
-            "yallist": "^4.0.0"
-          }
-        },
         "semver": {
         "semver": {
           "version": "7.3.7",
           "version": "7.3.7",
           "resolved": "https://repo.huaweicloud.com/repository/npm/semver/-/semver-7.3.7.tgz",
           "resolved": "https://repo.huaweicloud.com/repository/npm/semver/-/semver-7.3.7.tgz",
@@ -6795,12 +6831,6 @@
           "resolved": "https://repo.huaweicloud.com/repository/npm/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
           "resolved": "https://repo.huaweicloud.com/repository/npm/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
           "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
           "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
           "dev": true
           "dev": true
-        },
-        "yallist": {
-          "version": "4.0.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/yallist/-/yallist-4.0.0.tgz",
-          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-          "dev": true
         }
         }
       }
       }
     },
     },
@@ -10749,15 +10779,6 @@
             "lru-cache": "^6.0.0"
             "lru-cache": "^6.0.0"
           }
           }
         },
         },
-        "lru-cache": {
-          "version": "6.0.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/lru-cache/-/lru-cache-6.0.0.tgz",
-          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-          "dev": true,
-          "requires": {
-            "yallist": "^4.0.0"
-          }
-        },
         "normalize-package-data": {
         "normalize-package-data": {
           "version": "3.0.3",
           "version": "3.0.3",
           "resolved": "https://repo.huaweicloud.com/repository/npm/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
           "resolved": "https://repo.huaweicloud.com/repository/npm/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
@@ -10770,25 +10791,6 @@
             "validate-npm-package-license": "^3.0.1"
             "validate-npm-package-license": "^3.0.1"
           }
           }
         },
         },
-        "read-pkg-up": {
-          "version": "7.0.1",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
-          "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
-          "dev": true,
-          "requires": {
-            "find-up": "^4.1.0",
-            "read-pkg": "^5.2.0",
-            "type-fest": "^0.8.1"
-          },
-          "dependencies": {
-            "type-fest": {
-              "version": "0.8.1",
-              "resolved": "https://repo.huaweicloud.com/repository/npm/type-fest/-/type-fest-0.8.1.tgz",
-              "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
-              "dev": true
-            }
-          }
-        },
         "semver": {
         "semver": {
           "version": "7.3.7",
           "version": "7.3.7",
           "resolved": "https://repo.huaweicloud.com/repository/npm/semver/-/semver-7.3.7.tgz",
           "resolved": "https://repo.huaweicloud.com/repository/npm/semver/-/semver-7.3.7.tgz",
@@ -10803,18 +10805,6 @@
           "resolved": "https://repo.huaweicloud.com/repository/npm/type-fest/-/type-fest-0.18.1.tgz",
           "resolved": "https://repo.huaweicloud.com/repository/npm/type-fest/-/type-fest-0.18.1.tgz",
           "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
           "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
           "dev": true
           "dev": true
-        },
-        "yallist": {
-          "version": "4.0.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/yallist/-/yallist-4.0.0.tgz",
-          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-          "dev": true
-        },
-        "yargs-parser": {
-          "version": "20.2.9",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/yargs-parser/-/yargs-parser-20.2.9.tgz",
-          "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
-          "dev": true
         }
         }
       }
       }
     },
     },
@@ -13009,9 +12999,9 @@
       "dev": true
       "dev": true
     },
     },
     "sass": {
     "sass": {
-      "version": "1.54.9",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/sass/-/sass-1.54.9.tgz",
-      "integrity": "sha512-xb1hjASzEH+0L0WI9oFjqhRi51t/gagWnxLiwUNMltA0Ab6jIDkAacgKiGYKM9Jhy109osM7woEEai6SXeJo5Q==",
+      "version": "1.55.0",
+      "resolved": "https://repo.huaweicloud.com/repository/npm/sass/-/sass-1.55.0.tgz",
+      "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==",
       "dev": true,
       "dev": true,
       "requires": {
       "requires": {
         "chokidar": ">=3.0.0 <4.0.0",
         "chokidar": ">=3.0.0 <4.0.0",
@@ -13906,9 +13896,9 @@
       }
       }
     },
     },
     "stylelint": {
     "stylelint": {
-      "version": "14.11.0",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/stylelint/-/stylelint-14.11.0.tgz",
-      "integrity": "sha512-OTLjLPxpvGtojEfpESWM8Ir64Z01E89xsisaBMUP/ngOx1+4VG2DPRcUyCCiin9Rd3kPXPsh/uwHd9eqnvhsYA==",
+      "version": "14.12.1",
+      "resolved": "https://repo.huaweicloud.com/repository/npm/stylelint/-/stylelint-14.12.1.tgz",
+      "integrity": "sha512-ZEM4TuksChMBfuPadQsHUkbOoRySAT9QMfDvvYxdAchOJl0p+csTMBXOu6ORAAxKhwBmxqJiep8V88bXfNs3EQ==",
       "dev": true,
       "dev": true,
       "requires": {
       "requires": {
         "@csstools/selector-specificity": "^2.0.2",
         "@csstools/selector-specificity": "^2.0.2",
@@ -13917,7 +13907,7 @@
         "cosmiconfig": "^7.0.1",
         "cosmiconfig": "^7.0.1",
         "css-functions-list": "^3.1.0",
         "css-functions-list": "^3.1.0",
         "debug": "^4.3.4",
         "debug": "^4.3.4",
-        "fast-glob": "^3.2.11",
+        "fast-glob": "^3.2.12",
         "fastest-levenshtein": "^1.0.16",
         "fastest-levenshtein": "^1.0.16",
         "file-entry-cache": "^6.0.1",
         "file-entry-cache": "^6.0.1",
         "global-modules": "^2.0.0",
         "global-modules": "^2.0.0",
@@ -13944,57 +13934,23 @@
         "string-width": "^4.2.3",
         "string-width": "^4.2.3",
         "strip-ansi": "^6.0.1",
         "strip-ansi": "^6.0.1",
         "style-search": "^0.1.0",
         "style-search": "^0.1.0",
-        "supports-hyperlinks": "^2.2.0",
+        "supports-hyperlinks": "^2.3.0",
         "svg-tags": "^1.0.0",
         "svg-tags": "^1.0.0",
         "table": "^6.8.0",
         "table": "^6.8.0",
         "v8-compile-cache": "^2.3.0",
         "v8-compile-cache": "^2.3.0",
         "write-file-atomic": "^4.0.2"
         "write-file-atomic": "^4.0.2"
       },
       },
       "dependencies": {
       "dependencies": {
-        "@nodelib/fs.stat": {
-          "version": "2.0.5",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
-          "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-          "dev": true
-        },
-        "array-union": {
-          "version": "2.1.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/array-union/-/array-union-2.1.0.tgz",
-          "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
-          "dev": true
-        },
         "balanced-match": {
         "balanced-match": {
           "version": "2.0.0",
           "version": "2.0.0",
           "resolved": "https://repo.huaweicloud.com/repository/npm/balanced-match/-/balanced-match-2.0.0.tgz",
           "resolved": "https://repo.huaweicloud.com/repository/npm/balanced-match/-/balanced-match-2.0.0.tgz",
           "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==",
           "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==",
           "dev": true
           "dev": true
         },
         },
-        "cosmiconfig": {
-          "version": "7.0.1",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/cosmiconfig/-/cosmiconfig-7.0.1.tgz",
-          "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==",
-          "dev": true,
-          "requires": {
-            "@types/parse-json": "^4.0.0",
-            "import-fresh": "^3.2.1",
-            "parse-json": "^5.0.0",
-            "path-type": "^4.0.0",
-            "yaml": "^1.10.0"
-          }
-        },
-        "dir-glob": {
-          "version": "3.0.1",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/dir-glob/-/dir-glob-3.0.1.tgz",
-          "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
-          "dev": true,
-          "requires": {
-            "path-type": "^4.0.0"
-          }
-        },
         "fast-glob": {
         "fast-glob": {
-          "version": "3.2.11",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/fast-glob/-/fast-glob-3.2.11.tgz",
-          "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
+          "version": "3.2.12",
+          "resolved": "https://repo.huaweicloud.com/repository/npm/fast-glob/-/fast-glob-3.2.12.tgz",
+          "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
           "dev": true,
           "dev": true,
           "requires": {
           "requires": {
             "@nodelib/fs.stat": "^2.0.2",
             "@nodelib/fs.stat": "^2.0.2",
@@ -14004,56 +13960,18 @@
             "micromatch": "^4.0.4"
             "micromatch": "^4.0.4"
           }
           }
         },
         },
-        "globby": {
-          "version": "11.1.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/globby/-/globby-11.1.0.tgz",
-          "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
-          "dev": true,
-          "requires": {
-            "array-union": "^2.1.0",
-            "dir-glob": "^3.0.1",
-            "fast-glob": "^3.2.9",
-            "ignore": "^5.2.0",
-            "merge2": "^1.4.1",
-            "slash": "^3.0.0"
-          }
-        },
         "ignore": {
         "ignore": {
           "version": "5.2.0",
           "version": "5.2.0",
           "resolved": "https://repo.huaweicloud.com/repository/npm/ignore/-/ignore-5.2.0.tgz",
           "resolved": "https://repo.huaweicloud.com/repository/npm/ignore/-/ignore-5.2.0.tgz",
           "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
           "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
           "dev": true
           "dev": true
         },
         },
-        "import-fresh": {
-          "version": "3.3.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/import-fresh/-/import-fresh-3.3.0.tgz",
-          "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
-          "dev": true,
-          "requires": {
-            "parent-module": "^1.0.0",
-            "resolve-from": "^4.0.0"
-          },
-          "dependencies": {
-            "resolve-from": {
-              "version": "4.0.0",
-              "resolved": "https://repo.huaweicloud.com/repository/npm/resolve-from/-/resolve-from-4.0.0.tgz",
-              "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-              "dev": true
-            }
-          }
-        },
         "is-plain-object": {
         "is-plain-object": {
           "version": "5.0.0",
           "version": "5.0.0",
           "resolved": "https://repo.huaweicloud.com/repository/npm/is-plain-object/-/is-plain-object-5.0.0.tgz",
           "resolved": "https://repo.huaweicloud.com/repository/npm/is-plain-object/-/is-plain-object-5.0.0.tgz",
           "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
           "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
           "dev": true
           "dev": true
         },
         },
-        "path-type": {
-          "version": "4.0.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/path-type/-/path-type-4.0.0.tgz",
-          "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-          "dev": true
-        },
         "write-file-atomic": {
         "write-file-atomic": {
           "version": "4.0.2",
           "version": "4.0.2",
           "resolved": "https://repo.huaweicloud.com/repository/npm/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
           "resolved": "https://repo.huaweicloud.com/repository/npm/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
@@ -15336,9 +15254,9 @@
       "dev": true
       "dev": true
     },
     },
     "vue-eslint-parser": {
     "vue-eslint-parser": {
-      "version": "9.0.3",
-      "resolved": "https://repo.huaweicloud.com/repository/npm/vue-eslint-parser/-/vue-eslint-parser-9.0.3.tgz",
-      "integrity": "sha512-yL+ZDb+9T0ELG4VIFo/2anAOz8SvBdlqEnQnvJ3M7Scq56DvtjY0VY88bByRZB0D4J0u8olBcfrXTVONXsh4og==",
+      "version": "9.1.0",
+      "resolved": "https://repo.huaweicloud.com/repository/npm/vue-eslint-parser/-/vue-eslint-parser-9.1.0.tgz",
+      "integrity": "sha512-NGn/iQy8/Wb7RrRa4aRkokyCZfOUWk19OP5HP6JEozQFX5AoS/t+Z0ZN7FY4LlmWc4FNI922V7cvX28zctN8dQ==",
       "dev": true,
       "dev": true,
       "requires": {
       "requires": {
         "debug": "^4.3.4",
         "debug": "^4.3.4",
@@ -15373,9 +15291,9 @@
           "dev": true
           "dev": true
         },
         },
         "espree": {
         "espree": {
-          "version": "9.3.3",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/espree/-/espree-9.3.3.tgz",
-          "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==",
+          "version": "9.4.0",
+          "resolved": "https://repo.huaweicloud.com/repository/npm/espree/-/espree-9.4.0.tgz",
+          "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==",
           "dev": true,
           "dev": true,
           "requires": {
           "requires": {
             "acorn": "^8.8.0",
             "acorn": "^8.8.0",
@@ -15389,15 +15307,6 @@
           "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
           "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
           "dev": true
           "dev": true
         },
         },
-        "lru-cache": {
-          "version": "6.0.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/lru-cache/-/lru-cache-6.0.0.tgz",
-          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-          "dev": true,
-          "requires": {
-            "yallist": "^4.0.0"
-          }
-        },
         "semver": {
         "semver": {
           "version": "7.3.7",
           "version": "7.3.7",
           "resolved": "https://repo.huaweicloud.com/repository/npm/semver/-/semver-7.3.7.tgz",
           "resolved": "https://repo.huaweicloud.com/repository/npm/semver/-/semver-7.3.7.tgz",
@@ -15406,12 +15315,6 @@
           "requires": {
           "requires": {
             "lru-cache": "^6.0.0"
             "lru-cache": "^6.0.0"
           }
           }
-        },
-        "yallist": {
-          "version": "4.0.0",
-          "resolved": "https://repo.huaweicloud.com/repository/npm/yallist/-/yallist-4.0.0.tgz",
-          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-          "dev": true
         }
         }
       }
       }
     },
     },

+ 7 - 7
package.json

@@ -11,7 +11,7 @@
   },
   },
   "dependencies": {
   "dependencies": {
     "axios": "^0.27.2",
     "axios": "^0.27.2",
-    "core-js": "^3.25.1",
+    "core-js": "^3.25.2",
     "element-ui": "^2.15.10",
     "element-ui": "^2.15.10",
     "js-cookie": "^3.0.1",
     "js-cookie": "^3.0.1",
     "md5": "^2.3.0",
     "md5": "^2.3.0",
@@ -22,9 +22,9 @@
     "vuex": "^3.6.2"
     "vuex": "^3.6.2"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@babel/core": "^7.19.0",
-    "@babel/eslint-parser": "^7.18.9",
-    "@rushstack/eslint-patch": "^1.1.4",
+    "@babel/core": "^7.19.1",
+    "@babel/eslint-parser": "^7.19.1",
+    "@rushstack/eslint-patch": "^1.2.0",
     "@vue/cli-plugin-babel": "~5.0.8",
     "@vue/cli-plugin-babel": "~5.0.8",
     "@vue/cli-plugin-eslint": "~5.0.8",
     "@vue/cli-plugin-eslint": "~5.0.8",
     "@vue/cli-plugin-router": "~5.0.8",
     "@vue/cli-plugin-router": "~5.0.8",
@@ -39,15 +39,15 @@
     "compression-webpack-plugin": "^6.1.1",
     "compression-webpack-plugin": "^6.1.1",
     "eslint": "^7.32.0",
     "eslint": "^7.32.0",
     "eslint-plugin-prettier": "^4.2.1",
     "eslint-plugin-prettier": "^4.2.1",
-    "eslint-plugin-vue": "^9.4.0",
+    "eslint-plugin-vue": "^9.5.1",
     "html-webpack-plugin": "^5.5.0",
     "html-webpack-plugin": "^5.5.0",
     "postcss": "^8.4.16",
     "postcss": "^8.4.16",
     "postcss-html": "^1.5.0",
     "postcss-html": "^1.5.0",
     "prettier": "2.7.1",
     "prettier": "2.7.1",
-    "sass": "^1.54.9",
+    "sass": "^1.55.0",
     "sass-loader": "^10.3.1",
     "sass-loader": "^10.3.1",
     "script-ext-html-webpack-plugin": "^2.1.5",
     "script-ext-html-webpack-plugin": "^2.1.5",
-    "stylelint": "^14.11.0",
+    "stylelint": "^14.12.1",
     "stylelint-config-prettier": "^9.0.3",
     "stylelint-config-prettier": "^9.0.3",
     "stylelint-config-recess-order": "^3.0.0",
     "stylelint-config-recess-order": "^3.0.0",
     "stylelint-config-recommended-vue": "^1.4.0",
     "stylelint-config-recommended-vue": "^1.4.0",

+ 26 - 0
src/api/user.js

@@ -41,3 +41,29 @@ export function ResetOrgAdminPassword(data) {
     data
     data
   });
   });
 }
 }
+
+/**
+ * 开始批量注册学员
+ * @param {Object} data
+ */
+export function StartBatchRegisterStudent(data) {
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_FileServer,
+    params: getRequestParams('user_manager-StartBatchRegisterStudent'),
+    data
+  });
+}
+
+/**
+ * 得到批量注册学员任务进度
+ * @param {Object} data
+ */
+export function GetBatchRegisterStudentProgress(data) {
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_FileServer,
+    params: getRequestParams('user_manager-GetBatchRegisterStudentProgress'),
+    data
+  });
+}

+ 37 - 0
src/utils/upload.js

@@ -0,0 +1,37 @@
+import { Message } from 'element-ui';
+import { fileUpload } from '@/api/app';
+
+export const acceptTypeList = [
+  {
+    type: 'image',
+    name: '图片',
+    regexp: new RegExp(/^image/),
+    attr: 'type'
+  },
+  { type: 'xls', name: 'xls 文件', regexp: new RegExp(/.xls$/), attr: 'name' }
+];
+
+export function useUpload(accept_type) {
+  const accept = acceptTypeList.find(({ type }) => type === accept_type);
+  if (!accept) return new Error('所选类型不存在');
+
+  function beforeUpload(file) {
+    let filter = accept.regexp.test(file[accept.attr]);
+    if (!filter) {
+      Message.error(`上传的文件不是${accept.name},请重新上传!`);
+    }
+    return filter;
+  }
+
+  function upload(file) {
+    return fileUpload('Open', file).then(({ file_info_list }) => {
+      if (file_info_list.length <= 0) return false;
+      return file_info_list;
+    });
+  }
+
+  return {
+    beforeUpload,
+    upload
+  };
+}

+ 199 - 0
src/views/student_manager/BatchRegistration.vue

@@ -0,0 +1,199 @@
+<template>
+  <el-dialog :visible="visible" width="1248px" :before-close="close">
+    <div class="title">
+      <div class="title-name">批量导入学员</div>
+      <div class="title-operation">
+        <a class="download" download="模板" :href="templateURL">下载模板</a>
+        <el-upload
+          action="no"
+          :before-upload="beforeUpload"
+          :http-request="request"
+          :show-file-list="false"
+          accept=".xls"
+        >
+          <el-button type="primary">上传导入文件</el-button>
+        </el-upload>
+      </div>
+    </div>
+    <div class="example-list">
+      <div class="example-list-title">
+        <div v-for="(item, i) in titleList" :key="i" class="title-item">{{ item }}</div>
+      </div>
+      <div class="example-list-content">
+        <div v-for="(item, i) in contentList" :key="i" class="example-row">
+          <div v-for="(attr, j) in Object.keys(item)" :key="j" class="example-column">{{ item[attr] }}</div>
+        </div>
+      </div>
+    </div>
+    <div slot="footer" class="footer">
+      <el-button @click="close">取消</el-button>
+      <el-button type="primary" @click="confirm">确定</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import { Message } from 'element-ui';
+import { acceptTypeList, useUpload } from '@/utils/upload';
+
+defineProps({
+  visible: {
+    type: Boolean,
+    required: true
+  }
+});
+
+const emits = defineEmits(['update:visible', 'batchRegister']);
+
+let file_id = ref('');
+let titleList = ['姓名', '年龄', '学校/机构', '学号', '邮箱'];
+let contentList = [
+  {
+    name: '吴县平',
+    age: 46,
+    school: '北京语言大学',
+    studentID: 'acvd192311',
+    mailbox: 'nekssowp@163.com'
+  },
+  {
+    name: '周承瑶',
+    age: 46,
+    school: '北京语言大学',
+    studentID: 'acvd192311',
+    mailbox: 'nekssowp@163.com'
+  },
+  {
+    name: '周蓓蓓',
+    age: 46,
+    school: '北京语言大学',
+    studentID: 'acvd192311',
+    mailbox: 'nekssowp@163.com'
+  },
+  {
+    name: '李婧妍',
+    age: 46,
+    school: '北京语言大学',
+    studentID: 'acvd192311',
+    mailbox: 'nekssowp@163.com'
+  },
+  {
+    name: '吴彦瑾',
+    age: 46,
+    school: '北京语言大学',
+    studentID: 'acvd192311',
+    mailbox: 'nekssowp@163.com'
+  },
+  {
+    name: '赵妍',
+    age: 46,
+    school: '北京语言大学',
+    studentID: 'acvd192311',
+    mailbox: 'nekssowp@163.com'
+  },
+  {
+    name: '周源源',
+    age: 46,
+    school: '北京语言大学',
+    studentID: 'acvd192311',
+    mailbox: 'nekssowp@163.com'
+  }
+];
+const templateURL = `${process.env.VUE_APP_FILE}/CSFileStore/001/00101/D-8KCWO2CQE49QM5LQR2/F-ZIZUPTL6T777UYF46X.xls`;
+
+function close() {
+  emits('update:visible', false);
+  file_id.value = '';
+}
+
+function confirm() {
+  if (file_id.value.length <= 0) return Message.warning('未上传导入文件');
+  emits('batchRegister', file_id.value);
+}
+
+const { upload, beforeUpload } = useUpload(acceptTypeList[1].type);
+
+function request(file) {
+  upload(file).then(file_info_list => {
+    file_id.value = file_info_list[0].file_id;
+    Message.success('上传导入文件成功');
+  });
+}
+</script>
+
+<style lang="scss" scoped>
+.el-dialog {
+  :deep &__header {
+    display: none;
+  }
+
+  .title {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+
+    &-name {
+      font-size: 20px;
+      font-weight: bold;
+      color: #000;
+    }
+
+    &-operation {
+      display: flex;
+      align-items: center;
+
+      .download {
+        margin-right: 24px;
+        color: #0085ff;
+      }
+    }
+  }
+
+  .example-list {
+    position: relative;
+    margin-top: 16px;
+
+    &-title {
+      display: flex;
+      align-items: center;
+      height: 40px;
+      padding: 8px 16px;
+      color: #000;
+      background-color: #f2f2f2;
+      border-bottom: 1px solid $border-color;
+
+      .title-item {
+        flex: 1;
+      }
+    }
+
+    &-content {
+      .example-row {
+        display: flex;
+        align-items: center;
+        height: 40px;
+        padding: 8px 16px;
+        border-bottom: 1px solid #f7f7f7;
+
+        .example-column {
+          flex: 1;
+        }
+      }
+    }
+  }
+
+  .el-button--primary {
+    background-color: #0085ff;
+    border-color: #0085ff;
+  }
+
+  .footer {
+    display: flex;
+    justify-content: flex-end;
+
+    .el-button + .el-progress {
+      margin-left: 10px;
+    }
+  }
+}
+</style>

+ 93 - 0
src/views/student_manager/ExecutiveReport.vue

@@ -0,0 +1,93 @@
+<template>
+  <el-dialog title="执行报告" width="650px" :visible="visible" :before-close="close">
+    <div class="report">
+      <div>
+        <span>执行进度:{{ `${successCount}/${totalCount}` }}</span>
+        <span>({{ `${isInterrupt ? '导入中断' : '导入完成'}` }}),</span>
+        <span>导入成功数:{{ successCount }},</span>
+        <span :style="{ color: '#f56c6c' }">导入失败数:{{ errorCount }}</span>
+      </div>
+      <div>
+        <a download="执行报告" :href="executeReportFileUrl">下载执行报告</a>
+      </div>
+    </div>
+    <div
+      class="result"
+      :style="{
+        background: `linear-gradient(to right, #34cc83 0%, #34cc83 ${successPercentage}%, #f56c6c ${successPercentage}%, #f56c6c 100%)`
+      }"
+    ></div>
+
+    <div slot="footer">
+      <el-button @click="close">关闭</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  name: 'ExecutiveReport'
+};
+</script>
+
+<script setup>
+import { computed } from 'vue';
+
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    required: true
+  },
+  successCount: {
+    type: Number,
+    required: true
+  },
+  errorCount: {
+    type: Number,
+    required: true
+  },
+  // 报告文件URL
+  executeReportFileUrl: {
+    type: String,
+    required: true
+  },
+  // 是否终端
+  isInterrupt: {
+    type: Boolean,
+    required: true
+  }
+});
+
+let totalCount = computed(() => {
+  return props.successCount + props.errorCount;
+});
+let successPercentage = computed(() => {
+  return (props.successCount / totalCount.value) * 100;
+});
+
+const emits = defineEmits(['update:visible']);
+
+function close() {
+  emits('update:visible', false);
+}
+</script>
+
+<style lang="scss" scoped>
+.el-dialog {
+  .report {
+    display: flex;
+    justify-content: space-between;
+
+    a {
+      color: #0085ff;
+    }
+  }
+
+  .result {
+    width: 100%;
+    height: 20px;
+    margin-top: 20px;
+    border-radius: 10px;
+  }
+}
+</style>

+ 184 - 88
src/views/student_manager/index.vue

@@ -26,7 +26,7 @@
           <el-select v-model="is_audited" class="account-search">
           <el-select v-model="is_audited" class="account-search">
             <el-option v-for="item in auditList" :key="item.value" :label="item.label" :value="item.value" />
             <el-option v-for="item in auditList" :key="item.value" :label="item.label" :value="item.value" />
           </el-select>
           </el-select>
-          <date-search ref="dateSearch" name="加入机构时间" />
+          <DateSearch ref="dateSearch" name="加入机构时间" />
         </el-col>
         </el-col>
         <el-col :span="2">
         <el-col :span="2">
           <el-button class="search-button" icon="el-icon-search" @click="pageQueryOrgStudentUserList" />
           <el-button class="search-button" icon="el-icon-search" @click="pageQueryOrgStudentUserList" />
@@ -40,12 +40,16 @@
       :page-size="page_capacity"
       :page-size="page_capacity"
       :total="total_count"
       :total="total_count"
       :current-page="cur_page"
       :current-page="cur_page"
-      @prev-click="changePage"
-      @next-click="changePage"
-      @current-change="changePage"
-      @size-change="changePageSize"
+      @prev-click="changePage($event, pageQueryOrgStudentUserList)"
+      @next-click="changePage($event, pageQueryOrgStudentUserList)"
+      @current-change="changePage($event, pageQueryOrgStudentUserList)"
+      @size-change="changePageSize($event, pageQueryOrgStudentUserList)"
     >
     >
-      <el-table :data="org_student_user_list">
+      <template #button>
+        <el-button type="primary" class="table-button" @click="visible = true">批量注册</el-button>
+      </template>
+
+      <el-table :data="list">
         <el-table-column prop="user_name" label="用户名" width="180" />
         <el-table-column prop="user_name" label="用户名" width="180" />
         <el-table-column prop="user_real_name" label="姓名" width="180" />
         <el-table-column prop="user_real_name" label="姓名" width="180" />
         <el-table-column prop="org_name" label="机构名称" width="180" />
         <el-table-column prop="org_name" label="机构名称" width="180" />
@@ -68,7 +72,7 @@
                 <el-link
                 <el-link
                   :underline="false"
                   :underline="false"
                   :type="row.is_audited === 'true' ? 'danger' : 'success'"
                   :type="row.is_audited === 'true' ? 'danger' : 'success'"
-                  @click="auditOrgStudentUser(row)"
+                  @click="auditOrgStudentUser(row.id, row.is_audited)"
                 >
                 >
                   审核{{ row.is_audited === 'true' ? '拒绝' : '同意' }}
                   审核{{ row.is_audited === 'true' ? '拒绝' : '同意' }}
                 </el-link>
                 </el-link>
@@ -78,97 +82,167 @@
         </el-table-column>
         </el-table-column>
       </el-table>
       </el-table>
     </CommonTable>
     </CommonTable>
+
+    <BatchRegistration :visible.sync="visible" @batchRegister="batchRegister" />
+    <ExecutiveReport
+      :visible.sync="visible_executive"
+      :success-count="successCount"
+      :error-count="errorCount"
+      :execute-report-file-url="executeReportFileUrl"
+      :is-interrupt="isInterrupt"
+    />
+
+    <div v-show="loading" class="loading">
+      <el-progress type="circle" :percentage="percentage" :width="200" />
+    </div>
   </div>
   </div>
 </template>
 </template>
 
 
-<script>
-import CommonTable from '@/components/common/CommonTable.vue';
+<script setup>
+import { ref } from 'vue';
 import { PageQueryOrgStudentUserList } from '@/api/list';
 import { PageQueryOrgStudentUserList } from '@/api/list';
 import { AuditOrgStudentUser } from '@/api/student';
 import { AuditOrgStudentUser } from '@/api/student';
+import { useList } from '@/utils/list';
+import { Message } from 'element-ui';
+import { StartBatchRegisterStudent, GetBatchRegisterStudentProgress } from '@/api/user';
+
+import CommonTable from '@/components/common/CommonTable.vue';
 import DateSearch from '@/components/common/DateSearch.vue';
 import DateSearch from '@/components/common/DateSearch.vue';
+import BatchRegistration from './BatchRegistration.vue';
+import ExecutiveReport from './ExecutiveReport.vue';
 
 
-export default {
-  components: { DateSearch, CommonTable },
-  data() {
-    return {
-      user_name: '',
-      user_real_name: '',
-      is_valid: '',
-      validList: [
-        {
-          value: '',
-          label: '所有'
-        },
-        {
-          value: 'true',
-          label: '有效'
-        },
-        {
-          value: 'false',
-          label: '无效'
-        }
-      ],
-      auditList: [
-        {
-          value: '',
-          label: '所有'
-        },
-        {
-          value: 'true',
-          label: '已审核'
-        },
-        {
-          value: 'false',
-          label: '未审核'
-        }
-      ],
-      is_audited: '',
-      org_student_user_list: [],
-      page_capacity: 10,
-      total_count: 0,
-      cur_page: 1
-    };
+const { page_capacity, cur_page, total_count, list, changePage, changePageSize } = useList();
+
+const validList = [
+  {
+    value: '',
+    label: '所有'
   },
   },
-  created() {
-    this.pageQueryOrgStudentUserList();
+  {
+    value: 'true',
+    label: '有效'
   },
   },
-  methods: {
-    pageQueryOrgStudentUserList() {
-      PageQueryOrgStudentUserList({
-        user_name: this.user_name,
-        user_real_name: this.user_real_name,
-        is_valid: this.is_valid,
-        is_audited: this.is_audited,
-        page_capacity: this.page_capacity,
-        cur_page: this.cur_page,
-        join_org_time_min: this.$refs?.dateSearch?.join_org_time_min ?? '',
-        join_org_time_max: this.$refs?.dateSearch?.join_org_time_max ?? ''
-      }).then(({ org_student_user_list, total_page, cur_page, total_count }) => {
-        this.org_student_user_list = org_student_user_list;
-        this.cur_page = cur_page;
-        this.total_page = total_page;
-        this.total_count = total_count;
-      });
-    },
-    changePage(newPage) {
-      this.cur_page = newPage;
-      this.pageQueryOrgStudentUserList();
-    },
-    changePageSize(pageSize) {
-      this.page_capacity = pageSize;
-      this.pageQueryOrgStudentUserList();
-    },
-
-    auditOrgStudentUser(row) {
-      AuditOrgStudentUser({
-        id_list: [row.id],
-        is_audited: row.is_audited !== 'true'
-      }).then(() => {
-        this.$router.go(0);
-      });
-    }
+  {
+    value: 'false',
+    label: '无效'
+  }
+];
+
+const auditList = [
+  {
+    value: '',
+    label: '所有'
+  },
+  {
+    value: 'true',
+    label: '已审核'
+  },
+  {
+    value: 'false',
+    label: '未审核'
   }
   }
-};
+];
+
+let user_name = ref('');
+let user_real_name = ref('');
+let is_valid = ref('');
+let is_audited = ref('');
+let dateSearch = ref();
+
+function pageQueryOrgStudentUserList() {
+  PageQueryOrgStudentUserList({
+    user_name: user_name.value,
+    user_real_name: user_real_name.value,
+    is_valid: is_valid.value,
+    is_audited: is_audited.value,
+    page_capacity: page_capacity.value,
+    cur_page: cur_page.value,
+    join_org_time_min: dateSearch.value?.join_org_time_min ?? '',
+    join_org_time_max: dateSearch.value?.join_org_time_max ?? ''
+  }).then(({ org_student_user_list, cur_page: page, total_count: total }) => {
+    list.value = org_student_user_list;
+    cur_page.value = page;
+    total_count.value = total;
+  });
+}
+pageQueryOrgStudentUserList();
+
+function auditOrgStudentUser(id, is_audited) {
+  AuditOrgStudentUser({
+    id_list: [id],
+    is_audited: is_audited !== 'true'
+  }).then(() => {
+    pageQueryOrgStudentUserList();
+  });
+}
+
+let visible = ref(false);
+let visible_executive = ref(false);
+
+// 批量导入
+let loading = ref(false);
+let percentage = ref(0);
+let timer = null;
+let successCount = ref(0);
+let errorCount = ref(0);
+let executeReportFileUrl = ref('');
+let isInterrupt = ref(false);
+function getBatchRegisterProgress(batch_register_student_task_id) {
+  return GetBatchRegisterStudentProgress({ batch_register_student_task_id })
+    .then(
+      ({
+        is_exist_task,
+        is_finish,
+        is_interrupt,
+        progress_percent,
+        success_count,
+        error_count,
+        execute_report_file_url
+      }) => {
+        successCount.value = parseInt(success_count);
+        errorCount.value = parseInt(error_count);
+        executeReportFileUrl.value = execute_report_file_url;
+        if (is_exist_task === 'false') {
+          loading.value = false;
+          Message.warning('不存在这个批量注册任务');
+          return clearTimeout(timer);
+        }
+        if (is_interrupt === 'true') {
+          isInterrupt.value = true;
+          loading.value = false;
+          visible_executive.value = true;
+          return false;
+        }
+        percentage.value = parseInt(progress_percent);
+        if (is_finish === 'true') {
+          loading.value = false;
+          clearTimeout(timer);
+          visible_executive.value = true;
+          return false;
+        }
+        return true;
+      }
+    )
+    .then(is_continue => {
+      if (!is_continue) return;
+      timer = setTimeout(() => {
+        getBatchRegisterProgress(batch_register_student_task_id);
+      }, 100);
+    })
+    .catch(() => {
+      timer = setTimeout(() => {
+        getBatchRegisterProgress(batch_register_student_task_id);
+      }, 100);
+    });
+}
+
+function batchRegister(file_id) {
+  visible.value = false;
+  StartBatchRegisterStudent({ file_id }).then(({ batch_register_student_task_id }) => {
+    loading.value = true;
+    getBatchRegisterProgress(batch_register_student_task_id);
+  });
+}
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
@@ -197,5 +271,27 @@ export default {
       align-items: center;
       align-items: center;
     }
     }
   }
   }
+
+  .table-button {
+    background-color: #0085ff;
+    border-color: #0085ff;
+  }
+
+  .loading {
+    position: fixed;
+    top: 0;
+    left: 0;
+    z-index: 3;
+    width: 100%;
+    height: 100%;
+    background-color: #fff;
+    opacity: 0.8;
+
+    .el-progress {
+      position: absolute;
+      top: calc(50% - 100px);
+      left: calc(50% - 100px);
+    }
+  }
 }
 }
 </style>
 </style>

+ 8 - 0
vue.config.js

@@ -24,6 +24,14 @@ if (NODE_ENV === 'development') {
       pathRewrite: {
       pathRewrite: {
         [`^${process.env.VUE_APP_BASE_API}`]: ''
         [`^${process.env.VUE_APP_BASE_API}`]: ''
       }
       }
+    },
+    [process.env.VUE_APP_FILE]: {
+      // target: 'https://file-cs.helxsoft.cn',
+      target: 'https://file-kf.helxsoft.cn/',
+      changeOrigin: true,
+      pathRewrite: {
+        [`^${process.env.VUE_APP_FILE}`]: ''
+      }
     }
     }
   };
   };
 }
 }