forked from Gitlink/forgeplus-react
Merge branch 'dev_m_copy' into dev_military
# Conflicts: # src/forge/Merge/MessageCount.js
This commit is contained in:
commit
0a39ed80da
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"presets": [
|
||||
"es2015",
|
||||
"react",
|
||||
"stage-2"
|
||||
],
|
||||
"plugins": [[
|
||||
"transform-runtime",
|
||||
{
|
||||
"helpers": false,
|
||||
"polyfill": false,
|
||||
"regenerator": true,
|
||||
"moduleName": "babel-runtime"
|
||||
}
|
||||
]]
|
||||
}
|
|
@ -141,7 +141,6 @@ module.exports = {
|
|||
name: "static/media/[name].[hash:8].[ext]",
|
||||
},
|
||||
},
|
||||
// Process JS with Babel.
|
||||
{
|
||||
test: /\.(js|jsx|mjs)$/,
|
||||
include: paths.appSrc,
|
||||
|
@ -161,10 +160,8 @@ module.exports = {
|
|||
],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
test: /\.css$/,
|
||||
|
||||
use: [
|
||||
{
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
|
|
|
@ -1254,6 +1254,55 @@
|
|||
"ast-types-flow": "0.0.7"
|
||||
}
|
||||
},
|
||||
"babel-cli": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-cli/download/babel-cli-6.26.0.tgz",
|
||||
"integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"babel-register": "^6.26.0",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"chokidar": "^1.6.1",
|
||||
"commander": "^2.11.0",
|
||||
"convert-source-map": "^1.5.0",
|
||||
"fs-readdir-recursive": "^1.0.0",
|
||||
"glob": "^7.1.2",
|
||||
"lodash": "^4.17.4",
|
||||
"output-file-sync": "^1.1.2",
|
||||
"path-is-absolute": "^1.0.1",
|
||||
"slash": "^1.0.0",
|
||||
"source-map": "^0.5.6",
|
||||
"v8flags": "^2.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"chokidar": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npm.taobao.org/chokidar/download/chokidar-1.7.0.tgz?cache=0&sync_timestamp=1602585438968&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchokidar%2Fdownload%2Fchokidar-1.7.0.tgz",
|
||||
"integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"anymatch": "^1.3.0",
|
||||
"async-each": "^1.0.0",
|
||||
"fsevents": "^1.0.0",
|
||||
"glob-parent": "^2.0.0",
|
||||
"inherits": "^2.0.1",
|
||||
"is-binary-path": "^1.0.0",
|
||||
"is-glob": "^2.0.0",
|
||||
"path-is-absolute": "^1.0.0",
|
||||
"readdirp": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz",
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"babel-code-frame": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||
|
@ -1273,7 +1322,7 @@
|
|||
},
|
||||
"babel-core": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-core/download/babel-core-6.26.0.tgz",
|
||||
"integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
|
||||
"requires": {
|
||||
"babel-code-frame": "^6.26.0",
|
||||
|
@ -1299,8 +1348,8 @@
|
|||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1605791507452&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
|
||||
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
|
@ -1345,6 +1394,17 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"babel-helper-bindify-decorators": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-helper-bindify-decorators/download/babel-helper-bindify-decorators-6.24.1.tgz",
|
||||
"integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-helper-builder-binary-assignment-operator-visitor": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
|
||||
|
@ -1397,6 +1457,18 @@
|
|||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-helper-explode-class": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-helper-explode-class/download/babel-helper-explode-class-6.24.1.tgz",
|
||||
"integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-bindify-decorators": "^6.24.1",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-traverse": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-helper-function-name": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
|
||||
|
@ -1585,11 +1657,23 @@
|
|||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
|
||||
"integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU="
|
||||
},
|
||||
"babel-plugin-syntax-async-generators": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-plugin-syntax-async-generators/download/babel-plugin-syntax-async-generators-6.13.0.tgz",
|
||||
"integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=",
|
||||
"dev": true
|
||||
},
|
||||
"babel-plugin-syntax-class-properties": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
|
||||
"integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94="
|
||||
},
|
||||
"babel-plugin-syntax-decorators": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-plugin-syntax-decorators/download/babel-plugin-syntax-decorators-6.13.0.tgz",
|
||||
"integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=",
|
||||
"dev": true
|
||||
},
|
||||
"babel-plugin-syntax-dynamic-import": {
|
||||
"version": "6.18.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
|
||||
|
@ -1620,6 +1704,17 @@
|
|||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
|
||||
"integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM="
|
||||
},
|
||||
"babel-plugin-transform-async-generator-functions": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-plugin-transform-async-generator-functions/download/babel-plugin-transform-async-generator-functions-6.24.1.tgz",
|
||||
"integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-remap-async-to-generator": "^6.24.1",
|
||||
"babel-plugin-syntax-async-generators": "^6.5.0",
|
||||
"babel-runtime": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-async-to-generator": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
|
||||
|
@ -1641,6 +1736,19 @@
|
|||
"babel-template": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-decorators": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-plugin-transform-decorators/download/babel-plugin-transform-decorators-6.24.1.tgz",
|
||||
"integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-helper-explode-class": "^6.24.1",
|
||||
"babel-plugin-syntax-decorators": "^6.13.0",
|
||||
"babel-runtime": "^6.22.0",
|
||||
"babel-template": "^6.24.1",
|
||||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-es2015-arrow-functions": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
|
||||
|
@ -1935,7 +2043,7 @@
|
|||
},
|
||||
"babel-plugin-transform-runtime": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-plugin-transform-runtime/download/babel-plugin-transform-runtime-6.23.0.tgz",
|
||||
"integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=",
|
||||
"requires": {
|
||||
"babel-runtime": "^6.22.0"
|
||||
|
@ -1950,6 +2058,25 @@
|
|||
"babel-types": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-polyfill": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-polyfill/download/babel-polyfill-6.26.0.tgz",
|
||||
"integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.26.0",
|
||||
"core-js": "^2.5.0",
|
||||
"regenerator-runtime": "^0.10.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"regenerator-runtime": {
|
||||
"version": "0.10.5",
|
||||
"resolved": "https://registry.npm.taobao.org/regenerator-runtime/download/regenerator-runtime-0.10.5.tgz?cache=0&sync_timestamp=1595456367497&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregenerator-runtime%2Fdownload%2Fregenerator-runtime-0.10.5.tgz",
|
||||
"integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"babel-preset-env": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz",
|
||||
|
@ -1987,6 +2114,38 @@
|
|||
"semver": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"babel-preset-es2015": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-preset-es2015/download/babel-preset-es2015-6.24.1.tgz",
|
||||
"integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-plugin-check-es2015-constants": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-block-scoping": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-classes": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-computed-properties": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-destructuring": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-duplicate-keys": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-for-of": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-function-name": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-literals": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-modules-amd": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-modules-systemjs": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-modules-umd": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-object-super": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-parameters": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-shorthand-properties": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-spread": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-sticky-regex": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-template-literals": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-typeof-symbol": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-unicode-regex": "^6.24.1",
|
||||
"babel-plugin-transform-regenerator": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-preset-flow": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz",
|
||||
|
@ -2005,7 +2164,7 @@
|
|||
},
|
||||
"babel-preset-react": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-preset-react/download/babel-preset-react-6.24.1.tgz",
|
||||
"integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=",
|
||||
"requires": {
|
||||
"babel-plugin-syntax-jsx": "^6.3.13",
|
||||
|
@ -2036,6 +2195,31 @@
|
|||
"babel-preset-react": "6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-preset-stage-2": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-preset-stage-2/download/babel-preset-stage-2-6.24.1.tgz",
|
||||
"integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||
"babel-plugin-transform-decorators": "^6.24.1",
|
||||
"babel-preset-stage-3": "^6.24.1"
|
||||
}
|
||||
},
|
||||
"babel-preset-stage-3": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npm.taobao.org/babel-preset-stage-3/download/babel-preset-stage-3-6.24.1.tgz",
|
||||
"integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-plugin-syntax-trailing-function-commas": "^6.22.0",
|
||||
"babel-plugin-transform-async-generator-functions": "^6.24.1",
|
||||
"babel-plugin-transform-async-to-generator": "^6.24.1",
|
||||
"babel-plugin-transform-exponentiation-operator": "^6.24.1",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.22.0"
|
||||
}
|
||||
},
|
||||
"babel-register": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
|
||||
|
@ -3704,6 +3888,11 @@
|
|||
"randomfill": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"crypto-js": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/crypto-js/download/crypto-js-4.0.0.tgz",
|
||||
"integrity": "sha1-KQSrJnep0EKFai6i74DekuSjbcw="
|
||||
},
|
||||
"crypto-random-string": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
|
||||
|
@ -4778,6 +4967,11 @@
|
|||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"dompurify": {
|
||||
"version": "2.0.15",
|
||||
"resolved": "https://registry.npm.taobao.org/dompurify/download/dompurify-2.0.15.tgz?cache=0&sync_timestamp=1607352578938&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdompurify%2Fdownload%2Fdompurify-2.0.15.tgz",
|
||||
"integrity": "sha1-gOMA/D6JVHvQrxr/LrqIzhf8neo="
|
||||
},
|
||||
"domutils": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
|
||||
|
@ -6888,6 +7082,12 @@
|
|||
"minipass": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"fs-readdir-recursive": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npm.taobao.org/fs-readdir-recursive/download/fs-readdir-recursive-1.1.0.tgz",
|
||||
"integrity": "sha1-4y/AMKLM7kSmtTcTCNpUvgs5fSc=",
|
||||
"dev": true
|
||||
},
|
||||
"fs-write-stream-atomic": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
|
||||
|
@ -11339,6 +11539,17 @@
|
|||
"os-tmpdir": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"output-file-sync": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npm.taobao.org/output-file-sync/download/output-file-sync-1.1.2.tgz",
|
||||
"integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.4",
|
||||
"mkdirp": "^0.5.1",
|
||||
"object-assign": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"p-defer": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
|
||||
|
@ -14939,8 +15150,8 @@
|
|||
},
|
||||
"react-player": {
|
||||
"version": "1.15.3",
|
||||
"resolved": "https://registry.npmjs.org/react-player/-/react-player-1.15.3.tgz",
|
||||
"integrity": "sha512-8fc0R1AipFIy7l4lKgnIg+gMU2IY32ZMxxBlINjXAq/YnN3HUP3hOaE+aQ0lQv+a1/MMZgbekWD86ZGDO7kB8g==",
|
||||
"resolved": "https://registry.npm.taobao.org/react-player/download/react-player-1.15.3.tgz",
|
||||
"integrity": "sha1-0AzxRfnIYYTLCgcaH7+Oy3tomH8=",
|
||||
"requires": {
|
||||
"deepmerge": "^4.0.0",
|
||||
"load-script": "^1.0.0",
|
||||
|
@ -14949,8 +15160,8 @@
|
|||
"dependencies": {
|
||||
"deepmerge": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
|
||||
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
|
||||
"resolved": "https://registry.npm.taobao.org/deepmerge/download/deepmerge-4.2.2.tgz",
|
||||
"integrity": "sha1-RNLqNnm49NT/ujPwPYZfwee/SVU="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -17010,8 +17221,8 @@
|
|||
},
|
||||
"source-map-support": {
|
||||
"version": "0.4.18",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
|
||||
"integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
|
||||
"resolved": "https://registry.npm.taobao.org/source-map-support/download/source-map-support-0.4.18.tgz?cache=0&sync_timestamp=1587719517036&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map-support%2Fdownload%2Fsource-map-support-0.4.18.tgz",
|
||||
"integrity": "sha1-Aoam3ovkJkEzhZTpfM6nXwosWF8=",
|
||||
"requires": {
|
||||
"source-map": "^0.5.6"
|
||||
},
|
||||
|
@ -18666,6 +18877,12 @@
|
|||
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
|
||||
},
|
||||
"user-home": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npm.taobao.org/user-home/download/user-home-1.1.1.tgz",
|
||||
"integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=",
|
||||
"dev": true
|
||||
},
|
||||
"util": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
|
||||
|
@ -18717,6 +18934,15 @@
|
|||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz",
|
||||
"integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w=="
|
||||
},
|
||||
"v8flags": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npm.taobao.org/v8flags/download/v8flags-2.1.1.tgz?cache=0&sync_timestamp=1590964281452&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fv8flags%2Fdownload%2Fv8flags-2.1.1.tgz",
|
||||
"integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"user-home": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||
|
|
12
package.json
12
package.json
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "educoder",
|
||||
"name": "forge",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
|
@ -10,11 +10,9 @@
|
|||
"array-flatten": "^2.1.2",
|
||||
"autoprefixer": "7.1.6",
|
||||
"axios": "^0.18.1",
|
||||
"babel-core": "6.26.0",
|
||||
"babel-eslint": "7.2.3",
|
||||
"babel-jest": "20.0.3",
|
||||
"babel-loader": "7.1.2",
|
||||
"code-prettify": "^0.1.0",
|
||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||
"babel-preset-react-app": "^3.1.1",
|
||||
"babel-runtime": "6.26.0",
|
||||
|
@ -24,9 +22,11 @@
|
|||
"chalk": "1.1.3",
|
||||
"classnames": "^2.2.5",
|
||||
"clipboard": "^2.0.6",
|
||||
"code-prettify": "^0.1.0",
|
||||
"codemirror": "^5.53.0",
|
||||
"connected-react-router": "4.4.1",
|
||||
"css-loader": "^3.5.2",
|
||||
"dompurify": "^2.0.15",
|
||||
"dotenv": "4.0.0",
|
||||
"dotenv-expand": "4.2.0",
|
||||
"echarts": "^4.7.0",
|
||||
|
@ -182,7 +182,13 @@
|
|||
"port": "3007",
|
||||
"devDependencies": {
|
||||
"@babel/runtime": "7.0.0-beta.51",
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-plugin-import": "^1.13.0",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-preset-stage-2": "^6.24.1",
|
||||
"compression-webpack-plugin": "^1.1.12",
|
||||
"concat": "^1.0.3",
|
||||
"happypack": "^5.0.1",
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*头部导航条样式---2018-03-19--by-cs*/
|
||||
.newHeader {
|
||||
background: #24292D !important;
|
||||
width: 100%;
|
||||
height: 60px !important;
|
||||
min-width: 1200px;
|
||||
|
|
|
@ -1498,9 +1498,6 @@ a.edu-txt-w80,
|
|||
.font-bd {
|
||||
font-weight: bold;
|
||||
}
|
||||
.fwt-500{
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
.font-n {
|
||||
font-weight: normal;
|
||||
|
@ -2328,6 +2325,9 @@ input::-ms-clear {
|
|||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
.ant-modal-close{
|
||||
top:8px!important;
|
||||
}
|
||||
|
||||
.newContainer {
|
||||
min-height: 100%;
|
||||
|
@ -2348,7 +2348,6 @@ input::-ms-clear {
|
|||
margin: 0 auto;
|
||||
padding-bottom: 110px;
|
||||
min-width: 1200px;
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2662,7 +2661,7 @@ a.color-green:hover {
|
|||
|
||||
/*百分比宽度*/
|
||||
.width100 {
|
||||
width: 100%;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.width89 {
|
||||
|
@ -3948,74 +3947,53 @@ html>body #ajax-indicator {
|
|||
|
||||
.head-nav {
|
||||
text-align: center;
|
||||
height: 60px;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
padding: 0 70px;
|
||||
/* text-align: center;
|
||||
height: 60px;
|
||||
height: 70px;
|
||||
box-sizing: border-box;
|
||||
min-width: 780px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1; */
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
z-index: 3;
|
||||
height: 60px;
|
||||
height: 70px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li {
|
||||
float: left;
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
padding: 0 24px;
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
padding:0px 20px;
|
||||
}
|
||||
.head-nav ul#header-nav li.active a, .head-nav ul#header-nav li:hover a{
|
||||
color: #1484ef;
|
||||
}
|
||||
.head-nav ul#header-nav li.active a:after{
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background-color: #1484ef;
|
||||
left: 0;
|
||||
bottom: 12px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li a {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
color: #333333;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* .head-nav ul#header-nav li a:hover {
|
||||
.head-nav ul#header-nav li a:hover,.head-nav ul#header-nav li.active a {
|
||||
color: #5091FF;
|
||||
} */
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li:last-child {
|
||||
margin-right: 0px
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li.active a:first-child {
|
||||
color: #1484ef !important;
|
||||
.head-nav ul#header-nav li.active{
|
||||
/* background-color: #3B3B3B; */
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li.active p {
|
||||
color: #1484ef !important;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li p:hover {
|
||||
color: #cccccc;
|
||||
|
@ -4028,21 +4006,21 @@ html>body #ajax-indicator {
|
|||
color: #fff
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li.active div ul li a {
|
||||
/* .head-nav ul#header-nav li.active div ul li a {
|
||||
color: #000 !important;
|
||||
}
|
||||
} */
|
||||
|
||||
.head-nav ul#header-nav li.active div ul li a:hover {
|
||||
/* .head-nav ul#header-nav li.active div ul li a:hover {
|
||||
color: #FFF !important;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li.active ul li a {
|
||||
color: #000 !important;
|
||||
}
|
||||
} */
|
||||
|
||||
.head-nav ul#header-nav li.active ul li a:hover {
|
||||
/* .head-nav ul#header-nav li.active ul li a:hover {
|
||||
color: #FFF !important;
|
||||
}
|
||||
} */
|
||||
|
||||
/* .head-nav ul#header-nav li.active:after {
|
||||
content: '';
|
||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -5,6 +5,559 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "17567215",
|
||||
"name": "主页",
|
||||
"font_class": "zhuye1",
|
||||
"unicode": "e7e4",
|
||||
"unicode_decimal": 59364
|
||||
},
|
||||
{
|
||||
"icon_id": "17542255",
|
||||
"name": "项目简介",
|
||||
"font_class": "xiangmujianjie",
|
||||
"unicode": "e7e7",
|
||||
"unicode_decimal": 59367
|
||||
},
|
||||
{
|
||||
"icon_id": "17542254",
|
||||
"name": "参与成员",
|
||||
"font_class": "canyuchengyuan",
|
||||
"unicode": "e7e6",
|
||||
"unicode_decimal": 59366
|
||||
},
|
||||
{
|
||||
"icon_id": "17542253",
|
||||
"name": "使用文档",
|
||||
"font_class": "shiyongwendang",
|
||||
"unicode": "e7e5",
|
||||
"unicode_decimal": 59365
|
||||
},
|
||||
{
|
||||
"icon_id": "17541348",
|
||||
"name": "代码库",
|
||||
"font_class": "daimaku",
|
||||
"unicode": "e7d9",
|
||||
"unicode_decimal": 59353
|
||||
},
|
||||
{
|
||||
"icon_id": "17541349",
|
||||
"name": "forc",
|
||||
"font_class": "forc",
|
||||
"unicode": "e7da",
|
||||
"unicode_decimal": 59354
|
||||
},
|
||||
{
|
||||
"icon_id": "17541350",
|
||||
"name": "点赞",
|
||||
"font_class": "dianzan3",
|
||||
"unicode": "e7dd",
|
||||
"unicode_decimal": 59357
|
||||
},
|
||||
{
|
||||
"icon_id": "17541351",
|
||||
"name": "里程碑",
|
||||
"font_class": "lichengbei",
|
||||
"unicode": "e7de",
|
||||
"unicode_decimal": 59358
|
||||
},
|
||||
{
|
||||
"icon_id": "17541352",
|
||||
"name": "取消点赞",
|
||||
"font_class": "quxiaodianzan",
|
||||
"unicode": "e7df",
|
||||
"unicode_decimal": 59359
|
||||
},
|
||||
{
|
||||
"icon_id": "17541353",
|
||||
"name": "fork2",
|
||||
"font_class": "fork2",
|
||||
"unicode": "e7e0",
|
||||
"unicode_decimal": 59360
|
||||
},
|
||||
{
|
||||
"icon_id": "17541354",
|
||||
"name": "合并请求",
|
||||
"font_class": "hebingqingqiu1",
|
||||
"unicode": "e7e1",
|
||||
"unicode_decimal": 59361
|
||||
},
|
||||
{
|
||||
"icon_id": "17541355",
|
||||
"name": "任务",
|
||||
"font_class": "renwu",
|
||||
"unicode": "e7e2",
|
||||
"unicode_decimal": 59362
|
||||
},
|
||||
{
|
||||
"icon_id": "17541356",
|
||||
"name": "通知",
|
||||
"font_class": "tongzhi",
|
||||
"unicode": "e7e3",
|
||||
"unicode_decimal": 59363
|
||||
},
|
||||
{
|
||||
"icon_id": "17481990",
|
||||
"name": "金币",
|
||||
"font_class": "jinbi",
|
||||
"unicode": "e7c5",
|
||||
"unicode_decimal": 59333
|
||||
},
|
||||
{
|
||||
"icon_id": "17468131",
|
||||
"name": "未开摄像头",
|
||||
"font_class": "weikaishexiangtou1",
|
||||
"unicode": "e7d8",
|
||||
"unicode_decimal": 59352
|
||||
},
|
||||
{
|
||||
"icon_id": "17435144",
|
||||
"name": "关卡菜单",
|
||||
"font_class": "guankacaidan",
|
||||
"unicode": "e7ce",
|
||||
"unicode_decimal": 59342
|
||||
},
|
||||
{
|
||||
"icon_id": "17416333",
|
||||
"name": "重置实训",
|
||||
"font_class": "zhongzhishixun",
|
||||
"unicode": "e7d5",
|
||||
"unicode_decimal": 59349
|
||||
},
|
||||
{
|
||||
"icon_id": "17416337",
|
||||
"name": "复制粘贴",
|
||||
"font_class": "fuzhiniantie",
|
||||
"unicode": "e7d6",
|
||||
"unicode_decimal": 59350
|
||||
},
|
||||
{
|
||||
"icon_id": "17416342",
|
||||
"name": "共享桌面",
|
||||
"font_class": "gongxiangzhuomian",
|
||||
"unicode": "e7d7",
|
||||
"unicode_decimal": 59351
|
||||
},
|
||||
{
|
||||
"icon_id": "17415865",
|
||||
"name": "退出全屏",
|
||||
"font_class": "tuichuquanping",
|
||||
"unicode": "e7d4",
|
||||
"unicode_decimal": 59348
|
||||
},
|
||||
{
|
||||
"icon_id": "17415856",
|
||||
"name": "全屏",
|
||||
"font_class": "quanping",
|
||||
"unicode": "e7d2",
|
||||
"unicode_decimal": 59346
|
||||
},
|
||||
{
|
||||
"icon_id": "17415080",
|
||||
"name": "复制版本库地址",
|
||||
"font_class": "fuzhibanbenkudizhi1",
|
||||
"unicode": "e7d3",
|
||||
"unicode_decimal": 59347
|
||||
},
|
||||
{
|
||||
"icon_id": "17400088",
|
||||
"name": "实验环境倒计时",
|
||||
"font_class": "shiyanhuanjingdaojishi",
|
||||
"unicode": "e7d1",
|
||||
"unicode_decimal": 59345
|
||||
},
|
||||
{
|
||||
"icon_id": "17399931",
|
||||
"name": "vnc实训界面-工具栏",
|
||||
"font_class": "vncshixunjiemian-gongjulan",
|
||||
"unicode": "e7d0",
|
||||
"unicode_decimal": 59344
|
||||
},
|
||||
{
|
||||
"icon_id": "17399816",
|
||||
"name": "vnc实训界面-展开",
|
||||
"font_class": "vncshixunjiemian-zhankai",
|
||||
"unicode": "e7cf",
|
||||
"unicode_decimal": 59343
|
||||
},
|
||||
{
|
||||
"icon_id": "17399289",
|
||||
"name": "vnc实训界面-收起",
|
||||
"font_class": "vncshixunjiemian-shouqi",
|
||||
"unicode": "e7cd",
|
||||
"unicode_decimal": 59341
|
||||
},
|
||||
{
|
||||
"icon_id": "17393121",
|
||||
"name": "撤销分组",
|
||||
"font_class": "chexiaofenzu",
|
||||
"unicode": "e7ca",
|
||||
"unicode_decimal": 59338
|
||||
},
|
||||
{
|
||||
"icon_id": "17393122",
|
||||
"name": "撤销共享",
|
||||
"font_class": "chexiaogongxiang",
|
||||
"unicode": "e7cb",
|
||||
"unicode_decimal": 59339
|
||||
},
|
||||
{
|
||||
"icon_id": "17393123",
|
||||
"name": "选中",
|
||||
"font_class": "xuanzhong1",
|
||||
"unicode": "e7cc",
|
||||
"unicode_decimal": 59340
|
||||
},
|
||||
{
|
||||
"icon_id": "17347836",
|
||||
"name": "警示",
|
||||
"font_class": "jingshi1",
|
||||
"unicode": "e7c9",
|
||||
"unicode_decimal": 59337
|
||||
},
|
||||
{
|
||||
"icon_id": "17338109",
|
||||
"name": "删除",
|
||||
"font_class": "shanchu21",
|
||||
"unicode": "e7c8",
|
||||
"unicode_decimal": 59336
|
||||
},
|
||||
{
|
||||
"icon_id": "17338062",
|
||||
"name": "收藏",
|
||||
"font_class": "shoucang3",
|
||||
"unicode": "e7c7",
|
||||
"unicode_decimal": 59335
|
||||
},
|
||||
{
|
||||
"icon_id": "17320656",
|
||||
"name": "搜索",
|
||||
"font_class": "sousuo2",
|
||||
"unicode": "e7c6",
|
||||
"unicode_decimal": 59334
|
||||
},
|
||||
{
|
||||
"icon_id": "17272329",
|
||||
"name": "光标",
|
||||
"font_class": "guangbiao",
|
||||
"unicode": "e7c4",
|
||||
"unicode_decimal": 59332
|
||||
},
|
||||
{
|
||||
"icon_id": "17215358",
|
||||
"name": "QQ",
|
||||
"font_class": "QQ",
|
||||
"unicode": "e7c3",
|
||||
"unicode_decimal": 59331
|
||||
},
|
||||
{
|
||||
"icon_id": "675739",
|
||||
"name": "用户",
|
||||
"font_class": "yonghu",
|
||||
"unicode": "e7c2",
|
||||
"unicode_decimal": 59330
|
||||
},
|
||||
{
|
||||
"icon_id": "12703761",
|
||||
"name": "oschina",
|
||||
"font_class": "oschina",
|
||||
"unicode": "e7c1",
|
||||
"unicode_decimal": 59329
|
||||
},
|
||||
{
|
||||
"icon_id": "17189615",
|
||||
"name": "右",
|
||||
"font_class": "you",
|
||||
"unicode": "e7bf",
|
||||
"unicode_decimal": 59327
|
||||
},
|
||||
{
|
||||
"icon_id": "17189616",
|
||||
"name": "左",
|
||||
"font_class": "zuo",
|
||||
"unicode": "e7c0",
|
||||
"unicode_decimal": 59328
|
||||
},
|
||||
{
|
||||
"icon_id": "17126010",
|
||||
"name": "编程语言",
|
||||
"font_class": "bianchengyuyan",
|
||||
"unicode": "e7bd",
|
||||
"unicode_decimal": 59325
|
||||
},
|
||||
{
|
||||
"icon_id": "4550494",
|
||||
"name": "箭头",
|
||||
"font_class": "jiantou",
|
||||
"unicode": "e7bc",
|
||||
"unicode_decimal": 59324
|
||||
},
|
||||
{
|
||||
"icon_id": "17078373",
|
||||
"name": "自用试卷",
|
||||
"font_class": "ziyongshijuan",
|
||||
"unicode": "e7b3",
|
||||
"unicode_decimal": 59315
|
||||
},
|
||||
{
|
||||
"icon_id": "17078374",
|
||||
"name": "已公开试卷",
|
||||
"font_class": "yigongkaishijuan",
|
||||
"unicode": "e7bb",
|
||||
"unicode_decimal": 59323
|
||||
},
|
||||
{
|
||||
"icon_id": "17077771",
|
||||
"name": "视频",
|
||||
"font_class": "shipin",
|
||||
"unicode": "e7b4",
|
||||
"unicode_decimal": 59316
|
||||
},
|
||||
{
|
||||
"icon_id": "17077772",
|
||||
"name": "实训",
|
||||
"font_class": "shixun2",
|
||||
"unicode": "e7be",
|
||||
"unicode_decimal": 59326
|
||||
},
|
||||
{
|
||||
"icon_id": "17060498",
|
||||
"name": "放大",
|
||||
"font_class": "fangda2",
|
||||
"unicode": "e7ba",
|
||||
"unicode_decimal": 59322
|
||||
},
|
||||
{
|
||||
"icon_id": "17060439",
|
||||
"name": "开启防作弊",
|
||||
"font_class": "fangzuobi",
|
||||
"unicode": "e7b9",
|
||||
"unicode_decimal": 59321
|
||||
},
|
||||
{
|
||||
"icon_id": "17027771",
|
||||
"name": "闹钟",
|
||||
"font_class": "shizhong",
|
||||
"unicode": "e7b8",
|
||||
"unicode_decimal": 59320
|
||||
},
|
||||
{
|
||||
"icon_id": "16923000",
|
||||
"name": "上传视频 (1)",
|
||||
"font_class": "shangchuanshipin1",
|
||||
"unicode": "e7b7",
|
||||
"unicode_decimal": 59319
|
||||
},
|
||||
{
|
||||
"icon_id": "16922942",
|
||||
"name": "对勾",
|
||||
"font_class": "duigou1",
|
||||
"unicode": "e7b2",
|
||||
"unicode_decimal": 59314
|
||||
},
|
||||
{
|
||||
"icon_id": "16922946",
|
||||
"name": "链接 (1)",
|
||||
"font_class": "lianjie1",
|
||||
"unicode": "e7b5",
|
||||
"unicode_decimal": 59317
|
||||
},
|
||||
{
|
||||
"icon_id": "16922947",
|
||||
"name": "章节",
|
||||
"font_class": "zhangjie",
|
||||
"unicode": "e7b6",
|
||||
"unicode_decimal": 59318
|
||||
},
|
||||
{
|
||||
"icon_id": "16771382",
|
||||
"name": "模版管理2",
|
||||
"font_class": "mobanguanli2",
|
||||
"unicode": "e7b1",
|
||||
"unicode_decimal": 59313
|
||||
},
|
||||
{
|
||||
"icon_id": "16771348",
|
||||
"name": "分组作业",
|
||||
"font_class": "fenzuzuoye2",
|
||||
"unicode": "e7b0",
|
||||
"unicode_decimal": 59312
|
||||
},
|
||||
{
|
||||
"icon_id": "16771344",
|
||||
"name": "毕业作业",
|
||||
"font_class": "biyezuoye1",
|
||||
"unicode": "e7af",
|
||||
"unicode_decimal": 59311
|
||||
},
|
||||
{
|
||||
"icon_id": "16771343",
|
||||
"name": "统计",
|
||||
"font_class": "tongji3",
|
||||
"unicode": "e7ae",
|
||||
"unicode_decimal": 59310
|
||||
},
|
||||
{
|
||||
"icon_id": "16771339",
|
||||
"name": "签到",
|
||||
"font_class": "qiandao1",
|
||||
"unicode": "e7ad",
|
||||
"unicode_decimal": 59309
|
||||
},
|
||||
{
|
||||
"icon_id": "16771338",
|
||||
"name": "分班",
|
||||
"font_class": "fenban2",
|
||||
"unicode": "e7ac",
|
||||
"unicode_decimal": 59308
|
||||
},
|
||||
{
|
||||
"icon_id": "16771329",
|
||||
"name": "讨论",
|
||||
"font_class": "taolun2",
|
||||
"unicode": "e7ab",
|
||||
"unicode_decimal": 59307
|
||||
},
|
||||
{
|
||||
"icon_id": "16771324",
|
||||
"name": "视频直播",
|
||||
"font_class": "shipinzhibo1",
|
||||
"unicode": "e7aa",
|
||||
"unicode_decimal": 59306
|
||||
},
|
||||
{
|
||||
"icon_id": "16771321",
|
||||
"name": "考试试卷",
|
||||
"font_class": "kaoshishijuan1",
|
||||
"unicode": "e7a9",
|
||||
"unicode_decimal": 59305
|
||||
},
|
||||
{
|
||||
"icon_id": "16771320",
|
||||
"name": "考试问卷",
|
||||
"font_class": "kaoshiwenjuan1",
|
||||
"unicode": "e7a7",
|
||||
"unicode_decimal": 59303
|
||||
},
|
||||
{
|
||||
"icon_id": "16768917",
|
||||
"name": "学习资源",
|
||||
"font_class": "xuexiziyuan1",
|
||||
"unicode": "e7a8",
|
||||
"unicode_decimal": 59304
|
||||
},
|
||||
{
|
||||
"icon_id": "16767292",
|
||||
"name": "普通作业",
|
||||
"font_class": "putongzuoye1",
|
||||
"unicode": "e782",
|
||||
"unicode_decimal": 59266
|
||||
},
|
||||
{
|
||||
"icon_id": "16766394",
|
||||
"name": "实训作业",
|
||||
"font_class": "shixunzuoye1",
|
||||
"unicode": "e7a6",
|
||||
"unicode_decimal": 59302
|
||||
},
|
||||
{
|
||||
"icon_id": "15852679",
|
||||
"name": "Last updated",
|
||||
"font_class": "Lastupdated",
|
||||
"unicode": "e7a5",
|
||||
"unicode_decimal": 59301
|
||||
},
|
||||
{
|
||||
"icon_id": "15852678",
|
||||
"name": "CONTACTS",
|
||||
"font_class": "CONTACTS",
|
||||
"unicode": "e7a4",
|
||||
"unicode_decimal": 59300
|
||||
},
|
||||
{
|
||||
"icon_id": "15852677",
|
||||
"name": "SPONSORS",
|
||||
"font_class": "SPONSORS",
|
||||
"unicode": "e7a3",
|
||||
"unicode_decimal": 59299
|
||||
},
|
||||
{
|
||||
"icon_id": "15852676",
|
||||
"name": "FINAL REPORTS",
|
||||
"font_class": "FINALREPORTS",
|
||||
"unicode": "e7a2",
|
||||
"unicode_decimal": 59298
|
||||
},
|
||||
{
|
||||
"icon_id": "15852675",
|
||||
"name": "STEERING COMMITTEE",
|
||||
"font_class": "STEERINGCOMMITTEE",
|
||||
"unicode": "e7a1",
|
||||
"unicode_decimal": 59297
|
||||
},
|
||||
{
|
||||
"icon_id": "15852674",
|
||||
"name": "ORGANIZING ICSE - MOU",
|
||||
"font_class": "ORGANIZINGICSE-MOU",
|
||||
"unicode": "e7a0",
|
||||
"unicode_decimal": 59296
|
||||
},
|
||||
{
|
||||
"icon_id": "15852673",
|
||||
"name": "INFLUENTIAL PAPERS",
|
||||
"font_class": "INFLUENTIALPAPERS",
|
||||
"unicode": "e79f",
|
||||
"unicode_decimal": 59295
|
||||
},
|
||||
{
|
||||
"icon_id": "15852672",
|
||||
"name": "BIBLIOGRAPHIES",
|
||||
"font_class": "BIBLIOGRAPHIES",
|
||||
"unicode": "e79e",
|
||||
"unicode_decimal": 59294
|
||||
},
|
||||
{
|
||||
"icon_id": "15852671",
|
||||
"name": "PROCEEDINGS",
|
||||
"font_class": "PROCEEDINGS",
|
||||
"unicode": "e79d",
|
||||
"unicode_decimal": 59293
|
||||
},
|
||||
{
|
||||
"icon_id": "15852670",
|
||||
"name": "HISTORY",
|
||||
"font_class": "HISTORY",
|
||||
"unicode": "e79c",
|
||||
"unicode_decimal": 59292
|
||||
},
|
||||
{
|
||||
"icon_id": "15852669",
|
||||
"name": "CONDUCT & SAFETY",
|
||||
"font_class": "CONDUCTSAFETY",
|
||||
"unicode": "e79b",
|
||||
"unicode_decimal": 59291
|
||||
},
|
||||
{
|
||||
"icon_id": "15852667",
|
||||
"name": "EDI STATEMENT",
|
||||
"font_class": "EDISTATEMENT",
|
||||
"unicode": "e79a",
|
||||
"unicode_decimal": 59290
|
||||
},
|
||||
{
|
||||
"icon_id": "15852666",
|
||||
"name": "MAILING LIST",
|
||||
"font_class": "MAILINGLIST",
|
||||
"unicode": "e799",
|
||||
"unicode_decimal": 59289
|
||||
},
|
||||
{
|
||||
"icon_id": "15852665",
|
||||
"name": "HOME",
|
||||
"font_class": "HOME",
|
||||
"unicode": "e798",
|
||||
"unicode_decimal": 59288
|
||||
},
|
||||
{
|
||||
"icon_id": "15792809",
|
||||
"name": "准备中",
|
||||
|
@ -131,13 +684,6 @@
|
|||
"unicode": "e783",
|
||||
"unicode_decimal": 59267
|
||||
},
|
||||
{
|
||||
"icon_id": "15590916",
|
||||
"name": "普通作业",
|
||||
"font_class": "putongzuoye1",
|
||||
"unicode": "e782",
|
||||
"unicode_decimal": 59266
|
||||
},
|
||||
{
|
||||
"icon_id": "15590913",
|
||||
"name": "实训作业",
|
||||
|
|
|
@ -20,6 +20,243 @@ Created by iconfont
|
|||
/>
|
||||
<missing-glyph />
|
||||
|
||||
<glyph glyph-name="zhuye1" unicode="" d="M992.192 559.616L546.816 882.304A73.6 73.6 0 0 1 503.808 896c-15.104 0-30.336-4.48-42.88-13.568L27.712 570.368a62.272 62.272 0 0 1-26.752-50.432V-128h1017.792V509.44a62.08 62.08 0 0 1-26.496 50.176z m-363.584-615.616H390.976V256.576h237.632v-312.576z m311.808 0h-233.6V292.608c0 19.84-17.472 35.968-39.04 35.968H351.808c-21.632 0-39.168-16.064-39.168-35.968v-348.608h-233.6v572.16L503.808 821.76l436.608-316.416v-561.408z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="xiangmujianjie" unicode="" d="M399.847619-93.866667H175.542857C97.52381-93.866667 34.133333-30.47619 34.133333 47.542857V744.838095C34.133333 822.857143 97.52381 886.247619 175.542857 886.247619h653.409524c78.019048 0 141.409524-63.390476 141.409524-141.409524v-263.314285h-78.019048V744.838095c0 34.133333-29.257143 63.390476-63.390476 63.390476H175.542857c-34.133333 0-63.390476-29.257143-63.390476-63.390476v-702.171428c0-34.133333 29.257143-63.390476 63.390476-63.390477h229.180953v-73.142857zM785.066667 408.380952l-180.419048 146.285715L414.47619 408.380952V822.857143h78.019048v-253.561905L604.647619 652.190476 707.047619 569.295238V822.857143h78.019048zM575.390476-15.847619h385.219048v-78.019048h-385.219048zM575.390476 369.371429h385.219048v-78.019048h-385.219048zM575.390476 164.571429h385.219048v-78.019048h-385.219048z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="canyuchengyuan" unicode="" d="M307.2-118.690909H116.363636c-60.509091 0-107.054545 46.545455-107.054545 107.054545v791.272728C9.309091 840.145455 55.854545 886.690909 116.363636 886.690909h758.690909c60.509091 0 107.054545-46.545455 107.054546-107.054545v-167.563637h-74.472727V779.636364c0 18.618182-13.963636 32.581818-32.581819 32.581818H116.363636c-18.618182 0-32.581818-13.963636-32.581818-32.581818v-791.272728c0-18.618182 13.963636-32.581818 32.581818-32.581818h190.836364v-74.472727zM716.8 123.345455c-102.4 0-190.836364 83.781818-190.836364 190.836363 0 102.4 83.781818 190.836364 190.836364 190.836364s190.836364-83.781818 190.836364-190.836364c0-102.4-83.781818-190.836364-190.836364-190.836363z m0 307.2c-65.163636 0-116.363636-51.2-116.363636-116.363637S651.636364 197.818182 716.8 197.818182s116.363636 51.2 116.363636 116.363636-51.2 116.363636-116.363636 116.363637zM1014.690909-114.036364h-74.472727c0 130.327273-107.054545 237.381818-237.381818 237.381819S465.454545 16.290909 465.454545-114.036364H386.327273c0 172.218182 139.636364 311.854545 311.854545 311.854546s316.509091-139.636364 316.509091-311.854546zM162.909091 695.854545h386.327273v-74.472727H162.909091zM162.909091 453.818182h246.690909v-74.472727H162.909091z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shiyongwendang" unicode="" d="M861.090909-118.690909H162.909091c-69.818182 0-130.327273 55.854545-130.327273 121.018182V719.127273C32.581818 784.290909 93.090909 840.145455 162.909091 840.145455h121.018182c18.618182 0 37.236364-18.618182 37.236363-37.236364s-18.618182-37.236364-37.236363-37.236364H162.909091c-32.581818 0-55.854545-23.272727-55.854546-46.545454v-716.8c0-27.927273 23.272727-46.545455 55.854546-46.545455h698.181818c32.581818 0 55.854545 23.272727 55.854546 46.545455V719.127273c0 27.927273-23.272727 46.545455-55.854546 46.545454h-116.363636c-18.618182 0-37.236364 18.618182-37.236364 37.236364s18.618182 37.236364 37.236364 37.236364H861.090909c69.818182 0 130.327273-55.854545 130.327273-121.018182v-716.8c0-65.163636-60.509091-121.018182-130.327273-121.018182zM242.036364 584.145455h539.927272v-74.472728H242.036364zM242.036364 211.781818h539.927272v-74.472727H242.036364zM242.036364 397.963636h539.927272v-74.472727H242.036364zM581.818182 779.636364H442.181818c-27.927273 0-46.545455 18.618182-46.545454 46.545454s18.618182 46.545455 46.545454 46.545455h139.636364c27.927273 0 46.545455-18.618182 46.545454-46.545455s-18.618182-46.545455-46.545454-46.545454z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="daimaku" unicode="" d="M1024-128H0V561.664L512 896l512-334.336zM72-53.184h880V521.984L512 807.744 72 521.984zM307.136 105.344l-60.928 40.896L376.576 293.76l-146.56 128.768 55.552 47.616 193.664-171.008z m206.784 96h254.592v-67.072H514.048z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="forc" unicode="" d="M796.376006 894.867675a171.32651 171.32651 0 0 0 169.950598-142.687158 169.695799 169.695799 0 0 0-116.035236-188.550889 342.60206 342.60206 0 0 0-340.410792-291.5914h-229.318648v-66.24761a170.256356 170.256356 0 0 0 114.353565-150.229194l0.305759-10.19194a171.683228 171.683228 0 1 0-229.318648 160.268255V564.750742a169.695799 169.695799 0 0 0-112.111339 188.907606 172.345704 172.345704 0 0 0 339.034881 0 169.695799 169.695799 0 0 0-112.111339-189.009526v-179.378142h229.318648a228.605212 228.605212 0 0 1 224.630355 181.263651 169.491961 169.491961 0 0 0-107.423046 189.672002A171.32651 171.32651 0 0 0 796.376006 894.867675zM223.283225 102.138589a56.616226 56.616226 0 1 1 57.329662-56.616226 56.972944 56.972944 0 0 1-57.329662 56.616226z m0 679.496634a56.616226 56.616226 0 1 1 57.329662-56.616226 56.972944 56.972944 0 0 1-57.329662 56.616226z m573.092781 0a56.616226 56.616226 0 1 1 57.329662-56.616226 56.972944 56.972944 0 0 1-57.329662 56.616226z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="dianzan3" unicode="" d="M1068.085662 794.870057a352.143618 352.143618 0 0 1-482.689072 10.604533 352.143618 352.143618 0 0 1-482.689072-10.604533 343.733127 343.733127 0 0 1-3.364196-486.784615l3.217927-3.217927 404.288665-400.119987a109.702062 109.702062 0 0 1 155.04558-1.462694l1.462695 1.389559 404.288665 399.827448a343.733127 343.733127 0 0 1 3.437331 486.784616l-3.437331 3.510466z m-52.364451-438.808247l-404.21553-399.754313a36.567354 36.567354 0 0 0-51.706239 0L154.998834 356.427484a271.476036 271.476036 0 0 0-2.559714 384.396024l2.559714 2.559715a277.91189 277.91189 0 0 0 380.739289 6.21645l49.731602-42.783804 49.292793 42.710669a277.91189 277.91189 0 0 0 380.885558-7.898548 271.69544 271.69544 0 0 0 0.731347-384.688563l-0.658212-0.585078z" horiz-adv-x="1171" />
|
||||
|
||||
|
||||
<glyph glyph-name="lichengbei" unicode="" d="M677.82464 694.784a97.6 97.6 0 1 0 0-192h-345.6a97.6 97.6 0 1 0 0 192z m0-68.608h-345.6a27.904 27.904 0 1 1 0-54.848h345.6a27.904 27.904 0 1 1 0 54.848zM521.28064-128a39.232 39.232 0 0 0-13.696 2.496l-323.264 120.512C173.12064-1.28 63.87264 37.696 63.87264 122.56V673.344a21.632 21.632 0 0 0 0 2.752 24.96 24.96 0 0 1 0 3.072C64.12864 802.752 256.44864 896 512.12864 896s448-93.248 448-216.832a22.016 22.016 0 0 0 0-2.816 24.192 24.192 0 0 1 0-2.944v-550.848c0-66.752-78.912-111.616-94.784-119.872a35.072 35.072 0 0 0-4.032-1.856l-325.632-126.144a39.36 39.36 0 0 0-14.208-2.624zM140.92864 671.68v-549.12c0-23.872 45.44-48.96 69.824-57.088l310.528-115.776 309.376 119.872c25.152 13.888 52.608 38.976 52.608 52.992V671.424v6.08 3.52c-2.88 66.496-160.64 140.096-371.2 140.096S143.55264 747.52 140.92864 680.96a41.024 41.024 0 0 0 0-9.344zM741.69664 233.344H281.98464a34.048 34.048 0 1 0 0 65.664h459.712a34.048 34.048 0 1 0 0-65.664z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="quxiaodianzan" unicode="" d="M511.851263 19.736907a32.884449 32.884449 0 0 0 16.186315-4.222516l247.784965-137.999528a45.871887 45.871887 0 0 1 48.047124 2.687056 43.504719 43.504719 0 0 1 17.84973 42.673011L793.352386 221.330098a36.211281 36.211281 0 0 0 9.596629 30.901146l208.310831 215.092449a43.568696 43.568696 0 0 1 10.108449 44.208471 44.272449 44.272449 0 0 1-35.507528 29.749551l-284.124201 43.760629a34.291955 34.291955 0 0 0-25.591011 19.641101L552.540971 869.998253a44.78427 44.78427 0 0 1-81.123505 0l-123.476629-265.250831a34.291955 34.291955 0 0 0-25.591011-19.641101l-284.188179-43.760629a44.78427 44.78427 0 0 1-35.507528-29.813528 43.440741 43.440741 0 0 1 10.108449-44.080516l208.246853-215.156427a36.275258 36.275258 0 0 0 9.59663-30.901146l-48.303034-298.327212a43.568696 43.568696 0 0 1 17.977685-42.800966 45.80791 45.80791 0 0 1 48.047124-2.495124l247.65701 137.871573A32.820472 32.820472 0 0 0 511.851263 19.736907z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="fork2" unicode="" d="M808.294199 889.365588a139.04645 139.04645 0 0 1-140.75293-137.466377 137.655986 137.655986 0 0 1 90.506599-128.365155v-33.876771L506.626604 274.021842 255.268544 589.657285v33.876771a137.655986 137.655986 0 0 1 90.506598 128.365155 140.816133 140.816133 0 1 1-181.013197-131.71491v-42.219559a53.406478 53.406478 0 0 1 11.692542-33.118336l284.918818-357.855001v-41.208312a140.816133 140.816133 0 1 1 90.506598 0v41.208312l284.918818 357.855001a53.406478 53.406478 0 0 1 11.692542 33.118336v42.219559a137.08716 137.08716 0 0 1-40.197064 269.118084z m-663.630787-137.466377a60.3588 60.3588 0 1 0 60.358801-58.905133 59.600365 59.600365 0 0 0-60.358801 58.905133z m422.321992-736.314158A60.3588 60.3588 0 1 0 506.626604 74.490186a59.600365 59.600365 0 0 0 60.3588-58.905133z m241.308795 677.409025a58.905133 58.905133 0 1 0 60.3588 58.905133 59.600365 59.600365 0 0 0-60.3588-58.905133z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="hebingqingqiu1" unicode="" d="M724.710387 544.712656a22.806357 22.806357 0 0 0-37.511352-17.291984L492.221699 691.626445a22.602121 22.602121 0 0 0 0 34.583969L687.199035 890.416187a22.874436 22.874436 0 0 0 32.133137-2.655069 22.602121 22.602121 0 0 0 5.378215-14.636916v-123.494723h77.473537a145.484136 145.484136 0 0 0 145.892608-142.965225v-374.432733a182.38278 182.38278 0 1 0-82.034808 0V604.553815a63.653565 63.653565 0 0 1-62.768542 63.449328h-78.562795z m182.382781-389.00157a99.735264 99.735264 0 1 1 100.279893-99.735265 100.007579 100.007579 0 0 1-100.279893 99.667186zM182.599868 890.143872a181.293521 181.293521 0 0 0 40.847208-358.09385v-299.546187a182.38278 182.38278 0 1 0-82.034808 0v299.546187a181.293521 181.293521 0 0 0 40.847207 358.09385z m0-734.500865a99.735264 99.735264 0 1 1 100.279894-99.735264 100.007579 100.007579 0 0 1-100.279894 99.735264z m0 652.942608a99.735264 99.735264 0 1 1 100.279894-99.735264 100.007579 100.007579 0 0 1-100.279894 99.599107z" horiz-adv-x="1092" />
|
||||
|
||||
|
||||
<glyph glyph-name="renwu" unicode="" d="M983.055019-128H40.975019a42.325333 42.325333 0 0 0-40.96 43.281067V754.2784a42.325333 42.325333 0 0 0 40.96 43.4176h214.903466v-77.277867H73.196885v-771.413333h877.636267v771.413333h-182.749867V797.764267H983.055019a42.325333 42.325333 0 0 0 40.96-43.4176v-838.929067a42.3936 42.3936 0 0 0-40.96-43.4176z m-217.770667 441.7536L427.023019 72.704a39.799467 39.799467 0 0 0-58.231467 0l-132.642133 139.810133a44.714667 44.714667 0 0 0-12.014934 30.651734 42.325333 42.325333 0 0 0 40.96 43.4176 39.936 39.936 0 0 0 29.149867-12.765867l103.492267-109.226667 309.111466 210.466134a40.072533 40.072533 0 0 0 29.0816 12.629333 42.257067 42.257067 0 0 0 40.96-43.4176 44.032 44.032 0 0 0-11.810133-30.5152z m-362.973867 484.010667h219.477334v-77.277867H402.310485z m0 0M49.644885 502.3744h875.042134v-98.372267H49.644885zM312.130219 896h35.0208c9.6256 0 17.544533-10.990933 17.544533-24.644267v-196.744533c0-13.653333-7.850667-24.644267-17.544533-24.644267h-35.0208c-9.6256 0-17.544533 10.990933-17.544534 24.644267V871.355733c0.136533 13.653333 7.645867 24.644267 17.544534 24.644267zM662.201685 896h35.0208c9.6256 0 17.544533-10.990933 17.544534-24.644267v-196.744533c0-13.653333-7.850667-24.644267-17.544534-24.644267H662.201685c-9.6256 0-17.544533 10.990933-17.544533 24.644267V871.355733c0 13.653333 7.918933 24.644267 17.544533 24.644267z m0 0" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="tongzhi" unicode="" d="M965.27314 383.870204a285.184828 285.184828 0 0 1-146.24863 248.622671c-7.312431 0-14.624863 7.312431-21.937295 7.312432a34.075931 34.075931 0 0 1-36.562157-35.538418 36.562157 36.562157 0 0 1 14.624863-28.445358A211.183021 211.183021 0 0 0 884.836393 391.182636a207.234308 207.234308 0 0 0-116.998904-191.951327 36.562157 36.562157 0 0 1-14.624863-28.445358 34.075931 34.075931 0 0 1 36.562158-35.538417 25.739759 25.739759 0 0 1 14.624863 7.312431A266.757501 266.757501 0 0 1 965.27314 383.870204z m-43.874589 419.441071c-7.312431 0-14.624863 7.312431-21.937295 7.312431a34.075931 34.075931 0 0 1-36.562157-35.538417c0-14.186117 7.312431-21.3523 21.937294-28.445358a416.004227 416.004227 0 0 0 0-725.173831c-14.624863-7.312431-21.937294-14.186117-21.937294-28.445359a34.075931 34.075931 0 0 1 36.562157-35.538417 27.348494 27.348494 0 0 1 21.937295 7.312432 478.159895 478.159895 0 0 1 0 838.88214zM87.781361 618.453007h175.498356c21.937294 0 58.499452 7.312431 212.060513 120.874492a557.865398 557.865398 0 0 0 80.436746 56.890717v-440.79337a36.562157 36.562157 0 0 1 73.124315 0v504.557773a38.97526 38.97526 0 0 1-21.937294 35.538417 111.222083 111.222083 0 0 1-51.187021-7.312432L424.153209 789.125158a567.810305 567.810305 0 0 0-160.873492-99.522193h-219.372945c-29.249726 0-43.874589-14.186117-43.874589-35.538417v-540.315563a34.075931 34.075931 0 0 1 36.562157-35.538417H292.529442c7.312431 0 36.562157-14.186117 146.24863-99.522193L555.776976-120.687569c7.312431-7.312431 14.624863-7.312431 29.249726-7.312431 7.312431 0 14.624863 0 14.624863 7.312431a38.97526 38.97526 0 0 1 21.937295 35.538418v191.731953A33.198439 33.198439 0 0 1 585.026702 135.247534a34.075931 34.075931 0 0 1-36.562157-35.538417v-120.874493a333.373752 333.373752 0 0 0-51.187021 49.797659c-138.936198 113.781434-175.498356 120.874493-197.43565 120.874492H109.718655c-21.937294 0-29.249726 7.312431-29.249726 28.445359V590.007648c-14.624863 21.3523-7.312431 28.445358 7.312432 28.445359z" horiz-adv-x="1170" />
|
||||
|
||||
|
||||
<glyph glyph-name="jinbi" unicode="" d="M0 384c0-283.29 228.71-512 512-512s512 228.71 512 512S795.29 896 512 896 0 667.29 0 384zM119.45 384c0-139.93 75.11-269.67 194.56-337.92 119.5-68.25 269.67-71.68 392.55 0S901.12 244.07 901.12 384c0 215.04-174.08 392.55-392.55 392.55-218.42 0-389.12-177.51-389.12-392.55zM904.55 384c0 85.35-27.34 167.27-78.54 232.09-61.44 47.82-146.74 75.11-228.66 75.11A390.4 390.4 0 0 1 204.8 298.65c0-85.3 27.29-167.22 78.49-232.09 61.44-47.77 146.79-78.49 232.14-78.49A394.854 394.854 0 0 1 904.55 384zM552.96 609.28l85.35-170.65 180.89-34.15-126.31-139.93 20.48-187.75-160.41 81.92-167.27-81.92 27.34 187.75-126.31 139.93 177.51 34.15 88.73 170.65M512 650.24l92.16-167.27 174.08-37.53-126.31-139.93 20.48-187.75L512 203.11l-160.41-85.35 20.48 187.75-126.31 139.93 174.08 37.53L512 650.24" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="weikaishexiangtou1" unicode="" d="M516.877174 39.855494A428.075239 428.075239 0 1 1 94.646693 467.930733a425.046204 425.046204 0 0 1 422.230481-428.075239z m0 781.149854a354.098514 354.098514 0 1 0-346.7819-354.098514A350.57886 350.57886 0 0 0 516.877174 820.984017z m0 0M937.721124 173.026399a45.179557 45.179557 0 0 1-42.065197-79.650834c30.780973-16.553039 37.9696-28.967818 38.993499-31.996854-3.071698-29.991717-149.787938-98.273003-422.699768-98.273003-268.773571 0-419.606739 70.393078-421.675868 98.273003 0 2.133124 7.188626 14.483909 36.9457 31.036948a45.712838 45.712838 0 0 1 16.425052 62.073896 44.795595 44.795595 0 0 1-59.514148 17.576938C15.401152 134.822156 0 91.370429 0 61.378711c0-130.333851 265.723204-189.314717 511.949658-189.314717s511.949658 58.959536 511.949659 189.314717c0 29.927724-14.355922 73.379451-86.178193 111.647688zM511.949658 728.534441a222.420795 222.420795 0 1 1 220.586309-222.399464A221.162252 221.162252 0 0 1 511.949658 728.534441z m-75.917868-223.53002a91.041714 91.041714 0 1 0 90.27379 91.020383 91.468339 91.468339 0 0 0-90.27379-91.020383z m0 0M983.668606 837.409068L50.640354-73.925317a13.694653 13.694653 0 0 0-19.006131 0l-21.331236 20.883279a12.94806 12.94806 0 0 0 0 18.558176L943.331239 876.850523a13.694653 13.694653 0 0 0 19.006131 0l21.331236-20.88328a12.94806 12.94806 0 0 0 0-18.558175z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="guankacaidan" unicode="" d="M0-128V896h1024v-1024H0z m731.428571 694.857143H292.571429v-36.571429h438.857142v36.571429z m0-164.571429H292.571429v-36.571428h438.857142v36.571428z m0-164.571428H292.571429v-36.571429h438.857142v36.571429z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="zhongzhishixun" unicode="" d="M758.328889 384a108.544 108.544 0 1 1-109.226667-113.777778h1.137778a110.876444 110.876444 0 0 1 108.088889 113.777778z m-108.088889 512a499.939556 499.939556 0 0 1-487.537778-512H0l216.746667-227.555556 216.746666 227.555556H270.791111a380.074667 380.074667 0 1 0 758.897778 5.688889 406.243556 406.243556 0 0 0-205.368889-359.651556 364.544 364.544 0 0 0-394.24 29.866667l-76.8-81.92a468.707556 468.707556 0 0 1 576.284444-13.198222A525.198222 525.198222 0 0 1 1115.022222 538.112 490.439111 490.439111 0 0 1 650.24 896z" horiz-adv-x="1138" />
|
||||
|
||||
|
||||
<glyph glyph-name="fuzhiniantie" unicode="" d="M872.106667 896H397.084444a151.552 151.552 0 0 1-151.324444-151.722667v-475.136a151.552 151.552 0 0 1 151.324444-151.665777h475.022223A152.007111 152.007111 0 0 1 1024 269.141333V744.277333A152.064 152.064 0 0 1 872.106667 896z m62.008889-626.858667a61.781333 61.781333 0 0 0-62.008889-62.065777H397.084444a62.179556 62.179556 0 0 0-62.008888 62.065777V744.277333a62.179556 62.179556 0 0 0 62.008888 62.122667h475.022223a61.838222 61.838222 0 0 0 62.008889-62.122667v-475.136z m-245.191112-245.475555a62.122667 62.122667 0 0 0-62.008888-62.065778H151.893333a62.577778 62.577778 0 0 0-62.577777 62.065778V498.801778a62.577778 62.577778 0 0 0 62.577777 62.122666h35.271111V650.524444h-35.271111A152.064 152.064 0 0 1 0 498.801778v-475.136A152.007111 152.007111 0 0 1 151.893333-128h475.022223a151.552 151.552 0 0 1 151.324444 151.665778v35.669333h-89.315556v-35.669333z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="gongxiangzhuomian" unicode="" d="M942.084119 257.42158A92.842512 92.842512 0 0 1 1024.003982 353.449864V796.386015A98.531391 98.531391 0 0 1 928.999696 895.998293H282.742995A94.435398 94.435398 0 0 1 187.738709 801.107785l81.919864 0.625777h672.994434v-450.04725z m-163.839727 490.950293H95.009975A98.58828 98.58828 0 0 1 0.005689 648.759594v-480.312088a92.44429 92.44429 0 0 1 95.004286-92.501179h299.235057v-141.08421H209.925339a33.393722 33.393722 0 0 1-23.893293-33.223055 29.183951 29.183951 0 0 1 23.893293-29.639062h452.265913a29.695951 29.695951 0 0 1 24.462181 29.639062 33.791944 33.791944 0 0 1-24.462181 33.223055H469.907128v141.08421h308.337264a92.44429 92.44429 0 0 1 95.004286 92.501179V648.759594A98.190059 98.190059 0 0 1 778.244392 748.087429z m13.65331-578.103926H81.356664v483.55475h710.541038v-483.55475zM473.889344 477.979434l-12.515535-27.875509s-10.808871-27.249732 24.462181-21.333297l98.986502 23.722627a17.91997 17.91997 0 0 1 12.515535 26.055067l-54.044355 97.279838a17.066638 17.066638 0 0 1-27.875509-2.958217l-11.946647-27.875509s-182.044141 74.694987-225.848512-120.376688c0 0 48.924363 112.070924 196.26634 53.361688zM412.449446 350.491647l11.946647 27.875509s9.671095 27.249732-24.462182 20.76441l-98.986501-26.111957a17.46486 17.46486 0 0 1-11.946647-26.055067l56.319906-95.459397a16.725305 16.725305 0 0 1 27.306621 3.527106l11.377759 27.875509s183.750805-69.973217 222.435185 126.293122c0.568888 0-44.942147-113.265589-193.990788-58.709235z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="tuichuquanping" unicode="" d="M604.728889-9.614222l-3.413333 304.014222 304.355555-3.185778-115.484444-115.2L1024-57.628444 953.457778-128l-233.244445 233.585778z m-185.457778 0l2.844445 304.014222-303.786667-3.185778 115.484444-115.2L0-57.628444 70.542222-128l233.244445 233.585778z m185.457778 787.228444l-3.413333-304.014222 304.355555 3.185778-115.484444 115.2L1024 825.628444 953.457778 896l-233.244445-233.585778z m-185.457778 0l2.844445-304.014222-303.786667 3.185778 115.484444 115.2L0 825.628444 70.542222 896l233.244445-233.585778z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="quanping" unicode="" d="M731.022222 896l116.053334-116.224-225.848889-226.417778 56.888889-56.888889 225.848888 226.417778L1024 602.510222V896h-292.977778z m-43.804444-620.088889l-56.888889-56.888889L853.333333-5.233778 731.591111-128H1024v294.172444l-113.777778-114.232888-223.004444 224.199111zM336.782222 491.633778l56.888889 56.888889L170.666667 772.778667 292.408889 895.601778H0v-294.172445L113.777778 715.662222z m9.102222-220.16l-225.848888-226.474667L0 165.432889V-128h292.977778l-116.053334 116.224 225.848889 226.417778z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="fuzhibanbenkudizhi1" unicode="" d="M796.444444-128H227.555556a170.666667 170.666667 0 0 0-170.666667 170.666667V668.444444a170.666667 170.666667 0 0 0 170.666667 170.666667v-113.777778a56.888889 56.888889 0 0 1-56.888889-56.888889v-625.777777a56.888889 56.888889 0 0 1 56.888889-56.888889h568.888888a56.888889 56.888889 0 0 1 56.888889 56.888889V668.444444a56.888889 56.888889 0 0 1-56.888889 56.888889V839.111111a170.666667 170.666667 0 0 0 170.666667-170.666667v-625.777777a170.666667 170.666667 0 0 0-170.666667-170.666667zM284.444444 896h455.111112v-341.333333H284.444444V896z m113.777778-227.555556h227.555556V782.222222H398.222222v-113.777778z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shiyanhuanjingdaojishi" unicode="" d="M512 896a512 512 0 1 1 512-512 513.536 513.536 0 0 1-512 512z m0-953.628444A441.628444 441.628444 0 1 0 953.457778 384 442.197333 442.197333 0 0 0 512-57.628444z m153.6 230.4a38.912 38.912 0 0 1 51.2 0 39.822222 39.822222 0 0 1 0 51.2L556.942222 396.8c0 6.371556-6.826667 6.371556-6.826666 12.8v307.2A40.903111 40.903111 0 0 1 512 755.2a41.472 41.472 0 0 1-38.684444-38.4v-326.428444a59.221333 59.221333 0 0 1 19.342222-44.771556l172.942222-172.828444z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="vncshixunjiemian-gongjulan" unicode="" d="M1069.401234 738.420432h-164.474038V817.201576A80.253091 80.253091 0 0 1 823.010166 895.982721H328.948076a80.253091 80.253091 0 0 1-81.917031-78.781145v-78.781144H82.557007A80.82907 80.82907 0 0 1 0 659.639288v-708.838305A80.82907 80.82907 0 0 1 82.557007-127.980161h986.844227A80.82907 80.82907 0 0 1 1151.958242-49.199017V659.703286a80.82907 80.82907 0 0 1-82.557008 78.717146zM328.948076 817.201576h494.06209v-78.781144H328.948076V817.201576z m740.453158-866.400593H82.557007V265.861563h369.906591v-39.358574a80.82907 80.82907 0 0 1 82.557008-78.781144h81.91703a80.82907 80.82907 0 0 1 82.557007 78.781144v39.358574h369.906591v-315.06058z m-534.380628 275.702006V384.00128h81.91703v-157.562288H535.020606z m164.474037 118.139718V384.00128a80.82907 80.82907 0 0 1-82.557007 78.781144H535.020606A80.82907 80.82907 0 0 1 452.463598 384.00128v-39.358573H82.557007V659.703286h986.844227v-315.060579h-369.906591z" horiz-adv-x="1152" />
|
||||
|
||||
|
||||
<glyph glyph-name="vncshixunjiemian-zhankai" unicode="" d="M359.799168 896h204.8a51.2 51.2 0 0 0 51.2-51.2v-921.6a51.2 51.2 0 0 0-51.2-51.2H359.799168V896zM410.999168 473.6m12.8 0l0 0q12.8 0 12.8-12.8l0-153.6q0-12.8-12.8-12.8l0 0q-12.8 0-12.8 12.8l0 153.6q0 12.8 12.8 12.8ZM551.799168 396.8l-89.6-102.4V473.6l89.6-76.8" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="vncshixunjiemian-shouqi" unicode="" d="M375.43616 896h204.8v-1024H375.43616a51.2 51.2 0 0 0-51.2 51.2V844.8a51.2 51.2 0 0 0 51.2 51.2zM503.43616 473.6m12.8 0l0 0q12.8 0 12.8-12.8l0-153.6q0-12.8-12.8-12.8l0 0q-12.8 0-12.8 12.8l0 153.6q0 12.8 12.8 12.8ZM388.23616 396.8l89.6-102.4V473.6l-89.6-76.8" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="chexiaofenzu" unicode="" d="M1228.790784-127.995733H51.199616a50.602287 50.602287 0 0 0-51.199616 49.919625V846.076961A50.602287 50.602287 0 0 0 51.199616 895.996587h406.695616a13.3119 13.3119 0 0 0 8.53327-3.413308l187.731925-175.188019H1228.790784a50.602287 50.602287 0 0 0 51.199616-49.919626v-745.551742a50.602287 50.602287 0 0 0-51.199616-49.919625zM426.663467 384.000427v-85.332694h426.663466V384.000427z" horiz-adv-x="1280" />
|
||||
|
||||
|
||||
<glyph glyph-name="chexiaogongxiang" unicode="" d="M1190.570667-128h-1100.8c-59.733333 0-89.429333 24.064-89.429334 71.594667V824.405333C0.341333 871.936 30.464 896 89.770667 896h1100.8c59.733333 0 89.429333-24.064 89.429333-71.594667v-880.810666c0-47.445333-30.122667-71.594667-89.429333-71.594667zM267.434667 625.92l-9.642667-218.965333-9.130667-204.8a13.482667 13.482667 0 0 1 3.584-9.728 13.312 13.312 0 0 1 9.642667-4.096h375.466667a13.312 13.312 0 0 1 12.032 7.68 13.397333 13.397333 0 0 1-1.962667 14.250666L550.912 322.389333a10.069333 10.069333 0 0 1 1.194667 1.450667 372.650667 372.650667 0 0 0 294.997333 187.733333 276.48 276.48 0 0 0 89.941333-15.36 15.701333 15.701333 0 0 1 5.12-0.853333 14.592 14.592 0 0 1 13.482667 8.533333 11.434667 11.434667 0 0 1-2.986667 12.970667 398.421333 398.421333 0 0 1-270.165333 123.904A409.6 409.6 0 0 1 392.789333 496.64a12.117333 12.117333 0 0 1-1.962666-2.56L267.349333 626.261333z" horiz-adv-x="1280" />
|
||||
|
||||
|
||||
<glyph glyph-name="xuanzhong1" unicode="" d="M943.108257-127.946108h-862.270406A80.837851 80.837851 0 0 0 0-47.108257v862.270406A80.837851 80.837851 0 0 0 80.837851 896h862.270406A80.837851 80.837851 0 0 0 1023.946108 815.162149v-862.270406a80.837851 80.837851 0 0 0-80.837851-80.837851zM258.142203 434.63144l-69.574443-53.460765L459.913478 114.567444A1603.176254 1603.176254 0 0 0 835.324457 615.762118l-16.490922 37.72433v-0.377243a1722.277354 1722.277354 0 0 1-403.54255-337.201621l-157.148782 118.562181z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="jingshi1" unicode="" d="M512 896A512 512 0 1 0 0 384 512.605091 512.605091 0 0 0 512 896z m-28.392727-256a13.451636 13.451636 0 0 1-13.591273-13.963636l15.592727-328.517819a7.493818 7.493818 0 0 1 7.447273-6.981818h52.177455a7.540364 7.540364 0 0 1 7.447272 6.981818l15.546182 328.517819a13.312 13.312 0 0 1-13.591273 13.963636H483.607273z m35.514182-512a49.943273 49.943273 0 1 1-49.757091 49.943273 49.850182 49.850182 0 0 1 49.757091-49.943273z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shanchu21" unicode="" d="M519.469714 896a192.512 192.512 0 0 1-191.780571-186.916571H85.549714a49.225143 49.225143 0 0 1 0-98.450286h53.979429v-550.729143c0-103.387429 69.485714-187.904 155.721143-187.904h438.637714c85.942857 0 155.721143 84.114286 155.721143 187.904V610.304h48.932571a49.225143 49.225143 0 0 1 0 98.450286h-227.620571A191.963429 191.963429 0 0 1 519.469714 896z m-100.132571-186.916571a100.205714 100.205714 0 0 0 200.082286 0z m-124.342857-745.033143c-30.500571 0-64.073143 39.387429-64.073143 95.853714V610.304h566.857143v-550.912c0-56.283429-33.609143-95.853714-64.073143-95.853714H295.067429z m0 0M355.300571 78.518857a48.018286 48.018286 0 0 1 42.24 52.224v297.728a43.190857 43.190857 0 1 1-84.48 0v-297.910857a47.762286 47.762286 0 0 1 42.24-52.041143z m152.905143 0a48.018286 48.018286 0 0 1 42.24 52.224v297.728a43.190857 43.190857 0 1 1-84.48 0v-297.910857a48.128 48.128 0 0 1 42.24-52.041143z m160.914286 0a48.018286 48.018286 0 0 1 42.24 52.224v297.728a43.190857 43.190857 0 1 1-84.48 0v-297.910857a47.542857 47.542857 0 0 1 42.203429-52.041143z m0 0" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shoucang3" unicode="" d="M797.52334 896A304.639238 304.639238 0 0 1 554.66528 769.706982 303.743241 303.743241 0 0 1 311.80722 896C139.775651 896 0 743.979047 0 557.39818a447.657548 447.657548 0 0 1 90.453107-252.543369c116.991708-182.82621 411.732304-409.598976 424.361606-419.028286a64.341172 64.341172 0 0 1 79.701134 0c12.799968 9.42931 306.7299 236.842075 424.361606 419.028286A447.657548 447.657548 0 0 1 1109.33056 557.39818C1109.33056 743.979047 969.554909 896 797.52334 896z" horiz-adv-x="1109" />
|
||||
|
||||
|
||||
<glyph glyph-name="sousuo2" unicode="" d="M475.189041-54.326884a475.163442 475.163442 0 1 0 475.163441 475.163442 475.163442 475.163442 0 0 0-475.163441-475.163442z m0 814.551273a339.387831 339.387831 0 1 1 339.38783-339.387831 339.387831 339.387831 0 0 1-339.38783 339.387831zM958.288086-127.79521a65.481526 65.481526 0 0 0-46.436079 19.250237L772.543773 30.763262a65.686316 65.686316 0 1 0 92.872156 92.872156l139.308235-139.308234a65.686316 65.686316 0 0 0-46.436078-112.122394z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="guangbiao" unicode="" d="M0 541.675558m59.054074 0l1653.514063 0q59.054074 0 59.054074-59.054074l0 0q0-59.054074-59.054074-59.054074l-1653.514063 0q-59.054074 0-59.054074 59.054074l0 0q0 59.054074 59.054074 59.054074ZM874.827048 891.629999a29.527037 29.527037 0 0 0 21.909061 0l437.000145-174.859113a29.527037 29.527037 0 0 0-10.925003-56.987181h-874.000291a29.527037 29.527037 0 0 0-10.984058 56.928127zM896.795163 73.61297a29.527037 29.527037 0 0 0-21.909061 0l-437.000146 174.859112a29.527037 29.527037 0 0 0 10.925004 56.987181h874.000291a29.527037 29.527037 0 0 0 10.984057-56.928127z" horiz-adv-x="2194" />
|
||||
|
||||
|
||||
<glyph glyph-name="QQ" unicode="" d="M510.72 886.016c-276.992 0-501.76-224.768-501.76-501.76s224.768-501.76 501.76-501.76 501.76 224.768 501.76 501.76S787.712 886.016 510.72 886.016z m230.912-636.672c-10.496-5.376-26.88 6.912-42.496 29.952-6.144-25.088-21.248-47.616-42.752-65.792 22.784-8.448 37.376-22.016 37.376-37.632 0-25.344-40.192-46.08-89.6-46.08-44.544 0-81.664 16.896-88.32 38.656h-10.752c-6.912-22.016-43.776-38.656-88.32-38.656-49.408 0-89.6 20.48-89.6 46.08 0 15.616 14.848 29.184 37.376 37.632-21.504 18.176-36.864 40.96-42.752 65.792-15.36-23.04-32-35.584-42.496-29.952-15.36 7.936-12.288 50.688 6.912 95.488 14.848 35.072 35.328 61.184 50.688 66.816-0.256 2.304-0.256 4.608-0.256 6.656 0 13.568 3.84 26.112 10.24 36.352v2.304c0 6.144 1.536 12.032 4.096 17.152 3.84 91.392 63.488 164.096 159.744 164.096s155.904-72.704 159.744-164.096c2.56-5.12 4.096-11.008 4.096-17.152v-2.304c6.4-10.24 10.24-22.784 10.24-36.352 0-2.304 0-4.608-0.256-6.656 15.616-5.632 35.84-31.744 50.688-66.816 18.688-44.8 21.76-87.552 6.4-95.488z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="yonghu" unicode="" d="M637.953132 347.721749c71.730695 40.298821 120.348995 116.815519 120.348995 204.542536 0 129.46256-105.705484 234.781234-235.641835 234.781234-129.936351 0-235.628532-105.318674-235.628532-234.781234 0-84.393085 45.041846-158.307516 112.302739-199.683878-152.041812-47.787376-262.605953-189.523471-262.605953-356.600721 0-5.058203 0.560772-9.956769 0.762363-14.97404l52.356438 0c-0.230244 4.986571-0.76134 9.914814-0.76134 14.97404 0 177.279612 144.855132 321.502341 322.909387 321.502341 178.054255 0 322.910411-144.222729 322.910411-321.502341 0-5.058203-0.532119-9.987468-0.775666-14.97404l52.371788 0c0.200568 5.016247 0.760317 9.914814 0.760317 14.97404C887.263268 158.068318 783.009855 295.982364 637.953132 347.721749zM339.389222 552.264285c0 100.588953 82.208327 182.423773 183.27107 182.423773 101.06479 0 183.272094-81.83482 183.272094-182.423773 0-100.589976-82.207303-182.423773-183.272094-182.423773C421.597549 369.840512 339.389222 451.674309 339.389222 552.264285z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="oschina" unicode="" d="M996.072727 211.781818C923.927273 13.963636 735.418182-128 512-128 230.4-128 0 100.072727 0 384S230.4 896 512 896c221.090909 0 411.927273-141.963636 481.745455-339.781818l-321.163637-116.363637c-23.272727 65.163636-86.109091 114.036364-160.581818 114.036364-95.418182 0-169.890909-76.8-169.890909-169.890909s76.8-169.890909 169.890909-169.890909c74.472727 0 137.309091 46.545455 160.581818 114.036364l323.490909-116.363637z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="you" unicode="" d="M972.772848 435.172848a72.405869 72.405869 0 0 0 0-102.381899L563.172848-76.809051a72.405869 72.405869 0 1 0-102.381899 102.418102l358.409051 358.40905-358.409051 358.372848a72.405869 72.405869 0 0 0 102.381899 102.381899z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="zuo" unicode="" d="M460.807241-76.807241L51.228963 332.807241a72.408429 72.408429 0 0 0 0 102.385518L460.807241 844.807241a72.408429 72.408429 0 0 0 102.421722 0 72.408429 72.408429 0 0 0 0-102.421723l-358.421722-358.421722 358.421722-358.385519a72.408429 72.408429 0 0 0 0-102.385518 72.408429 72.408429 0 0 0-102.421722 0z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="bianchengyuyan" unicode="" d="M969.386667-114.346667H259.413333C157.013333-114.346667 68.266667-32.426667 68.266667 76.8V704.853333C68.266667 814.08 150.186667 896 259.413333 896h716.8C1078.613333 896 1160.533333 814.08 1160.533333 704.853333v-634.88c0-102.4-81.92-184.32-191.146666-184.32zM259.413333 793.6c-47.786667 0-81.92-40.96-81.92-81.92V76.8c0-47.786667 40.96-81.92 81.92-81.92h716.8c47.786667 0 81.92 40.96 81.92 81.92V704.853333c0 47.786667-40.96 81.92-81.92 81.92H259.413333zM54.613333 561.493333h1112.746667v-102.4H54.613333zM273.066667 670.72m-68.266667 0a68.266667 68.266667 0 1 1 136.533333 0 68.266667 68.266667 0 1 1-136.533333 0ZM498.346667 670.72m-68.266667 0a68.266667 68.266667 0 1 1 136.533333 0 68.266667 68.266667 0 1 1-136.533333 0ZM750.933333 670.72m-68.266666 0a68.266667 68.266667 0 1 1 136.533333 0 68.266667 68.266667 0 1 1-136.533333 0ZM384.477867 62.805333c-6.826667 0-13.653333 0-20.48 6.826667l-129.706667 102.4c-6.826667 6.826667-13.653333 13.653333-13.653333 27.306667 0 6.826667 6.826667 20.48 13.653333 27.306666l129.706667 122.88c13.653333 13.653333 34.133333 13.653333 47.786666 0 13.653333-13.653333 13.653333-34.133333 0-47.786666l-102.4-95.573334 102.4-81.92c6.826667-13.653333 13.653333-34.133333 0-47.786666-6.826667-6.826667-13.653333-13.653333-27.306666-13.653334zM814.557867 62.805333c-13.653333 0-20.48 6.826667-27.306667 13.653334-13.653333 13.653333-6.826667 34.133333 6.826667 47.786666l102.4 81.92-102.4 88.746667c-13.653333 13.653333-13.653333 34.133333 0 47.786667 6.826667 20.48 27.306667 20.48 40.96 6.826666l129.706666-122.88c6.826667-6.826667 13.653333-13.653333 13.653334-27.306666 0-6.826667-6.826667-20.48-13.653334-27.306667l-129.706666-102.4c-6.826667-6.826667-13.653333-6.826667-20.48-6.826667zM471.586133 77.6192l226.986667 324.4032 55.978667-39.1168-226.986667-324.471467z" horiz-adv-x="1228" />
|
||||
|
||||
|
||||
<glyph glyph-name="jiantou" unicode="" d="M512 896c-281.6 0-512-230.4-512-512s230.4-512 512-512 512 230.4 512 512-230.4 512-512 512z m0-938.666667c-234.666667 0-426.666667 192-426.666667 426.666667s192 426.666667 426.666667 426.666667 426.666667-192 426.666667-426.666667-192-426.666667-426.666667-426.666667zM793.6 499.2c-17.066667 17.066667-42.666667 17.066667-59.733333 0l-221.866667-221.866667-221.866667 221.866667c-17.066667 17.066667-42.666667 17.066667-59.733333 0-17.066667-17.066667-17.066667-42.666667 0-59.733333l251.733333-251.733334c17.066667-17.066667 42.666667-17.066667 59.733334 0l251.733333 251.733334c17.066667 12.8 17.066667 42.666667 0 59.733333z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="ziyongshijuan" unicode="" d="M875.91961-115.537171H148.055415a28.572098 28.572098 0 0 0-28.572098 28.522147V854.940098A28.597073 28.597073 0 0 0 148.055415 883.512195h578.035512l178.40078-322.584975v-647.942244a28.572098 28.572098 0 0 0-28.572097-28.522147zM269.361951 248.407415v-35.665171h285.446244v35.665171z m0 99.902439v-35.665171h478.108098v35.665171z m0 107.045463v-35.715122h478.108098v35.715122z m0 99.902439v-35.715122h478.108098v35.715122zM726.065951 705.086439l178.400781-178.40078V705.086439zM726.065951 705.086439h178.400781L726.065951 883.48722z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="yigongkaishijuan" unicode="" d="M875.898246-115.487525H148.076779a28.596376 28.596376 0 0 0-28.571401 28.571401V854.966074A28.596376 28.596376 0 0 0 148.076779 883.537475h577.996439l178.396429-322.577108v-647.901466a28.596376 28.596376 0 0 0-28.571401-28.546426zM444.555011 287.68391c-60.939001 0-116.783103-34.965001-165.958879-103.945952l-1.54845-2.172825-1.423575-2.072925a35.214751 35.214751 0 0 1 0-39.960001c49.950001-71.753177 106.693203-108.116778 168.905929-108.116778 60.988951 0 116.858028 34.965001 166.008829 103.945952l1.473525 2.122875 1.44855 2.072926a35.289676 35.289676 0 0 1 0 39.960001c-49.875076 71.778152-106.818078 108.166728-168.880954 108.166727z m-175.224604 114.160728v-35.664301h478.146386v35.664301z m0 107.067828v-35.714251h478.146386V508.887491z m0 99.900002v-35.714251h478.146386V608.787493z m175.224604-518.980513a70.729202 70.729202 0 0 0-70.629302 70.654277 70.729202 70.729202 0 0 0 70.629302 70.654277 70.729202 70.729202 0 0 0 70.654277-70.654277 70.729202 70.729202 0 0 0-70.629302-70.654277z m0 113.161728a42.582376 42.582376 0 0 1-42.457501-42.457501 42.607351 42.607351 0 0 1 42.457501-42.457501 42.607351 42.607351 0 0 1 42.457501 42.457501 42.582376 42.582376 0 0 1-42.432526 42.457501zM726.073218 705.11607l178.396429-178.396429V705.11607zM726.073218 705.11607h178.396429L726.073218 883.5125z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shipin" unicode="" d="M512.000213-127.998293a508.627426 508.627426 0 0 0-362.025309 149.972771A508.627426 508.627426 0 0 0 0.002133 383.999787a508.670092 508.670092 0 0 0 149.972771 362.067975A508.627426 508.627426 0 0 0 512.000213 895.997867a508.670092 508.670092 0 0 0 362.067976-149.972771A508.670092 508.670092 0 0 0 1023.998293 383.999787a508.627426 508.627426 0 0 0-149.972771-362.025309A508.712759 508.712759 0 0 0 512.000213-127.998293zM256.001173 492.628713v-324.64945a31.743881 31.743881 0 0 1 33.365209-31.402548h445.224997a31.743881 31.743881 0 0 1 33.365208 31.402548V492.628713zM652.202354 597.33232l75.690383-83.797019H767.999253V565.929771A31.701214 31.701214 0 0 1 734.634045 597.33232z m-111.274249 0l75.690383-83.797019h85.717012L626.645117 597.33232zM429.653855 597.33232l75.647717-83.797019h85.717012L515.328201 597.33232zM318.33694 597.33232l75.690382-83.797019h85.717012L404.053951 597.33232z m-28.970558 0A31.701214 31.701214 0 0 1 256.001173 565.929771v-52.39447h112.383579L292.737036 597.33232z m178.089998-371.795939c-15.402609 0-33.407875 6.869308-33.407874 26.197235v146.602117c0 19.327928 18.005266 26.197235 33.407874 26.197235a37.589192 37.589192 0 0 0 17.8346-4.266651l126.890191-69.11974a29.397223 29.397223 0 0 0 16.682604-26.197236 29.397223 29.397223 0 0 0-16.682604-26.197235l-126.890191-69.11974a34.133205 34.133205 0 0 0-17.8346-4.095985z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shixun2" unicode="" d="M512-127.998676a508.600064 508.600064 0 0 0-361.930098 150.068578A508.68834 508.68834 0 0 0 0.001324 384a508.68834 508.68834 0 0 0 150.068578 361.930098A508.600064 508.600064 0 0 0 512 895.998676a508.68834 508.68834 0 0 0 361.930098-150.068578 508.68834 508.68834 0 0 0 150.068578-361.930098 508.644202 508.644202 0 0 0-150.068578-361.930098 508.68834 508.68834 0 0 0-361.930098-150.068578zM306.450187 648.826901A58.83571 58.83571 0 0 1 247.173099 589.152573V286.896803a58.83571 58.83571 0 0 1 59.277088-59.674329h137.047921l-40.739205-59.718466a20.568223 20.568223 0 0 1-7.415153-18.626159 27.321309 27.321309 0 0 1 29.616475-29.881302h174.123688a24.187524 24.187524 0 0 1 13.241345 4.413782c1.677237 0.971032 3.354474 1.942064 5.340676 2.957234a30.896472 30.896472 0 0 1 12.491002 19.906155 27.012344 27.012344 0 0 1-5.075849 21.142015l-40.739205 59.718466h133.296207A58.83571 58.83571 0 0 1 776.826901 286.896803V589.020159A78.477038 78.477038 0 0 1 706.471221 648.826901z m285.174435-290.956489a143.315491 143.315491 0 0 0-68.899132 26.482691l-12.579278 7.150326a73.842568 73.842568 0 0 0-14.830307 7.459291 73.842568 73.842568 0 0 1-14.830306 7.459291 61.792944 61.792944 0 0 1-34.559911 11.255143 92.689415 92.689415 0 0 1-69.163959-44.844022 22.598562 22.598562 0 0 0-20.347534-13.241345 28.821994 28.821994 0 0 0-20.347533 9.533769 24.893729 24.893729 0 0 0-13.594448 18.008229 22.068908 22.068908 0 0 0 6.135157 19.288226 162.515442 162.515442 0 0 0 118.730727 71.944642 115.552805 115.552805 0 0 0 62.763976-19.729605c3.398612-2.251029 6.444121-4.413782 9.136528-6.576534a71.547401 71.547401 0 0 1 20.479947-12.049624c28.424754-18.40547 41.357134-26.791655 52.700553-26.791655 9.224804 0 17.655127 5.517227 32.441296 15.580649a44.137817 44.137817 0 0 0 19.288226 4.899298 22.598562 22.598562 0 0 0 21.495117-12.358589c2.339304-9.489631 5.958605-32.441295-11.12273-41.04817a99.26595 99.26595 0 0 0-63.072941-22.377873z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="fangda2" unicode="" d="M860.115543 119.677826a480.813387 480.813387 0 1 1-84.350991-84.223573l145.256993-145.193283a59.631818 59.631818 0 1 1 84.287281 84.287281l-145.193283 145.129575zM94.840545 413.186143A387.734236 387.734236 0 1 0 482.511071 25.515617a388.116491 388.116491 0 0 0-387.670526 387.670526z m549.109657 45.552084H528.126864V574.497856a45.679502 45.679502 0 0 1-91.231585 0V458.738227H321.135649a45.615792 45.615792 0 0 1 0-91.167876H436.83157v-115.75963a45.679502 45.679502 0 0 1 91.231584 0V367.570351h115.75963a45.615792 45.615792 0 0 1 0 91.167876z" horiz-adv-x="1028" />
|
||||
|
||||
|
||||
<glyph glyph-name="fangzuobi" unicode="" d="M420.69248 563.665455a36.631273 36.631273 0 0 1-27.415273-9.309091 39.284364 39.284364 0 0 1-12.846545-26.717091 39.749818 39.749818 0 0 1 9.309091-28.299637 37.236364 37.236364 0 0 1 25.786182-13.265454 38.074182 38.074182 0 0 1 40.215272 36.072727 38.539636 38.539636 0 0 1-34.862545 41.611636m441.250909-348.76509a33.466182 33.466182 0 0 0-52.829091-11.450182c-13.963636 13.591273-72.843636 98.909091-72.843636 98.909091L651.325207 239.709091a31.045818 31.045818 0 0 0-43.008 6.004364L464.538298 431.336727a98.164364 98.164364 0 0 0-101.515636 6.050909 106.356364 106.356364 0 0 0-10.519273 165.841455 98.536727 98.536727 0 0 0 73.309091 25.134545 103.470545 103.470545 0 0 0 93.556364-111.429818 111.429818 111.429818 0 0 0-10.100364-38.725818l130.327273-167.563636 86.202182 64.046545a29.556364 29.556364 0 0 0 23.738181 5.399273 32.581818 32.581818 0 0 0 20.48-13.498182l50.315637-74.472727a786.944 786.944 0 0 1 81.733818 369.245091v24.855272a175.197091 175.197091 0 0 0-114.967273 130.653091H237.443025a176.872727 176.872727 0 0 0-115.29309-130.699636l-0.279273-24.808727c0-286.347636 142.382545-572.509091 390.144-705.815273a671.045818 671.045818 0 0 1 161.373091 121.856 36.119273 36.119273 0 0 0 51.618909-1.908364 44.497455 44.497455 0 0 0-4.468364-59.205818 738.304 738.304 0 0 0-191.488-139.636364 35.421091 35.421091 0 0 0-33.466182-0.558545C212.448116 18.245818 46.280844 339.456 46.280844 661.550545c0 7.214545 0 16.430545 1.070545 29.277091 0 10.379636 0.558545 19.595636 1.117091 28.485819a37.655273 37.655273 0 0 0 33.186909 37.236363A99.328 99.328 0 0 1 166.088844 855.505455V856.250182A39.284364 39.284364 0 0 0 203.883753 896h616.401454a39.144727 39.144727 0 0 0 37.981091-39.703273 99.421091 99.421091 0 0 1 84.573091-99.700363 37.469091 37.469091 0 0 0 32.861091-36.305455c0.605091-8.936727 1.117091-18.618182 1.117091-29.649454 0.512-12.846545 0.512-22.062545 0.512-29.277091a841.402182 841.402182 0 0 0-115.432727-446.324364" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shizhong" unicode="" d="M181.527 640l9.31 9.31C218.763 691.2 256 728.435 302.544 756.363c-13.963 18.618-41.89 32.581-69.818 32.581-46.545 0-83.782-37.236-83.782-79.127 0-32.582 9.31-55.854 32.582-69.818z m660.946 0l-9.31 9.31c-27.927 41.89-69.818 79.126-111.708 107.054 13.963 23.272 41.89 37.236 69.818 37.236 46.545 0 83.782-37.236 83.782-83.782 0-32.582-9.31-55.854-32.582-69.818zM521.309 765.673c-200.145 0-363.054-162.91-363.054-363.055s162.909-363.054 363.054-363.054 363.055 162.909 363.055 363.054-162.91 363.055-363.055 363.055zM679.564 332.79999999999995h-204.8V560.873h74.472v-153.6h130.328V332.79999999999995zM232.727-16.289999999999964c-13.963 0-23.272 4.654-32.582 13.963-18.618 18.618-18.618 46.545 0 65.163l97.746 93.091c18.618 18.618 46.545 18.618 65.164 0 18.618-18.618 18.618-46.545 0-65.163l-97.746-93.091c-9.309-9.31-23.273-13.964-32.582-13.964z m572.51-9.31c-13.964 0-23.273 4.655-32.582 13.964l-102.4 102.4c-18.619 18.618-18.619 46.545 0 65.163s46.545 18.618 65.163 0l102.4-102.4c18.618-18.618 18.618-46.545 0-65.163-9.309-9.31-18.618-13.964-32.582-13.964z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shangchuanshipin1" unicode="" d="M547.584-62.272H0V896h958.272v-581.888H889.6V827.52H68.48V6.4h479.104z m0 0M844.928 16.192h179.2l-242.752 330.432-242.752-330.432h162.176v-144.256h144.256z m0 0l-222.464 396.8-292.16 229.312v-459.136z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="duigou1" unicode="" d="M1155.765578 895.525596a3193.803104 3193.803104 0 0 1-740.069493-640.444753l-288.200139 225.341673L0 378.900162l497.530693-506.425758A3054.209868 3054.209868 0 0 0 1186.008802 824.958073l-30.243224 71.160528m0-0.593005z" horiz-adv-x="1186" />
|
||||
|
||||
|
||||
<glyph glyph-name="lianjie1" unicode="" d="M95.99604 26.958728a63.101397 63.101397 0 0 1 63.99736-61.885447h703.970961a62.909405 62.909405 0 0 1 63.997361 61.885447V741.041272a63.101397 63.101397 0 0 1-63.997361 61.885447h-703.970961a62.909405 62.909405 0 0 1-63.99736-61.885447zM159.9934 895.978881h703.970961A157.689495 157.689495 0 0 0 1023.957762 741.041272v-714.082544A157.497503 157.497503 0 0 0 863.964361-127.978881h-703.970961A157.689495 157.689495 0 0 0 0 26.958728V741.041272A157.497503 157.497503 0 0 0 159.9934 895.978881zM389.743923 262.021032a24.446992 24.446992 0 0 1 34.494577 0L634.213839 471.612386a24.638984 24.638984 0 0 1-35.006556 34.686569L389.551931 296.707601a24.191002 24.191002 0 0 1 0-34.686569z m127.418744 61.117479a24.254999 24.254999 0 0 1-10.623562-32.894644 52.669827 52.669827 0 0 0 4.543813-30.014761 49.917941 49.917941 0 0 0-13.695435-26.622902l-1.279947-1.151953-105.019668-104.827676-1.151953-0.831965a48.509999 48.509999 0 0 0-67.38922 0.831965l-67.38922 67.261226-0.959961 0.831966a48.318007 48.318007 0 0 0-13.247453 33.406622 47.422044 47.422044 0 0 0 14.207414 34.17459l1.471939 1.471939 104.827676 104.827676a49.661951 49.661951 0 0 0 26.622902 13.56744 50.749907 50.749907 0 0 0 29.82277-4.671807 24.574986 24.574986 0 0 1 22.271081 43.838192 99.323903 99.323903 0 0 1-59.965527 9.343614 95.548059 95.548059 0 0 1-53.245803-27.39087l-105.147663-104.95567-1.151952-1.151953v-0.319987a97.339985 97.339985 0 0 1-1.279948-136.442371l1.279948-1.279948v-0.319986l67.069233-67.069234h0.319987a96.892003 96.892003 0 0 1 68.733165-28.670817 95.612056 95.612056 0 0 1 67.709207 27.262875l1.599934 1.47194 105.019668 105.147662 1.471939 0.831966a99.003916 99.003916 0 0 1 27.070883 53.693785 97.275987 97.275987 0 0 1-9.343614 59.64554 24.702981 24.702981 0 0 1-33.086636 11.13554zM831.965681 539.38559a98.043956 98.043956 0 0 1-26.942888 67.389221l-1.471939 1.471939-67.389221 67.38922A97.659972 97.659972 0 0 1 666.980487 703.986801a95.99604 95.99604 0 0 1-67.38922-27.070884l-1.599934-1.279947-105.019668-104.827676-1.151953-1.471939a95.484061 95.484061 0 0 1-27.262875-53.885777 98.235948 98.235948 0 0 1 9.21562-59.837532 24.638984 24.638984 0 0 1 43.710197 22.719063 50.365922 50.365922 0 0 0-4.543813 29.82277 49.533957 49.533957 0 0 0 13.695435 26.302915l1.47194 1.279947L632.933891 640.565417l0.959961 1.471939a50.045936 50.045936 0 0 0 33.21463 12.799472 48.318007 48.318007 0 0 0 34.494577-14.335409l67.069233-67.38922 1.151953-0.511979a50.045936 50.045936 0 0 0 12.799472-33.406622 46.910065 46.910065 0 0 0-14.207414-34.17459v-0.319987l-0.959961-0.95996-105.147662-104.827676a47.486041 47.486041 0 0 0-26.622902-13.887427 49.789946 49.789946 0 0 0-29.82277 4.863799 25.086965 25.086965 0 0 1-33.21463-10.943548 24.766978 24.766978 0 0 1 11.135541-33.086636 96.636014 96.636014 0 0 1 59.64554-9.023627 95.164074 95.164074 0 0 1 53.56579 27.262875l104.827676 104.827676 1.279947 1.471939a96.572016 96.572016 0 0 1 28.414828 68.86116z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="zhangjie" unicode="" d="M773.902013 896A123.083076 123.083076 0 0 0 895.918512 769.84518v-834.789101a63.994667 63.994667 0 0 0-61.008249-63.056079 82.211816 82.211816 0 0 0-28.712274 7.423381l-240.449296 126.154821a110.92409 110.92409 0 0 1-107.63903 0l-240.406633-126.154821a63.141405 63.141405 0 0 0-82.553121 25.981835 71.802016 71.802016 0 0 0-7.167402 29.864178V773.599533a121.547204 121.547204 0 0 0 118.432797 122.44313z m-71.759353-474.84043h-383.968003a40.828598 40.828598 0 0 1 0-81.614532h383.968003a40.529956 40.529956 0 0 1 39.463378 40.828598 43.132406 43.132406 0 0 1-39.463378 40.828597z m0 237.420215h-383.968003a40.529956 40.529956 0 0 1-39.463378-40.828598 39.847346 39.847346 0 0 1 39.463378-37.116907h383.968003a40.529956 40.529956 0 0 1 39.463378 40.828598 42.663111 42.663111 0 0 1-39.463378 37.116907z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="mobanguanli2" unicode="" d="M1133.714286-120.685714H36.571429V201.142857h73.142857v-248.685714h950.857143V201.142857h73.142857zM943.542857 91.428571h-731.428571V896h731.428571v-804.571429z m-658.285714 73.142858h585.142857V822.857143h-585.142857v-658.285714zM416.914286 618.057143h343.771428v-73.142857H416.914286zM416.914286 420.571429h343.771428v-73.142858H416.914286z" horiz-adv-x="1170" />
|
||||
|
||||
|
||||
<glyph glyph-name="fenzuzuoye2" unicode="" d="M585.142857-79.945143l-21.942857 7.314286c-29.257143 14.628571-58.514286 21.942857-80.457143 29.257143-65.828571 21.942857-131.657143 29.257143-204.8 36.571428-51.2 7.314286-117.028571 0-182.857143-14.628571-36.571429-7.314286-80.457143 14.628571-87.771428 58.514286v709.485714c0 36.571429 29.257143 73.142857 65.828571 73.142857 73.142857 7.314286 131.657143 7.314286 168.228572 7.314286h14.628571c51.2-7.314286 109.714286-14.628571 182.857143-36.571429 51.2-14.628571 73.142857-21.942857 87.771428-29.257143 29.257143-7.314286 51.2-7.314286 58.514286-7.314285 14.628571 0 102.4 29.257143 138.971429 36.571428 21.942857 7.314286 36.571429 14.628571 43.885714 14.628572 36.571429 7.314286 65.828571 14.628571 109.714286 21.942857 43.885714 7.314286 124.342857 7.314286 226.742857 0 36.571429 0 65.828571-36.571429 65.828571-73.142857v-702.171429c0-43.885714-29.257143-73.142857-73.142857-73.142857h-14.628571c-73.142857 14.628571-138.971429 21.942857-190.171429 21.942857-73.142857 0-146.285714-14.628571-219.428571-36.571429-21.942857-7.314286-43.885714-14.628571-58.514286-29.257142l-29.257143-14.628572z m-351.085714 153.6h43.885714c73.142857-7.314286 146.285714-21.942857 219.428572-43.885714 29.257143-7.314286 58.514286-14.628571 87.771428-29.257143 21.942857 7.314286 36.571429 21.942857 65.828572 29.257143 80.457143 29.257143 160.914286 43.885714 248.685714 43.885714 58.514286 0 131.657143-7.314286 204.8-21.942857l-7.314286 702.171429c-124.342857 14.628571-182.857143 7.314286-212.114286 0-36.571429-7.314286-73.142857-14.628571-102.4-21.942858-7.314286 0-21.942857-7.314286-43.885714-14.628571-87.771429-21.942857-131.657143-36.571429-153.6-36.571429-14.628571 0-29.257143 0-51.2 7.314286H512l7.314286 21.942857-7.314286-14.628571c-7.314286 0-73.142857 21.942857-95.085714 21.942857-65.828571 21.942857-117.028571 29.257143-168.228572 36.571429h-14.628571c-29.257143 0-87.771429 0-160.914286-7.314286v-694.857143c58.514286 14.628571 109.714286 21.942857 160.914286 21.942857zM548.571429 739.254857h73.142857v-775.314286h-73.142857zM160.914286 578.340571h226.742857v-73.142857H160.914286zM160.914286 344.283429h226.742857v-73.142858H160.914286zM782.628571 578.340571h226.742858v-73.142857h-226.742858zM782.628571 344.283429h226.742858v-73.142858h-226.742858z" horiz-adv-x="1170" />
|
||||
|
||||
|
||||
<glyph glyph-name="biyezuoye1" unicode="" d="M593.92 343.04L6.826667 581.973333 546.133333 841.386667c27.306667 13.653333 61.44 13.653333 88.746667 0l539.306667-238.933334-580.266667-259.413333zM177.493333 588.8L593.92 418.133333l416.426667 184.32L607.573333 786.773333c-6.826667 6.826667-20.48 6.826667-27.306666 0L177.493333 588.8zM54.613333 602.453333h68.266667v-361.813333h-68.266667zM109.226667 254.293333m-68.266667 0a68.266667 68.266667 0 1 1 136.533333 0 68.266667 68.266667 0 1 1-136.533333 0ZM279.893333 124.586667c191.146667-286.72 416.426667-286.72 682.666667-13.653334 163.84 170.666667-129.706667-116.053333-334.506667-116.053333-95.573333 0-211.626667 40.96-348.16 129.706667zM1037.653333 1.706667c-20.48 0-40.96 13.653333-40.96 34.133333-6.826667 47.786667-20.48 81.92-40.96 102.4-20.48 13.653333-40.96 20.48-75.093333 13.653333-20.48 0-40.96 13.653333-47.786667 34.133334 0 20.48 13.653333 40.96 34.133334 47.786666 54.613333 6.826667 102.4 0 136.533333-27.306666 40.96-34.133333 61.44-81.92 68.266667-157.013334 13.653333-20.48-6.826667-40.96-34.133334-47.786666 6.826667 0 0 0 0 0z" horiz-adv-x="1174" />
|
||||
|
||||
|
||||
<glyph glyph-name="tongji3" unicode="" d="M463.811765-73.788235C228.894118-73.788235 30.117647 118.964706 30.117647 353.882353c0 234.917647 192.752941 427.670588 433.694118 427.670588v-60.235294C259.011765 721.317647 90.352941 558.682353 90.352941 353.882353s168.658824-367.435294 373.458824-367.435294c198.776471 0 379.482353 156.611765 391.529411 337.317647H445.741176v60.235294h475.858824V353.882353c-6.023529-228.894118-210.823529-427.670588-457.788235-427.670588zM433.694118 775.529412h60.235294v-457.788236h-60.235294zM433.332706 381.711059l433.694118 4.698353 0.602352-60.235294-433.694117-4.698353zM969.788235 504.470588h-60.235294c0 162.635294-132.517647 301.176471-301.17647 301.176471v60.235294c198.776471 0 361.411765-162.635294 361.411764-361.411765zM969.788235 468.329412H578.258824V859.858824h60.235294v-331.294118h331.294117z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="qiandao1" unicode="" d="M984.615385-128h-866.461539C55.138462-128 0-72.861538 0-9.846154v708.923077C0 762.092308 55.138462 817.230769 118.153846 817.230769h866.461539c63.015385 0 118.153846-55.138462 118.153846-118.153846v-708.923077c0-63.015385-55.138462-118.153846-118.153846-118.153846zM118.153846 738.461538c-23.630769 0-39.384615-15.753846-39.384615-39.384615v-708.923077c0-23.630769 15.753846-39.384615 39.384615-39.384615h866.461539c23.630769 0 39.384615 15.753846 39.384615 39.384615v708.923077c0 23.630769-15.753846 39.384615-39.384615 39.384615h-866.461539zM315.076923 896h78.769231v-236.307692H315.076923zM504.123077 92.553846L299.323077 352.492308l63.015385 47.261538 141.784615-189.046154 299.323077 322.953846 55.138461-55.138461zM669.538462 896h78.76923v-236.307692h-78.76923z" horiz-adv-x="1102" />
|
||||
|
||||
|
||||
<glyph glyph-name="fenban2" unicode="" d="M354.986667 356.693333c-129.706667 0-232.106667 109.226667-232.106667 238.933334S225.28 834.56 354.986667 834.56c109.226667 0 204.8-81.92 232.106666-197.973333l-61.44-13.653334C512 711.68 443.733333 766.293333 354.986667 766.293333c-95.573333 0-170.666667-81.92-170.666667-177.493333s81.92-177.493333 170.666667-177.493333v-54.613334zM559.786667 206.506667c-136.533333 0-238.933333 109.226667-238.933334 238.933333S430.08 691.2 559.786667 691.2s238.933333-109.226667 238.933333-238.933333-102.4-245.76-238.933333-245.76z m0 416.426666C464.213333 622.933333 389.12 547.84 389.12 452.266667S464.213333 281.6 559.786667 281.6s170.666667 75.093333 170.666666 170.666667S655.36 622.933333 559.786667 622.933333zM116.053333 110.933333H61.44C54.613333 281.6 191.146667 418.133333 354.986667 418.133333v-61.44c-129.706667 0-238.933333-109.226667-238.933334-245.76zM921.6-114.346667h-68.266667c0 157.013333-129.706667 286.72-286.72 286.72s-286.72-129.706667-286.72-286.72h-68.266666c0 197.973333 157.013333 354.986667 354.986666 354.986667 191.146667 0 354.986667-157.013333 354.986667-354.986667z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="taolun2" unicode="" d="M118.153846-128c-23.630769 0-31.507692 0-39.384615 7.876923-31.507692 15.753846-23.630769 55.138462-7.876923 126.030769 15.753846 78.769231 15.753846 94.523077 7.876923 118.153846-55.138462 78.769231-78.769231 173.292308-78.769231 267.815385C0 667.569231 244.184615 896 551.384615 896s551.384615-228.430769 551.384616-504.123077-244.184615-504.123077-551.384616-504.123077c-55.138462 0-110.276923 7.876923-157.538461 23.630769-23.630769 7.876923-47.261538 0-141.784616-15.753846h-7.876923c-63.015385-23.630769-102.4-23.630769-126.030769-23.630769zM551.384615 817.230769C291.446154 817.230769 78.769231 628.184615 78.769231 391.876923c0-78.769231 23.630769-157.538462 70.892307-220.553846 31.507692-55.138462 23.630769-102.4 7.876924-181.169231 0-15.753846-7.876923-31.507692-7.876924-39.384615 15.753846 0 39.384615 7.876923 78.769231 15.753846H236.307692c102.4 15.753846 133.907692 23.630769 181.169231 15.753846 47.261538-15.753846 94.523077-15.753846 141.784615-15.753846 259.938462 0 472.615385 189.046154 472.615385 425.353846C1024 628.184615 811.323077 817.230769 551.384615 817.230769zM315.076923 226.461538c-63.015385 0-118.153846 55.138462-118.153846 118.153847S252.061538 462.769231 315.076923 462.769231s118.153846-55.138462 118.153846-118.153846S378.092308 226.461538 315.076923 226.461538z m0 157.538462c-23.630769 0-39.384615-15.753846-39.384615-39.384615s15.753846-39.384615 39.384615-39.384616 39.384615 15.753846 39.384615 39.384616-15.753846 39.384615-39.384615 39.384615zM551.384615 226.461538c-63.015385 0-118.153846 55.138462-118.153846 118.153847S488.369231 462.769231 551.384615 462.769231s118.153846-55.138462 118.153847-118.153846S614.4 226.461538 551.384615 226.461538z m0 157.538462c-23.630769 0-39.384615-15.753846-39.384615-39.384615s15.753846-39.384615 39.384615-39.384616 39.384615 15.753846 39.384616 39.384616-15.753846 39.384615-39.384616 39.384615zM787.692308 226.461538c-63.015385 0-118.153846 55.138462-118.153846 118.153847s55.138462 118.153846 118.153846 118.153846 118.153846-55.138462 118.153846-118.153846-55.138462-118.153846-118.153846-118.153847z m0 157.538462c-23.630769 0-39.384615-15.753846-39.384616-39.384615s15.753846-39.384615 39.384616-39.384616 39.384615 15.753846 39.384615 39.384616-15.753846 39.384615-39.384615 39.384615z" horiz-adv-x="1102" />
|
||||
|
||||
|
||||
<glyph glyph-name="shipinzhibo1" unicode="" d="M884.363636-128h-744.727272C65.163636-128 0-62.836364 0 11.636364v744.727272C0 830.836364 65.163636 896 139.636364 896h744.727272c74.472727 0 139.636364-65.163636 139.636364-139.636364v-744.727272c0-74.472727-65.163636-139.636364-139.636364-139.636364z m-744.727272 930.909091c-27.927273 0-46.545455-18.618182-46.545455-46.545455v-744.727272c0-27.927273 18.618182-46.545455 46.545455-46.545455h744.727272c27.927273 0 46.545455 18.618182 46.545455 46.545455v744.727272c0 27.927273-18.618182 46.545455-46.545455 46.545455h-744.727272zM1340.509091 11.636364l-372.363636 186.181818V495.709091l372.363636 167.563636v-651.636363z m-279.272727 242.036363l186.181818-93.090909V523.636364l-186.181818-83.781819v-186.181818zM186.181818 709.818182h186.181818v-93.090909H186.181818z" horiz-adv-x="1396" />
|
||||
|
||||
|
||||
<glyph glyph-name="kaoshishijuan1" unicode="" d="M443.733333-93.866667H136.533333c-54.613333 0-102.4 47.786667-102.4 102.4V759.466667C34.133333 814.08 81.92 861.866667 136.533333 861.866667h614.4c54.613333 0 102.4-47.786667 102.4-102.4v-327.68h-68.266666V759.466667c0 20.48-13.653333 34.133333-34.133334 34.133333H136.533333c-20.48 0-34.133333-13.653333-34.133333-34.133333v-750.933334c0-20.48 13.653333-34.133333 34.133333-34.133333h307.2v-68.266667zM750.933333 76.8c-75.093333 0-136.533333 61.44-136.533333 136.533333s61.44 136.533333 136.533333 136.533334 136.533333-61.44 136.533334-136.533334-61.44-136.533333-136.533334-136.533333z m0 204.8c-40.96 0-68.266667-27.306667-68.266666-68.266667s27.306667-68.266667 68.266666-68.266666 68.266667 27.306667 68.266667 68.266666-27.306667 68.266667-68.266667 68.266667zM989.866667-93.866667h-68.266667c0 95.573333-75.093333 170.666667-170.666667 170.666667s-170.666667-75.093333-170.666666-170.666667h-68.266667c0 129.706667 109.226667 238.933333 238.933333 238.933334s238.933333-109.226667 238.933334-238.933334zM580.266667 554.666667h-341.333334c-20.48 0-34.133333 13.653333-34.133333 34.133333s13.653333 34.133333 34.133333 34.133333h341.333334c20.48 0 34.133333-13.653333 34.133333-34.133333s-13.653333-34.133333-34.133333-34.133333zM512 349.866667h-273.066667c-20.48 0-34.133333 13.653333-34.133333 34.133333s13.653333 34.133333 34.133333 34.133333h273.066667c20.48 0 34.133333-13.653333 34.133333-34.133333s-13.653333-34.133333-34.133333-34.133333zM204.8 213.333333h204.8v-68.266666H204.8z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="kaoshiwenjuan1" unicode="" d="M471.811482-80.71359H161.957516c-53.887646 0-101.039337 47.151691-101.039337 101.039337V761.280884C60.918179 815.16853 108.06987 862.320221 161.957516 862.320221h606.236021c53.887646 0 101.039337-47.151691 101.039337-101.039337v-282.910143h-67.359558V761.280884c0 20.207867-13.471912 33.679779-33.679779 33.679779H161.957516c-20.207867 0-33.679779-13.471912-33.679779-33.679779v-740.955137c0-20.207867 13.471912-33.679779 33.679779-33.679779h309.853966v-67.359558zM700.83398-47.033811c-114.511249 0-202.078674 87.567425-202.078674 202.078674s87.567425 202.078674 202.078674 202.078673 202.078674-87.567425 202.078673-202.078673-87.567425-202.078674-202.078673-202.078674z m0 336.797789c-74.095514 0-134.719116-60.623602-134.719116-134.719115s60.623602-134.719116 134.719116-134.719116 134.719116 60.623602 134.719115 134.719116-60.623602 134.719116-134.719115 134.719115zM821.946465-13.69083l47.623207 47.623207 114.30917-114.30917-47.623207-47.623207zM599.794643 559.20221h-336.79779c-20.207867 0-33.679779 13.471912-33.679779 33.679779s13.471912 33.679779 33.679779 33.679779h336.79779c20.207867 0 33.679779-13.471912 33.679779-33.679779s-13.471912-33.679779-33.679779-33.679779zM397.715969 357.123536h-134.719116c-20.207867 0-33.679779 13.471912-33.679779 33.679779s13.471912 33.679779 33.679779 33.679779h134.719116c20.207867 0 33.679779-13.471912 33.679779-33.679779s-13.471912-33.679779-33.679779-33.679779z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="xuexiziyuan1" unicode="" d="M1024-64.984615H78.769231c-47.261538 0-78.769231 31.507692-78.769231 78.76923v787.692308c0 47.261538 31.507692 78.769231 78.769231 78.769231h315.076923l157.538461-165.415385h472.615385c47.261538 0 78.769231-31.507692 78.769231-78.769231v-622.276923c0-39.384615-31.507692-78.769231-78.769231-78.76923zM78.769231 801.476923v-787.692308h945.230769V636.061538H519.876923l-157.538461 165.415385H78.769231zM0 462.769231h1024v-78.769231H0zM118.153846 226.461538h315.076923v-78.76923h-315.076923zM984.615385 817.230769h-315.076923C645.907692 817.230769 630.153846 832.984615 630.153846 856.615385s15.753846 39.384615 39.384616 39.384615h315.076923c23.630769 0 39.384615-15.753846 39.384615-39.384615s-15.753846-39.384615-39.384615-39.384616z" horiz-adv-x="1102" />
|
||||
|
||||
|
||||
<glyph glyph-name="putongzuoye1" unicode="" d="M832-96H128c-51.2 0-96 44.8-96 96V768C32 819.2 76.8 864 128 864h544v-64H128c-19.2 0-32-12.8-32-32v-768c0-19.2 12.8-32 32-32h704c19.2 0 32 12.8 32 32V294.4c0 19.2 12.8 32 32 32s32-12.8 32-32V0c0-51.2-44.8-96-96-96zM480 576h-256c-19.2 0-32 12.8-32 32s12.8 32 32 32h256c19.2 0 32-12.8 32-32s-12.8-32-32-32zM416 384h-192c-19.2 0-32 12.8-32 32s12.8 32 32 32h192c19.2 0 32-12.8 32-32s-12.8-32-32-32zM512 230.4V409.6l320 384c19.2 25.6 51.2 44.8 89.6 44.8 32 0 70.4-6.4 96-32 51.2-44.8 64-128 12.8-179.2l-320-384-198.4-12.8zM576 384v-89.6l102.4 6.4 300.8 358.4c25.6 25.6 19.2 70.4-6.4 89.6-12.8 19.2-25.6 25.6-44.8 25.6-19.2 0-32-6.4-44.8-25.6L576 384zM729.6 96H192c-19.2 0-32 12.8-32 32s12.8 32 32 32h537.6c19.2 0 32-12.8 32-32s-12.8-32-32-32z" horiz-adv-x="1088" />
|
||||
|
||||
|
||||
<glyph glyph-name="shixunzuoye1" unicode="" d="M914.285714 91.428571h-804.571428C51.2 91.428571 0 142.628571 0 201.142857v585.142857C0 844.8 51.2 896 109.714286 896h804.571428c58.514286 0 109.714286-51.2 109.714286-109.714286v-585.142857c0-58.514286-51.2-109.714286-109.714286-109.714286zM109.714286 822.857143c-21.942857 0-36.571429-14.628571-36.571429-36.571429v-585.142857c0-21.942857 14.628571-36.571429 36.571429-36.571428h804.571428c21.942857 0 36.571429 14.628571 36.571429 36.571428v585.142857c0 21.942857-14.628571 36.571429-36.571429 36.571429h-804.571428zM0 310.857143h950.857143v-73.142857H0zM256-54.857143H804.571429v-73.142857H256zM248.685714 362.057143l-146.285714 182.857143 146.285714 226.742857 58.514286-43.885714-117.028571-175.542858 117.028571-146.285714zM760.685714 362.057143l-58.514285 43.885714 117.028571 146.285714-117.028571 175.542858 58.514285 43.885714 146.285715-226.742857zM351.085714 413.257143l263.314286 351.085714 58.514286-43.885714-263.314286-351.085714zM365.714286 164.571429h73.142857v-219.428572H365.714286zM585.142857 164.571429h73.142857v-219.428572H585.142857z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="Lastupdated" unicode="" d="M512-107.52c-281.6 0-512 225.28-512 501.76S230.4 896 512 896s512-225.28 512-501.76-230.4-501.76-512-501.76z m0 931.84c-240.64 0-440.32-194.56-440.32-430.08s199.68-430.08 440.32-430.08 440.32 194.56 440.32 430.08-199.68 430.08-440.32 430.08zM547.84 102.4H476.16v215.04H261.12V389.12h215.04V609.28h71.68v-220.16h215.04v-71.68h-215.04z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="CONTACTS" unicode="" d="M599.771429-69.485714l-14.628572 68.266666c107.27619 19.504762 199.92381 87.771429 258.438095 190.171429l58.514286-34.133333c-68.266667-121.904762-180.419048-199.92381-302.323809-224.304762zM146.285714 452.266667l-68.266666 9.752381C107.27619 700.952381 297.447619 881.371429 521.752381 881.371429s414.47619-180.419048 443.733333-419.352381l-68.266666-4.876191c-24.380952 204.8-185.295238 355.961905-375.466667 355.961905-190.171429 0-351.085714-156.038095-375.466667-360.838095zM112.152381 159.695238c-48.761905 0-87.771429 39.009524-87.771429 87.771429v126.780952c0 48.761905 39.009524 87.771429 87.771429 87.771429s87.771429-39.009524 87.771429-87.771429v-131.657143c-4.87619-43.885714-43.885714-82.895238-87.771429-82.895238z m0 234.057143c-9.752381 0-19.504762-9.752381-19.504762-19.504762v-131.657143c0-9.752381 9.752381-19.504762 19.504762-19.504762s19.504762 9.752381 19.504762 19.504762v131.657143c-4.87619 9.752381-14.628571 19.504762-19.504762 19.504762zM536.380952-103.619048h-97.523809c-34.133333 0-63.390476 29.257143-63.390476 63.390477 0 34.133333 29.257143 63.390476 63.390476 63.390476h97.523809c34.133333 0 63.390476-29.257143 63.390477-63.390476 0-39.009524-29.257143-63.390476-63.390477-63.390477zM911.847619 159.695238c-48.761905 0-87.771429 39.009524-87.771429 87.771429v126.780952c0 48.761905 39.009524 87.771429 87.771429 87.771429s87.771429-39.009524 87.771429-87.771429v-131.657143c0-43.885714-39.009524-82.895238-87.771429-82.895238z m0 234.057143c-9.752381 0-19.504762-9.752381-19.504762-19.504762v-131.657143c0-9.752381 9.752381-19.504762 19.504762-19.504762s19.504762 9.752381 19.504762 19.504762v131.657143c0 9.752381-9.752381 19.504762-19.504762 19.504762z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="SPONSORS" unicode="" d="M489.73913 392.904348c-138.017391 0-253.773913 111.304348-253.773913 253.773913S347.269565 896 489.73913 896s253.773913-111.304348 253.773913-253.773913-115.756522-249.321739-253.773913-249.321739z m0 440.765217c-102.4 0-191.443478-84.591304-191.443478-191.443478S382.886957 455.234783 489.73913 455.234783c102.4 0 191.443478 84.591304 191.443479 191.443478s-89.043478 186.991304-191.443479 186.991304zM120.208696-105.73913L115.756522-83.478261c-8.904348 35.617391-13.356522 66.782609-13.356522 102.4 0 222.608696 182.53913 405.147826 405.147826 405.147826s405.147826-182.53913 405.147826-405.147826c0-31.165217-4.452174-66.782609-13.356522-97.947826l-4.452173-22.26087-774.678261-4.452173zM507.547826 361.73913c-186.991304 0-342.817391-155.826087-342.817391-342.817391 0-22.26087 0-44.521739 4.452174-62.330435L845.913043-38.956522c4.452174 17.808696 4.452174 40.069565 4.452174 57.878261 0 186.991304-155.826087 342.817391-342.817391 342.817391zM512-38.956522l-106.852174 289.391305 106.852174 120.208695 97.947826-120.208695L512-38.956522z m-31.165217 276.034783l31.165217-89.043478 31.165217 89.043478-31.165217 35.617391-31.165217-35.617391z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="FINALREPORTS" unicode="" d="M633.904762-98.742857H219.428571c-73.142857 0-131.657143 58.514286-131.657142 131.657143V749.714286C87.771429 822.857143 146.285714 881.371429 219.428571 881.371429h580.266667c73.142857 0 131.657143-58.514286 131.657143-131.657143v-516.876191l-297.447619-331.580952zM219.428571 813.104762c-34.133333 0-63.390476-29.257143-63.390476-63.390476v-716.8c0-34.133333 29.257143-63.390476 63.390476-63.390476h385.219048l263.314286 287.695238V749.714286c0 34.133333-29.257143 63.390476-63.390476 63.390476H219.428571zM653.409524-64.609524h-68.266667v341.333334h312.076191v-68.266667h-243.809524zM238.933333 652.190476h570.514286v-68.266666H238.933333zM238.933333 447.390476h570.514286v-68.266666H238.933333z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="STEERINGCOMMITTEE" unicode="" d="M409.6 389.389474C269.473684 389.389474 156.294737 502.568421 156.294737 642.694737S269.473684 896 409.6 896s253.305263-113.178947 253.305263-253.305263-113.178947-253.305263-253.305263-253.305263z m0 431.157894c-97.010526 0-177.852632-80.842105-177.852632-177.852631S312.589474 464.842105 409.6 464.842105s177.852632 80.842105 177.852632 177.852632-80.842105 177.852632-177.852632 177.852631zM689.852632 340.884211V416.336842c97.010526 0 177.852632 80.842105 177.852631 177.852632 0 75.452632-48.505263 140.126316-118.568421 167.073684l26.947369 70.063158c102.4-37.726316 167.073684-129.347368 167.073684-237.136842 0-140.126316-113.178947-253.305263-253.305263-253.305263zM1050.947368-30.989474l-75.452631 16.168421c5.389474 21.557895 5.389474 43.115789 5.389474 70.063158 0 156.294737-123.957895 280.252632-280.252632 280.252632V416.336842c194.021053 0 355.705263-161.684211 355.705263-355.705263 5.389474-32.336842 0-64.673684-5.389474-91.621053zM37.726316-122.610526l-5.389474 26.947368c-10.778947 32.336842-16.168421 70.063158-16.168421 107.789474 0 226.357895 183.242105 414.989474 409.6 414.989473 226.357895 0 409.6-188.631579 409.6-414.989473 0-32.336842-5.389474-64.673684-10.778947-97.010527l-5.389474-26.947368-781.473684-10.778947z m388.042105 474.273684c-183.242105 0-334.147368-150.905263-334.147368-339.536842 0-21.557895 0-37.726316 5.389473-59.284211l662.905263 5.389474c0 16.168421 5.389474 32.336842 5.389474 53.894737 0 188.631579-150.905263 339.536842-339.536842 339.536842z" horiz-adv-x="1077" />
|
||||
|
||||
|
||||
<glyph glyph-name="ORGANIZINGICSE-MOU" unicode="" d="M614.4 537.6H450.56C373.76 537.6 312.32 604.16 312.32 675.84V757.76C312.32 834.56 373.76 896 450.56 896H614.4c76.8 0 138.24-61.44 138.24-138.24v-81.92C752.64 604.16 691.2 537.6 614.4 537.6zM450.56 824.32c-35.84 0-66.56-30.72-66.56-66.56v-81.92c0-35.84 30.72-66.56 66.56-66.56H614.4c35.84 0 66.56 30.72 66.56 66.56V757.76c0 35.84-30.72 66.56-66.56 66.56H450.56zM302.08-92.16H138.24c-76.8 0-138.24 61.44-138.24 138.24V128c0 76.8 61.44 138.24 138.24 138.24h163.84c76.8 0 138.24-61.44 138.24-138.24v-81.92c0-76.8-61.44-138.24-138.24-138.24z m-163.84 286.72c-35.84 0-66.56-30.72-66.56-66.56v-81.92c0-35.84 30.72-66.56 66.56-66.56h163.84c35.84 0 66.56 30.72 66.56 66.56V128c0 35.84-30.72 66.56-66.56 66.56H138.24zM936.96-92.16h-163.84c-76.8 0-138.24 61.44-138.24 138.24V128c0 76.8 61.44 138.24 138.24 138.24h163.84c76.8 0 138.24-61.44 138.24-138.24v-81.92c0-76.8-61.44-138.24-138.24-138.24z m-163.84 286.72c-35.84 0-66.56-30.72-66.56-66.56v-81.92c0-35.84 30.72-66.56 66.56-66.56h163.84c35.84 0 66.56 30.72 66.56 66.56V128c0 35.84-30.72 66.56-66.56 66.56h-163.84zM890.88 266.24H819.2v107.52H256v-107.52H184.32V445.44h317.44V537.6h71.68v-92.16h317.44z" horiz-adv-x="1075" />
|
||||
|
||||
|
||||
<glyph glyph-name="INFLUENTIALPAPERS" unicode="" d="M791.272727-90.763636H232.727273C162.909091-90.763636 107.054545-34.909091 107.054545 34.909091V756.363636C107.054545 826.181818 162.909091 882.036364 232.727273 882.036364h428.218182l251.345454-209.454546v-637.672727c4.654545-69.818182-51.2-125.672727-121.018182-125.672727zM232.727273 816.872727c-32.581818 0-60.509091-27.927273-60.509091-60.509091v-721.454545c0-32.581818 27.927273-60.509091 60.509091-60.509091h558.545454c32.581818 0 60.509091 27.927273 60.509091 60.509091V644.654545l-209.454545 172.218182H232.727273zM307.2 672.581818H512v-65.163636H307.2zM377.018182 640h65.163636v-125.672727H377.018182zM512 528.290909h228.072727v-65.163636H512zM307.2 337.454545h432.872727v-65.163636H307.2zM307.2 146.618182h316.509091v-65.163637H307.2zM884.363636 626.036364h-265.309091V849.454545h65.163637v-158.254545H884.363636z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="BIBLIOGRAPHIES" unicode="" d="M156.038095 696.07619H87.771429V881.371429h629.028571c73.142857 0 131.657143-58.514286 131.657143-131.657143v-48.761905h-68.266667V749.714286c0 34.133333-29.257143 63.390476-63.390476 63.390476H156.038095v-117.028572zM804.571429-128H87.771429V735.085714H804.571429c73.142857 0 131.657143-58.514286 131.657142-131.657143v-599.771428c0-73.142857-63.390476-131.657143-131.657142-131.657143zM156.038095-59.733333H804.571429c34.133333 0 63.390476 29.257143 63.390476 63.390476V603.428571c0 34.133333-29.257143 63.390476-63.390476 63.390477H156.038095v-726.552381zM302.32381 486.4h380.342857v-68.266667H302.32381zM302.32381 325.485714H512v-68.266666H302.32381z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="PROCEEDINGS" unicode="" d="M481.28 138.24L204.8 445.44l384 358.4 276.48-312.32-384-353.28zM302.08 440.32l184.32-199.68 276.48 256-179.2 204.8-281.6-261.12zM906.24-71.68c-30.72 0-61.44 15.36-87.04 40.96L532.48 281.6l174.08 163.84 291.84-327.68c20.48-20.48 30.72-51.2 25.6-81.92 0-30.72-15.36-56.32-35.84-76.8-25.6-20.48-51.2-30.72-81.92-30.72z m-271.36 348.16l240.64-266.24c15.36-20.48 46.08-20.48 66.56-5.12 10.24 10.24 15.36 15.36 15.36 30.72 0 10.24-5.12 20.48-10.24 30.72l-240.64 276.48-71.68-66.56zM849.92 450.56c-30.72 0-61.44 10.24-87.04 35.84l-194.56 204.8c-46.08 51.2-46.08 128 5.12 174.08 20.48 20.48 51.2 30.72 87.04 30.72 30.72 0 61.44-15.36 87.04-40.96l194.56-204.8c46.08-51.2 40.96-122.88-5.12-163.84-30.72-25.6-61.44-35.84-87.04-35.84z m-194.56 373.76c-10.24 0-25.6-5.12-35.84-15.36-20.48-20.48-20.48-51.2 0-71.68l194.56-204.8c20.48-20.48 46.08-20.48 66.56 0 20.48 15.36 20.48 46.08 5.12 66.56l-194.56 209.92c-10.24 10.24-20.48 15.36-35.84 15.36zM399.36 51.2c-35.84 0-71.68 15.36-97.28 40.96L35.84 368.64 215.04 537.6l358.4-384-76.8-66.56c-30.72-20.48-66.56-35.84-97.28-35.84z m-266.24 317.44l215.04-225.28c25.6-25.6 66.56-25.6 92.16-5.12l20.48 20.48L204.8 435.2l-71.68-66.56zM0-35.84h624.64v-71.68H0z" horiz-adv-x="1025" />
|
||||
|
||||
|
||||
<glyph glyph-name="HISTORY" unicode="" d="M422.956522-61.217391H178.086957c-66.782609 0-120.208696 53.426087-120.208696 120.208695V762.434783C57.878261 829.217391 111.304348 882.643478 178.086957 882.643478h574.330434c66.782609 0 120.208696-53.426087 120.208696-120.208695v-396.243479h-62.330435V762.434783c0 31.165217-26.713043 57.878261-57.878261 57.87826H178.086957c-31.165217 0-57.878261-26.713043-57.878261-57.87826v-703.443479c0-31.165217 26.713043-57.878261 57.878261-57.878261h244.869565v-62.330434zM756.869565-119.095652c-115.756522 0-213.704348 93.495652-213.704348 209.252174s93.495652 209.252174 213.704348 209.252174 213.704348-93.495652 213.704348-209.252174-97.947826-209.252174-213.704348-209.252174z m0 356.173913c-84.591304 0-151.373913-66.782609-151.373913-146.921739 0-80.13913 66.782609-146.921739 151.373913-146.921739s151.373913 66.782609 151.373913 146.921739c-4.452174 80.13913-71.234783 146.921739-151.373913 146.921739zM828.104348 1.113043h-120.208696v169.182609h62.330435v-106.852174h57.878261zM218.156522 668.93913h503.095652v-62.330434H218.156522zM218.156522 450.782609h414.052174v-62.330435H218.156522zM218.156522 245.982609h249.321739V183.652174H218.156522z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="CONDUCTSAFETY" unicode="" d="M499.2-110.933333l-17.066667 8.533333c-166.4 98.133333-273.066667 192-324.266666 294.4C110.933333 290.133333 81.066667 448 76.8 678.4v25.6l25.6 4.266667c98.133333 21.333333 170.666667 46.933333 217.6 68.266666C366.933333 797.866667 422.4 832 482.133333 878.933333l17.066667 12.8 17.066667-12.8c72.533333-46.933333 132.266667-81.066667 179.2-102.4 46.933333-17.066667 119.466667-42.666667 217.6-68.266666l21.333333-4.266667V682.666667c21.333333-204.8 8.533333-354.133333-46.933333-452.266667-55.466667-98.133333-174.933333-204.8-371.2-332.8l-17.066667-8.533333z m-362.666667 768c8.533333-204.8 34.133333-354.133333 76.8-439.466667s140.8-170.666667 285.866667-260.266667c179.2 115.2 290.133333 217.6 337.066667 302.933334 46.933333 85.333333 59.733333 217.6 42.666666 396.8-93.866667 25.6-162.133333 46.933333-204.8 64-42.666667 17.066667-102.4 51.2-170.666666 93.866666-55.466667-42.666667-110.933333-72.533333-157.866667-93.866666-46.933333-21.333333-115.2-42.666667-209.066667-64zM536.405333 205.226667h-59.733333v153.6h-149.333333v59.733333h149.333333v153.6h59.733333v-153.6h153.6v-59.733333h-153.6z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="EDISTATEMENT" unicode="" d="M819.2-128H200.347826C133.565217-128 80.13913-74.573913 80.13913-7.791304V762.434783C80.13913 829.217391 133.565217 882.643478 200.347826 882.643478h618.852174c66.782609 0 120.208696-53.426087 120.208696-120.208695v-770.226087c0-66.782609-53.426087-120.208696-120.208696-120.208696zM200.347826 820.313043C169.182609 820.313043 142.469565 793.6 142.469565 762.434783v-770.226087c0-31.165217 26.713043-57.878261 57.878261-57.878261h618.852174c31.165217 0 57.878261 26.713043 57.878261 57.878261V762.434783c0 31.165217-26.713043 57.878261-57.878261 57.87826H200.347826zM267.130435 308.313043h507.547826v-62.330434H267.130435zM267.130435 107.965217h262.678261v-62.330434H267.130435zM498.643478 744.626087h62.330435v-218.156522H498.643478zM538.713043 441.878261m-44.521739 0a44.521739 44.521739 0 1 1 89.043479 0 44.521739 44.521739 0 1 1-89.043479 0Z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="MAILINGLIST" unicode="" d="M1070.08 66.56h-215.04v71.68h215.04c35.84 0 66.56 30.72 66.56 66.56V742.4c0 35.84-30.72 66.56-66.56 66.56H153.6c-35.84 0-66.56-30.72-66.56-66.56v-537.6c0-35.84 30.72-66.56 66.56-66.56h230.4v-71.68H153.6C76.8 66.56 15.36 128 15.36 204.8V742.4C15.36 819.2 76.8 880.64 153.6 880.64h916.48c76.8 0 138.24-61.44 138.24-138.24v-537.6c0-76.8-61.44-138.24-138.24-138.24zM614.4 394.24L138.24 727.04l40.96 56.32L614.4 481.28l424.96 302.08 46.08-56.32zM134.6048 223.8464L388.7104 483.84l51.2512-50.0736-254.1056-259.9424zM795.648 428.4928l51.2 50.1248 254.2592-259.84-51.2-50.176zM460.8 286.72h307.2v-71.68H460.8zM460.8 189.44h307.2v-71.68H460.8zM460.8 87.04h307.2v-71.68H460.8zM460.8-15.36h307.2v-71.68H460.8z" horiz-adv-x="1228" />
|
||||
|
||||
|
||||
<glyph glyph-name="HOME" unicode="" d="M828.952381-113.371429h-151.161905c-43.885714 0-82.895238 39.009524-82.895238 82.895239v263.314285H477.866667V-30.47619c0-43.885714-39.009524-82.895238-82.895238-82.895239h-146.285715c-43.885714 0-82.895238 39.009524-82.895238 82.895239v360.838095H87.771429c-24.380952 0-48.761905 9.752381-63.390477 29.257143-14.628571 19.504762-19.504762 39.009524-19.504762 58.514285 0 24.380952 14.628571 43.885714 29.257143 53.638096L487.619048 842.361905c29.257143 24.380952 73.142857 24.380952 107.27619 0l443.733333-370.590476c19.504762-14.628571 29.257143-39.009524 29.257143-63.390477 0-43.885714-39.009524-82.895238-82.895238-82.895238h-78.019047v-360.838095c4.87619-39.009524-34.133333-78.019048-78.019048-78.019048z m-419.352381 414.476191h253.561905V-30.47619c0-9.752381 4.87619-14.628571 14.628571-14.628572H828.952381c9.752381 0 14.628571 4.87619 14.628571 14.628572v429.104761h146.285715c9.752381 0 14.628571 4.87619 14.628571 14.628572 0 4.87619 0 9.752381-4.87619 9.752381l-443.733334 370.590476c-4.87619 4.87619-14.628571 4.87619-19.504762 0L82.895238 423.009524c-4.87619-4.87619-4.87619-9.752381-4.87619-9.752381s0-4.87619 4.87619-9.752381 4.87619-4.87619 9.752381-4.876191h146.285714V-30.47619c0-9.752381 4.87619-14.628571 14.628572-14.628572h146.285714c9.752381 0 14.628571 4.87619 14.628571 14.628572v331.580952z" horiz-adv-x="1072" />
|
||||
|
||||
|
||||
<glyph glyph-name="zhunbeizhong" unicode="" d="M512 384m-480 0a480 480 0 1 1 960 0 480 480 0 1 1-960 0ZM512-128c-281.6 0-512 230.4-512 512s230.4 512 512 512 512-230.4 512-512-230.4-512-512-512zM512 832C262.4 832 64 633.6 64 384s198.4-448 448-448 448 198.4 448 448-198.4 448-448 448zM320 384m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM512 384m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM704 384m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0Z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
|
@ -74,9 +311,6 @@ Created by iconfont
|
|||
<glyph glyph-name="fenzuzuoye1" unicode="" d="M21.333333 896h1024v-1024H21.333333zM949.333333 736H718.933333c-51.2 0-96-12.8-140.8-38.4l-44.8-32-51.2 25.6C443.733333 723.2 392.533333 736 347.733333 736H117.333333C98.133333 736 85.333333 723.2 85.333333 704v-569.6c0-19.2 12.8-32 32-32h230.4c51.2 0 96-12.8 140.8-38.4l44.8-25.6h12.8l38.4 25.6c38.4 25.6 89.6 38.4 140.8 38.4h230.4c19.2 0 32 12.8 32 32V704c-6.4 19.2-19.2 32-38.4 32zM347.733333 172.8h-192V665.6H341.333333c38.4 0 70.4-12.8 102.4-32l51.2-32 6.4-6.4v-460.8c-44.8 25.6-102.4 38.4-153.6 38.4z m563.2 0H725.333333c-57.6 0-108.8-12.8-153.6-38.4V595.2l6.4 6.4 51.2 32c32 19.2 64 32 102.4 32H917.333333v-492.8zM418.133333 537.6H232.533333c-6.4 0-6.4-6.4-6.4-6.4v-44.8c0-6.4 0-6.4 6.4-6.4h185.6c6.4 0 6.4 6.4 6.4 6.4v38.4c0 6.4 0 12.8-6.4 12.8z m224-12.8v-44.8c0-6.4 6.4-6.4 6.4-6.4h185.6c6.4 0 6.4 6.4 6.4 6.4v44.8c0 6.4-6.4 6.4-6.4 6.4H648.533333c-6.4 6.4-6.4 0-6.4-6.4z m-224-128H232.533333c-6.4 0-6.4-6.4-6.4-6.4v-44.8c0-6.4 0-6.4 6.4-6.4h185.6c6.4 0 6.4 6.4 6.4 6.4v44.8s0 6.4-6.4 6.4z m416 0H648.533333c-6.4 0-6.4-6.4-6.4-6.4v-44.8c0-6.4 6.4-6.4 6.4-6.4h185.6c6.4 0 6.4 6.4 6.4 6.4v44.8s0 6.4-6.4 6.4z" horiz-adv-x="1365" />
|
||||
|
||||
|
||||
<glyph glyph-name="putongzuoye1" unicode="" d="M4.266667 896h1024v-1024H4.266667zM650.666667 832v-70.4h-512v-755.2h652.8v320h70.4v-358.4c0-19.2-12.8-32-32-32H100.266667c-19.2 0-32 12.8-32 32v832c0 19.2 12.8 32 32 32h550.4zM420.266667 454.4H260.266667c-19.2 0-38.4 19.2-38.4 38.4s19.2 32 38.4 32h160c19.2 0 32-12.8 32-32s-12.8-38.4-32-38.4zM516.266667 601.6H260.266667c-19.2 0-38.4 19.2-38.4 38.4s19.2 32 38.4 32h256c19.2 0 38.4-19.2 38.4-38.4s-19.2-32-38.4-32zM714.666667 89.6H260.266667c-19.2 0-38.4 19.2-38.4 38.4s19.2 38.4 38.4 38.4h454.4c19.2 0 38.4-19.2 38.4-38.4s-19.2-38.4-38.4-38.4zM522.666667 185.6c-25.6 0-51.2 19.2-64 44.8-6.4 12.8-6.4 19.2-6.4 32l12.8 134.4c0 12.8 6.4 25.6 12.8 32l236.8 345.6c19.2 32 51.2 51.2 89.6 57.6 38.4 6.4 70.4 0 102.4-19.2l12.8-6.4c57.6-44.8 70.4-128 32-185.6L708.266667 268.8c-6.4-12.8-19.2-19.2-32-25.6l-134.4-51.2c-6.4 0-12.8-6.4-19.2-6.4z m300.8 576h-12.8c-19.2 0-32-12.8-38.4-25.6L535.466667 390.4l-6.4-128L644.266667 307.2l243.2 345.6c19.2 25.6 12.8 64-12.8 89.6l-6.4 6.4 19.2 25.6-25.6-25.6c-12.8 6.4-25.6 12.8-38.4 12.8z" horiz-adv-x="1092" />
|
||||
|
||||
|
||||
<glyph glyph-name="shixunzuoye" unicode="" d="M4.266667 896h1024v-1024H4.266667zM964.266667 128H68.266667V832h896v-704zM138.666667 204.8h755.2V761.6H138.666667v-556.8zM708.266667-64H324.266667c-19.2 0-38.4 19.2-38.4 38.4s19.2 38.4 38.4 38.4h384c19.2 0 38.4-19.2 38.4-38.4s-19.2-38.4-38.4-38.4zM708.266667 403.2c-12.8 0-19.2 6.4-25.6 12.8-12.8 12.8-12.8 38.4 6.4 51.2L772.266667 544 682.666667 620.8c-12.8 12.8-12.8 38.4 0 51.2 12.8 12.8 38.4 12.8 51.2 0l89.6-83.2c12.8-12.8 19.2-32 19.2-44.8 0-19.2-6.4-38.4-19.2-51.2l-6.4-6.4-83.2-76.8c-12.8 0-19.2-6.4-25.6-6.4zM330.666667 403.2c-6.4 0-19.2 0-25.6 6.4L215.466667 492.8c-25.6 25.6-25.6 70.4 0 96l89.6 83.2c12.8 12.8 38.4 12.8 51.2 0 12.8-12.8 12.8-38.4 0-51.2L266.666667 537.6l83.2-70.4c12.8-12.8 19.2-38.4 6.4-51.2-6.4-6.4-19.2-12.8-25.6-12.8zM465.066667 384H452.266667c-19.2 12.8-25.6 32-19.2 51.2l102.4 243.2c6.4 19.2 25.6 32 44.8 19.2 19.2-6.4 25.6-25.6 19.2-44.8L503.466667 409.6c-6.4-12.8-19.2-25.6-38.4-25.6zM925.866667 256H119.466667c-19.2 0-38.4 19.2-38.4 38.4s19.2 38.4 38.4 38.4h800c19.2 0 38.4-19.2 38.4-38.4s-12.8-38.4-32-38.4zM401.066667 160h70.4V-64H401.066667zM586.666667 160h70.4V-64H586.666667z" horiz-adv-x="1092" />
|
||||
|
||||
|
||||
|
|
Before Width: | Height: | Size: 506 KiB After Width: | Height: | Size: 584 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,40 +1,111 @@
|
|||
|
||||
.maxW50{max-width: 50%;}
|
||||
.minW50{min-width: 50%;}
|
||||
.width70{width: 70%;}
|
||||
.width30{width: 30%;}
|
||||
.custom-commit-tabs .ant-tabs-bar{border-bottom: none;}
|
||||
.maxW200px{max-width: 200px;}
|
||||
.pr_tags_open{
|
||||
background: #28BD6C !important;
|
||||
color: #fff !important;
|
||||
border: none !important;
|
||||
.CodeMirror-merge {
|
||||
position: relative;
|
||||
white-space: pre;
|
||||
}
|
||||
.pr_tags_closed{
|
||||
background: #FA6400 !important;
|
||||
color: #fff !important;
|
||||
border: none !important;
|
||||
|
||||
.CodeMirror-merge, .CodeMirror-merge .CodeMirror {
|
||||
min-height:50px;
|
||||
}
|
||||
.pr_tags_merged{
|
||||
background: #4C9ED3 !important;
|
||||
color: #fff !important;
|
||||
border: none !important;
|
||||
|
||||
.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 48%; }
|
||||
.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 4%; }
|
||||
.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; }
|
||||
.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; }
|
||||
|
||||
.CodeMirror-merge-pane {
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
vertical-align: top;
|
||||
}
|
||||
.ant-btn-success{
|
||||
border: 1px solid #28BD6C !important;
|
||||
color: #28BD6C !important;
|
||||
.CodeMirror-merge-pane-rightmost {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
z-index: 1;
|
||||
}
|
||||
.ant-btn-success:hover{
|
||||
background: #28BD6C !important;
|
||||
color:#fff !important;
|
||||
|
||||
.CodeMirror-merge-gap {
|
||||
z-index: 2;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
background: #515151;
|
||||
}
|
||||
.display-flex{display: flex !important;}
|
||||
.merge-flex1{flex:1}
|
||||
.ant-tag.pr-branch-tag{
|
||||
border-radius: 12px;
|
||||
height: 24px;
|
||||
background: rgba(241,248,255,1);
|
||||
border: none;
|
||||
font-size: 13px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-scrolllock-wrap {
|
||||
position: absolute;
|
||||
bottom: 0; left: 50%;
|
||||
}
|
||||
.CodeMirror-merge-scrolllock {
|
||||
position: relative;
|
||||
left: -50%;
|
||||
cursor: pointer;
|
||||
color: #d8d8d8;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right {
|
||||
position: absolute;
|
||||
left: 0; top: 0;
|
||||
right: 0; bottom: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copy {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
color: #ce374b;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copy-reverse {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
color: #44c;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
|
||||
.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; }
|
||||
|
||||
.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);
|
||||
background-position: bottom left;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);
|
||||
background-position: bottom left;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-r-chunk { background: #9a6868; }
|
||||
.CodeMirror-merge-r-chunk-start { /*border-top: 1px solid #ee8; */}
|
||||
.CodeMirror-merge-r-chunk-end {/* border-bottom: 1px solid #ee8; */}
|
||||
.CodeMirror-merge-r-connect { fill:#9a6868;}
|
||||
|
||||
.CodeMirror-merge-l-chunk { background: #eef; }
|
||||
.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; }
|
||||
.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; }
|
||||
.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }
|
||||
|
||||
.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; }
|
||||
.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; }
|
||||
.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }
|
||||
|
||||
.CodeMirror-merge-collapsed-widget:before {
|
||||
content: "(...)";
|
||||
}
|
||||
.CodeMirror-merge-collapsed-widget {
|
||||
cursor: pointer;
|
||||
color: #88b;
|
||||
background: #eef;
|
||||
border: 1px solid #ddf;
|
||||
font-size: 90%;
|
||||
padding: 0 3px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; }
|
||||
|
|
|
@ -1,53 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name=”Keywords” Content=”EduCoder,信息技术实践教学,精品课程网,慕课MOOC″>
|
||||
<meta name=”Keywords” Content=”实践课程,项目实战,java实训,python实战,人工智能技术,后端开发学习,移动开发入门″>
|
||||
<meta name=”Keywords” Content=”翻转课堂,高效课堂创建,教学模式″>
|
||||
<meta name=”Keywords” Content=”实训项目,python教程,C语言入门,java书,php后端开发,app前端开发,数据库技术″>
|
||||
<meta name=”Keywords” Content=”在线竞赛,计算机应用大赛,编程大赛,大学生计算机设计大赛,全国高校绿色计算机大赛″>
|
||||
<meta name=”Description”
|
||||
Content=”EduCoder是信息技术类实践教学平台。EduCoder涵盖了计算机、大数据、云计算、人工智能、软件工程、物联网等专业课程。超10000个实训案例及22000个技能评测点,建立学、练、评、测一体化实验环境。”>
|
||||
<meta name=”Description”
|
||||
Content=”EduCoder实践课程,旨在于通过企业级实战实训案例,帮助众多程序员提升各项业务能力。解决学生、学员、企业员工等程序设计能力、算法设计能力、问题求解能力、应用开发能力、系统运维能力等。”>
|
||||
<meta name=”Description”
|
||||
Content=”EduCoder翻转课堂教学模式,颠覆了传统教学模式,让教师与学生的关系由“权威”变成了“伙伴”。将学习的主动权转交给学生,使学生可个性化化学,学生的学习主体得到了彰显。”>
|
||||
<meta name=”Description” Content=”EduCoder实训项目为单个知识点关卡实践训练,帮助学生巩固单一弱点,强化学习。 ”>
|
||||
<meta name=”Description” Content=”EduCoder实践教学平台,各类大赛为进一步提高各类学生综合运用高级语言程序设计能力,培养创新意识和实践探索精神,发掘优秀软件人才。 ”>
|
||||
<meta name=”Keywords” Content=”trustie,trustieforge,forge,确实让创建更美好,协同开发平台″>
|
||||
<meta name=”Keywords” Content=”TrustieOpenSourceProject″>
|
||||
<meta name=”Keywords” Content=”issue,bug,tracker,软件工程,课程实践″>
|
||||
<meta name=”Description” Content=”持续构建协同、共享、可信的软件创建生态开源创作与软件生产相结合,支持大规模群体开展软件协同创新活动”>
|
||||
<meta name="theme-color" content="#000000">
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
|
||||
<script type="text/javascript">
|
||||
window.__isR = true;
|
||||
if (
|
||||
(navigator.userAgent.indexOf('MSIE 9') != -1
|
||||
|| navigator.userAgent.indexOf('MSIE 10') != -1)
|
||||
&&
|
||||
location.pathname.indexOf("/compatibility") == -1) {
|
||||
location.href = '/compatibility.html'
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel=" stylesheet" type="text/css" href="%PUBLIC_URL%css/iconfont.css">
|
||||
<link rel=" stylesheet" type="text/css" href="%PUBLIC_URL%css/edu-purge.css">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/iconfont.css">
|
||||
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/edu-purge.css">
|
||||
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/editormd.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/merge.css">
|
||||
<%= htmlWebpackPlugin.tags.headTags %>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!--用于markdown转html -->
|
||||
<div id="md_div" style="display: none;"></div>
|
||||
<div id="root" class="page -layout-v -fit widthunit"></div>
|
||||
<div id="picture_display" style="display: none;"></div>
|
||||
<script src="%PUBLIC_URL%js/jquery-1.8.3.min.js"></script>
|
||||
<script src="%PUBLIC_URL%js/js_min_all.js"></script>
|
||||
<script src="%PUBLIC_URL%js/codemirror/codemirror.js"></script>
|
||||
<script src="%PUBLIC_URL%js/editormd/editormd.min.js"></script>
|
||||
<script src="%PUBLIC_URL%js/codemirror/merge/merge.js"></script>
|
||||
<%= htmlWebpackPlugin.tags.bodyTags %>
|
||||
</body>
|
||||
|
||||
</html>
|
30
src/App.js
30
src/App.js
|
@ -9,13 +9,7 @@ import {
|
|||
} from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import LoginDialog from './modules/login/LoginDialog';
|
||||
import Notcompletedysl from './modules/user/Notcompletedysl';
|
||||
import Trialapplicationysl from './modules/login/Trialapplicationysl';
|
||||
import Trialapplicationreview from './modules/user/Trialapplicationreview';
|
||||
import AccountProfile from "./modules/user/AccountProfile";
|
||||
import Accountnewprofile from './modules/user/Accountnewprofile';
|
||||
import Certifiedprofessional from './modules/modals/Certifiedprofessional';
|
||||
|
||||
import 'babel-polyfill';
|
||||
import Loading from './Loading'
|
||||
|
||||
import Loadable from 'react-loadable';
|
||||
|
@ -76,6 +70,10 @@ const OrganizeIndex = Loadable({
|
|||
loader: () => import('./forge/Team/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
const EducoderLogin = Loadable({
|
||||
loader: () => import('./modules/login/EducoderLogin'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
|
@ -213,18 +211,12 @@ class App extends Component {
|
|||
<Provider store={store}>
|
||||
<ConfigProvider locale={zhCN}>
|
||||
<MuiThemeProvider theme={theme}>
|
||||
<Accountnewprofile {...this.props}{...this.state} />
|
||||
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
|
||||
<Notcompletedysl {...this.props} {...this.state}></Notcompletedysl>
|
||||
<Trialapplicationysl {...this.props} {...this.state}></Trialapplicationysl>
|
||||
<Trialapplicationreview {...this.props} {...this.state}></Trialapplicationreview>
|
||||
<AccountProfile {...this.props} {...this.state} />
|
||||
<Certifiedprofessional {...this.props} {...this.state} ModalCancelsy={this.ModalCancelsy} ModalshowCancelsy={this.ModalshowCancelsy} />
|
||||
<Router>
|
||||
<Switch>
|
||||
{/*项目*/}
|
||||
<Route
|
||||
path={"/projects/:projectId/ops/:opsId/detail"}
|
||||
path={"/projects/:owner/:projectId/devops/:opsId/detail"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OpsDetail {...this.props} {...props} {...this.state} />)
|
||||
|
@ -240,7 +232,15 @@ class App extends Component {
|
|||
}
|
||||
}>
|
||||
</Route>
|
||||
|
||||
<Route
|
||||
path="/register"
|
||||
render={
|
||||
(props) => {
|
||||
|
||||
return (<EducoderLogin {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}
|
||||
/>
|
||||
{/*403*/}
|
||||
<Route path="/403" component={Shixunauthority} />
|
||||
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import axios from 'axios';
|
||||
import { requestProxy } from "./indexEduplus2RequestProxy";
|
||||
import { broadcastChannelOnmessage , isDev, queryString } from 'educoder';
|
||||
import { broadcastChannelOnmessage, isDev, queryString } from 'educoder';
|
||||
import { notification } from 'antd';
|
||||
import cookie from 'react-cookies';
|
||||
import './index.css';
|
||||
const $ = window.$;
|
||||
let timestamp;
|
||||
let checkSubmitFlg = false;
|
||||
let message501 = false;
|
||||
|
||||
broadcastChannelOnmessage('refreshPage', () => {
|
||||
|
@ -30,20 +27,17 @@ if (isDev) {
|
|||
}
|
||||
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
|
||||
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
|
||||
}
|
||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'p86402359'
|
||||
}
|
||||
function clearAllCookie() {
|
||||
cookie.remove('_educoder_session', { path: '/' });
|
||||
cookie.remove('autologin_trustie', { path: '/' });
|
||||
setpostcookie()
|
||||
}
|
||||
clearAllCookie();
|
||||
// clearAllCookie();
|
||||
function setpostcookie() {
|
||||
|
||||
const str = window.location.pathname;
|
||||
let newdomain = ".educoder.net"
|
||||
if (str.indexOf("/wxcode") !== -1) {
|
||||
console.log("123")
|
||||
cookie.remove('_educoder_session', { path: '/' });
|
||||
cookie.remove('autologin_trustie', { path: '/' });
|
||||
const _params = window.location.search;
|
||||
|
@ -53,7 +47,6 @@ function setpostcookie() {
|
|||
cookie.save('_educoder_session', _educoder_sessions[1], { domain: '.educoder.net', path: '/' });
|
||||
let autologin_trusties = _search.split('&')[1].split('=');
|
||||
cookie.save('autologin_trustie', autologin_trusties[1], { domain: '.educoder.net', path: '/' });
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,9 +56,9 @@ window._debugType = debugType;
|
|||
export function initAxiosInterceptors(props) {
|
||||
initOnlineOfflineListener()
|
||||
// TODO 避免重复的请求 https://github.com/axios/axios#cancellation
|
||||
var
|
||||
proxy = "http://localhost:3000"
|
||||
proxy = "http://39.105.176.215:49999"
|
||||
var
|
||||
proxy = "http://localhost:3000";
|
||||
proxy = "http://osredmforge.educoder.net";
|
||||
|
||||
const requestMap = {};
|
||||
window.setfalseInRequestMap = function (keyName) {
|
||||
|
@ -77,7 +70,7 @@ export function initAxiosInterceptors(props) {
|
|||
setpostcookie()
|
||||
clearAllCookie()
|
||||
|
||||
if (config.url.indexOf(proxy) !== -1 || config.url.indexOf(':') !== -1) {
|
||||
if (config.url.indexOf(proxy) !== -1) {
|
||||
return config
|
||||
}
|
||||
requestProxy(config)
|
||||
|
@ -109,12 +102,10 @@ export function initAxiosInterceptors(props) {
|
|||
});
|
||||
|
||||
axios.interceptors.response.use(function (response) {
|
||||
|
||||
// console.log(".............")
|
||||
if (response === undefined) {
|
||||
return
|
||||
}
|
||||
const config = response.config
|
||||
const config = response.config;
|
||||
if (response.data.status === -1) {
|
||||
if (window.location.pathname.startsWith('/tasks/')) {
|
||||
props.showSnackbar(response.data.message || '服务器异常,请联系管理员。')
|
||||
|
@ -127,12 +118,10 @@ export function initAxiosInterceptors(props) {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
throw new axios.Cancel('Operation canceled by the user.');
|
||||
}
|
||||
|
||||
if (response.data.status === 403 || response.data.status === "403") {
|
||||
|
||||
locationurl('/403');
|
||||
}
|
||||
|
||||
|
@ -159,8 +148,6 @@ export function initAxiosInterceptors(props) {
|
|||
message501 = false
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
|
||||
requestMap[response.config.url] = false;
|
||||
setpostcookie();
|
||||
return response;
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import React, { Component } from 'react';
|
||||
|
||||
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
|
||||
|
||||
import { Spin } from 'antd';
|
||||
|
||||
class Loading extends Component {
|
||||
|
@ -12,7 +9,6 @@ class Loading extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
// Loading
|
||||
return (
|
||||
<div className="App" style={{ minHeight: '800px', width: "100%" }}>
|
||||
<style>
|
||||
|
|
|
@ -68,7 +68,7 @@ export function appendFileSizeToUploadFile(item) {
|
|||
return `${item.title}${uploadNameSizeSeperator}${item.filesize}`
|
||||
}
|
||||
export function appendFileSizeToUploadFileAll(fileList) {
|
||||
return fileList.map(item => {
|
||||
return fileList && fileList.map(item => {
|
||||
if (item.name.indexOf(uploadNameSizeSeperator) == -1) {
|
||||
return Object.assign({}, item, { name: `${item.name}${uploadNameSizeSeperator}${bytesToSize(item.size)}` })
|
||||
}
|
||||
|
|
|
@ -6,18 +6,33 @@ const { Search } = Input;
|
|||
const $ = window.$;
|
||||
const isDev = window.location.port == 3007;
|
||||
const isdev2= window.location.hostname ==='www.educoder.net'
|
||||
export const TEST_HOST = "https://testforgeplus.trustie.net/"
|
||||
export const TEST_HOST = "http://39.105.176.215:49999"
|
||||
export function getImageUrl(path) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
// const local = 'http://localhost:3000'
|
||||
const local = 'https://testforgeplus.trustie.net/'
|
||||
const local = 'http://39.105.176.215:49999';
|
||||
if (isDev) {
|
||||
return `${local}/${path}`
|
||||
}
|
||||
return `/${path}`;
|
||||
}
|
||||
|
||||
export function getImage(path) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
// const local = 'http://localhost:3000'
|
||||
const local = 'http://39.105.176.215:49999';
|
||||
if(path.indexOf("http://")===-1){
|
||||
if (isDev) {
|
||||
return `${local}/images/${path}`
|
||||
}
|
||||
return `/${path}`;
|
||||
}else{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
export function getcdnImageUrl(path) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
|
@ -78,7 +93,7 @@ export function setImagesUrl(path){
|
|||
}
|
||||
|
||||
export function getUrl(path, goTest) {
|
||||
const local = 'https://testforgeplus.trustie.net'
|
||||
const local = 'http://39.105.176.215:49999'
|
||||
if (isDev) {
|
||||
return `${local}${path?path:''}`
|
||||
}
|
||||
|
@ -147,7 +162,7 @@ export function getmyUrl(geturl) {
|
|||
}
|
||||
|
||||
export function getUploadActionUrl(path, goTest) {
|
||||
return `${getUrl()}/api/attachments.json?debug=${window._debugType || 'admin'}`;
|
||||
return `${getUrl()}/api/attachments.json`;
|
||||
}
|
||||
|
||||
export function getUploadLogoActionUrl() {
|
||||
|
|
|
@ -38,13 +38,11 @@ export const formatDelta = (deltas) => {
|
|||
alt="${alt}"
|
||||
/>
|
||||
`;
|
||||
// text = "<img src="+url+" width='60px' height='30px' onclick='' alt="+alt+"/>";
|
||||
}
|
||||
}
|
||||
|
||||
formatted.push(text);
|
||||
});
|
||||
console.log(formatted);
|
||||
return formatted.join('');
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
export {
|
||||
getUploadLogoActionUrl as getUploadLogoActionUrl,
|
||||
getImageUrl as getImageUrl, getmyUrl as getmyUrl, getRandomNumber as getRandomNumber, getUrl as getUrl, publicSearchs as publicSearchs, getRandomcode as getRandomcode, getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl
|
||||
getImageUrl as getImageUrl,getImage as getImage, getmyUrl as getmyUrl, getRandomNumber as getRandomNumber, getUrl as getUrl, 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
|
||||
} from './UrlTool';
|
||||
|
@ -76,10 +76,4 @@ export { default as AliyunUploader } from './components/media/AliyunUploader'
|
|||
export { default as ImageLayer2 } from './hooks/ImageLayer2'
|
||||
|
||||
// 外部
|
||||
export { default as CBreadcrumb } from '../modules/courses/common/CBreadcrumb'
|
||||
export { CNotificationHOC as CNotificationHOC } from '../modules/courses/common/CNotificationHOC'
|
||||
export { default as ModalWrapper } from '../modules/courses/common/ModalWrapper'
|
||||
export { default as NoneData } from '../modules/courses/coursesPublic/NoneData'
|
||||
|
||||
export { default as WordNumberTextarea } from '../modules/modals/WordNumberTextarea'
|
||||
|
||||
|
|
|
@ -48,15 +48,15 @@ function buildToc(coll, k, level, ctx) {
|
|||
});
|
||||
ctx.push("</ul>")
|
||||
}
|
||||
ctx.push("</li>")
|
||||
ctx.push("</li>");
|
||||
k = buildToc(coll, k, level, ctx)
|
||||
return k
|
||||
}
|
||||
|
||||
export function getTocContent() {
|
||||
buildToc(toc, 0, 0, ctx)
|
||||
ctx.push("</ul>")
|
||||
return ctx.join("")
|
||||
buildToc(toc, 0, 0, ctx);
|
||||
ctx.push("</ul>");
|
||||
return ctx.join("");
|
||||
}
|
||||
|
||||
const tokenizer = {
|
||||
|
@ -157,7 +157,6 @@ renderer.heading = function (text, level, raw) {
|
|||
})
|
||||
return '<h' + level + ' id="' + anchor + '">' + text + '</h' + level + '>'
|
||||
}
|
||||
|
||||
marked.setOptions({
|
||||
silent: true,
|
||||
smartypants: true,
|
||||
|
|
|
@ -1,37 +1,58 @@
|
|||
import React, { useEffect, useRef, useMemo } from "react";
|
||||
import "katex/dist/katex.min.css";
|
||||
import { renderToString } from 'katex';
|
||||
import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions } from "../common/marked";
|
||||
import React, { useEffect, useRef, useMemo } from 'react'
|
||||
import 'katex/dist/katex.min.css'
|
||||
import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions } from '../common/marked';
|
||||
import 'code-prettify'
|
||||
import dompurify from 'dompurify';
|
||||
|
||||
import { renderToString } from 'katex'
|
||||
|
||||
const preRegex = /<pre[^>]*>/g
|
||||
|
||||
function _unescape(str) {
|
||||
let div = document.createElement('div')
|
||||
div.innerHTML = str
|
||||
return div.childNodes.length === 0 ? "" : div.childNodes[0].nodeValue;
|
||||
return div.childNodes.length === 0 ? "" : div.childNodes[0].nodeValue
|
||||
}
|
||||
|
||||
export default ({ value = '', className, style = {} }) => {
|
||||
let str = String(value)
|
||||
|
||||
|
||||
export default ({
|
||||
value = '',
|
||||
className,
|
||||
style = {},
|
||||
url
|
||||
}) => {
|
||||
let str = String(value);
|
||||
const html = useMemo(() => {
|
||||
let rs = marked(str)
|
||||
const math_expressions = getMathExpressions()
|
||||
let rs = marked(str);
|
||||
const math_expressions = getMathExpressions();
|
||||
if (str.match(/\[TOC\]/)) {
|
||||
rs = rs.replace("<p>[TOC]</p>", getTocContent())
|
||||
cleanToc()
|
||||
}
|
||||
rs = rs.replace(/(__special_katext_id_\d+__)/g, (_match, capture) => {
|
||||
const { type, expression } = math_expressions[capture]
|
||||
return renderToString(_unescape(expression), { displayMode: type === 'block', throwOnError: false, output: 'html' })
|
||||
return renderToString(_unescape(expression) || '', { displayMode: type === 'block', throwOnError: false, output: 'html' })
|
||||
})
|
||||
rs = rs.replace(/▁/g, "▁▁▁")
|
||||
resetMathExpressions()
|
||||
return rs
|
||||
}, [str])
|
||||
return dompurify.sanitize(rs)
|
||||
}, [str]);
|
||||
|
||||
const el = useRef()
|
||||
// 锚点跳转,链接地址里含#对应的id
|
||||
useEffect(()=>{
|
||||
if(url && url.hash && html){
|
||||
let u = url.hash;
|
||||
if(u){
|
||||
let id = decodeURIComponent(u.split("#")[1]);
|
||||
let ele = document.getElementById(id);
|
||||
if(ele){
|
||||
window.scrollTo(0, ele.offsetTop + 220);
|
||||
}
|
||||
}
|
||||
}
|
||||
},[url])
|
||||
|
||||
const el = useRef();
|
||||
function onAncherHandler(e) {
|
||||
let target = e.target
|
||||
if (target.tagName.toUpperCase() === 'A') {
|
||||
|
@ -40,7 +61,7 @@ export default ({ value = '', className, style = {} }) => {
|
|||
e.preventDefault()
|
||||
let viewEl = document.getElementById(ancher.replace('#', ''))
|
||||
if (viewEl) {
|
||||
viewEl.parentNode.scrollTop = viewEl.offsetTop
|
||||
viewEl.scrollIntoView(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +82,12 @@ export default ({ value = '', className, style = {} }) => {
|
|||
}
|
||||
}
|
||||
}, [html, el.current, onAncherHandler])
|
||||
|
||||
return (<div ref={el} style={style} className={`${className ? className : ''} markdown-body`} dangerouslySetInnerHTML={{ __html: html }}></div>)
|
||||
return (
|
||||
<div
|
||||
ref={el}
|
||||
style={style}
|
||||
className={`${className ? className : ''} markdown-body`}
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
></div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import './index.scss';
|
||||
import { Button } from 'antd';
|
||||
import Upload from "../Upload/Index";
|
||||
import UploadImg from "../Images/upload.png";
|
||||
import MDEditor from "../../modules/tpm/challengesnew/tpm-md-editor";
|
||||
import { AlignCenterBetween } from '../Component/layout';
|
||||
import axios from 'axios';
|
||||
import RenderHtml from '../../components/render-html';
|
||||
import Attachments from "../Upload/attachment";
|
||||
|
||||
function Index(props){
|
||||
const [ attachments , setAttachments ] = useState(undefined);
|
||||
const [ content , setContent ] = useState(undefined);
|
||||
const [ edit , setEdit ] = useState(false);
|
||||
const [ fileList , setFileList ] = useState(undefined);
|
||||
const [ editOpration , setEditOpration ] = useState(false);
|
||||
const { owner , projectsId } = props.match.params;
|
||||
|
||||
const { isManager , isDeveloper , current_user } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
if(owner && projectsId){
|
||||
Init();
|
||||
}
|
||||
},[owner,projectsId])
|
||||
|
||||
useEffect(()=>{
|
||||
if( (current_user && current_user.login) && (isManager === true || isDeveloper === true)){
|
||||
setEditOpration(true);
|
||||
}
|
||||
},[isManager , isDeveloper])
|
||||
function Init(){
|
||||
const url = `/${owner}/${projectsId}/about.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
setContent(result.data.content);
|
||||
setAttachments(result.data.attachments);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function editContent(){
|
||||
setEdit(true);
|
||||
}
|
||||
|
||||
|
||||
function onContentChange(value){
|
||||
setContent(value);
|
||||
};
|
||||
|
||||
function UploadFunc(fileList){
|
||||
setFileList(fileList);
|
||||
};
|
||||
|
||||
function sureSubmit(){
|
||||
const url = `/${owner}/${projectsId}/about.json`;
|
||||
axios.post(url,{
|
||||
content,attachment_ids:fileList
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
props.showNotification("项目主页编辑成功!");
|
||||
Init();
|
||||
setEdit(false);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
return(
|
||||
<div className="aboutPanels">
|
||||
|
||||
<div className="aboutContent">
|
||||
<AlignCenterBetween style={{padding:"14px 0px"}}>
|
||||
<span className="font-16"><i className="iconfont icon-xiangmujianjie mr5 font-16 color-blue"></i>项目简介</span>
|
||||
{ editOpration && !edit && <a onClick={editContent} className="color-blue">编辑</a> }
|
||||
</AlignCenterBetween>
|
||||
{
|
||||
edit ?
|
||||
<div>
|
||||
<MDEditor
|
||||
placeholder={"请输入描述信息"}
|
||||
height={500}
|
||||
mdID={"order-new-description"}
|
||||
initValue={content}
|
||||
onChange={onContentChange}
|
||||
className="mt20"
|
||||
></MDEditor>
|
||||
<div className="pb20">
|
||||
<Upload
|
||||
className="commentStyle mt20"
|
||||
isComplete={true}
|
||||
load={UploadFunc}
|
||||
icon={
|
||||
<img
|
||||
src={UploadImg}
|
||||
width="58"
|
||||
alt=""
|
||||
style={{ marginBottom: 15 }}
|
||||
/>
|
||||
}
|
||||
size={100}
|
||||
showNotification={props.showNotification}
|
||||
/>
|
||||
{attachments && attachments.length > 0 &&
|
||||
<Attachments
|
||||
attachments={attachments}
|
||||
showNotification={props.showNotification}
|
||||
canDelete={true}
|
||||
></Attachments>
|
||||
}
|
||||
</div>
|
||||
<div className="pb30">
|
||||
<Button type="primary" onClick={sureSubmit}>确定</Button>
|
||||
<Button className="ml30" onClick={()=>setEdit(false)}>取消</Button>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div style={{padding:"20px 0px"}}>
|
||||
{content ?
|
||||
<RenderHtml className="break_word_comments imageLayerParent" value={content} url={props.history.location}/>
|
||||
:
|
||||
<div>暂无简介~</div>
|
||||
}
|
||||
{attachments && attachments.length > 0 &&
|
||||
<Attachments
|
||||
attachments={attachments}
|
||||
showNotification={props.showNotification}
|
||||
></Attachments>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Index;
|
|
@ -0,0 +1,13 @@
|
|||
.aboutPanels{
|
||||
max-width: 1200px;
|
||||
margin:0px auto;
|
||||
.aboutContent{
|
||||
border-radius: 2px;
|
||||
border: 1px solid #EEEEEE;
|
||||
padding:0px 30px;
|
||||
width:100%;
|
||||
background-color: #fff;
|
||||
margin-top:20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
|
@ -177,7 +177,7 @@ class Activity extends Component{
|
|||
}
|
||||
</div>
|
||||
:
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
<NoneData _html="暂时还没有相关数据!" />
|
||||
}
|
||||
</Spin>
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@ class ActivityItem extends Component {
|
|||
</p >
|
||||
}
|
||||
<p className="itemLine mt10">
|
||||
<Link to={`/users/${item && item.login}`} className="show-user-link">
|
||||
<Link to={`/users/${item && item.user_login}`} className="show-user-link">
|
||||
<img alt="" src={getImageUrl(`images/${item.user_avatar}`)} className="createImage" />
|
||||
<span className="mr20">{item.user_name}</span>
|
||||
</Link>
|
||||
|
|
|
@ -101,6 +101,7 @@
|
|||
height: 22px;
|
||||
line-height: 22px;
|
||||
border-radius: 50%;
|
||||
width: 22px;
|
||||
}
|
||||
.change{
|
||||
color: black;
|
||||
|
|
|
@ -4,7 +4,7 @@ import './branch.css';
|
|||
import { getBranch , getTag } from '../GetData/getData';
|
||||
|
||||
|
||||
export default (({ projectsId , repo_id , changeBranch , branch , owner })=>{
|
||||
export default (({ projectsId , branch , owner , changeBranch , branchList , tagflag = true })=>{
|
||||
const [ showValue , setShowValue ] = useState(branch);
|
||||
const [ inputValue , setInputValue] = useState(undefined);
|
||||
const [ nav , setNav ] = useState(0);
|
||||
|
@ -17,10 +17,11 @@ export default (({ projectsId , repo_id , changeBranch , branch , owner })=>{
|
|||
useEffect(()=>{
|
||||
setShowValue(branch);
|
||||
},[branch])
|
||||
|
||||
useEffect(()=>{
|
||||
document.body.addEventListener('click', e => {
|
||||
let name = e.target.className;
|
||||
let turn = name == "ant-input OptionsInput" || name == "navli active"|| name == "navli" || name == "padding10 bor-bottom-greyE";
|
||||
let turn = name === "ant-input OptionsInput" || name === "navli active"|| name === "navli" || name === "padding10 bor-bottom-greyE";
|
||||
if(turn){
|
||||
return;
|
||||
}else{
|
||||
|
@ -30,8 +31,12 @@ export default (({ projectsId , repo_id , changeBranch , branch , owner })=>{
|
|||
})
|
||||
|
||||
useEffect(()=>{
|
||||
getBranchs(projectsId,owner);
|
||||
},[projectsId])
|
||||
if(branchList){
|
||||
setData(branchList);
|
||||
setDatas(branchList);
|
||||
setIsSpin(false);
|
||||
}
|
||||
},[branchList])
|
||||
|
||||
|
||||
async function getBranchs(id,owner){
|
||||
|
@ -63,7 +68,7 @@ export default (({ projectsId , repo_id , changeBranch , branch , owner })=>{
|
|||
}
|
||||
}
|
||||
function chooseitem(value){
|
||||
setShowValue(value);
|
||||
// setShowValue(value);
|
||||
changeBranch(value);
|
||||
}
|
||||
|
||||
|
@ -77,8 +82,8 @@ export default (({ projectsId , repo_id , changeBranch , branch , owner })=>{
|
|||
onChange={changeInputValue} style={{width:"220px"}}
|
||||
/>
|
||||
<ul className="navUl">
|
||||
<li className={nav==0?"navli active":"navli"} onClick={()=>changeNav(0)}><i className="iconfont icon-fenzhi1 font-14 mr3"></i>分支列表</li>
|
||||
<li className={nav==1?"navli active":"navli"} onClick={()=>changeNav(1)}><i className="iconfont icon-biaoqian3 font-14 mr3"></i>标签列表</li>
|
||||
<li className={nav === 0?"navli active":"navli"} onClick={()=>changeNav(0)}><i className="iconfont icon-fenzhi1 font-14 mr3"></i>分支列表</li>
|
||||
{ tagflag && <li className={nav === 1?"navli active":"navli"} onClick={()=>changeNav(1)}><i className="iconfont icon-biaoqian3 font-14 mr3"></i>标签列表</li> }
|
||||
</ul>
|
||||
</div>
|
||||
<Spin spinning={isSpin}>
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
width: 240px;
|
||||
min-width: 240px;
|
||||
}
|
||||
.branch-tagBox-list .ant-popover-arrow{
|
||||
display: none;
|
||||
|
|
|
@ -8,6 +8,10 @@ li.ant-menu-item{
|
|||
margin:0px!important;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.flags{
|
||||
border: 1px solid red;
|
||||
border-radius: 5px;
|
||||
}
|
||||
// Cards
|
||||
.cards{
|
||||
display: flex;
|
||||
|
@ -72,6 +76,7 @@ li.ant-menu-item{
|
|||
border-radius:11px;
|
||||
color: #fff;
|
||||
margin-left: 5px;
|
||||
font-size: 12px;
|
||||
&.running{
|
||||
background:#5091FF;
|
||||
color: #F1F8FF;
|
||||
|
@ -88,6 +93,10 @@ li.ant-menu-item{
|
|||
background:#F73030;
|
||||
color:#FCEEEE ;
|
||||
}
|
||||
&.killed{
|
||||
background:#eee;
|
||||
color:#999 ;
|
||||
}
|
||||
}
|
||||
.handleBox{
|
||||
position: fixed;
|
||||
|
@ -95,6 +104,7 @@ li.ant-menu-item{
|
|||
right:240px;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1800px){
|
||||
.handleBox{
|
||||
right:190px;
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
|
||||
|
||||
export default ({title , value , className})=>{
|
||||
const Keys = styled.span`
|
||||
display:flex;
|
||||
align-item:center;
|
||||
align-items:center;
|
||||
& span{
|
||||
display:block;
|
||||
height:20px;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import React from 'react';
|
||||
import { Modal , Button } from 'antd';
|
||||
import './Component.scss';
|
||||
|
||||
function Modals({visible,title,content,onOk,onCancel}){
|
||||
return(
|
||||
<Modal
|
||||
className="modalsStyle"
|
||||
visible={visible}
|
||||
title={title}
|
||||
onCancel={onCancel}
|
||||
closable={true}
|
||||
footer={
|
||||
<div>
|
||||
<Button onClick={onCancel}>取消</Button>
|
||||
<Button type={"primary"} style={{marginLeft:"20px"}} onClick={onOk}>确定</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div style={{fontSize:"16px"}}>{content}</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default Modals;
|
|
@ -0,0 +1,61 @@
|
|||
import React , { useState , useEffect } from 'react';
|
||||
import { Select } from 'antd';
|
||||
import { getUrl } from 'educoder';
|
||||
|
||||
import axios from 'axios';
|
||||
const Option = Select.Option;
|
||||
|
||||
export default (({ language , select_language })=>{
|
||||
const [ six , setSix ] = useState(undefined);
|
||||
const [ languages , setLanguage ] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
const url = '/ci/languages.json';
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
setLanguage(result.data);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
},[])
|
||||
|
||||
function changelanguage(value){
|
||||
let array = value ? languages.filter(item=>item.name === value) :undefined;
|
||||
select_language(value,array && array[0]);
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
const url = '/ci/languages/common.json';
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
setSix(result.data);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
},[])
|
||||
|
||||
return(
|
||||
<React.Fragment>
|
||||
{
|
||||
six &&
|
||||
<ul className="language">
|
||||
{
|
||||
six.map((item,key)=>{
|
||||
return(
|
||||
key < 6 ? <li className={language ===item.name ? "active":""} onClick={()=>changelanguage(item.name)}><img alt="" src={item.cover_url && getUrl(item.cover_url)} /></li> : ""
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
<Select showSearch={true} placeholder={"请选择文本语言"} style={{ width: 200 }} value={language} onChange={changelanguage}>
|
||||
<Option value={undefined}>请选择文本语言</Option>
|
||||
{languages && languages.map((item, key) => {
|
||||
return <Option value={item.name}>{item.name}</Option>;
|
||||
})}
|
||||
</Select>
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
|
@ -3,42 +3,54 @@ import './Component.scss';
|
|||
|
||||
export const Tags = (status)=>{
|
||||
switch(status){
|
||||
case 1:
|
||||
case "running":
|
||||
return(
|
||||
<span className="statusColor running">运行中</span>
|
||||
);
|
||||
case 2:
|
||||
case "failure":case"error":
|
||||
return (
|
||||
<span className="statusColor failed">未通过</span>
|
||||
);
|
||||
case 3:
|
||||
case "success":
|
||||
return (
|
||||
<span className="statusColor pass">已通过</span>
|
||||
);
|
||||
default:
|
||||
case "pending":
|
||||
return (
|
||||
<span className="statusColor Preparing">准备中</span>
|
||||
);
|
||||
case 'killed':
|
||||
return (
|
||||
<span className="statusColor killed">已撤销</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const TagsLine = (status)=>{
|
||||
switch(status){
|
||||
case 1:
|
||||
case "running":
|
||||
return(
|
||||
<span className="statuslineColor running">运行中</span>
|
||||
);
|
||||
case 2:
|
||||
case "failure":case "error":
|
||||
return (
|
||||
<span className="statuslineColor failed">未通过</span>
|
||||
);
|
||||
case 3:
|
||||
case "success":
|
||||
return (
|
||||
<span className="statuslineColor pass">已通过</span>
|
||||
);
|
||||
default:
|
||||
case "pending":
|
||||
return (
|
||||
<span className="statuslineColor Preparing">准备中</span>
|
||||
);
|
||||
case 'killed':
|
||||
return (
|
||||
<span className="statuslineColor killed">已撤销</span>
|
||||
);
|
||||
case 'skipped':
|
||||
return (
|
||||
<span className="statuslineColor skipped">已跳过</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
import React ,{ useState } from 'react';
|
||||
import { Modal , Input , Spin } from 'antd';
|
||||
import { AlignCenter } from "./layout";
|
||||
import axios from 'axios';
|
||||
import './Component.scss';
|
||||
|
||||
function PasswordAuthority({ authorityValBox , successFunc , cancelFunc }){
|
||||
const [ authorityVal , setAuthorityVal ] = useState(undefined);
|
||||
const [ authorityValFlag , setAuthorityValFlag ] = useState(false);
|
||||
const [ isSpin , setIsSpin ] = useState(false);
|
||||
|
||||
// 取消授权-登录密码的输入
|
||||
function cancelAuthority(){
|
||||
setAuthorityVal(undefined);
|
||||
cancelFunc();
|
||||
}
|
||||
// 确认授权
|
||||
function okAuthority(){
|
||||
if(!authorityVal){
|
||||
setAuthorityValFlag(true);
|
||||
return;
|
||||
}
|
||||
setIsSpin(true);
|
||||
const url = `/users/ci/oauth_grant.json`;
|
||||
axios.get(url,{
|
||||
params:{password:authorityVal}
|
||||
}).then(result=>{
|
||||
setIsSpin(false);
|
||||
if(result){
|
||||
successFunc(result.data.step);
|
||||
}
|
||||
}).catch(error=>{setIsSpin(false);});
|
||||
}
|
||||
return(
|
||||
<Modal visible={authorityValBox} centered={true} title="授权" onCancel={cancelAuthority} onOk={okAuthority}>
|
||||
<Spin spinning={isSpin}>
|
||||
<p style={{textAlign:"center"}}>请输入您的登录密码,确认授权DevOps应用</p>
|
||||
<AlignCenter style={{justifyContent:"center",marginTop:"20px"}}>
|
||||
<span>密码:</span>
|
||||
<Input.Password value={authorityVal} className={authorityValFlag===true && "flags"} onChange={(e)=>setAuthorityVal(e.target.value)} style={{width:"220px"}}></Input.Password>
|
||||
</AlignCenter>
|
||||
</Spin>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default PasswordAuthority;
|
|
@ -1,27 +1,66 @@
|
|||
import React , { forwardRef , useCallback } from 'react';
|
||||
import activate from '../Images/activate.png';
|
||||
import { Blueback } from '../Component/layout';
|
||||
import styled from 'styled-components';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Form , Input } from 'antd';
|
||||
import axios from 'axios';
|
||||
import React, { forwardRef, useCallback, useState , useEffect } from "react";
|
||||
import activate from "../Images/activate.png";
|
||||
import { Blueback , AlignCenter } from "../Component/layout";
|
||||
import PasswordAuthority from "../Component/PasswordAuthority";
|
||||
import styled from "styled-components";
|
||||
import { Form, Input , Spin , Modal } from "antd";
|
||||
import axios from "axios";
|
||||
|
||||
const P = styled.p`{
|
||||
width:200px;
|
||||
line-height:30px;
|
||||
font-size:16px;
|
||||
color:#333;
|
||||
text-align:center;
|
||||
margin-top:30px;
|
||||
margin-bottom:30px!important;
|
||||
}`;
|
||||
function About( props , ref){
|
||||
const { form: { getFieldDecorator , validateFields } } = props;
|
||||
const P = styled.p`
|
||||
{
|
||||
width: 230px;
|
||||
line-height: 30px;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px !important;
|
||||
}
|
||||
`;
|
||||
function About(props, ref) {
|
||||
const { form: { getFieldDecorator, validateFields , setFieldsValue } } = props;
|
||||
const [isSpining, setIsSpining] = useState(true);
|
||||
const [ authorityValBox , setAuthorityValBox ] = useState(false);
|
||||
const [ authorityVal , setAuthorityVal ] = useState(undefined);
|
||||
const [ authorityValFlag , setAuthorityValFlag ] = useState(false);
|
||||
//0: 标识未开启devops
|
||||
//1: 标识用户已填写了云服务器相关信息,但并未开启认证
|
||||
const [step, setStep] = useState(undefined);
|
||||
// step大于1时:为true,不能再修改服务器信息
|
||||
const owner = props.match.params.owner;
|
||||
const projectsId = props.match.params.projectsId;
|
||||
|
||||
|
||||
const AuthorLogin = props.author && props.author.login;
|
||||
const CurrentLogin = props.current_user && props.current_user.login;
|
||||
useEffect(()=>{
|
||||
if(CurrentLogin === AuthorLogin){
|
||||
auth('get');
|
||||
}else{
|
||||
setIsSpining(false);
|
||||
}
|
||||
},[AuthorLogin,CurrentLogin])
|
||||
|
||||
function auth(type){
|
||||
const url = `/${owner}/${projectsId}/ci_authorize.json`;
|
||||
axios({
|
||||
method:`${type}`,
|
||||
url
|
||||
}).then(result=>{
|
||||
if(result && result.data ){
|
||||
setIsSpining(false);
|
||||
setStep(result.data.step);
|
||||
setFieldsValue({...result.data.cloud_account});
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget, isRequired) => (
|
||||
<React.Fragment>
|
||||
<span className={isRequired?"required":""}>{label}</span>
|
||||
<span className={isRequired ? "required" : ""}>{label}</span>
|
||||
<Form.Item>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
</Form.Item>
|
||||
|
@ -29,52 +68,122 @@ function About( props , ref){
|
|||
),
|
||||
[]
|
||||
);
|
||||
|
||||
function startActive(){
|
||||
let projectsId = props.match.params.projectsId;
|
||||
validateFields((error,values)=>{
|
||||
if(!error){
|
||||
const url = `/dev_ops/cloud_accounts.json`;
|
||||
axios.post(url,{
|
||||
...values,
|
||||
project_id:projectsId
|
||||
}).then(result=>{
|
||||
if(result && result.data.redirect_url){
|
||||
window.location.href = result.data.redirect_url;
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
// 下一步
|
||||
function goStep() {
|
||||
validateFields((error, values) => {
|
||||
if (!error) {
|
||||
if(step > 0){
|
||||
setAuthorityValBox(true);
|
||||
}else{
|
||||
setIsSpining(true);
|
||||
const url = `/${owner}/${projectsId}/cloud_accounts.json`;
|
||||
axios.post(url, {...values,ip_num:values.ip}).then((result) => {
|
||||
setIsSpining(false);
|
||||
if (result && result.data.redirect_url) {
|
||||
props.showNotification("服务器信息配置完成!");
|
||||
setStep(1);
|
||||
setAuthorityValBox(true);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
setIsSpining(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 开始激活
|
||||
function startActive(){
|
||||
setIsSpining(true);
|
||||
const url = `/${owner}/${projectsId}/activate.json`;
|
||||
axios.post(url).then(result=>{
|
||||
setIsSpining(false);
|
||||
if(result && result.data.status === 0){
|
||||
props.history.push(`/projects/${owner}/${projectsId}/devops/dispose`);
|
||||
// 需要将顶部的open_devops修改
|
||||
let { changeOpenDevops } = props;
|
||||
changeOpenDevops && changeOpenDevops(true);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
setIsSpining(false);
|
||||
})
|
||||
}
|
||||
return(
|
||||
<div className="activatePanel">
|
||||
<img src={activate} alt="" width="250px"/>
|
||||
<P>定义DevOps工作流,帮助您检测bug、发布代码…</P>
|
||||
<Link to={""} style={{color:"#5091FF",marginBottom:"20px"}}>了解什么是DevOps?</Link>
|
||||
<Form>
|
||||
{helper(
|
||||
"服务器IP地址:",
|
||||
"ip_num",
|
||||
[{ required: true, message: "请输入服务器IP地址" }],
|
||||
<Input placeholder="请输入服务器IP地址" style={{width:"368px"}} size="large" />,true
|
||||
)}
|
||||
{helper(
|
||||
"服务器用户名:",
|
||||
"account",
|
||||
[{ required: true, message: "请输入服务器用户名" }],
|
||||
<Input placeholder="请输入服务器用户名" size="large" />,true
|
||||
)}
|
||||
{helper(
|
||||
"服务器密码:",
|
||||
"secret",
|
||||
[{ required: true, message: "请输入服务器密码" }],
|
||||
<Input.Password placeholder="请输入服务器密码" size="large" />,true
|
||||
)}
|
||||
</Form>
|
||||
<Blueback onClick={startActive}>开始激活</Blueback>
|
||||
</div>
|
||||
)
|
||||
// 取消授权-登录密码的输入
|
||||
function cancelAuthority(){
|
||||
setAuthorityValBox(false);
|
||||
}
|
||||
// 确认授权
|
||||
function okAuthority(step){
|
||||
setAuthorityValBox(false);
|
||||
setStep(step);
|
||||
}
|
||||
return (
|
||||
<Spin spinning={isSpining}>
|
||||
<PasswordAuthority authorityValBox={authorityValBox} successFunc={okAuthority} cancelFunc={cancelAuthority}></PasswordAuthority>
|
||||
<div className="activatePanel">
|
||||
<img src={activate} alt="" width="250px" />
|
||||
<P>定义DevOps工作流,帮助您检测bug、发布代码…</P>
|
||||
{
|
||||
CurrentLogin !== AuthorLogin && (step === undefined || (step && step < 1)) &&
|
||||
<div className="noOperation">DevOps开启功能暂未对项目创建者以外的角色开放,可以联系项目创建者进行开启,开启后便可查看构建信息。</div>
|
||||
}
|
||||
<a href={"https://forum.trustie.net/forums/3080/detail"} target="_blank" style={{ color: "#5091FF"}}>
|
||||
了解什么是DevOps?
|
||||
</a>
|
||||
<a href={"https://forum.trustie.net/forums/3110/detail"} target="_blank" style={{ color: "#5091FF"}}>
|
||||
如何使用DevOps?
|
||||
</a>
|
||||
{
|
||||
AuthorLogin === CurrentLogin ?
|
||||
<React.Fragment>
|
||||
{ step <=1 ?
|
||||
<React.Fragment>
|
||||
<Input.Password style={{display:'none'}} size="large" />
|
||||
<Form style={{marginTop:"20px"}}>
|
||||
<p className="mb20" style={{width:"370px"}}>请仔细核对您的服务器信息,一旦确认提交将无法修改</p>
|
||||
{helper(
|
||||
"服务器IP地址:",
|
||||
"ip",
|
||||
[{ required: true, message: "请输入服务器IP地址" }],
|
||||
<Input
|
||||
placeholder="请输入服务器IP地址"
|
||||
style={{ width: "368px" }}
|
||||
size="large"
|
||||
disabled={step > 0}
|
||||
/>,
|
||||
true
|
||||
)}
|
||||
{helper(
|
||||
"服务器用户名:",
|
||||
"account",
|
||||
[{ required: true, message: "请输入服务器用户名" }],
|
||||
<Input placeholder="请输入服务器用户名" size="large" disabled={step > 0}/>,
|
||||
true
|
||||
)}
|
||||
{helper(
|
||||
"服务器密码:",
|
||||
"secret",
|
||||
[{ required: true, message: "请输入服务器密码" }],
|
||||
<Input.Password placeholder="请输入服务器密码" size="large" disabled={step > 0}/>,
|
||||
true
|
||||
)}
|
||||
</Form>
|
||||
<Blueback onClick={goStep}>下一步</Blueback>
|
||||
</React.Fragment>
|
||||
:""}
|
||||
{step > 1 &&
|
||||
<div style={{textAlign:'center',marginTop:"20px"}}>
|
||||
<Blueback onClick={startActive} className="mt20">开始激活</Blueback>
|
||||
</div>
|
||||
}
|
||||
</React.Fragment>
|
||||
:""
|
||||
}
|
||||
</div>
|
||||
</Spin>
|
||||
);
|
||||
}
|
||||
export default Form.create()(forwardRef(About));
|
||||
export default Form.create()(forwardRef(About));
|
||||
|
|
|
@ -1,53 +1,45 @@
|
|||
import React , { useState , useEffect } from 'react';
|
||||
import { Spin } from 'antd';
|
||||
import { Blueback } from '../Component/layout';
|
||||
import Editor from "react-monaco-editor";
|
||||
import Modals from './DisposeModal';
|
||||
import FileLanguage from '../Component/FileLanguage';
|
||||
import FileLanguage from '../Component/OpsFileLanguage';
|
||||
import axios from 'axios';
|
||||
|
||||
|
||||
function Dispose(props){
|
||||
const [ info , setInfo ] = useState(undefined);
|
||||
const [ spining , setSpining ] = useState(true);
|
||||
const [ info , setInfo ] = useState('.trustie-pipeline.yml');
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const [ ymlValue , setYmlValue ] = useState("");
|
||||
const [ six , setSix ] = useState(undefined);
|
||||
const [ sha , setSha ] = useState(undefined);
|
||||
const [ fileLanguage , setFileLanguage ] = useState(undefined);
|
||||
const [ first , setFirst ] = useState(false);
|
||||
|
||||
let projectsId = props.match.params.projectsId;
|
||||
let owner = props.match.params.owner;
|
||||
|
||||
useEffect(()=>{
|
||||
if(projectsId){
|
||||
const url = '/dev_ops/builds/get_trustie_pipeline.json';
|
||||
const url = `/${owner}/${projectsId}/get_trustie_pipeline.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
project_id:projectsId
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data.content){
|
||||
setInfo(result.data);
|
||||
setInfo(result.data.name);
|
||||
setYmlValue(result.data.content);
|
||||
setFirst(true);
|
||||
setSha(result.data.sha);
|
||||
}else{
|
||||
setFirst(false);
|
||||
}
|
||||
setSpining(false);
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
},[])
|
||||
|
||||
useEffect(()=>{
|
||||
const url = '/dev_ops/languages/common.json';
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
setSix(result.data);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
},[])
|
||||
},[projectsId])
|
||||
|
||||
// 修改文件内容
|
||||
function changeEditor(value){
|
||||
|
@ -57,25 +49,25 @@ function Dispose(props){
|
|||
// 切换语言
|
||||
function select_language(value,array){
|
||||
setFileLanguage(value);
|
||||
// console.log(array);
|
||||
setYmlValue( array && array.content);
|
||||
}
|
||||
|
||||
// 确定提交
|
||||
function submit(){
|
||||
let url = '';
|
||||
const { defaultBranch } = props;
|
||||
let params = {
|
||||
branch: "master",
|
||||
branch: defaultBranch,
|
||||
content:ymlValue,
|
||||
filepath:info && info.name,
|
||||
filepath:info,
|
||||
message:''
|
||||
}
|
||||
if(first){
|
||||
// 为true,则是编辑否则是新建
|
||||
url = `/${owner}/${projectsId}/update_file.json`;
|
||||
url = `/${owner}/${projectsId}/update_trustie_pipeline.json`;
|
||||
axios.put(url,{
|
||||
...params,
|
||||
sha:info && info.sha
|
||||
sha
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
setVisible(true);
|
||||
|
@ -95,37 +87,24 @@ function Dispose(props){
|
|||
}
|
||||
}
|
||||
function suresubmit(){
|
||||
props.history.push(`/projects/${owner}/${projectsId}/ops/list`);
|
||||
setVisible(false);
|
||||
props.history.push(`/projects/${owner}/${projectsId}/devops/list`);
|
||||
}
|
||||
|
||||
return(
|
||||
<React.Fragment>
|
||||
<Spin spinning={spining}>
|
||||
<Modals visible={visible} closeFunc={(flag)=>setVisible(flag)} sureFunc={suresubmit}></Modals>
|
||||
<p>编程语言:</p>
|
||||
{
|
||||
six &&
|
||||
<ul className="language">
|
||||
{
|
||||
six && six.map((item,key)=>{
|
||||
return(
|
||||
key < 6 ? <li><img alt="" src={item.cover_url} /></li> : ""
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
|
||||
<div className="mt20 mb20">
|
||||
<FileLanguage language={fileLanguage} select_language={select_language}/>
|
||||
</div>
|
||||
<p>配置脚本:</p>
|
||||
<div className="editorBody">
|
||||
<p className="editorHead">
|
||||
<span>{info && info.name}</span>
|
||||
<a><i className="iconfont icon-bianji6 font-14"></i></a>
|
||||
</p>
|
||||
<p className="editorHead">{info}</p>
|
||||
<Editor
|
||||
height="300px"
|
||||
language={"java"}
|
||||
language={"yml"}
|
||||
theme={"vs-grey"}
|
||||
defaultValue="请输入内容"
|
||||
value={ymlValue}
|
||||
|
@ -134,7 +113,7 @@ function Dispose(props){
|
|||
></Editor>
|
||||
</div>
|
||||
<Blueback onClick={submit}>确定提交</Blueback>
|
||||
</React.Fragment>
|
||||
</Spin>
|
||||
)
|
||||
}
|
||||
export default Dispose;
|
|
@ -8,7 +8,7 @@ const Div = styled.div`{
|
|||
text-align:center;
|
||||
color:#333;
|
||||
}`
|
||||
export default (({visible , closeFunc , suresubmit})=>{
|
||||
export default (({visible , closeFunc , sureFunc})=>{
|
||||
return(
|
||||
<Modal
|
||||
title="提示"
|
||||
|
@ -17,7 +17,7 @@ export default (({visible , closeFunc , suresubmit})=>{
|
|||
footer={
|
||||
<div>
|
||||
<Button onClick={()=>closeFunc(false)}>取消</Button>
|
||||
<Button type={"primary"} onClick={suresubmit} style={{marginLeft:"20px"}}>确定</Button>
|
||||
<Button type={"primary"} onClick={()=>sureFunc()} style={{marginLeft:"20px"}}>确定</Button>
|
||||
</div>
|
||||
}
|
||||
onCancel={()=>closeFunc(false)}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React , { useEffect } from 'react';
|
||||
import { WhiteBack } from '../Component/layout';
|
||||
import './ops.scss';
|
||||
|
||||
|
@ -15,20 +15,33 @@ const Infos = Loadable({
|
|||
loading: Loading,
|
||||
})
|
||||
export default ((props)=>{
|
||||
const { projectsId , owner } = props.match.params;
|
||||
const open_devops = props.projectDetail && props.projectDetail.open_devops;
|
||||
|
||||
// 工作流:两种状态进入的链接不同
|
||||
useEffect(()=>{
|
||||
if(open_devops !== undefined){
|
||||
if(open_devops){
|
||||
props.history.replace(`/projects/${owner}/${projectsId}/devops/list`);
|
||||
}else{
|
||||
props.history.replace(`/projects/${owner}/${projectsId}/devops`);
|
||||
}
|
||||
}
|
||||
},[open_devops])
|
||||
return(
|
||||
<WhiteBack className="opsPanel">
|
||||
<Switch {...props}>
|
||||
<Route path="/projects/:projectsId/ops/dispose"
|
||||
<Route path="/projects/:owner/:projectsId/devops/dispose"
|
||||
render={
|
||||
() => (<Infos {...props} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/ops/list"
|
||||
<Route path="/projects/:owner/:projectsId/devops/list"
|
||||
render={
|
||||
() => (<Infos {...props} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/ops"
|
||||
<Route path="/projects/:owner/:projectsId/devops"
|
||||
render={
|
||||
() => (<About {...props} />)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import React , { useEffect , useState , useRef } from 'react';
|
||||
import { Banner } from '../Component/layout';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
|
@ -11,27 +11,46 @@ const Div = styled.div`{
|
|||
padding:24px 30px;
|
||||
}`;
|
||||
export default ((props)=>{
|
||||
const [ menu , setMenu ] = useState(undefined);
|
||||
const [ menu , setMenu ] = useState(false);
|
||||
const [ permission , setPermission ] = useState("");
|
||||
const childRef = useRef();
|
||||
|
||||
const path = props.location.pathname;
|
||||
const owner = props.match.params.owner;
|
||||
const projectsId = props.match.params.projectsId;
|
||||
|
||||
const projectDetail = props.projectDetail;
|
||||
useEffect(()=>{
|
||||
// console.log(props.match.params.projectsId)
|
||||
if(path === `/projects/${props.match.params.projectsId}/ops/list`){
|
||||
if(path === `/projects/${owner}/${projectsId}/devops/list`){
|
||||
setMenu(true);
|
||||
}else{
|
||||
setMenu(false);
|
||||
}
|
||||
},[path])
|
||||
|
||||
useEffect(()=>{
|
||||
if(projectDetail){
|
||||
setPermission(props.projectDetail.permission);
|
||||
}
|
||||
},[projectDetail])
|
||||
|
||||
const updateChildState = () => {
|
||||
// changeVal就是子组件暴露给父组件的方法
|
||||
if (childRef.current) {
|
||||
childRef.current.changeVal();
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="disposePanel">
|
||||
<Banner>
|
||||
<Link to={`/projects/${props.match.params.projectsId}/ops/dispose`}>工作流配置</Link>
|
||||
{ menu ? <Link to={`/projects/${props.match.params.projectsId}/ops/list`} style={{ marginLeft:"66px",color:"#5091FF" }}>构建列表</Link>:""}
|
||||
{ permission !=="Reporter" && <Link to={`/projects/${owner}/${props.match.params.projectsId}/devops/dispose`} className={menu===false && "color-blue"} style={{ marginRight:"66px"}}>工作流配置</Link>}
|
||||
<Link to={`/projects/${owner}/${props.match.params.projectsId}/devops/list`}className={menu===true && "color-blue"}>构建列表</Link>
|
||||
{ menu===true && <a onClick={updateChildState} style={{float:"right",fontSize:"14px",color:"#FF6E21",marginTop:"5px"}}>刷新</a>}
|
||||
</Banner>
|
||||
<Div>
|
||||
{ menu && menu === true && <Structure {...props}/> }
|
||||
{ menu && menu === false && <Dispost {...props}/> }
|
||||
{ menu === true && <Structure {...props} wrappedComponentRef={(form) => childRef.current = form} ref={childRef}/> }
|
||||
{ menu === false && permission !=="Reporter" && <Dispost {...props}/> }
|
||||
</Div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -1,42 +1,127 @@
|
|||
import React from 'react';
|
||||
import { FlexAJ , Blueline , AlignCenter } from '../Component/layout';
|
||||
import styled from 'styled-components';
|
||||
import { Menu } from 'antd';
|
||||
import { TagsLine } from '../Component/OpsStatus';
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { FlexAJ, Blueline, AlignCenter } from "../Component/layout";
|
||||
import styled from "styled-components";
|
||||
import { Menu, Popconfirm } from "antd";
|
||||
import { TagsLine } from "../Component/OpsStatus";
|
||||
import { Time } from "../Utils/Time";
|
||||
import { truncateCommitId } from "../common/util";
|
||||
import { getUrl } from 'educoder';
|
||||
|
||||
const SubMenu = Menu.SubMenu;
|
||||
const Img = styled.img`{
|
||||
width:25px;
|
||||
height:25px;
|
||||
border-radius:50%;
|
||||
margin-right:10px;
|
||||
}`
|
||||
export default (()=>{
|
||||
return(
|
||||
const Img = styled.img`
|
||||
{
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
`;
|
||||
export default ({ data, repeatSet , chooseSteps }) => {
|
||||
const [tamp, setTamp] = useState(undefined);
|
||||
const [sha, setSha] = useState(undefined);
|
||||
useEffect(() => {
|
||||
if (data && data.started) {
|
||||
let t = parseInt(data.started) * 1000;
|
||||
let time = Time(t);
|
||||
setTamp(time);
|
||||
}
|
||||
if (data && data.after) {
|
||||
setSha(truncateCommitId(data.after));
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
function renderStatusBtn() {
|
||||
let status = data && data.status;
|
||||
let number = data && data.number;
|
||||
if (status === "failure" || status === "error" || status === "success") {
|
||||
return "";
|
||||
}else if(status === "killed"){
|
||||
return(
|
||||
<Popconfirm
|
||||
title="确认重新构建?"
|
||||
onConfirm={(e) => repeatSet(e,'repeat',number)}
|
||||
onCancel={(e)=>{e.stopPropagation()}}
|
||||
cancelText="取消"
|
||||
okText="确定"
|
||||
>
|
||||
<Blueline onClick={(e)=>{e.stopPropagation()}}>重新构建</Blueline>
|
||||
</Popconfirm>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Popconfirm
|
||||
title="确认撤销构建?"
|
||||
onConfirm={(e) => repeatSet(e,'cancel',number)}
|
||||
onCancel={(e)=>{e.stopPropagation()}}
|
||||
cancelText="取消"
|
||||
okText="确定"
|
||||
>
|
||||
<Blueline onClick={(e)=>{e.stopPropagation()}}>撤销构建</Blueline>
|
||||
</Popconfirm>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function clickSub(e,stageN,stepN){
|
||||
chooseSteps(stageN,stepN);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FlexAJ className="leftheader">
|
||||
<AlignCenter>
|
||||
<Img src="https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2091711702,2468700162&fm=111&gp=0.jpg"/>
|
||||
<span className="nest">开始时间:<span>2020.07.10 15:30</span></span>
|
||||
<span className="nest">运行时间:<span>20s</span></span>
|
||||
<Img src={getUrl(`/images/${data && data.author && data.author.image_url}`)} />
|
||||
{data && data.started &&
|
||||
<span className="nest">
|
||||
开始时间:<span> {data.started}</span>
|
||||
</span>
|
||||
}
|
||||
{
|
||||
data && data.duration_time &&
|
||||
<span className="nest">
|
||||
运行时间:<span>{data.duration_time}</span>
|
||||
</span>
|
||||
}
|
||||
</AlignCenter>
|
||||
<Blueline>重新创建</Blueline>
|
||||
{renderStatusBtn()}
|
||||
</FlexAJ>
|
||||
<div className="leftMainContent">
|
||||
<AlignCenter className="contentBranch">
|
||||
<i className="iconfont icon-fenzhi1"></i>
|
||||
<span>分支:</span>
|
||||
<span className="branchname">master</span>
|
||||
<span className="branchsha">8b3476f5</span>
|
||||
<span className="branchname">{data && data.branch_target}</span>
|
||||
<span className="branchsha">{data && truncateCommitId(data.build_after_sha)}</span>
|
||||
</AlignCenter>
|
||||
</div>
|
||||
<Menu mode='inline' className="leftMenu">
|
||||
<SubMenu title={<div><i className="iconfont icon-gongzuoliu font-14 mr4"></i><span>CI</span></div>}>
|
||||
<Menu.Item>
|
||||
<FlexAJ><span>Build setup 01 {TagsLine(1)}</span><span>20s</span></FlexAJ>
|
||||
</Menu.Item>
|
||||
</SubMenu>
|
||||
<Menu mode="inline" className="leftMenu" defaultOpenKeys={[`0`]} defaultSelectedKeys={[`0`]}>
|
||||
{data && data.stages ? data.stages.map((item, key) => {
|
||||
return item.steps && item.steps.length > 0 ?
|
||||
<SubMenu
|
||||
title={
|
||||
<div>
|
||||
<i className="iconfont icon-gongzuoliu font-14 mr4"></i>
|
||||
<span>{item.name}</span>
|
||||
</div>
|
||||
}
|
||||
key={`${key}`}
|
||||
>
|
||||
{item.steps.map((i, k) => {
|
||||
return (
|
||||
<Menu.Item key={`${k}`} onClick={(e)=>clickSub(e,item.number,i.id)}>
|
||||
<FlexAJ>
|
||||
<span>
|
||||
{i.name} {i.status ? TagsLine(i.status) : ""}
|
||||
</span>
|
||||
<span>{i.duration_time}</span>
|
||||
</FlexAJ>
|
||||
</Menu.Item>
|
||||
);
|
||||
})}
|
||||
</SubMenu>
|
||||
: "";
|
||||
})
|
||||
: ""}
|
||||
</Menu>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,21 +1,107 @@
|
|||
import React from 'react';
|
||||
import { FlexAJ , AlignCenter } from '../Component/layout';
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Spin } from "antd";
|
||||
import { FlexAJ, AlignCenter } from "../Component/layout";
|
||||
import axios from "axios";
|
||||
|
||||
export default (()=>{
|
||||
return(
|
||||
<div className="rightMainContent">
|
||||
<div>
|
||||
<FlexAJ className="items">
|
||||
<span>Build setup 01</span>
|
||||
<AlignCenter>20<i className="iconfont icon-triangle"></i></AlignCenter>
|
||||
</FlexAJ>
|
||||
export default ({
|
||||
data,
|
||||
stepN,
|
||||
stageN,
|
||||
projectId,
|
||||
owner,
|
||||
opsId,
|
||||
rightSpin,
|
||||
}) => {
|
||||
const [coders, setCoders] = useState(undefined);
|
||||
const [empty, setEmpty] = useState(false);
|
||||
const [spining, setSpining] = useState(true);
|
||||
const [stage, setStage] = useState(undefined);
|
||||
const [step, setStep] = useState(undefined);
|
||||
useEffect(() => {
|
||||
setSpining(rightSpin);
|
||||
}, [rightSpin]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
let stages = data.stages;
|
||||
if (stages && stages.length > 0) {
|
||||
let pre = stageN
|
||||
? stages.filter((item) => item.number === stageN)[0]
|
||||
: stages[0];
|
||||
setStage(pre);
|
||||
let p = pre && pre.steps;
|
||||
let sub = stepN
|
||||
? p && p.length > 0 && p.filter((item) => item.id === stepN)[0]
|
||||
: p[0];
|
||||
|
||||
setStep(sub);
|
||||
if (sub && sub.status !== "skipped") {
|
||||
getStep(pre.number, sub.number);
|
||||
}
|
||||
// 如果状态是skipped就不用去调用接口查询对应的out信息了
|
||||
if(sub.status === "skipped"){
|
||||
setCoders(undefined);
|
||||
setEmpty(true);
|
||||
setSpining(false);
|
||||
}
|
||||
} else {
|
||||
setSpining(false);
|
||||
}
|
||||
}
|
||||
}, [data, stageN, stepN]);
|
||||
|
||||
function getStep(stageN, stepN) {
|
||||
if (stageN && stepN) {
|
||||
const url = `/${owner}/${projectId}/builds/${opsId}/logs/${stageN}/${stepN}.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
setCoders(result.data);
|
||||
setSpining(false);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Spin spinning={spining}>
|
||||
<div className="rightMainContent">
|
||||
{data && data.status !== "error" ? (
|
||||
<div>
|
||||
<FlexAJ className="items">
|
||||
<span>{step && step.name}</span>
|
||||
<AlignCenter>
|
||||
{step && step.duration_time}
|
||||
<i className="iconfont icon-sanjiaoxing-down"></i>
|
||||
</AlignCenter>
|
||||
</FlexAJ>
|
||||
<div>
|
||||
{coders && coders.length > 0 ? (
|
||||
coders.map((item, key) => {
|
||||
return (
|
||||
<div className="opsDetailOut">
|
||||
<span>{key + 1}</span>
|
||||
<p>{item.out}</p>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
) : empty ? (
|
||||
<div className="opsDetailOut">
|
||||
<span>1</span>
|
||||
<p>
|
||||
{stage && stage.name} – {step && step.name}: Skipped
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ color: "red" }}>error:{data && data.error}</div>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<FlexAJ className="items"></FlexAJ>
|
||||
</div>
|
||||
<div>
|
||||
<FlexAJ className="items"></FlexAJ>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
</Spin>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,240 +1,320 @@
|
|||
import React , { useState , useEffect } from 'react';
|
||||
import { FlexAJ , AlignCenter , Blueback } from '../Component/layout';
|
||||
import { Table , Pagination } from 'antd';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import styled from 'styled-components';
|
||||
import axios from 'axios';
|
||||
import React, { useState, useEffect , useImperativeHandle ,forwardRef } from "react";
|
||||
import { FlexAJ, AlignCenter } from "../Component/layout";
|
||||
import { Table, Pagination, Popconfirm } from "antd";
|
||||
import { truncateCommitId } from "../common/util";
|
||||
import {getUrl} from 'educoder';
|
||||
import axios from "axios";
|
||||
|
||||
const STATUS = [
|
||||
{name:"所有",value:"1"},
|
||||
{name:"准备中",value:"2"},
|
||||
{name:"运行中",value:"3"},
|
||||
{name:"已完成",value:"4"}
|
||||
]
|
||||
const LIMIT = 15;
|
||||
const datasource = [
|
||||
{
|
||||
status:2,
|
||||
author:"caishi",
|
||||
message:{
|
||||
branch:"master",
|
||||
sha:"8b3476f5",
|
||||
image:"https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2034740944,4251903193&fm=26&gp=0.jpg",
|
||||
message:"将分支“ 221063-improve-buy-ci-minutes-link”"
|
||||
},
|
||||
begin:"2020-07-08",
|
||||
run:"20s"
|
||||
},
|
||||
{
|
||||
status:1,
|
||||
author:"caishi",
|
||||
message:{
|
||||
branch:"master",
|
||||
sha:"8b3476f5",
|
||||
image:"https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2034740944,4251903193&fm=26&gp=0.jpg",
|
||||
message:"将分支“ 221063-improve-buy-ci-minutes-link”"
|
||||
},
|
||||
begin:"2020-07-08",
|
||||
run:""
|
||||
}
|
||||
{ name: "所有"},
|
||||
{ name: "运行中", value: "running" },
|
||||
{ name: "已撤销", value: "killed" },
|
||||
{ name: "构建失败", value: "failure" },
|
||||
{ name: "已完成", value: "success" },
|
||||
];
|
||||
const LIMIT = 15;
|
||||
function Structure(props,ref){
|
||||
const [status, setStatus] = useState(undefined);
|
||||
const [page, setPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [data, setData] = useState(undefined);
|
||||
const [tableLoading, setTableLoading] = useState(true);
|
||||
|
||||
const Img = styled.img`{
|
||||
border-radius:50%;
|
||||
margin-rigth:10px;
|
||||
width:25px;
|
||||
height:25px;
|
||||
}`
|
||||
export default ((props)=>{
|
||||
const [ status ,setStatus ] = useState("1");
|
||||
const [ page ,setPage ] = useState(1);
|
||||
const [ total ,setTotal ] = useState(10);
|
||||
const [ data , setData ] = useState(undefined);
|
||||
let projectsId = props.match.params.projectsId;
|
||||
let owner = props.match.params.owner;
|
||||
const permission = props.projectDetail && props.projectDetail.permission;
|
||||
|
||||
let projectsId = props.match.params.projectsId;
|
||||
|
||||
useEffect(()=>{
|
||||
if(projectsId){
|
||||
const url ='/dev_ops/builds.json';
|
||||
axios.get(url,{
|
||||
params:{
|
||||
project_id:projectsId
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
let list = result.data && result.data.map((item,key)=>{
|
||||
return {
|
||||
status:item.status,
|
||||
author:item.sender,
|
||||
message:{
|
||||
branch:item.source,
|
||||
image:item.author_avatar,
|
||||
message:item.message,
|
||||
sha:truncateCommitId(item.after)
|
||||
},
|
||||
started:item.started,
|
||||
timestamp:item.timestamp
|
||||
}
|
||||
})
|
||||
setData(list);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
useImperativeHandle(ref, () => ({
|
||||
changeVal: () => {
|
||||
setTableLoading(true);
|
||||
Init();
|
||||
}
|
||||
},[])
|
||||
}))
|
||||
|
||||
function ChangeStatus(value){
|
||||
setStatus(value)
|
||||
useEffect(() => {
|
||||
if (projectsId) {
|
||||
Init();
|
||||
}
|
||||
}, [page]);
|
||||
|
||||
let current_user = props.current_user;
|
||||
function Init(status) {
|
||||
const url = `/${owner}/${projectsId}/builds.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
search:status,
|
||||
page,limit:LIMIT
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result && result.data) {
|
||||
let list = result.data.builds && result.data.builds.map((item, key) => {
|
||||
return {
|
||||
...item,
|
||||
author:item.author && item.author.name,
|
||||
message: {
|
||||
branch: item.branch_target,
|
||||
message: item.message,
|
||||
sha: truncateCommitId(item.build_after_sha),
|
||||
},
|
||||
started: item.started || "--"
|
||||
};
|
||||
});
|
||||
setTotal(result.data.total_count);
|
||||
setData(list);
|
||||
setTableLoading(false);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
function ChangeStatus(value) {
|
||||
setStatus(value);
|
||||
Init(value);
|
||||
}
|
||||
// 切换分页
|
||||
function ChangePage(page){
|
||||
setPage(page)
|
||||
function ChangePage(page) {
|
||||
setPage(page);
|
||||
}
|
||||
function renderStatus() {
|
||||
return(
|
||||
return (
|
||||
<ul className="listNav">
|
||||
{
|
||||
STATUS.map((item,key)=>{
|
||||
return <li onClick={()=>ChangeStatus(item.value)} className={ status === item.value ? "active":""}>{item.name}</li>
|
||||
})
|
||||
}
|
||||
{STATUS.map((item, key) => {
|
||||
return (
|
||||
<li
|
||||
onClick={() => ChangeStatus(item.value)}
|
||||
className={status === item.value ? "active" : ""}
|
||||
>
|
||||
{item.name}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
)
|
||||
);
|
||||
}
|
||||
function renderStatusBtn(status){
|
||||
if(status === "failure" || status ==="success"){
|
||||
function renderStatusBtn(status, number) {
|
||||
if (status === "error" || status === "success") {
|
||||
return "";
|
||||
}else if(status === "killed" || status === "failure"){
|
||||
return(
|
||||
<a className="color-blue">重新构建</a>
|
||||
)
|
||||
}else{
|
||||
return(
|
||||
<a className="color-red">撤销构建</a>
|
||||
)
|
||||
<Popconfirm
|
||||
title="确认重新构建?"
|
||||
onConfirm={(e) => repeatSet(e,number)}
|
||||
onCancel={(e)=>{e.stopPropagation()}}
|
||||
cancelText="取消"
|
||||
okText="确定"
|
||||
>
|
||||
<a className="color-blue" onClick={(e)=>{e.stopPropagation()}}>重新构建</a>
|
||||
</Popconfirm>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Popconfirm
|
||||
title="确认撤销构建?"
|
||||
onConfirm={(e) => cancelSet(e,number)}
|
||||
onCancel={(e)=>{e.stopPropagation()}}
|
||||
cancelText="取消"
|
||||
okText="确定"
|
||||
>
|
||||
<a className="color-red" onClick={(e)=>{e.stopPropagation()}}>撤销构建</a>
|
||||
</Popconfirm>
|
||||
);
|
||||
}
|
||||
}
|
||||
function renderTableStatus (status){
|
||||
switch (status){
|
||||
// 重新构建
|
||||
function repeatSet(e,number) {
|
||||
e.stopPropagation();
|
||||
setTableLoading(true);
|
||||
const url = `/${owner}/${projectsId}/builds/${number}/restart.json`;
|
||||
axios.post(url).then((result) => {
|
||||
if (result) {
|
||||
props.showNotification("工作流正在重新构建!");
|
||||
Init();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
// 撤销构建
|
||||
function cancelSet(e,number) {
|
||||
e.stopPropagation();
|
||||
setTableLoading(true);
|
||||
const url = `/${owner}/${projectsId}/builds/${number}/stop.json`;
|
||||
axios.delete(url).then((result) => {
|
||||
if (result) {
|
||||
props.showNotification("撤销构建成功!");
|
||||
Init(projectsId);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
function renderTableStatus(status) {
|
||||
switch (status) {
|
||||
case "running":
|
||||
return(
|
||||
<span className="statusTag running"><i className="iconfont icon-yunhangzhong"></i>运行中</span>
|
||||
);
|
||||
case "failure":
|
||||
return (
|
||||
<span className="statusTag failed"><i className="iconfont icon-weitongguo"></i>未通过</span>
|
||||
<span className="statusTag running">
|
||||
<i className="iconfont icon-yunhangzhong"></i>运行中
|
||||
</span>
|
||||
);
|
||||
case "failure": case 'error':
|
||||
return (
|
||||
<span className="statusTag failed">
|
||||
<i className="iconfont icon-weitongguo"></i>未通过
|
||||
</span>
|
||||
);
|
||||
case "success":
|
||||
return (
|
||||
<span className="statusTag pass"><i className="iconfont icon-yitongguo"></i>已通过</span>
|
||||
<span className="statusTag pass">
|
||||
<i className="iconfont icon-yitongguo"></i>已通过
|
||||
</span>
|
||||
);
|
||||
default:
|
||||
case 'killed':
|
||||
return (
|
||||
<span className="statusTag Preparing"><i className="iconfont icon-zhunbeizhong"></i>准备中</span>
|
||||
<span className="statusTag killed">
|
||||
<i className="iconfont icon-weitongguo"></i>已撤销
|
||||
</span>
|
||||
);
|
||||
case 'pending':
|
||||
return (
|
||||
<span className="statusTag Preparing">
|
||||
<i className="iconfont icon-zhunbeizhong"></i>准备中
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function clickRows(event,e){
|
||||
props.history.push(`/projects/${owner}/${projectsId}/devops/${e.number}/detail`);
|
||||
}
|
||||
const column = [
|
||||
{
|
||||
title:'序号',
|
||||
dataIndex:"No",
|
||||
key:"No",
|
||||
width:"8%",
|
||||
render:(item,value,key)=>{
|
||||
return(
|
||||
<span>#{key+1}</span>
|
||||
)
|
||||
}
|
||||
title: "序号",
|
||||
dataIndex: "number",
|
||||
key: "number",
|
||||
width: "8%",
|
||||
render: ( value, item, key) => {
|
||||
return <span>#{value}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title:'状态',
|
||||
dataIndex:"status",
|
||||
key:"status",
|
||||
width:"12%",
|
||||
render:(value,item,key)=>{
|
||||
return(renderTableStatus(value))
|
||||
}
|
||||
title: "状态",
|
||||
dataIndex: "status",
|
||||
key: "status",
|
||||
width: "12%",
|
||||
render: (value, item, key) => {
|
||||
return renderTableStatus(value);
|
||||
},
|
||||
},
|
||||
{
|
||||
title:'构建人',
|
||||
dataIndex:"author",
|
||||
key:"author",
|
||||
width:"12%",
|
||||
align:"center"
|
||||
title: "构建人",
|
||||
dataIndex: "author",
|
||||
key: "author",
|
||||
width: "12%",
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title:'提交信息',
|
||||
dataIndex:"message",
|
||||
key:"message",
|
||||
width:"30%",
|
||||
render:(value,item,key)=>{
|
||||
title: "提交信息",
|
||||
dataIndex: "message",
|
||||
key: "message",
|
||||
width: "30%",
|
||||
render: (value, item, key) => {
|
||||
let meg = item.message;
|
||||
return (
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div>
|
||||
{ meg.branch && <span className="mr10 color-grey-8"><i className="iconfont icon-fenzhi1 font-16 mr5"></i>分支{meg.branch}</span>}
|
||||
{ meg.sha && <span className="color-orange">{meg.sha}</span>}
|
||||
{meg.branch && (
|
||||
<span className="mr10 color-grey-8">
|
||||
<i className="iconfont icon-fenzhi1 font-16 mr5"></i>分支
|
||||
{meg.branch}
|
||||
</span>
|
||||
)}
|
||||
{meg.sha && <span className="color-orange">{meg.sha}</span>}
|
||||
</div>
|
||||
<AlignCenter>
|
||||
<Img src={meg.image} />
|
||||
<div className="task-hide ml5" style={{maxWidth:"300px"}}>{meg.message}</div>
|
||||
<img style={{borderRadius:"50%",marginRight:"10px",width:"25px",height:"25px"}} src={`${current_user && getUrl(`/images/${current_user.image_url}`)}`} />
|
||||
<div className="task-hide ml5" style={{ maxWidth: "300px" }}>
|
||||
{meg.message}
|
||||
</div>
|
||||
</AlignCenter>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title:'开始时间',
|
||||
dataIndex:"started",
|
||||
key:"started",
|
||||
width:"15%",
|
||||
render:(value,item,key)=>{
|
||||
return (
|
||||
<span>{value || "--"}</span>
|
||||
)
|
||||
}
|
||||
title: "开始时间",
|
||||
dataIndex: "started",
|
||||
key: "started",
|
||||
width: "15%",
|
||||
render: (value, item, key) => {
|
||||
return <span>{value || "--"}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title:'运行时间',
|
||||
dataIndex:"timestamp",
|
||||
key:"timestamp",
|
||||
width:"15%",
|
||||
render:(value,item,key)=>{
|
||||
return (
|
||||
<span>{value || value === 0 ? `${value}s` : "--"}</span>
|
||||
)
|
||||
}
|
||||
title: "运行时间",
|
||||
dataIndex: "duration_time",
|
||||
key: "duration_time",
|
||||
width: "15%",
|
||||
render: (value, item, key) => {
|
||||
return <span>{value || "--"}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title:'操作',
|
||||
dataIndex:"operation",
|
||||
key:"operation",
|
||||
render:(value,item,key)=>{
|
||||
return(renderStatusBtn(item.status));
|
||||
}
|
||||
}
|
||||
]
|
||||
return(
|
||||
title: "操作",
|
||||
dataIndex: "operation",
|
||||
key: "operation",
|
||||
render: (value, item, key) => {
|
||||
if(permission === "Admin" || permission === "Owner"){
|
||||
return renderStatusBtn(item.status, item.number);
|
||||
}else{
|
||||
return "--";
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
return (
|
||||
<div className="listPart">
|
||||
<FlexAJ>
|
||||
{renderStatus()}
|
||||
<span>
|
||||
<Blueback className="mr30">手动创建</Blueback>
|
||||
<span className="mr30"><i className="iconfont icon-fenzhi1 font-16 mr5 color-blue"></i>分支</span>
|
||||
<span><i className="iconfont icon-biaoqian3 font-16 mr5 color-blue"></i>标签</span>
|
||||
</span>
|
||||
{/* <Blueback>手动创建</Blueback> */}
|
||||
{/* <span className="mr30">
|
||||
<i className="iconfont icon-fenzhi1 font-16 mr5 color-blue"></i>分支
|
||||
</span>
|
||||
<span>
|
||||
<i className="iconfont icon-biaoqian3 font-16 mr5 color-blue"></i>
|
||||
标签
|
||||
</span> */}
|
||||
</FlexAJ>
|
||||
<Table
|
||||
onRow={(record,index)=>{
|
||||
return{
|
||||
onClick:(event)=>clickRows(event,record)
|
||||
}
|
||||
}}
|
||||
columns={column}
|
||||
className="normalTable"
|
||||
dataSource={data}
|
||||
pagination={false}
|
||||
loading={tableLoading}
|
||||
></Table>
|
||||
{
|
||||
total > LIMIT ?
|
||||
<div style={{textAlign:'center',margin:"30px 50px"}}>
|
||||
<Pagination showQuickJumper defaultCurrent={page} total={total} pageSize={LIMIT} onChange={ChangePage}></Pagination>
|
||||
</div>:""
|
||||
}
|
||||
{total > LIMIT ?
|
||||
<div style={{ textAlign: "center", margin: "30px 50px" }}>
|
||||
<Pagination
|
||||
showQuickJumper
|
||||
defaultCurrent={page}
|
||||
total={total}
|
||||
pageSize={LIMIT}
|
||||
onChange={ChangePage}
|
||||
></Pagination>
|
||||
</div>
|
||||
:
|
||||
"" }
|
||||
</div>
|
||||
)
|
||||
})
|
||||
);
|
||||
};
|
||||
export default forwardRef(Structure);
|
||||
|
|
|
@ -12,8 +12,14 @@
|
|||
.disposePanel{
|
||||
.language{
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
li{
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
border:1px solid #fff;
|
||||
&.active{
|
||||
border:1px solid #5091FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
.editorBody{
|
||||
|
@ -36,6 +42,7 @@
|
|||
top:7px;
|
||||
}
|
||||
.listPart{
|
||||
min-height: 400px;
|
||||
.listNav{
|
||||
display: flex;
|
||||
li{
|
||||
|
@ -63,6 +70,7 @@
|
|||
.ant-table-thead > tr > th, .ant-table-tbody > tr > td{
|
||||
padding:10px 5px;
|
||||
color:#333;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ant-table-thead{
|
||||
border:1px solid rgba(238,238,238,1)
|
||||
|
@ -70,6 +78,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.ant-modal-close{
|
||||
top:7px;
|
||||
}
|
||||
// 列表
|
||||
.listPart{
|
||||
.statusTag{
|
||||
|
@ -103,8 +114,13 @@
|
|||
border:1px solid #F73030;
|
||||
color:#F73030 ;
|
||||
}
|
||||
&.killed{
|
||||
background:#eee;
|
||||
border:1px solid #999;
|
||||
color:#999 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -205,6 +221,14 @@
|
|||
border:1px solid rgba(255,110,33,1);
|
||||
color:rgba(255,110,33,1);
|
||||
}
|
||||
&.killed{
|
||||
border:1px solid #999;
|
||||
color:#999;
|
||||
}
|
||||
&.skipped{
|
||||
border:1px solid #d4d9de;
|
||||
color:#798390;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.rightSection{
|
||||
|
@ -212,6 +236,8 @@
|
|||
background-color: #081930;
|
||||
.rightMainContent{
|
||||
padding:24px 30px;
|
||||
height:100vh;
|
||||
overflow-y: auto;
|
||||
& > div{
|
||||
margin-bottom: 12px;
|
||||
.items{
|
||||
|
@ -264,4 +290,27 @@
|
|||
cursor: col-resize;
|
||||
}
|
||||
}
|
||||
}
|
||||
.opsDetailOut{
|
||||
display: flex;
|
||||
color: #fff;
|
||||
line-height: 22px;
|
||||
align-items: flex-start;
|
||||
margin-top: 5px;
|
||||
&>span{
|
||||
margin-right: 10px;
|
||||
min-width: 20px;
|
||||
text-align: left;
|
||||
padding-left: 3px;
|
||||
}
|
||||
&>p{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
.noOperation{
|
||||
margin-bottom:20px;
|
||||
width:380px;
|
||||
text-align:center;
|
||||
line-height:22px;
|
||||
color:#666;
|
||||
}
|
|
@ -1,33 +1,114 @@
|
|||
import React from 'react';
|
||||
import './ops.scss';
|
||||
import { FlexAJ, AlignCenter } from '../Component/layout';
|
||||
import { Tags } from '../Component/OpsStatus';
|
||||
import SplitPane from 'react-split-pane';
|
||||
import LeftPanel from './OpsDetailLeftpanel';
|
||||
import RightPanel from './OpsDetailRightpanel';
|
||||
import React, { useEffect, useState, useRef, useContext } from "react";
|
||||
import "./ops.scss";
|
||||
import { FlexAJ, AlignCenter } from "../Component/layout";
|
||||
import { Tags } from "../Component/OpsStatus";
|
||||
import SplitPane from "react-split-pane";
|
||||
import LeftPanel from "./OpsDetailLeftpanel";
|
||||
import RightPanel from "./OpsDetailRightpanel";
|
||||
import axios from "axios";
|
||||
import { Spin } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export default (props) => {
|
||||
const [data, setData] = useState(undefined);
|
||||
const [stageN, setStageN] = useState(undefined);
|
||||
const [stepN, setStepN] = useState(undefined);
|
||||
const [rightSpin, setRightSpin] = useState(false);
|
||||
const [spinning, setSpinning] = useState(true);
|
||||
|
||||
export default (()=>{
|
||||
return(
|
||||
<div className="opsDetailPanel">
|
||||
<FlexAJ className="opsInfos">
|
||||
<AlignCenter>
|
||||
<span>#1</span>
|
||||
<span className="ml10">将分支“221063-improve-buy-ci-minutes-link”合并到“221063-improve-buy-ci-minutes-link"</span>
|
||||
{Tags(1)}
|
||||
</AlignCenter>
|
||||
<a style={{color:"#ddd"}}><i className="iconfont icon-yiguanbi font-15 mr5"></i>退出</a>
|
||||
</FlexAJ>
|
||||
<div className="opsSection">
|
||||
<SplitPane className="outer-split-pane" split="vertical" minSize={468} maxSize={-350} defaultSize="40%">
|
||||
<section className="leftSection">
|
||||
<LeftPanel />
|
||||
</section>
|
||||
<section className="rightSection">
|
||||
<RightPanel />
|
||||
</section>
|
||||
</SplitPane>
|
||||
let projectId = props.match.params.projectId;
|
||||
let owner = props.match.params.owner;
|
||||
let opsId = props.match.params.opsId;
|
||||
|
||||
useEffect(() => {
|
||||
if (opsId && projectId) {
|
||||
Init();
|
||||
}
|
||||
}, [opsId]);
|
||||
|
||||
function Init() {
|
||||
const url = `/${owner}/${projectId}/builds/${opsId}.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
setSpinning(false);
|
||||
setData(result.data);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
setSpinning(false);
|
||||
});
|
||||
}
|
||||
|
||||
// 重新构建
|
||||
function repeatSet(e,type,number) {
|
||||
if(type==="repeat"){
|
||||
// 重新构建
|
||||
const url = `/${owner}/${projectId}/builds/${number}/restart.json`;
|
||||
axios.post(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
props.showNotification("工作流正在重新构建!");
|
||||
props.history.push(`/projects/${owner}/${projectId}/devops/${result.data.number}/detail`);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}else{
|
||||
// 撤销构建
|
||||
const url = `/${owner}/${projectId}/builds/${number}/stop.json`;
|
||||
axios.delete(url).then((result) => {
|
||||
if (result) {
|
||||
props.showNotification("撤销构建成功!");
|
||||
Init();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function chooseSteps(pre,sub){
|
||||
if(pre && sub){
|
||||
setStepN(sub);
|
||||
setStageN(pre);
|
||||
setRightSpin(true);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Spin spinning={spinning}>
|
||||
<div className="opsDetailPanel">
|
||||
<FlexAJ className="opsInfos">
|
||||
<AlignCenter>
|
||||
<span>#{data && data.number}</span>
|
||||
<span className="ml10">{data && data.message}</span>
|
||||
{Tags(`${data && data.status}`)}
|
||||
</AlignCenter>
|
||||
<Link
|
||||
style={{ color: "#ddd" }}
|
||||
to={`/projects/${owner}/${projectId}/devops/list`}
|
||||
>
|
||||
<i className="iconfont icon-yiguanbi font-15 mr5"></i>退出
|
||||
</Link>
|
||||
</FlexAJ>
|
||||
<div className="opsSection">
|
||||
<SplitPane
|
||||
className="outer-split-pane"
|
||||
split="vertical"
|
||||
minSize={468}
|
||||
maxSize={-350}
|
||||
defaultSize="40%"
|
||||
>
|
||||
<section className="leftSection">
|
||||
<LeftPanel data={data} repeatSet={repeatSet} chooseSteps={chooseSteps} />
|
||||
</section>
|
||||
<section className="rightSection">
|
||||
<RightPanel data={data} rightSpin={rightSpin} stepN={stepN} stageN={stageN} owner={owner} projectId={projectId} opsId={opsId} />
|
||||
</section>
|
||||
</SplitPane>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
});
|
||||
</Spin>
|
||||
);
|
||||
};
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
|
@ -50,7 +50,6 @@ class Index extends Component {
|
|||
)}
|
||||
></Route>
|
||||
<Route
|
||||
exact
|
||||
path="/projects"
|
||||
render={(props) => (
|
||||
<ProjectIndex {...this.props} {...props} />
|
||||
|
|
|
@ -32,9 +32,9 @@ export default ((props)=>{
|
|||
return(
|
||||
<li key={key}>
|
||||
<div>
|
||||
<Link to={`/projects/${owner}/${projectsId}?branch=${item.name}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/branch/${item.name}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
|
||||
<p className="f-wrap-alignCenter mt15">
|
||||
<span className="mr5 commitKey" style={{marginLeft:0}}>{item.last_commit && truncateCommitId(item.last_commit.sha)}</span>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.last_commit.sha}`)}`} className="mr5 commitKey" style={{marginLeft:0}}>{item.last_commit && truncateCommitId(item.last_commit.sha)}</Link>
|
||||
<span className="color-grey-3 hide-1 messages leftPoint">{item.last_commit && item.last_commit.message}</span>
|
||||
<span className="color-grey-8 ml30">最后更新于{item.last_commit && item.last_commit.time_from_now}</span>
|
||||
</p>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Spin , Pagination } from 'antd';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import { truncateCommitId } from '../common/util'
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import SelectBranch from '../Branch/Select';
|
||||
import Nodata from '../Nodata';
|
||||
import { getBranch } from '../GetData/getData';
|
||||
|
||||
import axios from 'axios';
|
||||
import {Link} from "react-router-dom";
|
||||
|
@ -12,21 +13,44 @@ class CoderRootCommit extends Component{
|
|||
constructor(props){
|
||||
super(props)
|
||||
this.state={
|
||||
branch:"master",
|
||||
commitDatas:undefined,
|
||||
dataCount:undefined,
|
||||
limit:20,
|
||||
page:1,
|
||||
isSpining:false
|
||||
isSpining:false,
|
||||
branchList:undefined
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
const { branch , page , limit } = this.state;
|
||||
this.Init();
|
||||
this.getBranchs();
|
||||
}
|
||||
|
||||
// 获取分支列表
|
||||
getBranchs=()=>{
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
axios.get(`/${owner}/${projectsId}/branches.json`).then(result=>{
|
||||
this.setState({
|
||||
branchList:result.data
|
||||
})
|
||||
}).catch((error)=>{})
|
||||
}
|
||||
|
||||
componentDidUpdate=(prevProps)=>{
|
||||
const { location } = this.props;
|
||||
const prevlocation = prevProps && prevProps.location;
|
||||
if (location !== prevlocation) {
|
||||
this.Init();
|
||||
}
|
||||
}
|
||||
Init =()=>{
|
||||
const { branchName } = this.props.match.params;
|
||||
const { page , limit } = this.state;
|
||||
this.setState({
|
||||
isSpining:true
|
||||
})
|
||||
this.getCommitList( branch , page , limit );
|
||||
this.getCommitList( branchName , page , limit );
|
||||
}
|
||||
|
||||
getCommitList=(branch , page , limit)=>{
|
||||
|
@ -68,26 +92,20 @@ class CoderRootCommit extends Component{
|
|||
|
||||
// 切换分支 search:tag为根据标签搜索
|
||||
changeBranch=(value)=>{
|
||||
const { page , limit } = this.state;
|
||||
const { getTopCount } = this.props;
|
||||
this.setState({
|
||||
isSpining:true,
|
||||
branch:value,
|
||||
})
|
||||
this.getCommitList(value , page , limit);
|
||||
getTopCount && getTopCount(value);
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/commits/branch/${value}`);
|
||||
}
|
||||
|
||||
ChangePage=(page)=>{
|
||||
|
||||
const { branch , limit } = this.state;
|
||||
this.getCommitList(branch , page , limit);
|
||||
const { branchName } = this.props.match.params;
|
||||
const { limit } = this.state;
|
||||
this.getCommitList(branchName , page , limit);
|
||||
}
|
||||
render(){
|
||||
const { branch , commitDatas , dataCount , limit , page , isSpining } = this.state;
|
||||
const { branchs , projectDetail, commit_class } = this.props;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
|
||||
const { commitDatas , dataCount , limit , page , isSpining , branchList } = this.state;
|
||||
const { projectDetail, commit_class , defaultBranch } = this.props;
|
||||
const { projectsId , owner , branchName } = this.props.match.params;
|
||||
let branch = branchName || defaultBranch;
|
||||
return(
|
||||
<React.Fragment>
|
||||
<div className={commit_class}>
|
||||
|
@ -98,6 +116,8 @@ class CoderRootCommit extends Component{
|
|||
branch={branch}
|
||||
changeBranch={this.changeBranch}
|
||||
owner={owner}
|
||||
history={this.props.history}
|
||||
branchList={branchList}
|
||||
></SelectBranch>
|
||||
</div>
|
||||
<Spin spinning={isSpining}>
|
||||
|
@ -113,13 +133,13 @@ class CoderRootCommit extends Component{
|
|||
return(
|
||||
<div key={k}>
|
||||
<p className="f-wrap-alignCenter">
|
||||
<span className="commitKey" style={{marginLeft:0}}>{truncateCommitId(`${item.sha}`)}</span>
|
||||
<span className="flex1 ml20 font-16 color-grey-3">{item.message}</span>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="commitKey" style={{marginLeft:0}}>{truncateCommitId(`${item.sha}`)}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="flex1 ml20 font-16 color-grey-3">{item.message}</Link>
|
||||
</p>
|
||||
<p className="f-wrap-alignCenter mt15">
|
||||
<Link to={`/users/${item.login}`} className="show-user-link">
|
||||
{item.image_url?<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr15 radius"/>:""}
|
||||
<label className="font-14 color-grey-6" style={{'verticalAlign':'middle'}}>{item.name ?`${item.name}:`:""}提交于 {item.time_from_now}</label>
|
||||
<label className="font-14 color-grey-6" style={{verticalAlign:'middle'}}>{item.name ?`${item.name}:`:""}提交于 {item.time_from_now}</label>
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { Component } from "react";
|
||||
import { Menu, Spin, Button } from "antd";
|
||||
import { Menu, Spin } from "antd";
|
||||
import { getImageUrl } from "educoder";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
|
@ -10,16 +10,16 @@ import RootTable from './RootTable';
|
|||
import CoderRootFileDetail from './CoderRootFileDetail';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import RenderHtml from '../../components/render-html';
|
||||
import Nodata from '../Nodata';
|
||||
import { getBranch } from '../GetData/getData';
|
||||
|
||||
import axios from "axios";
|
||||
/**
|
||||
* address:http和SSH,http_url(对应git地址)
|
||||
* branch:当前分支
|
||||
* filePath:点击目录时当前目录的路径
|
||||
* subfileType:保存当前点击目录的文件类型(显示目录列表时才显示新建文件,如果点击的是文件就不显示新建文件按钮)
|
||||
* readMeContent:根目录下面的readme文件内容
|
||||
*/
|
||||
|
||||
function getPathUrl(array,index){
|
||||
if(array && array.length>0 && index){
|
||||
let str = "";
|
||||
|
@ -29,13 +29,11 @@ function getPathUrl(array,index){
|
|||
return str.substr(1);
|
||||
}
|
||||
}
|
||||
|
||||
class CoderRootDirectory extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
address: "http",
|
||||
branch: "master",
|
||||
filePath: undefined,
|
||||
subFileType: undefined,
|
||||
readMeContent: undefined,
|
||||
|
@ -65,7 +63,17 @@ class CoderRootDirectory extends Component {
|
|||
|
||||
componentDidMount = () => {
|
||||
this.Init();
|
||||
this.getBranchs();
|
||||
};
|
||||
// 获取分支列表
|
||||
getBranchs=()=>{
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
axios.get(`/${owner}/${projectsId}/branches.json`).then(result=>{
|
||||
this.setState({
|
||||
branchList:result.data
|
||||
})
|
||||
}).catch((error)=>{})
|
||||
}
|
||||
|
||||
componentDidUpdate = (prevState) => {
|
||||
const { location } = this.props;
|
||||
|
@ -80,32 +88,27 @@ class CoderRootDirectory extends Component {
|
|||
|
||||
Init = () => {
|
||||
let { search } = this.props.history.location;
|
||||
let branchName = undefined;
|
||||
if (search && search.indexOf("?branch=") > -1) {
|
||||
branchName = search.split("?branch=")[1];
|
||||
this.setState({
|
||||
branch: branchName,
|
||||
});
|
||||
}
|
||||
if (search && search.indexOf("?url=") > -1) {
|
||||
let url = search.split("?url=")[1];
|
||||
this.setState({
|
||||
filePath: url,
|
||||
});
|
||||
this.getFileDetail(url);
|
||||
const { branchName } = this.props.match.params;
|
||||
const { defaultBranch } = this.props;
|
||||
let branch = branchName || defaultBranch;
|
||||
if (search && (search.indexOf("?url=") > -1 || search.indexOf("&url=") > -1)) {
|
||||
let url = search.split("url=")[1];
|
||||
if(url && decodeURI(url).indexOf("&")){
|
||||
url=decodeURI(url).split("&")[0];
|
||||
}
|
||||
this.getFileDetail(decodeURI(url),branch);
|
||||
} else {
|
||||
const { branch } = this.state;
|
||||
this.getProjectRoot(branchName || branch);
|
||||
this.getProjectRoot(branch);
|
||||
}
|
||||
};
|
||||
|
||||
// 页面地址返回到主目录
|
||||
returnMain = (branch) => {
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { projectsId , owner , branchName } = this.props.match.params;
|
||||
this.setState({
|
||||
readOnly:true
|
||||
})
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/coders`);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}${branchName?`/branch/${branchName}`:""}`);
|
||||
this.getProjectRoot(branch);
|
||||
};
|
||||
|
||||
|
@ -142,7 +145,7 @@ class CoderRootDirectory extends Component {
|
|||
ChangeFile = (arr, readOnly) => {
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
//点击直接跳转页面 加载一次路由
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/coders?url=${arr.path}`);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}?url=${arr.path}`);
|
||||
this.setState({
|
||||
readOnly: readOnly,
|
||||
chooseType:"file"
|
||||
|
@ -162,19 +165,12 @@ class CoderRootDirectory extends Component {
|
|||
index: k,
|
||||
name: i,
|
||||
path: str.substr(1),
|
||||
type:
|
||||
filePath && filePath.length > 0
|
||||
? filePath[k]
|
||||
? filePath[k].type
|
||||
: type
|
||||
: type,
|
||||
type: filePath && filePath.length > 0 ? filePath[k] ? filePath[k].type : type : type,
|
||||
});
|
||||
});
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
//点击直接跳转页面 加载一次路由
|
||||
this.props.history.push(
|
||||
`/projects/${owner}/${projectsId}/coders?url=${str.substr(1)}`
|
||||
);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}?url=${str.substr(1)}`);
|
||||
} else {
|
||||
list.push({
|
||||
index: 0,
|
||||
|
@ -190,60 +186,74 @@ class CoderRootDirectory extends Component {
|
|||
|
||||
// 获取子目录
|
||||
getFileDetail = (path, ref) => {
|
||||
const { projectsId ,owner } = this.props.match.params;
|
||||
const { branch } = this.state;
|
||||
this.setState({
|
||||
filePath: decodeURI(path),
|
||||
});
|
||||
const { projectsId , owner , branchName } = this.props.match.params;
|
||||
const { chooseType } = this.state;
|
||||
const url = `/${owner}/${projectsId}/sub_entries.json`;
|
||||
|
||||
axios.get(url,{
|
||||
params:{
|
||||
filepath:path,
|
||||
ref:ref || branch
|
||||
ref:ref || branchName,
|
||||
type:chooseType
|
||||
}
|
||||
}).then((result)=>{
|
||||
let entries = result.data && result.data.entries
|
||||
if( entries && entries.length > 0){
|
||||
let { chooseType } = this.state;
|
||||
// 当前返回的子目录只有一条数据,且这条数据返回的是文件类型
|
||||
if(entries.length === 1 && entries[0].type === "file" && chooseType ==="file"){
|
||||
let entries = result.data && result.data.entries;
|
||||
this.setState({
|
||||
isSpin:false
|
||||
})
|
||||
if(result){
|
||||
if(entries){
|
||||
// 返回对象entries.type则是文件类型,否则是文件夹
|
||||
if(entries.type){
|
||||
this.setState({
|
||||
fileDetail:[entries],
|
||||
rootList:undefined,
|
||||
subFileType:false
|
||||
})
|
||||
}else{
|
||||
this.setState({
|
||||
fileDetail:undefined,
|
||||
rootList:entries,
|
||||
branchLastCommit:result.data.last_commit && result.data.last_commit.commit,
|
||||
lastCommitAuthor:result.data.last_commit && (result.data.last_commit.author || (result.data.last_commit.commit && result.data.last_commit.commit.author))
|
||||
})
|
||||
this.renderData(entries);
|
||||
}
|
||||
}else{
|
||||
this.setState({
|
||||
fileDetail:entries,
|
||||
fileDetail:undefined,
|
||||
rootList:undefined,
|
||||
isSpin:false,
|
||||
subFileType:false
|
||||
})
|
||||
}else{
|
||||
this.setState({
|
||||
fileDetail:undefined,
|
||||
rootList:entries,
|
||||
isSpin:false,
|
||||
branchLastCommit:result.data.last_commit && result.data.last_commit.commit,
|
||||
lastCommitAuthor:result.data.last_commit && (result.data.last_commit.author || (result.data.last_commit.commit && result.data.last_commit.commit.author))
|
||||
})
|
||||
this.renderData(entries);
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
isSpin:false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
renderData = (data) => {
|
||||
const rootList = [];
|
||||
const readMeContent = [];
|
||||
const readMeFile = [];
|
||||
data &&
|
||||
data.map((item, key) => {
|
||||
rootList.push({
|
||||
key,
|
||||
message: item.commit && item.commit.message,
|
||||
...item,
|
||||
});
|
||||
if (item.is_readme_file) {
|
||||
readMeContent.push({ ...item });
|
||||
readMeFile.push({ ...item });
|
||||
}
|
||||
data && data.map((item, key) => {
|
||||
rootList.push({
|
||||
key,
|
||||
message: item.commit && item.commit.message,
|
||||
...item,
|
||||
});
|
||||
if (item.is_readme_file) {
|
||||
readMeContent.push({ ...item });
|
||||
readMeFile.push({ ...item });
|
||||
}
|
||||
});
|
||||
this.setState({
|
||||
rootList: rootList,
|
||||
readMeContent,
|
||||
|
@ -256,8 +266,8 @@ class CoderRootDirectory extends Component {
|
|||
this.setState({
|
||||
chooseType:type
|
||||
})
|
||||
const { projectsId, owner } = this.props.match.params;
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/coders?url=${path}`);
|
||||
const { projectsId, owner , branchName } = this.props.match.params;
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}${branchName?`/branch/${branchName}`:""}?url=${path}`);
|
||||
if(filename.substring(filename.length - 3) === ".md"){
|
||||
this.setState({
|
||||
md:true
|
||||
|
@ -285,26 +295,23 @@ class CoderRootDirectory extends Component {
|
|||
<span className="commonBox-title-read">
|
||||
{readMeContent[0].name}
|
||||
</span>
|
||||
{permission ? (
|
||||
{permission ?
|
||||
<a
|
||||
onClick={() => this.ChangeFile(readMeFile[0], false)}
|
||||
className="ml20 pull-right"
|
||||
>
|
||||
<i className="iconfont icon-bianji6 font-16 color-blue"></i>
|
||||
</a>
|
||||
) : (
|
||||
:
|
||||
""
|
||||
)}
|
||||
}
|
||||
</div>
|
||||
<div className="commonBox-info">
|
||||
{readMeContent[0].content ? (
|
||||
<RenderHtml
|
||||
className="break_word_comments imageLayerParent"
|
||||
value={readMeContent[0].content}
|
||||
/>
|
||||
) : (
|
||||
{readMeContent[0].content ?
|
||||
<RenderHtml className="break_word_comments imageLayerParent" value={readMeContent[0].content} url={this.props.history.location}/>
|
||||
:
|
||||
<span>暂无~</span>
|
||||
)}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -313,24 +320,18 @@ class CoderRootDirectory extends Component {
|
|||
|
||||
// 选择分支
|
||||
changeBranch = (value) => {
|
||||
this.setState({
|
||||
branch: value,
|
||||
isSpin: true,
|
||||
readOnly:true
|
||||
});
|
||||
const { getTopCount } = this.props;
|
||||
getTopCount && getTopCount(value);
|
||||
|
||||
let { search } = this.props.history.location;
|
||||
if (search && search.indexOf("?url=") > -1) {
|
||||
let url = search.split("?url=")[1];
|
||||
this.setState({
|
||||
filePath: url,
|
||||
});
|
||||
this.getFileDetail(url, value);
|
||||
} else {
|
||||
this.getProjectRoot(value);
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
|
||||
let url = `/projects/${owner}/${projectsId}${value && `/branch/${value}`}`;
|
||||
if (search && (search.indexOf("?url=") > -1 || search.indexOf("&url=") > -1)) {
|
||||
let u = search.split("url=")[1];
|
||||
if(u && decodeURI(u).indexOf("&")){
|
||||
u=decodeURI(u).split("&")[0];
|
||||
}
|
||||
url += `?url=${u}`;
|
||||
}
|
||||
this.props.history.push(url);
|
||||
}
|
||||
|
||||
// 子目录路径返回链接
|
||||
|
@ -340,7 +341,7 @@ class CoderRootDirectory extends Component {
|
|||
readOnly:true
|
||||
})
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/coders?url=${url}`);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}?url=${url}`);
|
||||
}
|
||||
|
||||
onEdit=(readOnly)=>{
|
||||
|
@ -368,6 +369,7 @@ class CoderRootDirectory extends Component {
|
|||
|
||||
title = (branchLastCommit,lastCommitAuthor) => {
|
||||
if (branchLastCommit) {
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
return (
|
||||
<div className="f-wrap-alignCenter">
|
||||
{lastCommitAuthor ? (
|
||||
|
@ -393,13 +395,13 @@ class CoderRootDirectory extends Component {
|
|||
) : (
|
||||
""
|
||||
)}
|
||||
<span className="color-blue flex-1 hide-1">
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${branchLastCommit.sha}`)}`} className="color-blue flex-1 hide-1">
|
||||
{branchLastCommit.message}
|
||||
</span>
|
||||
</Link>
|
||||
<span>{branchLastCommit.time_from_now}</span>
|
||||
<span className="commitKey">
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${branchLastCommit.sha}`)}`} className="commitKey">
|
||||
{truncateCommitId(branchLastCommit.sha)}
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}else{
|
||||
|
@ -407,33 +409,37 @@ class CoderRootDirectory extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
render(){
|
||||
const { branchLastCommit , lastCommitAuthor , rootList , branch ,filePath , fileDetail , subFileType , readMeContent, isSpin , zip_url , tar_url} = this.state;
|
||||
const { isManager , isDeveloper , projectDetail } = this.props;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { branchLastCommit , lastCommitAuthor , rootList ,filePath , fileDetail , subFileType , readMeContent, isSpin , zip_url , tar_url , branchList} = this.state;
|
||||
const { isManager , isDeveloper , projectDetail , platform , defaultBranch } = this.props;
|
||||
|
||||
const { projectsId , owner , branchName } = this.props.match.params;
|
||||
let branch = branchName || defaultBranch;
|
||||
const columns = [
|
||||
{
|
||||
key:"name",
|
||||
dataIndex: 'name',
|
||||
width:"30%",
|
||||
render: (text,item) => (
|
||||
<a onClick={()=>this.goToSubRoot(item.path,item.type,text)} className="ml12 task-hide" style={{ display: "block", maxWidth: "345px" }}>
|
||||
<i className={ item.type === "file" ? "iconfont icon-wenjia font-15 color-green-file mr5":"iconfont icon-wenjianjia1 color-green-file font-15 mr5"}></i>{text}
|
||||
<i className={ item.type === "file" ? "iconfont icon-wenjia font-15 color-green-file mr5" : "iconfont icon-wenjianjia1 color-green-file font-15 mr5"}></i>{text}
|
||||
</a>
|
||||
),
|
||||
},
|
||||
{
|
||||
dataIndex: "commit",
|
||||
key:"message",
|
||||
dataIndex: "message",
|
||||
width: "60%",
|
||||
render: (text, item) =>
|
||||
item.commit && item.commit.message ?
|
||||
<span className="task-hide" style={{ display: "block", maxWidth: "670px" }} >
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.commit.sha}`)}`} title={item.commit.message} className="task-hide" style={{ display: "block", maxWidth: "670px" }} >
|
||||
{item.commit.message}
|
||||
</span>
|
||||
</Link>
|
||||
: ""
|
||||
},
|
||||
{
|
||||
dataIndex: "commit",
|
||||
key:"time_from_now",
|
||||
dataIndex: "time_from_now",
|
||||
width: "10%",
|
||||
className: "edu-txt-right",
|
||||
render: (text, item) =>
|
||||
|
@ -452,13 +458,21 @@ class CoderRootDirectory extends Component {
|
|||
<div className="main">
|
||||
<div className="f-wrap-between mb20">
|
||||
<div className="f-wrap-alignCenter">
|
||||
<SelectBranch
|
||||
repo_id={projectDetail && projectDetail.repo_id}
|
||||
projectsId={projectsId}
|
||||
branch={branch}
|
||||
changeBranch={this.changeBranch}
|
||||
owner={owner}
|
||||
></SelectBranch>
|
||||
{
|
||||
platform ?
|
||||
<SelectBranch
|
||||
repo_id={projectDetail && projectDetail.repo_id}
|
||||
projectsId={projectsId}
|
||||
branch={branch}
|
||||
changeBranch={this.changeBranch}
|
||||
owner={owner}
|
||||
history={this.props.history}
|
||||
branchList={branchList}
|
||||
></SelectBranch>
|
||||
:
|
||||
<span>分支:<span className="color-grey-6">master</span></span>
|
||||
}
|
||||
|
||||
|
||||
{filePath && (
|
||||
<span className="ml20 font-16">
|
||||
|
@ -468,7 +482,8 @@ class CoderRootDirectory extends Component {
|
|||
>
|
||||
{projectDetail && projectDetail.identifier}
|
||||
</a>
|
||||
{ array && array.map((item, key) => {
|
||||
{array &&
|
||||
array.map((item, key) => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{
|
||||
|
@ -484,7 +499,7 @@ class CoderRootDirectory extends Component {
|
|||
)}
|
||||
</div>
|
||||
<div className="f-wrap-alignCenter">
|
||||
{subFileType && (projectDetail && parseInt(projectDetail.type)) !== 2 && (isManager || isDeveloper) && (
|
||||
{subFileType && (projectDetail && parseInt(projectDetail.type)) !== 2 && (isManager || isDeveloper) && platform && (
|
||||
<div>
|
||||
<span>
|
||||
<Link to={`/projects/${owner}/${projectsId}/${branch}/uploadfile${urlRoot}`} >
|
||||
|
@ -525,10 +540,13 @@ class CoderRootDirectory extends Component {
|
|||
{...this.state}
|
||||
readOnly={this.state.readOnly}
|
||||
onEdit={this.onEdit}
|
||||
currentBranch={branch}
|
||||
></CoderRootFileDetail>
|
||||
)}
|
||||
{/* readme.txt (isManager || isDeveloper)*/}
|
||||
{this.renderReadMeContent(readMeContent, isManager || isDeveloper)}
|
||||
{
|
||||
!rootList && !fileDetail && <Nodata _html="暂未发现当前文件!"/>
|
||||
}
|
||||
{ rootList && this.renderReadMeContent(readMeContent, isManager || isDeveloper)}
|
||||
</div>
|
||||
</Spin>
|
||||
);
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import React, { Component } from "react";
|
||||
import { Popconfirm, Select } from "antd";
|
||||
import { Popconfirm , Select } from "antd";
|
||||
import "./list.css";
|
||||
import axios from "axios";
|
||||
import Meditor from "../Newfile/m_editor";
|
||||
import MDEditor from "../../modules/tpm/challengesnew/tpm-md-editor";
|
||||
import RenderHtml from "../../components/render-html";
|
||||
|
||||
|
||||
function bytesToSize(bytes) {
|
||||
if (bytes === 0) return "0 B";
|
||||
let k = 1024,
|
||||
|
@ -21,7 +19,7 @@ class CoderRootFileDetail extends Component {
|
|||
value: undefined,
|
||||
language: undefined,
|
||||
languages: undefined,
|
||||
description:props.detail.content
|
||||
description: props.detail.content
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -95,8 +93,10 @@ class CoderRootFileDetail extends Component {
|
|||
default_language = item;
|
||||
}
|
||||
}
|
||||
this.state.languages = languages;
|
||||
this.state.language = default_language;
|
||||
this.setState({
|
||||
languages,
|
||||
language: default_language
|
||||
})
|
||||
};
|
||||
|
||||
select_language = (e) => {
|
||||
|
@ -107,11 +107,13 @@ class CoderRootFileDetail extends Component {
|
|||
EditFile = (flag) => {
|
||||
const { onEdit } = this.props;
|
||||
onEdit && onEdit(flag);
|
||||
// this.setState({
|
||||
// readOnly: false,
|
||||
// });
|
||||
};
|
||||
|
||||
DownLoadFile = (url) => {
|
||||
let download_url = "/attachments/entries/get_file?download_url=" + url
|
||||
window.open(download_url)
|
||||
}
|
||||
|
||||
// 编辑文件
|
||||
|
||||
changeMmirror = (e, e1, value) => {
|
||||
|
@ -122,17 +124,16 @@ class CoderRootFileDetail extends Component {
|
|||
|
||||
deleteFile = () => {
|
||||
const { branch, detail } = this.props;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { projectsId, owner } = this.props.match.params;
|
||||
|
||||
const url = `/${owner}/${projectsId}/delete_file.json`;
|
||||
axios
|
||||
.delete(url, {
|
||||
params: {
|
||||
filepath: detail.path,
|
||||
branch,
|
||||
sha: detail.sha,
|
||||
},
|
||||
})
|
||||
axios.delete(url, {
|
||||
params: {
|
||||
filepath: detail.path,
|
||||
branch,
|
||||
sha: detail.sha,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.props.showNotification("删除成功!");
|
||||
|
@ -163,12 +164,13 @@ class CoderRootFileDetail extends Component {
|
|||
current_user,
|
||||
isManager,
|
||||
isDeveloper,
|
||||
md
|
||||
md,
|
||||
currentBranch,
|
||||
platform
|
||||
} = this.props;
|
||||
const { language, languages , description } = this.state;
|
||||
const { language, languages, description } = this.state;
|
||||
let flag = current_user && current_user.login && (isManager || isDeveloper);
|
||||
const Option = Select.Option;
|
||||
|
||||
return (
|
||||
<div className="mb20">
|
||||
<div className="grid-item branchTitle">
|
||||
|
@ -178,40 +180,52 @@ class CoderRootFileDetail extends Component {
|
|||
</span>
|
||||
</div>
|
||||
<p className="text-right">
|
||||
{flag && (
|
||||
{flag && platform && (
|
||||
<div>
|
||||
{readOnly ? (
|
||||
<a onClick={() => this.EditFile(false)} className="ml20">
|
||||
<i className="iconfont icon-bianji1 font-15 color-grey-6"></i>
|
||||
</a>
|
||||
<span>
|
||||
{
|
||||
detail.direct_download ?
|
||||
""
|
||||
:
|
||||
<span>
|
||||
<a onClick={() => this.DownLoadFile(detail.download_url)} className="ml20">
|
||||
<i className="iconfont icon-xiazai1 font-15 color-grey-6"></i>
|
||||
</a>
|
||||
<a onClick={() => this.EditFile(false)} className="ml20">
|
||||
<i className="iconfont icon-bianji1 font-15 color-grey-6"></i>
|
||||
</a>
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<Select
|
||||
showSearch={true}
|
||||
placeholder={"请选择文本语言"}
|
||||
style={{ width: 200 }}
|
||||
value={language}
|
||||
onChange={this.select_language}
|
||||
>
|
||||
<Option value={undefined}>请选择文本语言</Option>
|
||||
{languages &&
|
||||
languages.map((item, key) => {
|
||||
return (
|
||||
<Option value={item} key={key}>
|
||||
{item}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
<button
|
||||
type="button"
|
||||
className="ant-btn ant-btn-sm ml20"
|
||||
onClick={() => this.EditFile(true)}
|
||||
>
|
||||
<span>取 消</span>
|
||||
</button>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<React.Fragment>
|
||||
<Select
|
||||
showSearch={true}
|
||||
placeholder={"请选择文本语言"}
|
||||
style={{ width: 200 }}
|
||||
value={language}
|
||||
onChange={this.select_language}
|
||||
>
|
||||
<Option value={undefined}>请选择文本语言</Option>
|
||||
{languages &&
|
||||
languages.map((item, key) => {
|
||||
return (
|
||||
<Option value={item} key={key}>
|
||||
{item}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
<button
|
||||
type="button"
|
||||
className="ant-btn ant-btn-sm ml20"
|
||||
onClick={() => this.EditFile(true)}
|
||||
>
|
||||
<span>取 消</span>
|
||||
</button>
|
||||
</React.Fragment>
|
||||
)}
|
||||
|
||||
<Popconfirm
|
||||
title="确认删除这个文件?"
|
||||
|
@ -245,20 +259,21 @@ class CoderRootFileDetail extends Component {
|
|||
</div>
|
||||
) : (
|
||||
md && readOnly ?
|
||||
<div className="files-md">
|
||||
<RenderHtml className="file-md imageLayerParent" value={description} />
|
||||
</div>
|
||||
:
|
||||
<Meditor
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
language={language ? language : "javascript"}
|
||||
filepath={`/${detail.path}`}
|
||||
content={detail.content}
|
||||
readOnly={readOnly}
|
||||
editorType="update"
|
||||
></Meditor>
|
||||
)}
|
||||
<div className="files-md">
|
||||
<RenderHtml className="file-md imageLayerParent" value={description} url={this.props.history.location}/>
|
||||
</div>
|
||||
:
|
||||
<Meditor
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
language={language ? language : "javascript"}
|
||||
filepath={`/${detail.path}`}
|
||||
content={detail.content}
|
||||
readOnly={readOnly}
|
||||
editorType="update"
|
||||
currentBranch={currentBranch}
|
||||
></Meditor>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -55,12 +55,20 @@ class CoderRootIndex extends Component{
|
|||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
let { search } = this.props.history.location;
|
||||
let branchName = undefined;
|
||||
if (search && search.indexOf("?branch=") > -1) {
|
||||
branchName = search.split("?branch=")[1];
|
||||
this.Init();
|
||||
}
|
||||
componentDidUpdate=(prevProps)=>{
|
||||
const { location } = this.props;
|
||||
const prevlocation = prevProps && prevProps.location;
|
||||
if (location !== prevlocation) {
|
||||
this.Init();
|
||||
}
|
||||
this.getTopCount(branchName);
|
||||
}
|
||||
|
||||
Init=()=>{
|
||||
const { branchName } = this.props.match.params;
|
||||
const { defaultBranch } = this.props;
|
||||
this.getTopCount(branchName || defaultBranch);
|
||||
}
|
||||
|
||||
getTopCount=(branch)=>{
|
||||
|
@ -97,17 +105,23 @@ class CoderRootIndex extends Component{
|
|||
(props) => (<FileNew {...this.props} {...props} {...this.state} getTopCount={this.getTopCount} />)
|
||||
}
|
||||
></Route>
|
||||
|
||||
{/* diff */}
|
||||
<Route path="/projects/:owner/:projectsId/commits/branch/:branchName"
|
||||
render={
|
||||
(props) => (<CoderRootCommit {...this.props} {...props} {...this.state} commit_class="main" getTopCount={this.getTopCount} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:owner/:projectsId/commits/:sha"
|
||||
render={
|
||||
(props) => (<Diff {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:owner/:projectsId/commits"
|
||||
render={
|
||||
() => (<CoderRootCommit {...this.props} {...this.state} commit_class="main" getTopCount={this.getTopCount} />)
|
||||
}
|
||||
></Route>
|
||||
{/* diff */}
|
||||
<Route path="/projects/:owner/:projectsId/diff/:sha"
|
||||
render={
|
||||
() => (<Diff {...this.props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
<Route path="/projects/:owner/:projectsId/releases/:versionId/update"
|
||||
render={
|
||||
|
@ -125,12 +139,18 @@ class CoderRootIndex extends Component{
|
|||
() => (<CoderRootVersion {...this.props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
|
||||
<Route path="/projects/:owner/:projectsId/tag"
|
||||
render={
|
||||
() => (<CoderRootTag {...this.props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:owner/:projectsId/branch"
|
||||
<Route path="/projects/:owner/:projectsId/branch/:branchName"
|
||||
render={
|
||||
(props) => (<CoderRootDirectory {...this.props} {...this.state} getTopCount={this.getTopCount} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:owner/:projectsId/branchs"
|
||||
render={
|
||||
() => (<CoderRootBranch {...this.props} {...this.state} />)
|
||||
}
|
||||
|
|
|
@ -3,13 +3,12 @@ import axios from 'axios';
|
|||
import { Spin } from 'antd';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import Nodata from '../Nodata';
|
||||
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
export default (( props, { projectDetail }) => {
|
||||
const [isSpin, setSpin] = useState(true);
|
||||
const [data, setData] = useState(undefined);
|
||||
|
||||
const repo_id = projectDetail && projectDetail.repo_id;
|
||||
const { projectsId , owner } = props.match.params;
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -49,7 +48,7 @@ export default (( props, { projectDetail }) => {
|
|||
<span className="font-16">{item.name}</span>
|
||||
</span>
|
||||
<span className="ul_tbody_third">
|
||||
<span className="commitKey" style={{ "marginLeft": 0 }}>{truncateCommitId(`${item.id}`)}</span>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.id}`)}`} className="commitKey" style={{ "marginLeft": 0 }}>{truncateCommitId(`${item.id}`)}</Link>
|
||||
</span>
|
||||
<span className="ul_tbody_forth">
|
||||
<a href={item.tarball_url} style={{ color: "#4CC1DA" }} className="mr30"><i className="iconfont icon-TAR font-18 mr5"></i>TAR</a>
|
||||
|
|
|
@ -4,23 +4,13 @@ import { Link, Route, Switch } from 'react-router-dom';
|
|||
import { Content } from '../Component/layout';
|
||||
import '../css/index.scss'
|
||||
import './list.css';
|
||||
import SpecialModal from './SpecialModal';
|
||||
|
||||
import Loadable from 'react-loadable';
|
||||
import Loading from '../../Loading';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
import img_1 from '../Images/1.png';
|
||||
import img_2 from '../Images/2.png';
|
||||
import img_3 from '../Images/3.png';
|
||||
import img_6 from '../Images/6.png';
|
||||
import img_7 from '../Images/7.png';
|
||||
import img_parise from '../Images/parise.png';
|
||||
import img_focus from '../Images/focus.png';
|
||||
import img_parised from '../Images/parised.png';
|
||||
import img_focused from '../Images/focused.png';
|
||||
import img_fork from '../Images/fork.png';
|
||||
import img_milepost from '../Images/milepost.png';
|
||||
const Setting = Loadable({
|
||||
loader: () => import('../Settings/Index'),
|
||||
loading: Loading,
|
||||
|
@ -114,6 +104,10 @@ const TrendsIndex = Loadable({
|
|||
loading: Loading,
|
||||
})
|
||||
|
||||
const DevAbout = Loadable({
|
||||
loader: () => import('../About/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
const DevIndex = Loadable({
|
||||
loader: () => import('../DevOps/Index'),
|
||||
loading: Loading,
|
||||
|
@ -124,7 +118,9 @@ const DevIndex = Loadable({
|
|||
function checkPathname(pathname){
|
||||
let name = "";
|
||||
if(pathname){
|
||||
if(pathname.indexOf("/issues")>-1 ||pathname.indexOf("Milepost") > 0){
|
||||
if(pathname.indexOf("/about")>-1){
|
||||
name="about"
|
||||
}else if(pathname.indexOf("/issues")>-1 ||pathname.indexOf("Milepost") > 0){
|
||||
name = "issues";
|
||||
}else if(pathname.indexOf("/pulls")>-1){
|
||||
name="pulls"
|
||||
|
@ -134,6 +130,8 @@ function checkPathname(pathname){
|
|||
name="activity"
|
||||
}else if(pathname.indexOf("/setting")>-1){
|
||||
name="setting"
|
||||
}else if(pathname.indexOf("/devops")>-1){
|
||||
name="devops"
|
||||
}
|
||||
}
|
||||
return name;
|
||||
|
@ -159,6 +157,14 @@ class Detail extends Component {
|
|||
project: null,
|
||||
firstSync:false,
|
||||
secondSync:false,
|
||||
open_devops:false,
|
||||
// 默认分支
|
||||
defaultBranch:undefined,
|
||||
|
||||
// 非本平台项目
|
||||
platform:false,
|
||||
visible:false,
|
||||
user_apply_signatures:[]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,13 +181,35 @@ class Detail extends Component {
|
|||
}
|
||||
|
||||
getProject = (num) => {
|
||||
const {user} = this.props;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/simple.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
this.setState({
|
||||
project: result.data
|
||||
project: result.data,
|
||||
open_devops:result.data.open_devops,
|
||||
platform:result.data.platform && result.data.platform !== 'educoder'
|
||||
})
|
||||
let signa = result.data.user_apply_signatures && result.data.user_apply_signatures[0];
|
||||
if(result.data.is_secret && !result.data.is_member && (!signa || (signa && signa.status !== "passed")) && user.login !== owner){
|
||||
this.setState({
|
||||
visible:true,
|
||||
is_secret:result.data.is_secret,
|
||||
user_apply_signatures:signa
|
||||
})
|
||||
}
|
||||
|
||||
// 工作流:两种状态进入的链接不同
|
||||
const pathname = this.props.history.location.pathname;
|
||||
if(pathname===`/projects/${owner}/${projectsId}/devops`){
|
||||
if(result.data.open_devops && pathname === `/projects/${owner}/${projectsId}/devops`){
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/devops/list`);
|
||||
}else if(result.data.open_devops===false && pathname !== `/projects/${owner}/${projectsId}/devops`){
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/devops`);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.data.type !== 0 && result.data.mirror_status === 1) {
|
||||
console.log("--------start channel --------");
|
||||
// 是镜像项目,且未完成迁移
|
||||
|
@ -207,6 +235,13 @@ class Detail extends Component {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 工作流激活后修改状态
|
||||
changeOpenDevops=(flag)=>{
|
||||
this.setState({
|
||||
open_devops:flag
|
||||
})
|
||||
}
|
||||
canvasChannel = () => {
|
||||
const name = window.location.hostname === "localhost" ? "testforgeplus.trustie.net" : window.location.hostname;
|
||||
const actioncable = require("actioncable");
|
||||
|
@ -234,11 +269,11 @@ class Detail extends Component {
|
|||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
if (result && result.data) {
|
||||
this.setState({
|
||||
projectDetail: result.data,
|
||||
project_id: result.data.project_id,
|
||||
isManager: result.data.permission && result.data.permission === "Manager",
|
||||
isManager: result.data.permission && (result.data.permission === "Manager" || result.data.permission === "Admin" || result.data.permission === "Owner"),
|
||||
isReporter: result.data.permission && result.data.permission === "Reporter",
|
||||
isDeveloper: result.data.permission && result.data.permission === "Developer",
|
||||
http_url: result.data.clone_url,
|
||||
|
@ -248,6 +283,7 @@ class Detail extends Component {
|
|||
watchers_count: result.data.watchers_count,
|
||||
praises_count: result.data.praises_count,
|
||||
forked_count: result.data.forked_count,
|
||||
defaultBranch:result.data.default_branch
|
||||
})
|
||||
}
|
||||
}).catch((error) => { })
|
||||
|
@ -255,8 +291,10 @@ class Detail extends Component {
|
|||
|
||||
// 关注和取消关注
|
||||
focusFunc = (flag) => {
|
||||
const { project_id } = this.state;
|
||||
const { platform } = this.state;
|
||||
if(!platform)return;
|
||||
|
||||
const { project_id } = this.state;
|
||||
axios({
|
||||
method: flag ? 'delete' : 'post',
|
||||
url: `/watchers/${flag ? 'unfollow' : 'follow'}.json`,
|
||||
|
@ -276,6 +314,8 @@ class Detail extends Component {
|
|||
|
||||
// 点赞和取消点赞
|
||||
pariseFunc = (flag) => {
|
||||
const { platform } = this.state;
|
||||
if(!platform)return;
|
||||
const { project_id } = this.state;
|
||||
axios({
|
||||
method: flag ? 'delete' : 'post',
|
||||
|
@ -306,6 +346,8 @@ class Detail extends Component {
|
|||
|
||||
// fork项目
|
||||
forkFunc = () => {
|
||||
const { platform } = this.state;
|
||||
if(!platform)return;
|
||||
const { current_user } = this.props
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/forks.json`;
|
||||
|
@ -321,6 +363,8 @@ class Detail extends Component {
|
|||
|
||||
// 同步镜像
|
||||
synchronismMirror = () => {
|
||||
const { platform } = this.state;
|
||||
if(!platform)return;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/sync_mirror.json`;
|
||||
axios.post(url).then(result => {
|
||||
|
@ -334,10 +378,24 @@ class Detail extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
hideModal=()=>{
|
||||
this.setState({
|
||||
visible:false
|
||||
})
|
||||
}
|
||||
|
||||
sureModal=()=>{
|
||||
this.hideModal();
|
||||
this.props.history.push('/projects');
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
const { projectDetail, watchers_count, praises_count, forked_count, firstSync , secondSync , isManager, watched, praised, project } = this.state;
|
||||
const { projectDetail, watchers_count, praises_count,
|
||||
forked_count, firstSync , secondSync ,
|
||||
isManager, watched, praised,
|
||||
project , open_devops , platform , defaultBranch , project_id , user_apply_signatures , visible } = this.state;
|
||||
const url = this.props.history.location.pathname;
|
||||
const urlArr = url.split("/");
|
||||
const urlFlag = (urlArr.length === 3);
|
||||
|
@ -346,8 +404,6 @@ class Detail extends Component {
|
|||
const { projectsId , owner } = this.props.match.params;
|
||||
|
||||
const { state } = this.props.history.location;
|
||||
const { current_user } = this.props;
|
||||
const checkLogin = current_user && current_user.login;
|
||||
|
||||
const text = (
|
||||
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
||||
|
@ -359,16 +415,18 @@ class Detail extends Component {
|
|||
</React.Fragment> : ""
|
||||
);
|
||||
|
||||
|
||||
const common = {
|
||||
getDetail: this.getDetail
|
||||
getDetail: this.getDetail,
|
||||
changeOpenDevops:this.changeOpenDevops,
|
||||
defaultBranch
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<SpecialModal {...this.props} visible={visible} hideModal={this.sureModal} user_apply_signatures={user_apply_signatures} project_id={project_id} sureModal={this.sureModal}></SpecialModal>
|
||||
<div className="detailHeader-wrapper">
|
||||
<div className="normal">
|
||||
<div className="f-wrap-between pb15" style={{ position: "relative" }}>
|
||||
<p className="font-22 color-white df flex-1 lineH2 mt15" style={{ alignItems: "center" }}>
|
||||
<p className="color-white font-22 df flex-1 lineH2 mt15" style={{ alignItems: "center" }}>
|
||||
{project && project.author &&
|
||||
<Link to={`/users/${project.author.login}`} className="show-user-link color-white">
|
||||
{project.author.name}
|
||||
|
@ -391,10 +449,11 @@ class Detail extends Component {
|
|||
projectDetail.type === 2 ?
|
||||
<Tooltip title={"镜像自: " + projectDetail.mirror_url} className="ml5" placement={'right'}>
|
||||
<i className="iconfont icon-banbenku font-18 mt6" style={{ color: "#8D90E3" }}/>
|
||||
</Tooltip>:
|
||||
</Tooltip>
|
||||
:
|
||||
<Tooltip title={"镜像自: " + projectDetail.mirror_url} className="ml5" placement={'right'}>
|
||||
<i className="iconfont icon-jingxiang font-18 color-green mt6" />
|
||||
</Tooltip>
|
||||
<i className="iconfont icon-jingxiang font-18 color-green mt6" />
|
||||
</Tooltip>
|
||||
:""
|
||||
}
|
||||
</span>
|
||||
|
@ -407,29 +466,45 @@ class Detail extends Component {
|
|||
<a className="synchronism ml30" onClick={this.synchronismMirror}>同步镜像</a> : ""
|
||||
}
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={() => this.focusFunc(watched)}>
|
||||
<img src={watched ? img_focused : img_focus} alt="" width="14px" />
|
||||
{watched ? '取消关注' : '关注'}
|
||||
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={() => this.focusFunc(watched)}>
|
||||
<i className={watched ? "iconfont icon-shixing color-orange font-16 mr3":"iconfont icon-kongxing color-grey-9 font-16 mr3"}></i>
|
||||
<span>{watched ? '取消关注' : '关注'}</span>
|
||||
</a>
|
||||
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${owner}/${projectsId}/watchers`, state }}>
|
||||
{watchers_count}
|
||||
</Link>
|
||||
{
|
||||
platform ?
|
||||
<Link className="detail_tag_btn_count" style={{color:`${watched?"#2878FF":"#666"}`}} to={platform?{ pathname: `/projects/${owner}/${projectsId}/watchers`, state }:""}>
|
||||
{watchers_count}
|
||||
</Link>
|
||||
:
|
||||
<span className="detail_tag_btn_count">{watchers_count}</span>
|
||||
}
|
||||
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={() => this.pariseFunc(praised)}>
|
||||
<img src={praised ? img_parised : img_parise} width="13px" alt="" />
|
||||
{praised ? '取消点赞' : '点赞'}
|
||||
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={() => this.pariseFunc(praised)}>
|
||||
<i className={praised ? "iconfont icon-weibiaoti105 color-orange font-14 mr3":"iconfont icon-guanzhu color-grey-9 font-14 mr3"}></i>
|
||||
<span>{praised ? '取消点赞' : '点赞'}</span>
|
||||
</a>
|
||||
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${owner}/${projectsId}/stargazers`, state }}>
|
||||
{praises_count}
|
||||
</Link>
|
||||
{
|
||||
platform ?
|
||||
<Link className="detail_tag_btn_count" style={{color:`${praised?"#2878FF":"#666"}`}} to={{ pathname: `/projects/${owner}/${projectsId}/stargazers`, state }}>
|
||||
{praises_count}
|
||||
</Link>:
|
||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||
}
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={this.forkFunc}>
|
||||
<img src={img_fork} alt="" width="10px" />Fork</a>
|
||||
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${owner}/${projectsId}/fork_users`, state }}>
|
||||
{forked_count}
|
||||
</Link>
|
||||
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={this.forkFunc}>
|
||||
<i className="iconfont icon-fork color-grey-9 mr3"></i>复刻 (Fork)
|
||||
</a>
|
||||
{
|
||||
platform ?
|
||||
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${owner}/${projectsId}/fork_users`, state }}>
|
||||
{forked_count}
|
||||
</Link>
|
||||
:
|
||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||
}
|
||||
</span>
|
||||
</span>
|
||||
}
|
||||
|
@ -438,46 +513,66 @@ class Detail extends Component {
|
|||
firstSync ? "" :
|
||||
<div className="f-wrap-between pb20">
|
||||
<ul className="headerMenu-wrapper">
|
||||
<li className={pathname==="about" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/about`, state }}>
|
||||
<i className={ pathname === "about" ? "iconfont icon-zhuye1 color-blue mr5 font-14":"iconfont icon-zhuye1 color-white font-14 mr5"}></i>
|
||||
<span>主页</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className={(pathname==="" || urlFlag) ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}`, state }}>
|
||||
<img alt="" src={img_1} width="18" />代码库
|
||||
<i className={(pathname==="" || urlFlag) ? "iconfont icon-daimaku color-blue mr5 font-14":"iconfont icon-daimaku color-white font-14 mr5"}></i>
|
||||
<span>代码库</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className={pathname==="issues" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/issues`, state }}>
|
||||
<img alt="" src={img_2} width="12" />任务
|
||||
{projectDetail && projectDetail.issues_count ? <span>{projectDetail.issues_count}</span> : ""}
|
||||
<i className={pathname==="issues" ? "iconfont icon-renwu color-blue mr5 font-14":"iconfont icon-renwu color-white font-14 mr5"}></i>
|
||||
<span>易修 (Issue)</span>
|
||||
{projectDetail && projectDetail.issues_count ? <span className="num">{projectDetail.issues_count}</span> : ""}
|
||||
</Link>
|
||||
</li>
|
||||
{
|
||||
projectDetail && parseInt(projectDetail.type) !== 2 &&
|
||||
projectDetail && parseInt(projectDetail.type) !== 2 && platform &&
|
||||
<li className={pathname==="pulls" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/pulls`, state }}>
|
||||
<img alt="" src={img_3} width="13" />合并请求
|
||||
{projectDetail && projectDetail.pull_requests_count ? <span>{projectDetail.pull_requests_count}</span> : ""}
|
||||
<i className={pathname==="pulls" ? "iconfont icon-hebingqingqiu1 color-blue mr5 font-14":"iconfont icon-hebingqingqiu1 color-white font-14 mr5"}></i>
|
||||
<span>合并请求</span>
|
||||
{projectDetail && projectDetail.pull_requests_count ? <span className="num">{projectDetail.pull_requests_count}</span> : ""}
|
||||
</Link>
|
||||
</li>
|
||||
}
|
||||
{/* <li className={url.indexOf("/ops") > -1 ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/ops`, state }}>
|
||||
<i className="iconfont icon-gongzuoliu font-13 mr8"></i>工作流
|
||||
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
|
||||
</Link>
|
||||
</li> */}
|
||||
{/* {
|
||||
platform &&
|
||||
<li className={pathname==="devops" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/devops${open_devops ? `/list`:""}`, state }}>
|
||||
<i className="iconfont icon-gongzuoliu font-13 mr8"></i>工作流(beta版)
|
||||
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
|
||||
</Link>
|
||||
</li>
|
||||
} */}
|
||||
|
||||
<li className={pathname==="milestones" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/milestones`, state }}>
|
||||
<img alt="" src={img_milepost} width="16" />里程碑
|
||||
{projectDetail && projectDetail.versions_count ? <span>{projectDetail.versions_count}</span> :""}
|
||||
<i className={pathname==="milestones" ? "iconfont icon-lichengbei color-blue mr5 font-14":"iconfont icon-lichengbei color-white font-14 mr5"}></i>
|
||||
<span>里程碑</span>
|
||||
{projectDetail && projectDetail.versions_count ? <span className="num">{projectDetail.versions_count}</span> :""}
|
||||
</Link>
|
||||
</li>
|
||||
<li className={pathname==="activity" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/activity`, state }}>
|
||||
<img alt="" src={img_6} width="16" />动态
|
||||
</Link>
|
||||
<i className={pathname==="activity" ? "iconfont icon-tongzhi color-blue mr5 font-14":"iconfont icon-tongzhi color-white font-14 mr5"}></i>
|
||||
<span>动态</span>
|
||||
</Link>
|
||||
</li>
|
||||
{
|
||||
isManager &&
|
||||
<li className={url.indexOf("/setting") > 0 ? "active" : ""}><Link to={`/projects/${owner}/${projectsId}/setting`}><img alt="" src={img_7} width="19" />仓库设置</Link></li>
|
||||
isManager && platform &&
|
||||
<li className={url.indexOf("/setting") > 0 ? "active" : ""}>
|
||||
<Link to={`/projects/${owner}/${projectsId}/setting`}>
|
||||
<i className={url.indexOf("/setting") > 0 ? "iconfont icon-cangku color-blue mr5 font-14":"iconfont icon-cangku color-white font-14 mr5"}></i>
|
||||
<span>仓库设置</span>
|
||||
</Link>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -493,8 +588,14 @@ class Detail extends Component {
|
|||
:
|
||||
<Spin spinning={secondSync} className="spinstyle" tip="正在同步镜像" size="large">
|
||||
<Switch {...this.props}>
|
||||
{/* 主页 */}
|
||||
<Route path="/projects/:owner/:projectsId/about"
|
||||
render={
|
||||
() => (<DevAbout {...this.props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 工作流 */}
|
||||
<Route path="/projects/:owner/:projectsId/ops"
|
||||
<Route path="/projects/:owner/:projectsId/devops"
|
||||
render={
|
||||
() => (<DevIndex {...this.props} {...this.state} {...common} />)
|
||||
}
|
||||
|
@ -623,6 +724,16 @@ class Detail extends Component {
|
|||
(props) => (<ForkUsers {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:owner/:projectsId/commits/branch/:branchName"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:owner/:projectsId/branch/:branchName"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:owner/:projectsId"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||
|
|
|
@ -3,27 +3,53 @@ import { Link } from 'react-router-dom';
|
|||
|
||||
class DetailTop extends Component {
|
||||
render() {
|
||||
const { coderCount } = this.props;
|
||||
const { coderCount , platform } = this.props;
|
||||
const { projectsId, owner } = this.props.match.params;
|
||||
const { pathname } = this.props.location;
|
||||
return (
|
||||
<p className="branch-wrapper">
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits`} className={pathname.indexOf("/commits") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-tijiaojilu font-20 mr3 font-bd"></i>
|
||||
<span>{(coderCount && coderCount.commits_count) || 0}</span>个提交
|
||||
</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/branch`} className={pathname.indexOf("/branch") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-fenzhi1 font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.branches_count) || 0}</span>个分支
|
||||
</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/tag`} className={pathname.indexOf("/tag") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-biaoqian3 font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.tags_count) || 0}</span>个标签
|
||||
</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/releases`} className={pathname.indexOf("/releases") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-fahangban font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.version_releasesed_count) || 0}</span>个发行版
|
||||
</Link>
|
||||
|
||||
{
|
||||
platform ?
|
||||
<React.Fragment>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits`} className={pathname.indexOf("/commits") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-tijiaojilu font-20 mr3 font-bd"></i>
|
||||
<span>{(coderCount && coderCount.commits_count) || 0}</span>个提交
|
||||
</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/branchs`} className={pathname.indexOf("/branchs") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-fenzhi1 font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.branches_count) || 0}</span>个分支
|
||||
</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/tag`} className={pathname.indexOf("/tag") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-biaoqian3 font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.tags_count) || 0}</span>个标签
|
||||
</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/releases`} className={pathname.indexOf("/releases") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-fahangban font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.version_releasesed_count) || 0}</span>个发行版
|
||||
</Link>
|
||||
</React.Fragment>
|
||||
:
|
||||
<React.Fragment>
|
||||
<a href="javscript:void(0)" style={{cursor:"default"}}>
|
||||
<i className="iconfont icon-tijiaojilu font-20 mr3 font-bd"></i>
|
||||
<span>{(coderCount && coderCount.commits_count) || 0}</span>个提交
|
||||
</a>
|
||||
<a href="javscript:void(0)" style={{cursor:"default"}}>
|
||||
<i className="iconfont icon-fenzhi1 font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.branches_count) || 0}</span>个分支
|
||||
</a>
|
||||
<a href="javscript:void(0)" style={{cursor:"default"}}>
|
||||
<i className="iconfont icon-biaoqian3 font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.tags_count) || 0}</span>个标签
|
||||
</a>
|
||||
<a href="javscript:void(0)" style={{cursor:"default"}}>
|
||||
<i className="iconfont icon-fahangban font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.version_releasesed_count) || 0}</span>个发行版
|
||||
</a>
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
<a href="javscript:void(0)" style={{cursor:"default"}}>
|
||||
<i className="iconfont icon-cangku font-18 mr3"></i>
|
||||
仓库 <span className="ml3">{(coderCount && coderCount.size) || 0}</span>
|
||||
|
|
|
@ -2,7 +2,8 @@ import React, { useEffect, useState } from "react";
|
|||
import styled from "styled-components";
|
||||
import { Button ,Spin } from "antd";
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import Nodata from '../Nodata';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import Files from '../Merge/Files';
|
||||
|
||||
import User from "../Component/User";
|
||||
import Keys from "../Component/Keys";
|
||||
|
@ -11,65 +12,34 @@ import axios from "axios";
|
|||
|
||||
const Infos = styled.div`
|
||||
border: 1px solid #dddddd;
|
||||
margin-bottom:15px;
|
||||
& .commitinfos {
|
||||
background-color: #f1f8ff;
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 20px;
|
||||
}
|
||||
& > .f-wrap-between {
|
||||
padding: 10px 24px;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
`;
|
||||
const Operation = styled.p`
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 12px 0px;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const FileUl = styled.ul`
|
||||
padding-top: 10px;
|
||||
& li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
`;
|
||||
const DetailP = styled.p`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 20px 12px 12px;
|
||||
background-color: #fafafa;
|
||||
border: 1px solid #dddddd;
|
||||
`;
|
||||
|
||||
export default ({ projectDetail, match }) => {
|
||||
export default ({ match , history }) => {
|
||||
const [data, setData] = useState({undefined});
|
||||
const [commit, setCommit] = useState(undefined);
|
||||
const [files, setFiles] = useState(undefined);
|
||||
const [parents, setParents] = useState(undefined);
|
||||
const [committer, setCommitter] = useState(undefined);
|
||||
const [fileflag , setFileflag] = useState(false);
|
||||
const [isSpin, setIsSpin] = useState(true);
|
||||
|
||||
const repo_id = projectDetail && projectDetail.repo_id;
|
||||
const { sha } = match.params;
|
||||
const { sha , projectsId, owner } = match.params;
|
||||
useEffect(() => {
|
||||
if (repo_id && sha) {
|
||||
const url = `/repositories/${repo_id}/commits/${sha}.json`;
|
||||
if (projectsId && owner && sha) {
|
||||
const url = `/${owner}/${projectsId}/commits/${sha}.json`;
|
||||
axios
|
||||
.get(url)
|
||||
.then(result => {
|
||||
if (result) {
|
||||
setData(result.data);
|
||||
setCommit(result.data.commit);
|
||||
setFiles(result.data.files);
|
||||
setParents(result.data.parents);
|
||||
setCommitter(result.data.committer || (result.data.commit && result.data.commit.committer));
|
||||
setIsSpin(false);
|
||||
|
@ -79,78 +49,32 @@ export default ({ projectDetail, match }) => {
|
|||
console.log(error);
|
||||
});
|
||||
}
|
||||
}, [repo_id, sha]);
|
||||
const renderFiles = () => {
|
||||
return (
|
||||
<FileUl>
|
||||
{
|
||||
files && files.length > 0 && files.map((item,key)=>{
|
||||
return(
|
||||
<li>
|
||||
<span className="mr30 task-hide flex1">
|
||||
<i className="iconfont icon-wenjia color-grey-3 font-16 mr8"></i>
|
||||
{item.Name}
|
||||
</span>
|
||||
<span>
|
||||
<label className="color-green mr20">+{item.Addition}</label>
|
||||
<label className="color-red">-{item.Deletion}</label>
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</FileUl>
|
||||
);
|
||||
};
|
||||
|
||||
function changeFlag(){
|
||||
let flag = !fileflag;
|
||||
setFileflag(flag);
|
||||
}
|
||||
|
||||
const filesDetail = () => {
|
||||
return (
|
||||
<div>
|
||||
<DetailP>
|
||||
<span>
|
||||
<i className="iconfont icon-youjiantou mr4 font-15 color-grey-9"></i>
|
||||
<span className="font-16 color-grey-3">README.md</span>
|
||||
</span>
|
||||
<Button>查看文件</Button>
|
||||
</DetailP>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
}, [projectsId , owner, sha]);
|
||||
return (
|
||||
<div className="main">
|
||||
<Spin spinning={isSpin}>
|
||||
<Infos>
|
||||
<div className="commitinfos">
|
||||
<p className="f-wrap-between">
|
||||
<span className="font-20 color-grey-3">
|
||||
{ commit && commit.title }
|
||||
</span>
|
||||
<Button type="primary">浏览代码</Button>
|
||||
</p>
|
||||
{commit && commit.message ? (
|
||||
<pre className="mt10">{commit.message}</pre>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<div className="f-wrap-between">
|
||||
{commit && commit.message &&
|
||||
<pre className="task-hide" style={{marginBottom:"0px",height:"28px",whiteSpace:"pre-wrap"}}>{commit.message}</pre>
|
||||
}
|
||||
<Button type="primary" onClick={()=>{history.push(`/projects/${owner}/${projectsId}/branch/${truncateCommitId(sha)}`)}} className="ml30">浏览代码</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="f-wrap-between" style={{ alignItems: "center" }}>
|
||||
<ul className="df">
|
||||
<User
|
||||
url={(committer && committer.image_url)|| "https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3025493530,1989042357&fm=26&gp=0.jpg"}
|
||||
url={(committer && getImageUrl(`images/${committer.image_url}`))|| "https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3025493530,1989042357&fm=26&gp=0.jpg"}
|
||||
name={committer && committer.name}
|
||||
/>
|
||||
{committer && committer.time_from_now && <li className="ml20 mt2">{committer.time_from_now}</li>}
|
||||
</ul>
|
||||
<li className="df">
|
||||
{
|
||||
parents && parents.length > 0 && parents.map((item,key)=>{
|
||||
return(
|
||||
<Keys title="父节点" value={truncateCommitId(item.sha) } className="mr20"></Keys>
|
||||
<Keys title="父节点" value={truncateCommitId(item.sha)} key={key} className="mr20"></Keys>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -158,35 +82,12 @@ export default ({ projectDetail, match }) => {
|
|||
</li>
|
||||
</div>
|
||||
</Infos>
|
||||
{
|
||||
files && files.length > 0 ?
|
||||
<React.Fragment>
|
||||
<Operation>
|
||||
<span className="files_info" onClick={changeFlag}>
|
||||
<i className={fileflag ? "iconfont icon-sanjiaoxing-down mr8 color-grey-9 font-16":"iconfont icon-triangle mr8 color-grey-9 font-16"}></i>
|
||||
<span className="color-grey-9">
|
||||
共有<span>{files && files.length}个文件被更改</span>,包括
|
||||
{data && data.additions ? (
|
||||
<span className="color-green">{data.additions}次插入</span>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{data && data.additions && data.deletions ? "和" : ""}
|
||||
{data && data.deletions ? (
|
||||
<span className="color-red">{data.deletions}次删除</span>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</span>
|
||||
</span>
|
||||
<Button>双栏查看</Button>
|
||||
</Operation>
|
||||
{fileflag && renderFiles()}
|
||||
{filesDetail()}
|
||||
</React.Fragment>
|
||||
:
|
||||
<Nodata _html="暂无文件修改信息!"/>
|
||||
}
|
||||
<Files
|
||||
history={history}
|
||||
data={data}
|
||||
owner={owner}
|
||||
projectsId={projectsId}
|
||||
/>
|
||||
</Spin>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import React, { Component } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Menu, Input, Spin, Pagination, Popover, Affix } from "antd";
|
||||
import "../css/index.scss";
|
||||
import "./list.css";
|
||||
import ListItem from "./IndexItem";
|
||||
import axios from "axios";
|
||||
import img_new from "../Images/new.png";
|
||||
import img_array from "../Images/array.png";
|
||||
import banner_list from "../Images/banner_list.png";
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Menu, Input , Spin, Pagination , Popover } from 'antd';
|
||||
import '../css/index.scss'
|
||||
import './list.css';
|
||||
import './Index.scss';
|
||||
import ListItem from './IndexItem'
|
||||
import axios from 'axios';
|
||||
import img_new from '../Images/new.png';
|
||||
import img_array from '../Images/array.png';
|
||||
import banner from '../Images/banner_list.png';
|
||||
const Search = Input.Search;
|
||||
|
||||
class Index extends Component {
|
||||
|
@ -22,249 +22,151 @@ class Index extends Component {
|
|||
sort: undefined,
|
||||
total: 0,
|
||||
isSpin: true,
|
||||
project_type: undefined,
|
||||
category_id: undefined,
|
||||
language_id: undefined,
|
||||
|
||||
typeList: undefined,
|
||||
categoryList: undefined,
|
||||
languageSpin: false,
|
||||
categorySPin: false,
|
||||
menu_active_id: undefined,
|
||||
};
|
||||
recommendList:undefined,
|
||||
|
||||
languageList:undefined,
|
||||
languageId:undefined
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
const {
|
||||
page,
|
||||
limit,
|
||||
search,
|
||||
sort,
|
||||
project_type,
|
||||
category_id,
|
||||
language_id,
|
||||
} = this.state;
|
||||
this.getListData(
|
||||
page,
|
||||
limit,
|
||||
search,
|
||||
sort,
|
||||
project_type,
|
||||
category_id,
|
||||
language_id
|
||||
);
|
||||
const { page,search, sort,category_id , languageId } = this.state;
|
||||
this.getListData(page,search, sort,category_id , languageId);
|
||||
|
||||
this.getType();
|
||||
|
||||
this.getCategory();
|
||||
};
|
||||
|
||||
this.getRecommand();
|
||||
|
||||
this.getLanguage();
|
||||
}
|
||||
|
||||
// 获取语言列表
|
||||
getLanguage=()=>{
|
||||
const url = '/project_languages.json';
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
languageList:result.data.project_languages
|
||||
})
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
// 获取推荐列表
|
||||
getRecommand=()=>{
|
||||
const url = `/projects/recommend.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
recommendList:result.data
|
||||
})
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
// 获取列表
|
||||
getListData = (
|
||||
page,
|
||||
limit,
|
||||
search,
|
||||
sort,
|
||||
project_type,
|
||||
category_id,
|
||||
language_id
|
||||
) => {
|
||||
getListData = (page,search, sort,category_id,language_id) => {
|
||||
const { current_user } = this.props;
|
||||
const url = `/projects.json`;
|
||||
axios
|
||||
.get(url, {
|
||||
params: {
|
||||
user_id: current_user && current_user.user_id,
|
||||
page,
|
||||
limit,
|
||||
search,
|
||||
sort_by: sort,
|
||||
category_id,
|
||||
language_id,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
projectsList: result.data.projects,
|
||||
total: result.data.total_count,
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {});
|
||||
};
|
||||
axios.get(url, {
|
||||
params: {
|
||||
user_id: current_user && current_user.user_id,
|
||||
page,
|
||||
limit:15,
|
||||
search,
|
||||
sort_by: sort,
|
||||
category_id,
|
||||
language_id
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
projectsList: result.data.projects,
|
||||
total: result.data.total_count,
|
||||
isSpin: false
|
||||
})
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}
|
||||
|
||||
// 获取类型
|
||||
getType = () => {
|
||||
this.setState({ languageSpin: true });
|
||||
const url = `/projects/group_type_list.json`;
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
if (result && result.data) {
|
||||
this.setTypeList(result.data, undefined);
|
||||
this.setState({ languageSpin: false });
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({ languageSpin: false });
|
||||
});
|
||||
};
|
||||
axios.get(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
this.setTypeList(result.data, undefined)
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}
|
||||
|
||||
setTypeList = (list, active_type) => {
|
||||
this.setState({
|
||||
typeList: list.map((item, key) => {
|
||||
return (
|
||||
<li
|
||||
key={key}
|
||||
className={
|
||||
active_type && parseInt(active_type) === parseInt(item.id)
|
||||
? "active"
|
||||
: ""
|
||||
}
|
||||
onClick={() => this.changeType(`${item.id}`, list)}
|
||||
>
|
||||
<li key={key} className={active_type && parseInt(active_type) === item.id ? 'active' : ''} onClick={() => this.changeType(`${item.id}`, list)}>
|
||||
<p>
|
||||
<span className="font-16">{item.name}</span>
|
||||
<span className="color-blue">{item.projects_count}</span>
|
||||
</p>
|
||||
</li>
|
||||
);
|
||||
}),
|
||||
});
|
||||
};
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 切换类型
|
||||
changeType = (type, list) => {
|
||||
const { page, limit, sort, category_id, language_id } = this.state;
|
||||
let new_language_id = type;
|
||||
if (parseInt(language_id) === parseInt(new_language_id)) {
|
||||
new_language_id = undefined;
|
||||
}
|
||||
changeType = (id, list) => {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
language_id: new_language_id,
|
||||
search: undefined,
|
||||
});
|
||||
this.setTypeList(list, new_language_id);
|
||||
// const { page, limit, sort, category_id, language_id } = this.state;
|
||||
this.getListData(
|
||||
page,
|
||||
limit,
|
||||
undefined,
|
||||
sort,
|
||||
undefined,
|
||||
category_id,
|
||||
new_language_id
|
||||
);
|
||||
};
|
||||
languageId: id,
|
||||
search: undefined
|
||||
})
|
||||
this.setTypeList(list, id)
|
||||
const { page,sort, category_id} = this.state;
|
||||
this.getListData(page,undefined, sort,category_id , id);
|
||||
}
|
||||
|
||||
// 获取类型
|
||||
getCategory = () => {
|
||||
this.setState({ categorySpin: true });
|
||||
const url = `/project_categories/group_list.json`;
|
||||
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
if (result && result.data) {
|
||||
this.setCategoryList(result.data, undefined);
|
||||
this.setState({ categorySpin: false });
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({ categorySpin: false });
|
||||
});
|
||||
};
|
||||
children_category = (childrens, list, active_id) => {
|
||||
return (
|
||||
<div className="category-popver-content">
|
||||
{childrens.map((item, key) => {
|
||||
return (
|
||||
<div
|
||||
key={key}
|
||||
onClick={() => this.changeCategory(item.id, list, item.parent_id)}
|
||||
className={
|
||||
active_id && parseInt(active_id) === item.id
|
||||
? "active category-popver"
|
||||
: "category-popver"
|
||||
}
|
||||
>
|
||||
{item.name}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
axios.get(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
this.setCategoryList(result.data, undefined);
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}
|
||||
|
||||
setCategoryList = (list, active_id, children_active_id = undefined) => {
|
||||
setCategoryList = (list, active_id) => {
|
||||
this.setState({
|
||||
categoryList: list.map((item, key) => {
|
||||
return (
|
||||
<li
|
||||
key={key}
|
||||
className={
|
||||
active_id && parseInt(active_id) === item.id ? "active" : ""
|
||||
}
|
||||
>
|
||||
{item.children && item.children.length > 0 ? (
|
||||
<Popover
|
||||
content={this.children_category(
|
||||
item.children,
|
||||
list,
|
||||
children_active_id
|
||||
)}
|
||||
placement="right"
|
||||
trigger="click"
|
||||
>
|
||||
<p>
|
||||
<span className="font-16">{item.name}</span>
|
||||
<i className="iconfont icon-youjiantou color-grey-9 font-12 ml5"></i>
|
||||
{/* <span className="color-blue">{item.projects_count}</span> */}
|
||||
</p>
|
||||
</Popover>
|
||||
) : (
|
||||
<p onClick={() => this.changeCategory(`${item.id}`, list)}>
|
||||
<span className="font-16">{item.name}</span>
|
||||
<span></span>
|
||||
{/* <span className="color-blue">{item.projects_count}</span> */}
|
||||
</p>
|
||||
)}
|
||||
<li key={key} className={active_id && parseInt(active_id) === item.id ? 'active' : ''} onClick={() => this.changeCategory(`${item.id}`, list)}>
|
||||
<p>
|
||||
<span className="font-16">{item.name}</span>
|
||||
<span className="color-blue">{item.projects_count}</span>
|
||||
</p>
|
||||
</li>
|
||||
);
|
||||
}),
|
||||
});
|
||||
};
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
changeCategory = (id, list, parent_id = undefined) => {
|
||||
const { limit, sort, category_id, language_id } = this.state;
|
||||
let new_category_id = id;
|
||||
if (parseInt(category_id) === parseInt(new_category_id)) {
|
||||
new_category_id = undefined;
|
||||
}
|
||||
changeCategory = (id, list) => {
|
||||
this.setState({
|
||||
category_id: new_category_id,
|
||||
page: 1,
|
||||
search: undefined,
|
||||
menu_active_id: new_category_id,
|
||||
category_id: id,
|
||||
page: 1
|
||||
});
|
||||
let active_id = parent_id ? parent_id : new_category_id;
|
||||
let children_active_id = parent_id ? id : undefined;
|
||||
|
||||
this.setCategoryList(list, active_id, children_active_id);
|
||||
|
||||
this.getListData(
|
||||
1,
|
||||
limit,
|
||||
undefined,
|
||||
sort,
|
||||
undefined,
|
||||
new_category_id,
|
||||
language_id
|
||||
);
|
||||
};
|
||||
this.setCategoryList(list, id)
|
||||
const { sort,languageId } = this.state;
|
||||
this.getListData(1,undefined, sort,id , languageId);
|
||||
}
|
||||
|
||||
// 排序
|
||||
ChangeSoryBy = (e) => {
|
||||
|
@ -272,11 +174,11 @@ class Index extends Component {
|
|||
sort_by: e.key,
|
||||
page: 1,
|
||||
search: undefined,
|
||||
isSpin: true,
|
||||
});
|
||||
const { limit, project_type, category_id } = this.state;
|
||||
this.getListData(1, limit, undefined, e.key, project_type, category_id);
|
||||
};
|
||||
isSpin: true
|
||||
})
|
||||
const {category_id , languageId } = this.state;
|
||||
this.getListData(1,undefined, e.key,category_id , languageId);
|
||||
}
|
||||
|
||||
// 搜索
|
||||
searchFun = (value) => {
|
||||
|
@ -285,161 +187,142 @@ class Index extends Component {
|
|||
search: value,
|
||||
isSpin: true,
|
||||
project_type: undefined,
|
||||
sort: "updated_on",
|
||||
});
|
||||
const { limit, sort, category_id } = this.state;
|
||||
this.getListData(1, limit, value, sort, undefined, category_id);
|
||||
};
|
||||
sort: "updated_on"
|
||||
})
|
||||
const {sort, category_id , languageId } = this.state;
|
||||
this.getListData(1,value, sort,category_id , languageId);
|
||||
}
|
||||
changeSearchValue = (e) => {
|
||||
this.setState({
|
||||
search: e.target.value,
|
||||
});
|
||||
};
|
||||
search: e.target.value
|
||||
})
|
||||
}
|
||||
// 翻页
|
||||
ChangePage = (page) => {
|
||||
this.setState({
|
||||
page,
|
||||
});
|
||||
const { limit, search, sort, project_type, category_id } = this.state;
|
||||
this.getListData(page, limit, search, sort, project_type, category_id);
|
||||
};
|
||||
page
|
||||
})
|
||||
const {search, sort,category_id , languageId } = this.state;
|
||||
this.getListData(page,search, sort, category_id , languageId);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { current_user } = this.props;
|
||||
const menu = (
|
||||
getoDetail=(login,identifier)=>{
|
||||
this.props.history.push(`/projects/${login}/${identifier}`);
|
||||
}
|
||||
|
||||
|
||||
menu =()=> {
|
||||
return(
|
||||
<Menu onClick={this.ChangeSoryBy}>
|
||||
<Menu.Item key="updated_on">更新时间排序</Menu.Item>
|
||||
<Menu.Item key="created_on">创建时间排序</Menu.Item>
|
||||
<Menu.Item key="forked_count">fork数据排序</Menu.Item>
|
||||
<Menu.Item key="praises_count">点赞数量排序</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
const newItem = (
|
||||
)
|
||||
}
|
||||
|
||||
newItem = ()=>{
|
||||
return(
|
||||
<Menu>
|
||||
<Menu.Item key="created_mirror">
|
||||
<Link to={`/projects/mirror/new`}>新建镜像项目</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="created_deposit">
|
||||
<Link to={`/projects/deposit/new`}>新建托管项目</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="created_mirror"><Link to={`/projects/mirror/new`}>新建镜像项目</Link></Menu.Item>
|
||||
<Menu.Item key="created_deposit"><Link to={`/projects/deposit/new`}>新建托管项目</Link></Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
const {
|
||||
projectsList,
|
||||
isSpin,
|
||||
total,
|
||||
search,
|
||||
limit,
|
||||
page,
|
||||
typeList,
|
||||
categoryList,
|
||||
languageSpin,
|
||||
categorySpin,
|
||||
} = this.state;
|
||||
pagination=(total,limit,page)=>{
|
||||
return(
|
||||
total && total > limit ?
|
||||
<div className="edu-txt-center pt30 mb30 border-top-grey">
|
||||
<Pagination simple defaultCurrent={page} total={total} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||||
</div>:""
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { current_user } = this.props;
|
||||
|
||||
const { projectsList , isSpin , total , search , limit , page , typeList , categoryList } = this.state;
|
||||
|
||||
const pagination =
|
||||
total && total > limit ? (
|
||||
<div className="edu-txt-center pt30 mb30 border-top-grey">
|
||||
<Pagination
|
||||
simple
|
||||
defaultCurrent={page}
|
||||
total={total}
|
||||
pageSize={limit}
|
||||
onChange={this.ChangePage}
|
||||
></Pagination>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
<div className="banner_list_img">
|
||||
<img src={banner_list}></img>
|
||||
</div>
|
||||
<p className="t_project_banner"></p>
|
||||
<p className="t_project_banner">
|
||||
<img src={banner} width="100%" alt=""/>
|
||||
</p>
|
||||
{/* {
|
||||
recommendList && recommendList.length>0 &&
|
||||
<div className="recommandProjects">
|
||||
{
|
||||
recommendList.map((item,key)=>{
|
||||
return(
|
||||
<div onClick={()=>this.getoDetail(item.author && item.author.login,item.identifier)}>
|
||||
<div className="mainInfo">
|
||||
<img src={getUrl(`/images/${item.author && item.author.image_url}`)} alt=""/>
|
||||
<p className="school">{item.name}</p>
|
||||
<p className="name">{item.author && item.author.name}</p>
|
||||
</div>
|
||||
<div className="baseInfo">
|
||||
<span className="look"><i className="iconfont icon-dianjiliang font-12"></i>{item.visits}</span>
|
||||
<span className="type">{item.category && item.category.name}</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
||||
*/}
|
||||
<div className="ProjectListIndex">
|
||||
<div className="list-left">
|
||||
<Affix offsetTop={5} style={{ position: "sticky", maxHeight: "100vh"}}>
|
||||
<div className="mb20">
|
||||
<Spin spinning={languageSpin}>
|
||||
<ul className="list-l-Menu">
|
||||
<li className="MenuTitle">
|
||||
<i className="iconfont icon-bianchengyuyan color-grey-9 font-15 mr5"></i>
|
||||
语言
|
||||
</li>
|
||||
<div className="list-affix">{typeList}</div>
|
||||
</ul>
|
||||
</Spin>
|
||||
</div>
|
||||
<div className="mb20">
|
||||
<Spin spinning={categorySpin}>
|
||||
<ul className="list-l-Menu">
|
||||
<li className="MenuTitle">
|
||||
<i className="iconfont icon-xiangmuleibie color-grey-9 font-15 mr5"></i>
|
||||
项目类别
|
||||
</li>
|
||||
<div className="list-affix">{categoryList}</div>
|
||||
</ul>
|
||||
</Spin>
|
||||
</div>
|
||||
</Affix>
|
||||
<ul className="list-l-Menu">
|
||||
<li className="MenuTitle"><i className="iconfont icon-bianchengyuyan color-grey-9 font-15 mr5"></i>
|
||||
语言</li>
|
||||
<div className="list-affix">{typeList}</div>
|
||||
</ul>
|
||||
<ul className="list-l-Menu">
|
||||
<li className="MenuTitle"><i className="iconfont icon-xiangmuleibie color-grey-9 font-15 mr5"></i>项目类别</li>
|
||||
<div className="list-affix">{categoryList}</div>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
className="list-right boxShandow radius-2"
|
||||
style={{ padding: 0 }}
|
||||
>
|
||||
<div className="list-right boxShandow radius-2" style={{padding:0}}>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="list-r-operation">
|
||||
<Search
|
||||
placeholder="输入项目名称关键字进行搜索"
|
||||
enterButton="搜索"
|
||||
size="large"
|
||||
onSearch={this.searchFun}
|
||||
className="list-r-Search"
|
||||
value={search}
|
||||
onChange={this.changeSearchValue}
|
||||
/>
|
||||
<div>
|
||||
{current_user && current_user.login && (
|
||||
<Popover
|
||||
content={newItem}
|
||||
trigger={["click"]}
|
||||
placement="bottom"
|
||||
className="mr50"
|
||||
>
|
||||
<Search
|
||||
placeholder="输入项目名称关键字进行搜索"
|
||||
enterButton="搜索"
|
||||
size="large"
|
||||
onSearch={this.searchFun}
|
||||
className="list-r-Search"
|
||||
value={search}
|
||||
onChange={this.changeSearchValue}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{
|
||||
current_user && current_user.login &&
|
||||
<Popover content={this.newItem()} trigger={["click"]} placement='bottom' className="mr50">
|
||||
<a className="ant-dropdown-link">
|
||||
<span className="color-blue font-16">
|
||||
<img src={img_new} alt="" width="13px" /> 新建
|
||||
</span>
|
||||
<span className="color-blue font-16"><img src={img_new} alt="" width="13px" /> 新建</span>
|
||||
</a>
|
||||
</Popover>
|
||||
)}
|
||||
}
|
||||
|
||||
<Popover
|
||||
content={menu}
|
||||
trigger={["click"]}
|
||||
placement="bottom"
|
||||
>
|
||||
<Popover content={this.menu()} trigger={['click']} placement='bottom'>
|
||||
<a className="ant-dropdown-link">
|
||||
<span className="color-blue font-16">
|
||||
排序 <img src={img_array} alt="" width="10px" />
|
||||
</span>
|
||||
<span className="color-blue font-16">排序 <img src={img_array} alt="" width="10px" /></span>
|
||||
</a>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
<ListItem
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
projects={projectsList}
|
||||
></ListItem>
|
||||
{pagination}
|
||||
<ListItem {...this.props} {...this.state} projects={projectsList} getListData={this.getListData}></ListItem>
|
||||
{this.pagination(total,limit,page)}
|
||||
</Spin>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
export default Index;
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/* recommandProjects */
|
||||
.recommandProjects{
|
||||
display: flex;
|
||||
max-width: 1200px;
|
||||
margin:20px auto;
|
||||
}
|
||||
.recommandProjects >div{
|
||||
background-color: #fff;
|
||||
border-radius: 10px;
|
||||
width: 220px;
|
||||
margin-right: 25px;
|
||||
cursor: pointer;
|
||||
&:last-child{
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
.recommandProjects > div:hover{
|
||||
box-shadow: 0px 2px 20px 0px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.recommandProjects > div .mainInfo{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 160px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding:20px;
|
||||
box-sizing: border-box;
|
||||
img{
|
||||
height: 50px;
|
||||
width:50px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.name{
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
margin-top:12px;
|
||||
}
|
||||
.school{
|
||||
margin-top:12px;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
max-width:100%;
|
||||
}
|
||||
}
|
||||
.recommandProjects{
|
||||
.baseInfo{
|
||||
padding:18px 15px;
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
color:#888;
|
||||
.look{
|
||||
i{
|
||||
margin-right: 5px;
|
||||
}
|
||||
margin-right: 10px;
|
||||
}
|
||||
.type{
|
||||
flex:1;
|
||||
width:0;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
.singleBtn{
|
||||
display: inline-block;
|
||||
.ant-upload-list-item{
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
width: 100%;
|
||||
left: 0px;
|
||||
.ant-upload-list-item-name{
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,26 +6,80 @@ import '../css/index.scss';
|
|||
import Nodata from '../Nodata';
|
||||
import './list.css';
|
||||
import img_parise from '../Images/parise.png';
|
||||
import SpecialModal from './SpecialModal';
|
||||
|
||||
class IndexItem extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
visible:false,
|
||||
user_apply_signatures:[],
|
||||
project_id:undefined
|
||||
}
|
||||
}
|
||||
TurnToDetail = (login, url) => {
|
||||
this.props.history.push({
|
||||
pathname: url,
|
||||
state: login
|
||||
})
|
||||
}
|
||||
/**
|
||||
* link:跳转到详情的地址
|
||||
* user_apply_signatures:是否已经发送访问特殊开源项目的文件
|
||||
* project_id:项目id
|
||||
* is_secret:是否是特殊开源许可证项目
|
||||
* id:创建者login
|
||||
* is_member:是否是项目成员(如果是项目成员可以直接进入项目)
|
||||
* */
|
||||
projectHref=(link , user_apply_signatures,project_id,is_secret , id,is_member)=>{
|
||||
const { user , showLoginDialog } = this.props;
|
||||
if(is_secret && (!user || (user && !user.login))){
|
||||
showLoginDialog();
|
||||
return;
|
||||
}
|
||||
let signa = user_apply_signatures && user_apply_signatures[0];
|
||||
if((is_secret && !is_member && (!signa || (signa && signa.status !== "passed"))) && user.login !== id ){
|
||||
this.setState({
|
||||
visible:true,
|
||||
user_apply_signatures:user_apply_signatures.length>0 ? user_apply_signatures[0] : undefined,
|
||||
project_id
|
||||
})
|
||||
}else{
|
||||
this.props.history.push(link);
|
||||
}
|
||||
}
|
||||
hideModal=()=>{
|
||||
this.setState({
|
||||
visible:false
|
||||
})
|
||||
}
|
||||
|
||||
sureModal=()=>{
|
||||
this.hideModal();
|
||||
const { getListData } = this.props;
|
||||
getListData && getListData(1);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { projects } = this.props;
|
||||
const { visible , user_apply_signatures , project_id } = this.state;
|
||||
const renderList = (
|
||||
projects && projects.length > 0 ? projects.map((item, key) => {
|
||||
return (
|
||||
<div className="p-r-Item" key={key}>
|
||||
<Link to={`/users/${item.author.login}`} className="show-user-link">
|
||||
<img className="p-r-photo" alt="" src={getImageUrl(`images/${item.author && item.author.image_url}`)} ></img>
|
||||
</Link>
|
||||
{
|
||||
item.platform === "educoder" ?
|
||||
<a style={{cursor:"default"}} className="show-user-link">
|
||||
<img className="p-r-photo" alt="" src={item.author && item.author.image_url} ></img>
|
||||
</a>
|
||||
:
|
||||
<Link to={`/users/${item.author.login}`} className="show-user-link">
|
||||
<img className="p-r-photo" alt="" src={getImageUrl(`${item.author && item.author.image_url}`)} ></img>
|
||||
</Link>
|
||||
}
|
||||
<div className="p-r-Infos">
|
||||
<div className="p-r-name">
|
||||
<Link to={`/projects/${item.author.login}/${item.identifier}`} className="hide-1 color-grey-3 font-18 task-hide fwt-500 " style={{ whiteSpace: "wrap", display: 'flex', width: 400 }}>
|
||||
<a onClick={()=>this.projectHref(`/projects/${item.author.login}/${item.identifier}`,item.user_apply_signatures, item.id,item.is_secret,item.author.login,item.is_member)} className="hide-1 color-grey-3 font-18 task-hide fwt-500 " style={{ whiteSpace: "wrap", display: 'flex', width: 400 }}>
|
||||
{item.author.name}/{item.name}
|
||||
{
|
||||
item.forked_from_project_id ?
|
||||
|
@ -44,19 +98,19 @@ class IndexItem extends Component {
|
|||
<i className="iconfont icon-jingxiang font-18 color-green" />
|
||||
</span>:""
|
||||
}
|
||||
</Link>
|
||||
</a>
|
||||
<span className="p-r-tags">
|
||||
<span className="pariseTag"><img src={img_parise} alt="" className="pariseImg" />赞 ({item.praises_count})</span>
|
||||
<span><i className="iconfont icon-fork mr3 font-16" style={{ color: "#1B8FFF" }} />fork ({item.forked_count})</span>
|
||||
<span className="pariseTag"><img src={img_parise} alt="" className="pariseImg" />赞 {item.praises_count}</span>
|
||||
<span><i className="iconfont icon-fork mr3 font-16" style={{ color: "#1B8FFF" }} />fork {item.forked_count}</span>
|
||||
</span>
|
||||
</div>
|
||||
<p className="break_word task-hide-2 mt8 color-grey-3 " style={{ maxHeight: "44px",lineHeight:"22px" }}>{item.description}</p>
|
||||
|
||||
<div className="p-r-about">
|
||||
<span className="p-r-detail">
|
||||
<span><label>浏览量:</label>{item.visits}</span>
|
||||
{item.category && item.category.id && <span><label>项目类别:</label>{item.category.name}</span>}
|
||||
{item.last_update_time ? <span ><label>更新于</label>{item.time_ago}</span> : ""}
|
||||
{/* <span><label>浏览量:</label>{item.visits}</span> */}
|
||||
{/* {item.category && item.category.id && <span>{item.category.name}</span>} */}
|
||||
{item.last_update_time ? <span><label>更新于</label>{item.time_ago}</span> : ""}
|
||||
{item.language && item.language.id ? <span className="color-grey-3">{item.language.name}</span> : ""}
|
||||
</span>
|
||||
</div>
|
||||
|
@ -67,6 +121,7 @@ class IndexItem extends Component {
|
|||
)
|
||||
return (
|
||||
<div className="project-list minH-670">
|
||||
<SpecialModal {...this.props} visible={visible} hideModal={this.hideModal} user_apply_signatures={user_apply_signatures} project_id={project_id} sureModal={this.sureModal}></SpecialModal>
|
||||
{renderList}
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import { Modal } from 'antd';
|
||||
import UploadSingle from '../Upload/single';
|
||||
import './Index.scss';
|
||||
import axios from 'axios';
|
||||
import { getUrl } from 'educoder';
|
||||
|
||||
function SpecialModal({ visible , hideModal , sureModal , showNotification , user_apply_signatures , project_id }){
|
||||
const [ id ,setId ] = useState(undefined);
|
||||
|
||||
|
||||
function loadFunc(id){
|
||||
setId(id);
|
||||
}
|
||||
|
||||
function sure(){
|
||||
if(!user_apply_signatures || (user_apply_signatures && user_apply_signatures.status !== "waiting")){
|
||||
if(!id || (id && id.length === 0)){
|
||||
showNotification("请先提交文件进行审核!");
|
||||
return;
|
||||
}
|
||||
const url = `/apply_signatures.json`;
|
||||
axios.post(url,{
|
||||
attachment_id:id,
|
||||
project_id:project_id
|
||||
}).then(result=>{
|
||||
if(result && result.data.id){
|
||||
showNotification("已提交文件,正在等待审核!");
|
||||
sureModal();
|
||||
}
|
||||
})
|
||||
}else{
|
||||
sureModal();
|
||||
}
|
||||
}
|
||||
return(
|
||||
<Modal title="提示" visible={visible} closable={false} onCancel={hideModal} onOk={sure}>
|
||||
{
|
||||
!user_apply_signatures || (user_apply_signatures && user_apply_signatures.status !== "waiting") ?
|
||||
<div style={{width:"420px",textAlign:'center',margin:"0 auto",paddingBottom:"30px",position:"relative"}}>
|
||||
<div>该项目为私有项目,请先<a href={getUrl(`/api/apply_signatures/template_file`)} className="color-blue">下载</a>开源协议,阅读并填写<br/>相关信息后,将协议<UploadSingle size={"5"} load={loadFunc} showNotification={showNotification} className={'singleBtn'}><span className="color-blue" style={{cursor:"pointer"}}>上传</span></UploadSingle>,平台审核通过后即可进入当前项目</div>
|
||||
</div>
|
||||
:
|
||||
<p style={{textAlign:'center'}}>您上传的文件正在审核中,通过后才能访问当前项目</p>
|
||||
}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default SpecialModal;
|
|
@ -1,17 +1,9 @@
|
|||
|
||||
.lineH2{line-height:2}
|
||||
/* .t_project_banner {
|
||||
height: 260px;
|
||||
background: url(../Images/banner_list.png) no-repeat center;
|
||||
.t_project_banner {
|
||||
/* height: 260px;
|
||||
background: url(../Images/banner_list.jpg) no-repeat center; */
|
||||
background-color: #050d34;
|
||||
} */
|
||||
.banner_list_img{
|
||||
/* max-height: 260px; */
|
||||
}
|
||||
.banner_list_img img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
}
|
||||
.ProjectListIndex{
|
||||
width: 1200px;
|
||||
|
@ -55,7 +47,7 @@
|
|||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
padding:25px 30px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
border-bottom: 1px solid #E0E0E0;
|
||||
}
|
||||
.list-r-Search{
|
||||
width: 400px;
|
||||
|
@ -77,6 +69,7 @@
|
|||
color: #fff!important;
|
||||
}
|
||||
|
||||
|
||||
/* 列表 */
|
||||
.project-list{
|
||||
padding:0px 30px;
|
||||
|
@ -96,15 +89,10 @@
|
|||
box-shadow:0px 2px 20px 10px rgba(0,0,0,0.03);
|
||||
}
|
||||
.p-r-photo{
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
margin-right: 18px;
|
||||
}
|
||||
.p-r-detail{
|
||||
font-size: 12px;
|
||||
color: #888888;
|
||||
line-height: 16px;
|
||||
margin-right: 22px;
|
||||
}
|
||||
.p-r-Infos{
|
||||
flex: 1;
|
||||
|
@ -227,6 +215,18 @@ line-height: 16px;
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.headerMenu-wrapper li{
|
||||
position: relative;
|
||||
text-align: center;
|
||||
height: 40px;
|
||||
line-height: 28px;
|
||||
border:1px solid transparent;
|
||||
}
|
||||
.headerMenu-wrapper{
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.headerMenu-wrapper li{
|
||||
padding:0px 18px;
|
||||
position: relative;
|
||||
|
@ -243,14 +243,9 @@ line-height: 16px;
|
|||
margin-right: 8px;
|
||||
}
|
||||
.headerMenu-wrapper li a > span{
|
||||
background-color: #676AF1;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
border-radius: 10px;
|
||||
display: block;
|
||||
padding:0px 6px;
|
||||
margin-left: 5px;
|
||||
font-size: 11px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.headerMenu-wrapper li.active{
|
||||
border-radius: 15px;
|
||||
|
@ -268,6 +263,7 @@ line-height: 16px;
|
|||
.ant-tooltip {
|
||||
max-width: fit-content!important;
|
||||
}
|
||||
|
||||
.detail_tag_btn_name{
|
||||
padding:0px 10px;
|
||||
display: flex;
|
||||
|
@ -309,6 +305,7 @@ line-height: 16px;
|
|||
.branch-wrapper > a >i{
|
||||
color: #5091FF;
|
||||
margin-right: 5px;
|
||||
cursor: default;
|
||||
}
|
||||
.branch-wrapper a{
|
||||
display: flex;
|
||||
|
@ -426,6 +423,7 @@ line-height: 16px;
|
|||
padding: 13px 16px!important;
|
||||
}
|
||||
.commitKey{
|
||||
cursor: pointer;
|
||||
border:1px solid #FD7700;
|
||||
background-color:#FFF3DC;
|
||||
color: #FD7700!important;
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import React from 'react';
|
||||
import { AlignCenter , FlexAJ } from '../Component/layout';
|
||||
import User from '../Component/User';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
function Commits({ commits , projectsId , owner }){
|
||||
return(
|
||||
<div className="pb20">
|
||||
{
|
||||
commits.map((item,key)=>{
|
||||
return(
|
||||
<div className="prCommits">
|
||||
<p className="prCreate">{item.created_at}</p>
|
||||
<div className="prInfo">
|
||||
<FlexAJ>
|
||||
<AlignCenter>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="commitKey" style={{marginLeft:0}}>{truncateCommitId(`${item.sha}`)}</Link>
|
||||
<p className="ml15 font-16 color-grey-3 task-hide" style={{maxWidth:"700px"}}>{item.message}</p>
|
||||
</AlignCenter>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(item.sha)}`} className="color-blue">浏览代码</Link>
|
||||
</FlexAJ>
|
||||
<AlignCenter className="mt15">
|
||||
<User url={getImageUrl(`images/${item.committer && item.committer.image_url}`)} name={`${item.committer && item.committer.name}`}></User><span>:提交于{item.time_from_now}</span>
|
||||
</AlignCenter>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Commits;
|
|
@ -0,0 +1,86 @@
|
|||
import React ,{useEffect,useState } from 'react';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import { AlignCenter , FlexAJ } from '../Component/layout';
|
||||
import { Button } from 'antd';
|
||||
import './merge.css';
|
||||
|
||||
function Files({data,history,owner,projectsId}){
|
||||
const [ files , setFiles ] = useState(data && data.files);
|
||||
|
||||
useEffect(()=>{
|
||||
if(data){
|
||||
setFiles(data.files);
|
||||
}
|
||||
},[data])
|
||||
|
||||
function showDown(flag,index,isBin){
|
||||
if(!isBin){
|
||||
var lists = files.concat();
|
||||
lists[index].flag = !flag ? true : false;
|
||||
lists.splice();
|
||||
setFiles(lists);
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
<div>
|
||||
<AlignCenter className="color-grey-9 pb10" style={{borderBottom:"1px solid #eee"}}>
|
||||
<i className="iconfont icon-sanjiaoxing-down mr5"></i>
|
||||
<span>
|
||||
共有<span className="color-grey-3"> {data && data.files_count} 个文件被更改</span>,包括
|
||||
{ data && data.total_addition ? <span className="color-green"> {data && data.total_addition} 次插入</span>:"" }
|
||||
{ data && data.total_addition && data.total_deletion ? " 和 ":""}
|
||||
{ data && data.total_deletion ? <span className="color-red"> {data && data.total_deletion} 次删除</span>:""}
|
||||
</span>
|
||||
</AlignCenter>
|
||||
{
|
||||
files && files.length>0 &&
|
||||
<div>
|
||||
{
|
||||
files.map((item,key)=>{
|
||||
return(
|
||||
<div className="files" key={key}>
|
||||
<FlexAJ className="filesInfo" style={{cursor:item.isBin ? "default":"pointer"}} onClick={()=>showDown(item.flag,key,item.isBin)}>
|
||||
<AlignCenter>
|
||||
{!item.isBin ? <i className={!item.flag?"iconfont icon-xiajiantou font-16 mr15 color-grey-9":"iconfont icon-youjiantou font-16 mr15 color-grey-9"}></i>:""}
|
||||
<i className="iconfont icon-wenjia font-16 mr8 color-grey-9"></i>
|
||||
<span>{item.name}</span>
|
||||
</AlignCenter>
|
||||
<span>
|
||||
<Button className="mr20" onClick={()=>{history.push(`/projects/${owner}/${projectsId}${item.sha ? `/branch/${truncateCommitId(item.sha)}?`:"?"}url=${item.name}`)}}>查看文件</Button>
|
||||
<span className="color-green">+{item.addition}</span>
|
||||
<span className="color-red ml20">-{item.deletion}</span>
|
||||
</span>
|
||||
</FlexAJ>
|
||||
{
|
||||
item.sections && item.sections.length >= 1 && !item.flag &&
|
||||
<div className="filesContent">
|
||||
{
|
||||
item.sections.map((i,k)=>{
|
||||
return(
|
||||
i.lines && i.lines.length>0 && i.lines.map((item,key)=>{
|
||||
return(
|
||||
<div key={k+key} className={(item.type === 2) ? "linesContent add" : item.type === 3 ? "linesContent reduce": item.type===4?"linesContent translate":"linesContent"}>
|
||||
<span className="lines">
|
||||
<span>{item.leftIdx && item.leftIdx !=="0" ? item.leftIdx :"" }</span>
|
||||
<span>{item.rightIdx && item.rightIdx !=="0" ? item.rightIdx :"" }</span>
|
||||
</span>
|
||||
<p>{item.content}</p>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Files;
|
|
@ -214,7 +214,7 @@ class MergeDetail extends Component {
|
|||
)
|
||||
} else {
|
||||
return (
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
<NoneData _html="暂时还没有相关数据!" />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ class MergeItem extends Component {
|
|||
<span className="ml15">
|
||||
<Tag className="pr-branch-tag">
|
||||
<Link
|
||||
to={`/projects/${item.is_original ? item.fork_project_user : owner}/${ item.is_original ? item.fork_project_identifier : projectsId }?branch=${item.pull_request_head}`}
|
||||
to={`/projects/${item.is_original ? item.fork_project_user : owner}/${ item.is_original ? item.fork_project_identifier : projectsId }/branch/${item.pull_request_head}`}
|
||||
className="maxW200px hide-1 ver-middle"
|
||||
>
|
||||
{item.is_original
|
||||
|
@ -116,7 +116,7 @@ class MergeItem extends Component {
|
|||
</span>
|
||||
<Tag className="pr-branch-tag">
|
||||
<Link
|
||||
to={`/projects/${owner}/${projectsId}?branch=${item.pull_request_base}`}
|
||||
to={`/projects/${owner}/${projectsId}/branch/${item.pull_request_base}`}
|
||||
className="maxW200px hide-1 ver-middle"
|
||||
>
|
||||
{/* {item.is_fork ? item.pull_request_base : `${item.author_name}:${item.pull_request_base}`} */}
|
||||
|
|
|
@ -5,6 +5,7 @@ import axios from 'axios';
|
|||
import{ Form , Table , Spin } from 'antd'
|
||||
import { getImageUrl } from 'educoder';
|
||||
import {Link} from "react-router-dom";
|
||||
import { truncateCommitId} from '../common/util';
|
||||
class MergeSubmit extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
@ -36,7 +37,6 @@ class MergeSubmit extends Component{
|
|||
}
|
||||
|
||||
getDetail=()=>{
|
||||
|
||||
const { projectsId , mergeId, owner} = this.props.match.params;
|
||||
const url = `/projects/${owner}/${projectsId}/pull_requests/${mergeId}.json`;
|
||||
axios.get(url).then((result)=>{
|
||||
|
@ -83,8 +83,16 @@ class MergeSubmit extends Component{
|
|||
}).catch((error)=>{console.log(error)})
|
||||
}
|
||||
|
||||
title =()=>{
|
||||
return(
|
||||
<div className="f-wrap-between" style={{alignItems:"center"}}>
|
||||
<span className="font-16">提交列表</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render(){
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { titledata } = this.state;
|
||||
const columns=[{
|
||||
title:"作者",
|
||||
|
@ -102,7 +110,7 @@ class MergeSubmit extends Component{
|
|||
title:"SHA",
|
||||
dataIndex: 'sha',
|
||||
render: (text) => (
|
||||
<span className="commitKey">{text}</span>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${text}`)}`} className="commitKey">{text}</Link>
|
||||
)
|
||||
},{
|
||||
title:"备注",
|
||||
|
@ -118,14 +126,6 @@ class MergeSubmit extends Component{
|
|||
<span>{text}</span>
|
||||
)
|
||||
}]
|
||||
|
||||
const title =()=>{
|
||||
return(
|
||||
<div className="f-wrap-between" style={{alignItems:"center"}}>
|
||||
<span className="font-16">提交列表</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return(
|
||||
<Spin spinning={this.state.isSpin}>
|
||||
|
@ -136,11 +136,9 @@ class MergeSubmit extends Component{
|
|||
showHeader={false}
|
||||
size="small"
|
||||
pagination={false}
|
||||
title={() => title()}
|
||||
title={() => this.title()}
|
||||
/>
|
||||
</Spin>
|
||||
// </div>
|
||||
// </div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, { Component } from "react";
|
||||
import { Tabs } from 'antd';
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { AlignCenter } from '../Component/layout';
|
||||
import axios from "axios";
|
||||
import { getImageUrl } from "educoder";
|
||||
import {
|
||||
|
@ -39,6 +40,9 @@ class MessageCount extends Component {
|
|||
SpinMerge: false,
|
||||
edit_spin: false,
|
||||
pr_status: undefined,
|
||||
pull_request:undefined,
|
||||
|
||||
copyVisible:false,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -47,7 +51,18 @@ class MessageCount extends Component {
|
|||
SpinFlag: true,
|
||||
});
|
||||
this.getDetail();
|
||||
|
||||
// this.clickBody();
|
||||
};
|
||||
clickBody=()=>{
|
||||
document.body.addEventListener('click', e => {
|
||||
let name = e.target.className;
|
||||
if(name.indexOf("notHide")>-1 || name.indexOf("ant-tabs-tab")>-1 || name==="ant-tabs-nav-scroll"){return;}
|
||||
this.setState({
|
||||
copyVisible:false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getDetail = () => {
|
||||
const { projectsId, mergeId, owner } = this.props.match.params;
|
||||
|
@ -55,11 +70,12 @@ class MessageCount extends Component {
|
|||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
if (result && result.data) {
|
||||
this.setState({
|
||||
data: result.data,
|
||||
SpinFlag: false,
|
||||
pr_status: result.data.pull_request.status,
|
||||
pr_status: result.data.pull_request && result.data.pull_request.status,
|
||||
pull_request:result.data.pull_request
|
||||
});
|
||||
} else {
|
||||
this.setState({ SpinFlag: false });
|
||||
|
@ -106,12 +122,12 @@ class MessageCount extends Component {
|
|||
SpinMerge: true,
|
||||
});
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { data, title, body, mergekey, pr_status } = this.state;
|
||||
const url = `/${owner}/${projectsId}/pulls/${data.pull_request.id}/pr_merge.json`;
|
||||
const { title, body, mergekey, pull_request } = this.state;
|
||||
const url = `/${owner}/${projectsId}/pulls/${pull_request.id}/pr_merge.json`;
|
||||
axios
|
||||
.post(url, {
|
||||
project_id: projectsId,
|
||||
id: data.pull_request.id,
|
||||
id: pull_request.id,
|
||||
do: mergekey,
|
||||
body: body,
|
||||
title: title,
|
||||
|
@ -195,9 +211,36 @@ class MessageCount extends Component {
|
|||
};
|
||||
|
||||
commentCtx = (v) => {
|
||||
return <RenderHtml className="break_word_comments imageLayerParent" value={v} />;
|
||||
return <RenderHtml className="break_word_comments imageLayerParent" value={v} url={this.props.history.location}/>;
|
||||
};
|
||||
|
||||
setCopyVisible=(e)=>{
|
||||
e.stopPropagation();
|
||||
this.setState({
|
||||
copyVisible:true
|
||||
})
|
||||
}
|
||||
|
||||
copyItem =()=>{
|
||||
return(
|
||||
<div className="copyTab notHide">
|
||||
<Tabs defaultActiveKey="1" className="notHide" animated={false} size={"small"}>
|
||||
<Tabs.TabPane key="1" tab={<span className="notHide">HTTPS</span>}>{this.returnCopyUrl("https://gitee.com/44886/polhttp.git")}</Tabs.TabPane>
|
||||
<Tabs.TabPane key="2" tab={<span className="notHide">SSH</span>}>{this.returnCopyUrl("https://gitee.com/44886/polssh.git")}</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
returnCopyUrl=(url)=>{
|
||||
return(
|
||||
<div className="df notHide">
|
||||
<Input value={url} className="notHide" disabled={true}/>
|
||||
<Button type="primary" ghost className="ml15 notHide">复制</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { projectsId, mergeId , owner } = this.props.match.params;
|
||||
|
||||
|
@ -208,8 +251,15 @@ class MessageCount extends Component {
|
|||
isSpin,
|
||||
ismesrge,
|
||||
SpinFlag,
|
||||
copyVisible,
|
||||
pull_request
|
||||
} = this.state;
|
||||
const { current_user, projectDetail } = this.props;
|
||||
|
||||
const permission = projectDetail && (projectDetail.permission === "Admin" || projectDetail.permission === "Owner" || projectDetail.permission === "Manager");
|
||||
const userLogin = current_user && current_user.login;
|
||||
const operate = userLogin && projectDetail && pr_status === 0 && permission;
|
||||
|
||||
const menu = (
|
||||
<Menu onClick={(e) => this.getOption(e)}>
|
||||
<Menu.Item key={"merge"} value="合并请求">
|
||||
|
@ -238,13 +288,13 @@ class MessageCount extends Component {
|
|||
<div className="ver-middle">
|
||||
<span className="mr10 ver-middle">
|
||||
<span className="font-18 fwb">
|
||||
{data.issue.subject}
|
||||
{ data.issue && data.issue.subject}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
{data.pull_request && (
|
||||
{pull_request && (
|
||||
<Tag
|
||||
className={`pr_tags_${data.pull_request.pull_request_staus}`}
|
||||
className={`pr_tags_${pull_request.pull_request_staus}`}
|
||||
>
|
||||
{pr_status === 1
|
||||
? "已合并"
|
||||
|
@ -258,10 +308,10 @@ class MessageCount extends Component {
|
|||
<div className="mt15">
|
||||
<Tag className="pr-branch-tag">
|
||||
<Link
|
||||
to={`/projects/${owner}/${data.pull_request.is_original?data.pull_request.identifier:projectsId}?branch=${data.pull_request.head}`}
|
||||
to={`/projects/${owner}/${pull_request.is_original?data.project_identifier:projectsId}/branch/${pull_request.head}`}
|
||||
className="ver-middle"
|
||||
>
|
||||
{data.pull_request.is_original ? data.pull_request.fork_project_user : data.issue.project_author_name}:{data.pull_request.head}
|
||||
{pull_request.is_original ? pull_request.fork_project_user : data.issue.project_author_name}:{pull_request.head}
|
||||
</Link>
|
||||
</Tag>
|
||||
<span className="mr8 ver-middle">
|
||||
|
@ -273,11 +323,11 @@ class MessageCount extends Component {
|
|||
</span>
|
||||
<Tag className="pr-branch-tag">
|
||||
<Link
|
||||
to={`/projects/${owner}/${projectsId}?branch=${data.pull_request.base}`}
|
||||
to={`/projects/${owner}/${projectsId}/branch/${pull_request.base}`}
|
||||
className="ver-middle"
|
||||
>
|
||||
{/* {data.pull_request.is_fork ? data.pull_request.base : `${data.pull_request.pull_request_user}:${data.pull_request.base}`} */}
|
||||
{data.issue.project_author_name}:{data.pull_request.base}
|
||||
{data.issue.project_author_name}:{pull_request.base}
|
||||
</Link>
|
||||
</Tag>
|
||||
</div>
|
||||
|
@ -352,24 +402,29 @@ class MessageCount extends Component {
|
|||
</div>
|
||||
</div>
|
||||
<div className="ml10">
|
||||
<div className="mt15 text-right">
|
||||
{current_user && projectDetail &&
|
||||
pr_status !== 2 &&
|
||||
projectDetail.permission !=="Reporter" && (
|
||||
<div className="mt15 text-right" style={{display:"flex",justifyContent:"flex-end"}}>
|
||||
{/* <span className="composeButton">
|
||||
<Dropdown overlay={this.copyItem()} visible={copyVisible} onClick={(e)=>this.setCopyVisible(e)}>
|
||||
<span>复制</span>
|
||||
</Dropdown>
|
||||
<span>下载为<i className="iconfont icon-sanjiaoxing-down color-blue"></i></span>
|
||||
</span> */}
|
||||
{operate && (
|
||||
<Button
|
||||
type="success"
|
||||
type="green"
|
||||
ghost
|
||||
className="ml20"
|
||||
onClick={()=>{this.props.history.push(`/projects/${owner}/${projectsId}/pulls/${mergeId}/UpdateMerge`);}}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
)}
|
||||
{projectDetail && projectDetail.permission !=="Reporter" && pr_status === 0 && (
|
||||
{operate && (
|
||||
<Button
|
||||
type="danger"
|
||||
ghost
|
||||
onClick={() => this.closedetail()}
|
||||
className="ml15"
|
||||
className="ml20"
|
||||
loading={isSpin}
|
||||
>
|
||||
拒绝
|
||||
|
@ -378,14 +433,12 @@ class MessageCount extends Component {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt15">
|
||||
{data.issue.description &&
|
||||
data.issue.description.length > 0 ? (
|
||||
this.commentCtx(data.issue.description)
|
||||
) : (
|
||||
<span className="color-grey-9 ml3 mr3">没有描述</span>
|
||||
)}
|
||||
</div>
|
||||
{
|
||||
data.issue.description ?
|
||||
<div className="mt15">{this.commentCtx(data.issue.description)}</div>
|
||||
:
|
||||
<p className="color-grey-9 ml3 mr3 mt15">没有描述</p>
|
||||
}
|
||||
</div>
|
||||
<div className="mt15">
|
||||
{pr_status === 2 && (
|
||||
|
@ -473,14 +526,12 @@ class MessageCount extends Component {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className=" main">
|
||||
<MergeFooter
|
||||
footer_type="show"
|
||||
order_id={data && data.issue.id}
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
></MergeFooter>
|
||||
</div>
|
||||
<MergeFooter
|
||||
footer_type={true}
|
||||
order_id={data && data.issue.id}
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
></MergeFooter>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { Component } from "react";
|
||||
import { Input, Select, Button, Spin, Alert } from "antd";
|
||||
import { Input, Select , Spin, Alert } from "antd";
|
||||
import axios from "axios";
|
||||
import "../Order/order.css";
|
||||
import "./merge.css";
|
||||
|
@ -24,21 +24,42 @@ class NewMerge extends Component {
|
|||
merge_head: false, // 是否向fork后的源项目发起合并请求
|
||||
default_message: "必须选择不同的分支",
|
||||
project_id: undefined, // 当前项目的id,也即开始发送合并请求的源项目id
|
||||
merge_project_user: undefined
|
||||
merge_project_user: undefined,
|
||||
oldProject:undefined,//保存选择目标分支、跳转页面后会刷新的project
|
||||
comparesData:undefined,//提交和文件的内容,保存compare接口返回的数据
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
this.getmergelist(projectsId);
|
||||
// 监听回退事件
|
||||
if (window.history && window.history.pushState) {
|
||||
window.addEventListener('popstate', this.handleBack, false);
|
||||
}
|
||||
};
|
||||
|
||||
//获取新建分枝数据
|
||||
componentDidUpdate=(preProps)=>{
|
||||
const { project } = this.props;
|
||||
let oldProject = preProps.project;
|
||||
if(project && oldProject && (oldProject.id !== project.id)){
|
||||
this.compareProject(this.state.id,"master","master");
|
||||
}
|
||||
}
|
||||
// 页面销毁取消监听
|
||||
componentWillUnmount () {
|
||||
window.removeEventListener('popstate', this.handleBack, false);
|
||||
};
|
||||
|
||||
handleBack=()=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
this.getmergelist(projectsId);
|
||||
}
|
||||
|
||||
//获取新建分支数据
|
||||
getmergelist = (projectsId) => {
|
||||
this.setState({isSpin: true})
|
||||
const { owner } = this.props.match.params;
|
||||
|
||||
const url = `/${owner}/${projectsId}/pulls/new.json`;
|
||||
axios
|
||||
.get(url)
|
||||
|
@ -56,6 +77,7 @@ class NewMerge extends Component {
|
|||
this.set_default_pull(result.data.branches);
|
||||
this.set_default_merge(result.data.merge_projects);
|
||||
}
|
||||
this.compareProject(result.data.id,"master","master");
|
||||
this.setState({isSpin: false})
|
||||
})
|
||||
.catch((error) => {
|
||||
|
@ -64,6 +86,32 @@ class NewMerge extends Component {
|
|||
});
|
||||
};
|
||||
|
||||
// 获取compare接口
|
||||
compareProject=(baseid , localBranch , mergeBranch)=>{
|
||||
const { project } = this.props;
|
||||
const { owner , projectsId } = this.props.match.params;
|
||||
let url = `/${owner}/${projectsId}/compare`;
|
||||
if(project){
|
||||
if(baseid === project.id){
|
||||
this.setState({
|
||||
oldProject:project
|
||||
})
|
||||
url += `/${localBranch}...${mergeBranch}.json`;
|
||||
}else{
|
||||
const { oldProject } = this.state;
|
||||
const { author , identifier } =oldProject;
|
||||
url += `/${mergeBranch}...${author && author.login}/${identifier}:${localBranch}.json`;
|
||||
}
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
comparesData:result.data
|
||||
})
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
}
|
||||
|
||||
set_default_pull = (branches) => {
|
||||
if(branches && branches.length>0){
|
||||
let default_pull = branches.filter((e) => e.name === "master")
|
||||
|
@ -117,12 +165,16 @@ class NewMerge extends Component {
|
|||
selectBrach = (type, value) => {
|
||||
this.state[type] = value;
|
||||
this.ischeckmerge();
|
||||
let { id ,merge , pull } = this.state;
|
||||
if(type==="pull"){
|
||||
this.compareProject(id,value,merge);
|
||||
}else{
|
||||
this.compareProject(id,pull,value);
|
||||
}
|
||||
};
|
||||
|
||||
selectProjectName = (value) => {
|
||||
console.log("value",value)
|
||||
const { project_id, projects_names,id } = this.state;
|
||||
const { owner } = this.props.match.params;
|
||||
const { projects_names,id } = this.state;
|
||||
let arr = projects_names && projects_names.filter(item=>item.id===value);
|
||||
let identifier = arr && arr[0].project_id;
|
||||
let login = arr && arr[0].project_user_login;
|
||||
|
@ -138,7 +190,6 @@ class NewMerge extends Component {
|
|||
})
|
||||
this.props.history.push(`/projects/${login}/${identifier}/pulls/new`);
|
||||
this.newMergelist(login,identifier);
|
||||
|
||||
};
|
||||
|
||||
//判断2分支是否可以合并
|
||||
|
@ -146,7 +197,7 @@ class NewMerge extends Component {
|
|||
ischeckmerge = () => {
|
||||
this.setState({ isSpin: true });
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { pull, merge, project_id, merge_head, id } = this.state;
|
||||
const { pull, merge , merge_head, id } = this.state;
|
||||
const url = `/${owner}/${projectsId}/pulls/check_can_merge.json`;
|
||||
axios.post(url, {
|
||||
head: pull,
|
||||
|
@ -194,9 +245,9 @@ class NewMerge extends Component {
|
|||
show_message,
|
||||
default_message,
|
||||
merge_head,
|
||||
projects_names,
|
||||
projects_names,id,comparesData
|
||||
} = this.state;
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
const renderBrances = (list, type) => {
|
||||
if (list && list.length > 0) {
|
||||
return list.map((item, key) => {
|
||||
|
@ -228,29 +279,26 @@ class NewMerge extends Component {
|
|||
return <div dangerouslySetInnerHTML={{ __html: html }}></div>;
|
||||
};
|
||||
let { project } = this.props;
|
||||
console.log("222 ",project);
|
||||
console.log("222111 ",projects_names);
|
||||
return (
|
||||
<div>
|
||||
<div className="main">
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="merge-header width100 inline-block">
|
||||
<div className="width45 pull-left">
|
||||
<div className="width40 pull-left">
|
||||
<div className="color-grey-3 mb10 fwb">源分支:</div>
|
||||
<Input.Group compact className="display-flex">
|
||||
<Select
|
||||
defaultValue={project && project.id}
|
||||
class=" maxW50 hide-1 task-hide"
|
||||
value={id}
|
||||
className="hide-1 task-hide flex1"
|
||||
disabled
|
||||
style={{maxWidth:"200px"}}
|
||||
>
|
||||
{renderProjectNames(projects_names)}
|
||||
</Select>
|
||||
<Select
|
||||
defaultValue={pull}
|
||||
value={pull}
|
||||
onSelect={(e) => this.selectBrach("pull", e)}
|
||||
showSearch
|
||||
className="minW50 merge-flex1"
|
||||
className="merge-flex1 flex1"
|
||||
>
|
||||
{renderBrances(branches, false)}
|
||||
</Select>
|
||||
|
@ -261,24 +309,22 @@ class NewMerge extends Component {
|
|||
className={"iconfont icon-youjiang color-grey-c font-32"}
|
||||
></i>
|
||||
</div>
|
||||
<div className="width45 pull-left">
|
||||
<div className="width40 pull-left">
|
||||
<div>
|
||||
<div className="color-grey-3 mb10 fwb">目标分支:</div>
|
||||
<Input.Group compact className="display-flex">
|
||||
<Select
|
||||
defaultValue={project && project.id}
|
||||
class=" maxW50 hide-1 task-hide"
|
||||
value={project && project.id}
|
||||
className="hide-1 task-hide flex1"
|
||||
onSelect={(e) => this.selectProjectName(e)}
|
||||
style={{maxWidth:"200px"}}
|
||||
>
|
||||
{renderProjectNames(merge_projects)}
|
||||
</Select>
|
||||
<Select
|
||||
defaultValue={merge}
|
||||
value={merge}
|
||||
onSelect={(e) => this.selectBrach("merge", e)}
|
||||
showSearch
|
||||
className="minW50 merge-flex1"
|
||||
className="merge-flex1 flex1"
|
||||
>
|
||||
{renderBrances(merge_branches, merge_head)}
|
||||
</Select>
|
||||
|
@ -297,10 +343,20 @@ class NewMerge extends Component {
|
|||
data={data}
|
||||
merge={merge}
|
||||
pull={pull}
|
||||
files_count={comparesData && comparesData.diff && comparesData.diff.files_count}
|
||||
commits_count={comparesData && comparesData.commits_count}
|
||||
></MergeForm>
|
||||
)}
|
||||
</Spin>
|
||||
</div>
|
||||
<MergeFooter
|
||||
order_id={data && data.issue && data.issue.id}
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
merge={merge}
|
||||
pull={pull}
|
||||
comparesData={comparesData}
|
||||
></MergeFooter>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -37,11 +37,15 @@ class UpdateMerge extends Component {
|
|||
merge: result.data.base,
|
||||
});
|
||||
} else {
|
||||
this.setState({ isSpin: false });
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({ isSpin: false });
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
@ -52,6 +56,7 @@ class UpdateMerge extends Component {
|
|||
<div>
|
||||
<div className="main">
|
||||
<Spin spinning={isSpin}>
|
||||
{" "}
|
||||
{data ? (
|
||||
<div>
|
||||
<div className="merge-header width100 inline-block">
|
||||
|
@ -66,17 +71,17 @@ class UpdateMerge extends Component {
|
|||
defaultValue={data.is_original ? `${data.fork_project_user}:${pull}` : `${pull}`}
|
||||
className="minW50 merge-flex1"
|
||||
disabled
|
||||
></Select>
|
||||
</Input.Group>
|
||||
</div>
|
||||
></Select>{" "}
|
||||
</Input.Group>{" "}
|
||||
</div>{" "}
|
||||
<div className="width10 pull-left text-center mt25">
|
||||
<i
|
||||
className={"iconfont icon-youjiang color-grey-c font-32"}
|
||||
></i>
|
||||
</div>
|
||||
></i>{" "}
|
||||
</div>{" "}
|
||||
<div className="width45 pull-left">
|
||||
<div>
|
||||
<div className="color-grey-3 mb10 fwb">目标分支:</div>
|
||||
<div className="color-grey-3 mb10 fwb"> 目标分支 : </div>{" "}
|
||||
<Input.Group compact className="display-flex">
|
||||
<Button className="merge-header-button maxW50 hide-1 task-hide">
|
||||
{`${data.project_author}/${data.project_name}`}
|
||||
|
@ -85,19 +90,18 @@ class UpdateMerge extends Component {
|
|||
defaultValue={data.is_original ? `${data.project_login}:${merge}` : `${merge}`}
|
||||
className="minW50 merge-flex1"
|
||||
disabled
|
||||
></Select>
|
||||
</Input.Group>
|
||||
</div>
|
||||
</div>
|
||||
></Select>{" "}
|
||||
</Input.Group>{" "}
|
||||
</div>{" "}
|
||||
</div>{" "}
|
||||
</div>
|
||||
|
||||
<MergeForm
|
||||
{...this.props}
|
||||
merge_type="edit"
|
||||
data={data}
|
||||
merge={merge}
|
||||
pull={pull}
|
||||
></MergeForm>
|
||||
></MergeForm>{" "}
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
|
|
|
@ -40,4 +40,161 @@ form .ant-cascader-picker, form .ant-select {
|
|||
}
|
||||
.merge-header-button{
|
||||
background:rgba(241,248,255,1);
|
||||
}
|
||||
.width70{
|
||||
width:70%;
|
||||
}
|
||||
.width30{
|
||||
width:30%;
|
||||
}
|
||||
.width40{
|
||||
width:40%;
|
||||
}
|
||||
.display-flex{
|
||||
display: flex!important;
|
||||
}
|
||||
.w120{
|
||||
width: 120px;
|
||||
}
|
||||
.w240{
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.custom-commit-tabs .ant-tabs-nav .ant-tabs-tab{
|
||||
padding:14px 0px!important;
|
||||
}
|
||||
.custom-commit-tabs .ant-tabs-bar{
|
||||
border-bottom: none;
|
||||
}
|
||||
.custom-commit-tabs .ant-tabs-nav .ant-tabs-tab-active .tabNum{
|
||||
background-color: #EBF4FE;
|
||||
}
|
||||
.custom-commit-tabs .ant-tabs-ink-bar{
|
||||
width: 34px!important;
|
||||
}
|
||||
.tabNum{
|
||||
display: inline-block;
|
||||
margin-left:8px ;
|
||||
border-radius: 10px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
background-color: #eee;
|
||||
padding:0px 9px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 复制-下载为,组合按钮 */
|
||||
.composeButton{
|
||||
display: flex;
|
||||
border:1px solid #5091FF;
|
||||
border-radius: 5px;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
}
|
||||
.composeButton > span{
|
||||
display: block;
|
||||
padding:0px 18px;
|
||||
color: #5091FF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.composeButton > span:hover{
|
||||
background-color: #F1F8FF;
|
||||
}
|
||||
.composeButton > span:first-child{
|
||||
border-radius: 5px 0px 0px 5px;
|
||||
border-right: 1px solid #5091FF;
|
||||
}
|
||||
.ant-btn{
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* 绿色按钮-type="green" */
|
||||
.ant-btn.ant-btn-green{
|
||||
border:1px solid #28BD6C;
|
||||
color: #28BD6C;
|
||||
}
|
||||
.copyTab{
|
||||
min-width: 370px;
|
||||
padding:0px 18px 22px 18px;
|
||||
box-shadow: 0px 2px 10px rgba(0,0,0,0.2);
|
||||
background-color: #fff;
|
||||
}
|
||||
.copyTab .ant-tabs-tab{
|
||||
padding:12px 0px!important;
|
||||
}
|
||||
|
||||
/* pr--提交tab页面 */
|
||||
.prCommits{
|
||||
border:1px solid #ddd;
|
||||
border-top: none;
|
||||
}
|
||||
.prCommits:first-child{
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
.prCommits .prCreate{
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
padding:0px 25px;
|
||||
background-color:#fafafa;
|
||||
color:#333;
|
||||
font-size: 16px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
.prCommits .prInfo{
|
||||
padding:20px 25px;
|
||||
}
|
||||
/* pr-文件修改信息页面 */
|
||||
.files{
|
||||
border:1px solid #ddd;
|
||||
margin-top: 15px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.filesInfo{
|
||||
padding:10px 15px;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
.filesContent{
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
.linesContent{
|
||||
display: flex;
|
||||
min-height: 30px;
|
||||
line-height: 30px;
|
||||
color: #333;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.linesContent > p{
|
||||
flex:1;
|
||||
}
|
||||
.linesContent .lines{
|
||||
display: flex;
|
||||
border-right: 1px solid #ddd;
|
||||
width: 100px;
|
||||
padding: 0px 8px;
|
||||
box-sizing: border-box;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.linesContent .lines > span:first-child{
|
||||
margin-right: 0px;
|
||||
}
|
||||
.linesContent .lines > span{
|
||||
width: 50%;
|
||||
text-align: right;
|
||||
display: block;
|
||||
color: #888;
|
||||
}
|
||||
.linesContent.translate{
|
||||
background-color:#F1F8FF;
|
||||
}
|
||||
.linesContent.translate .lines > span{
|
||||
border-right: 1px solid transparent;
|
||||
}
|
||||
.linesContent.reduce{
|
||||
background-color:rgba(247, 48, 48, 0.15);;
|
||||
}
|
||||
.linesContent.add{
|
||||
background: rgba(48, 232, 132, 0.15);
|
||||
}
|
|
@ -423,7 +423,7 @@ class merge extends Component {
|
|||
</Spin>
|
||||
</div>
|
||||
) : (
|
||||
<NoneData _html="暂时还没有相关数据哦!" projectsId={projectsId} owner={owner} />
|
||||
<NoneData _html="暂时还没有相关数据!" projectsId={projectsId} owner={owner} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,45 +1,169 @@
|
|||
import React, { Component } from "react";
|
||||
import { Tabs, Empty } from "antd";
|
||||
import { Tabs, Spin } from "antd";
|
||||
import "../Order/order.css";
|
||||
import "./merge.css";
|
||||
import CodesCommit from "../Main/CoderRootCommit";
|
||||
import Commits from "./Commits";
|
||||
import Comments from "../comments/comments";
|
||||
|
||||
import Files from "./Files";
|
||||
import axios from 'axios';
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
class MergeFooter extends Component {
|
||||
constructor(props) {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {};
|
||||
this.state={
|
||||
pageData:undefined,
|
||||
commitsData:undefined,
|
||||
filesData:undefined,
|
||||
isSpin:false,
|
||||
activeKey:"1",
|
||||
commitCount:0,
|
||||
filesCount:0
|
||||
}
|
||||
}
|
||||
componentDidMount=()=>{
|
||||
const { footer_type ,data } = this.props;
|
||||
if(footer_type){
|
||||
const { projectsId , owner , mergeId } = this.props.match.params;
|
||||
this.getCommit(owner,projectsId,mergeId);
|
||||
this.getFile(owner,projectsId,mergeId);
|
||||
}
|
||||
this.setState({
|
||||
activeKey:footer_type ? "1" : "2",
|
||||
commitCount:data && data.commits_count,
|
||||
filesCount:data && data.files_count
|
||||
})
|
||||
}
|
||||
componentDidUpdate=(prevProps)=>{
|
||||
const { comparesData } = this.props;
|
||||
const { footer_type } = this.props;
|
||||
if(footer_type){
|
||||
const { data } = this.props;
|
||||
if(data !== prevProps.data){
|
||||
this.setState({
|
||||
commitCount:data && data.commits_count,
|
||||
filesCount:data && data.files_count
|
||||
})
|
||||
}
|
||||
}
|
||||
if(comparesData !== prevProps.comparesData){
|
||||
this.setState({
|
||||
activeKey:footer_type ? "1" : "2"
|
||||
})
|
||||
this.changeTab(footer_type ? "1" : "2");
|
||||
}
|
||||
}
|
||||
|
||||
changeTab=(index)=>{
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
this.setState({
|
||||
activeKey:index
|
||||
})
|
||||
const { footer_type , comparesData } = this.props;
|
||||
const { projectsId , owner , mergeId } = this.props.match.params;
|
||||
|
||||
if(footer_type){
|
||||
if(index === "2"){
|
||||
this.getCommit(owner,projectsId,mergeId);
|
||||
}else if(index === "3"){
|
||||
this.getFile(owner,projectsId,mergeId);
|
||||
}else{
|
||||
this.setState({
|
||||
isSpin:false
|
||||
})
|
||||
}
|
||||
}else{
|
||||
this.setState({
|
||||
commitsData:comparesData.commits,
|
||||
filesData:comparesData.diff,
|
||||
commitCount:comparesData.commits_count,
|
||||
filesCount:comparesData.diff && comparesData.diff.files_count,
|
||||
isSpin:false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
getCommit =(owner,projectsId,mergeId)=>{
|
||||
const url = `/${owner}/${projectsId}/pulls/${mergeId}/commits.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
commitsData:result.data.commits,
|
||||
isSpin:false,
|
||||
commitCount:result.data.commits_count
|
||||
})
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
getFile =(owner,projectsId,mergeId)=>{
|
||||
const url = `/${owner}/${projectsId}/pulls/${mergeId}/files.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
filesData:result.data,
|
||||
isSpin:false,
|
||||
filesCount:result.data.files_count,
|
||||
})
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
render() {
|
||||
const { footer_type, order_id } = this.props;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
|
||||
const { footer_type, order_id, data , comparesData } = this.props;
|
||||
let { isSpin , activeKey , filesCount, commitCount , filesData , commitsData } = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Tabs
|
||||
defaultActiveKey={footer_type === "show" ? "1" : "2"}
|
||||
className="custom-commit-tabs"
|
||||
>
|
||||
{
|
||||
footer_type === "show" &&
|
||||
<TabPane tab={<span className="ml-3 font-16">评论</span>} key="1">
|
||||
<Comments
|
||||
order_id={order_id}
|
||||
showNotification={this.props.showNotification}
|
||||
only_show_content={true}
|
||||
{...this.props}
|
||||
/>
|
||||
</TabPane>
|
||||
}
|
||||
|
||||
{/* <TabPane tab={<span className="ml-3 font-16">提交</span>} key="2">
|
||||
<CodesCommit {...this.props} main_class="pd10"></CodesCommit>
|
||||
</TabPane> */}
|
||||
{/* <TabPane tab={<span className="ml-3 font-16">文件</span>} key="3">
|
||||
<Empty />
|
||||
</TabPane> */}
|
||||
</Tabs>
|
||||
!footer_type && !comparesData || (comparesData && ((comparesData.commits && comparesData.commits.length===0)||(comparesData && !comparesData.diff)) )?"":
|
||||
<div className="main" style={{paddingTop:"0px"}}>
|
||||
<Spin spinning={isSpin}>
|
||||
<Tabs
|
||||
activeKey={activeKey}
|
||||
className="custom-commit-tabs"
|
||||
animated={false}
|
||||
onChange={this.changeTab}
|
||||
>
|
||||
{
|
||||
footer_type &&
|
||||
<TabPane
|
||||
tab={
|
||||
<span><span className="font-16">评论</span>
|
||||
{data && parseInt(data.comments_count) > 0 && <span className="tabNum">{data.comments_count}</span>}
|
||||
</span>
|
||||
} key="1">
|
||||
<Comments
|
||||
order_id={order_id}
|
||||
showNotification={this.props.showNotification}
|
||||
only_show_content={true}
|
||||
{...this.props}
|
||||
/>
|
||||
</TabPane>
|
||||
}
|
||||
{
|
||||
commitsData && commitsData.length > 0 &&
|
||||
<TabPane tab={<span><span className="font-16">提交</span>
|
||||
{commitCount > 0 && <span className="tabNum">{commitCount}</span>}
|
||||
</span>} key="2">
|
||||
<Commits {...this.props} commits={commitsData} projectsId={projectsId} owner={owner}></Commits>
|
||||
</TabPane>
|
||||
}
|
||||
{
|
||||
filesData && filesData.files && filesData.files.length>0 &&
|
||||
<TabPane tab={
|
||||
<span><span className="font-16">文件</span>
|
||||
{filesCount > 0 && <span className="tabNum">{filesCount}</span>}
|
||||
</span>
|
||||
} key="3">
|
||||
<Files {...this.props} data={filesData} projectsId={projectsId} owner={owner}/>
|
||||
</TabPane>
|
||||
}
|
||||
|
||||
</Tabs>
|
||||
</Spin>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ class MergeForm extends Component {
|
|||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
const { projectsId, mergeId , owner } = this.props.match.params;
|
||||
const { merge, pull, merge_type, data } = this.props;
|
||||
const { merge, pull, merge_type, data , commits_count , files_count } = this.props;
|
||||
if (values.issue_tag_ids && values.issue_tag_ids.length > 0) {
|
||||
values.issue_tag_ids = [parseInt(values.issue_tag_ids)];
|
||||
} else {
|
||||
|
@ -154,7 +154,9 @@ class MergeForm extends Component {
|
|||
base: merge,
|
||||
is_original: data && data.is_original,
|
||||
fork_project_id: data && data.fork_project_id,
|
||||
merge_user_login: data && data.merge_user_login
|
||||
merge_user_login: data && data.merge_user_login,
|
||||
files_count,
|
||||
commits_count
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
|
@ -221,7 +223,7 @@ class MergeForm extends Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { merge_type, data } = this.props;
|
||||
const { merge_type } = this.props;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const { projectsId, mergeId ,owner } = this.props.match.params;
|
||||
const {
|
||||
|
@ -264,7 +266,7 @@ class MergeForm extends Component {
|
|||
</Form.Item>
|
||||
<MDEditor
|
||||
placeholder={"请输入合并请求的描述..."}
|
||||
height={350}
|
||||
height={450}
|
||||
mdID={"merge-new-description"}
|
||||
initValue={desc}
|
||||
onChange={this.onContentChange}
|
||||
|
|
|
@ -38,7 +38,9 @@ class Index extends Component {
|
|||
project_language_name: undefined,
|
||||
project_category_name: undefined,
|
||||
license_name: undefined,
|
||||
ignore_name: undefined
|
||||
ignore_name: undefined,
|
||||
|
||||
licenseForDisabled:undefined
|
||||
}
|
||||
}
|
||||
componentDidMount = () => {
|
||||
|
@ -114,7 +116,7 @@ class Index extends Component {
|
|||
_data = data.filter(item => item.name.toLowerCase().indexOf(name.toLowerCase()) > -1);
|
||||
}
|
||||
let list = _data && _data.map((item) => (
|
||||
<Option key={item.id} value={item.name}>
|
||||
<Option key={item.id} value={item.name} onClick={()=>this.selectSerect(item.is_secret)}>
|
||||
{item.name}
|
||||
</Option>
|
||||
));
|
||||
|
@ -124,6 +126,17 @@ class Index extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
selectSerect=(flag)=>{
|
||||
if(flag){
|
||||
this.props.form.setFieldsValue({
|
||||
private:true
|
||||
})
|
||||
}
|
||||
this.setState({
|
||||
licenseForDisabled:flag
|
||||
})
|
||||
}
|
||||
|
||||
subMitFrom = () => {
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
|
@ -168,7 +181,8 @@ class Index extends Component {
|
|||
}
|
||||
|
||||
ChangePlatform = (value, e, name, list) => {
|
||||
this.setOptionsList(list, name, value)
|
||||
this.setOptionsList(list, name, value);
|
||||
|
||||
this.setState({
|
||||
[name + "_id"]: e.key,
|
||||
[name + "_name"]: value,
|
||||
|
@ -249,6 +263,7 @@ class Index extends Component {
|
|||
project_category_list,
|
||||
license_list,
|
||||
ignore_list,
|
||||
licenseForDisabled,
|
||||
|
||||
mirrorCheck
|
||||
} = this.state;
|
||||
|
@ -434,8 +449,8 @@ class Index extends Component {
|
|||
style={{ margin: "0px" }}
|
||||
className="privatePart"
|
||||
>
|
||||
{getFieldDecorator('private')(
|
||||
<Checkbox value="limit">将项目设为私有<span className="ml15 font-13 color-grey-9">(只有项目所有人或拥有权限的项目成员才能看到)</span></Checkbox>
|
||||
{getFieldDecorator('private',{valuePropName:"checked"})(
|
||||
<Checkbox value="limit" disabled={licenseForDisabled}>将项目设为私有<span className="ml15 font-13 color-grey-9">(只有项目所有人或拥有权限的项目成员才能看到)</span></Checkbox>
|
||||
)}
|
||||
</Form.Item >
|
||||
{
|
||||
|
|
|
@ -51,9 +51,7 @@ class Index extends Component {
|
|||
<div className="grid-item">
|
||||
<div className="setInputAddon">
|
||||
<Input
|
||||
addonBefore={`/${
|
||||
projectDetail && projectDetail.identifier
|
||||
}${urlroot}/`}
|
||||
addonBefore={`/${ projectDetail && projectDetail.identifier }${urlroot}/`}
|
||||
value={filename}
|
||||
onChange={this.changeFileName}
|
||||
placeholder="命名文件..."
|
||||
|
|
|
@ -54,14 +54,12 @@ class UserSubmitComponent extends Component {
|
|||
const { getTopCount } = this.props;
|
||||
getTopCount && getTopCount(values.branchname);
|
||||
}
|
||||
let url = values.branchname
|
||||
? `/projects/${owner}/${projectsId}?branch=${values.branchname}`
|
||||
: `/projects/${owner}/${projectsId}`;
|
||||
let url = `/projects/${owner}/${projectsId}${values.branchname ? `/branch/${values.branchname}`: (branch ? `/branch/${branch}` : "")}`;
|
||||
this.props.history.push(url);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({ isSpin: false });
|
||||
this.setState({ isSpin : false });
|
||||
console.log(error);
|
||||
});
|
||||
} else {
|
||||
|
@ -73,7 +71,7 @@ class UserSubmitComponent extends Component {
|
|||
// 确认修改文件
|
||||
UpdateFile = () => {
|
||||
this.setState({ isSpin: true });
|
||||
const { branch, detail, content, filepath } = this.props;
|
||||
const { branch, detail, content , currentBranch } = this.props;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { submitType } = this.state;
|
||||
const url = `/${owner}/${projectsId}/update_file.json`;
|
||||
|
@ -82,7 +80,7 @@ class UserSubmitComponent extends Component {
|
|||
axios
|
||||
.put(url, {
|
||||
filepath: detail.path,
|
||||
branch: branch,
|
||||
branch: submitType === "1" ? undefined : (currentBranch || branch),
|
||||
new_branch: submitType === "1" ? values.branchname : undefined,
|
||||
content: content,
|
||||
sha: detail.sha,
|
||||
|
@ -91,12 +89,9 @@ class UserSubmitComponent extends Component {
|
|||
.then((result) => {
|
||||
this.setState({ isSpin: false });
|
||||
if (result.data && result.data.status === 1) {
|
||||
let url = values.branchname
|
||||
? `/projects/${owner}/${projectsId}?branch=${values.branchname}`
|
||||
: `/projects/${owner}/${projectsId}`;
|
||||
|
||||
let url = `/projects/${owner}/${projectsId}${(values.branchname ? `/branch/${values.branchname}` : ((currentBranch || branch) ? `/branch/${currentBranch || branch}`:""))}`;
|
||||
this.props.history.push(url);
|
||||
this.props.showNotification("修改成功!");
|
||||
this.props.showNotification("文件修改成功!");
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
@ -115,7 +110,7 @@ class UserSubmitComponent extends Component {
|
|||
|
||||
const { branch, projectsId , owner } = this.props.match.params;
|
||||
|
||||
const { current_user, filepath, projectDetail } = this.props;
|
||||
const { current_user, filepath, projectDetail , currentBranch } = this.props;
|
||||
const { editor_type } = this.props;
|
||||
return (
|
||||
<div>
|
||||
|
@ -175,12 +170,11 @@ class UserSubmitComponent extends Component {
|
|||
>
|
||||
<Radio value="0" className="mb10">
|
||||
<i className="iconfont icon-banbenku font-16 mr5"></i>
|
||||
直接提交至<span className="color-orange">{branch}</span>分支
|
||||
直接提交至<span className="color-orange">{currentBranch || branch}</span>分支
|
||||
</Radio>
|
||||
<Radio value="1">
|
||||
<Icon type="pull-request" className="mr5" />
|
||||
为此提交创建一个<span className="font-bd">新的分支</span>
|
||||
并发起合并请求
|
||||
为此提交创建一个<span className="font-bd">新的分支</span>并发起合并请求
|
||||
</Radio>
|
||||
</Radio.Group>
|
||||
{
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React, { Component } from "react";
|
||||
import Editor from "react-monaco-editor";
|
||||
|
||||
import UserSubmitComponent from "./UserSubmitComponent";
|
||||
|
||||
import "./index.css";
|
||||
|
@ -21,7 +20,7 @@ class m_editor extends Component {
|
|||
|
||||
render() {
|
||||
const { editorValue } = this.state;
|
||||
const { readOnly, editorType, language } = this.props;
|
||||
const { readOnly, editorType, language , currentBranch } = this.props;
|
||||
const editor_options = {
|
||||
lineNumbers: "on",
|
||||
wordWrap: true, //强制换行
|
||||
|
@ -29,6 +28,7 @@ class m_editor extends Component {
|
|||
lineHeight: 24,
|
||||
renderLineHighlight: "line",
|
||||
revealHorizontalRightPadding: 5,
|
||||
placeholder:"请输入内容",
|
||||
readOnly: readOnly,
|
||||
cursorStyle: readOnly ? "underline-thin" : "line",
|
||||
folding: true,
|
||||
|
@ -46,16 +46,17 @@ class m_editor extends Component {
|
|||
<div>
|
||||
<div className="branchTable">
|
||||
<Editor
|
||||
height="600px"
|
||||
height="400px"
|
||||
language={language ? language : "plaintext"}
|
||||
theme={"vs-grey"}
|
||||
defaultValue=""
|
||||
placeholder="请输入内容"
|
||||
value={editorValue}
|
||||
options={editor_options}
|
||||
onChange={this.changeEditor}
|
||||
editorWillMount={this.editorWillMount}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{!readOnly && (
|
||||
<UserSubmitComponent
|
||||
{...this.props}
|
||||
|
@ -63,6 +64,7 @@ class m_editor extends Component {
|
|||
filepath={`${this.props.filepath}`}
|
||||
content={editorValue}
|
||||
editor_type={editorType}
|
||||
currentBranch={currentBranch}
|
||||
></UserSubmitComponent>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -53,7 +53,6 @@ class UploadFile extends Component {
|
|||
{...this.props}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<UserSubmitComponent
|
||||
{...this.props}
|
||||
|
|
|
@ -182,7 +182,7 @@ class Detail extends Component {
|
|||
};
|
||||
|
||||
commentCtx = (v) => {
|
||||
return <RenderHtml className="break_word_comments imageLayerParent" value={v} />;
|
||||
return <RenderHtml className="break_word_comments imageLayerParent" value={v} url={this.props.history.location} />;
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -309,8 +309,10 @@ class Detail extends Component {
|
|||
<div className="list-left list-left-padding">
|
||||
<div className="list-right-item-padding background-f boder-4">
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">分支:</span>
|
||||
<span>{data && data.branch_name ? data.branch_name : "--"}</span>
|
||||
<span className="issue_detail_info">负责人:</span>
|
||||
<span>
|
||||
{data && data.assign_user_name ? data.assign_user_name : "--"}
|
||||
</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">标签:</span>
|
||||
|
@ -344,12 +346,6 @@ class Detail extends Component {
|
|||
<span className="issue_detail_info">分类:</span>
|
||||
<span>{data && data.tracker ? data.tracker : "--"}</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">负责人:</span>
|
||||
<span>
|
||||
{data && data.assign_user_name ? data.assign_user_name : "--"}
|
||||
</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">开始日期:</span>
|
||||
<span>{data && data.start_date ? data.start_date : "--"}</span>
|
||||
|
@ -363,6 +359,10 @@ class Detail extends Component {
|
|||
<span className="issue_detail_info">完成度:</span>
|
||||
<span>{data && data.done_ratio ? data.done_ratio : "--"}</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">分支:</span>
|
||||
<span>{data && data.branch_name ? data.branch_name : "--"}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -251,7 +251,7 @@ class Milepost extends Component {
|
|||
})
|
||||
}
|
||||
</div>
|
||||
: <NoneData _html="暂时还没有相关数据哦!" />
|
||||
: <NoneData _html="暂时还没有相关数据!" />
|
||||
}
|
||||
{
|
||||
data && data.versions_count > limit ?
|
||||
|
|
|
@ -271,7 +271,7 @@ class MilepostDetail extends Component {
|
|||
<div className="setItemStyle">
|
||||
{
|
||||
search_count === 0 ?
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
<NoneData _html="暂时还没有相关数据!" />
|
||||
:
|
||||
issues && issues.length>0 && issues.map((item,key)=>{
|
||||
return(
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Popconfirm, Tag } from 'antd'
|
||||
import { Popconfirm } from 'antd'
|
||||
import { TagInfo } from '../Utils/TagColor';
|
||||
|
||||
|
||||
class OrderItem extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -54,7 +52,7 @@ class OrderItem extends Component {
|
|||
{current_user && current_user.login && checkbox}
|
||||
<div className="flex-1">
|
||||
<p className="mb10 df" style={{alignItems:"center"}}>
|
||||
<Link to={`/projects/${owner}/${projectsId}/issues/${item.id}/detail`} target="_blank" title={item.name} className="hide-1 font-16 color-grey-3 lineh-30 mr10" style={{maxWidth:"300px"}}>{item.name}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/issues/${item.id}/detail`} target="_blank" title={item.name} className="hide-1 font-16 color-grey-3 lineh-30 mr10" style={{maxWidth:"370px"}}>{item.name}</Link>
|
||||
{TagInfo(item.priority,"mr10")}
|
||||
</p>
|
||||
<p className="color-grey-6 font-12">
|
||||
|
|
|
@ -362,7 +362,7 @@ class Tags extends Component {
|
|||
</div>
|
||||
</div>
|
||||
:
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
<NoneData _html="暂时还没有相关数据!" />
|
||||
}
|
||||
{
|
||||
data && data.issue_tags_count > limit ?
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
padding-left: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.attachment-list-div:hover {
|
||||
background-color: #e6f7ff;
|
||||
}
|
||||
.attachment-list-div:hover .attachment-list-delete {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.searchBanner{
|
||||
display: flex;
|
||||
|
|
|
@ -52,12 +52,9 @@ class NewMilepost extends Component {
|
|||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/milestones.json`;
|
||||
let time = undefined;
|
||||
if (this.state.selectedValue === undefined) {
|
||||
|
||||
} else {
|
||||
time = this.state.selectedValue.format("YYYY-MM-DD")
|
||||
if (this.state.selectedValue) {
|
||||
time = this.state.selectedValue.format("YYYY-MM-DD");
|
||||
}
|
||||
|
||||
axios.post(url, {
|
||||
...values,
|
||||
project_id: projectsId,
|
||||
|
@ -68,10 +65,8 @@ class NewMilepost extends Component {
|
|||
this.setState({ isSpin: false })
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/milestones`);
|
||||
}
|
||||
|
||||
}).catch(error => {
|
||||
this.setState({ isSpin: false })
|
||||
console.log(error);
|
||||
})
|
||||
}else{
|
||||
this.setState({ isSpin: false })
|
||||
|
@ -105,7 +100,7 @@ class NewMilepost extends Component {
|
|||
required: true, message: '请输入标题'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder="标题" />
|
||||
<Input placeholder="标题" autoComplete="off"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
|
|
@ -187,6 +187,9 @@
|
|||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.topWrapper_select.wrapperStyle li{
|
||||
width:90px;
|
||||
}
|
||||
.topWrapper_select li {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
@ -222,7 +225,7 @@
|
|||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 16px 20px;
|
||||
padding: 16px 0px 16px 20px;
|
||||
}
|
||||
.issueNo {
|
||||
padding: 0px 5px;
|
||||
|
@ -383,7 +386,7 @@
|
|||
}
|
||||
/* 任务标签列表 */
|
||||
.tagList > div {
|
||||
border-bottom: 1px dashed #f4f4f4;
|
||||
border-bottom: 1px dashed #efefef;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 15px 0px;
|
||||
|
@ -561,12 +564,6 @@ a.issue-type-button.active:hover {
|
|||
.attachment-list-delete {
|
||||
display: none;
|
||||
}
|
||||
.attachment-list-div:hover {
|
||||
background-color: #e6f7ff;
|
||||
}
|
||||
.attachment-list-div:hover .attachment-list-delete {
|
||||
display: block !important;
|
||||
}
|
||||
.attachment-list-a {
|
||||
color: rgba(0, 0, 0, 0.65) !important;
|
||||
}
|
||||
|
|
|
@ -212,7 +212,10 @@ class order extends Component {
|
|||
<Menu.Item
|
||||
key={item.id}
|
||||
onClick={(e) => this.getOption(e, id, item.name, toGet)}
|
||||
style={{textAlign:item.color ? "left" :"center",padding:"6px 15px"}}
|
||||
>
|
||||
{/* 标签前面的颜色tag */}
|
||||
{item.color && <span className="tagColor" style={{backgroundColor:`${item.color}`}}></span>}
|
||||
{item.name}
|
||||
</Menu.Item>
|
||||
);
|
||||
|
@ -239,6 +242,8 @@ class order extends Component {
|
|||
this.setState({
|
||||
search: value,
|
||||
isSpin: true,
|
||||
checkedValue:[],
|
||||
all:undefined
|
||||
});
|
||||
const { status_type } = this.state;
|
||||
|
||||
|
@ -258,7 +263,10 @@ class order extends Component {
|
|||
assigned_to_ids: "负责人",
|
||||
status_ids: "状态",
|
||||
done_ratios: "完成度",
|
||||
fixed_version_ids:"里程碑",
|
||||
paix: "排序",
|
||||
checkedValue:[],
|
||||
all:undefined
|
||||
});
|
||||
this.state.select_params = {
|
||||
search: undefined,
|
||||
|
@ -324,19 +332,19 @@ class order extends Component {
|
|||
id: id,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
const { status_type } = this.state;
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
const { status_type } = this.state;
|
||||
|
||||
this.getIssueList(status_type);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
this.getIssueList(status_type);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
islogin() {
|
||||
islogin=()=>{
|
||||
this.props.showLoginDialog();
|
||||
}
|
||||
renderNew =()=>{
|
||||
|
@ -349,9 +357,7 @@ class order extends Component {
|
|||
)
|
||||
}else{
|
||||
return(
|
||||
<a className="topWrapper_btn ml10" onClick={this.islogin}>
|
||||
+ 创建任务
|
||||
</a>
|
||||
<a className="topWrapper_btn ml10" onClick={this.islogin}>+ 创建任务</a>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -471,7 +477,7 @@ class order extends Component {
|
|||
})
|
||||
const { checkedValue } = this.state;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/projects/${owner}/${projectsId}/issues/clean.json`;
|
||||
const url = `/${owner}/${projectsId}/issues/clean.json`;
|
||||
axios.post(url, {
|
||||
ids: checkedValue
|
||||
}).then(result => {
|
||||
|
@ -608,7 +614,7 @@ class order extends Component {
|
|||
</div>
|
||||
{
|
||||
checkedValue && checkedValue.length > 0 ?
|
||||
<ul className="topWrapper_select">
|
||||
<ul className="topWrapper_select wrapperStyle">
|
||||
<li className="mr20">
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
|
@ -628,7 +634,7 @@ class order extends Component {
|
|||
</li>
|
||||
<li className="mr20">
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
className="topWrapperSelect wrapperStyle"
|
||||
overlay={this.renderMenu(
|
||||
issue_chosen && issue_chosen.issue_version,
|
||||
"更换里程碑",
|
||||
|
@ -645,7 +651,7 @@ class order extends Component {
|
|||
</li>
|
||||
<li className="mr20">
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
className="topWrapperSelect wrapperStyle"
|
||||
overlay={this.renderMenu(
|
||||
issue_chosen && issue_chosen.issue_status,
|
||||
"修改状态",
|
||||
|
@ -802,7 +808,7 @@ class order extends Component {
|
|||
|
||||
</div>
|
||||
{search_count === 0 ? (
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
<NoneData _html="暂时还没有相关数据!" />
|
||||
) : (
|
||||
<div style={{ minHeight: "500px" }}>
|
||||
<Checkbox.Group name="issues" onChange={this.checkIssues} value={checkedValue} style={{ width: "100%" }}>
|
||||
|
|
|
@ -34,6 +34,8 @@ class order_form extends Component {
|
|||
subject: "",
|
||||
get_attachments: undefined,
|
||||
show_token: false,
|
||||
cannot_edit: false,
|
||||
issue_current_user: true
|
||||
};
|
||||
}
|
||||
componentDidUpdate=(prevPros)=>{
|
||||
|
@ -116,7 +118,7 @@ class order_form extends Component {
|
|||
return list.map((item, key) => {
|
||||
return (
|
||||
<Option key={key + 1} value={String(item.id)}>
|
||||
{item.name}
|
||||
{item.color && <span className="tagColor" style={{backgroundColor:`${item.color}`}}></span>}{item.name}
|
||||
</Option>
|
||||
);
|
||||
});
|
||||
|
@ -263,6 +265,7 @@ class order_form extends Component {
|
|||
});
|
||||
this.setState({
|
||||
done_ratio: "0",
|
||||
issue_current_user: true,
|
||||
});
|
||||
} else if (e === "3") {
|
||||
this.props.form.setFieldsValue({
|
||||
|
@ -270,6 +273,11 @@ class order_form extends Component {
|
|||
});
|
||||
this.setState({
|
||||
done_ratio: "100",
|
||||
issue_current_user: true,
|
||||
});
|
||||
}else if (e === "5") {
|
||||
this.setState({
|
||||
issue_current_user: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -371,19 +379,13 @@ class order_form extends Component {
|
|||
</div>
|
||||
<div className="list-left list-left-padding issue-edit-form-right">
|
||||
<div className="pd20 background-f issue-form-right">
|
||||
<Form.Item>
|
||||
{getFieldDecorator("branch_name", {
|
||||
rules: []
|
||||
})(
|
||||
<Form.Item label="指派成员">
|
||||
{getFieldDecorator("assigned_to_id", {rules: []})(
|
||||
<Select>
|
||||
<Option value={""}>分支未指定</Option>
|
||||
{branches && branches.length > 0 && branches.map((item, key) => {
|
||||
return (
|
||||
<Option value={item} key={key}>
|
||||
{item}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
<Option value={""}>未指派成员</Option>
|
||||
{this.renderSelect(
|
||||
issue_chosen && issue_chosen.assign_user
|
||||
)}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
|
@ -452,16 +454,6 @@ class order_form extends Component {
|
|||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="指派成员">
|
||||
{getFieldDecorator("assigned_to_id", {rules: []})(
|
||||
<Select>
|
||||
<Option value={""}>未指派成员</Option>
|
||||
{this.renderSelect(
|
||||
issue_chosen && issue_chosen.assign_user
|
||||
)}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="开始日期">
|
||||
<DatePicker
|
||||
value={start_date ? moment(start_date, "YYYY-MM-DD") : null}
|
||||
|
@ -485,28 +477,22 @@ class order_form extends Component {
|
|||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
{/* <Form.Item label="是否上链">
|
||||
<Switch
|
||||
checkedChildren="是"
|
||||
unCheckedChildren="否"
|
||||
defaultChecked={false}
|
||||
checked={issue_type && issue_type === "2"}
|
||||
onChange={this.change_issue_type}
|
||||
/>
|
||||
<Form.Item label="指定分支">
|
||||
{getFieldDecorator("branch_name", {
|
||||
rules: []
|
||||
})(
|
||||
<Select>
|
||||
<Option value={""}>分支未指定</Option>
|
||||
{branches && branches.length > 0 && branches.map((item, key) => {
|
||||
return (
|
||||
<Option value={item} key={key}>
|
||||
{item}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
{(show_token || (issue_type && issue_type === "2")) && (
|
||||
<Form.Item label="token">
|
||||
{getFieldDecorator("token", {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写token值",
|
||||
},
|
||||
],
|
||||
initialValue: token,
|
||||
})(<Input placeholder="请填写token值" />)}
|
||||
</Form.Item>
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import React , { useState } from 'react';
|
||||
import React , { useEffect, useState } from 'react';
|
||||
import SelectBranch from '../Branch/Select';
|
||||
import Title from '../Component/Title';
|
||||
import styled from 'styled-components';
|
||||
import { Blueline , FlexAJ , NumUl , GreenUnder , AlignCenter , WhiteBack } from '../Component/layout';
|
||||
import { AlignCenter , WhiteBack , FlexAJ } from '../Component/layout';
|
||||
import axios from 'axios';
|
||||
import { Button, Select , Pagination } from 'antd';
|
||||
import { getBranch } from '../GetData/getData';
|
||||
|
||||
const Div = styled.div`{
|
||||
padding:20px 30px;
|
||||
|
@ -10,19 +13,92 @@ const Div = styled.div`{
|
|||
}`
|
||||
|
||||
export default ((props)=>{
|
||||
const LIMIT = 15;
|
||||
const [ branch , setBranch ] = useState("master");
|
||||
const [ branchList , setBranchList ] = useState(undefined);
|
||||
const [ protectBranch , setProtectBranch ] = useState("master");
|
||||
const [ protectBranchList , setProtectBranchList ] = useState(undefined);
|
||||
|
||||
const [ count , setCount ] = useState(0);
|
||||
const [ page , setPage ] = useState(1);
|
||||
let defaultBranch = props.defaultBranch;
|
||||
|
||||
useEffect(()=>{
|
||||
if(defaultBranch){
|
||||
setBranch(defaultBranch);
|
||||
setProtectBranch(defaultBranch);
|
||||
}
|
||||
},[defaultBranch]);
|
||||
|
||||
const { projectsId , owner } = props.match.params;
|
||||
const projectDetail = props.projectDetail;
|
||||
|
||||
function resetSetting(){
|
||||
useEffect(()=>{
|
||||
if(defaultBranch){
|
||||
setBranch(defaultBranch);
|
||||
}
|
||||
},[defaultBranch]);
|
||||
|
||||
useEffect(()=>{
|
||||
if(owner){
|
||||
getBranchs(projectsId,owner);
|
||||
getProtectBranchList(owner,projectsId);
|
||||
}
|
||||
},[owner])
|
||||
|
||||
// 获取已经设置过分支保护的分支列表
|
||||
function getProtectBranchList(owner,repo){
|
||||
const url = `/${owner}/${repo}/protected_branches.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
page,limit:LIMIT
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
setCount(result.data.total_count);
|
||||
setProtectBranchList(result.data.protected_branches);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
// 获取分支列表(下拉、过滤掉已经设置过分支保护的分支)
|
||||
async function getBranchs(id,owner){
|
||||
let re = await getBranch(id,owner);
|
||||
setBranchList(re);
|
||||
}
|
||||
|
||||
// 设为默认分支
|
||||
function resetSetting(){
|
||||
const url = `/${owner}/${projectsId}.json`;
|
||||
axios.put(url, {
|
||||
default_branch:branch
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
props.showNotification(`分支设置成功!`);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
// 跳转
|
||||
function settingRule(protectBranch){
|
||||
props.history.push(`/projects/${owner}/${projectsId}/setting/branch/${protectBranch}`);
|
||||
}
|
||||
|
||||
// 翻页
|
||||
function changePageNum(page){
|
||||
setPage(page);
|
||||
}
|
||||
|
||||
return(
|
||||
<WhiteBack>
|
||||
<Title>分支设置</Title>
|
||||
<Div>
|
||||
<div className="pb20" style={{borderBottom:"1px solid #eee"}}>
|
||||
<p className="color-grey-3 mb10">默认分支</p>
|
||||
<div className="pb20" style={{borderBottom:"1px dashed #eee"}}>
|
||||
<p className="color-grey-3 mb10 font-18">默认分支</p>
|
||||
<p className="mb10">默认分支被视作为代码库中的基本分支,是所有克隆、代码提交、合并请求的目标分支</p>
|
||||
<AlignCenter>
|
||||
<SelectBranch
|
||||
|
@ -31,20 +107,49 @@ export default ((props)=>{
|
|||
projectsId={projectsId}
|
||||
changeBranch={setBranch}
|
||||
owner={owner}
|
||||
history={props.history}
|
||||
branchList = {branchList}
|
||||
tagflag={false}
|
||||
/>
|
||||
<a className="color-blue ml20" onClick={resetSetting()}>设为默认分支</a>
|
||||
<a className="color-blue ml20" onClick={()=>resetSetting()}>设为默认分支</a>
|
||||
</AlignCenter>
|
||||
</div>
|
||||
<div>
|
||||
<FlexAJ className="pt20">
|
||||
<span className="color-grey-3">保护分支规则</span>
|
||||
<Blueline>+ 新建规则</Blueline>
|
||||
</FlexAJ>
|
||||
<NumUl>
|
||||
<li>限制分支的推送、合并。强制推送相关请去<GreenUnder>仓库设置</GreenUnder>。</li>
|
||||
<li>一个分支同时只能有一个保护分支规则生效,越早创建的规则优先级越高。</li>
|
||||
<li>保护分支规则只影响状态是【保护分支】的分支。【常规分支】和【只读分支】都不影响。</li>
|
||||
</NumUl>
|
||||
<div className="mt10">
|
||||
<p className="color-grey-3 mb10 font-18">分支保护</p>
|
||||
<AlignCenter>
|
||||
<SelectBranch
|
||||
branch={protectBranch}
|
||||
repo_id={ projectDetail && projectDetail.repo_id}
|
||||
projectsId={projectsId}
|
||||
changeBranch={setProtectBranch}
|
||||
owner={owner}
|
||||
history={props.history}
|
||||
branchList = {branchList}
|
||||
tagflag={false}
|
||||
/>
|
||||
<a className={ protectBranchList && protectBranchList.length > 0?"color-blue ml20":"color-grey ml20"} onClick={()=>settingRule(protectBranch)}>设置分支保护</a>
|
||||
</AlignCenter>
|
||||
{
|
||||
protectBranchList && protectBranchList.length > 0 &&
|
||||
<div className="protectBranchList">
|
||||
{
|
||||
protectBranchList.map((item,key)=>{
|
||||
return(
|
||||
<FlexAJ>
|
||||
<span>{item.branch_name}</span>
|
||||
<Button onClick={()=>settingRule(item.branch_name)}>编辑</Button>
|
||||
</FlexAJ>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
||||
{
|
||||
count > LIMIT &&
|
||||
<div className="mt15 mb20" style={{textAlign:"center"}}>
|
||||
<Pagination simple current={page} pageSize={LIMIT} total={count} onChange={changePageNum}></Pagination>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</Div>
|
||||
</WhiteBack>
|
||||
|
|
|
@ -1,60 +1,305 @@
|
|||
import React , { forwardRef , useCallback } from 'react';
|
||||
import { Form , Input , Select , Button } from 'antd';
|
||||
import Title from '../Component/Title';
|
||||
import { WhiteBack , Cancel } from '../Component/layout';
|
||||
import styled from 'styled-components';
|
||||
import React, { forwardRef, useCallback, useState, useEffect } from "react";
|
||||
import { Form, InputNumber , Select, Button , Checkbox , Radio } from "antd";
|
||||
import Title from "../Component/Title";
|
||||
import { Cancel } from "../Component/layout";
|
||||
import axios from "axios";
|
||||
|
||||
const {Option} = Select;
|
||||
const Div = styled.div`{
|
||||
padding:20px 30px;
|
||||
}`
|
||||
export default Form.create()(
|
||||
forwardRef(( { form })=>{
|
||||
const { getFieldDecorator } = form;
|
||||
forwardRef(({ form, match, history , showNotification }) => {
|
||||
const [ protect , setProtect ] = useState(false);
|
||||
const [ protects , setProtects ] = useState(false);
|
||||
const [ mergeOptions , setMergeOptions ] = useState(undefined);
|
||||
const [ approveOptions , setApproveOptions ] = useState(undefined);
|
||||
const [ options , setOptions ] = useState(undefined);
|
||||
const [ list, setList ] = useState(undefined);
|
||||
|
||||
const { projectsId, owner , branch } = match.params;
|
||||
const { getFieldDecorator, validateFields , setFieldsValue , getFieldsValue } = form;
|
||||
|
||||
useEffect(() => {
|
||||
const url = `/${owner}/${projectsId}/collaborators.json`;
|
||||
axios.get(url).then((result) => {
|
||||
setList(result.data.members);
|
||||
})
|
||||
.catch((error) => {});
|
||||
}, []);
|
||||
|
||||
useEffect(()=>{
|
||||
if(branch){
|
||||
// 需要设置分支保护的分支名,获取分支保护详情
|
||||
getGuardDetail(owner,projectsId,branch);
|
||||
}
|
||||
},[]);
|
||||
|
||||
function getGuardDetail(owner,projectsId,branch){
|
||||
const url = `/${owner}/${projectsId}/protected_branches/${branch}/edit.json`;
|
||||
axios.get(url).then((result)=>{
|
||||
if(result){
|
||||
setProtect(result.data.protected);
|
||||
setProtects(result.data.protected);
|
||||
let protected_branch = result.data.protected_branch;
|
||||
|
||||
if(protected_branch){
|
||||
let enable_push = protected_branch.enable_push_whitelist ? 2 : protected_branch.enable_push ? 1 : 0;
|
||||
|
||||
setFieldsValue({
|
||||
...protected_branch,
|
||||
enable_push
|
||||
})
|
||||
setOptions(enable_push);
|
||||
setMergeOptions(protected_branch.enable_merge_whitelist);
|
||||
setApproveOptions(protected_branch.enable_approvals_whitelist);
|
||||
console.log("111",getFieldsValue("enable_status_check"));
|
||||
}
|
||||
}
|
||||
}).catch(error=>{});
|
||||
}
|
||||
|
||||
|
||||
function saveBranchRule() {
|
||||
validateFields((error, values) => {
|
||||
if (!error) {
|
||||
let url = "";
|
||||
if(protects){
|
||||
// 为true则修改
|
||||
url = `/${owner}/${projectsId}/protected_branches/${branch}.json`;
|
||||
}else{
|
||||
// 否则是保存
|
||||
url = `/${owner}/${projectsId}/protected_branches.json`;
|
||||
}
|
||||
axios({
|
||||
method:!protects ? "post" : (protect ? "patch" : "delete"),
|
||||
url,
|
||||
params:
|
||||
{
|
||||
branch_name:branch,
|
||||
enable_push:values.enable_push !== 0 ?false : true,
|
||||
enable_push_whitelist:values.enable_push === 2 ? true : false,
|
||||
...values
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
showNotification("保存成功!");
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget , className , isRequired ) => (
|
||||
(label, name, rules, widget, className, isRequired,flag) => (
|
||||
<div className={className}>
|
||||
<span className={isRequired?"required":""}>{label}</span>
|
||||
<span className={isRequired ? "required" : ""}>{label}</span>
|
||||
<Form.Item>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
{getFieldDecorator(name, { rules, validateFirst: true , valuePropName:flag ? "checked":"value" })(widget)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
),
|
||||
[]
|
||||
);
|
||||
return(
|
||||
<WhiteBack>
|
||||
<Title>新建保护分支规则</Title>
|
||||
<Div>
|
||||
// 启用分支保护
|
||||
function changeProtect(e){
|
||||
setProtect(e.target.checked);
|
||||
}
|
||||
// 切换保护选线
|
||||
function changeProtectOption(e){
|
||||
setOptions(e.target.value);
|
||||
}
|
||||
// 切换是否启用合并白名单
|
||||
function changeMergeOption(e){
|
||||
setMergeOptions(e.target.checked);
|
||||
}
|
||||
|
||||
// 是否启用批准仅限列入白名单的用户或团队
|
||||
function changeWhitelistUsernameOption(e){
|
||||
setApproveOptions(e.target.checked);
|
||||
}
|
||||
return (
|
||||
<div style={{backgroundColor:"#fff"}}>
|
||||
<Title>新建'{branch}'保护分支规则</Title>
|
||||
<Form>
|
||||
<div style={{padding:"20px 30px"}}>
|
||||
{helper(
|
||||
"设置分支/通配符",
|
||||
"sign",
|
||||
[{ required: true, message: "请输入分支/通配符" }],
|
||||
<Input placeholder="请输入分支名称或通配符规则" />,'setStyleRule'
|
||||
)}
|
||||
<p className="color-grey-8 mb20">例如:设置为“master”,则对名称为“master”的分支生效;设置为“*-stable“ 或 ”release*“,则对名称符合此通配符的所有保护分支生效。</p>
|
||||
{helper(
|
||||
"可推送代码成员",
|
||||
"psuhmember",
|
||||
"",
|
||||
"branchProtect",
|
||||
[],
|
||||
<Select placeholder="请选择仓库成员" >
|
||||
<Option value="0">请选择仓库成员</Option>
|
||||
</Select>,'setSelectWidth'
|
||||
<Checkbox checked={protect} onChange={changeProtect}>
|
||||
启用分支保护<span className="color-grey-9 ml5 font-12">组织删除并限制Git推送和合并到分支</span>
|
||||
</Checkbox>,
|
||||
"setStyleRule"
|
||||
)}
|
||||
{helper(
|
||||
"可合并Pull Request成员",
|
||||
"pullmember",
|
||||
[],
|
||||
<Select placeholder="请选择仓库成员" >
|
||||
<Option value="0">请选择仓库成员</Option>
|
||||
</Select>,'setSelectWidth'
|
||||
)}
|
||||
<div className="df pb30">
|
||||
<Button type="primary">保存</Button>
|
||||
<Cancel className="ml30">取消</Cancel>
|
||||
<div className="pl25 shortStyle">
|
||||
{helper(
|
||||
"",
|
||||
"enable_push",
|
||||
[],
|
||||
<Radio.Group disabled={!protect} onChange={changeProtectOption}>
|
||||
<Radio className="columsRadio" value={0}>
|
||||
禁用推送<span className="color-grey-9 ml5 font-12">此分支不允许推送</span>
|
||||
</Radio>
|
||||
<Radio className="columsRadio" value={1}>
|
||||
启用推送<span className="color-grey-9 ml5 font-12">任何拥有写访问权限的人将被允许推送到此分支(但不能强行推送)</span>
|
||||
</Radio>
|
||||
<Radio className="columsRadio" value={2}>
|
||||
启用推送白名单<span className="color-grey-9 ml5 font-12">只有列入白名单的用户或团队才能被允许推送到此分支(但不能强行推送)</span>
|
||||
</Radio>
|
||||
</Radio.Group>,
|
||||
""
|
||||
)}
|
||||
<div className="pl25 pt5 pb5 mb15">
|
||||
{helper(
|
||||
"",
|
||||
"push_whitelist_usernames",
|
||||
[],
|
||||
<Select
|
||||
mode="multiple"
|
||||
placeholder="搜索用户"
|
||||
style={{ width: '100%' }}
|
||||
disabled={!protect || (options ===undefined || options !== 2)}
|
||||
>
|
||||
{list && list.map(item => (
|
||||
<Select.Option key={item.id} value={item.login}>
|
||||
{item.name}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>,
|
||||
"setStyleRule"
|
||||
)}
|
||||
</div>
|
||||
{helper(
|
||||
"",
|
||||
"enable_merge_whitelist",
|
||||
[],
|
||||
<Checkbox disabled={!protect} checked={mergeOptions} onChange={changeMergeOption}>
|
||||
启用合并白名单<span className="color-grey-9 ml5 font-12">仅允许白名单用户或团队合并合并请求到此分支</span>
|
||||
</Checkbox>,
|
||||
"setStyleRule"
|
||||
)}
|
||||
<div className="pl25 pt5 pb5">
|
||||
{helper(
|
||||
"",
|
||||
"merge_whitelist_usernames",
|
||||
[],
|
||||
<Select
|
||||
mode="multiple"
|
||||
placeholder="搜索用户"
|
||||
style={{ width: '100%' }}
|
||||
disabled={!protect || !mergeOptions}
|
||||
>
|
||||
{list && list.map(item => (
|
||||
<Select.Option key={item.id} value={item.login}>
|
||||
{item.name}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>,
|
||||
"setStyleRule"
|
||||
)}
|
||||
</div>
|
||||
{helper(
|
||||
"",
|
||||
"enable_status_check",
|
||||
[],
|
||||
<Checkbox disabled={!protect}>
|
||||
启用状态检查
|
||||
</Checkbox>,
|
||||
"setStyleRule",false,true
|
||||
)}
|
||||
<div style={{display:"flex",alignItems:"center"}}>
|
||||
{helper(
|
||||
"所需的批准数",
|
||||
"required_approvals",
|
||||
[],
|
||||
<InputNumber min={0} style={{width:"140px"}}/>,
|
||||
"inlineFlex"
|
||||
)}
|
||||
<span className="color-grey-9 ml5 font-12">只允许合并有足够审核人数的拉取请求</span>
|
||||
</div>
|
||||
|
||||
{helper(
|
||||
"",
|
||||
"enable_approvals_whitelist",
|
||||
[],
|
||||
<Checkbox name="enable_approvals_whitelist" disabled={!protect} checked={approveOptions} onChange={changeWhitelistUsernameOption}>
|
||||
批准仅限列入白名单的用户或团队<span className="color-grey-9 ml5 font-12">只有白名单用户或团队的审核才能计数 没有批准的白名单,任何有写访问权限的人的审核都将计数</span>
|
||||
</Checkbox>,
|
||||
"setStyleRule"
|
||||
)}
|
||||
<div className="pl25 pt5 pb5 mb15">
|
||||
{helper(
|
||||
"",
|
||||
"approvals_whitelist_usernames",
|
||||
[],
|
||||
<Select
|
||||
mode="multiple"
|
||||
placeholder="搜索用户"
|
||||
style={{ width: '100%' }}
|
||||
disabled={!protect || !approveOptions}
|
||||
>
|
||||
{list && list.map(item => (
|
||||
<Select.Option key={item.id} value={item.login}>
|
||||
{item.name}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>,
|
||||
"setStyleRule"
|
||||
)}
|
||||
</div>
|
||||
|
||||
{helper(
|
||||
"",
|
||||
"block_on_rejected_reviews",
|
||||
[],
|
||||
<Checkbox disabled={!protect} name="block_on_rejected_reviews">
|
||||
拒绝审核阻止了合并<span className="color-grey-9 ml5 font-12">如果官方审查人员要求作出改动,即使有足够的批准,合并也不允许</span>
|
||||
</Checkbox>,
|
||||
"setStyleRule",false,true
|
||||
)}
|
||||
|
||||
{helper(
|
||||
"",
|
||||
"dismiss_stale_approvals",
|
||||
[],
|
||||
<Checkbox disabled={!protect} name="dismiss_stale_approvals">
|
||||
取消过时的批准<span className="color-grey-9 ml5 font-12">当新的提交更改合并请求内容被推送到分支时,旧的批准将被撤销</span>
|
||||
</Checkbox>,
|
||||
"setStyleRule",false,true
|
||||
)}
|
||||
{helper(
|
||||
"",
|
||||
"require_signed_commits",
|
||||
[],
|
||||
<Checkbox disabled={!protect} name="require_signed_commits">
|
||||
需要签名提交
|
||||
</Checkbox>,
|
||||
"setStyleRule",false,true
|
||||
)}
|
||||
{helper(
|
||||
"",
|
||||
"block_on_outdated_branch",
|
||||
[],
|
||||
<Checkbox disabled={!protect} name="block_on_outdated_branch">
|
||||
如果拉取请求已经过时,阻止合并<span className="color-grey-9 ml5 font-12">当头部分支落后基础分支时,不能合并</span>
|
||||
</Checkbox>,
|
||||
"setStyleRule",false,true
|
||||
)}
|
||||
</div>
|
||||
</Div>
|
||||
</WhiteBack>
|
||||
)
|
||||
|
||||
<div className="df pb30 pt20">
|
||||
<Button type="primary" onClick={saveBranchRule}>
|
||||
保存
|
||||
</Button>
|
||||
<Cancel
|
||||
className="ml30"
|
||||
onClick={() => {
|
||||
history.push(`/projects/${owner}/${projectsId}/setting/branch`);
|
||||
}}
|
||||
>
|
||||
取消
|
||||
</Cancel>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
)
|
||||
);
|
||||
|
|
|
@ -290,8 +290,10 @@ class Collaborator extends Component {
|
|||
return "text-green";
|
||||
} else if (role === "Developer") {
|
||||
return "text-primary";
|
||||
} else {
|
||||
} else if(role === "Reporter"){
|
||||
return "text-yellow";
|
||||
}else{
|
||||
return "text-gray";
|
||||
}
|
||||
};
|
||||
const member_roles = (item) => {
|
||||
|
@ -302,7 +304,11 @@ class Collaborator extends Component {
|
|||
<label className={get_color(item.role)}>
|
||||
{operation && operation[0].name}
|
||||
</label>
|
||||
) : (
|
||||
) :
|
||||
item.is_apply_signature ?
|
||||
<label className="text-grey">外围贡献者</label>
|
||||
:
|
||||
(
|
||||
<Dropdown overlay={setRoles(`${item.id}`)} placement={"bottomCenter"}>
|
||||
<span className={get_color(item.role)}>
|
||||
{operation && operation[0].name}
|
||||
|
@ -360,6 +366,11 @@ class Collaborator extends Component {
|
|||
dataIndex: "email",
|
||||
render: (text) => <span>{text}</span>,
|
||||
},
|
||||
{
|
||||
title: "Token值",
|
||||
dataIndex: "token",
|
||||
render: (text) => <span>{text}</span>,
|
||||
},
|
||||
{
|
||||
title: roleTitle,
|
||||
dataIndex: "role_name",
|
||||
|
@ -493,7 +504,7 @@ class Collaborator extends Component {
|
|||
rowKey={(record) => record.id}
|
||||
></Table>
|
||||
) : (
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
<NoneData _html="暂时还没有相关数据!" />
|
||||
)}
|
||||
</div>
|
||||
</Spin>
|
||||
|
|
|
@ -28,6 +28,10 @@ const Tags = Loadable({
|
|||
loader: () => import("./new_tags"),
|
||||
loading: Loading,
|
||||
});
|
||||
const Special = Loadable({
|
||||
loader: () => import("./SpecialProject"),
|
||||
loading: Loading,
|
||||
});
|
||||
const Manage = Loadable({
|
||||
loader: () => import("./ManageWeb"),
|
||||
loading: Loading,
|
||||
|
@ -40,11 +44,12 @@ class Index extends Component {
|
|||
render() {
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { pathname } = this.props.history.location;
|
||||
const { projectDetail } = this.props;
|
||||
|
||||
const flag = pathname === `/projects/${owner}/${projectsId}/setting`;
|
||||
return (
|
||||
<Box className="ProjectListIndex">
|
||||
<Short>
|
||||
<div className="ProjectListIndex">
|
||||
<div style={{width:"28%",borderRadius:"5px",marginBottom:"30%"}}>
|
||||
<ul className="list-l-Menu">
|
||||
<li className={flag ? "active" : ""}>
|
||||
<p>
|
||||
|
@ -65,18 +70,18 @@ class Index extends Component {
|
|||
</Link>
|
||||
</p>
|
||||
</li>
|
||||
{/* <li
|
||||
<li
|
||||
className={
|
||||
pathname.indexOf("setting/branch") > -1 ? "active" : ""
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<Link to={`/projects/${projectsId}/setting/branch`} className="w-100">
|
||||
<Link to={`/projects/${owner}/${projectsId}/setting/branch`} className="w-100">
|
||||
<i className="iconfont icon-fenzhi font-20 mr10"></i>
|
||||
分支设置
|
||||
</Link>
|
||||
</p>
|
||||
</li> */}
|
||||
</li>
|
||||
<li
|
||||
className={pathname.indexOf("setting/tags") > -1 ? "active" : ""}
|
||||
>
|
||||
|
@ -87,6 +92,20 @@ class Index extends Component {
|
|||
</Link>
|
||||
</p>
|
||||
</li>
|
||||
{
|
||||
projectDetail && projectDetail.permission && (projectDetail.permission === "Owner" || projectDetail.permission === "Admin") ?
|
||||
<li
|
||||
className={pathname.indexOf("setting/special") > -1 ? "active" : ""}
|
||||
>
|
||||
<p>
|
||||
<Link to={`/projects/${owner}/${projectsId}/setting/special`} className="w-100">
|
||||
<i className="iconfont icon-jingyan font-18 mr10"></i>
|
||||
特殊开源许可证项目管理
|
||||
</Link>
|
||||
</p>
|
||||
</li>
|
||||
:""
|
||||
}
|
||||
|
||||
{/* <li
|
||||
className={
|
||||
|
@ -101,9 +120,9 @@ class Index extends Component {
|
|||
</p>
|
||||
</li> */}
|
||||
</ul>
|
||||
</Short>
|
||||
<Long>
|
||||
<Gap>
|
||||
</div>
|
||||
<div style={{width:"72%",borderRadius:"5px",marginBottom:"30px"}}>
|
||||
<div style={{paddingLeft:"20px",boxSizing:"border-box"}}>
|
||||
<Switch {...this.props}>
|
||||
{/* 协作者 */}
|
||||
<Route
|
||||
|
@ -112,7 +131,15 @@ class Index extends Component {
|
|||
<Collaborator {...this.props} {...props} {...this.state} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
<Route
|
||||
path="/projects/:owner/:projectsId/setting/special"
|
||||
render={(props) => (
|
||||
<Special {...this.props} {...props} {...this.state} />
|
||||
)}
|
||||
></Route>
|
||||
{/* 修改仓库信息 */}
|
||||
|
||||
<Route
|
||||
path="/projects/:owner/:projectsId/setting/tags"
|
||||
render={(props) => (
|
||||
|
@ -120,7 +147,7 @@ class Index extends Component {
|
|||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/projects/:owner/:projectsId/setting/branch/new"
|
||||
path="/projects/:owner/:projectsId/setting/branch/:branch"
|
||||
render={(props) => (
|
||||
<BranchNew {...this.props} {...props} {...this.state} />
|
||||
)}
|
||||
|
@ -128,7 +155,7 @@ class Index extends Component {
|
|||
<Route
|
||||
path="/projects/:owner/:projectsId/setting/branch"
|
||||
render={(props) => (
|
||||
<Branch {...this.props} {...props} {...this.state} />
|
||||
<Branch {...this.props} {...props } {...this.state} />
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
|
@ -151,9 +178,9 @@ class Index extends Component {
|
|||
)}
|
||||
></Route>
|
||||
</Switch>
|
||||
</Gap>
|
||||
</Long>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,11 @@ class Setting extends Component {
|
|||
CategoryList: undefined,
|
||||
LanguageList: undefined,
|
||||
private_check: undefined,
|
||||
is_secret:false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate=(prevPros)=>{
|
||||
console.log("dddd",this.props.checkIfLogin());
|
||||
if(prevPros && this.props && !this.props.checkIfLogin()){
|
||||
this.props.history.push("/403")
|
||||
return
|
||||
|
@ -53,10 +53,11 @@ class Setting extends Component {
|
|||
.then((result) => {
|
||||
if (result) {
|
||||
this.props.form.setFieldsValue({
|
||||
...result.data,
|
||||
...result.data
|
||||
});
|
||||
this.setState({
|
||||
private_check: result.data.private,
|
||||
is_secret:result.data.is_secret
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -145,7 +146,6 @@ class Setting extends Component {
|
|||
});
|
||||
};
|
||||
changePrivate = (e) => {
|
||||
console.log(e);
|
||||
this.setState({
|
||||
private_check: e.target.checked,
|
||||
});
|
||||
|
@ -154,10 +154,10 @@ class Setting extends Component {
|
|||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
|
||||
const { CategoryList, LanguageList, private_check } = this.state;
|
||||
const { CategoryList, LanguageList, private_check , is_secret } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<WhiteBack>
|
||||
<WhiteBack style={{paddingBottom:"20px"}}>
|
||||
<Title>基本设置</Title>
|
||||
<Form className="baseForm">
|
||||
<Form.Item label="项目名称">
|
||||
|
@ -179,6 +179,7 @@ class Setting extends Component {
|
|||
<Checkbox
|
||||
checked={private_check}
|
||||
onChange={this.changePrivate}
|
||||
disabled={is_secret}
|
||||
>
|
||||
将仓库设为私有
|
||||
</Checkbox>
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
import React , { useEffect , useState} from 'react';
|
||||
import { Input , Table , Pagination, Button , Dropdown , Menu } from 'antd';
|
||||
import { Banner , WhiteBack , AlignCenterBetween } from '../Component/layout';
|
||||
import axios from 'axios';
|
||||
|
||||
const { Search } = Input;
|
||||
|
||||
const LIMIT = 15;
|
||||
function SpecialProject(props){
|
||||
const [ page , setPage] = useState(1);
|
||||
const [ searchValue , SetSearchValue ] = useState(undefined);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
const [ list , setList ] = useState(undefined);
|
||||
const [ status , setStatus ] = useState(undefined);
|
||||
const [ loading ,setLoading ] = useState(true);
|
||||
|
||||
const { owner , projectsId} = props.match.params;
|
||||
const { project_id } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
if(project_id){
|
||||
setLoading(true);
|
||||
Init(searchValue, status);
|
||||
}
|
||||
},[page,project_id]);
|
||||
|
||||
function Init(search,status){
|
||||
const url = `/apply_signatures.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
project_id,
|
||||
page,limit:LIMIT,search,status
|
||||
}
|
||||
}).then(result=>{
|
||||
setLoading(false);
|
||||
if(result){
|
||||
setList(result.data.apply_signatures);
|
||||
setTotal(result.data.total_count);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function changePage(page){
|
||||
setLoading(true);
|
||||
setPage(page);
|
||||
}
|
||||
|
||||
const column = [
|
||||
{
|
||||
dataIndex:"column",
|
||||
key:1,
|
||||
width:"12%",
|
||||
title:"序号",
|
||||
render:(txt,item,index)=>{
|
||||
return `${index+1}`
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex:"name",
|
||||
key:2,
|
||||
title:"申请人",
|
||||
render:(text,item,m)=>{
|
||||
return item.user && <span className="task-hide" style={{maxWidth:"139px",display:"block"}}>{item.user.name}</span>
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex:"email",
|
||||
key:2,
|
||||
title:"邮箱",
|
||||
width:"22%",
|
||||
render:(text,item,m)=>{
|
||||
return item.user && <span>{item.user.email}</span>
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex:"attachment",
|
||||
key:3,
|
||||
title:"附件",
|
||||
width:"28%",
|
||||
render:(text,item,m)=>{
|
||||
return item.attachment && <a className="task-hide" style={{maxWidth:"173px",display:"block"}} href={`${item.attachment.path}`}>{item.attachment.filename}</a>
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex:"operation",
|
||||
key:4,
|
||||
width:"18%",
|
||||
title:"操作",
|
||||
render:(text, item) =>{
|
||||
return(
|
||||
<React.Fragment>
|
||||
{
|
||||
item.status === "waiting" &&
|
||||
<span>
|
||||
<Button size="small" onClick={()=>operation(item.id,"unpassed")}>拒绝</Button>
|
||||
<Button size="small" onClick={()=>operation(item.id,"passed")} type={"primary"} className="ml20">同意</Button>
|
||||
</span>
|
||||
}
|
||||
{
|
||||
item.status === "unpassed" &&
|
||||
<span style={{color:"#ff041c"}}>已拒绝</span>
|
||||
}
|
||||
{
|
||||
item.status === "passed" &&
|
||||
<span style={{color:"#13b4f1"}}>已同意</span>
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
// 拒绝&同意
|
||||
function operation(ids,s){
|
||||
setLoading(true);
|
||||
const url = `/apply_signatures/${ids}.json`;
|
||||
axios.put(url,{
|
||||
project_id:project_id,
|
||||
status:s
|
||||
}).then(result=>{
|
||||
setLoading(false);
|
||||
if(result){
|
||||
props.showNotification(`${s==="passed"?"同意":"拒绝"}此申请已操作成功!`);
|
||||
Init(searchValue,status);
|
||||
}
|
||||
}).catch(error=>{setLoading(false)})
|
||||
}
|
||||
|
||||
function searchList(){
|
||||
setLoading(true);
|
||||
Init(searchValue,status);
|
||||
}
|
||||
|
||||
const menu=(
|
||||
<Menu onClick={chooseStatus}>
|
||||
<Menu.Item key="all">全部</Menu.Item>
|
||||
<Menu.Item key="waiting">审核中</Menu.Item>
|
||||
<Menu.Item key="unpassed">已拒绝</Menu.Item>
|
||||
<Menu.Item key="passed">已同意</Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
|
||||
function chooseStatus(e){
|
||||
setStatus(e.key);
|
||||
Init(searchValue, e.key);
|
||||
}
|
||||
|
||||
|
||||
return(
|
||||
<WhiteBack style={{minHeight:"500px"}}>
|
||||
<Banner>项目管理</Banner>
|
||||
<AlignCenterBetween style={{padding:"10px 20px",textAlign:"right"}}>
|
||||
<Search
|
||||
placeholder="请输入用户姓名或者邮箱搜索"
|
||||
allowClear
|
||||
enterButton="搜索"
|
||||
style={{width:400}}
|
||||
size="middle"
|
||||
value={searchValue}
|
||||
onChange={(e)=>SetSearchValue(e.target.value)}
|
||||
onSearch={searchList}
|
||||
/>
|
||||
<Dropdown overlay={menu} placement="bottomRight">
|
||||
<span>
|
||||
<span style={{color:status ? "color-blue" : "color-grey-3"}}>{status ==="waiting"?"审核中":status==="unpassed"?"已拒绝":status==="passed"?"已同意":"全部"}</span>
|
||||
<i className="iconfont icon-xiajiantou color-grey-9 font-14 ml8"></i>
|
||||
</span>
|
||||
</Dropdown>
|
||||
</AlignCenterBetween>
|
||||
<Table
|
||||
columns={column}
|
||||
rowKey={(record) => record.id}
|
||||
pagination={false}
|
||||
dataSource={list}
|
||||
loading={loading}
|
||||
></Table>
|
||||
{
|
||||
total > LIMIT &&
|
||||
<div className="center mt20 mb20">
|
||||
<Pagination simple current={page} total={total} pageSize={LIMIT} onChange={changePage}></Pagination>
|
||||
</div>
|
||||
}
|
||||
|
||||
</WhiteBack>
|
||||
)
|
||||
}
|
||||
export default SpecialProject;
|
|
@ -410,7 +410,7 @@ class NewTags extends Component {
|
|||
</div>
|
||||
);
|
||||
} else {
|
||||
return <NoneData _html="暂时还没有相关数据哦!" />;
|
||||
return <NoneData _html="暂时还没有相关数据!" />;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -139,6 +139,7 @@
|
|||
.padding15-10{
|
||||
padding:15px 10px;
|
||||
}
|
||||
.center{text-align: center;}
|
||||
.w-100{width: 100%;}
|
||||
.fwb{font-weight: 600;}
|
||||
.text-black{color: #333;}
|
||||
|
@ -151,6 +152,9 @@
|
|||
.text-yellow{color: #FF6E21 !important;}
|
||||
.text-delete{color: #BBBBBB; }
|
||||
.text-delete:hover{color: #db2828; }
|
||||
.text-grey{
|
||||
color: #999;
|
||||
}
|
||||
.new-tag-div{
|
||||
padding: 15px;
|
||||
height: 75px;
|
||||
|
@ -187,7 +191,29 @@
|
|||
width: 100%;
|
||||
}
|
||||
}
|
||||
.shortStyle{
|
||||
.setStyleRule{
|
||||
min-height: 35px;
|
||||
}
|
||||
.columsRadio{
|
||||
display: block;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.ant-row.ant-form-item{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
.inlineFlex{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
& > span{
|
||||
margin-right: 10px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
.setStyleRule{
|
||||
min-height: 35px;
|
||||
.ant-row.ant-form-item{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
@ -196,4 +222,22 @@
|
|||
.ant-select.ant-select-enabled{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.setHeight{
|
||||
.ant-select-selection,.ant-select-selection__rendered{
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
.protectBranchList{
|
||||
border:1px solid #eee;
|
||||
border-radius: 5px;
|
||||
margin-top: 25px;
|
||||
&>div{
|
||||
padding:5px 15px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
&>div:last-child{
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue