forked from Gitlink/forgeplus-react
pattern
This commit is contained in:
commit
e238f9c423
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<div style={editorBoxClass}>
|
||||
<Spin spinning={loading} tip="上传中,请耐心等待">
|
||||
<Toolbar
|
||||
editor={editor}
|
||||
defaultConfig={toolbarConfig}
|
||||
mode="default"
|
||||
style={{ borderBottom: '1px solid #ccc' }}
|
||||
/>
|
||||
<Editor
|
||||
defaultConfig={editorConfig}
|
||||
value={value}
|
||||
onCreated={setEditor}
|
||||
onChange={(editor) => setValue && setValue(editor.getHtml())}
|
||||
mode="default"
|
||||
style={{ height: '500px', overflowY: 'hidden' }}
|
||||
/>
|
||||
</Spin>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default MyEditor;
|
||||
|
|
@ -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(
|
||||
<div className="applyBox">
|
||||
|
|
@ -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,只能包含数字、字母、下划线、中划线,必须以字母开头结尾"},
|
||||
]
|
||||
})(
|
||||
<Input placeholder="请输入专区域名标识" maxLength={20} style={{height:"36px"}}/>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -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 = (
|
||||
<Menu>
|
||||
<Menu.Item>
|
||||
<a onClick={()=>{history.push(`/zone/${deptId}/news/add?type=richEditor`)}}>富文本编辑器</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<a onClick={()=>{history.push(`/zone/${deptId}/news/add?type=mdEditor`)}}>MD编辑器</a>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
|
|
@ -34,7 +45,7 @@ function Main(props){
|
|||
getMainList();
|
||||
} else {
|
||||
getCateList();
|
||||
}
|
||||
}
|
||||
getHotList();
|
||||
}
|
||||
},[id])
|
||||
|
|
@ -109,7 +120,17 @@ function Main(props){
|
|||
<div>
|
||||
<div className="main_content">
|
||||
<div className="boxmain">
|
||||
<p className="in_title">{ tempConfig[temp].mainTitle }</p>
|
||||
<div className='titleButBox'>
|
||||
<p className="in_title">{tempConfig[temp].mainTitle}</p>
|
||||
{role && role.role !== "None" && <div className='createButs'>
|
||||
{role.role === "Member" && <Button type="primary" ghost className='mr20'>
|
||||
<Link to={`/zone/${deptId}/news/self`}>我的文章</Link>
|
||||
</Button>}
|
||||
{role.role === "Member" ? <Dropdown overlay={menu}>
|
||||
<Button icon='plus' type="primary" ghost>新建</Button>
|
||||
</Dropdown> : <Button type="primary" ghost onClick={()=>{window.open(role.docManageUrl)}}>管理资讯</Button>}
|
||||
</div>}
|
||||
</div>
|
||||
{
|
||||
mainList && mainList.length>0 &&
|
||||
(
|
||||
|
|
|
|||
|
|
@ -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 === "<p><br></p>"
|
||||
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(
|
||||
<div className='boxmain pt30 newsCreateBox pb100'>
|
||||
<Breadcrumb separator=">">
|
||||
<Breadcrumb.Item href={`/zone/${deptId}/news`}>{tempConfig[temp].mainTitle}</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>{isEdit ? '编辑' : '新建'}文章</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
<div className='formBox'>
|
||||
<Form {...layout} onSubmit={submit}>
|
||||
<Form.Item label="标题">
|
||||
{getFieldDecorator("name", {
|
||||
rules:[{ required:true,message:"请输入文章标题!" },
|
||||
{type: 'string', max: 200, message: "最大长度200"},
|
||||
{pattern: /^[^<>[\]/\\]+$/, message: "不能输入特殊字符:< > [ ] / \\"}]
|
||||
})(
|
||||
<Input placeholder="请输入文章标题" maxLength={ 200 } width="220px"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="概览">
|
||||
{getFieldDecorator("summary", {
|
||||
rules:[{ required:true,message:"请输入概览!" },
|
||||
{type: 'string', max: 200, message: "最大长度200"}]
|
||||
})(
|
||||
<Input.TextArea placeholder="请输入概览" maxLength={ 200 } width="220px"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="栏目">
|
||||
{getFieldDecorator("dirId", {
|
||||
rules:[{ required:true,message:"请选择文章所属栏目!" }]
|
||||
})(
|
||||
<Select placeholder="请选择文章所属栏目">
|
||||
{dirList && dirList.map(item=>{
|
||||
return <Select.Option key={item.id} value={item.id}>{item.name}</Select.Option>
|
||||
})}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="内容" wrapperCol={{span: 21}}>
|
||||
{getFieldDecorator("content",{
|
||||
rules:[{required:true,message:"请输入内容!"}],
|
||||
})(
|
||||
type === "richEditor" ? <RichEditor uploadUrl={`${httpUrl}/file/common/upload`} videoUploadUrl={`${httpUrl}/file/common/upload?type=cms`} setValue={(value)=>{setFieldsValue({"content": value})}}/> : <MdEditor
|
||||
placeholder={"请输入详细介绍"}
|
||||
height={500}
|
||||
mdID={"order-new-description"}
|
||||
initValue={value}
|
||||
onChange={(value)=>{setFieldsValue({"content": value})}}
|
||||
imageExpand={false}
|
||||
></MdEditor>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="首图" extra="建议图片比例,长:宽为3:2,上传jpg、jpeg、webp、png、svg、gif、bmp格式的图片">
|
||||
<UploadImage maxSize={ 5 } getImageUrl={ (url) => setImageUrl(url) } url={ imageUrl ? imageUrl : undefined} action={ getZoneUrl(`/api/cms/common/upload`) } />
|
||||
</Form.Item>
|
||||
<Form.Item wrapperCol={{ offset: 2 }}>
|
||||
<Button className='mr20 themeBut' onClick={()=>{history.go(-1)}}>取消</Button>
|
||||
<Button type="primary" htmlType="submit" loading={loading} className='themeBut'>提交</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Form.create()(NewsCreate);
|
||||
|
|
@ -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=>{
|
||||
|
|
|
|||
|
|
@ -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){
|
|||
<span><i className="iconfont icon-a-31shijian mr5 font-15"></i>{moment(i.createTime).format("YYYY/MM/DD")}</span>
|
||||
</span>
|
||||
<span className="s-info-right">
|
||||
<a href="" style={{color:"#466aff"}}><i className="iconfont icon-a-bianji12 mr5 font-14"></i>编辑</a>
|
||||
<a href={`/zone/${deptId}/${source ? 'source' : 'news'}/${i.id}/edit`} style={{color:"#466aff"}}><i className="iconfont icon-a-bianji12 mr5 font-14"></i>编辑</a>
|
||||
<a style={{color:"#d81017",marginLeft:"25px"}}onClick={()=>{setVisible(true);setDeleId(i.id)}}><i className="iconfont icon-fuzhi-shanchu mr5 font-14"></i>删除</a>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
<div className={`${temp}_source_box`}>
|
||||
<div className="source_h">
|
||||
<p className="in_title">资源发布</p>
|
||||
<div style={{marginTop:"30px",textAlign:"center"}}>
|
||||
<Search
|
||||
<div style={{marginTop:"30px",textAlign:"center"}} className='titleButBox'>
|
||||
<Search
|
||||
placeholder="请输入资源名称"
|
||||
onSearch={onSourceSearch}
|
||||
style={{width:'645px',borderColor:"#fff",boxShadow:"0px 0px 10px rgba(61, 85, 183, 0.1)"}}
|
||||
|
|
@ -84,6 +91,12 @@ function Source(props){
|
|||
allowClear
|
||||
enterButton={temp === "zone" ? <span><i className="iconfont icon-sousuo5 font-15"/>搜索</span> :undefined}
|
||||
/>
|
||||
{role && role.role !== "None" && <div className='createButs'>
|
||||
{role.role === "Member" && <Button size='large' type="primary" ghost className='mr20'>
|
||||
<Link to={`/zone/${deptId}/source/self`}>我的资源</Link>
|
||||
</Button>}
|
||||
<Button size='large' icon={role.role === "Member" && 'plus'} type="primary" ghost onClick={addSource}>{role.role === "Member" ? '新建' : '管理资源'}</Button>
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
<div className="sources">
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
<div className='boxmain pt30 newsCreateBox pb100 sourceCreateBox'>
|
||||
<Breadcrumb separator=">">
|
||||
<Breadcrumb.Item><Link className="primaryColor" to={`/zone/${deptId}/source`}>资源列表</Link></Breadcrumb.Item>
|
||||
<Breadcrumb.Item>{isEdit ? '编辑' : '新建'}资源</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
<div className='formBox'>
|
||||
<Form {...layout} onSubmit={submit}>
|
||||
<Form.Item label="资源名称">
|
||||
{getFieldDecorator("name", {
|
||||
rules:[{ required:true,message:"请输入资源名称!" },
|
||||
{type: 'string', max: 200, message: "最大长度200"}]
|
||||
})(
|
||||
<Input placeholder="请输入资源名称" maxLength={ 200 } width="220px"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="资源领域">
|
||||
{getFieldDecorator("domainId", {
|
||||
rules:[{ required:true,message:"请选择资源领域!" }]
|
||||
})(
|
||||
<Select placeholder="请选择资源领域">
|
||||
{zoneList && zoneList.map(item =>{
|
||||
return <Select.Option key={item.id} value={item.id}>{item.name}</Select.Option>
|
||||
})}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="资源简介">
|
||||
{getFieldDecorator("summary", {
|
||||
rules:[{ required:true,message:"请输入资源简介!" },
|
||||
{type: 'string', max: 300, message: "最大长度300"}]
|
||||
})(
|
||||
<Input.TextArea placeholder="请输入资源简介" maxLength={ 200 } width="220px"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="资源附件" extra={ <span >可上传多个资源文件,单个文件限制200MB以内</span> }>
|
||||
{getFieldDecorator("fileList", {
|
||||
rules:[{ required:true,message:"请上传资源附件!" }]
|
||||
})(
|
||||
<Upload action={getZoneUrl(`/api/file/common/upload?type=resource`)} showUploadList={false} beforeUpload={beforeUpload} onChange={onChange} withCredentials={true}>
|
||||
<Button>
|
||||
<Icon type="upload" />单击上传
|
||||
</Button>
|
||||
</Upload>
|
||||
)}
|
||||
</Form.Item>
|
||||
{/* 附件展示 */}
|
||||
<div className="sourceFilesBox">
|
||||
{files && files.map((item, index)=>{
|
||||
const {uid, status, response, name, zoneResourceType} = item;
|
||||
return <div key={index} className="sourseFileItem mb15">
|
||||
{status === "uploading" ? <Icon type="loading" className='mr10'/> : <Icon type="file" className='mr10'/>}
|
||||
<span className="fileName task-hide">{name}</span>
|
||||
<span className='mr20 ml20' style={{width: '100px'}}>{response && response.fileSize}</span>
|
||||
<span className='mr50'>{zoneResourceType && zoneResourceType.name}</span>
|
||||
<Icon type="delete" onClick={()=>{deleteFile(uid)}}/>
|
||||
</div>
|
||||
})}
|
||||
</div>
|
||||
<Form.Item wrapperCol={{ offset: 2 }}>
|
||||
<Button className='mr20 themeBut' onClick={()=>{history.go(-1)}}>取消</Button>
|
||||
<Button type="primary" htmlType="submit" loading={loadingBut} className='themeBut'>提交</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Form.create()(SourceCreate);
|
||||
|
|
@ -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){
|
||||
|
|
|
|||
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
|
@ -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, // 请求超时时间
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
<div className="information_main">
|
||||
{ (!sourcedetail && deptId!=="apply") && (id ? <PublicBanner {...props} data={data} temp={ temp } adminUrl={adminUrl}/> : <div style={{ width: '100%', height: '450px' }}></div>)}
|
||||
|
|
@ -139,10 +162,22 @@ function Index(props){
|
|||
<SourceSelfList {...props} {...p} id={id} temp={ temp }/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/zone/:deptId/news/add"
|
||||
render={(p) => (
|
||||
<NewsCreate {...props} {...p} id={id} temp={ temp } data={data}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/zone/:deptId/news/:id/edit"
|
||||
render={(p) => (
|
||||
<NewsCreate {...props} {...p} id={id} temp={ temp } data={data}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/zone/:deptId/news/:cateId"
|
||||
render={(p) => (
|
||||
<Main {...props} {...p} id={id} temp={ temp }/>
|
||||
<Main {...props} {...p} id={id} temp={ temp } role={role}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
|
|
@ -157,16 +192,28 @@ function Index(props){
|
|||
<SourceSelfList {...props} {...p} id={id} temp={ temp }/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/zone/:deptId/source/add"
|
||||
render={(p) => (
|
||||
<SourceCreate {...props} {...p} id={id} temp={ temp } data={data}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/zone/:deptId/source/:sourceid/edit"
|
||||
render={(p) => (
|
||||
<SourceCreate {...props} {...p} id={id} temp={ temp }/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/zone/:deptId/source/:sourceid"
|
||||
render={(p) => (
|
||||
<SourceDetail {...props} {...p} id={id} temp={ temp }/>
|
||||
<SourceDetail {...props} {...p} id={id} temp={ temp } data={data}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/zone/:deptId/source"
|
||||
render={(p) => (
|
||||
<Source {...props} {...p} id={id} temp={ temp }/>
|
||||
<Source {...props} {...p} id={id} temp={ temp } role={role}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
|
|
@ -184,7 +231,7 @@ function Index(props){
|
|||
<Route
|
||||
path="/zone/:deptId/news"
|
||||
render={(p) => (
|
||||
<Main {...props} {...p} id={id} temp={ temp }/>
|
||||
<Main {...props} {...p} id={id} temp={ temp } role={role}/>
|
||||
)}
|
||||
></Route>
|
||||
{data && data.helperShow === 1 && <Route
|
||||
|
|
|
|||
|
|
@ -15,6 +15,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
// 公共样式
|
||||
.themeBut{
|
||||
border-color: var(--primary-color);
|
||||
color: var(--primary-color);
|
||||
&:hover, &:active, &:focus{
|
||||
border-color: var(--light-color);
|
||||
color: var(--light-color);
|
||||
}
|
||||
&.ant-btn-primary{
|
||||
color: white;
|
||||
background-color: var(--primary-color);
|
||||
}
|
||||
}
|
||||
|
||||
.information_main{
|
||||
background-color:#f3f5f8;
|
||||
min-height: 100vh;
|
||||
|
|
@ -1521,6 +1535,47 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
// 新增文章/资源
|
||||
.titleButBox{
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
.createButs{
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
button{
|
||||
border-color: var(--primary-color);
|
||||
color: var(--primary-color);
|
||||
&:hover{
|
||||
border-color: var(--light-color);
|
||||
color: var(--light-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 新增文章
|
||||
.newsCreateBox{
|
||||
.formBox{
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
padding: 30px 35px 50px;
|
||||
}
|
||||
}
|
||||
// 新增资源
|
||||
.sourceCreateBox{
|
||||
.sourceFilesBox{
|
||||
margin-left: 93px;
|
||||
}
|
||||
.sourseFileItem{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.fileName{
|
||||
max-width: 400px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
.primaryColor{
|
||||
color: var(--primary-color)!important;
|
||||
}
|
||||
|
|
@ -1667,4 +1722,4 @@
|
|||
margin:0px 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,24 +70,28 @@ const Mysite = Loadable({
|
|||
loader: () => 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){
|
|||
<li className={active === 7 ?"active":""}><Link to={`/settings/mybot`}><i className="iconfont icon-kaifabot mr5 font-18"></i><span className="text-shodow-bold">我的Bot</span></Link></li>
|
||||
<li className={active === 8 ?"active":""}><Link to={`/settings/installbot`}><i className="iconfont icon-BOTpeizhi mr5 font-17"></i><span className="text-shodow-bold">Bot安装</span></Link></li>
|
||||
</ul>
|
||||
{/* <ul className="securityUl">
|
||||
<ul className="securityUl">
|
||||
<li>个人建站</li>
|
||||
<li className={active === 9 ?"active":""}><Link to={`/settings/mysite`}><i className="iconfont icon-liebiaoicon mr5 font-15"></i><span className="text-shodow-bold">我的站点</span></Link></li>
|
||||
</ul> */}
|
||||
</ul>
|
||||
</div>
|
||||
<LongWidth>
|
||||
<Gap>
|
||||
|
|
@ -262,6 +266,13 @@ function Index(props){
|
|||
<Disposition {...props} {...p}/>
|
||||
)}
|
||||
></Route>
|
||||
{/* 创建站点 */}
|
||||
{id_card_verify && website_permission && <Route
|
||||
path="/settings/mysite/create"
|
||||
render={(p) => (
|
||||
<CreateSite {...props} {...p}/>
|
||||
)}
|
||||
></Route>}
|
||||
{/* 个人建站 */}
|
||||
<Route
|
||||
path="/settings/mysite"
|
||||
|
|
|
|||
|
|
@ -111,4 +111,9 @@
|
|||
border-color: rgba(230, 126, 34, 1);
|
||||
color: rgba(230, 126, 34, 1);
|
||||
}
|
||||
&.error{
|
||||
background-color: #fcbabe47;
|
||||
border-color: #f60011;
|
||||
color: #f60011;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
import React, { useState, useEffect, Fragment } from "react";
|
||||
import { Button, message, Form, Input, Select } from "antd";
|
||||
import "./index.scss";
|
||||
import "../../users/Material/Index.scss";
|
||||
import axios from "axios";
|
||||
import { AlignCenter, AlignTop } from "../../Component/layout";
|
||||
import { Link } from "react-router-dom";
|
||||
import { getImageUrl } from "../../../common/UrlTool";
|
||||
const { TextArea } = Input;
|
||||
|
||||
function CreateSite(props) {
|
||||
const { current_user, history, form } = props;
|
||||
const { getFieldDecorator, validateFieldsAndScroll, setFieldsValue } = form;
|
||||
const [tag, setTag] = useState(undefined);
|
||||
const [language, setLanguage] = useState(undefined);
|
||||
const [themes, setThemes] = useState([]);
|
||||
const [theme, setTheme] = useState(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
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 (
|
||||
<Fragment>
|
||||
<div className="mySites_head mb30"><Link to={`/settings/mysite`} className="font-16">我的站点 / </Link><span>新建站点</span></div>
|
||||
<Form
|
||||
form={form}
|
||||
name="register"
|
||||
className="createSiteForm"
|
||||
scrollToFirstError
|
||||
layout="horizontal"
|
||||
labelCol={{ span: 3 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
onSubmit={submit}
|
||||
>
|
||||
<div className="formTitle font-16 mb20 ml20">站点配置</div>
|
||||
<Form.Item name="站点名称" label="站点名称">
|
||||
{getFieldDecorator("site_name", {
|
||||
rules: [{ required: true, message: "请输入站点名称" },
|
||||
{type: 'string', max: 50, min: 1, message: "长度1-50"}],
|
||||
})(<Input placeholder="请输入站点名称" />)}
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="站点标识"
|
||||
label="站点标识"
|
||||
className="Create-Form-biaoshi"
|
||||
>
|
||||
{getFieldDecorator("identifier", {
|
||||
rules: [{ required: true, message: "请输入站点标识" },
|
||||
{pattern: /^[a-zA-Z0-9]{2,100}$/, message: '长度2-100,只能包含数字和字母'}],
|
||||
})(
|
||||
<Input
|
||||
onChange={(e) => {
|
||||
setTag(e.target.value);
|
||||
}}
|
||||
placeholder="请输入站点标识"
|
||||
/>
|
||||
)}
|
||||
<span style={{wordBreak: 'break-all'}}>
|
||||
http://{current_user.login}.kingchan.cn/{tag}
|
||||
</span>
|
||||
</Form.Item>
|
||||
<Form.Item name="建站工具" label="建站工具">
|
||||
{getFieldDecorator("language_frame", {initialValue: 0})(
|
||||
<Select style={{ width: 100 }} onChange={(value)=>{setLanguage(value)}}>
|
||||
<Select.Option value={0}>hugo</Select.Option>
|
||||
<Select.Option value={1}>jekyll</Select.Option>
|
||||
<Select.Option value={2}>hexo</Select.Option>
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item name="主题选择" label="主题选择" wrapperCol={{span: 20}}>
|
||||
<AlignTop style={{flexWrap: 'wrap'}}>
|
||||
{themes && themes.map(item=>{
|
||||
const {image, name, clone_url} = item;
|
||||
return <div className="mr20 themeBox" onClick={()=>{setTheme(item)}}>
|
||||
<i className={`iconfont icon-wancheng ${theme && theme.clone_url === clone_url ? 'active' : ''}`}></i>
|
||||
<img src={getImageUrl(image)} alt="" width="125px" height="85px"/>
|
||||
<p className="task-hide" style={{maxWidth: '120px'}}>{name}</p>
|
||||
</div>
|
||||
})}
|
||||
</AlignTop>
|
||||
</Form.Item>
|
||||
<div className="formTitle font-16 mb20 ml20">项目配置</div>
|
||||
<div className="font-15 mb20 ml40">我们会为您生成一个项目,来管理您的个人主页,请配置您的项目信息</div>
|
||||
<AlignCenter style={{marginLeft: '58px'}}>
|
||||
<Form.Item name="拥有者" label="拥有者" style={{width: '260px'}} labelCol={{span: 6}}>
|
||||
<Input
|
||||
placeholder={current_user.username}
|
||||
disabled
|
||||
/>
|
||||
</Form.Item>
|
||||
{/* <span className="mb20 font-18">/</span> 0.87 */}
|
||||
<Form.Item name="项目标识" label="项目标识" style={{flex: '0.83'}} labelCol={{span: 4}}>
|
||||
{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,只能包含数字、字母、下划线、中划线、英文句号,必须以数字和字母开头,不能以下划线/中划线/英文句号开头和结尾"}],
|
||||
})(
|
||||
<Input placeholder="请输入项目标识"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</AlignCenter>
|
||||
<Form.Item
|
||||
name="项目名称"
|
||||
label="项目名称"
|
||||
>
|
||||
{getFieldDecorator("name", {
|
||||
rules: [{ required: true, message: "请输入项目名称" },
|
||||
{type: 'string', max: 50, min: 1, message: "长度1-50"}],
|
||||
})(
|
||||
<Input placeholder="请输入项目名称"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item name="项目简介" label="项目简介">
|
||||
{getFieldDecorator("description", {
|
||||
rules: [{type: 'string', max: 200, message: "长度200"}]
|
||||
})(
|
||||
<TextArea rows={4} />
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item style={{marginLeft: '123px'}} className="mt40">
|
||||
<Button type="primary" htmlType="submit" className="mr20">
|
||||
创建站点
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
history.push("/settings/mysite");
|
||||
}}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
export default Form.create()(CreateSite);
|
||||
|
|
@ -1,8 +1,33 @@
|
|||
.default_head{
|
||||
.mySites_head{
|
||||
height: 65px;
|
||||
line-height: 64px;
|
||||
border-bottom: 1px solid rgba(224, 230, 245, 1);
|
||||
color:#151d40;
|
||||
font-size:17px;
|
||||
padding-bottom:20px;
|
||||
}
|
||||
.createSiteForm{
|
||||
.themeBox{
|
||||
text-align: center;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-wancheng{
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: -7px;
|
||||
color: #e5e3e0;
|
||||
&.active{
|
||||
color: #ffa13a;
|
||||
}
|
||||
}
|
||||
}
|
||||
.siteBox{
|
||||
padding: 15px 0;
|
||||
border-bottom: 1px dashed #e0e6f5;
|
||||
.siteName{
|
||||
color: #05101a;
|
||||
&:active, &:hover{
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,88 @@
|
|||
import React, { useState, useEffect, Fragment } from "react";
|
||||
import { Button, Icon, message, Modal } from "antd";
|
||||
import { Button, Pagination, Spin } from "antd";
|
||||
import './index.scss';
|
||||
import '../../users/Material/Index.scss';
|
||||
import '../bot/exploit/index.scss'
|
||||
import axios from "axios";
|
||||
import Nodata from "../../Nodata";
|
||||
import { FlexAJ } from "../../Component/layout";
|
||||
|
||||
function MySiteList(props){
|
||||
const {current_user} = props;
|
||||
const {current_user, history} = props;
|
||||
const {id_card_verify, website_permission} = current_user;
|
||||
const [total, setTotal] = useState(0);
|
||||
const [pages, setPages] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
|
||||
useEffect(()=>{
|
||||
document.title='我的站点';
|
||||
window.scrollTo(0,0);
|
||||
}, [])
|
||||
|
||||
return <Fragment>
|
||||
<div className="default_head">我的站点</div>
|
||||
</Fragment>
|
||||
useEffect(()=>{
|
||||
if(id_card_verify){
|
||||
setLoading(true);
|
||||
// 获取站点列表
|
||||
axios.get(`/site_pages.json`, {params: {limit: 15, page: page}}).then(res=>{
|
||||
if(res && res.status === 200){
|
||||
const {total_count, pages} = res.data;
|
||||
setPages(pages);
|
||||
setTotal(total_count);
|
||||
}
|
||||
setLoading(false);
|
||||
})
|
||||
}
|
||||
}, [id_card_verify, page])
|
||||
|
||||
return <Spin spinning={loading}>
|
||||
<FlexAJ className="mySites_head">
|
||||
<span>我的站点</span>
|
||||
{id_card_verify && website_permission && <Button type="primary" onClick={()=>{history.push(`/settings/mysite/create`)}}>新建站点</Button>}
|
||||
</FlexAJ>
|
||||
{/* 站点权限被管理员关闭 */}
|
||||
{id_card_verify && !website_permission && <div className="tipsBox font-15 mt20">您的站点权限被锁定,请联系平台管理员。</div>}
|
||||
{/* 未通过实名认证 */}
|
||||
{!id_card_verify && <Fragment>
|
||||
<div className="tipsBox font-15 mt30">您尚未通过实名认证,无法使用此服务,如需使用,请先进行实名认证。</div>
|
||||
<Button type="primary" className="mt20" onClick={()=>{history.push(`/settings/verification`)}}>前往验证</Button>
|
||||
</Fragment>}
|
||||
|
||||
{/* 通过实名认证 */}
|
||||
{id_card_verify && <Fragment>
|
||||
{!loading && total === 0 ? <div className="mt30">
|
||||
<div style={{marginBottom: '130px'}}>个人建站是一个免费的静态网页托管服务,您可以使用 个人建站服务托管个人主页、项目站点等静态网页。</div>
|
||||
<Nodata _html="暂无数据"/>
|
||||
</div> : <div className="mt10">
|
||||
{pages && pages.map(item=>{
|
||||
const {owner, repo, url, state, state_description, build_state} = item
|
||||
return <FlexAJ>
|
||||
<div className="siteBox">
|
||||
<i className="iconfont icon-cangkuyuyanicon font-16 mr5 color-grey-6"></i>
|
||||
{state && build_state ? <a className={`font-16 siteName`} onClick={()=>{window.open(url)}}>{item.site_name}</a> : <span className={`font-16`}>{item.site_name}</span>}
|
||||
<span className={`statusBot ml20 font-12 ${state ? build_state ? "public" : "private" : "error"}`}>{state ? build_state ? "已部署" : "未部署" : '被关闭'}</span>
|
||||
<div className="color-grey-6 mt8">
|
||||
<span className="">主题:</span> {item.theme}
|
||||
<span className="ml5 mr5 color-grey-ccc">|</span>
|
||||
建站工具:{item.language_frame}
|
||||
</div>
|
||||
{!state && <div className="color-grey-6 mt5">关闭原因:{state_description}</div>}
|
||||
</div>
|
||||
<Button className="themeCorBorBut" onClick={()=>{history.push(`/${owner}/${repo}/service/pages`)}}>去仓库</Button>
|
||||
</FlexAJ>
|
||||
})}
|
||||
<div className="mt50" style={{textAlign: 'center'}}>
|
||||
<Pagination
|
||||
simple
|
||||
current = {page}
|
||||
pageSize={15}
|
||||
onChange={(page)=>{setPage(page)}}
|
||||
total = {total}
|
||||
hideOnSinglePage
|
||||
></Pagination>
|
||||
</div>
|
||||
</div>}
|
||||
</Fragment>}
|
||||
</Spin>
|
||||
}
|
||||
export default MySiteList;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
import "./index.scss";
|
||||
import Loadable from 'react-loadable';
|
||||
|
|
@ -18,7 +18,22 @@ const Reposyncer = Loadable({
|
|||
loader: () => import('./reposyncer'),
|
||||
loading: Loading,
|
||||
})
|
||||
// 个人建站服务
|
||||
const Pages = Loadable({
|
||||
loader: () => import('./pages'),
|
||||
loading: Loading,
|
||||
})
|
||||
function ServerIndex(props){
|
||||
const { projectDetail } = props;
|
||||
const { owner , projectsId } = props.match.params;
|
||||
|
||||
useEffect(()=>{
|
||||
// 非项目协作者不可进入服务tab (3397)
|
||||
if(projectDetail && projectDetail.permission === ""){
|
||||
props.history.push(`/${owner}/${projectsId}`);
|
||||
}
|
||||
}, [projectDetail])
|
||||
|
||||
return(
|
||||
<div className="panels">
|
||||
<Switch {...props}>
|
||||
|
|
@ -32,6 +47,12 @@ function ServerIndex(props){
|
|||
() => (<Data {...props}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 个人建站服务 */}
|
||||
{projectDetail && projectDetail.author.type === "User" && <Route path="/:owner/:projectsId/service/pages"
|
||||
render={
|
||||
() => (<Pages {...props}/>)
|
||||
}
|
||||
></Route>}
|
||||
<Route path="/:owner/:projectsId/service"
|
||||
render={
|
||||
() => (<List {...props}/>)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ function Main(props){
|
|||
const { owner , projectsId } = props.match.params;
|
||||
const [ has_trace_user , setHas_trace_user ] = useState(false);
|
||||
|
||||
const { current_user , resetUserInfo, projectDetail, showNotification } = props;
|
||||
const { current_user , resetUserInfo, projectDetail, showNotification, isDeveloper, isManager, isReporter } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
// 更新网页标题
|
||||
|
|
@ -64,6 +64,16 @@ function Main(props){
|
|||
<Link to={`/${owner}/${projectsId}/service/reposyncer`} className="btnhover">查看详情</Link>
|
||||
</span>
|
||||
</li> */}
|
||||
{projectDetail && projectDetail.author.type === "User" && <li>
|
||||
<span className="servername">
|
||||
<img src={require('./img/logo.png')} alt=""/>
|
||||
<a onClick={openDetail}>个人建站服务</a>
|
||||
</span>
|
||||
<p className="task-hide-2 serverdesc">支持Hugo、Jekyll、Hexo静态网站服务</p>
|
||||
<span className="serverbtn">
|
||||
<Link to={`/${owner}/${projectsId}/service/pages`} className="btnhover">查看详情</Link>
|
||||
</span>
|
||||
</li>}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,207 @@
|
|||
import React, { Fragment, useEffect, useState } from 'react';
|
||||
import { Spin, message, Button, Form, Input, Select, Descriptions, Alert } from 'antd';
|
||||
import axios from 'axios';
|
||||
import SelectBranch from '../../../forge/Branch/Select';
|
||||
import './index.scss';
|
||||
|
||||
function Pages(props) {
|
||||
const {current_user, history, form, projectDetail, defaultBranch, isManager} = props;
|
||||
const { owner , projectsId } = props.match.params;
|
||||
const {id_card_verify} = current_user;
|
||||
const { getFieldDecorator, validateFieldsAndScroll } = form;
|
||||
const [reload, setReload] = useState(undefined);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [pageInfo, setPageInfo] = useState(undefined);
|
||||
const [tag, setTag] = useState(undefined);
|
||||
const [branch, setBranch ] = useState(null);
|
||||
const [building, setBuilding] = useState(false);
|
||||
const [isBuild, setIsBuild] = useState(false);
|
||||
const [result, setResult] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
// 更新网页标题
|
||||
if(projectDetail){
|
||||
const { author, name} = projectDetail;
|
||||
document.title = `个人建站-${author.name}/${name}`;
|
||||
}
|
||||
}, [projectDetail])
|
||||
|
||||
useEffect(()=>{
|
||||
if(id_card_verify){
|
||||
setLoading(true);
|
||||
// 获取站点列表
|
||||
axios.get(`/site_pages/x.json`, {params:{owner, repo: projectsId}}).then(res=>{
|
||||
if(res && res.status === 200){
|
||||
const {last_build_info} = res.data.data
|
||||
setPageInfo(res.data.data);
|
||||
last_build_info && last_build_info.length && setResult(last_build_info);
|
||||
}
|
||||
setLoading(false);
|
||||
})
|
||||
}
|
||||
}, [id_card_verify, reload])
|
||||
|
||||
// 基于仓库创建站点
|
||||
function submit(e) {
|
||||
e.preventDefault();
|
||||
validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
axios.post(`/site_pages.json`,{
|
||||
...values,
|
||||
owner,
|
||||
repo: projectsId
|
||||
}).then(res=>{
|
||||
if(res && res.status === 200){
|
||||
setReload(Math.random());
|
||||
message.success("创建成功");
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 部署
|
||||
function startBuild(){
|
||||
setBuilding(true);
|
||||
axios.post(`/site_pages/${pageInfo.id}/build.json`,{
|
||||
owner,
|
||||
repo: projectsId,
|
||||
branch: branch || defaultBranch
|
||||
}).then(res=>{
|
||||
if(res && res.data && res.data.status === 0){
|
||||
setResult(res.data.data);
|
||||
}else{
|
||||
message.error((res && res.data && res.data.message) || "部署失败,请稍后重试");
|
||||
}
|
||||
setReload(Math.random());
|
||||
setIsBuild(false);
|
||||
setBuilding(false);
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='mb100'>
|
||||
<div className="servertitle">
|
||||
<span className="systitle">个人建站服务{!pageInfo && !loading && id_card_verify && isManager && ' - 新建站点'}</span>
|
||||
</div>
|
||||
{/* 未通过实名认证 */}
|
||||
{!id_card_verify && <Fragment>
|
||||
<div className="tipsBox font-15 mt30">您尚未通过实名认证,无法使用此服务,如需使用,请先进行实名认证。</div>
|
||||
<Button type="primary" className="mt20" onClick={()=>{history.push(`/settings/verification`)}}>前往验证</Button>
|
||||
</Fragment>}
|
||||
{id_card_verify && isManager && <Spin spinning={loading}>
|
||||
{/* 未开通 */}
|
||||
{!pageInfo ? <Form
|
||||
form={form}
|
||||
name="register"
|
||||
className="mt30"
|
||||
scrollToFirstError
|
||||
layout="horizontal"
|
||||
labelCol={{ span: 2 }}
|
||||
wrapperCol={{ span: 14 }}
|
||||
onSubmit={submit}
|
||||
>
|
||||
<Form.Item name="站点名称" label="站点名称">
|
||||
{getFieldDecorator("site_name", {
|
||||
rules: [{ required: true, message: "请输入站点名称" },
|
||||
{type: 'string', max: 50, min: 1, message: "长度1-50"}],
|
||||
})(<Input placeholder="请输入站点名称" />)}
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="站点标识"
|
||||
label="站点标识"
|
||||
className="Create-Form-biaoshi"
|
||||
>
|
||||
{getFieldDecorator("identifier", {
|
||||
rules: [{ required: true, message: "请输入站点标识" },
|
||||
{pattern: /^[a-zA-Z0-9]{2,100}$/, message: '长度2-100,只能包含数字和字母'}],
|
||||
})(
|
||||
<Input
|
||||
onChange={(e) => {
|
||||
setTag(e.target.value);
|
||||
}}
|
||||
placeholder="请输入站点标识"
|
||||
/>
|
||||
)}
|
||||
<span style={{wordBreak: 'break-all'}}>
|
||||
http://{current_user.login}.kingchan.cn/{tag}
|
||||
</span>
|
||||
</Form.Item>
|
||||
<Form.Item name="建站工具" label="建站工具">
|
||||
{getFieldDecorator("language_frame", {initialValue: 0})(
|
||||
<Select style={{ width: 100 }}>
|
||||
<Select.Option value={0}>hugo</Select.Option>
|
||||
<Select.Option value={1}>jekyll</Select.Option>
|
||||
<Select.Option value={2}>hexo</Select.Option>
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item style={{marginLeft: '100px'}} className="mt40">
|
||||
<Button type="primary" htmlType="submit" className="mr20">
|
||||
创建站点
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
history.push(`/${owner}/${projectsId}/service`);
|
||||
}}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form> : pageInfo.state ? <div className='mt30'>
|
||||
{/* 已开通 */}
|
||||
<Descriptions title="站点信息">
|
||||
<Descriptions.Item label="站点名称">
|
||||
<span onClick={()=>{pageInfo.last_build_at && window.open(pageInfo.url)}} className= {pageInfo.last_build_at && 'theme-btn'}>{pageInfo.site_name}</span>
|
||||
<span className={`pageStateBox ml20 font-12 ${pageInfo.build_state ? "public" : "private"}`}>{pageInfo.build_state === null ? '未部署' : pageInfo.build_state ? "已部署" : "部署失败"}</span>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="网站地址" span={2}><span onClick={()=>{pageInfo.last_build_at && window.open(pageInfo.url)}} className= {pageInfo.last_build_at && 'theme-btn'}>{pageInfo.url}</span></Descriptions.Item>
|
||||
<Descriptions.Item label="建站工具">{pageInfo.language_frame}</Descriptions.Item>
|
||||
<Descriptions.Item label="建站时间">{pageInfo.created_at}</Descriptions.Item>
|
||||
{pageInfo.last_build_at && <Descriptions.Item label="上次部署时间">{pageInfo.last_build_at}</Descriptions.Item>}
|
||||
</Descriptions>
|
||||
{!isBuild && <Button type='primary' style={{width: '135px', height: '34px'}} className='mt20' onClick={()=>{setIsBuild(true)}}>去部署</Button>}
|
||||
{isBuild && <div>
|
||||
<div className='mt20 ant-descriptions-title'>部署</div>
|
||||
<div style={{display: 'inline-flex'}}>
|
||||
<span>部署分支:</span>
|
||||
<SelectBranch
|
||||
repo_id={projectDetail && projectDetail.repo_id}
|
||||
projectsId={projectsId}
|
||||
branch={branch || defaultBranch}
|
||||
changeBranch={(params)=>{setBranch(params)}}
|
||||
owner={owner}
|
||||
history={props.history}
|
||||
tagflag={false}
|
||||
branchList={projectDetail && projectDetail.branches && projectDetail.branches.list}
|
||||
></SelectBranch>
|
||||
<span className='color-grey-6 ml30'>选择您要部署的分支</span>
|
||||
</div>
|
||||
<div className='mt20'>
|
||||
<Button type='primary' loading={building} onClick={startBuild}>确定</Button>
|
||||
<Button type='primary' ghost onClick={()=>{setIsBuild(false)}} className='ml30'>取消</Button>
|
||||
</div>
|
||||
</div>}
|
||||
</div> : <div className='mt30'>
|
||||
{/* 站点权限被关闭 */}
|
||||
{pageInfo && <Alert type="error" message={`您的个人站点 ${pageInfo.site_name} 已被关闭,关闭原因为:${pageInfo.state_description}`}></Alert>}
|
||||
</div>}
|
||||
{result && <div className='mt30'>
|
||||
<div className='mt20 ant-descriptions-title'>部署结果</div>
|
||||
<div className='buildResult'>{result.map(item=> <p>{item}</p>)}</div>
|
||||
</div>}
|
||||
</Spin>}
|
||||
{!isManager && <div className='mt30'>
|
||||
{/* 非管理员权限 */}
|
||||
{pageInfo && pageInfo.state && <Descriptions title="站点信息">
|
||||
<Descriptions.Item label="站点名称"><span onClick={()=>{pageInfo.last_build_at && window.open(pageInfo.url)}} className= {pageInfo.last_build_at && 'theme-btn'}>{pageInfo.site_name}</span></Descriptions.Item>
|
||||
<Descriptions.Item label="网站地址" span={2}><span onClick={()=>{pageInfo.last_build_at && window.open(pageInfo.url)}} className= {pageInfo.last_build_at && 'theme-btn'}>{pageInfo.url}</span></Descriptions.Item>
|
||||
<Descriptions.Item label="建站工具">{pageInfo.language_frame}</Descriptions.Item>
|
||||
<Descriptions.Item label="建站时间">{pageInfo.created_at}</Descriptions.Item>
|
||||
{pageInfo.last_build_at && <Descriptions.Item label="上次部署时间">{pageInfo.last_build_at}</Descriptions.Item>}
|
||||
</Descriptions>}
|
||||
</div>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Form.create()(Pages);
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
.buildResult{
|
||||
padding: 10px 20px;
|
||||
background-color: rgb(20, 20, 20);
|
||||
color: white;
|
||||
}
|
||||
.theme-btn{
|
||||
color: $primary-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
.pageStateBox{
|
||||
border: 1px solid $primary-color;
|
||||
border-radius: 5px;
|
||||
color: $primary-color;
|
||||
padding: 4px 6px 4px;
|
||||
background-color: rgba(70, 106, 255, 0.09);
|
||||
line-height: 12px;
|
||||
&.public{
|
||||
background-color: rgba(58, 213, 115, 0.08);
|
||||
border-color: #25c589;
|
||||
color: #25c589;
|
||||
}
|
||||
&.private{
|
||||
background-color: rgba(230, 126, 34, 0.08);
|
||||
border-color: rgba(230, 126, 34, 1);
|
||||
color: rgba(230, 126, 34, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ const TokenKey = 'autologin_trustie';
|
|||
|
||||
function UploadImage({ getImage , url, getImageId, maxSize = 2, action = getUploadActionUrl(), getImageUrl }){
|
||||
const [ imageUrl , setImageUrl ] = useState(undefined);
|
||||
const [loading, setLoading] = useState(false);
|
||||
useEffect(()=>{
|
||||
setImageUrl(url);
|
||||
},[url])
|
||||
|
|
@ -33,7 +34,9 @@ function UploadImage({ getImage , url, getImageId, maxSize = 2, action = getUplo
|
|||
}
|
||||
// 上传完成后
|
||||
function handleChange(info){
|
||||
setLoading(true);
|
||||
if(info && info.file && info.file.status === "done"){
|
||||
setLoading(false);
|
||||
getImageId && getImageId(info.file.response.id);
|
||||
getImageUrl && getImageUrl(info.file.response.url)
|
||||
getBase64(info.file.originFileObj, imageUrl =>
|
||||
|
|
@ -58,7 +61,7 @@ function UploadImage({ getImage , url, getImageId, maxSize = 2, action = getUplo
|
|||
<img src={imageUrl} alt="avatar" style={{ width: '100%' }} />
|
||||
:
|
||||
<div>
|
||||
<Icon type={'plus'} />
|
||||
<Icon type={loading ? 'loading' : 'plus'} />
|
||||
<div className="ant-upload-text">点击上传</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -331,19 +331,20 @@ form{
|
|||
border: 1px solid #DDDDDD !important;
|
||||
background-color: #fff !important;
|
||||
}
|
||||
.ant-btn.ant-btn-background-ghost{
|
||||
border-color: #D0D0D0;
|
||||
}
|
||||
.ant-btn.ant-btn-background-ghost.ant-btn-primary:hover{
|
||||
background-color:$primary-color!important;
|
||||
border-color: $primary-color;
|
||||
color: #fff;
|
||||
}
|
||||
.ant-btn.ant-btn-background-ghost.ant-btn-danger:hover{
|
||||
background-color: #DF0002!important;
|
||||
border-color: #DF0002;
|
||||
color: #fff;
|
||||
}
|
||||
// ghost模式按钮:如有影响,单独修改
|
||||
// .ant-btn.ant-btn-background-ghost{
|
||||
// border-color: #D0D0D0;
|
||||
// }
|
||||
// .ant-btn.ant-btn-background-ghost.ant-btn-primary:hover{
|
||||
// background-color:$primary-color!important;
|
||||
// border-color: $primary-color;
|
||||
// color: #fff;
|
||||
// }
|
||||
// .ant-btn.ant-btn-background-ghost.ant-btn-danger:hover{
|
||||
// background-color: #DF0002!important;
|
||||
// border-color: #DF0002;
|
||||
// color: #fff;
|
||||
// }
|
||||
.newPopUl{
|
||||
li{
|
||||
height: 30px;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ function Index(props){
|
|||
break;
|
||||
case '/settings/verification':
|
||||
setType('4');
|
||||
documentTitle = "身份认证";
|
||||
documentTitle = "实名认证";
|
||||
break;
|
||||
default:
|
||||
setType('2');
|
||||
|
|
@ -55,7 +55,7 @@ function Index(props){
|
|||
<Menu.Item key="3" className="font-16" onClick={()=>{props.history.push('/settings/phone')}}>手机号管理</Menu.Item>
|
||||
<Menu.Item key="0" className="font-16" onClick={()=>{props.history.push('/settings/emails')}}>邮箱管理</Menu.Item>
|
||||
<Menu.Item key="1" className="font-16" onClick={()=>{props.history.push('/settings/password')}}>密码管理</Menu.Item>
|
||||
{/* <Menu.Item key="4" className="font-16" onClick={()=>{props.history.push('/settings/verification')}}>身份认证</Menu.Item> */}
|
||||
<Menu.Item key="4" className="font-16" onClick={()=>{props.history.push('/settings/verification')}}>实名认证</Menu.Item>
|
||||
<Menu.Item key="2" className="font-16" onClick={()=>{props.history.push('/settings/cancel')}}>账号注销</Menu.Item>
|
||||
</Menu>}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { getImageUrl } from '../../../common/UrlTool';
|
|||
export default Form.create()(
|
||||
forwardRef((props)=>{
|
||||
const { getFieldDecorator, validateFields , setFieldsValue } = props && props.form;
|
||||
const { resetUserInfo , current_user } = props;
|
||||
const { current_user } = props;
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [data, setData] = useState(undefined);
|
||||
const [reload, setReload] = useState(undefined);
|
||||
|
|
@ -18,7 +18,7 @@ export default Form.create()(
|
|||
if(current_user && current_user.login){
|
||||
setLoading(true);
|
||||
// 获取用户身份认证信息
|
||||
axios.get(`http://ng.learnerhub.net/api/identity_verifications.json`).then(res=>{
|
||||
axios.get(`/identity_verifications.json`).then(res=>{
|
||||
setLoading(false);
|
||||
if(res && res.status === 200){
|
||||
if(res.data && res.data.status === 0){
|
||||
|
|
@ -38,7 +38,7 @@ export default Form.create()(
|
|||
validateFields((error, values) => {
|
||||
if (!error) {
|
||||
if(data){
|
||||
axios.put(`http://ng.learnerhub.net/api/identity_verifications/${data.id}.json`, values).then(res => {
|
||||
axios.put(`/identity_verifications/${data.id}.json`, values).then(res => {
|
||||
if(res && res.status === 200){
|
||||
message.success("提交成功");
|
||||
setReload(Math.random());
|
||||
|
|
@ -46,7 +46,7 @@ export default Form.create()(
|
|||
}).catch((error) => {});
|
||||
}else{
|
||||
// 新增
|
||||
axios.post(`http://ng.learnerhub.net/api/identity_verifications.json`, values).then(res=>{
|
||||
axios.post(`/identity_verifications.json`, values).then(res=>{
|
||||
if(res && res.status === 200){
|
||||
message.success("提交成功");
|
||||
setReload(Math.random());
|
||||
|
|
@ -67,15 +67,16 @@ export default Form.create()(
|
|||
</div>
|
||||
)}
|
||||
{data.state === "已拒绝" && <div className="tipsBox mb20 errorTip">
|
||||
您提交的身份信息未提供,原因:{data.description || "无,如有需要请联系平台管理员"}
|
||||
您提交的身份信息未审核通过,原因:{data.description || "无,如有需要请联系平台管理员"}
|
||||
</div>}
|
||||
{data.state === "已通过" && <Alert className="mb20" type='success' message="您提交的身份信息已通过" />}
|
||||
{data.state === "已通过" && <Alert className="mb20" type='success' message="您提交的身份信息已审核通过" />}
|
||||
</Fragment>
|
||||
)}
|
||||
<Form layout={"inline"} className="verificationForm">
|
||||
<Form.Item label="真实姓名" labelCol={{ span: 4 }}>
|
||||
{getFieldDecorator("name", {
|
||||
rules: [{ required: true, message: "请输入真实姓名" }],
|
||||
rules: [{ required: true, message: "请输入真实姓名" },
|
||||
{type: 'string', max: 50, min: 1, message: "长度1-50"}],
|
||||
})(
|
||||
<Input
|
||||
placeholder="请输入与身份证一致的真实姓名"
|
||||
|
|
@ -83,7 +84,7 @@ export default Form.create()(
|
|||
/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="身份证号" labelCol={{ span: 4 }}>
|
||||
<Form.Item label="身份证号码" labelCol={{ span: 4 }}>
|
||||
{getFieldDecorator("number", {
|
||||
rules: [
|
||||
{ required: true, message: "请输入大陆身份证号码" },
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ import 'codemirror/lib/codemirror.css';
|
|||
import './css/newquestion.css';
|
||||
const $ = window.$
|
||||
|
||||
const mdIcons = ["bold", "italic", "del", "|", "list-ul", "list-ol", "|", "code", "code-block", "link", "|", "inline-latex", "latex", '|', "image", "table", '|', "line-break", "watch", "clear","fullscreen"];
|
||||
const mdIcons = ["bold", "italic", "del", "|", "list-ul", "list-ol", "|", "code", "code-block", "link", "|", "image", "table", '|', "line-break", "watch", "clear","fullscreen"];
|
||||
const mdIconsHasLatex = ["bold", "italic", "del", "|", "list-ul", "list-ol", "|", "code", "code-block", "link", "|", "inline-latex", "latex", '|', "image", "table", '|', "line-break", "watch", "clear","fullscreen"];
|
||||
|
||||
const NULL_CH = '▁';
|
||||
|
||||
|
|
@ -74,7 +75,7 @@ function md_elocalStorage(editor, mdu, id) {
|
|||
return tid
|
||||
}
|
||||
|
||||
export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, className = '', noStorage = false, imageExpand = true, placeholder = '', width = '100%', height = 400, initValue = '', emoji, watch=true, showNullButton = false, showResizeBar = false, startInit = true , forMember = true , isCanAtme = false , isQuoteIssue = false , changeAtWhoLoginList, owner, projectsId , isFocus = true}) => {
|
||||
export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, className = '', noStorage = false, imageExpand = true, placeholder = '', width = '100%', height = 400, initValue = '', emoji, watch=true, showNullButton = false, showResizeBar = false, startInit = true , forMember = true , isCanAtme = false , isQuoteIssue = false , changeAtWhoLoginList, owner, projectsId , isFocus = true, showLatexButton = true}) => {
|
||||
|
||||
const editorEl = useRef();
|
||||
const resizeBarEl = useRef();
|
||||
|
|
@ -353,7 +354,7 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla
|
|||
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"],
|
||||
imageUploadURL: getUploadActionUrl(),
|
||||
toolbarIcons: function () {
|
||||
return showNullButton ? [...mdIcons, 'null-button'] : mdIcons
|
||||
return showLatexButton ? mdIconsHasLatex : mdIcons
|
||||
},
|
||||
toolbarIconsClass: {
|
||||
"line-break": "fa-minus",
|
||||
|
|
|
|||
Loading…
Reference in New Issue