diff --git a/package-lock.json b/package-lock.json index f5aabc0e..e143c4b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "educoder", + "name": "forge", "version": "0.1.0", "lockfileVersion": 1, "requires": true, @@ -252,6 +252,22 @@ } } }, + "@babel/runtime-corejs3": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.6.tgz", + "integrity": "sha512-Xl8SPYtdjcMoCsIM4teyVRg7jIcgl8F2kRtoCcXuHzXswt9UxZCS6BzRo8fcnCuP6u2XtPgvyonmEPF57Kxo9Q==", + "requires": { + "core-js-pure": "^3.14.0", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + } + } + }, "@babel/template": { "version": "7.8.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", @@ -1256,7 +1272,7 @@ }, "babel-cli": { "version": "6.26.0", - "resolved": "https://registry.npm.taobao.org/babel-cli/download/babel-cli-6.26.0.tgz", + "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", "dev": true, "requires": { @@ -1279,7 +1295,7 @@ "dependencies": { "chokidar": { "version": "1.7.0", - "resolved": "https://registry.npm.taobao.org/chokidar/download/chokidar-1.7.0.tgz?cache=0&sync_timestamp=1602585438968&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchokidar%2Fdownload%2Fchokidar-1.7.0.tgz", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "optional": true, @@ -1297,7 +1313,7 @@ }, "source-map": { "version": "0.5.7", - "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } @@ -1396,7 +1412,7 @@ }, "babel-helper-bindify-decorators": { "version": "6.24.1", - "resolved": "https://registry.npm.taobao.org/babel-helper-bindify-decorators/download/babel-helper-bindify-decorators-6.24.1.tgz", + "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", "dev": true, "requires": { @@ -1459,7 +1475,7 @@ }, "babel-helper-explode-class": { "version": "6.24.1", - "resolved": "https://registry.npm.taobao.org/babel-helper-explode-class/download/babel-helper-explode-class-6.24.1.tgz", + "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", "dev": true, "requires": { @@ -1659,7 +1675,7 @@ }, "babel-plugin-syntax-async-generators": { "version": "6.13.0", - "resolved": "https://registry.npm.taobao.org/babel-plugin-syntax-async-generators/download/babel-plugin-syntax-async-generators-6.13.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", "dev": true }, @@ -1670,7 +1686,7 @@ }, "babel-plugin-syntax-decorators": { "version": "6.13.0", - "resolved": "https://registry.npm.taobao.org/babel-plugin-syntax-decorators/download/babel-plugin-syntax-decorators-6.13.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", "dev": true }, @@ -1706,7 +1722,7 @@ }, "babel-plugin-transform-async-generator-functions": { "version": "6.24.1", - "resolved": "https://registry.npm.taobao.org/babel-plugin-transform-async-generator-functions/download/babel-plugin-transform-async-generator-functions-6.24.1.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", "dev": true, "requires": { @@ -1738,7 +1754,7 @@ }, "babel-plugin-transform-decorators": { "version": "6.24.1", - "resolved": "https://registry.npm.taobao.org/babel-plugin-transform-decorators/download/babel-plugin-transform-decorators-6.24.1.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", "dev": true, "requires": { @@ -2043,7 +2059,7 @@ }, "babel-plugin-transform-runtime": { "version": "6.23.0", - "resolved": "https://registry.npm.taobao.org/babel-plugin-transform-runtime/download/babel-plugin-transform-runtime-6.23.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", "requires": { "babel-runtime": "^6.22.0" @@ -2060,7 +2076,7 @@ }, "babel-polyfill": { "version": "6.26.0", - "resolved": "https://registry.npm.taobao.org/babel-polyfill/download/babel-polyfill-6.26.0.tgz", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "dev": true, "requires": { @@ -2071,7 +2087,7 @@ "dependencies": { "regenerator-runtime": { "version": "0.10.5", - "resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.10.5.tgz?cache=0&sync_timestamp=1595456367497&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.10.5.tgz", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", "dev": true } @@ -2116,7 +2132,7 @@ }, "babel-preset-es2015": { "version": "6.24.1", - "resolved": "https://registry.npm.taobao.org/babel-preset-es2015/download/babel-preset-es2015-6.24.1.tgz", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", "dev": true, "requires": { @@ -2164,7 +2180,7 @@ }, "babel-preset-react": { "version": "6.24.1", - "resolved": "https://registry.npm.taobao.org/babel-preset-react/download/babel-preset-react-6.24.1.tgz", + "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=", "requires": { "babel-plugin-syntax-jsx": "^6.3.13", @@ -2197,7 +2213,7 @@ }, "babel-preset-stage-2": { "version": "6.24.1", - "resolved": "https://registry.npm.taobao.org/babel-preset-stage-2/download/babel-preset-stage-2-6.24.1.tgz", + "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", "dev": true, "requires": { @@ -2209,7 +2225,7 @@ }, "babel-preset-stage-3": { "version": "6.24.1", - "resolved": "https://registry.npm.taobao.org/babel-preset-stage-3/download/babel-preset-stage-3-6.24.1.tgz", + "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", "dev": true, "requires": { @@ -3486,7 +3502,7 @@ }, "code-prettify": { "version": "0.1.0", - "resolved": "https://registry.npm.taobao.org/code-prettify/download/code-prettify-0.1.0.tgz", + "resolved": "https://registry.npmjs.org/code-prettify/-/code-prettify-0.1.0.tgz", "integrity": "sha1-RocMyMGlDQm61TmzOpg9vUqjSx4=" }, "codemirror": { @@ -3771,6 +3787,11 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" }, + "core-js-pure": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.14.0.tgz", + "integrity": "sha512-YVh+LN2FgNU0odThzm61BsdkwrbrchumFq3oztnE9vTKC4KS2fvnPmcx8t6jnqAyOTCTF4ZSiuK8Qhh7SNcL4g==" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -3888,11 +3909,6 @@ "randomfill": "^1.0.3" } }, - "crypto-js": { - "version": "4.0.0", - "resolved": "https://registry.npm.taobao.org/crypto-js/download/crypto-js-4.0.0.tgz", - "integrity": "sha1-KQSrJnep0EKFai6i74DekuSjbcw=" - }, "crypto-random-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", @@ -7125,8 +7141,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "optional": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "aproba": { "version": "1.2.0", @@ -7147,14 +7162,12 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "optional": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7169,20 +7182,17 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "optional": true + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "optional": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "optional": true + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "core-util-is": { "version": "1.0.2", @@ -7299,8 +7309,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "optional": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.5", @@ -7312,7 +7321,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7327,7 +7335,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7335,14 +7342,12 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "optional": true + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -7361,7 +7366,6 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", - "optional": true, "requires": { "minimist": "^1.2.5" } @@ -7423,8 +7427,7 @@ "npm-normalize-package-bin": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "optional": true + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" }, "npm-packlist": { "version": "1.4.8", @@ -7452,8 +7455,7 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "optional": true + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "object-assign": { "version": "4.1.1", @@ -7465,7 +7467,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "optional": true, "requires": { "wrappy": "1" } @@ -7543,8 +7544,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safer-buffer": { "version": "2.1.2", @@ -7580,7 +7580,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7600,7 +7599,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7644,14 +7642,12 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "optional": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "optional": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } }, @@ -11541,7 +11537,7 @@ }, "output-file-sync": { "version": "1.1.2", - "resolved": "https://registry.npm.taobao.org/output-file-sync/download/output-file-sync-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", "dev": true, "requires": { @@ -18879,7 +18875,7 @@ }, "user-home": { "version": "1.1.1", - "resolved": "https://registry.npm.taobao.org/user-home/download/user-home-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", "dev": true }, @@ -18936,7 +18932,7 @@ }, "v8flags": { "version": "2.1.1", - "resolved": "https://registry.npm.taobao.org/v8flags/download/v8flags-2.1.1.tgz?cache=0&sync_timestamp=1590964281452&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fv8flags%2Fdownload%2Fv8flags-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", "dev": true, "requires": { @@ -19025,6 +19021,56 @@ "makeerror": "1.0.x" } }, + "wangeditor": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/wangeditor/-/wangeditor-4.7.3.tgz", + "integrity": "sha512-O6mbZkpGPksGWHYl7dKtYFbdfULn5oS7DYF9RS1WpG9rBumqa5CtLaxryc6P0i4IYb/fKRE55hD2XpkPzILpjg==", + "requires": { + "@babel/runtime": "^7.11.2", + "@babel/runtime-corejs3": "^7.11.2", + "tslib": "^2.1.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz", + "integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + }, + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, + "wangeditor-for-react": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/wangeditor-for-react/-/wangeditor-for-react-1.4.0.tgz", + "integrity": "sha512-N0WaZvhdbj/tsT6FZTm65S9o3EECxNTcMn4val+00lPi7GhUCMwdWh1buBCvp3nbmM0pHo7hWxdcK/U9KkmUug==", + "requires": { + "react": "^17.0.2", + "wangeditor": "^4.7.0" + }, + "dependencies": { + "react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + } + } + }, "warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", diff --git a/package.json b/package.json index edc6e18e..1476879f 100644 --- a/package.json +++ b/package.json @@ -107,6 +107,7 @@ "styled-components": "^4.4.1", "sw-precache-webpack-plugin": "0.11.4", "url-loader": "0.6.2", + "wangeditor-for-react": "^1.4.0", "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.10.3", "webpack-manifest-plugin": "^2.2.0", diff --git a/src/App.js b/src/App.js index 789c0af2..588e5b8f 100644 --- a/src/App.js +++ b/src/App.js @@ -45,6 +45,11 @@ const OpsDetail = Loadable({ loader: () => import('./forge/DevOps/opsDetail'), loading: Loading, }) +//任务/需求 +const Task = Loadable({ + loader: () => import('./military/task'), + loading: Loading, +}) //403页面 const Shixunauthority = Loadable({ loader: () => import('./modules/403/Shixunauthority'), @@ -240,6 +245,9 @@ class App extends Component { } } /> + {/*任务*/} + + {/*403*/} diff --git a/src/military/components/DelModal.jsx b/src/military/components/DelModal.jsx new file mode 100644 index 00000000..b2ba4434 --- /dev/null +++ b/src/military/components/DelModal.jsx @@ -0,0 +1,20 @@ +import { Modal } from 'antd'; + +export default ( + handleOk, + title, + content, + handleCancel) => { + return Modal.confirm({ + title: title || "警告", + content: content || "确认删除?", + okText: '确定', + cancelText: '取消', + onOk() { + handleOk && handleOk(); + }, + onCancel() { + handleCancel && handleCancel(); + } + }); +} \ No newline at end of file diff --git a/src/military/components/Upload.jsx b/src/military/components/Upload.jsx new file mode 100644 index 00000000..1bcf218d --- /dev/null +++ b/src/military/components/Upload.jsx @@ -0,0 +1,97 @@ +import React, { useEffect, useState } from "react"; +import { Upload, Button } from 'antd'; +import axios from 'axios'; +import { appendFileSizeToUploadFileAll } from 'educoder'; +axios.defaults.withCredentials = true; + +function Uploads({ className, size, actionUrl, fileList, showNotification, load }) { + const [files, setFiles] = useState(undefined); + + useEffect(() => { + if (fileList) { + init(); + } + }, [fileList]); + + function init() { + let f = appendFileSizeToUploadFileAll(fileList); + setFiles(f); + } + function onAttachmentRemove(file) { + if (!file.percent || file.percent === 100) { + deleteAttachment(file); + return false; + } + } + function deleteAttachment(file) { + let id = (file.response && file.response.data && file.response.data.id) || file.id; + + // 暂时不直接删除上传的文件,只在最后保存的时候进行修改 + let nf = files.filter(item => { + let itemId = (item.response && item.response.data && item.response.data.id) || item.id; + return itemId !== id; + }); + setFiles(nf); + // fileIdList(nf); + load && load(nf); + + // 发送服务到后台删除文件,同步更新数据 + // const url = actionUrl + `/busiAttachments/${id}`; + // axios.delete(url).then((response) => { + // if (response.data) { + // if (response.data.code === "1") { + // let nf = files.filter(item => (item.response.data.id !== id) && (item.id !== id)); + // setFiles(nf); + // fileIdList(nf); + // } else { + // showNotification(response.data.message); + // } + // } + // }).catch(function (error) { + // console.log(error); + // }); + } + + + function handleChange(info) { + if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') { + let fileList = info.fileList; + setFiles(appendFileSizeToUploadFileAll(fileList)); + if (info.file.status === 'done' || info.file.status === 'removed') load && load(fileList); + } + } + + // function fileIdList(fileList) { + // let id = []; + // let fileType = []; + // for (const item of fileList) { + // id.push(item.id || item.response.data.id); + // fileType.push(item.fileType || item.response.data.fileType); + // } + // load && load(id.join(), fileType.join()); + // } + + function beforeUpload(file) { + const isLt100M = file.size / 1024 / 1024 < size; + if (!isLt100M) { + showNotification(`文件大小必须小于${size}MB!`); + } + return isLt100M; + } + + const upload = { + name: 'file', + fileList: files, + action: actionUrl + `/busiAttachments/upload`, + onChange: handleChange, + onRemove: onAttachmentRemove, + beforeUpload: beforeUpload, + }; + return ( + + + (你可以上传小于{size}MB的文件) + + ) +} +export default Uploads; \ No newline at end of file diff --git a/src/military/components/chooseNav/index.jsx b/src/military/components/chooseNav/index.jsx new file mode 100644 index 00000000..3f1216c4 --- /dev/null +++ b/src/military/components/chooseNav/index.jsx @@ -0,0 +1,29 @@ +import React, { useEffect, useState } from 'react'; +import classNames from 'classnames'; +import './index.scss'; + +export default (props) => { + const { title, options, changeOptionId, type } = props; + + const [option, setOption] = useState({ code: "", dicItemName: "" ,dicItemCode:""}); + + useEffect(() => { + changeOptionId(option, type); + }, [option]) + + return ( + +
+
{title}
+
+
{ setOption({ code: "", dicItemName: "" }) }}>全部
+ { + options.map((item) => { + return
{ setOption(item) }} >{item.dicItemName}
+ }) + } +
+
+ + ) +} \ No newline at end of file diff --git a/src/military/components/chooseNav/index.scss b/src/military/components/chooseNav/index.scss new file mode 100644 index 00000000..42ac7b01 --- /dev/null +++ b/src/military/components/chooseNav/index.scss @@ -0,0 +1,42 @@ +.nav-content { + margin:20px 0; + background: #fff; + border-bottom: 1px solid #eaeaea; + box-shadow: #ddd 0px 0px 5px; +} +.shop-box { + width: 1280px; + border-top: 1px solid #eaeaea; + display: flex; + justify-content: start; +} +.choose-title { + width: 110px; + background: #f3f3f3; + text-align: center; + padding: 16px 0; + font-size: 14px; + color: #666; + font-weight: 600; +} +.choose-list { + width: 1170px; + padding: 16px 0; + display: flex; + justify-content: start; +} +.choose-item { + font-size: 14px; + color:#666; + text-align: center; + padding: 0 15px ; + cursor: pointer; + &:hover{ + color: #0072ff; + } +} + +.choose-item-checked { + color: #0072ff; +} + diff --git a/src/military/components/itemListTask/index.jsx b/src/military/components/itemListTask/index.jsx new file mode 100644 index 00000000..dae5511c --- /dev/null +++ b/src/military/components/itemListTask/index.jsx @@ -0,0 +1,21 @@ +import React from 'react'; +import './index.scss'; +export default (props) => { + const { list, itemClick, } = props; + + return ( + list.map(item => { + return ( +
+
{ itemClick(item.id) }}> + {item.achievementName || item.title} +
+
+ {item.publisher &&

发布单位:{item.publisher}

} +

发布时间:{item.publishDate || item.createTime}

+
+
+ ) + }) + ) +} \ No newline at end of file diff --git a/src/military/components/itemListTask/index.scss b/src/military/components/itemListTask/index.scss new file mode 100644 index 00000000..c4739395 --- /dev/null +++ b/src/military/components/itemListTask/index.scss @@ -0,0 +1,70 @@ +.list-box { + position: relative; + padding: 20px; + background: #fff; + border-bottom: 1px solid #dedede; +} +.list-title { + font-size: 17px; + color: #000; + cursor: pointer; +} +.list-title:hover { + color: #409eff; +} +.list-title span { + padding: 3px 5px; + margin-left:.5em; + background: #f8c753; + font-size: 13px; + color: #fff; + border-radius: 3px; +} +span.list-done { + background: #35d77e; +} +span.list-error { + background: #f56c6c; +} + +.list-tag { + display: inline-block; + margin: 5px 10px 5px 0; + background: #cfe9ff; + color: #0089ff; + font-size: 14px; + border-radius: 3px; + padding: 2px 5px; +} +.list-other > p { + display: inline-block; + margin: 0 10px 0 0; + font-size: 12px; + color: #666; +} + +.list-box-action { + position: absolute; + display: flex; + align-items: center; + top: 0; + bottom: 0; + right: 100px; + visibility: hidden; +} +.list-box:hover .list-box-action { + visibility: visible; +} +.list-box-action button { + display: inline-block; + margin: 0 25px; + width: 50px; + height: 50px; + color: #0089ff; + line-height: 50px; + text-align: center; + border: 0; + border-radius: 25px; + box-shadow: 2px 2px 5px 2px #eee; + cursor: pointer; +} diff --git a/src/military/components/sortBox/index.jsx b/src/military/components/sortBox/index.jsx new file mode 100644 index 00000000..b826aed4 --- /dev/null +++ b/src/military/components/sortBox/index.jsx @@ -0,0 +1,48 @@ +import React, { useEffect, useState } from 'react'; +import { Icon, } from 'antd'; +import classNames from 'classnames'; +import './index.scss'; + +export default (props) => { + const { options, changeOptionId, type, defaultValue } = props; + + const [myOptions, setMyOptions] = useState(options); + const [option, setOption] = useState(defaultValue || { name: "", type: "" }); + + useEffect(() => { + changeOptionId(option, type); + }, [option]); + + function itemClick(activeItem) { + const newOption = { + ...activeItem, + value: !activeItem.value + }; + for(const item of myOptions){ + if(item.type===activeItem.type){ + item.value=newOption.value; + } + } + setOption(newOption); + setMyOptions(myOptions); + } + + return ( + +
+ { + myOptions.map((item) => { + return
{ itemClick(item) }} > + {item.name} + { + item.icon && + + + } +
+ }) + } +
+ + ) +} \ No newline at end of file diff --git a/src/military/components/sortBox/index.scss b/src/military/components/sortBox/index.scss new file mode 100644 index 00000000..cbc72547 --- /dev/null +++ b/src/military/components/sortBox/index.scss @@ -0,0 +1,40 @@ +.sort-box { + display: flex; + justify-content: start; + align-items: center; + margin-left: 20px; + font-size: 1rem; + .sort-item { + display: flex; + align-items: center; + color: #333; + padding: 0 20px; + background-color: #fff; + &:hover { + background-color: #fff; + color: #409eff; + cursor: pointer; + } + } + .sort-item-checked { + // background-color: #409eff; + // color: #fff; + color: #409eff; + } + .caret-up-down { + display: inline-flex; + flex-flow: column nowrap; + margin-left:.25em; + font-size: .75em; + color:#ccc; + } + .caret-checked{ + color: #409eff; + } + .anticon-caret-up{ + margin-bottom: -.15em; + } + .anticon-caret-down{ + margin-top: -.15em; + } +} diff --git a/src/military/fetch.js b/src/military/fetch.js new file mode 100644 index 00000000..ee368840 --- /dev/null +++ b/src/military/fetch.js @@ -0,0 +1,112 @@ +import { notification } from 'antd'; +import axios from 'axios'; +import cookie from 'react-cookies'; + +// export const httpUrl='http://117.50.100.12:8001'; +// export const httpUrl='http://192.168.31.72:8081'; +export const httpUrl = 'http://106.75.31.211:58088'; + +// const TokenKey = 'autologin_forge_military'; +const TokenKey = 'autologin_trustie'; +axios.defaults.withCredentials = true; + +// 创建axios实例 +const service = axios.create({ + // baseURL: httpUrl, + timeout: 5000 // 请求超时时间 +}); + + +// request拦截器 +service.interceptors.request.use(config => { + if (cookie.load(TokenKey)) { + config.headers['Authorization'] = cookie.load(TokenKey); // 让每个请求携带自定义token 请根据实际情况自行修改 + } + return config; +}, error => { + // Do something with request error + console.log(error); // for debug + Promise.reject(error); +}); +// respone拦截器 +service.interceptors.response.use( + response => { + const res = response; + if (res.status == 400) { + notification.open({ + message: "提示", + description: '请求错误', + }); + return Promise.reject('error'); + } + if (res.status == 401) { + notification.open({ + message: "提示", + description: '未授权,请登录!', + }); + return Promise.reject('error'); + } + if (res.status == 403) { + notification.open({ + message: "提示", + description: '无权限', + }); + window.location.href="https://testforgeplus.trustie.net/403"; + return Promise.reject('error'); + } + if (res.status == 40001) { + notification.open({ + message: "提示", + description: '账户或密码错误!', + }); + return Promise.reject('error'); + } + if (response.status != 200 && res.status != 200) { + notification.open({ + message: "提示", + description: res.message, + }); + } else { + return response.data; + } + }, + error => { + let res = error.response||{}; + if (res.status == 400) { + notification.open({ + message: "提示", + description: '请求错误', + }); + return Promise.reject('error'); + } + if (res.status == 401) { + notification.open({ + message: "提示", + description: '未授权,请登录!', + }); + return Promise.reject('error'); + } + if (res.status == 403) { + notification.open({ + message: "提示", + description: '无权限', + }); + // window.location.href="https://testforgeplus.trustie.net/403"; + return Promise.reject('error'); + } + if (res.status == 40001) { + notification.open({ + message: "提示", + description: '账户或密码错误!', + }); + return Promise.reject('error'); + } + notification.open({ + message: "提示", + description: error.message, + }); + return Promise.reject(error); + } +); + +export default service; diff --git a/src/military/index.scss b/src/military/index.scss new file mode 100644 index 00000000..dfca5f05 --- /dev/null +++ b/src/military/index.scss @@ -0,0 +1,87 @@ +// 本模块公共样式 + +.centerbox { + width: 80vw; + max-width: 1280px; + margin: 40px auto; +} +.center-content { + background: #fff; + border: 1px solid #dedede; + box-shadow: #eee 0px 1px 1px 3px; +} +.centerScreen { + display: flex; + justify-content: space-between; + height: 46px; + background-color: #fff; + border-bottom: 1px solid #dedede; +} + + +// 内容标题右侧样式 +.center-right-but { + display: flex; + align-items: center; +} +.center-right-but > span { + margin: 0 10px; + font-size: 16px; + color: #0089ff; + cursor: pointer; +} + +// 通用标签样式 +.list-tag { + display: inline-block; + margin-right: 10px; + background: #cfe9ff; + color: #0089ff; + font-size: 14px; + border-radius: 3px; + padding: 2px 5px; + line-height: 25px; +} + +// 文件预览modal样式 +.file-modal { + width: 800px !important; + .ant-modal-body { + padding-top: 40px; + .pdf-box { + height: 70vh; + overflow-y: scroll; + } + } + .ant-modal-close { + top: 0 !important; + } + .show-img { + width: 100%; + } + .react-pdf__Page__canvas, + .react-pdf__Page__textContent { + margin: 0 auto; + max-width: 100%; + } +} + +.edit-input { + max-width: 500px; +} + +.none_panels{ + display: flex; + justify-content: center; + align-items: center; + flex-flow: column nowrap; + height: 40vh; +} + + +.newFooter .footerInfos>ul { + padding: 0 40px; + box-sizing: border-box; + max-width: 25%; + text-align: left; +} diff --git a/src/military/task.js b/src/military/task.js new file mode 100644 index 00000000..b573a4e8 --- /dev/null +++ b/src/military/task.js @@ -0,0 +1,67 @@ +import React, { Component } from "react"; + +import { Route, Switch } from "react-router-dom"; +import { withRouter } from "react-router"; +import { SnackbarHOC } from "educoder"; +import { CNotificationHOC } from "../modules/courses/common/CNotificationHOC"; +import { TPMIndexHOC } from "../modules/tpm/TPMIndexHOC"; +import Loadable from "react-loadable"; +import Loading from "../Loading"; +import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC"; +import './index.scss'; + +const TaskList = Loadable({ + loader: () => import("./task/taskList"), + loading: Loading, +}); + +const TaskDetail = Loadable({ + loader: () => import("./task/taskDetail"), + loading: Loading, +}); + +const TaskAdd = Loadable({ + loader: () => import("./task/taskEdit"), + loading: Loading, +}); + + +class Index extends Component { + render() { + return ( +
+ + + ( + + )} + > + + ( + + )} + > + + ( + + )} + > + + + +
+ ); + } +} +export default withRouter( + ImageLayerOfCommentHOC({ + imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget", + parentSelector: ".newMain", + })(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Index)))) +); diff --git a/src/military/task/api.js b/src/military/task/api.js new file mode 100644 index 00000000..522fd700 --- /dev/null +++ b/src/military/task/api.js @@ -0,0 +1,70 @@ +import fetch from '../fetch'; +import { notification } from 'antd'; + +// 获取字典分类列表 +export function getDictionary(id) { + return fetch({ + url: '/dicItem/getData?dicTypeCode=' + id, + method: 'get' + }); +} + +// 列表查询 +export async function getTaskList(params) { + let res = await fetch({ + url: '/api/announcements/', + method: 'get', + params, + }); + if (res.code === '1') { + return res.data; + } else { + notification.open({ + message: "提示", + description: res.message || '请求错误', + }); + } +} + + +// 详情查询 +export async function getTaskDetail(id) { + let res = await fetch({ + url: '/api/announcements/' + id, + method: 'get', + }); + if (res.code === '1') { + return res.data; + } else { + notification.open({ + message: "提示", + description: res.message || '请求错误', + }); + } +} + +//新增公告 +export function addTask(data) { + return fetch({ + url: '/api/announcements/add', + method: 'post', + data: data + }); +} + +//删除 +export function deleteTask(id) { + return fetch({ + url: '/api/announcements/' + id, + method: 'DELETE', + }); +} + +//更新 +export function editTask(data) { + return fetch({ + url: '/api/announcements/update', + method: 'put', + data: data + }); +} \ No newline at end of file diff --git a/src/military/task/static.js b/src/military/task/static.js new file mode 100644 index 00000000..dd380b5d --- /dev/null +++ b/src/military/task/static.js @@ -0,0 +1,19 @@ +// 公告开始 +export const taskStatus = [ + { code: 0, name: "关闭", dicItemName: '关闭' }, + { code: 1, name: "正常", dicItemName: '正常' }, + { code: 2, name: "草稿", dicItemName: '草稿' }, +]; + +export const taskType = [ + { code: 1, name: "更正", dicItemName: "更正" }, + { code: 2, name: "中标", dicItemName: "中标" }, + { code: 3, name: "废标", dicItemName: "废标" }, +]; + +export const taskChecked = [ + { code: 0, name: "未通过", dicItemName: "未通过" }, + { code: 1, name: "通过", dicItemName: "通过" }, + { code: 2, name: "未处理", dicItemName: "未处理" }, +]; +//公告结束 \ No newline at end of file diff --git a/src/military/task/taskDetail/index.jsx b/src/military/task/taskDetail/index.jsx new file mode 100644 index 00000000..f78ad68e --- /dev/null +++ b/src/military/task/taskDetail/index.jsx @@ -0,0 +1,63 @@ +import React, { useEffect, useState } from 'react'; +import { httpUrl } from '../../fetch'; +import { getTaskDetail } from '../api'; +import { taskStatus, taskType } from '../static'; +import './index.scss'; + +const taskStatusArr = []; +const taskTypeArr = []; +for (const item of taskStatus) { + taskStatusArr.push(item.name); +} +for (const item of taskType) { + taskTypeArr.push(item.name); +} + + +export default ({ match,history, showNotification }) => { + const [detailData, setDetailData] = useState({}); + const id = match.params.taskId; + + useEffect(() => { + id && getTaskDetail(id).then(data => { + setDetailData(data || {}); + }) + }, [id]); + + return ( + + +
+
+ {history.go(-1)}}>公告 >  详情 +
+
+
+
{detailData.title}
+
+
+
+ {detailData.publisher &&

发布单位:{detailData.publisher}

} +

发布时间:{detailData.publishDate || detailData.createdAt}

+

截止时间:{detailData.closingDate}

+
+ + {/* 富文本内容插入 */} +
+
+ + { + detailData.fileDownloadPath && +

公告附件:

+

{ window.open(httpUrl + detailData.fileDownloadPath) }} >{detailData.fileName}

+
+ } + +
+
+ +
+
+ + ) +} diff --git a/src/military/task/taskDetail/index.scss b/src/military/task/taskDetail/index.scss new file mode 100644 index 00000000..000938bc --- /dev/null +++ b/src/military/task/taskDetail/index.scss @@ -0,0 +1,37 @@ +.centerbox{ + position: relative; + .head-navigation{ + span{ + display: inline-flex; + align-items: center; + &:hover{ + color: #409eff; + } + } + } +} +.head-navigation { + position: absolute; + top:-2.3em; +} +// 内容详情 +.item-content { + padding: 10px 10px 0 30px; +} +.content-notice { + padding: 20px; +} + +.center-author { + display: flex; + align-items: center; +} + +.content-text { + margin: 1em 0; + min-height: 30vh; +} + +.content-download{ + color: #409eff; +} diff --git a/src/military/task/taskEdit/index.jsx b/src/military/task/taskEdit/index.jsx new file mode 100644 index 00000000..b9fc9125 --- /dev/null +++ b/src/military/task/taskEdit/index.jsx @@ -0,0 +1,247 @@ +import React, { forwardRef, useCallback, useEffect, useState } from 'react'; +import { Form, Input, Select, Button, DatePicker } from 'antd'; +import moment from 'moment'; +import Upload from '../../components/Upload'; +import { httpUrl } from '../../fetch'; +import { getDictionary, getTaskDetail, addTask, updateTask } from '../api'; +import './index.scss'; + +const Option = Select.Option; +const { TextArea } = Input; +const format = "YYYY-MM-DD HH:mm:ss"; + +export default Form.create()(forwardRef(({current_user, form, showNotification, match, history }, ref) => { + + const [requireType, setRequireType] = useState([]); + const [tagType, setTagType] = useState([]); + const [fileList, setFileList] = useState(null); + const [typeCode, setTypeCode] = useState(''); + const [typeName, setTypeName] = useState(''); + + const id = match.params.requireId; + const { getFieldDecorator, validateFields, setFieldsValue, } = form; + + useEffect(() => { + id && getTaskDetail(id).then(data => { + const formValue = { + title: data.title, + attachments: data.attachments, + // typeCode: data.typeCode, //为使用select labelInValue,在代码中初始化值 + endTime: moment(data.endTime), + tag: data.tag, + remark: data.remark + }; + setFieldsValue(formValue); + setTypeName(data.typeName); + setTypeCode(data.typeCode) + if (data.attachmentList.length) { + for (const item of data.attachmentList) { + item.name = item.fileName; + item.size = item.fileSize; + item.uid = "rc-upload" + item.id + } + setFileList(data.attachmentList); + } + }) + }, [id]); + + // 加载选项数据 + useEffect(() => { + getDictionary('requirement_type').then((res) => { + setRequireType(res.data); + }); + getDictionary("tag_type").then((res) => { + setTagType(res.data); + }); + }, []); + + + // 上传附件后得到的文件数组 + function UploadFunc(fileList) { + setFileList(fileList); + let files = []; + for (const item of fileList) { + files.push(item.id || item.response.data.id); + } + setFieldsValue({ + attachments: files.join() + }); + } + + const helper = useCallback( + (label, name, rules, widget, initialValue) => ( + + {getFieldDecorator(name, { rules, initialValue, validateFirst: true, })(widget)} + + ), []); + + const formItemLayout = { + labelCol: { + xs: { span: 12 }, + sm: { span: 4 }, + }, + wrapperCol: { + xs: { span: 12 }, + sm: { span: 16 }, + }, + }; + + const tailFormItemLayout = { + wrapperCol: { + xs: { + span: 20, + offset: 4, + }, + sm: { + span: 20, + offset: 4, + }, + }, + }; + + // 修改 + function saveItem() { + validateFields((error, values) => { + if (!error) { + let params = { + ...values, + createUserAccount:current_user.login|| sessionStorage.getItem("SET_Account"), //用户信息 + createUserName:current_user.username|| sessionStorage.getItem("SET_NAME"), //模拟时使用莫胜吕 + typeName, + typeCode, + status: 0, //状态 + }; + params.tag = params.tag.join(); + params.endTime = params.endTime.format(format); + if (id) { + // 编辑 + params.id = id; + updateTask(params).then(res => { + if (res.code === '1') { + showNotification("需求更新成功!"); + history.go(-1); + } else { + showNotification(res.message); + } + }); + } else { + // 新增 + addTask(params).then(res => { + if (res.code === '1') { + showNotification("需求新增成功!"); + history.go(-1); + } else { + showNotification(res.message); + } + }); + } + } + }) + } + + function changeTypeName(value) { + setTypeCode(value.key); + setTypeName(value.label); + } + + return ( +
+
+ +
+
{id ? '修改' : '新增'}需求
+
+
+ {helper( + "需求名称:", + "title", + [{ required: true, message: "请输入需求名称" }], + + )} + + {helper( + "需求类型:", + "typeCode", + [{ required: true, message: "请选择需求类别" }], + + , { key: typeCode, label: typeName })} + + {helper( + "结束时间:", + "endTime", + [{ required: true, message: "请输入结束时间" }], + + )} + + + + + {/* 用一个隐藏的input实现上传文件的必填校验 */} + {getFieldDecorator('attachments', { + rules: [{ required: true, message: "请上传需求文件" }], validateFirst: true + })()} + + + {helper( + "标签:", + "tag", + [{ required: true, message: "请选择需求标签" }], + + )} + + {helper( + "需求描述:", + "remark", + [{ required: true, message: "请输入需求描述" }], +