diff --git a/package-lock.json b/package-lock.json index 29895360..fa7933b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -489,11 +489,21 @@ "resolved": "http://173.15.15.82:8081/repository/npm-all/@tootallnate/once/-/once-1.1.2.tgz", "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" }, + "@transloadit/prettier-bytes": { + "version": "0.0.7", + "resolved": "https://registry.npmmirror.com/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz", + "integrity": "sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==" + }, "@types/estree": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" }, + "@types/event-emitter": { + "version": "0.3.3", + "resolved": "https://registry.npmmirror.com/@types/event-emitter/-/event-emitter-0.3.3.tgz", + "integrity": "sha512-UfnOK1pIxO7P+EgPRZXD9jMpimd8QEFcEZ5R67R1UhGbv4zghU5+NE7U8M8G9H5Jc8FI51rqDWQs6FtUfq2e/Q==" + }, "@types/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", @@ -663,6 +673,158 @@ } } }, + "@uppy/companion-client": { + "version": "2.2.2", + "resolved": "https://registry.npmmirror.com/@uppy/companion-client/-/companion-client-2.2.2.tgz", + "integrity": "sha512-5mTp2iq97/mYSisMaBtFRry6PTgZA6SIL7LePteOV5x0/DxKfrZW3DEiQERJmYpHzy7k8johpm2gHnEKto56Og==", + "requires": { + "@uppy/utils": "^4.1.2", + "namespace-emitter": "^2.0.1" + } + }, + "@uppy/core": { + "version": "2.3.4", + "resolved": "https://registry.npmmirror.com/@uppy/core/-/core-2.3.4.tgz", + "integrity": "sha512-iWAqppC8FD8mMVqewavCz+TNaet6HPXitmGXpGGREGrakZ4FeuWytVdrelydzTdXx6vVKkOmI2FLztGg73sENQ==", + "requires": { + "@transloadit/prettier-bytes": "0.0.7", + "@uppy/store-default": "^2.1.1", + "@uppy/utils": "^4.1.3", + "lodash.throttle": "^4.1.1", + "mime-match": "^1.0.2", + "namespace-emitter": "^2.0.1", + "nanoid": "^3.1.25", + "preact": "^10.5.13" + } + }, + "@uppy/store-default": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/@uppy/store-default/-/store-default-2.1.1.tgz", + "integrity": "sha512-xnpTxvot2SeAwGwbvmJ899ASk5tYXhmZzD/aCFsXePh/v8rNvR2pKlcQUH7cF/y4baUGq3FHO/daKCok/mpKqQ==" + }, + "@uppy/utils": { + "version": "4.1.3", + "resolved": "https://registry.npmmirror.com/@uppy/utils/-/utils-4.1.3.tgz", + "integrity": "sha512-nTuMvwWYobnJcytDO3t+D6IkVq/Qs4Xv3vyoEZ+Iaf8gegZP+rEyoaFT2CK5XLRMienPyqRqNbIfRuFaOWSIFw==", + "requires": { + "lodash.throttle": "^4.1.1" + } + }, + "@uppy/xhr-upload": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/@uppy/xhr-upload/-/xhr-upload-2.1.3.tgz", + "integrity": "sha512-YWOQ6myBVPs+mhNjfdWsQyMRWUlrDLMoaG7nvf/G6Y3GKZf8AyjFDjvvJ49XWQ+DaZOftGkHmF1uh/DBeGivJQ==", + "requires": { + "@uppy/companion-client": "^2.2.2", + "@uppy/utils": "^4.1.2", + "nanoid": "^3.1.25" + } + }, + "@wangeditor/basic-modules": { + "version": "1.1.7", + "resolved": "https://registry.npmmirror.com/@wangeditor/basic-modules/-/basic-modules-1.1.7.tgz", + "integrity": "sha512-cY9CPkLJaqF05STqfpZKWG4LpxTMeGSIIF1fHvfm/mz+JXatCagjdkbxdikOuKYlxDdeqvOeBmsUBItufDLXZg==", + "requires": { + "is-url": "^1.2.4" + } + }, + "@wangeditor/code-highlight": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/@wangeditor/code-highlight/-/code-highlight-1.0.3.tgz", + "integrity": "sha512-iazHwO14XpCuIWJNTQTikqUhGKyqj+dUNWJ9288Oym9M2xMVHvnsOmDU2sgUDWVy+pOLojReMPgXCsvvNlOOhw==", + "requires": { + "prismjs": "^1.23.0" + } + }, + "@wangeditor/core": { + "version": "1.1.19", + "resolved": "https://registry.npmmirror.com/@wangeditor/core/-/core-1.1.19.tgz", + "integrity": "sha512-KevkB47+7GhVszyYF2pKGKtCSj/YzmClsD03C3zTt+9SR2XWT5T0e3yQqg8baZpcMvkjs1D8Dv4fk8ok/UaS2Q==", + "requires": { + "@types/event-emitter": "^0.3.3", + "event-emitter": "^0.3.5", + "html-void-elements": "^2.0.0", + "i18next": "^20.4.0", + "scroll-into-view-if-needed": "^2.2.28", + "slate-history": "^0.66.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.22.15", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.15.tgz", + "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "i18next": { + "version": "20.6.1", + "resolved": "https://registry.npmmirror.com/i18next/-/i18next-20.6.1.tgz", + "integrity": "sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==", + "requires": { + "@babel/runtime": "^7.12.0" + } + }, + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + } + } + }, + "@wangeditor/editor": { + "version": "5.1.23", + "resolved": "https://registry.npmmirror.com/@wangeditor/editor/-/editor-5.1.23.tgz", + "integrity": "sha512-0RxfeVTuK1tktUaPROnCoFfaHVJpRAIE2zdS0mpP+vq1axVQpLjM8+fCvKzqYIkH0Pg+C+44hJpe3VVroSkEuQ==", + "requires": { + "@uppy/core": "^2.1.1", + "@uppy/xhr-upload": "^2.0.3", + "@wangeditor/basic-modules": "^1.1.7", + "@wangeditor/code-highlight": "^1.0.3", + "@wangeditor/core": "^1.1.19", + "@wangeditor/list-module": "^1.0.5", + "@wangeditor/table-module": "^1.1.4", + "@wangeditor/upload-image-module": "^1.0.2", + "@wangeditor/video-module": "^1.1.4", + "dom7": "^3.0.0", + "is-hotkey": "^0.2.0", + "lodash.camelcase": "^4.3.0", + "lodash.clonedeep": "^4.5.0", + "lodash.debounce": "^4.0.8", + "lodash.foreach": "^4.5.0", + "lodash.isequal": "^4.5.0", + "lodash.throttle": "^4.1.1", + "lodash.toarray": "^4.4.0", + "nanoid": "^3.2.0", + "slate": "^0.72.0", + "snabbdom": "^3.1.0" + } + }, + "@wangeditor/editor-for-react": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/@wangeditor/editor-for-react/-/editor-for-react-1.0.6.tgz", + "integrity": "sha512-KJNSfgMr5Blzae3oyaiz20flMKHZHnvsz4bCYQKDCUs/qkvC+xNTnwedlCmhGP187oPWPEypCIYI8Zg6sz0psQ==" + }, + "@wangeditor/list-module": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/@wangeditor/list-module/-/list-module-1.0.5.tgz", + "integrity": "sha512-uDuYTP6DVhcYf7mF1pTlmNn5jOb4QtcVhYwSSAkyg09zqxI1qBqsfUnveeDeDqIuptSJhkh81cyxi+MF8sEPOQ==" + }, + "@wangeditor/table-module": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/@wangeditor/table-module/-/table-module-1.1.4.tgz", + "integrity": "sha512-5saanU9xuEocxaemGdNi9t8MCDSucnykEC6jtuiT72kt+/Hhh4nERYx1J20OPsTCCdVr7hIyQenFD1iSRkIQ6w==" + }, + "@wangeditor/upload-image-module": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/@wangeditor/upload-image-module/-/upload-image-module-1.0.2.tgz", + "integrity": "sha512-z81lk/v71OwPDYeQDxj6cVr81aDP90aFuywb8nPD6eQeECtOymrqRODjpO6VGvCVxVck8nUxBHtbxKtjgcwyiA==" + }, + "@wangeditor/video-module": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/@wangeditor/video-module/-/video-module-1.1.4.tgz", + "integrity": "sha512-ZdodDPqKQrgx3IwWu4ZiQmXI8EXZ3hm2/fM6E3t5dB8tCaIGWQZhmqd6P5knfkRAd3z2+YRSRbxOGfoRSp/rLg==" + }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "http://173.15.15.82:8081/repository/npm-all/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -4065,6 +4227,11 @@ "webpack-sources": "^1.0.1" } }, + "compute-scroll-into-view": { + "version": "1.0.20", + "resolved": "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", + "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==" + }, "concat": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/concat/-/concat-1.0.3.tgz", @@ -4850,6 +5017,15 @@ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "d3-color": { "version": "1.4.1", "resolved": "http://173.15.15.82:8081/repository/npm-all/d3-color/-/d3-color-1.4.1.tgz", @@ -5397,6 +5573,14 @@ "resolved": "http://173.15.15.82:8081/repository/npm-all/dom-walk/-/dom-walk-0.1.2.tgz", "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" }, + "dom7": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/dom7/-/dom7-3.0.0.tgz", + "integrity": "sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g==", + "requires": { + "ssr-window": "^3.0.0-alpha.1" + } + }, "domain-browser": { "version": "1.2.0", "resolved": "http://173.15.15.82:8081/repository/npm-all/domain-browser/-/domain-browser-1.2.0.tgz", @@ -5749,11 +5933,40 @@ "is-symbol": "^1.0.2" } }, + "es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmmirror.com/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, "es6-promise": { "version": "4.2.8", "resolved": "http://173.15.15.82:8081/repository/npm-all/es6-promise/-/es6-promise-4.2.8.tgz", "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, "escalade": { "version": "3.1.1", "resolved": "http://173.15.15.82:8081/repository/npm-all/escalade/-/escalade-3.1.1.tgz", @@ -6405,6 +6618,15 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmmirror.com/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, "eventemitter3": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", @@ -6566,6 +6788,21 @@ } } }, + "ext": { + "version": "1.7.0", + "resolved": "https://registry.npmmirror.com/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "requires": { + "type": "^2.7.2" + }, + "dependencies": { + "type": { + "version": "2.7.2", + "resolved": "https://registry.npmmirror.com/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + } + } + }, "extend": { "version": "3.0.2", "resolved": "http://173.15.15.82:8081/repository/npm-all/extend/-/extend-3.0.2.tgz", @@ -8702,6 +8939,11 @@ "void-elements": "3.1.0" } }, + "html-void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/html-void-elements/-/html-void-elements-2.0.1.tgz", + "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==" + }, "html-webpack-plugin": { "version": "4.5.2", "resolved": "http://173.15.15.82:8081/repository/npm-all/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz", @@ -9755,6 +9997,11 @@ "is-extglob": "^1.0.0" } }, + "is-hotkey": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/is-hotkey/-/is-hotkey-0.2.0.tgz", + "integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==" + }, "is-in-browser": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", @@ -9945,6 +10192,11 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" + }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", @@ -10946,6 +11198,16 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, "lodash.cond": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", @@ -10975,6 +11237,11 @@ "integrity": "sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==", "dev": true }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==" + }, "lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -11010,6 +11277,11 @@ "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmmirror.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw==" + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -11340,6 +11612,14 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, + "mime-match": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/mime-match/-/mime-match-1.0.2.tgz", + "integrity": "sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==", + "requires": { + "wildcard": "^1.1.0" + } + }, "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", @@ -11576,11 +11856,21 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" }, + "namespace-emitter": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/namespace-emitter/-/namespace-emitter-2.0.1.tgz", + "integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==" + }, "nan": { "version": "2.17.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==" }, + "nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" + }, "nanomatch": { "version": "1.2.13", "resolved": "http://173.15.15.82:8081/repository/npm-all/nanomatch/-/nanomatch-1.2.13.tgz", @@ -11638,6 +11928,11 @@ "resolved": "http://173.15.15.82:8081/repository/npm-all/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, "nice-try": { "version": "1.0.5", "resolved": "http://173.15.15.82:8081/repository/npm-all/nice-try/-/nice-try-1.0.5.tgz", @@ -13561,6 +13856,11 @@ "resolved": "http://173.15.15.82:8081/repository/npm-all/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" }, + "preact": { + "version": "10.17.1", + "resolved": "https://registry.npmmirror.com/preact/-/preact-10.17.1.tgz", + "integrity": "sha512-X9BODrvQ4Ekwv9GURm9AKAGaomqXmip7NQTZgY7gcNmr7XE83adOMJvd3N42id1tMFU7ojiynRsYnY6/BRFxLA==" + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -13601,6 +13901,11 @@ "ansi-styles": "^3.0.0" } }, + "prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmmirror.com/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==" + }, "private": { "version": "0.1.8", "resolved": "http://173.15.15.82:8081/repository/npm-all/private/-/private-0.1.8.tgz", @@ -16355,7 +16660,7 @@ }, "sass-loader": { "version": "7.3.1", - "resolved": "https://registry.npmmirror.com/sass-loader/-/sass-loader-7.3.1.tgz", + "resolved": "http://173.15.15.82:8081/repository/npm-all/sass-loader/-/sass-loader-7.3.1.tgz", "integrity": "sha512-tuU7+zm0pTCynKYHpdqaPpe+MMTQ76I9TPZ7i4/5dZsigE350shQWe5EZNl5dBidM49TPET75tNqRbcsUZWeNA==", "dev": true, "requires": { @@ -16521,6 +16826,14 @@ "resolved": "https://registry.npmjs.org/scroll-into-view/-/scroll-into-view-1.16.2.tgz", "integrity": "sha512-vyTE0i27o6eldt9xinjHec41Dw05y+faoI+s2zNKJAVOdbA5M2XZrYq/obJ8E+QDQulJ2gDjgui9w9m9RZSRng==" }, + "scroll-into-view-if-needed": { + "version": "2.2.31", + "resolved": "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz", + "integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==", + "requires": { + "compute-scroll-into-view": "^1.0.20" + } + }, "scrollama": { "version": "3.2.0", "resolved": "https://registry.npmmirror.com/scrollama/-/scrollama-3.2.0.tgz", @@ -17159,6 +17472,43 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" }, + "slate": { + "version": "0.72.8", + "resolved": "https://registry.npmmirror.com/slate/-/slate-0.72.8.tgz", + "integrity": "sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw==", + "requires": { + "immer": "^9.0.6", + "is-plain-object": "^5.0.0", + "tiny-warning": "^1.0.3" + }, + "dependencies": { + "immer": { + "version": "9.0.21", + "resolved": "https://registry.npmmirror.com/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==" + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + } + } + }, + "slate-history": { + "version": "0.66.0", + "resolved": "https://registry.npmmirror.com/slate-history/-/slate-history-0.66.0.tgz", + "integrity": "sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng==", + "requires": { + "is-plain-object": "^5.0.0" + }, + "dependencies": { + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + } + } + }, "slice-ansi": { "version": "1.0.0", "resolved": "http://173.15.15.82:8081/repository/npm-all/slice-ansi/-/slice-ansi-1.0.0.tgz", @@ -17181,6 +17531,11 @@ "resolved": "http://173.15.15.82:8081/repository/npm-all/slick-carousel/-/slick-carousel-1.8.1.tgz", "integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==" }, + "snabbdom": { + "version": "3.5.1", + "resolved": "https://registry.npmmirror.com/snabbdom/-/snabbdom-3.5.1.tgz", + "integrity": "sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA==" + }, "snapdragon": { "version": "0.8.2", "resolved": "http://173.15.15.82:8081/repository/npm-all/snapdragon/-/snapdragon-0.8.2.tgz", @@ -17514,6 +17869,11 @@ "tweetnacl": "~0.14.0" } }, + "ssr-window": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/ssr-window/-/ssr-window-3.0.0.tgz", + "integrity": "sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==" + }, "ssri": { "version": "5.3.0", "resolved": "http://173.15.15.82:8081/repository/npm-all/ssri/-/ssri-5.3.0.tgz", @@ -18557,6 +18917,11 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -20760,6 +21125,11 @@ } } }, + "wildcard": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/wildcard/-/wildcard-1.1.2.tgz", + "integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==" + }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", diff --git a/package.json b/package.json index c549382c..6f96decb 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,8 @@ "dependencies": { "@monaco-editor/react": "^2.3.0", "@novnc/novnc": "^1.1.0", + "@wangeditor/editor": "^5.1.23", + "@wangeditor/editor-for-react": "^1.0.6", "actioncable": "^5.2.4-3", "ahooks": "^2.10.14", "antd": "^3.26.15", diff --git a/src/common/educoder.js b/src/common/educoder.js index 7b14824a..6575c503 100644 --- a/src/common/educoder.js +++ b/src/common/educoder.js @@ -7,7 +7,7 @@ export { getImageUrl as getImageUrl,getImageUrlAbsolute as getImageUrlAbsolute,getImage as getImage, getmyUrl as getmyUrl, getRandomNumber as getRandomNumber, getUrl as getUrl, getZoneUrl as getZoneUrl, publicSearchs as publicSearchs, getRandomcode as getRandomcode, getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl , getUploadActionUrl as getUploadActionUrl, getUploadActionUrltwo as getUploadActionUrltwo, getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth , getTaskUrlById as getTaskUrlById, TEST_HOST, htmlEncode as htmlEncode, getupload_git_file as getupload_git_file, getcdnImageUrl as getcdnImageUrl, - turnbar,returnbar,setSeoMeta as setSeoMeta , IsPC as IsPC + turnbar,returnbar,setSeoMeta as setSeoMeta , IsPC as IsPC, addMeta as addMeta } from './UrlTool'; export { setmiyah as setmiyah } from './Component'; diff --git a/src/forge/Component/RichEditor/index.jsx b/src/forge/Component/RichEditor/index.jsx new file mode 100644 index 00000000..2a15b968 --- /dev/null +++ b/src/forge/Component/RichEditor/index.jsx @@ -0,0 +1,124 @@ +import React, { useState, useEffect } from 'react'; +import { Editor, Toolbar } from '@wangeditor/editor-for-react'; +import '@wangeditor/editor/dist/css/style.css'; +import cookie from 'react-cookies'; +import { message, Spin } from 'antd'; +import axios from 'axios'; + +// 富文本编辑器 +function MyEditor(props) { + const {value, setValue, uploadUrl, videoUploadUrl} = props; + // editor 实例 + const [editor, setEditor] = useState(null); + const [loading, setLoading] = useState(false); + + // 模拟 ajax 请求,异步设置 html + useEffect(() => { + if(value && setValue){ + setValue(value); + } + }, []); + + // 工具栏配置 + const toolbarConfig = {}; + // 隐藏 代办 + toolbarConfig.excludeKeys = [ + 'todo' + ] + + // 编辑器配置 + const editorConfig = { + placeholder: '请输入内容...', + MENU_CONF:{ + uploadImage:{ + server: uploadUrl, + headers: { + Authorization: cookie.load('autologin_trustie') + }, + withCredentials: true, + fieldName: "file", + maxFileSize: 20 * 1024 * 1024, + allowedFileTypes: ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml", "image/bmp"], + customInsert(res, insertFn){ + const {url} = res; + insertFn(url, "图片", url); + }, + onBeforeUpload(file){ + const {type, name} = Object.values(file)[0]; + const typeRange = ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml", "image/bmp"]; + const suffix = name && name.split(".")[1]; + const isType = typeRange.indexOf(type) !== -1 && suffix !== "tiff"; + if(!isType){ + message.error("只能上传jpg、jpeg、webp、png、svg、gif、bmp格式的图片!") + return false; + } + return file; + }, + onError(file, err) { + message.error(`${file.name} 上传出错, ${err}` ) + }, + }, + uploadVideo:{ + // 自定义上传视频 + async customUpload(file, insertFn){ + if (!file.type.includes("video")) { + return message.error("请上传视频格式的文件!"); + } else if (file.size / 1024 / 1024 > 200) { + return message.error("请上传200M以内的文件!"); + } + const formData = new FormData(); + formData.append("file", file); + setLoading(true); + axios.post(videoUploadUrl || uploadUrl, formData, {headers: {Authorization: cookie.load('autologin_trustie')}}).then(res=>{ + setLoading(false); + if(res && res.data && res.data.code === 200){ + insertFn(res.data.url) + }else{ + message.error(res && res.data && res.data.msg) + } + }) + } + } + } + }; + + // 及时销毁 editor ,重要! + useEffect(() => { + return () => { + if (editor === null) return; + editor.destroy(); + setEditor(null); + }; + }, [editor]); + + const editorBoxClass = { + border: '1px solid #ccc', + zIndex: 100, + 'video': { + maxWidth: '100%' + } + } + + return ( +
+ + + setValue && setValue(editor.getHtml())} + mode="default" + style={{ height: '500px', overflowY: 'hidden' }} + /> + +
+ ); +} + +export default MyEditor; \ No newline at end of file diff --git a/src/forge/Information/Pages/apply.jsx b/src/forge/Information/Pages/apply.jsx index 2d5c29d6..bbb63880 100644 --- a/src/forge/Information/Pages/apply.jsx +++ b/src/forge/Information/Pages/apply.jsx @@ -5,7 +5,7 @@ import { postCreateZone } from '../api'; const { TextArea } = Input; const phonereg = /^([1][3456789])\d{9}$/ -const idenReg = /^[a-zA-Z][a-zA-Z0-9-_]{0,18}[a-zA-Z]+$/g +const idenReg = /^[a-zA-Z][a-zA-Z0-9-_]{0,18}[a-zA-Z]$/g function Apply(props){ const { form } = props; const { getFieldDecorator , validateFields } = form; @@ -39,12 +39,12 @@ function Apply(props){ } - function checkIndentity(rule, value, callback){ - if(value && !idenReg.test(value)){ - callback("专区标识长度2-20,只能以字母开头结尾,可包含数字、下划线、中划线"); - } - callback(); - } + // function checkIndentity(rule, value, callback){ + // if(value && !idenReg.test(value)){ + // callback("专区标识长度2-20,只能以字母开头结尾,可包含数字、下划线、中划线"); + // } + // callback(); + // } return(
@@ -93,8 +93,8 @@ function Apply(props){ {getFieldDecorator("key",{ rules:[ { required: true,message:"请输入专区域名标识" }, - { validator: checkIndentity } - ] + { pattern: /^[a-zA-Z][a-zA-Z0-9_-]{0,18}[a-zA-Z]$/, message: "长度2-20,只能包含数字、字母、下划线、中划线,必须以字母开头结尾"}, + ] })( )} diff --git a/src/forge/Information/Pages/main.jsx b/src/forge/Information/Pages/main.jsx index 04d33aa1..9fe9137f 100644 --- a/src/forge/Information/Pages/main.jsx +++ b/src/forge/Information/Pages/main.jsx @@ -1,7 +1,7 @@ import React , { useState , useEffect } from 'react'; -import { Menu , Spin , Skeleton } from 'antd'; +import { Menu , Spin , Skeleton, Button, Dropdown } from 'antd'; import Hot from '../Component/hot'; -import { Box , LongWidth } from '../../Component/layout'; +import { Box , FlexAJ, LongWidth } from '../../Component/layout'; import { Link } from 'react-router-dom'; import Lists from './newsList'; import guideArrow from '../img/guideArrow.png'; @@ -24,7 +24,18 @@ function Main(props){ const [ isSpin , setIsSpin ] = useState(true); const [ newCateId , setNewCateId ] = useState(undefined); const { deptId , cateId } = props.match.params; - const { id, temp } = props; + const { id, temp, role, history } = props; + + const menu = ( + + + {history.push(`/zone/${deptId}/news/add?type=richEditor`)}}>富文本编辑器 + + + {history.push(`/zone/${deptId}/news/add?type=mdEditor`)}}>MD编辑器 + + + ); useEffect(()=>{ @@ -34,7 +45,7 @@ function Main(props){ getMainList(); } else { getCateList(); - } + } getHotList(); } },[id]) @@ -109,7 +120,17 @@ function Main(props){
-

{ tempConfig[temp].mainTitle }

+
+

{tempConfig[temp].mainTitle}

+ {role && role.role !== "None" &&
+ {role.role === "Member" && } + {role.role === "Member" ? + + : } +
} +
{ mainList && mainList.length>0 && ( diff --git a/src/forge/Information/Pages/newsCreate.jsx b/src/forge/Information/Pages/newsCreate.jsx new file mode 100644 index 00000000..84483c79 --- /dev/null +++ b/src/forge/Information/Pages/newsCreate.jsx @@ -0,0 +1,175 @@ +import React,{ useState , useEffect } from 'react'; +import { Breadcrumb, Button, Form, Input, message, Select } from 'antd'; +import { getZoneUrl } from 'educoder'; +import MdEditor from '../../../modules/tpm/challengesnew/tpm-md-editor'; +import RichEditor from '../../Component/RichEditor'; +import UploadImage from '../../Team/Component/UploadImage'; +import { tempConfig } from '../tempInfo'; +import '../index.scss'; +import { Base64 } from 'js-base64'; +import { addNewsByDirId, getDirListById, getNewsDetailByAu, updateDoc } from '../api'; +import { httpUrl } from '../fetch'; + +function NewsCreate(props){ + const {history, id} = props; + const temp = props.temp; + const { getFieldDecorator, validateFields , setFieldsValue, setFields } = props.form; + const { deptId, id: newsId } = props.match.params; + const pathname = props.location.pathname; + const [type, setType] = useState(new URLSearchParams(props.location.search.substring(1)).get('type')); + const [value, setValue] = useState(undefined); + const [imageUrl, setImageUrl] = useState(undefined) + const [dirList, setDirList] = useState(undefined); + const [loading, setLoading] = useState(false); + const [isEdit, setIsEdit] = useState(false); + const layout = { + labelCol: { span: 2 }, + wrapperCol: { span: 14 }, + }; + + useEffect(()=>{ + id && getDircList(); + },[id]) + + useEffect(()=>{ + if(pathname){ + if(pathname.endsWith("/edit")){ + setIsEdit(true); + getNewsDetail(); + }else{ + setIsEdit(false); + } + } + },[pathname]) + + function getDircList(){ + getDirListById(id).then(res=>{ + if(res){ + setDirList(res.data.rows); + } + }) + } + + function getNewsDetail() { + getNewsDetailByAu(newsId).then(res=>{ + if(res && res.data){ + const {name, summary, cmsDir, content, headImg, editorType} = res.data.data; + setType(editorType === "rich_editor" ? 'richEditor' : 'mdEditor') + setFieldsValue({ + name, + summary, + dirId: cmsDir && cmsDir.id, + content: Base64.decode(content), + headImg + }); + setImageUrl(headImg); + setValue(Base64.decode(content)); + } + }) + } + + // 新建文章 + function submit(e){ + e.preventDefault(); + validateFields((err, fieldsValue)=>{ + const hasContent = type === "richEditor" && fieldsValue.content === "


" + if(err || hasContent){ + hasContent && setFields({content: {value:fieldsValue.content,errors:[new Error('请输入内容!')]}}); + return; + } + setLoading(true); + const params = { + ...fieldsValue, + editorType: type === "richEditor" ? "rich_editor" : "markdown_editor", + headImg: imageUrl, + content: Base64.encode(fieldsValue.content) + } + if(isEdit){ + delete params.editorType; + return updateDoc(newsId, params).then(res=>{ + const {data:{code, msg}} = res; + setLoading(false); + if(code === 200){ + message.success("更新成功"); + history.push(`/zone/${deptId}/news/self`); + }else{ + message.error(msg || '更新失败,请联系管理员!') + } + }) + } + addNewsByDirId(fieldsValue.dirId, params).then(res=>{ + const {data:{code, msg}} = res; + setLoading(false); + if(code === 200){ + message.success("新增成功"); + history.push(`/zone/${deptId}/news/self`); + }else{ + message.error(msg || '新增失败,请联系管理员!') + } + }) + }) + } + + return( +
+ + {tempConfig[temp].mainTitle} + {isEdit ? '编辑' : '新建'}文章 + +
+
+ + {getFieldDecorator("name", { + rules:[{ required:true,message:"请输入文章标题!" }, + {type: 'string', max: 200, message: "最大长度200"}, + {pattern: /^[^<>[\]/\\]+$/, message: "不能输入特殊字符:< > [ ] / \\"}] + })( + + )} + + + {getFieldDecorator("summary", { + rules:[{ required:true,message:"请输入概览!" }, + {type: 'string', max: 200, message: "最大长度200"}] + })( + + )} + + + {getFieldDecorator("dirId", { + rules:[{ required:true,message:"请选择文章所属栏目!" }] + })( + + )} + + + {getFieldDecorator("content",{ + rules:[{required:true,message:"请输入内容!"}], + })( + type === "richEditor" ? {setFieldsValue({"content": value})}}/> : {setFieldsValue({"content": value})}} + imageExpand={false} + > + )} + + + setImageUrl(url) } url={ imageUrl ? imageUrl : undefined} action={ getZoneUrl(`/api/cms/common/upload`) } /> + + + + + +
+
+
+ ) +} +export default Form.create()(NewsCreate); \ No newline at end of file diff --git a/src/forge/Information/Pages/newsDetail.jsx b/src/forge/Information/Pages/newsDetail.jsx index 50e58767..b98da833 100644 --- a/src/forge/Information/Pages/newsDetail.jsx +++ b/src/forge/Information/Pages/newsDetail.jsx @@ -7,7 +7,7 @@ import { getNewsDetail } from '../api'; import { IsPC } from 'educoder'; import { tempConfig } from '../tempInfo'; import Acce from '../Component/mobile/accessory'; - +import { addMeta, setSeoMeta } from 'educoder'; function NewsDetail(props){ @@ -44,6 +44,21 @@ function NewsDetail(props){ } },[id]) + useEffect(()=>{ + // 设置网页标题 + if(detail){ + const { name, cmsDir, summary} = detail; + document.title = `${ name }/${ cmsDir.name }`; + addMeta('Keywords', `${ name },${ cmsDir.name },${ summary }`); + } + return componentWillUnmount + }, [detail]) + + function componentWillUnmount() { + document.title= zonedetail.name; + setSeoMeta(`${zonedetail.name},`, zonedetail.name, zonedetail.subTitle, `/zone/${deptId}`) + } + function getDetails(){ setIsSpin(true) getNewsDetail(id).then(result=>{ diff --git a/src/forge/Information/Pages/selfList.jsx b/src/forge/Information/Pages/selfList.jsx index 5df34fde..fce4407b 100644 --- a/src/forge/Information/Pages/selfList.jsx +++ b/src/forge/Information/Pages/selfList.jsx @@ -18,8 +18,8 @@ function SelfList(props){ const [ visible ,setVisible ] = useState(false); const [ deleId , setDeleId] = useState(undefined); const pathname = props.location.pathname; + const { deptId} = props.match.params; const { id , temp } = props; - const { deptId } = props.match.params; const limit = 15; useEffect(()=>{ @@ -141,7 +141,7 @@ function SelfList(props){ {moment(i.createTime).format("YYYY/MM/DD")} - 编辑 + 编辑 {setVisible(true);setDeleId(i.id)}}>删除
diff --git a/src/forge/Information/Pages/source.jsx b/src/forge/Information/Pages/source.jsx index 06c22e4f..eed911c1 100644 --- a/src/forge/Information/Pages/source.jsx +++ b/src/forge/Information/Pages/source.jsx @@ -1,5 +1,5 @@ import React , { useEffect , useState } from 'react'; -import { Input , Pagination, Spin, Tag } from 'antd'; +import { Button, Input , Pagination, Spin, Tag } from 'antd'; import SourceIcon from '../img/sourceIcon.png'; import { Link } from 'react-router-dom'; import axios from 'axios'; @@ -23,8 +23,7 @@ function Source(props){ const [ search , setSearch ] = useState(undefined); const [ isSpin , setIsSpin ] = useState(true); const limit = 20; - const { id , temp } = props; - + const { id , temp, history, role } = props; useEffect(()=>{ id && getLists(); @@ -70,12 +69,20 @@ function Source(props){ setPage(1); } + function addSource(){ + if(role && role.role === "Manager"){ + window.open(role.resourceManageUrl); + }else{ + history.push(`/zone/${deptId}/source/add`) + } + } + return(

资源发布

-
- + 搜索 :undefined} /> + {role && role.role !== "None" &&
+ {role.role === "Member" && } + +
}
diff --git a/src/forge/Information/Pages/sourceCreate.jsx b/src/forge/Information/Pages/sourceCreate.jsx new file mode 100644 index 00000000..526df0e1 --- /dev/null +++ b/src/forge/Information/Pages/sourceCreate.jsx @@ -0,0 +1,235 @@ +import React,{ useState , useEffect } from 'react'; +import { Breadcrumb, Button, Form, Icon, Input, message, Select, Upload } from 'antd'; +import { getZoneUrl } from 'educoder'; +import '../index.scss'; +import { Link } from 'react-router-dom'; +import { getTypeByFileId, getSourceZoneList, addResource, getSourceDetailByAu, updateMyResource } from '../api'; + +function SourceCreate(props){ + const {history, id} = props; + const { getFieldDecorator, validateFields , setFieldsValue, setFields } = props.form; + const { deptId, sourceid} = props.match.params; + const pathname = props.location.pathname; + const [ zoneList , setZoneList ] = useState(undefined); + const [files, setFiles] = useState([]); + const [loadingBut, setLoadingBut] = useState(false); + const [isEdit, setIsEdit] = useState(false); + + const layout = { + labelCol: { span: 2 }, + wrapperCol: { span: 14 }, + }; + + useEffect(()=>{ + id && getZoneList(); + },[id]) + + useEffect(()=>{ + if(pathname){ + if(pathname.endsWith("/edit")){ + setIsEdit(true); + getSourceDetail(); + }else{ + setIsEdit(false); + } + } + },[pathname]) + + function getSourceDetail() { + getSourceDetailByAu(sourceid).then(res=>{ + if(res && res.data){ + const {name, domainId, summary, fileList} = res.data.data; + const fileMap = fileList.map(item=>{ + const {fileId, fileSizeInfo, fileOriginName, zoneResourceType: {id, name}} = item; + return { + uid: fileId, + status: "done", + response: {fileId: fileId, fileSize: fileSizeInfo}, + name: fileOriginName, + zoneResourceType:{id, name} + } + }) + setFiles(fileMap); + setFieldsValue({ + name, + domainId, + summary, + fileList: fileMap + }); + } + }) + } + + function getZoneList(){ + getSourceZoneList(id).then(response=>{ + if(response && response.data){ + setZoneList(response.data.rows); + } + }).catch(error=>{}) + } + + // 新建文章 + function submit(e){ + e.preventDefault(); + validateFields((err, fieldsValue)=>{ + if(err || !files.length){ + !files.length && setFields({fileList: {value:undefined,errors:[new Error('请上传资源附件!')]}}); + return; + } + const fileIds = files.map(item=>{return item.response.fileId}).toString(); + const params = { + ...fieldsValue, + zoneId: id, + fileIds + } + delete params.fileList; + if(isEdit){ + delete params.zoneId; + params.id= parseInt(sourceid, 10); + updateMyResource(params).then((res)=>{ + const {data:{code, msg}} = res; + if(code === 200){ + message.success("编辑成功"); + history.push(`/zone/${deptId}/source/self`); + }else{ + message.error(msg || '编辑失败,请联系管理员!') + } + }) + return; + } + addResource(params).then((res)=>{ + const {data:{code, msg}} = res; + if(code === 200){ + message.success("新增成功"); + history.push(`/zone/${deptId}/source/self`); + }else{ + message.error(msg || '新增失败,请联系管理员!') + } + }) + }) + } + + function beforeUpload(file){ + if (file.size > 200 * 1024 * 1024) { + message.error('单个文件限制200MB以内'); + return false; + } + if(files){ + const sameNameFIles = files.filter(item=>item.name === file.name); + if(sameNameFIles.length >= 1){ + message.error("请不要重复上传同名文件!"); + return false; + } + } + return true; + } + + async function onChange({file, fileList: fileListByUpload}){ + if(file && (file.status === "done" || file.status === 'uploading' || file.status === 'removed')){ + setLoadingBut(true); + const fileList = [...files]; + const index = fileList.findIndex(item=>item.uid === file.uid); + if(index !== -1){ + fileList[index] = file; + }else{ + fileList.push(file); + } + setFiles(fileList); + if(!file.response) return + if(file.response.code !== 200){ + message.error(file.response.msg || '上传失败,请联系管理员!') + fileList.pop() + setFiles([...fileList]); + setLoadingBut(false); + }else{ + // 获取此附件的资源类别 + await getTypeByFileId(id, file.response.fileId).then((res)=>{ + const {data:{code, data: data1, msg}} = res; + if(code !== 200){ + return message.error(msg); + } + fileList[fileList.length-1].zoneResourceType = { + id: data1.id, + name: data1.name + } + }) + setFiles([...fileList]); + setLoadingBut(false); + } + } + } + + function deleteFile(uid){ + const fileList = files.filter(item=>item.uid !== uid); + setFiles(fileList); + } + + return( +
+ + 资源列表 + {isEdit ? '编辑' : '新建'}资源 + +
+
+ + {getFieldDecorator("name", { + rules:[{ required:true,message:"请输入资源名称!" }, + {type: 'string', max: 200, message: "最大长度200"}] + })( + + )} + + + {getFieldDecorator("domainId", { + rules:[{ required:true,message:"请选择资源领域!" }] + })( + + )} + + + {getFieldDecorator("summary", { + rules:[{ required:true,message:"请输入资源简介!" }, + {type: 'string', max: 300, message: "最大长度300"}] + })( + + )} + + 可上传多个资源文件,单个文件限制200MB以内 }> + {getFieldDecorator("fileList", { + rules:[{ required:true,message:"请上传资源附件!" }] + })( + + + + )} + + {/* 附件展示 */} +
+ {files && files.map((item, index)=>{ + const {uid, status, response, name, zoneResourceType} = item; + return
+ {status === "uploading" ? : } + {name} + {response && response.fileSize} + {zoneResourceType && zoneResourceType.name} + {deleteFile(uid)}}/> +
+ })} +
+ + + + +
+
+
+ ) +} +export default Form.create()(SourceCreate); \ No newline at end of file diff --git a/src/forge/Information/Pages/sourceDetail.jsx b/src/forge/Information/Pages/sourceDetail.jsx index d94f8536..9b06fa4c 100644 --- a/src/forge/Information/Pages/sourceDetail.jsx +++ b/src/forge/Information/Pages/sourceDetail.jsx @@ -9,11 +9,13 @@ import { Base64 } from 'js-base64'; import { httpUrl } from '../fetch'; import { AlignCenter, FlexAJ } from '../../Component/layout'; import SourceIcon from '../img/sourceIcon.png'; +import { addMeta, setSeoMeta } from 'educoder'; function SourceDetail(props){ const { deptId , sourceid } = props.match.params; const [ detail , setDetail ] = useState(undefined); + const zonedetail = props.data; useEffect(()=>{ if(sourceid){ @@ -21,6 +23,21 @@ function SourceDetail(props){ } },[sourceid]) + useEffect(()=>{ + // 设置网页标题 + if(detail){ + const { name, domainName, summary} = detail; + document.title = `${ name }/${ domainName }`; + addMeta('Keywords', `${ name },${ domainName },${ summary }`); + } + return componentWillUnmount + }, [detail]) + + function componentWillUnmount() { + document.title= zonedetail.name; + setSeoMeta(`${zonedetail.name},`, zonedetail.name, zonedetail.subTitle, `/zone/${deptId}`) + } + function getDetails(){ getSourceDetail(sourceid).then(response=>{ if(response){ diff --git a/src/forge/Information/api.js b/src/forge/Information/api.js index 9a226ea5..2496268c 100644 --- a/src/forge/Information/api.js +++ b/src/forge/Information/api.js @@ -17,6 +17,13 @@ export function getCheckZoneRole(id) { }); } +export function getCurrentRole(id) { + return fetch({ + url: `/zone/zoneFront/${id}/checkCurrentRole`, + method: 'get', + }); +} + /********首页接口******/ export function getHomePageList(id) { return fetch({ @@ -115,6 +122,13 @@ export function applyJoin(id,data) { } // 资源模块 +export function addResource(data) { + return fetch({ + url: `/zone/zoneFront/addResource`, + method: 'post', + data: data + }); +} export function getSourceTypeList(id){ return fetch({ url:`/zone/open/${id}/resourceType/list`, @@ -158,7 +172,82 @@ export function delSourceMyList(id){ export function postCreateZone(data) { return fetch({ url: `/zone/application`, + }) +} + +// 根据文件id获取专区下资源类别 +export function getTypeByFileId(zoneId, fileId){ + return fetch({ + url:`/zone/resourceType/zone/${zoneId}/getResourceTypeByFileId/${fileId}`, + method: 'get' + }) +} + +// 新增领域 +export function addSourceType(data) { + return fetch({ + url: `/zone/resourceType`, method: 'post', data: data }); +} + +// 修改当前文件对应的资源类别 +export function updateResourceTypeByFileId(data) { + return fetch({ + url: '/zone/resourceType/updateResourceTypeByFileId', + method: 'PUT', + data: data + }); +} + +// 获取文章领域列表 +export function getDirListById(id){ + return fetch({ + url:`/cms/doc/open/zone/${id}/dirList`, + method: 'get' + }) +} + +// 新增文章 +export function addNewsByDirId(dirId, data) { + return fetch({ + url: `/cms/doc/dir/${dirId}`, + method: 'post', + data: data + }); +} + +// 获取文章详细信息(需要用户权限) +export function getNewsDetailByAu(id){ + return fetch({ + url:`/cms/doc/${id}`, + method: 'get', + }) +} + +// 修改文章详细信息(需要用户权限) +export function updateDoc(id, data) { + return fetch({ + url: `/cms/doc/${id}`, + method: 'PUT', + data: data + }); +} + +// 获取资源详细信息(需要用户权限) +export function getSourceDetailByAu(id){ + return fetch({ + url:`/zone/zoneFront/myResource/${id}`, + method: 'get', + }) +} + +// 修改资源详细信息(需要用户权限) +export function updateMyResource(data) { + return fetch({ + url: `/zone/zoneFront/editResource`, + method: 'PUT', + data: data + }); } \ No newline at end of file diff --git a/src/forge/Information/fetch.js b/src/forge/Information/fetch.js index ddb0df2b..d7491da4 100644 --- a/src/forge/Information/fetch.js +++ b/src/forge/Information/fetch.js @@ -1,5 +1,6 @@ import axios from 'axios'; import { message , notification } from 'antd'; +import cookie from 'react-cookies'; function beforeFetch(actionUrl){ if (window.location.href.indexOf('localhost') < 0) { @@ -8,6 +9,7 @@ function beforeFetch(actionUrl){ const service = axios.create({ headers:{Authorization:"0cd46d63363af9205eb7ccecff574309ce069a97"}, + // headers:{Authorization: cookie.load("autologin_trustie")}, baseURL: actionUrl, timeout: 1800000, // 请求超时时间 }); diff --git a/src/forge/Information/index.jsx b/src/forge/Information/index.jsx index 14960da6..e8b70855 100644 --- a/src/forge/Information/index.jsx +++ b/src/forge/Information/index.jsx @@ -8,7 +8,7 @@ import { CNotificationHOC } from "../../modules/courses/common/CNotificationHOC" import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC"; import Loadable from "react-loadable"; import Loading from "../../Loading"; -import { getMainInfos , getCheckZoneRole } from './api'; +import { getMainInfos , getCheckZoneRole, getCurrentRole } from './api'; import PublicBanner from "./Component/publicBanner"; import './index.scss'; import { IsPC } from 'educoder'; @@ -16,11 +16,17 @@ import "slick-carousel/slick/slick.css"; import "slick-carousel/slick/slick-theme.css"; import { tempEnum } from "./tempInfo"; import { ImageLayerOfCommentHOC } from "../../modules/page/layers/ImageLayerOfCommentHOC"; +import { setSeoMeta } from 'educoder'; + const SourceDetail = Loadable({ loader: () => import("./Pages/sourceDetail"), loading: Loading, }); +const SourceCreate = Loadable({ + loader: () => import("./Pages/sourceCreate"), + loading: Loading, +}); const VIP = Loadable({ loader: () => import("./Pages/zoneVIP"), loading: Loading, @@ -64,6 +70,10 @@ const NewsList = Loadable({ loader: () => import("./Pages/newsList"), loading: Loading, }); +const NewsCreate = Loadable({ + loader: () => import("./Pages/newsCreate"), + loading: Loading, +}); const Main = Loadable({ loader: () => import("./Pages/main"), @@ -81,8 +91,10 @@ function Index(props){ const { deptId } = props.match.params; const [ id , setId ] = useState(undefined); const [ temp , setTemp ] = useState(tempEnum.zone); + const [ role , setRole ] = useState(undefined); const { pathname } = props.history.location; const sourcedetail = pathname.indexOf(`/zone/${deptId}/newdetail/`)>-1 && IsPC(); + const {current_user} = props; useEffect(()=>{ if(deptId && deptId!=="apply"){ @@ -115,7 +127,9 @@ function Index(props){ setId(data.id); if(data.id){ getAdminUrl(data.id); + getRole(data.id) } + setSeoMeta(`${data.name},`, data.name, data.subTitle, `/zone/${deptId}`) } }).catch(console.error()) } @@ -129,6 +143,15 @@ function Index(props){ } }).catch(error=>{}) } + + function getRole(id){ + if(current_user && current_user.login){ + getCurrentRole(id).then(res=>{ + setRole(res.data.data); + }).catch(error=>{}) + } + } + return(
{ (!sourcedetail && deptId!=="apply") && (id ? :
)} @@ -139,10 +162,22 @@ function Index(props){ )} > + ( + + )} + > + ( + + )} + > ( -
+
)} > )} > + ( + + )} + > + ( + + )} + > ( - + )} > ( - + )} > ( -
+
)} > {data && data.helperShow === 1 && import("./website/mySiteList"), loading: Loading, }); +const CreateSite = Loadable({ + loader: () => import("./website/createSite"), + loading: Loading, +}); function Index(props){ const { current_user,mygetHelmetapi , checkIfLogin } = props; const { pathname } = props.location; const notice_url = mygetHelmetapi && mygetHelmetapi.common && mygetHelmetapi.common.notice; + const {id_card_verify, website_permission} = current_user; const [ avatarVisible , setAvatarVisible ] = useState(false); const [active, setActive] = useState(1); - console.log('active', active); useEffect(()=>{ if(checkIfLogin() === false){ - props.history.push('/login'); + props.history.push(`/login?go_page=${pathname}`); } },[]) useEffect(()=>{ - console.log('pathname', pathname, ["/settings/profile"].indexOf(pathname)); + const pattern = /^\/settings\/installbot\/\d+$/; if(["/settings/profile"].indexOf(pathname) !== -1){ setActive(1); }else if(["/settings/emails", "/settings/phone", "/settings/password", "/settings/cancel"].indexOf(pathname) !== -1){ @@ -100,11 +104,11 @@ function Index(props){ setActive(5); }else if(["/settings/CLA"].indexOf(pathname) !== -1){ setActive(6); - }else if(["/settings/mybot"].indexOf(pathname) !== -1){ + }else if(["/settings/mybot", "/settings/mybot/new"].indexOf(pathname) !== -1){ setActive(7); - }else if(["/settings/installbot"].indexOf(pathname) !== -1){ + }else if(["/settings/installbot"].indexOf(pathname) !== -1 || pattern.test(pathname)){ setActive(8); - }else if(["/settings/mysite"].indexOf(pathname) !== -1){ + }else if(["/settings/mysite", "/settings/mysite/create"].indexOf(pathname) !== -1){ setActive(9); } }, [pathname]) @@ -154,10 +158,10 @@ function Index(props){
  • 我的Bot
  • Bot安装
  • - {/*
      +
      • 个人建站
      • 我的站点
      • -
      */} +
    @@ -262,6 +266,13 @@ function Index(props){ )} > + {/* 创建站点 */} + {id_card_verify && website_permission && ( + + )} + >} {/* 个人建站 */} { + document.title = "创建站点"; + }, []); + + useEffect(()=>{ + axios.get(`/site_pages/themes.json`, {params: {language_frame: language}}).then(res=>{ + if(res && res.status === 200){ + setThemes(res.data.themes); + setTheme(res.data.themes[0]) + } + }) + }, [language]) + + useEffect(()=>{ + if(theme && theme.clone_url && theme && theme.clone_url.indexOf("/") > -1){ + let arr = theme && theme.clone_url.split("/"); + let first = arr[arr.length-1]; + if(first.indexOf(".") > -1){ + let second = first.split('.')[0]; + if(!second)return; + setFieldsValue({ + repository_name:second, + name:second + }) + }else{ + setFieldsValue({ + repository_name:first + }) + } + } + }, [theme]) + + function submit(e) { + e.preventDefault(); + validateFieldsAndScroll((err, values) => { + if (!err) { + axios.post(`/projects/page_migrate.json`,{ + ...values, + clone_addr: theme && theme.clone_url, + theme: theme && theme.name, + user_id: current_user.user_id + }).then(res=>{ + if(res && res.status === 200){ + message.success("新建成功"); + history.push(`/settings/mysite`); + } + }) + } + }); + } + + return ( + +
    我的站点 / 新建站点
    +
    +
    站点配置
    + + {getFieldDecorator("site_name", { + rules: [{ required: true, message: "请输入站点名称" }, + {type: 'string', max: 50, min: 1, message: "长度1-50"}], + })()} + + + {getFieldDecorator("identifier", { + rules: [{ required: true, message: "请输入站点标识" }, + {pattern: /^[a-zA-Z0-9]{2,100}$/, message: '长度2-100,只能包含数字和字母'}], + })( + { + setTag(e.target.value); + }} + placeholder="请输入站点标识" + /> + )} + + http://{current_user.login}.kingchan.cn/{tag} + + + + {getFieldDecorator("language_frame", {initialValue: 0})( + + )} + + + + {themes && themes.map(item=>{ + const {image, name, clone_url} = item; + return
    {setTheme(item)}}> + + +

    {name}

    +
    + })} +
    +
    +
    项目配置
    +
    我们会为您生成一个项目,来管理您的个人主页,请配置您的项目信息
    + + + + + {/* / 0.87 */} + + {getFieldDecorator("repository_name", { + rules: [{ required: true, message: "请输入项目标识" }, + {pattern: /^[a-zA-Z0-9][a-zA-Z0-9_.-]{2,100}[a-zA-Z0-9]$/, message: "长度2-100,只能包含数字、字母、下划线、中划线、英文句号,必须以数字和字母开头,不能以下划线/中划线/英文句号开头和结尾"}], + })( + + )} + + + + {getFieldDecorator("name", { + rules: [{ required: true, message: "请输入项目名称" }, + {type: 'string', max: 50, min: 1, message: "长度1-50"}], + })( + + )} + + + {getFieldDecorator("description", { + rules: [{type: 'string', max: 200, message: "长度200"}] + })( +