Compare commits
289 Commits
master
...
dev_milita
Author | SHA1 | Date |
---|---|---|
caishi | 7e27014dde | |
xiaoxiaoqiong | 10c237498e | |
xxq250 | 070f869aa6 | |
何童崇 | c14ee5c359 | |
xxq250 | 7ee151e652 | |
何童崇 | 7e3e35784e | |
何童崇 | 90f8e04e93 | |
何童崇 | 0dc7a1f582 | |
何童崇 | b6f2eb107c | |
何童崇 | 3f6165585d | |
何童崇 | e4005a03b3 | |
baladiwei | 846a24aef4 | |
baladiwei | 955eed9232 | |
何童崇 | fee2aec384 | |
何童崇 | 97f3fa75c1 | |
何童崇 | eb180d3570 | |
何童崇 | 9276136bfe | |
何童崇 | 1bad39e83a | |
何童崇 | c9e7da7df3 | |
何童崇 | 7f0b770dca | |
baladiwei | 70536036e1 | |
何童崇 | 2d8c3c5853 | |
baladiwei | 0f92ff94a0 | |
何童崇 | 6507c87bc8 | |
何童崇 | b423e4b7e7 | |
何童崇 | 76b4cf0d9b | |
何童崇 | 6d2a50ef5e | |
baladiwei | 938be1da55 | |
何童崇 | 954cf38074 | |
何童崇 | bdcc7a4699 | |
何童崇 | e4d4375102 | |
何童崇 | 54bffb41da | |
何童崇 | 4097ebb69b | |
何童崇 | 162fd200a5 | |
何童崇 | cc9cf251fe | |
何童崇 | c6bc26c5ae | |
何童崇 | 6e7da0ef5b | |
baladiwei | d9bd0387db | |
何童崇 | c0cfe12db4 | |
何童崇 | dc6cfc342e | |
何童崇 | c3ecbe1f97 | |
何童崇 | a59a8c3693 | |
何童崇 | 14e4dc7d9e | |
baladiwei | 97f62a5684 | |
baladiwei | e74a3b6a95 | |
何童崇 | 38878183d5 | |
baladiwei | 0e0c13f1a4 | |
何童崇 | a667a32de0 | |
何童崇 | 230e597787 | |
何童崇 | f0ea3a53c4 | |
何童崇 | 51a4680481 | |
baladiwei | 61a4882e58 | |
何童崇 | 148e8f91eb | |
baladiwei | 8f52a091fa | |
tongChong | 62eabdf7c0 | |
谢思 | d5490d5e71 | |
baladiwei | cef374c52d | |
谢思 | 7be60d3140 | |
durian | feafa5b6f3 | |
谢思 | 2dd6ed108f | |
baladiwei | 969323fdde | |
何童崇 | a73b4ff79a | |
baladiwei | 16ca2a359e | |
baladiwei | 444d954e72 | |
何童崇 | 6fc31c0bb8 | |
何童崇 | cf73f72e19 | |
baladiwei | 745a25a003 | |
tongChong | b080df1449 | |
何童崇 | 0aa2a4aec3 | |
何童崇 | 4dc1c4c814 | |
何童崇 | ddc576b054 | |
谢思 | caef7a0ab3 | |
谢思 | 85f0578302 | |
baladiwei | bff55b6810 | |
baladiwei | 01f71bca87 | |
何童崇 | d3cea0ff3b | |
baladiwei | be6e3d273b | |
何童崇 | 6b8f1e3749 | |
tongChong | b5e145b4b5 | |
何童崇 | 15b63be594 | |
谢思 | 032127bef6 | |
谢思 | f4f843a7b9 | |
何童崇 | 4cf8357463 | |
何童崇 | 0ff1367ad8 | |
何童崇 | 0e44cbbcdd | |
tongChong | e736591a4f | |
tongChong | d15900fc7c | |
谢思 | 4f87542f1f | |
何童崇 | 94ee3601c9 | |
tongChong | 19d09c7901 | |
谢思 | 3b29605321 | |
何童崇 | 6e82862307 | |
tongChong | 700ac5862e | |
谢思 | 4ccab2ed4f | |
何童崇 | 3f3299a3b8 | |
baladiwei | b73a38351b | |
baladiwei | 586c5d6d1d | |
tongChong | 819772d180 | |
谢思 | e733f1886e | |
tongChong | 86d2442958 | |
谢思 | b7fc83edf9 | |
tongChong | 74325b5dc7 | |
xiesi | a25959bfa0 | |
baladiwei | fe72be2f30 | |
baladiwei | 4d41f44100 | |
tongChong | afa839e0b1 | |
xiesi | 83d59a2e64 | |
tongChong | 758f4267ed | |
xiesi | 38948a84cd | |
xiesi | 51d739f4a0 | |
tongChong | 706830928e | |
xiesi | 8dc08c3992 | |
何童崇 | 70ec86569f | |
何童崇 | 00b41844bb | |
何童崇 | 81c93d2580 | |
何童崇 | a87e55103c | |
何童崇 | 05101c5e32 | |
何童崇 | e72b3e687f | |
何童崇 | f25a52622d | |
何童崇 | f5fa216b23 | |
何童崇 | a57b96a1b8 | |
何童崇 | 8efbea44ab | |
何童崇 | fa80b5d1df | |
何童崇 | 6c95ff98f4 | |
何童崇 | cb7170a87c | |
何童崇 | 7757e4b6b7 | |
何童崇 | cad9a4fc3a | |
何童崇 | dc20d3e270 | |
何童崇 | 4503e1b176 | |
何童崇 | 91fe328eaf | |
何童崇 | 8d9d5c3ce3 | |
何童崇 | a2aa344e31 | |
何童崇 | 981e199273 | |
何童崇 | b6d6309c3c | |
何童崇 | 16aac3b835 | |
何童崇 | bdf3a8e72a | |
何童崇 | 507976bf10 | |
何童崇 | b6c2c66321 | |
何童崇 | 0b7fbe564c | |
何童崇 | ce958f3369 | |
何童崇 | 0e176d9334 | |
何童崇 | 3608b7b712 | |
何童崇 | b9888a81f6 | |
何童崇 | 0bb6ec51c2 | |
何童崇 | 7d2c90dfd1 | |
何童崇 | 66c5f09813 | |
何童崇 | a4d38f8c86 | |
何童崇 | 21a3c54754 | |
何童崇 | 4493711521 | |
何童崇 | 76b23f88db | |
何童崇 | bca9499844 | |
何童崇 | 3137048aed | |
何童崇 | 62b5d86082 | |
何童崇 | 7a472651f1 | |
何童崇 | 99c90295c0 | |
何童崇 | d7fd642f7f | |
何童崇 | 97bc41e771 | |
何童崇 | 6156d98af2 | |
caishi | 6facc3e65f | |
何童崇 | c8f6891239 | |
何童崇 | 11b5c87888 | |
caishi | 2f538ff394 | |
何童崇 | 48a153d434 | |
何童崇 | 9c3ecabf47 | |
何童崇 | f18070da47 | |
何童崇 | 1e87e0c8ec | |
何童崇 | bec68aa090 | |
何童崇 | aed83337fa | |
何童崇 | e5b7110090 | |
何童崇 | 716916b7b6 | |
何童崇 | b5ccdbfcd6 | |
何童崇 | 1e7df569e6 | |
何童崇 | 701d9dfc99 | |
何童崇 | e7b3a01c47 | |
何童崇 | b19c084ac8 | |
何童崇 | 1d4bb3f4fc | |
何童崇 | e0b267bd6c | |
何童崇 | 4bf4aa7c78 | |
何童崇 | e3643be01b | |
何童崇 | 9c8add0152 | |
何童崇 | edb7099131 | |
何童崇 | cce818d4e0 | |
caishi | 909663bc47 | |
caishi | 9ea9da9672 | |
何童崇 | 97bd7673e1 | |
何童崇 | 2aa89426ad | |
何童崇 | 5131dacf05 | |
何童崇 | 6b63cd25aa | |
caishi | 8162b8b908 | |
何童崇 | 7a59d43eec | |
caishi | 008ba8d1de | |
何童崇 | 98a9344b02 | |
何童崇 | b8342288dd | |
何童崇 | 09e81b9e78 | |
caishi | 7cf5e23cb9 | |
何童崇 | 8594168d33 | |
caishi | 2d7c6cb82d | |
何童崇 | c36925c136 | |
何童崇 | 6ec6ab2308 | |
何童崇 | 4109e4b07e | |
何童崇 | 216e984740 | |
何童崇 | 92f3934d5e | |
何童崇 | 2ed7e0d4c4 | |
caishi | 6cfe81aea3 | |
何童崇 | 4dcbd51482 | |
caishi | c32b333bc2 | |
caishi | c965da7dd5 | |
caishi | b44399968f | |
caishi | 2591f28ccc | |
caishi | 5530e8c723 | |
caishi | fa26dc9fa5 | |
caishi | 4cf40f9dfc | |
caishi | 2c034f5dff | |
caishi | d68d8318c1 | |
caishi | 41ae6b1f8d | |
caishi | a6e2171fca | |
caishi | 916cc293ac | |
caishi | 5565eac601 | |
caishi | 860b71c7c6 | |
caishi | f1c2841fe0 | |
caishi | c6d5078d42 | |
caishi | ebe2d625fa | |
caishi | b5e1a91af5 | |
caishi | 4b8d72a6eb | |
caishi | f0e1858cd4 | |
caishi | a92468953a | |
caishi | fdab967b6a | |
caishi | 7e8929f166 | |
caishi | 0a39ed80da | |
caishi | 5ed44f1d63 | |
caishi | 64e639ebea | |
caishi | 3fb9eb40f3 | |
caishi | efc2443bb8 | |
caishi | 2c3d917bd4 | |
caishi | 617f139f52 | |
caishi | de550d5f42 | |
caishi | f12230dc91 | |
caishi | 1df2639cd5 | |
caishi | c746e9e634 | |
caishi | d8d464a332 | |
caishi | 83e337b2e9 | |
caishi | 5a6b7bd717 | |
caishi | c68a3dbd6f | |
caishi | 350f9426ea | |
caishi | 5bda100e32 | |
caishi | dde7fa730a | |
caishi | 3f8f1b8083 | |
caishi | 6eef4bd09e | |
caishi | 0dcaea3db4 | |
caishi | 033134fa83 | |
caishi | 1bab0b01f7 | |
caishi | 7b2f233cae | |
caishi | 2ecdd73c7f | |
caishi | 4e7a2fa3d7 | |
caishi | 91662e2e3e | |
sylor_huang@126.com | c2129c994a | |
sylor_huang@126.com | e968ece34c | |
sylor_huang@126.com | 70d407963e | |
sylor_huang@126.com | 00ccba74a1 | |
sylor_huang@126.com | 0790abb6f9 | |
caishi | 6c4c161a1b | |
caishi | 65a2bd43cf | |
sylor_huang@126.com | 10f813a443 | |
sylor_huang@126.com | e79ec30c81 | |
sylor_huang@126.com | 2a7fea3612 | |
sylor_huang@126.com | cc46a3ac30 | |
sylor_huang@126.com | cca5f98c9b | |
sylor_huang@126.com | d4535005c8 | |
sylor_huang@126.com | 73d128e0c9 | |
sylor_huang@126.com | f09457a0ac | |
sylor_huang@126.com | 78c218b12b | |
sylor_huang@126.com | d9f87fdd18 | |
caishi | 33c3395221 | |
sylor_huang@126.com | 74d26a40d3 | |
sylor_huang@126.com | 3f78ed249c | |
caishi | 07e1525f09 | |
sylor_huang@126.com | a9161b86a2 | |
sylor_huang@126.com | e0e6cdcc79 | |
sylor_huang@126.com | 3b0c708d82 | |
sylor_huang@126.com | 0922df3875 | |
sylor_huang@126.com | ad3fe09cfb | |
sylor_huang@126.com | 91f4327eb4 | |
sylor_huang@126.com | f2f910b5e4 | |
sylor_huang@126.com | 85d924db70 | |
Jasder | f1614a4b62 | |
Jasder | 2fa71241db | |
Jasder | 13c6556574 | |
caishi | 5601b71937 | |
Jasder | 1a024f8011 |
|
@ -86,3 +86,6 @@ typings/
|
|||
|
||||
.DS_Store
|
||||
.idea/*
|
||||
|
||||
package.json
|
||||
package-lock.json
|
|
@ -101,9 +101,13 @@ module.exports = {
|
|||
extensions: [".web.js", ".mjs", ".js", ".json", ".web.jsx", ".jsx"],
|
||||
alias: {
|
||||
educoder: __dirname + "/../src/common/educoder.js",
|
||||
src: path.join(paths.appSrc), // 整个源代码目录
|
||||
forge: path.join(paths.appSrc, 'forge'),
|
||||
military: path.join(paths.appSrc, 'military'),
|
||||
// Support React Native Web
|
||||
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
||||
"react-native": "react-native-web",
|
||||
'react-dom': '@hot-loader/react-dom',
|
||||
},
|
||||
plugins: [
|
||||
// Prevents users from importing files from outside of src/ (or node_modules/).
|
||||
|
|
|
@ -87,6 +87,9 @@ module.exports = {
|
|||
extensions: [".web.js", ".mjs", ".js", ".json", ".web.jsx", ".jsx"],
|
||||
alias: {
|
||||
educoder: __dirname + "/../src/common/educoder.js",
|
||||
src: path.join(paths.appSrc),
|
||||
forge: path.join(paths.appSrc, 'forge'),
|
||||
military: path.join(paths.appSrc, 'military'),
|
||||
// Support React Native Web
|
||||
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
||||
"react-native": "react-native-web",
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"educoder": ["./src/common/educoder.js"],
|
||||
"forge":["./src/forge"],
|
||||
"military":["./src/military"],
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"build"
|
||||
]
|
||||
}
|
|
@ -80,6 +80,7 @@
|
|||
"react-color": "^2.18.0",
|
||||
"react-content-loader": "^3.1.1",
|
||||
"react-cookies": "^0.1.1",
|
||||
"react-countup": "^6.1.0",
|
||||
"react-datepicker": "^2.14.1",
|
||||
"react-dev-utils": "^9.2.0-next.80",
|
||||
"react-dom": "^16.13.1",
|
||||
|
@ -92,6 +93,7 @@
|
|||
"react-resizable": "^1.10.1",
|
||||
"react-router": "^4.2.0",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"react-slick": "^0.28.1",
|
||||
"react-split-pane": "^0.1.91",
|
||||
"react-url-query": "^1.5.0",
|
||||
"react-zmage": "^0.8.5-beta.31",
|
||||
|
@ -102,11 +104,13 @@
|
|||
"scroll-into-view": "^1.14.2",
|
||||
"showdown": "^1.9.1",
|
||||
"showdown-katex": "^0.8.0",
|
||||
"slick-carousel": "^1.8.1",
|
||||
"store": "^2.0.12",
|
||||
"style-loader": "0.19.0",
|
||||
"styled-components": "^4.4.1",
|
||||
"sw-precache-webpack-plugin": "0.11.4",
|
||||
"url-loader": "0.6.2",
|
||||
"wangeditor-for-react": "^1.4.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"webpack-dev-server": "^3.10.3",
|
||||
"webpack-manifest-plugin": "^2.2.0",
|
||||
|
@ -115,7 +119,7 @@
|
|||
},
|
||||
"scripts": {
|
||||
"start": "node --max_old_space_size=15360 scripts/start.js",
|
||||
"build": "NODE_ENV=production node --max_old_space_size=15360 scripts/build.js",
|
||||
"build": " NODE_ENV=production node --max_old_space_size=15360 scripts/build.js",
|
||||
"test-build": "NODE_ENV=testBuild node --max_old_space_size=15360 scripts/build.js",
|
||||
"pre-build": "NODE_ENV=preBuild node --max_old_space_size=15360 scripts/build.js",
|
||||
"gen_stats": "NODE_ENV=production webpack --profile --config=./config/webpack.config.prod.js --json > stats.json",
|
||||
|
@ -182,6 +186,7 @@
|
|||
"port": "3007",
|
||||
"devDependencies": {
|
||||
"@babel/runtime": "7.0.0-beta.51",
|
||||
"@hot-loader/react-dom": "^16.14.0",
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-plugin-import": "^1.13.0",
|
||||
|
@ -191,6 +196,7 @@
|
|||
"babel-preset-stage-2": "^6.24.1",
|
||||
"compression-webpack-plugin": "^1.1.12",
|
||||
"concat": "^1.0.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"happypack": "^5.0.1",
|
||||
"mockjs": "^1.1.0",
|
||||
"node-sass": "^4.12.0",
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*头部导航条样式---2018-03-19--by-cs*/
|
||||
.newHeader {
|
||||
background: #24292D !important;
|
||||
width: 100%;
|
||||
height: 60px !important;
|
||||
min-width: 1200px;
|
||||
|
|
|
@ -3971,7 +3971,9 @@ html>body #ajax-indicator {
|
|||
cursor: pointer;
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
padding:0px 20px;
|
||||
margin-right: 40px;
|
||||
}.head-nav ul#header-nav li:first-child{
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li a {
|
||||
|
|
After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 9.7 KiB |
|
@ -2,10 +2,11 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name=”Keywords” Content=”trustie,trustieforge,forge,确实让创建更美好,协同开发平台″>
|
||||
<meta name=”Keywords” Content=”TrustieOpenSourceProject″>
|
||||
<meta name=”Keywords” Content=”issue,bug,tracker,软件工程,课程实践″>
|
||||
<meta name=”Description” Content=”持续构建协同、共享、可信的软件创建生态开源创作与软件生产相结合,支持大规模群体开展软件协同创新活动”>
|
||||
<title>红山开源社区</title>
|
||||
<meta name="keywords" content="红山开源,创客空间,群智共享">
|
||||
<meta name="keywords" content="红山开源社区,开源开放,众创,论坛">
|
||||
<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">
|
||||
|
||||
|
|
34
src/App.js
|
@ -45,6 +45,16 @@ const OpsDetail = Loadable({
|
|||
loader: () => import('./forge/DevOps/opsDetail'),
|
||||
loading: Loading,
|
||||
})
|
||||
// Notice项目公告
|
||||
const Notice = Loadable({
|
||||
loader: () => import('./military/notice'),
|
||||
loading: Loading,
|
||||
})
|
||||
//任务/需求
|
||||
const Task = Loadable({
|
||||
loader: () => import('./military/task'),
|
||||
loading: Loading,
|
||||
})
|
||||
//403页面
|
||||
const Shixunauthority = Loadable({
|
||||
loader: () => import('./modules/403/Shixunauthority'),
|
||||
|
@ -75,6 +85,11 @@ const EducoderLogin = Loadable({
|
|||
loading: Loading,
|
||||
})
|
||||
|
||||
const HomePage = Loadable({
|
||||
loader: () => import('./home'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -121,6 +136,8 @@ class App extends Component {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
document.title = "loading...";
|
||||
this.disableVideoContextMenu();
|
||||
|
@ -240,6 +257,18 @@ class App extends Component {
|
|||
}
|
||||
}
|
||||
/>
|
||||
{/*公告*/}
|
||||
<Route
|
||||
path={"/notice"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<Notice {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/*任务*/}
|
||||
<Route path="/task" component={Task} />
|
||||
|
||||
{/*403*/}
|
||||
<Route path="/403" component={Shixunauthority} />
|
||||
|
||||
|
@ -259,11 +288,12 @@ class App extends Component {
|
|||
(props) => {
|
||||
return (<InfosIndex {...this.props} {...this.state} />)
|
||||
}
|
||||
}></Route>
|
||||
}></Route>
|
||||
<Route exact path="/"
|
||||
render={
|
||||
(props) => (
|
||||
<Projects {...this.props} {...props} {...this.state}></Projects>
|
||||
<HomePage {...props} {...this.props} {...this.state} />
|
||||
// <Projects {...this.props} {...props} {...this.state}></Projects>
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -4,16 +4,14 @@ import { broadcastChannelOnmessage, isDev, queryString } from 'educoder';
|
|||
import { notification } from 'antd';
|
||||
import cookie from 'react-cookies';
|
||||
import './index.css';
|
||||
|
||||
let message501 = false;
|
||||
|
||||
broadcastChannelOnmessage('refreshPage', () => {
|
||||
window.location.reload();
|
||||
window.location.reload()
|
||||
})
|
||||
|
||||
function locationurl(list) {
|
||||
if (window.location.port === "3007") {
|
||||
|
||||
} else {
|
||||
if (window.location.port !== "3007") {
|
||||
window.location.href = list
|
||||
}
|
||||
}
|
||||
|
@ -27,14 +25,14 @@ 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 || 'a'
|
||||
}
|
||||
function clearAllCookie() {
|
||||
cookie.remove('_educoder_session', { path: '/' });
|
||||
cookie.remove('autologin_trustie', { path: '/' });
|
||||
setpostcookie()
|
||||
}
|
||||
clearAllCookie();
|
||||
// clearAllCookie();
|
||||
function setpostcookie() {
|
||||
const str = window.location.pathname;
|
||||
if (str.indexOf("/wxcode") !== -1) {
|
||||
|
@ -54,9 +52,12 @@ setpostcookie();
|
|||
|
||||
window._debugType = debugType;
|
||||
export function initAxiosInterceptors(props) {
|
||||
initOnlineOfflineListener();
|
||||
var proxy = "http://localhost:3000";
|
||||
proxy = "https://testforgeplus.trustie.net";
|
||||
initOnlineOfflineListener()
|
||||
// TODO 避免重复的请求 https://github.com/axios/axios#cancellation
|
||||
var
|
||||
proxy = "http://localhost:3000";
|
||||
proxy = "https://forge.osredm.com";
|
||||
// proxy = "http://117.50.100.12:49999";
|
||||
|
||||
const requestMap = {};
|
||||
window.setfalseInRequestMap = function (keyName) {
|
||||
|
@ -90,7 +91,6 @@ export function initAxiosInterceptors(props) {
|
|||
}
|
||||
if (config.url.indexOf('update_file') === -1) {
|
||||
requestMap[config.url] = true;
|
||||
|
||||
window.setTimeout("setfalseInRequestMap('" + config.url + "')", 900)
|
||||
}
|
||||
return config;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import moment from "moment";
|
||||
import moment from "moment";
|
||||
|
||||
// 处理整点 半点
|
||||
// 取传入时间往后的第一个半点
|
||||
|
@ -12,7 +12,7 @@ export function handleDateString(dateString) {
|
|||
if (miniute < 30 || miniute == 60) {
|
||||
return [ar[0], '30'].join(':')
|
||||
}
|
||||
if (miniute < 60) {
|
||||
if (miniute < 60) {
|
||||
// 加一个小时
|
||||
const tempStr = [ar[0], '00'].join(':');
|
||||
const format = "YYYY-MM-DD HH:mm";
|
||||
|
@ -20,7 +20,7 @@ export function handleDateString(dateString) {
|
|||
_moment.add(1, 'hours')
|
||||
return _moment.format(format)
|
||||
}
|
||||
|
||||
|
||||
return dateString
|
||||
}
|
||||
|
||||
|
@ -38,62 +38,91 @@ export function getNextHalfHourOfMoment(moment) {
|
|||
return moment
|
||||
}
|
||||
|
||||
export function formatSeconds(value) {
|
||||
export function formatSeconds(value) {
|
||||
|
||||
var theTime = parseInt(value);// 秒
|
||||
var middle= 0;// 分
|
||||
var hour= 0;// 小时
|
||||
|
||||
if(theTime > 60) {
|
||||
middle= parseInt(theTime/60);
|
||||
theTime = parseInt(theTime%60);
|
||||
if(middle> 60) {
|
||||
hour= parseInt(middle/60);
|
||||
middle= parseInt(middle%60);
|
||||
}
|
||||
}
|
||||
var result = ""+parseInt(theTime)+"秒";
|
||||
if(middle > 0) {
|
||||
if(hour>0){
|
||||
result = ""+parseInt(middle)+"分";
|
||||
}else{
|
||||
result = ""+parseInt(middle)+"分"+result;
|
||||
}
|
||||
|
||||
}
|
||||
if(hour> 0) {
|
||||
result = ""+parseInt(hour)+"小时"+result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var theTime = parseInt(value);// 秒
|
||||
var middle = 0;// 分
|
||||
var hour = 0;// 小时
|
||||
|
||||
export function formatDuring(mss){
|
||||
var days = parseInt(mss / (1000 * 60 * 60 * 24));
|
||||
var hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||
var minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
|
||||
// console.log("formatDuringformatDuring");
|
||||
// console.log(days);
|
||||
// console.log(hours);
|
||||
// console.log(minutes);
|
||||
// console.log(Math.abs(days));
|
||||
// console.log(Math.abs(hours));
|
||||
// console.log(Math.abs(minutes));
|
||||
if (theTime > 60) {
|
||||
middle = parseInt(theTime / 60);
|
||||
theTime = parseInt(theTime % 60);
|
||||
if (middle > 60) {
|
||||
hour = parseInt(middle / 60);
|
||||
middle = parseInt(middle % 60);
|
||||
}
|
||||
}
|
||||
var result = "" + parseInt(theTime) + "秒";
|
||||
if (middle > 0) {
|
||||
if (hour > 0) {
|
||||
result = "" + parseInt(middle) + "分";
|
||||
} else {
|
||||
result = "" + parseInt(middle) + "分" + result;
|
||||
}
|
||||
|
||||
try {
|
||||
days = Math.abs(days);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
try {
|
||||
hours = Math.abs(hours);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
try {
|
||||
minutes = Math.abs(minutes);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
return days + "天" + hours + "小时" + minutes + "分";
|
||||
}
|
||||
if (hour > 0) {
|
||||
result = "" + parseInt(hour) + "小时" + result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
export function formatDuring(s) {
|
||||
s = Math.abs(s);
|
||||
let days = Math.floor(s / (60 * 60 * 24));
|
||||
let hours = Math.floor((s % (60 * 60 * 24)) / (60 * 60));
|
||||
let minutes = Math.floor((s % (60 * 60)) / (60));
|
||||
let second = Math.floor(s % 60);
|
||||
|
||||
if (days) {
|
||||
if(hours){
|
||||
return days + "天" + hours + "小时";
|
||||
}
|
||||
return days + "天";
|
||||
}
|
||||
if (hours) {
|
||||
if(minutes){
|
||||
return hours + "小时" + minutes + "分";
|
||||
}
|
||||
return hours + "小时" ;
|
||||
}
|
||||
if (minutes) {
|
||||
return minutes + "分";
|
||||
}
|
||||
return second + "秒";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
返回:多久以前
|
||||
backDate:以前的某个日期
|
||||
*/
|
||||
export function timeAgo(backDate) {
|
||||
try {
|
||||
moment(backDate);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
let time = new Date() - moment(backDate);
|
||||
var days = Math.floor(time / (1000 * 60 * 60 * 24));
|
||||
var hours = Math.floor((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||
var minutes = Math.floor((time % (1000 * 60 * 60)) / (1000 * 60));
|
||||
var seconds = Math.floor((time % (1000 * 60 * 60)) / 1000);
|
||||
if (time <= 0) {
|
||||
return "刚刚";
|
||||
}
|
||||
if (days) {
|
||||
return days + "天前";
|
||||
}
|
||||
if (hours) {
|
||||
return hours + "小时前";
|
||||
}
|
||||
if (minutes) {
|
||||
return minutes + "分前";
|
||||
}
|
||||
if (seconds) {
|
||||
return seconds + "秒前";
|
||||
}
|
||||
}
|
|
@ -3,6 +3,6 @@ export function isDev() {
|
|||
}
|
||||
|
||||
// const isMobile
|
||||
export const isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
|
||||
export const isMobile = (/android|webos|iphone|ipad|ipod|blackberry|honor|huawei|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
|
||||
|
||||
// const isWeiXin = (/MicroMessenger/i.test(navigator.userAgent.toLowerCase()));
|
||||
|
|
|
@ -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,12 +6,13 @@ 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}`
|
||||
}
|
||||
|
@ -22,7 +23,7 @@ export function getImage(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(path.indexOf("http://")===-1){
|
||||
if (isDev) {
|
||||
return `${local}/images/${path}`
|
||||
|
@ -33,6 +34,30 @@ export function getImage(path) {
|
|||
}
|
||||
}
|
||||
|
||||
export function getTestImage(path) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
// const local = 'http://localhost:3000'
|
||||
const local = 'http://117.50.100.12:49999';
|
||||
if(path.indexOf("http://")===-1){
|
||||
if (isDev) {
|
||||
return `${local}${path}`
|
||||
}
|
||||
return `${path}`;
|
||||
}else{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
export function getLogoImageUrl(path) {
|
||||
const local = 'http://117.50.100.12:49999';
|
||||
|
||||
if (isDev) {
|
||||
return `${local}/${path}`
|
||||
}
|
||||
return `/${path}`;
|
||||
}
|
||||
|
||||
export function getcdnImageUrl(path) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
|
@ -93,7 +118,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:''}`
|
||||
}
|
||||
|
@ -162,7 +187,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() {
|
||||
|
@ -233,3 +258,9 @@ export function publicSearchs(Placeholder,onSearch,onInputs,onChanges,loadings)
|
|||
allowClear={true}
|
||||
></Search>)
|
||||
}
|
||||
|
||||
export function getUrlToken(name, str) {
|
||||
const reg = new RegExp(`(^|&)${ name}=([^&]*)(&|$)`);
|
||||
const r = str.substr(1).match(reg);
|
||||
if (r != null) return decodeURIComponent(r[2]); return null;
|
||||
}
|
|
@ -6,7 +6,7 @@ export {
|
|||
getUploadLogoActionUrl as getUploadLogoActionUrl,
|
||||
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
|
||||
, getTaskUrlById as getTaskUrlById, TEST_HOST, htmlEncode as htmlEncode, getupload_git_file as getupload_git_file, getcdnImageUrl as getcdnImageUrl,getTestImage as getTestImage,getLogoImageUrl as getLogoImageUrl,getUrlToken as getUrlToken
|
||||
} from './UrlTool';
|
||||
|
||||
export { setmiyah as setmiyah } from './Component';
|
||||
|
@ -27,7 +27,7 @@ export {
|
|||
markdownToHTML, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, isImageExtension,
|
||||
downloadFile, sortDirections, validateLength, mdJSONParse, exportMdtoHtml
|
||||
} from './TextUtil'
|
||||
export { handleDateString, getNextHalfHourOfMoment, formatDuring, formatSeconds } from './DateUtil'
|
||||
export { handleDateString, getNextHalfHourOfMoment, formatDuring, formatSeconds ,timeAgo} from './DateUtil'
|
||||
|
||||
export { configShareForIndex, configShareForPaths, configShareForShixuns, configShareForCourses, configShareForCustom } from './util/ShareUtil'
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class CloneAddress extends Component {
|
|||
const { http_url, downloadUrl } = this.props;
|
||||
return (
|
||||
<div className="gitAddressClone">
|
||||
{/* <p className="addressTips"><span>版本库地址已变更,请基于新地址提交代码</span></p> */}
|
||||
<p className="addressTips"><span>版本库地址已变更,请基于新地址提交代码</span></p>
|
||||
{
|
||||
http_url && <span>HTTP</span>
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
|
||||
|
||||
import React , { useState , useEffect } from 'react';
|
||||
import { Select } from 'antd';
|
||||
import axios from 'axios';
|
||||
|
@ -57,7 +59,6 @@ const LANGUAGE = [
|
|||
|
||||
export default (({ language , select_language })=>{
|
||||
const [ languages , setLanguage ] = useState(undefined);
|
||||
|
||||
// useEffect(()=>{
|
||||
// const url = '/dev_ops/languages.json';
|
||||
// axios.get(url).then(result=>{
|
||||
|
|
|
@ -5,7 +5,7 @@ import './Component.scss';
|
|||
export default (()=>{
|
||||
return(
|
||||
<div className="handleBox">
|
||||
<a href="https://forum.trustie.net/forums/3075/detail" target="_blank" >
|
||||
<a href="https://www.osredm.com/forums/594/detail" target="_blank" >
|
||||
<img src={Handbook} alt=""/>
|
||||
</a>
|
||||
</div>
|
||||
|
|
Before Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 222 KiB |
|
@ -145,7 +145,7 @@ class CoderRootCommit extends Component{
|
|||
)
|
||||
})
|
||||
}
|
||||
{commitDatas && commitDatas.length > 0 && <Nodata _html="暂无数据"/>}
|
||||
{commitDatas && commitDatas.length === 0 && <Nodata _html="暂无数据"/>}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
|
|
|
@ -251,7 +251,7 @@ class CoderRootDirectory extends Component {
|
|||
// readme文件内容
|
||||
renderReadMeContent = (readMeContent, permission) => {
|
||||
const { fileDetail, readMeFile } = this.state;
|
||||
if (fileDetail) {
|
||||
if (fileDetail && fileDetail.length !== 0) {
|
||||
return;
|
||||
}
|
||||
if (readMeContent && readMeContent.length > 0) {
|
||||
|
|
|
@ -4,6 +4,7 @@ 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';
|
||||
|
@ -117,19 +118,20 @@ const DevIndex = Loadable({
|
|||
function checkPathname(projectsId,owner,pathname){
|
||||
let name = "";
|
||||
if(pathname && pathname !== `/projects/${owner}/${projectsId}`){
|
||||
if(pathname.indexOf("/about")>-1){
|
||||
let url = pathname.split(`/projects/${owner}/${projectsId}`)[1];
|
||||
if(url.indexOf("/about")>-1){
|
||||
name="about"
|
||||
}else if(pathname.indexOf("/issues")>-1 ||pathname.indexOf("Milepost") > 0){
|
||||
}else if(url.indexOf("/issues")>-1 ||url.indexOf("Milepost") > 0){
|
||||
name = "issues";
|
||||
}else if(pathname.indexOf("/pulls")>-1){
|
||||
}else if(url.indexOf("/pulls")>-1){
|
||||
name="pulls"
|
||||
}else if(pathname.indexOf("/milestones")>-1){
|
||||
}else if(url.indexOf("/milestones")>-1){
|
||||
name="milestones"
|
||||
}else if(pathname.indexOf("/activity")>-1){
|
||||
}else if(url.indexOf("/activity")>-1){
|
||||
name="activity"
|
||||
}else if(pathname.indexOf("/setting")>-1){
|
||||
}else if(url.indexOf("/setting")>-1){
|
||||
name="setting"
|
||||
}else if(pathname.indexOf(`/devops`)>-1){
|
||||
}else if(url.indexOf(`/devops`)>-1){
|
||||
name="devops"
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +163,9 @@ class Detail extends Component {
|
|||
defaultBranch:undefined,
|
||||
|
||||
// 非本平台项目
|
||||
platform:false
|
||||
platform:false,
|
||||
visible:false,
|
||||
user_apply_signatures:[]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,6 +182,7 @@ 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) => {
|
||||
|
@ -187,6 +192,24 @@ class Detail extends Component {
|
|||
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 --------");
|
||||
|
@ -357,13 +380,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 , open_devops , platform , defaultBranch } = this.state;
|
||||
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);
|
||||
|
@ -390,18 +424,19 @@ class Detail extends Component {
|
|||
}
|
||||
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 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={`${project.author.type ==="Organization" ? "/organize":'/users'}/${project.author.login}`} className="show-user-link">
|
||||
<Link to={`/users/${project.author.login}`} className="show-user-link color-white">
|
||||
{project.author.name}
|
||||
</Link>
|
||||
}
|
||||
<span className="ml5 mr5">/</span>
|
||||
<span className="hide-1 flex-1 df">
|
||||
<Link to={`/projects/${owner}/${projectsId}`} className="font-22">{project && project.name}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}`} className="color-white font-22">{project && project.name}</Link>
|
||||
{
|
||||
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
||||
<Tooltip placement={'right'} title={text}>
|
||||
|
@ -438,15 +473,14 @@ class Detail extends Component {
|
|||
<span>{watched ? '取消关注' : '关注'}</span>
|
||||
</a>
|
||||
{
|
||||
watchers_count > 0 ?
|
||||
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" style={{cursor:platform?"pointer":"default"}} onClick={() => this.pariseFunc(praised)}>
|
||||
|
@ -454,13 +488,11 @@ class Detail extends Component {
|
|||
<span>{praised ? '取消点赞' : '点赞'}</span>
|
||||
</a>
|
||||
{
|
||||
praises_count > 0 ?
|
||||
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">
|
||||
|
@ -468,14 +500,12 @@ class Detail extends Component {
|
|||
<i className="iconfont icon-fork color-grey-9 mr3"></i>复刻 (Fork)
|
||||
</a>
|
||||
{
|
||||
forked_count > 0 ?
|
||||
platform ?
|
||||
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${owner}/${projectsId}/fork_users`, state }}>
|
||||
{forked_count}
|
||||
</Link>
|
||||
:
|
||||
<span className="detail_tag_btn_count">{forked_count}</span>
|
||||
:""
|
||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||
}
|
||||
</span>
|
||||
</span>
|
||||
|
@ -483,23 +513,23 @@ class Detail extends Component {
|
|||
</div>
|
||||
{
|
||||
firstSync ? "" :
|
||||
<div className="f-wrap-between mt15">
|
||||
<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==="" || urlFlag) ? "iconfont icon-zhuye1 color-grey-3 mr5 font-14":"iconfont icon-zhuye1 color-grey-6 font-14 mr5"}></i>
|
||||
<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 }}>
|
||||
<i className={(pathname==="" || urlFlag) ? "iconfont icon-daimaku color-grey-3 mr5 font-14":"iconfont icon-daimaku color-grey-6 font-14 mr5"}></i>
|
||||
<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 }}>
|
||||
<i className={pathname==="issues" ? "iconfont icon-renwu color-grey-3 mr5 font-14":"iconfont icon-renwu color-grey-6 font-14 mr5"}></i>
|
||||
<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>
|
||||
|
@ -508,32 +538,32 @@ class Detail extends Component {
|
|||
projectDetail && parseInt(projectDetail.type) !== 2 && platform &&
|
||||
<li className={pathname==="pulls" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/pulls`, state }}>
|
||||
<i className={pathname==="pulls" ? "iconfont icon-hebingqingqiu1 color-grey-3 mr5 font-14":"iconfont icon-hebingqingqiu1 color-grey-6 font-14 mr5"}></i>
|
||||
<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>
|
||||
}
|
||||
{
|
||||
{/* {
|
||||
platform &&
|
||||
<li className={pathname==="devops" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/devops${open_devops ? `/dispose`:""}`, state }}>
|
||||
<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 }}>
|
||||
<i className={pathname==="milestones" ? "iconfont icon-lichengbei color-grey-3 mr5 font-14":"iconfont icon-lichengbei color-grey-6 font-14 mr5"}></i>
|
||||
<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 }}>
|
||||
<i className={pathname==="activity" ? "iconfont icon-tongzhi color-grey-3 mr5 font-14":"iconfont icon-tongzhi color-grey-6 font-14 mr5"}></i>
|
||||
<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>
|
||||
|
@ -541,7 +571,7 @@ class Detail extends Component {
|
|||
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-grey-3 mr5 font-14":"iconfont icon-cangku color-grey-6 font-14 mr5"}></i>
|
||||
<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>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Menu, Input , Spin, Pagination , Popover , Select } from 'antd';
|
||||
import { getUrl } from 'educoder';
|
||||
import { Menu, Input , Spin, Pagination , Popover, Affix, } from 'antd';
|
||||
import '../css/index.scss'
|
||||
import './list.css';
|
||||
import './Index.scss';
|
||||
|
@ -9,7 +8,7 @@ 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.jpg';
|
||||
import banner from '../Images/banner_list.png';
|
||||
const Search = Input.Search;
|
||||
|
||||
class Index extends Component {
|
||||
|
@ -23,7 +22,6 @@ class Index extends Component {
|
|||
sort: undefined,
|
||||
total: 0,
|
||||
isSpin: true,
|
||||
project_type: undefined,
|
||||
category_id: undefined,
|
||||
|
||||
typeList: undefined,
|
||||
|
@ -37,8 +35,8 @@ class Index extends Component {
|
|||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
const { page, limit, search, sort, project_type, category_id , languageId } = this.state;
|
||||
this.getListData(page, limit, search, sort, project_type, category_id , languageId);
|
||||
const { page,search, sort,category_id , languageId } = this.state;
|
||||
this.getListData(page,search, sort,category_id , languageId);
|
||||
|
||||
this.getType();
|
||||
|
||||
|
@ -73,19 +71,24 @@ class Index extends Component {
|
|||
}
|
||||
|
||||
// 获取列表
|
||||
getListData = (page, limit, search, sort, project_type, category_id,languageId) => {
|
||||
getListData = (page,search, sort,category_id,language_id) => {
|
||||
const { current_user } = this.props;
|
||||
const url = `/projects.json`;
|
||||
if(category_id==0){
|
||||
category_id=undefined;
|
||||
}
|
||||
if(language_id==0){
|
||||
language_id=undefined;
|
||||
}
|
||||
axios.get(url, {
|
||||
params: {
|
||||
user_id: current_user && current_user.user_id,
|
||||
page,
|
||||
limit,
|
||||
limit:15,
|
||||
search,
|
||||
sort_by: sort,
|
||||
project_type,
|
||||
category_id,
|
||||
language_id:languageId
|
||||
language_id
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
|
@ -103,7 +106,11 @@ class Index extends Component {
|
|||
const url = `/projects/group_type_list.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
this.setTypeList(result.data, undefined)
|
||||
result.data.unshift({
|
||||
name:'全部语言',
|
||||
id:0,
|
||||
});
|
||||
this.setTypeList(result.data, 0)
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}
|
||||
|
@ -112,7 +119,7 @@ class Index extends Component {
|
|||
this.setState({
|
||||
typeList: list.map((item, key) => {
|
||||
return (
|
||||
<li key={key} className={active_type && active_type === item.project_type ? 'active' : ''} onClick={() => this.changeType(`${item.project_type}`, list)}>
|
||||
<li key={key} className={ 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>
|
||||
|
@ -123,16 +130,16 @@ class Index extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
// 切换类型
|
||||
changeType = (type, list) => {
|
||||
// 切换语言类型
|
||||
changeType = (id, list) => {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
project_type: type,
|
||||
languageId: id,
|
||||
search: undefined
|
||||
})
|
||||
this.setTypeList(list, type)
|
||||
const { page, limit, sort, category_id , languageId } = this.state;
|
||||
this.getListData(page, limit, undefined, sort, type, category_id , languageId);
|
||||
this.setTypeList(list, id);
|
||||
const { page,sort, category_id} = this.state;
|
||||
this.getListData(page,undefined, sort,category_id , id);
|
||||
}
|
||||
|
||||
// 获取类型
|
||||
|
@ -141,7 +148,11 @@ class Index extends Component {
|
|||
|
||||
axios.get(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
this.setCategoryList(result.data, undefined);
|
||||
result.data.unshift({
|
||||
name:'全部类别',
|
||||
id:0,
|
||||
});
|
||||
this.setCategoryList(result.data, 0);
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}
|
||||
|
@ -150,7 +161,7 @@ class Index extends Component {
|
|||
this.setState({
|
||||
categoryList: list.map((item, key) => {
|
||||
return (
|
||||
<li key={key} className={active_id && parseInt(active_id) === item.id ? 'active' : ''} onClick={() => this.changeCategory(`${item.id}`, list)}>
|
||||
<li key={key} className={ 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>
|
||||
|
@ -167,8 +178,8 @@ class Index extends Component {
|
|||
page: 1
|
||||
});
|
||||
this.setCategoryList(list, id)
|
||||
const { limit, sort, project_type , languageId } = this.state;
|
||||
this.getListData(1, limit, undefined, sort, project_type, id , languageId);
|
||||
const { sort,languageId } = this.state;
|
||||
this.getListData(1,undefined, sort,id , languageId);
|
||||
}
|
||||
|
||||
// 排序
|
||||
|
@ -179,8 +190,8 @@ class Index extends Component {
|
|||
search: undefined,
|
||||
isSpin: true
|
||||
})
|
||||
const { limit, project_type, category_id , languageId } = this.state;
|
||||
this.getListData(1, limit, undefined, e.key, project_type, category_id , languageId);
|
||||
const {category_id , languageId } = this.state;
|
||||
this.getListData(1,undefined, e.key,category_id , languageId);
|
||||
}
|
||||
|
||||
// 搜索
|
||||
|
@ -192,8 +203,8 @@ class Index extends Component {
|
|||
project_type: undefined,
|
||||
sort: "updated_on"
|
||||
})
|
||||
const { limit, sort, category_id , languageId } = this.state;
|
||||
this.getListData(1, limit, value, sort, undefined, category_id , languageId);
|
||||
const {sort, category_id , languageId } = this.state;
|
||||
this.getListData(1,value, sort,category_id , languageId);
|
||||
}
|
||||
changeSearchValue = (e) => {
|
||||
this.setState({
|
||||
|
@ -205,23 +216,14 @@ class Index extends Component {
|
|||
this.setState({
|
||||
page
|
||||
})
|
||||
const { limit, search, sort, project_type, category_id , languageId } = this.state;
|
||||
this.getListData(page, limit, search, sort, project_type, category_id , languageId);
|
||||
const {search, sort,category_id , languageId } = this.state;
|
||||
this.getListData(page,search, sort, category_id , languageId);
|
||||
}
|
||||
|
||||
getoDetail=(login,identifier)=>{
|
||||
this.props.history.push(`/projects/${login}/${identifier}`);
|
||||
}
|
||||
|
||||
// 选择语言类别
|
||||
changeLanguage=(e)=>{
|
||||
this.setState({
|
||||
isSpin:true,
|
||||
languageId:e === 0 ?undefined:e
|
||||
})
|
||||
const { page, limit, sort , project_type , category_id } = this.state;
|
||||
this.getListData(page, limit, undefined, sort, project_type, category_id ,e === 0 ?undefined:e);
|
||||
}
|
||||
|
||||
menu =()=> {
|
||||
return(
|
||||
|
@ -255,15 +257,14 @@ class Index extends Component {
|
|||
render() {
|
||||
const { current_user } = this.props;
|
||||
|
||||
const { projectsList , recommendList , languageList , languageId ,
|
||||
isSpin, total, search, limit, page, typeList, categoryList } = this.state;
|
||||
const { projectsList , isSpin , total , search , limit , page , typeList , categoryList } = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p className="t_project_banner">
|
||||
<img src={banner} width="100%" alt=""/>
|
||||
</p>
|
||||
{
|
||||
{/* {
|
||||
recommendList && recommendList.length>0 &&
|
||||
<div className="recommandProjects">
|
||||
{
|
||||
|
@ -285,44 +286,29 @@ class Index extends Component {
|
|||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
*/}
|
||||
<div className="ProjectListIndex">
|
||||
<div className="list-left">
|
||||
|
||||
<Affix className="affix-list-left" offsetTop={90}>
|
||||
<div className="affix-list-content">
|
||||
<ul className="list-l-Menu">
|
||||
<li className="MenuTitle"><i className="iconfont icon-xiangmuleixing color-grey-9 font-15 mr5"></i>项目类型</li>
|
||||
{typeList}
|
||||
<li className="MenuTitle" onClick={() => {this.getType();this.changeType(undefined, this.state.typeList);}}>
|
||||
<span><i className="iconfont icon-bianchengyuyan color-grey-9 font-15 mr5"></i>
|
||||
语言</span></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>
|
||||
{categoryList}
|
||||
<li className="MenuTitle" onClick={() => {this.getCategory();this.changeCategory(undefined, this.state.categoryList);}}>
|
||||
<span><i className="iconfont icon-xiangmuleibie color-grey-9 font-15 mr5"></i>项目类别</span></li>
|
||||
<div className="list-affix">{categoryList}</div>
|
||||
</ul>
|
||||
</div>
|
||||
</Affix>
|
||||
|
||||
<div className="list-right boxShandow radius-2" style={{padding:0}}>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="list-r-operation">
|
||||
<div>
|
||||
<Select
|
||||
showSearch
|
||||
placeholder="请选择语言"
|
||||
style={{width:"150px",marginRight:"20px"}}
|
||||
size={"large"}
|
||||
onChange={this.changeLanguage}
|
||||
value={languageId}
|
||||
allowClear={true}
|
||||
optionFilterProp="children"
|
||||
filterOption={(input,option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
|
||||
>
|
||||
<Select.Option key={0} value={0}>请选择语言</Select.Option>
|
||||
{
|
||||
languageList && languageList.length>0 && languageList.map((item,key)=>{
|
||||
return(
|
||||
<Select.Option key={item.id} value={item.id}>
|
||||
{item.name}
|
||||
</Select.Option>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Select>
|
||||
<Search
|
||||
placeholder="输入项目名称关键字进行搜索"
|
||||
enterButton="搜索"
|
||||
|
@ -350,7 +336,7 @@ class Index extends Component {
|
|||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
<ListItem {...this.props} {...this.state} projects={projectsList}></ListItem>
|
||||
<ListItem {...this.props} {...this.state} projects={projectsList} getListData={this.getListData}></ListItem>
|
||||
{this.pagination(total,limit,page)}
|
||||
</Spin>
|
||||
</div>
|
||||
|
|
|
@ -71,4 +71,16 @@
|
|||
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,72 +6,123 @@ 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;
|
||||
return (
|
||||
<div className="project-list minH-670">
|
||||
{ projects && projects.length > 0 ? projects.map((item, key) => {
|
||||
return (
|
||||
<div className="p-r-Item" key={key}>
|
||||
{
|
||||
item.platform === "educoder" ?
|
||||
<a href="javascript:void(0)" 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 " style={{ whiteSpace: "wrap", display: 'flex', width: 400 }}>
|
||||
{item.author.name}/{item.name}
|
||||
{
|
||||
item.forked_from_project_id ?
|
||||
<span className="ml5">
|
||||
<i className="iconfont icon-fork font-18 color-orange" />
|
||||
</span>
|
||||
: ""
|
||||
}
|
||||
{
|
||||
item.type && item.type !== 0 ?
|
||||
item.type === 2 ?
|
||||
<Tooltip title="该项目是一个镜像" className="ml5">
|
||||
<i className="iconfont icon-banbenku font-18 color-green" />
|
||||
</Tooltip>:
|
||||
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}>
|
||||
{
|
||||
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">
|
||||
<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 ?
|
||||
<span className="ml5">
|
||||
<i className="iconfont icon-jingxiang font-18 color-green" />
|
||||
</span>:""
|
||||
}
|
||||
</Link>
|
||||
<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>
|
||||
</div>
|
||||
<p className="break_word task-hide-2 mt10" style={{ maxHeight: "44px",lineHeight:"22px" }}>{item.description}</p>
|
||||
<i className="iconfont icon-fork font-18 color-orange" />
|
||||
</span>
|
||||
: ""
|
||||
}
|
||||
{
|
||||
item.type && item.type !== 0 ?
|
||||
item.type === 2 ?
|
||||
<Tooltip title="该项目是一个镜像" className="ml5">
|
||||
<i className="iconfont icon-banbenku font-18 color-green" />
|
||||
</Tooltip>:
|
||||
<span className="ml5">
|
||||
<i className="iconfont icon-jingxiang font-18 color-green" />
|
||||
</span>:""
|
||||
}
|
||||
</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>
|
||||
</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>{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>
|
||||
<div className="p-r-about">
|
||||
<span className="p-r-detail">
|
||||
{/* <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>
|
||||
</div>
|
||||
)
|
||||
}) : <Nodata _html="暂无数据~"></Nodata>}
|
||||
</div>
|
||||
)
|
||||
}) : <Nodata _html="暂无数据~"></Nodata>
|
||||
)
|
||||
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;
|
|
@ -18,6 +18,14 @@
|
|||
box-sizing: border-box;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.affix-list-left{
|
||||
width: 26%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.affix-list-content{
|
||||
padding-right:20px;
|
||||
}
|
||||
.list-right{
|
||||
width:74%;
|
||||
background: #fff;
|
||||
|
@ -208,9 +216,7 @@
|
|||
}
|
||||
/* -----------详情------------ */
|
||||
.detailHeader-wrapper{
|
||||
background-color:#FAFBFC;
|
||||
/* background: url(../Images/forgeBanner.jpg) no-repeat center; */
|
||||
/* background-size:cover; */
|
||||
background:linear-gradient(82deg,rgba(82,91,215,1) 0%,rgba(34,24,171,1) 100%);
|
||||
}
|
||||
.headerMenu-wrapper{
|
||||
font-size: 16px;
|
||||
|
@ -222,36 +228,42 @@
|
|||
text-align: center;
|
||||
height: 40px;
|
||||
line-height: 28px;
|
||||
margin-right: 40px;
|
||||
border:1px solid transparent;
|
||||
}
|
||||
.headerMenu-wrapper{
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.headerMenu-wrapper li{
|
||||
padding:0px 18px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.headerMenu-wrapper li a{
|
||||
color: #666;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.headerMenu-wrapper li a > img{
|
||||
margin-right: 8px;
|
||||
}
|
||||
.headerMenu-wrapper li a > span.num{
|
||||
height: 28px;
|
||||
line-height: 29px;
|
||||
margin-left: 8px;
|
||||
font-size: 12px;
|
||||
color: #2878FF;
|
||||
float: right;
|
||||
.headerMenu-wrapper li a > span{
|
||||
display: block;
|
||||
margin-left: 5px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.headerMenu-wrapper li.active::after{
|
||||
position: absolute;
|
||||
bottom:0px;
|
||||
height:2px;
|
||||
background-color: #5091FF;
|
||||
content:'';
|
||||
left: 0px;
|
||||
width:100%;
|
||||
.headerMenu-wrapper li.active{
|
||||
border-radius: 15px;
|
||||
border:1px solid #71A6FF;
|
||||
}
|
||||
.detail_tag_btn{
|
||||
height:26px;
|
||||
line-height: 26px;
|
||||
border-radius:5px;
|
||||
border:1px solid #f1f1f1;
|
||||
border:1px solid #71A6FF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 30px
|
||||
|
@ -259,19 +271,26 @@
|
|||
.ant-tooltip {
|
||||
max-width: fit-content!important;
|
||||
}
|
||||
|
||||
.detail_tag_btn_name{
|
||||
padding:0px 10px;
|
||||
color: #666!important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
}
|
||||
.detail_tag_btn_name img{
|
||||
margin-right: 10px;
|
||||
}
|
||||
.detail_tag_btn_count{
|
||||
padding:0px 10px;
|
||||
background: #fff;
|
||||
color: #fff !important;
|
||||
background: rgba(255,255,255,0.2);
|
||||
border-radius: 0px 4px 4px 0px;
|
||||
font-size: 12px;
|
||||
height:100%;
|
||||
}
|
||||
.detail_tag_btn_count:hover{
|
||||
/* color: #1C91FF !important; */
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
.files-md{
|
||||
border:1px solid #eee;
|
||||
|
|
|
@ -47,7 +47,7 @@ function Files({data,history,owner,projectsId}){
|
|||
<span>{item.name}</span>
|
||||
</AlignCenter>
|
||||
<span>
|
||||
<Button className="mr20" onClick={()=>{history.push(`/projects/${owner}/${projectsId}${item.sha ? `/branch/${truncateCommitId(item.sha)}/`:"/"}tree/${item.name}`)}}>查看文件</Button>
|
||||
<Button className="mr20" onClick={()=>{history.push(`/projects/${owner}/${projectsId}/tree/${truncateCommitId(item.sha)}/${item.name}`)}}>查看文件</Button>
|
||||
<span className="color-green">+{item.addition}</span>
|
||||
<span className="color-red ml20">-{item.deletion}</span>
|
||||
</span>
|
||||
|
|
|
@ -43,7 +43,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 = () => {
|
||||
|
@ -145,7 +147,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>
|
||||
));
|
||||
|
@ -155,6 +157,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) {
|
||||
|
@ -198,7 +211,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,
|
||||
|
@ -272,6 +286,7 @@ class Index extends Component {
|
|||
project_category_list,
|
||||
license_list,
|
||||
ignore_list,
|
||||
licenseForDisabled,
|
||||
|
||||
mirrorCheck
|
||||
} = this.state;
|
||||
|
@ -477,8 +492,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 >
|
||||
{
|
||||
|
|
|
@ -15,8 +15,8 @@ const MENU_LIST = [
|
|||
function CollaboratorMember({projectsId,owner,project_id,author,showNotification,newId}){
|
||||
const [ roleName , setRoleName ] = useState(undefined);
|
||||
const [ search , setSearch ] = useState(undefined);
|
||||
const [ page , setPage ] = useState(undefined);
|
||||
const [ isSpin , setIsSpin ] = useState(false);
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ isSpin , setIsSpin ] = useState(true);
|
||||
const [ role , setRole ] = useState(undefined);
|
||||
const [ listData , setListData ] = useState(undefined);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
|
@ -166,7 +166,11 @@ function CollaboratorMember({projectsId,owner,project_id,author,showNotification
|
|||
<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}
|
||||
|
@ -261,14 +265,8 @@ function CollaboratorMember({projectsId,owner,project_id,author,showNotification
|
|||
</div>
|
||||
</Spin>
|
||||
{total > LIMIT ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
<Pagination
|
||||
showQuickJumper
|
||||
pageSize={LIMIT}
|
||||
current={page}
|
||||
total={total}
|
||||
onChange={()=>setPage(page)}
|
||||
></Pagination>
|
||||
<div className="edu-txt-center mt20 pb20">
|
||||
<Pagination simple current={page} pageSize={LIMIT} total={total} onChange={(page)=>setPage(page)}/>
|
||||
</div>
|
||||
:""}
|
||||
</React.Fragment>
|
||||
|
|
|
@ -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,6 +44,7 @@ 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 (
|
||||
|
@ -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={
|
||||
|
@ -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) => (
|
||||
|
|
|
@ -15,6 +15,7 @@ class Setting extends Component {
|
|||
CategoryList: undefined,
|
||||
LanguageList: undefined,
|
||||
private_check: undefined,
|
||||
is_secret:false
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -52,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
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -152,7 +154,7 @@ 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 style={{paddingBottom:"20px"}}>
|
||||
|
@ -177,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;
|
|
@ -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;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { Component } from "react";
|
||||
import { Upload, Button, Icon } from 'antd';
|
||||
import { Upload , Icon } from 'antd';
|
||||
import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder';
|
||||
|
||||
import axios from 'axios';
|
||||
|
@ -45,8 +45,7 @@ class Index extends Component {
|
|||
deleteAttachment = (file) => {
|
||||
|
||||
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
|
||||
axios.delete(url, {
|
||||
}).then((response) => {
|
||||
axios.delete(url).then((response) => {
|
||||
if (response.data) {
|
||||
if (response.data.status === 0) {
|
||||
this.setState((state) => {
|
||||
|
@ -71,11 +70,26 @@ class Index extends Component {
|
|||
handleChange = (info) => {
|
||||
const { changeIsComplete } = this.props;
|
||||
changeIsComplete && changeIsComplete(true);
|
||||
|
||||
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
|
||||
let fileList = info.fileList;
|
||||
|
||||
this.setState({ fileList: appendFileSizeToUploadFileAll(fileList) });
|
||||
this.fileIdList(fileList);
|
||||
|
||||
if ( info.file.status === 'done') {
|
||||
let filelist = info.fileList && info.fileList.length>0 && info.fileList[info.fileList.length-1];
|
||||
if(filelist && filelist.response && filelist.response.status === -1){
|
||||
this.props.showNotification(filelist.response.message)
|
||||
this.setState((state) => {
|
||||
state.fileList.pop()
|
||||
return {
|
||||
fileList: state.fileList,
|
||||
};
|
||||
});
|
||||
this.fileIdList(this.state.fileList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
import React, { useEffect , useState } from "react";
|
||||
import { Upload } from 'antd';
|
||||
import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
function Single({ children , showNotification , className , load , size }) {
|
||||
const [ fileList , setFileList ] = useState(undefined);
|
||||
// 移除
|
||||
function onAttachmentRemove(file){
|
||||
if (!file.percent || file.percent === 100) {
|
||||
deleteAttachment(file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function deleteAttachment(file){
|
||||
let uid = file.response ? file.response.id : file.uid;
|
||||
const url = `/attachments/${uid}.json`
|
||||
axios.delete(url).then((response) => {
|
||||
if (response.data && response.data.status === 0) {
|
||||
let list = fileList.filter(item=> item.response && item.response.id !== uid);
|
||||
setFileList(list);
|
||||
fileIdList(list);
|
||||
}
|
||||
}).catch(error=>{});
|
||||
}
|
||||
|
||||
|
||||
function handleChange(info){
|
||||
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
|
||||
let fileList = [info.file];
|
||||
|
||||
let list = appendFileSizeToUploadFileAll(fileList);
|
||||
setFileList(list);
|
||||
if ( info.file.status === 'done') {
|
||||
let f = info.fileList && info.fileList.length>0 && info.fileList[info.fileList.length-1];
|
||||
if(f && f.response && f.response.status === -1){
|
||||
showNotification(f.response.message)
|
||||
setFileList(f);
|
||||
}
|
||||
fileIdList(fileList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fileIdList(fileList){
|
||||
let l = fileList && fileList.length > 0 && fileList[0];
|
||||
let array = [l && l.response && l.response.id];
|
||||
load && load(array);
|
||||
}
|
||||
|
||||
function beforeUpload(file){
|
||||
if(!size) return;
|
||||
const isLt100M = file.size / 1024 / 1024 < size;
|
||||
if (!isLt100M) {
|
||||
showNotification(`文件大小必须小于${size}MB!`);
|
||||
}
|
||||
return isLt100M;
|
||||
}
|
||||
|
||||
//判断是否已经提交,如已提交评论则上一条评论数据清除
|
||||
const upload = {
|
||||
name: 'file',
|
||||
fileList: fileList,
|
||||
action: `${getUploadActionUrl()}`,
|
||||
onChange: handleChange,
|
||||
onRemove: onAttachmentRemove,
|
||||
beforeUpload: beforeUpload
|
||||
};
|
||||
|
||||
return (
|
||||
<Upload {...upload} className={className}>
|
||||
{children}
|
||||
</Upload>
|
||||
)
|
||||
}
|
||||
export default Single;
|
|
@ -1,21 +0,0 @@
|
|||
|
||||
1.请求URL: https://code.ihub.org.cn/api/v1/mirrors/create.json
|
||||
|
||||
2.请求方式: POST
|
||||
|
||||
3.参数:
|
||||
|
||||
{
|
||||
"image_url": "xxx.git", #必填,且后缀必为.git,
|
||||
"language": "Ruby", #必填,如数据库不存在,则会创建新的记录
|
||||
}
|
||||
|
||||
|
||||
4. 返回值: {
|
||||
"status": 1,
|
||||
"message": "同步成功,项目ID===1806"
|
||||
}
|
||||
|
||||
5. 返回值说明: 仅有当有返回值,且返回值的status 的值为1, 才是创建成功,其余均为创建失败
|
||||
|
||||
|
|
@ -62,6 +62,9 @@
|
|||
.text-yellow{
|
||||
color: #FFA802 !important
|
||||
}
|
||||
.text-grey{
|
||||
color: #999;
|
||||
}
|
||||
.text-gray {
|
||||
color: #888888;
|
||||
}
|
||||
|
|
|
@ -166,7 +166,12 @@ form{
|
|||
margin-bottom: 12px;
|
||||
border-radius:2px;
|
||||
background-color: #fff;
|
||||
&>li{
|
||||
.list-affix{
|
||||
min-height: 20px;
|
||||
max-height: 240px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
& li{
|
||||
font-size: 1rem;
|
||||
padding:0px 0px 0px 20px;
|
||||
box-sizing: border-box;
|
||||
|
@ -205,7 +210,7 @@ form{
|
|||
width: 6px;
|
||||
content: '';
|
||||
height: 33px;
|
||||
background: #4CACFF;
|
||||
background: #1484EF;
|
||||
}
|
||||
.MenuTitle{
|
||||
font-size: 16px;
|
||||
|
@ -215,6 +220,21 @@ form{
|
|||
line-height: 62px;
|
||||
border-bottom: 1px solid #E0E0E0;
|
||||
font-weight: 400;
|
||||
|
||||
span{
|
||||
display: block;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span:hover{
|
||||
color: #1484EF;
|
||||
|
||||
.iconfont{
|
||||
color: #1484EF !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ant-menu-inline{
|
||||
border:none;
|
||||
|
|
|
@ -6,7 +6,6 @@ import { withRouter } from "react-router";
|
|||
import { SnackbarHOC } from "educoder";
|
||||
import { CNotificationHOC } from "../../modules/courses/common/CNotificationHOC";
|
||||
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
|
||||
import Handbook from '../Component/Handbook';
|
||||
const Infos = Loadable({
|
||||
loader: () => import("./Infos"),
|
||||
loading: Loading,
|
||||
|
@ -15,7 +14,6 @@ export default withRouter(
|
|||
(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC((props)=>{
|
||||
return(
|
||||
<div>
|
||||
<Handbook />
|
||||
<Switch>
|
||||
<Route
|
||||
path="/users/:username"
|
||||
|
@ -27,4 +25,4 @@ export default withRouter(
|
|||
</div>
|
||||
)
|
||||
}))))
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import React, { Component } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Avatar, Tag, Button, Spin } from "antd";
|
||||
import FocusButton from "../UsersList/focus_button";
|
||||
|
||||
|
@ -52,7 +51,7 @@ class Infos extends Component {
|
|||
isSpin: false,
|
||||
user: undefined,
|
||||
project_type: undefined,
|
||||
route_type: undefined
|
||||
route_type: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -138,7 +137,7 @@ class Infos extends Component {
|
|||
|
||||
|
||||
render() {
|
||||
const { current_user, mygetHelmetapi } = this.props;
|
||||
const { current_user, main_web_site_url } = this.props;
|
||||
const { username } = this.props.match.params;
|
||||
|
||||
const { user, isSpin, project_type, route_type } = this.state;
|
||||
|
@ -147,7 +146,7 @@ class Infos extends Component {
|
|||
<Spin spinning={isSpin}>
|
||||
<div className="new-content-flex">
|
||||
<div className="list-left">
|
||||
<div className="bgcF">
|
||||
<div className="bgcF mb20">
|
||||
<div className="list-l-Menu text-center pd20 ">
|
||||
<Avatar
|
||||
size={110}
|
||||
|
@ -168,11 +167,7 @@ class Infos extends Component {
|
|||
<Button
|
||||
block
|
||||
className="text-button-grey"
|
||||
href={`${
|
||||
mygetHelmetapi &&mygetHelmetapi.new_course&&
|
||||
mygetHelmetapi.new_course.edit_account
|
||||
}`}
|
||||
target="_blank"
|
||||
href={`${main_web_site_url || "https://osredm.com/"}users/${user.login}/profiles`}
|
||||
>
|
||||
{" "}
|
||||
<i className="iconfont icon-shezhi4 font-15 mr5"></i>
|
||||
|
@ -193,22 +188,22 @@ class Infos extends Component {
|
|||
)}
|
||||
</div>
|
||||
<div className="width100 inline-block mt20">
|
||||
<Link
|
||||
to={`/users/${user && user.login}/watchers`}
|
||||
<a
|
||||
href={`/users/${user && user.login}/user_watchlist`}
|
||||
className={`with50 text-center pull-left ${route_type === "watchers" ? "text-primary" : ""}`}
|
||||
onClick={() =>this.route_link("watchers")}
|
||||
>
|
||||
<div>{current_user && user && user.login === current_user.login ? "我关注的" : "TA关注的"}</div>
|
||||
<span>{user && user.watching_count}</span>
|
||||
</Link>
|
||||
<Link
|
||||
to={`/users/${user && user.login}/fan_users`}
|
||||
</a>
|
||||
<a
|
||||
href={`/users/${user && user.login}/user_fanslist`}
|
||||
onClick={() =>this.route_link("fan_users")}
|
||||
className={`with50 text-center pull-left ${route_type === "fan_users" ? "text-primary" : ""}`}
|
||||
>
|
||||
<div>{current_user && user && user.login === current_user.login ? "关注我的" : "关注TA的"}</div>
|
||||
<span>{user && user.watched_count}</span>
|
||||
</Link>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -230,7 +225,7 @@ class Infos extends Component {
|
|||
|
||||
<div className="bgcF">
|
||||
<ul className="list-l-Menu">
|
||||
<li className="MenuTitle" onClick={() => this.change_project_type(undefined)}>
|
||||
<li className="MenuTitle" onClick={() => this.change_project_type()}>
|
||||
<i className="iconfont icon-xiangmuleixing font-15 mr5"></i>
|
||||
项目类型
|
||||
<i className="iconfont icon-youjiantou font-15 mr20 color-grey-9 pull-right"></i>
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
import React, { memo, useState, useEffect } from 'react';
|
||||
import { Collapse, Button } from 'antd';
|
||||
import moment from 'moment';
|
||||
import Line from '../Line';
|
||||
import { getTaskCategory, getTaskList } from '../../military/task/api';
|
||||
import { taskModeIdArr } from '../../military/task/static';
|
||||
|
||||
import './index.scss';
|
||||
const { Panel } = Collapse;
|
||||
|
||||
const taskModeNameArr = [];
|
||||
for (const item of taskModeIdArr) {
|
||||
taskModeNameArr[item.dicItemCode] = item.dicItemName;
|
||||
}
|
||||
|
||||
|
||||
let taskArrMock = [
|
||||
{
|
||||
id: 447,
|
||||
name: "研发配置要求为包含网络化协同控制仿真验证与多样化目标识别仿真验证模块的1套软件和1份测试报告。",
|
||||
taskModeId: 1, //悬赏模式
|
||||
bounty: 1.0, //赏金
|
||||
description: "<p>统筹管理员能看到不?</p>", //详情
|
||||
createdAt: "2021-11-10 17:42:38", //创建时间
|
||||
publishedAt: "2021-11-10 17:43:41", //发布时间
|
||||
collectingDays: 30, //成果提交天数
|
||||
},
|
||||
{
|
||||
id: 448,
|
||||
name: "研发配置要求验证与多样化目标识别仿真验证模块的1套软件和1份测试报告。",
|
||||
taskModeId: 2, //悬赏模式
|
||||
bounty: 100.0, //赏金
|
||||
description: "<p>统筹管理员能看到不?</p>", //详情
|
||||
createdAt: "2021-11-10 17:42:38",
|
||||
publishedAt: "2021-11-11 17:43:41",
|
||||
collectingDays: 30,
|
||||
},
|
||||
{
|
||||
id: 449,
|
||||
name: "研发配置要求为包含网络",
|
||||
taskModeId: 3, //悬赏模式
|
||||
bounty: 10000.0, //赏金
|
||||
description: "<p>统筹管理员能看到不?</p>", //详情
|
||||
createdAt: "2021-11-10 17:42:38",
|
||||
publishedAt: "2021-11-12 17:43:41",
|
||||
collectingDays: 30,
|
||||
}
|
||||
]
|
||||
|
||||
function getSomeDayAfter(initailDate, nDay) {
|
||||
return moment(new Date(initailDate).setDate(new Date(initailDate).getDate() + nDay)).format('YYYY-MM-DD');
|
||||
}
|
||||
|
||||
function FifthSection({ fifth, history }) {
|
||||
|
||||
const [taskCategoryArr, setTaskCategoryArr] = useState([]);
|
||||
const [taskArr, serTaskArr] = useState(taskArrMock);
|
||||
|
||||
useEffect(() => {
|
||||
const params = {
|
||||
curPage: 1,
|
||||
pageSize: 3,
|
||||
orderBy: 'visitsDesc',
|
||||
isDelete: '0',
|
||||
recommend: '1',
|
||||
};
|
||||
getTaskList(params).then(data => {
|
||||
if (data) {
|
||||
serTaskArr(data.rows);
|
||||
}
|
||||
})
|
||||
}, []);
|
||||
|
||||
|
||||
// 获取分类数据
|
||||
useEffect(() => {
|
||||
getTaskCategory().then(data => {
|
||||
if (data) {
|
||||
for (const item of data) {
|
||||
switch (item.name) {
|
||||
case "军事理论":
|
||||
item.icon = "junshililun1";
|
||||
break;
|
||||
case "政策法规":
|
||||
item.icon = "zhengcefagui1";
|
||||
break;
|
||||
case "医学":
|
||||
item.icon = "yixue1";
|
||||
break;
|
||||
case "电子":
|
||||
item.icon = "dianzi1";
|
||||
break;
|
||||
case "通信":
|
||||
item.icon = "tongxin1";
|
||||
break;
|
||||
case "计算机科学":
|
||||
item.icon = "jisuanji1";
|
||||
item.name = "计算机";
|
||||
break;
|
||||
case "软件工程":
|
||||
item.icon = "ruanjiangongcheng1";
|
||||
break;
|
||||
case "人工智能":
|
||||
item.icon = "rengongzhineng";
|
||||
break;
|
||||
case "知识图谱":
|
||||
item.icon = "zhishitupu";
|
||||
break;
|
||||
case "大数据":
|
||||
item.icon = "dashuju";
|
||||
break;
|
||||
default:
|
||||
item.icon = "dianzi1";
|
||||
}
|
||||
}
|
||||
setTaskCategoryArr(data.slice(0, 10));
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
function goTask(item) {
|
||||
history.push(`/task?type=${item.id}`)
|
||||
// console.log(item);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className={`homepage-main fifth-main clearfix ${fifth ? 'active' : ''}`}>
|
||||
<div className="circle-wave">
|
||||
<ul className="icon-circle">
|
||||
{
|
||||
taskCategoryArr.map((item, i) => {
|
||||
return (<li key={item.id} onClick={() => { goTask(item) }}>
|
||||
<i className={`iconfont icon-${item.icon}`}></i>
|
||||
<span>{item.name}</span>
|
||||
</li>)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
|
||||
<div className="circleBox">
|
||||
<div className="circle1"></div>
|
||||
<div className="circle2"></div>
|
||||
<div className="circle3"></div>
|
||||
<div className="circle4"></div>
|
||||
<div className="circle5">
|
||||
<div className="circle-center">
|
||||
创客空间
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="task-main">
|
||||
<h2 className="homePage-blue-tit">创客空间</h2>
|
||||
<h4 className="homePage-subhead">开源项目版块集项目托管、版本管理等功能于一体,为开源协作和群智汇聚提供创作环境</h4>
|
||||
<Line />
|
||||
<Collapse
|
||||
accordion
|
||||
defaultActiveKey={['1']}
|
||||
expandIconPosition="right"
|
||||
>
|
||||
{
|
||||
taskArr.map((item, i) => {
|
||||
return (
|
||||
<Panel header={item.name} key={i + 1 + ''}>
|
||||
<p className="collapse-des ellipsis-2" dangerouslySetInnerHTML={{ __html: item.description }}></p>
|
||||
<div className="collapse-content">
|
||||
<p className="collapse-content-item">
|
||||
<i className="iconfont icon-quxiaoguanzhu"></i>
|
||||
<span >{taskModeNameArr[item.taskModeId]}</span>
|
||||
<span className="collapse-content-money">¥ {item.bounty}</span>
|
||||
</p>
|
||||
|
||||
<p className="collapse-content-item">
|
||||
<i className="iconfont icon-quxiaoguanzhu"></i>
|
||||
<span >发布时间</span>
|
||||
<span className="collapse-content-time">{moment(item.publishedAt || item.createdAt).format('YYYY-MM-DD')}</span>
|
||||
</p>
|
||||
|
||||
<p className="collapse-content-item">
|
||||
<i className="iconfont icon-quxiaoguanzhu"></i>
|
||||
<span >截止时间</span>
|
||||
<span className="collapse-content-time">{getSomeDayAfter(item.publishedAt || item.createdAt, item.collectingDays)}</span>
|
||||
<Button className="collapse-detail" onClick={() => { history.push(`/task/taskDetail/${item.id}`) }}>详情</Button>
|
||||
</p>
|
||||
</div>
|
||||
</Panel>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
</Collapse>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="text-center">
|
||||
<Button className="homepage-btn " type="primary" onClick={() => { history.push('/task') }}>寻找创客 <i className="iconfont icon-gengduoicon"></i></Button>
|
||||
</div>
|
||||
|
||||
<svg className="waves waves-low "
|
||||
viewBox="0 24 150 28" preserveAspectRatio="none" shapeRendering="auto">
|
||||
<defs>
|
||||
<path id="wave-path" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
|
||||
</defs>
|
||||
|
||||
<g className="parallax">
|
||||
{/* <use xlinkHref="#wave-path" x="50" y="3" fill="rgba(4,22,112,0.2)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="0" fill="rgba(4,22,112,0.3)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="9" fill="#0037AF" /> */}
|
||||
|
||||
<use xlinkHref="#wave-path" x="50" y="3" fill="rgba(0,55,175,0.2)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="0" fill="rgba(0,55,175,0.2)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="9" fill="#0037AF" />
|
||||
</g>
|
||||
</svg>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(FifthSection);
|
|
@ -0,0 +1,342 @@
|
|||
$deg: 36deg;
|
||||
$deg2: -36deg;
|
||||
|
||||
$bgcolorlist:#254dea #e33230 #0766fb #f02c66 #6038ff #f85e55 #c13cff #2cb840 #5744f6 #e9862e;
|
||||
|
||||
.home-fifth-section {
|
||||
min-height: 50vh;
|
||||
background: linear-gradient(#fff 0%, #cbdcff 100%);
|
||||
|
||||
.fifth-main {
|
||||
display: flex;
|
||||
margin: 5vh auto 3vh;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.homepage-btn {
|
||||
margin-bottom: 10vh;
|
||||
}
|
||||
|
||||
.circle-wave {
|
||||
position: relative;
|
||||
width: 37.5em;
|
||||
height: 43.75em;
|
||||
flex: none;
|
||||
|
||||
&:hover .icon-circle {
|
||||
animation-play-state: paused;
|
||||
|
||||
li span {
|
||||
animation-play-state: paused;
|
||||
}
|
||||
}
|
||||
}
|
||||
.icon-circle {
|
||||
position: absolute;
|
||||
width: 35em;
|
||||
height: 35em;
|
||||
border-radius: 50%;
|
||||
animation: iconCircle infinite 20s linear;
|
||||
|
||||
li {
|
||||
width: 4.375em;
|
||||
height: 4.375em;
|
||||
position: absolute;
|
||||
background-color: #254dea;
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
line-height: 4.375em;
|
||||
text-align: center;
|
||||
left: 50%;
|
||||
margin-left: -1.25em;
|
||||
margin-top: -1.25em;
|
||||
cursor: pointer;
|
||||
.iconfont {
|
||||
font-size: 1.5em !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
@for $i from 1 to length($bgcolorlist) + 1 {
|
||||
li:nth-child(#{$i}) {
|
||||
background: nth($bgcolorlist, $i);
|
||||
transform: rotate(($i - 1) * $deg);
|
||||
transform-origin: 1.25em 18.75em;
|
||||
span {
|
||||
transform: rotate(($i - 1) * $deg2);
|
||||
animation: iconItem#{$i} infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes iconItem#{$i} {
|
||||
0% {
|
||||
transform: rotate(($i - 1) * $deg2);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(($i + 9) * $deg2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
li {
|
||||
span {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
border-radius: 50%;
|
||||
width: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
visibility: hidden;
|
||||
}
|
||||
&:hover span {
|
||||
visibility: visible;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes iconCircle {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.circleBox {
|
||||
position: relative;
|
||||
right: 0.9375em;
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
margin: 12.5em auto 0;
|
||||
}
|
||||
|
||||
.circle1,
|
||||
.circle2,
|
||||
.circle3,
|
||||
.circle4,
|
||||
.circle5 {
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.circle5 {
|
||||
background-color: rgba(98, 88, 252, 0.3);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.circle-center {
|
||||
width: 6.25em;
|
||||
height: 6.25em;
|
||||
padding: 1em 2em;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(to bottom right, #2bebd7 0%, #692fd1 100%);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
font-size: 1.25em;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.circle1 {
|
||||
animation: cricle-wave 5s linear 0s infinite;
|
||||
background-color: rgba(98, 88, 252, 0.3);
|
||||
}
|
||||
|
||||
.circle2 {
|
||||
animation: cricle-wave 5s linear 1s infinite;
|
||||
background-color: rgba(98, 88, 252, 0.3);
|
||||
}
|
||||
|
||||
.circle3 {
|
||||
animation: cricle-wave 5s linear 2s infinite;
|
||||
background-color: rgba(98, 88, 252, 0.3);
|
||||
}
|
||||
|
||||
.circle4 {
|
||||
animation: cricle-wave 5s linear 3s infinite;
|
||||
background-color: rgba(98, 88, 252, 0.3);
|
||||
}
|
||||
|
||||
@keyframes cricle-wave {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
10% {
|
||||
transform: scale(1.15);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
20% {
|
||||
transform: scale(1.3);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
30% {
|
||||
transform: scale(1.45);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
40% {
|
||||
transform: scale(1.6);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1.75);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
60% {
|
||||
transform: scale(1.9);
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: scale(2.05);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
80% {
|
||||
transform: scale(2.2);
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
90% {
|
||||
transform: scale(2.35);
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(2.5);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.task-main {
|
||||
margin:-2.5em 0 0 2.5em;
|
||||
.home-line {
|
||||
text-align: left;
|
||||
margin-bottom: 1.56em !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-collapse {
|
||||
border: 0;
|
||||
background: inherit;
|
||||
font-size: .875em;
|
||||
.ant-collapse-item {
|
||||
border: 0;
|
||||
margin-bottom: 0.9375em;
|
||||
}
|
||||
.ant-collapse-item:last-child,
|
||||
.ant-collapse-item:last-child > .ant-collapse-header {
|
||||
border-radius: .375em .375em 0 0;
|
||||
}
|
||||
|
||||
.ant-collapse-header {
|
||||
height: 4.875em;
|
||||
background: #ffffff;
|
||||
box-shadow: 0px 0px .625em .3125em rgba(38, 118, 255, 0.04);
|
||||
border-radius: .375em;
|
||||
font-size: 1.125em;
|
||||
color: #0a1255;
|
||||
letter-spacing: 0;
|
||||
font-weight: 500;
|
||||
padding: 1.6875em 2.8125em 1.6875em 3.375em;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
// max-width: 35em;
|
||||
|
||||
.ant-collapse-arrow {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 1.75em;
|
||||
height: 1.75em;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0px 0px 3.125em 1px rgba(38, 118, 255, 0.1);
|
||||
svg {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-collapse-item-active {
|
||||
background: #ffffff;
|
||||
box-shadow: 0px 0px .625em .3125em rgba(38, 118, 255, 0.04);
|
||||
border-radius: .375em;
|
||||
border: 0;
|
||||
.ant-collapse-header {
|
||||
height: 3em;
|
||||
padding: 0.9375em 3.375em;
|
||||
background: #596cee;
|
||||
color: #fff;
|
||||
border-bottom-left-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
}
|
||||
|
||||
.ant-collapse-arrow {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-collapse-content > .ant-collapse-content-box {
|
||||
padding: 1.375em 1.75em;
|
||||
}
|
||||
}
|
||||
|
||||
.collapse-des {
|
||||
font-size: 0.9375em;
|
||||
color: #3a4772;
|
||||
letter-spacing: 0;
|
||||
line-height: 1.75em;
|
||||
font-weight: 400;
|
||||
margin-bottom: 0.5em !important;
|
||||
|
||||
|
||||
}
|
||||
.collapse-content {
|
||||
padding: .75em;
|
||||
background: #f5f7fa;
|
||||
border-radius: .25em;
|
||||
|
||||
.collapse-content-item {
|
||||
position: relative;
|
||||
height: 1.875em;
|
||||
line-height: 1.875em;
|
||||
font-weight: 400;
|
||||
}
|
||||
.iconfont {
|
||||
margin-right: .75em;
|
||||
color: #ea0000;
|
||||
}
|
||||
.collapse-content-money {
|
||||
margin-left: 1.375em;
|
||||
color: #ea0000;
|
||||
}
|
||||
.collapse-content-time {
|
||||
margin-left: 1.375em;
|
||||
}
|
||||
}
|
||||
|
||||
.collapse-detail{
|
||||
color: #4154f1;
|
||||
border-color: #4154f1;
|
||||
position: absolute;
|
||||
right: 1.25em;
|
||||
}
|
||||
.waves {
|
||||
position: relative;
|
||||
bottom: -1.5vh;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
import React, { memo, useEffect, useState } from 'react';
|
||||
import { Button } from 'antd';
|
||||
import './index.scss';
|
||||
|
||||
import circle from '../img/1-circle.png';
|
||||
import code1 from '../img/1-code.png';
|
||||
import codeBed from '../img/1-code-bed.png';
|
||||
import glass from '../img/1-glass.png';
|
||||
import logo from '../img/1-logo.png';
|
||||
import box1 from '../img/1-box1.png';
|
||||
import box2 from '../img/1-box2.png';
|
||||
import box3 from '../img/1-box3.png';
|
||||
import box4 from '../img/1-box4.png';
|
||||
|
||||
import text1 from '../img/1-text1.png';
|
||||
import text2 from '../img/1-text2.png';
|
||||
import text3 from '../img/1-text3.png';
|
||||
import text4 from '../img/1-text4.png';
|
||||
|
||||
function FirstSection({ first }) {
|
||||
|
||||
const [circulation, setCirculation] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
const playGlass = document.getElementById("playGlass");
|
||||
playGlass.addEventListener("webkitAnimationEnd", secondAnimation);
|
||||
return () => {
|
||||
setCirculation('');
|
||||
playGlass.removeEventListener("webkitAnimationEnd",secondAnimation);
|
||||
};
|
||||
}, []);
|
||||
|
||||
function secondAnimation(){
|
||||
setCirculation('circulation');
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setCirculation('');
|
||||
}, [first]);
|
||||
|
||||
|
||||
function goNext(){
|
||||
window.scrollTo({
|
||||
letf:0,
|
||||
top:document.querySelector(".home-second-section").offsetTop,
|
||||
behavior:"smooth"
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`grid-picture ${first ? "active" : ""}`}>
|
||||
<div className="homepage-main website-content">
|
||||
|
||||
<div className="website">
|
||||
<h3 className="website-title">红山开源</h3>
|
||||
<div className="website-vision">
|
||||
<span>群智共享</span>
|
||||
<span>开源开放</span>
|
||||
<span>协同创新</span>
|
||||
<span>择优孵化</span>
|
||||
</div>
|
||||
<div className="website-des">红山开源是一个依托互联网群体智慧实现世界范围内资源深度融合、开放共享和协同创新的开源社区,是集开源项目演化发展、科研任务众包、竞赛组织选拔和社区开放交流为一体的创新科研服务平台。红山开源致力于打造一个“开放、汇聚、协同、众创”的生态空间。
|
||||
</div>
|
||||
{/* <Button className="website-more homepage-btn" type="primary" onClick={goNext}>了解详情</Button> */}
|
||||
</div>
|
||||
|
||||
<div className={`play-img ${circulation}`}>
|
||||
<img alt="images-not_found" className="play-text3" src={text3}></img>
|
||||
<img alt="images-not_found" className="play-text4" src={text4}></img>
|
||||
<img alt="images-not_found" className="play-logo" src={logo}></img>
|
||||
<img alt="images-not_found" id="playGlass" className="play-glass" src={glass}></img>
|
||||
<img alt="images-not_found" className="play-code-bed" src={codeBed}></img>
|
||||
<img alt="images-not_found" className="play-code1" src={code1}></img>
|
||||
<img alt="images-not_found" className="play-circle" src={circle}></img>
|
||||
<div className="play-circle-circle1"></div>
|
||||
<div className="play-circle-circle2"></div>
|
||||
<div className="play-circle-circle3"></div>
|
||||
<img alt="images-not_found" className="play-box4" src={box4}></img>
|
||||
<img alt="images-not_found" className="play-box3" src={box3}></img>
|
||||
<img alt="images-not_found" className="play-box2" src={box2}></img>
|
||||
<img alt="images-not_found" className="play-box1" src={box1}></img>
|
||||
<img alt="images-not_found" className="play-text1" src={text1}></img>
|
||||
<img alt="images-not_found" className="play-text2" src={text2}></img>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<svg className="waves"
|
||||
viewBox="0 24 150 28" preserveAspectRatio="none" shapeRendering="auto">
|
||||
<defs>
|
||||
<path id="wave-path" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
|
||||
</defs>
|
||||
<g className="parallax">
|
||||
{/* <use xlinkHref="#gentle-wave" x="48" y="0" fill="rgba(255,255,255,0.7" />
|
||||
<use xlinkHref="#gentle-wave" x="48" y="3" fill="rgba(255,255,255,0.5)" />
|
||||
<use xlinkHref="#gentle-wave" x="48" y="5" fill="rgba(255,255,255,0.4)" />
|
||||
<use xlinkHref="#gentle-wave" x="48" y="7" fill="#fff" /> */}
|
||||
{/* <use xlinkHref="#wave-path" x="50" y="0" fill="rgba(255,255,255,0.7" /> */}
|
||||
<use xlinkHref="#wave-path" x="50" y="3" fill="rgba(255,255,255,0.6)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="0" fill="rgba(255,255,255,0.45)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="9" fill="#fff" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(FirstSection);
|
|
@ -0,0 +1,696 @@
|
|||
.home-first-section {
|
||||
height: 90vh;
|
||||
min-height: 650px;
|
||||
// background: linear-gradient(
|
||||
// #1a2358 0%,
|
||||
// #12277b 33%,
|
||||
// #0c2d8f 67%,
|
||||
// #002a89 100%
|
||||
// );
|
||||
background: linear-gradient(
|
||||
#0037AF 0%,
|
||||
#0c2d8f 100%,
|
||||
);
|
||||
|
||||
.grid-picture {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
background: url(../img/grid.png) no-repeat;
|
||||
background-size: 100% auto;
|
||||
.waves {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -2px;
|
||||
height: 10vh;
|
||||
}
|
||||
}
|
||||
|
||||
.website-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 80vh;
|
||||
min-height: 600px;
|
||||
}
|
||||
|
||||
.website {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
margin-right: 3.5%;
|
||||
color: #fff;
|
||||
.website-title {
|
||||
color: #fff;
|
||||
font-size: 2.4em;
|
||||
}
|
||||
.website-vision {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1.3em;
|
||||
color: #ff832b;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
.website-des {
|
||||
font-size: 1em;
|
||||
line-height: 2.3;
|
||||
margin-bottom: 1.5em;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.website-more {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.play-img {
|
||||
display: flex;
|
||||
flex: none;
|
||||
justify-content: center;
|
||||
align-items: flex-end;
|
||||
position: relative;
|
||||
width: 680px;
|
||||
height: 580px;
|
||||
img {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.play-glass {
|
||||
position: relative;
|
||||
width: 351px;
|
||||
z-index: 1;
|
||||
}
|
||||
.play-circle {
|
||||
position: absolute;
|
||||
width: 165px;
|
||||
height: 160px;
|
||||
right: 17%;
|
||||
bottom: -6.5%;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.play-circle-circle1,.play-circle-circle2,.play-circle-circle3,.play-circle-circle4,.play-circle-circle5 {
|
||||
position: absolute;
|
||||
width: 85px;
|
||||
height: 53px;
|
||||
right: 23.2%;
|
||||
bottom: 9%;
|
||||
z-index: 2;
|
||||
border: 1px solid rgb(73, 169, 241);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.play-pillar {
|
||||
position: absolute;
|
||||
left: -11%;
|
||||
top: 37%;
|
||||
width: 230px;
|
||||
}
|
||||
.play-box1 {
|
||||
position: absolute;
|
||||
left: -6%;
|
||||
bottom: 30%;
|
||||
width: 57px;
|
||||
}
|
||||
.play-box2 {
|
||||
position: absolute;
|
||||
left: 0%;
|
||||
bottom: 34%;
|
||||
width: 57px;
|
||||
}
|
||||
.play-box3 {
|
||||
position: absolute;
|
||||
left: 6%;
|
||||
bottom: 38%;
|
||||
width: 57px;
|
||||
}
|
||||
.play-box4 {
|
||||
position: absolute;
|
||||
left: 12%;
|
||||
bottom: 42%;
|
||||
width: 57px;
|
||||
}
|
||||
.play-code1 {
|
||||
position: absolute;
|
||||
right: 0%;
|
||||
top: 33%;
|
||||
width: 128px;
|
||||
z-index: 1;
|
||||
}
|
||||
.play-code-bed {
|
||||
position: absolute;
|
||||
right: -5%;
|
||||
top: 44%;
|
||||
width: 211px;
|
||||
z-index: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
.play-logo {
|
||||
position: absolute;
|
||||
top: 25%;
|
||||
width: 87px;
|
||||
z-index: 10;
|
||||
color: #fff;
|
||||
font-size: 40px;
|
||||
}
|
||||
.play-text1 {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
}
|
||||
.play-text2 {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
}
|
||||
.play-text3 {
|
||||
position: absolute;
|
||||
}
|
||||
.play-text4 {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
.website {
|
||||
animation: website 0.75s 1 forwards;
|
||||
}
|
||||
.play-glass {
|
||||
animation: glass 0.75s 1 forwards;
|
||||
}
|
||||
.play-circle {
|
||||
animation: circle 0.75s 1 forwards;
|
||||
}
|
||||
.play-circle-circle1,.play-circle-circle2,.play-circle-circle3,.play-circle-circle4,.play-circle-circle5{
|
||||
animation: circle-before 0.75s 1 forwards;
|
||||
}
|
||||
.play-box1 {
|
||||
animation: box1 0.75s 1 forwards;
|
||||
}
|
||||
.play-box2 {
|
||||
animation: box2 0.75s 1 forwards;
|
||||
}
|
||||
.play-box3 {
|
||||
animation: box3 0.75s 1 forwards;
|
||||
}
|
||||
.play-box4 {
|
||||
animation: box4 0.75s 1 forwards;
|
||||
}
|
||||
// .play-code {
|
||||
// animation: code 0.75s 1 forwards;
|
||||
// }
|
||||
.play-code1 {
|
||||
animation: code1 0.75s 1 forwards;
|
||||
}
|
||||
.play-code-bed {
|
||||
animation: codeBed 0.75s 1 forwards;
|
||||
}
|
||||
.play-logo {
|
||||
animation: logo 6s 0.5s infinite; //linear
|
||||
}
|
||||
.play-text1 {
|
||||
// animation: text1-show 0.5s 1 0.5s forwards;
|
||||
animation: text1-show 6s 0.5s infinite;
|
||||
}
|
||||
.play-text2 {
|
||||
animation: text2-show 6s 0.5s infinite;
|
||||
}
|
||||
.play-text3 {
|
||||
animation: text3-show 6s 0.5s infinite;
|
||||
}
|
||||
.play-text4 {
|
||||
animation: text4-show 6s 0.5s infinite;
|
||||
}
|
||||
|
||||
.circulation {
|
||||
.play-code1 {
|
||||
animation: code1-circulation 6s infinite;
|
||||
}
|
||||
|
||||
.play-box1 {
|
||||
animation: box1-circulation 2s infinite;
|
||||
}
|
||||
|
||||
.play-box2 {
|
||||
animation: box2-circulation 2s infinite;
|
||||
}
|
||||
|
||||
.play-box3 {
|
||||
animation: box3-circulation 2s infinite;
|
||||
}
|
||||
|
||||
.play-box4 {
|
||||
animation: box4-circulation 2s infinite;
|
||||
}
|
||||
|
||||
.play-circle-circle1{
|
||||
animation: circle-circle 6s 0.25s infinite;
|
||||
}
|
||||
.play-circle-circle2{
|
||||
animation: circle-circle 6s 2.25s infinite;
|
||||
}
|
||||
.play-circle-circle3{
|
||||
animation: circle-circle 6s 4.25s infinite;
|
||||
}
|
||||
// .play-circle-circle4{
|
||||
// animation: circle-circle 6s 4.5s infinite;
|
||||
// }
|
||||
// .play-circle-circle5{
|
||||
// animation: circle-circle 6s 6s infinite;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes website {
|
||||
0% {
|
||||
top: 25vh;
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
top: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes glass {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: rotate(-25deg);
|
||||
top: 5.5%;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: rotate(0deg);
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes logo {
|
||||
0% {
|
||||
opacity: 1;
|
||||
top: 23%;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
top: 12%;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
top: 23%;
|
||||
}
|
||||
}
|
||||
|
||||
// logo动效方案一
|
||||
// @keyframes logo {
|
||||
// 10% {
|
||||
// opacity: 0;
|
||||
// top: 33%;
|
||||
// transform: rotateY(0deg);
|
||||
// }
|
||||
// 50% {
|
||||
// opacity: 1;
|
||||
// top: 12%;
|
||||
// transform: rotateY(360deg);
|
||||
// }
|
||||
// 90% {
|
||||
// opacity: 0;
|
||||
// top: 33%;
|
||||
// transform: rotateY(360deg);
|
||||
// }
|
||||
// }
|
||||
|
||||
// logo动效方案二
|
||||
// @keyframes logo {
|
||||
// 15% {
|
||||
// opacity: 0;
|
||||
// top: 33%;
|
||||
// // transform: rotate(0deg);
|
||||
// }
|
||||
// 40% {
|
||||
// opacity: 1;
|
||||
// top: 10%;
|
||||
// transform: rotateX(0deg);
|
||||
// }
|
||||
// 60% {
|
||||
// opacity: 1;
|
||||
// top: 10%;
|
||||
// transform: rotateX(360deg);
|
||||
// }
|
||||
// 85% {
|
||||
// opacity: 0;
|
||||
// top: 40%;
|
||||
// // transform: rotateY(360deg);
|
||||
// }
|
||||
// }
|
||||
|
||||
// logo动效方案三
|
||||
// @keyframes logo {
|
||||
// 0% {
|
||||
// opacity: 1;
|
||||
// top: 10%;
|
||||
// transform: rotateY(0deg);
|
||||
// }
|
||||
|
||||
// 25% {
|
||||
// opacity: 1;
|
||||
// top: 10%;
|
||||
// transform: rotateY(90deg);
|
||||
// }
|
||||
// 50% {
|
||||
// opacity: 1;
|
||||
// top: 10%;
|
||||
// transform: rotateY(180deg);
|
||||
// }
|
||||
|
||||
// 75% {
|
||||
// opacity: 1;
|
||||
// top: 10%;
|
||||
// transform: rotateY(270deg);
|
||||
// }
|
||||
|
||||
// 100% {
|
||||
// opacity: 1;
|
||||
// top: 10%;
|
||||
// transform: rotateY(360deg);
|
||||
// }
|
||||
// }
|
||||
|
||||
@keyframes circle {
|
||||
0% {
|
||||
opacity: 0;
|
||||
bottom: -10%;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
bottom: -6.5%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes circle-before {
|
||||
0% {
|
||||
opacity: 0;
|
||||
bottom: -1%;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
bottom: 9%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@keyframes box1 {
|
||||
0% {
|
||||
opacity: 0;
|
||||
bottom: 20%;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
bottom: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes box2 {
|
||||
0% {
|
||||
opacity: 0;
|
||||
bottom: 24%;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
bottom: 34%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes box3 {
|
||||
0% {
|
||||
opacity: 0;
|
||||
bottom: 28%;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
bottom: 38%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes box4 {
|
||||
0% {
|
||||
opacity: 0;
|
||||
bottom: 32%;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
bottom: 42%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes box1-circulation {
|
||||
0% {
|
||||
opacity: 1;
|
||||
height: 60px;
|
||||
}
|
||||
48% {
|
||||
height: 65px;
|
||||
}
|
||||
52% {
|
||||
height: 65px;
|
||||
}
|
||||
100% {
|
||||
height: 60px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes box2-circulation {
|
||||
0% {
|
||||
height: 96px;
|
||||
opacity: 1;
|
||||
}
|
||||
48% {
|
||||
height: 90px;
|
||||
}
|
||||
52% {
|
||||
height: 90px;
|
||||
}
|
||||
100% {
|
||||
height: 96px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes box3-circulation {
|
||||
0% {
|
||||
height: 128px;
|
||||
opacity: 1;
|
||||
}
|
||||
48% {
|
||||
height: 135px;
|
||||
}
|
||||
52% {
|
||||
height: 135px;
|
||||
}
|
||||
100% {
|
||||
height: 128px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes box4-circulation {
|
||||
0% {
|
||||
height: 113px;
|
||||
opacity: 1;
|
||||
}
|
||||
48% {
|
||||
height: 108px;
|
||||
}
|
||||
52% {
|
||||
height: 108px;
|
||||
}
|
||||
100% {
|
||||
height: 113px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// @keyframes code {
|
||||
// 0% {
|
||||
// opacity: 0;
|
||||
// top: 40%;
|
||||
// }
|
||||
// 100% {
|
||||
// opacity: 1;
|
||||
// top: 30%;
|
||||
// }
|
||||
// }
|
||||
|
||||
@keyframes code1 {
|
||||
0% {
|
||||
opacity: 0;
|
||||
top: 43%;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
top: 33%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes code1-circulation {
|
||||
0% {
|
||||
opacity: 1;
|
||||
top: 33%;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
top: 30%;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
top: 33%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes codeBed {
|
||||
0% {
|
||||
opacity: 0;
|
||||
top: 54%;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
top: 44%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes text1-show {
|
||||
5% {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
bottom: 36%;
|
||||
right: 60%;
|
||||
}
|
||||
20% {
|
||||
opacity: 1;
|
||||
width: 262px;
|
||||
bottom: 12%;
|
||||
left: 55%;
|
||||
}
|
||||
80% {
|
||||
opacity: 1;
|
||||
width: 262px;
|
||||
bottom: 12%;
|
||||
left: 55%;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
bottom: 36%;
|
||||
right: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes text2-show {
|
||||
5% {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
bottom: 36%;
|
||||
right: 60%;
|
||||
}
|
||||
20% {
|
||||
opacity: 1;
|
||||
width: 262px;
|
||||
bottom: 10%;
|
||||
right: 56%;
|
||||
}
|
||||
80% {
|
||||
opacity: 1;
|
||||
width: 262px;
|
||||
bottom: 10%;
|
||||
right: 56%;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
bottom: 36%;
|
||||
right: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes text3-show {
|
||||
5% {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
right: 36%;
|
||||
top: 50%;
|
||||
}
|
||||
20% {
|
||||
opacity: 1;
|
||||
right: 8%;
|
||||
top: 6%;
|
||||
width: 227px;
|
||||
}
|
||||
80% {
|
||||
opacity: 1;
|
||||
right: 8%;
|
||||
top: 6%;
|
||||
width: 227px;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
right: 36%;
|
||||
top: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes text4-show {
|
||||
5% {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
right: 50%;
|
||||
top: 50%;
|
||||
}
|
||||
20% {
|
||||
opacity: 1;
|
||||
top: 14%;
|
||||
right: 55%;
|
||||
width: 206px;
|
||||
}
|
||||
80% {
|
||||
opacity: 1;
|
||||
top: 14%;
|
||||
right: 55%;
|
||||
width: 206px;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
right: 50%;
|
||||
top: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes circle-circle {
|
||||
|
||||
0% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
bottom: 9%;
|
||||
}
|
||||
|
||||
33% {
|
||||
transform: scale(1.2);
|
||||
opacity: 0.7;
|
||||
bottom: 9.5%;
|
||||
}
|
||||
|
||||
|
||||
67% {
|
||||
transform: scale(1.5);
|
||||
opacity: 0.35;
|
||||
bottom: 10.2%;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(2);
|
||||
opacity: 0;
|
||||
bottom: 11.5%;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
import React, { memo } from "react";
|
||||
// import logo from '../../modules/tpm/images/hskylogo.png';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
function HomeFooter() {
|
||||
let chromesettingArray = JSON.parse(localStorage.getItem('chromesetting'));
|
||||
let footerHtml= chromesettingArray.footer;
|
||||
|
||||
return (
|
||||
<div className="home-footer homePage">
|
||||
<div className="arc"></div>
|
||||
<div className="homepage-main footer-main" dangerouslySetInnerHTML={{__html:footerHtml}}>
|
||||
{/* <p>
|
||||
<span className="mr15"><i className="iconfont icon-weibiaoti- font-16"></i>+86-010-66357650</span>
|
||||
<span className="mr15"><i className="iconfont icon-xiazai18 font-16"></i> 北京市海淀区西三环北路72号</span>
|
||||
<span className="footer-email mr15"><i className="iconfont icon-mail font-16"></i>osredm@163.com</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
版权所有:红山开源社区
|
||||
<a className="police" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010802034576">
|
||||
<img className="police-img" src="https://forge.osredm.com/police.png" />京公网安备 11010802034576 号</a>
|
||||
<a className="police-number" href="https://beian.miit.gov.cn/#/Integrated/index">京ICP备2021005060</a>
|
||||
</p>
|
||||
*/}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(HomeFooter);
|
|
@ -0,0 +1,61 @@
|
|||
.home-footer {
|
||||
height: 40vh;
|
||||
min-width: 100vw;
|
||||
// background: #162046;
|
||||
background: linear-gradient(#cbdcff 0%, #162046 5%, #162046 100%);
|
||||
|
||||
overflow: hidden;
|
||||
.arc {
|
||||
position: relative;
|
||||
margin: -15vh -5vw 0 -5vw;
|
||||
height: 30vh;
|
||||
// width: 110vw;
|
||||
// background: linear-gradient(#cbdcff 0%, #bbccef 100%);
|
||||
background: #cbdcff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.logo {
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
bottom: 75px;
|
||||
width: 190px;
|
||||
height: 60px;
|
||||
}
|
||||
.footer-main {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 18vh;
|
||||
font-size: 12px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #bdc2d1;
|
||||
line-height: 28px;
|
||||
}
|
||||
.police {
|
||||
color: #bdc2d1;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.police-img {
|
||||
width: 16px;
|
||||
border-radius: 10px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
.police-number {
|
||||
color: #bdc2d1;
|
||||
}
|
||||
|
||||
.footer-email {
|
||||
display: inline-flex;
|
||||
.iconfont {
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.footerbottom {
|
||||
background-color: #162046 !important;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
import React, { memo } from 'react';
|
||||
import { Button } from 'antd';
|
||||
import Line from '../Line';
|
||||
import logoLine from '../img/4-logo.png';
|
||||
import task from '../img/4-task.png';
|
||||
import codeManage from '../img/4-codeManage.png';
|
||||
import versionManage from '../img/4-versionManage.png';
|
||||
import editorInline from '../img/4-editorInline.png';
|
||||
import teamwork from '../img/4-teamwork.png';
|
||||
import './index.scss';
|
||||
|
||||
const code = [
|
||||
{ str: <span><span className='code-blue'>latest:</span> Pulling from appleboy/drone-ssh</span> },
|
||||
{ str: <span><span className='code-red'>Digest:</span>sha256:095ca4ceafcb7</span> },
|
||||
{ str: <span>Status:Image is up to date for appleboy/drone-ssh:latest</span> },
|
||||
{ str: <span><span className='code-green'>echo ====开始部署=======</span></span> },
|
||||
// { str: <span><span className='code-green'>echo ====暂停容器开始======= </span></span> },
|
||||
{ str: <span><span className='code-red'>docker</span> rm -f mo-test</span> },
|
||||
{ str: <span><span className='code-red'>docker</span> rmi mo-test:1.0</span> },
|
||||
// { str: <span><span className='code-blue'>cd</span> /opt/demo</span> },
|
||||
{ str: <span><span className='code-red'>docker </span>build -t mo-test:1.0 .</span> },
|
||||
{ str: <span><span className='code-red'>docker </span>run -d -p 8080:8080 --name mo-test mo-test:1.0</span> },
|
||||
{ str: <span><span className='code-green'>echo ====部署成功=======</span></span> },
|
||||
{ str: <span className="code-input"><span className='code-blue'>~/opt/Users/demo/app/static/</span><span className="animation-is-typing"></span></span> },
|
||||
// { str: <span><span className='code-green'>======END======</span></span> },
|
||||
]
|
||||
|
||||
function FourthSection({ fourth, history }) {
|
||||
return (
|
||||
<div className="fourth-main homepage-main">
|
||||
<div className="fourth-title">
|
||||
<div className="fourth-main-title">
|
||||
<h2 className="homePage-blue-tit">开源项目</h2>
|
||||
<h4 className="homePage-subhead">开源项目版块集项目托管、版本管理等功能于一体,为开源协作和群智汇聚提供创作环境</h4>
|
||||
<Line />
|
||||
<Button className="homepage-btn" type="primary" onClick={()=>{history.push('/projects')}}>查看项目 <i className="iconfont icon-gengduoicon"></i></Button>
|
||||
</div>
|
||||
|
||||
<div className={fourth ? "code-box clearfix activeCode" : "code-box clearfix"} >
|
||||
<div className="code-box-action code-box-picture">
|
||||
<img src={task}></img>
|
||||
</div>
|
||||
<div className="code-box-action code-box-code">
|
||||
<div className="hadoopCode">
|
||||
<ul className="code-content">
|
||||
<li key={0}>
|
||||
<pre >
|
||||
<span className="codenum">1</span>
|
||||
<span className="">
|
||||
<span className='word-item code-blue' style={{ animationDelay: '2.4s' }}> ~/</span>
|
||||
<span className='word-item code-blue' style={{ animationDelay: '2.5s' }}>c</span>
|
||||
<span className='word-item code-blue' style={{ animationDelay: '2.6s' }}>d</span>
|
||||
<span className="code-input js-type-letters animation-is-typing" style={{ animationDelay: '2.6s' }}></span>
|
||||
<span className='word-item code-green' style={{ animationDelay: '3.3s' }}> /opt</span>
|
||||
<span className='word-item code-green' style={{ animationDelay: '3.4s' }}>/Us</span>
|
||||
<span className='word-item code-green' style={{ animationDelay: '3.5s' }}>ers</span>
|
||||
<span className='word-item code-green' style={{ animationDelay: '3.6s' }}>/de</span>
|
||||
<span className='word-item code-green' style={{ animationDelay: '3.7s' }}>mo</span>
|
||||
<span className='word-item code-green' style={{ animationDelay: '3.8s' }}>/app</span>
|
||||
<span className='word-item code-green' style={{ animationDelay: '3.9s' }}>/sta</span>
|
||||
<span className='word-item code-green' style={{ animationDelay: '4.0s' }}>tic</span>
|
||||
<span className="code-input js-type-letters animation-is-typing" style={{ animationDelay: '4.0s' }}></span>
|
||||
</span>
|
||||
</pre>
|
||||
</li>
|
||||
{
|
||||
code.map((i, k) => {
|
||||
return (
|
||||
<li key={k + 1}><pre className="word-item" style={{ animationDelay: `${k * 0.2 + 4.5}s` }}><span className="codenum">{k + 2}</span>{i.str}</pre></li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<img src={logoLine}></img>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={fourth ? "fourth-projects activeCode" : "fourth-projects"}>
|
||||
|
||||
<div className="project-item">
|
||||
<div className="fourth-item-img">
|
||||
<img src={codeManage} />
|
||||
<div className="fourth-item-circle"></div>
|
||||
</div>
|
||||
<h3 className="fourth-item-title">代码托管</h3>
|
||||
<p className="fourth-item-des">免费提供海量代码仓储</p>
|
||||
</div>
|
||||
|
||||
<div className="project-item">
|
||||
<div className="fourth-item-img">
|
||||
<img src={versionManage} />
|
||||
<div className="fourth-item-circle"></div>
|
||||
</div>
|
||||
<h3 className="fourth-item-title">版本管理</h3>
|
||||
<p className="fourth-item-des">记录和维护软件演化全过程</p>
|
||||
</div>
|
||||
|
||||
<div className="project-item">
|
||||
<div className="fourth-item-img">
|
||||
<img src={editorInline} />
|
||||
<div className="fourth-item-circle"></div>
|
||||
</div>
|
||||
<h3 className="fourth-item-title">在线编辑</h3>
|
||||
<p className="fourth-item-des">轻量级修改和提交</p>
|
||||
</div>
|
||||
|
||||
<div className="project-item">
|
||||
<div className="fourth-item-img">
|
||||
<img src={teamwork} />
|
||||
<div className="fourth-item-circle"></div>
|
||||
</div>
|
||||
<h3 className="fourth-item-title">质量追踪</h3>
|
||||
<p className="fourth-item-des">代码安全和质量管控</p>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(FourthSection);
|
|
@ -0,0 +1,349 @@
|
|||
.home-fourth-section {
|
||||
text-align: center;
|
||||
min-height: 45vh;
|
||||
padding: 1.95em 0 1.25em 0;
|
||||
background: url(../img/4-map.png) no-repeat;
|
||||
|
||||
.homepage-btn{
|
||||
margin-top:1.25em;
|
||||
}
|
||||
.fourth-main {
|
||||
margin: 1.25em auto;
|
||||
}
|
||||
.fourth-title {
|
||||
display: flex;
|
||||
}
|
||||
.fourth-main-title {
|
||||
width: 33%;
|
||||
margin-right: 4.5%;
|
||||
}
|
||||
|
||||
.code-box {
|
||||
position: relative;
|
||||
width: 62.5%;
|
||||
img {
|
||||
float: left;
|
||||
width: 32%;
|
||||
}
|
||||
&>img{
|
||||
max-width: 20vw;
|
||||
}
|
||||
}
|
||||
.code-box-action {
|
||||
width: 67%;
|
||||
height: 20.75em;
|
||||
border-radius: 1.25em;
|
||||
}
|
||||
.code-box-picture {
|
||||
position: relative;
|
||||
float: left;
|
||||
// background: url(../img/task.png) no-repeat;
|
||||
opacity: 0;
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.code-box-code {
|
||||
position: absolute;
|
||||
top: 6.25em;
|
||||
left: 10em;
|
||||
background: #fff;
|
||||
box-shadow: 0px 0px .25em .25em rgba(0, 0, 0, 0.06);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.hadoopCode {
|
||||
border-radius: .3em;
|
||||
margin: .625em;
|
||||
background: #1c1c25;
|
||||
padding: 1.125em 1.25em;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
li {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
font-size: .75em;
|
||||
font-weight: 500;
|
||||
line-height: 2.1em;
|
||||
color: #e1e1e1;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas,
|
||||
Liberation Mono, monospace;
|
||||
word-break: break-all;
|
||||
overflow: initial;
|
||||
margin-bottom: 0;
|
||||
.codenum {
|
||||
display: inline-block;
|
||||
width: .95em;
|
||||
text-align: left;
|
||||
margin-right: .95em;
|
||||
}
|
||||
.code-green {
|
||||
color: #00fa30;
|
||||
}
|
||||
.code-red {
|
||||
color: #ff5058;
|
||||
}
|
||||
.code-blue {
|
||||
color: #05cfc8;
|
||||
}
|
||||
}
|
||||
.code-input{
|
||||
position: relative;
|
||||
}
|
||||
.animation-is-typing::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -0.8em;
|
||||
bottom: 0;
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
font-size: 1em;
|
||||
line-height: 1em;
|
||||
content: "▊";
|
||||
}
|
||||
.word-item {
|
||||
opacity: 0;
|
||||
}
|
||||
.js-type-letters{
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
||||
.fourth-projects {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 1.25em 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.project-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 15.875em;
|
||||
height: 12em;
|
||||
border: .1em dashed #517df1;
|
||||
border-radius: 0.375em;
|
||||
|
||||
.fourth-item-img {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 4.5em;
|
||||
height: 4.5em;
|
||||
background: #ffffff;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0px 0px .5em .5em rgba(38, 118, 255, 0.04);
|
||||
}
|
||||
|
||||
.fourth-item-circle {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
animation: turnCircle infinite 10s linear;
|
||||
}
|
||||
.fourth-item-circle::before,
|
||||
.fourth-item-circle::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: .5em;
|
||||
height: .5em;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(-45deg, #0949ff 0, #03bdff 100%);
|
||||
}
|
||||
.fourth-item-circle::before {
|
||||
top: -.25em;
|
||||
left: 2em;
|
||||
}
|
||||
.fourth-item-circle::after {
|
||||
left: 2em;
|
||||
bottom: -.25em;
|
||||
}
|
||||
|
||||
.fourth-item-title {
|
||||
margin: 0.5em auto 0;
|
||||
font-family: PingFangSC-Medium;
|
||||
font-size: 1.25em;
|
||||
color: #0a1255;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.fourth-item-des {
|
||||
font-family: PingFangSC-Medium;
|
||||
font-size: 1em;
|
||||
color: #777988;
|
||||
line-height: 2em;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.project-item:nth-child(2) {
|
||||
margin-top: 5em;
|
||||
border-color: #df0757;
|
||||
.fourth-item-circle {
|
||||
animation: turnCircle2 infinite 10s linear;
|
||||
}
|
||||
.fourth-item-circle::before,
|
||||
.fourth-item-circle::after {
|
||||
background: linear-gradient(-45deg, #df0757 0, #ffa38d 100%);
|
||||
}
|
||||
}
|
||||
|
||||
.project-item:nth-child(3) {
|
||||
margin-top: 10em;
|
||||
border-color: #00ffa4;
|
||||
.fourth-item-circle::before,
|
||||
.fourth-item-circle::after {
|
||||
background: linear-gradient(-45deg, #00ffa4 0, #f2ffa4 100%);
|
||||
}
|
||||
}
|
||||
|
||||
.project-item:nth-child(4) {
|
||||
margin-top: 8.75em;
|
||||
border-color: #8b5ff0;
|
||||
.fourth-item-circle {
|
||||
animation: turnCircle2 infinite 10s linear;
|
||||
}
|
||||
.fourth-item-circle::before,
|
||||
.fourth-item-circle::after {
|
||||
background: linear-gradient(-45deg, #8b5ff0 0, #fe86ff 100%);
|
||||
}
|
||||
}
|
||||
|
||||
.activeCode {
|
||||
.code-box-picture {
|
||||
animation: taskPicture 1s 1 forwards;
|
||||
}
|
||||
.code-box-code {
|
||||
animation: taskCode 1s 1 0.75s forwards;
|
||||
}
|
||||
.hadoopCode .code-content {
|
||||
margin: 0;
|
||||
animation: showBackgroud 16s 2s infinite;
|
||||
}
|
||||
|
||||
.animation-is-typing::before {
|
||||
animation: BlinkingCursor .8s infinite;
|
||||
}
|
||||
|
||||
.js-type-letters{
|
||||
animation: BlinkingCursor-1 16s infinite;
|
||||
}
|
||||
|
||||
.word-item {
|
||||
animation: show 16s infinite;
|
||||
}
|
||||
&.fourth-projects {
|
||||
animation: taskPicture 1s 1 1s forwards;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
1% {
|
||||
opacity: 1;
|
||||
}
|
||||
70% {
|
||||
opacity: 1;
|
||||
}
|
||||
71% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes BlinkingCursor-1 {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
2% {
|
||||
opacity: 1;
|
||||
}
|
||||
4% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@keyframes BlinkingCursor {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes showBackgroud {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
71% {
|
||||
opacity: 1;
|
||||
}
|
||||
72% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes taskPicture {
|
||||
0% {
|
||||
opacity: 0;
|
||||
top: 35vh;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes taskCode {
|
||||
0% {
|
||||
opacity: 0;
|
||||
top: 35vh;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes turnCircle {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes turnCircle2 {
|
||||
0% {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import React, { memo } from 'react';
|
||||
import './index.scss';
|
||||
|
||||
|
||||
export default memo(() => {
|
||||
return (
|
||||
<p className="home-line">
|
||||
<i className="yellow-line"></i>
|
||||
<i className="brown-line"></i>
|
||||
<i className="yellow-line"></i>
|
||||
</p>
|
||||
)
|
||||
})
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
.home-line {
|
||||
text-align: center;
|
||||
line-height: 0;
|
||||
.yellow-line {
|
||||
display: inline-block;
|
||||
width: 23px;
|
||||
height: 4px;
|
||||
background: #ff8520;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.brown-line {
|
||||
display: inline-block;
|
||||
width: 38px;
|
||||
height: 4px;
|
||||
margin:0 5px;
|
||||
background: #e67a21;
|
||||
border-radius: 3px;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
import React, { memo, useEffect, useState } from 'react';
|
||||
import { Button } from 'antd';
|
||||
import axios from 'axios';
|
||||
import Slider from 'react-slick';
|
||||
import "slick-carousel/slick/slick.css";
|
||||
import "slick-carousel/slick/slick-theme.css";
|
||||
import Line from '../Line';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
|
||||
let setting = {
|
||||
infinite: true,
|
||||
speed: 750,
|
||||
slidesToShow: 3,
|
||||
slidesToScroll: 1,
|
||||
pauseOnDotsHover: true,
|
||||
autoplaySpeed: 4000,
|
||||
centerMode: true,
|
||||
centerPadding: "10px",
|
||||
// pauseOnFocus: true,
|
||||
autoplay: true,
|
||||
arrows: false,
|
||||
vertical: true,
|
||||
}
|
||||
|
||||
|
||||
function SecondSection({ second ,main_web_site_url}) {
|
||||
|
||||
const [leftItem, setLeftItem] = useState({});
|
||||
const [list, setList] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
const url = `/home/platform_communicates.json`;
|
||||
axios.get(url, {
|
||||
params: {
|
||||
limit: 10,
|
||||
page: 1
|
||||
}
|
||||
}).then(result => {
|
||||
if (result && result.data) {
|
||||
let communicates = result.data.communicates;
|
||||
if (communicates.length) {
|
||||
setLeftItem(communicates[0]);
|
||||
setList(communicates.slice(1, 5));
|
||||
}
|
||||
}
|
||||
}).catch(error => { });
|
||||
}, [])
|
||||
|
||||
|
||||
function goDetail(id) {
|
||||
window.open(`${main_web_site_url}/forums/${id}/detail`);
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<h2 className="homePage-blue-tit">社区动态</h2>
|
||||
<h4 className="homePage-subhead">为社区用户提供自主交流空间,实现思维碰撞和智慧融合</h4>
|
||||
<Line />
|
||||
<div className="homepage-main community-main">
|
||||
|
||||
<div className={`community-left ${second ? "community-active" : ''}`}>
|
||||
<div className="community-english">C O M M U N I T Y D Y N A M I C S</div>
|
||||
<h3 className="community-star">
|
||||
<i className="iconfont icon-quxiaoguanzhu"></i>
|
||||
<i className="iconfont icon-quxiaoguanzhu"></i>
|
||||
<i className="iconfont icon-quxiaoguanzhu"></i>
|
||||
<i className="iconfont icon-quxiaoguanzhu"></i>
|
||||
<i className="iconfont icon-quxiaoguanzhu"></i>
|
||||
</h3>
|
||||
|
||||
<h4 className="community-left-tit link" onClick={() => { goDetail(leftItem.fake_id) }}>{leftItem.title}</h4>
|
||||
|
||||
<div className="community-left-content ellipsis-8">
|
||||
{leftItem.content}
|
||||
</div>
|
||||
|
||||
<div className="text-center">
|
||||
<Button className="homepage-btn" type="primary" onClick={() => { window.open(`${main_web_site_url}/forums`)}}>更多动态 <i className="iconfont icon-gengduoicon"></i></Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="home-second-section-slide">
|
||||
<Slider {...setting}>
|
||||
{
|
||||
list&&list.map((item, i) => {
|
||||
return (
|
||||
<div className="news-slide-item" key={i}>
|
||||
<div className="slide-title" >
|
||||
<span className="order-num">{i + 1}</span>
|
||||
<h3 className="slide-title-content ellipsis-1 link" onClick={() => { goDetail(item.fake_id) }}>{item.title}</h3>
|
||||
<span className="slide-tag">{item.tag}</span>
|
||||
</div>
|
||||
<p className="ellipsis-2">{item.content}</p>
|
||||
<span className="news-time">{item.created_time && item.created_time.split(' ')[0]}</span>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Slider>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<svg className="waves waves-low "
|
||||
viewBox="0 24 150 28" preserveAspectRatio="none" shapeRendering="auto">
|
||||
<defs>
|
||||
<path id="wave-path" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
|
||||
</defs>
|
||||
<g className="parallax">
|
||||
{/* <use xlinkHref="#wave-path" x="50" y="3" fill="rgba(4,22,112,0.2)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="0" fill="rgba(4,22,112,0.2)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="9" fill="#041670" /> */}
|
||||
<use xlinkHref="#wave-path" x="50" y="3" fill="rgba(0,55,175,0.2)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="0" fill="rgba(0,55,175,0.2)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="9" fill="#0037AF" />
|
||||
</g>
|
||||
</svg>
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(SecondSection);
|
|
@ -0,0 +1,166 @@
|
|||
.home-second-section {
|
||||
background: linear-gradient(#fff 0%, #cbdcff 100%);
|
||||
text-align: center;
|
||||
padding-top: 40px;
|
||||
margin-bottom: -10px;
|
||||
|
||||
.community-left-tit {
|
||||
font-size: 1.15em;
|
||||
color: #000870;
|
||||
}
|
||||
|
||||
.community-main {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 1.25em auto 3.15em;
|
||||
text-align: left;
|
||||
|
||||
.homepage-btn {
|
||||
margin-top: 2.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.community-english {
|
||||
font-size: 1.25em;
|
||||
opacity: 0.88;
|
||||
color: #e67a21;
|
||||
margin-right: 1.25em;
|
||||
}
|
||||
|
||||
.community-star {
|
||||
color: #ff7a21;
|
||||
i {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.community-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 50%;
|
||||
padding-right: 20px;
|
||||
opacity: 0;
|
||||
text-align: left;
|
||||
}
|
||||
.community-left-content {
|
||||
font-size: .95em;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #3c476e;
|
||||
line-height: 2.25em;
|
||||
}
|
||||
|
||||
.community-active {
|
||||
position: relative;
|
||||
animation: community 0.75s 1 forwards;
|
||||
}
|
||||
|
||||
@keyframes community {
|
||||
0% {
|
||||
right: 50vw;
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
right: 0;
|
||||
opacity: 1;
|
||||
transition: all 2s;
|
||||
}
|
||||
}
|
||||
|
||||
// .parallax > use:nth-child(1) {
|
||||
// animation-delay: -5s;
|
||||
// animation-duration: 20s;
|
||||
// }
|
||||
}
|
||||
|
||||
.home-second-section-slide {
|
||||
width: 50%;
|
||||
.slick-track > div {
|
||||
max-width: 83.3%;
|
||||
position: relative;
|
||||
transition: all 0.7s;
|
||||
}
|
||||
.news-slide-item {
|
||||
height: 11.25em;
|
||||
overflow: hidden;
|
||||
background-image: linear-gradient(
|
||||
to bottom right,
|
||||
#e9f5ff 0%,
|
||||
#f1f2fd 25%,
|
||||
#e8f2ff 50%,
|
||||
#e1eaff 75%,
|
||||
#c6d3ff 100%
|
||||
);
|
||||
margin-bottom: 10px;
|
||||
padding: 1.25em 1.8em 1.6em;
|
||||
border: 1px solid #fff;
|
||||
border-radius: .3em;
|
||||
|
||||
.slide-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.slide-title-content {
|
||||
color: #000870;
|
||||
font-size: 1em;
|
||||
margin-bottom: 0 !important;
|
||||
flex: auto;
|
||||
}
|
||||
.order-num {
|
||||
flex: none;
|
||||
display: inline-block;
|
||||
margin-right: 1em;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
width: 1.75em;
|
||||
height: 1.75em;
|
||||
line-height: 1.75em;
|
||||
background: linear-gradient(
|
||||
272deg,
|
||||
#4154f1 0%,
|
||||
#4154f1 47%,
|
||||
#4154f1 100%
|
||||
);
|
||||
box-shadow: 0px 0px 9px 2px rgba(65, 84, 241, 0.33);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.slide-tag {
|
||||
flex: none;
|
||||
color: #fff;
|
||||
padding: .2em .75em;
|
||||
background: #586dff;
|
||||
border-radius: .2em;
|
||||
}
|
||||
|
||||
|
||||
.news-time {
|
||||
font-size: .95em;
|
||||
font-weight: 400;
|
||||
color: #3c476e;
|
||||
}
|
||||
|
||||
p {
|
||||
margin:1em 0 .5em;
|
||||
color: #3c476e;
|
||||
font-size: .9em;
|
||||
|
||||
}
|
||||
}
|
||||
.slick-center {
|
||||
margin-left: 100px;
|
||||
}
|
||||
|
||||
.slick-slide:nth-child(n) .slide-tag{
|
||||
background: #586dff;
|
||||
}
|
||||
|
||||
.slick-slide:nth-child(2n) .slide-tag{
|
||||
background: #e53939;
|
||||
}
|
||||
|
||||
.slick-slide:nth-child(3n) .slide-tag{
|
||||
background: #ff7300;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
import React, { memo, useEffect, useState } from 'react';
|
||||
import { Button } from 'antd';
|
||||
import axios from 'axios';
|
||||
import Slider from 'react-slick';
|
||||
import "slick-carousel/slick/slick.css";
|
||||
import "slick-carousel/slick/slick-theme.css";
|
||||
import { getTestImage } from "educoder";
|
||||
import Line from '../Line';
|
||||
|
||||
|
||||
import './index.scss';
|
||||
|
||||
|
||||
let setting = {
|
||||
infinite: true,
|
||||
dots:true,
|
||||
speed: 750,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
pauseOnDotsHover: true,
|
||||
autoplaySpeed: 5000,
|
||||
// pauseOnFocus: true,
|
||||
centerMode: true,
|
||||
centerPadding: "0px",
|
||||
autoplay: true,
|
||||
arrows: false,
|
||||
}
|
||||
|
||||
|
||||
function SeventhSection({ main_web_site_url }) {
|
||||
|
||||
const [list, setList] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
const url = `/home/platform_people.json`;
|
||||
axios.get(url, {
|
||||
params: {
|
||||
limit: 6,
|
||||
page: 1
|
||||
}
|
||||
}).then(result => {
|
||||
if (result && result.data) {
|
||||
setList(result.data.people);
|
||||
}
|
||||
}).catch(error => { });
|
||||
}, [])
|
||||
|
||||
function goDetail(fake_login) {
|
||||
window.open(`${main_web_site_url}/accounts/${fake_login}`);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="homepage-main seventh-main">
|
||||
<h2 className="homePage-blue-tit">论坛交流</h2>
|
||||
<h4 className="homePage-subhead">论坛交流版块通过技术交流、学术探讨等方式,为社区用户提供自主交流空间,实现思维碰撞和智慧融合</h4>
|
||||
<Line />
|
||||
<div className="clients">
|
||||
{
|
||||
list&& list.map((item, i) => {
|
||||
return (<img className="client link" key={i} src={getTestImage(item.image_url)} onClick={() => { goDetail(item.fake_login) }} alt="images-not_found" />)
|
||||
})
|
||||
}
|
||||
<i className="start-icon iconfont icon-a-shuangyinhao12x"></i>
|
||||
<i className="end-icon iconfont icon-a-shuangyinhao12x"></i>
|
||||
|
||||
</div>
|
||||
<Slider {...setting}>
|
||||
{
|
||||
list&& list.map((item, i) => {
|
||||
return (<div className="issue-item" key={i} >
|
||||
<img className="author-head link" src={getTestImage(item.image_url)} onClick={() => { goDetail(item.fake_login) }} alt="images-not_found" />
|
||||
<span className="issue-author link" onClick={() => { goDetail(item.fake_login) }}>{item.name}</span>
|
||||
<h3 className="issue-title ellipsis-1">{item.announcement}</h3>
|
||||
<p className="issue-content ellipsis-5">{item.content}</p>
|
||||
<span className="issue-time">{item.created_time && item.created_time.split(' ')[0]}</span>
|
||||
</div>)
|
||||
})
|
||||
}
|
||||
|
||||
</Slider>
|
||||
|
||||
<Button className="homepage-btn" type="primary" onClick={() => { window.open(`${main_web_site_url}/forums`) }}>参与交流 <i className="iconfont icon-gengduoicon"></i></Button>
|
||||
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(SeventhSection);
|
|
@ -0,0 +1,207 @@
|
|||
.home-seventh-section {
|
||||
background: linear-gradient(#fff 0%, #cbdcff 100%);
|
||||
text-align: center;
|
||||
padding-top: 2.5em;
|
||||
padding-bottom: 0.625em;
|
||||
z-index: 100000;
|
||||
margin-bottom: -0.625em;
|
||||
border-bottom: 1px solid #cbdcff;
|
||||
.seventh-main {
|
||||
position: relative;
|
||||
}
|
||||
.clients {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 31.25em;
|
||||
left: 0;
|
||||
bottom: 2.5em;
|
||||
// z-index: 10;
|
||||
.client {
|
||||
position: absolute;
|
||||
width: 6.25em;
|
||||
height: 6.25em;
|
||||
border-radius: 50%;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.client:nth-child(1) {
|
||||
top: 0;
|
||||
left: 0;
|
||||
animation: zoomin 0.9s infinite alternate;
|
||||
}
|
||||
.client:nth-child(2) {
|
||||
top: 11.875em;
|
||||
left: -7.1875em;
|
||||
animation: zoomin 1.3s infinite alternate;
|
||||
}
|
||||
.client:nth-child(3) {
|
||||
left: 0;
|
||||
bottom: 4.375em;
|
||||
animation: zoomin 1.6s infinite alternate;
|
||||
}
|
||||
.client:nth-child(4) {
|
||||
top: 2.5em;
|
||||
right: 0;
|
||||
animation: zoomin 1.9s infinite alternate;
|
||||
}
|
||||
.client:nth-child(5) {
|
||||
right: -5.3125em;
|
||||
bottom: 8.4375em;
|
||||
animation: zoomin 2.1s infinite alternate;
|
||||
}
|
||||
.client:nth-child(6) {
|
||||
right: 9.375em;
|
||||
bottom: 0.625em;
|
||||
animation: zoomin 1.6s infinite alternate;
|
||||
}
|
||||
|
||||
.icon-a-shuangyinhao12x {
|
||||
position: absolute;
|
||||
color: #ef7a30;
|
||||
font-size: 2.25em !important ;
|
||||
}
|
||||
.start-icon {
|
||||
top: 50px;
|
||||
left: 280px;
|
||||
transform: rotateY(180deg);
|
||||
z-index: 100;
|
||||
}
|
||||
.end-icon {
|
||||
bottom: 130px;
|
||||
right: 330px;
|
||||
z-index: 100;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-dots {
|
||||
height: 31.25em;
|
||||
left: 0;
|
||||
bottom: -4.5em;
|
||||
z-index: 101;
|
||||
li {
|
||||
position: absolute;
|
||||
width: 7em;
|
||||
height: 7em;
|
||||
border-radius: 50%;
|
||||
button{
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
&:before {
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
color: #fff;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
li:nth-child(1) {
|
||||
top: -.5em;
|
||||
left: -.5em;
|
||||
}
|
||||
li:nth-child(2) {
|
||||
top: 11.875em;
|
||||
left: -7.6875em;
|
||||
}
|
||||
li:nth-child(3) {
|
||||
left: -.5em;
|
||||
bottom: 3.875em;
|
||||
}
|
||||
li:nth-child(4) {
|
||||
top: 2.5em;
|
||||
right: -.5em;
|
||||
}
|
||||
li:nth-child(5) {
|
||||
right: -5.8125em;
|
||||
bottom: 8em;
|
||||
}
|
||||
li:nth-child(6) {
|
||||
right: 8.875em;
|
||||
bottom: 0.125em;
|
||||
}
|
||||
}
|
||||
.slick-slider {
|
||||
margin: 2.5em auto 1.25em;
|
||||
height: 30em;
|
||||
background: url(../img/7-bg.png) no-repeat;
|
||||
background-size: 50.25em 29.625em;
|
||||
background-position: center;
|
||||
}
|
||||
.slick-list {
|
||||
width: 33.75em;
|
||||
margin: 0 auto;
|
||||
z-index: 10000;
|
||||
}
|
||||
.issue-item {
|
||||
text-align: center;
|
||||
|
||||
.author-head {
|
||||
width: 8.125em;
|
||||
height: 8.125em;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.issue-author {
|
||||
display: inline-block;
|
||||
font-size: 1.125em;
|
||||
font-weight: 500;
|
||||
color: #ff7300;
|
||||
line-height: 1.75em;
|
||||
margin: 0.625em auto;
|
||||
}
|
||||
.issue-title {
|
||||
font-size: 1.25em;
|
||||
font-weight: 500;
|
||||
color: #000870;
|
||||
line-height: 1.75em;
|
||||
margin-bottom: 1.25em;
|
||||
}
|
||||
.issue-content {
|
||||
text-align: left;
|
||||
text-indent: 2em;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
color: #3c476e;
|
||||
line-height: 28px;
|
||||
}
|
||||
.issue-time {
|
||||
height: 28px;
|
||||
font-size: 15px;
|
||||
color: #3c476e;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.homepage-btn {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
@keyframes zoomin {
|
||||
0% {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
.home-seventh-section {
|
||||
.slick-dots,.clients {
|
||||
width: 86%;
|
||||
left: 8%;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
.home-seventh-section {
|
||||
.slick-dots,.clients {
|
||||
width: 80%;
|
||||
left: 11%;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
import React, { memo, useEffect, useState } from 'react';
|
||||
import { Button } from 'antd';
|
||||
import axios from 'axios';
|
||||
import Line from '../Line';
|
||||
import completeIcon1 from '../img/6-completeIcon1.png';
|
||||
import completeIcon2 from '../img/6-completeIcon2.png';
|
||||
import completeIcon3 from '../img/6-completeIcon3.png';
|
||||
import ball from '../img/6-ball.png';
|
||||
import cup from '../img/6-cup.png';
|
||||
import yLetter from '../img/6-y.png';
|
||||
import net from '../img/6-net.png';
|
||||
import overall from '../img/6-overall.png';
|
||||
import pillar1 from '../img/6-pillar1.png';
|
||||
import pillar2 from '../img/6-pillar2.png';
|
||||
import pillar3 from '../img/6-pillar3.png';
|
||||
import './index.scss';
|
||||
let iconArr = [completeIcon1, completeIcon2, completeIcon3];
|
||||
|
||||
|
||||
function SixthSection({ sixth, main_web_site_url }) {
|
||||
|
||||
const [list, setList] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
const url = `/home/competitions.json`;
|
||||
axios.get(url).then(result => {
|
||||
if (result && result.data) {
|
||||
setList(result.data.competitions);
|
||||
}
|
||||
}).catch(error => { });
|
||||
}, [])
|
||||
|
||||
function goDetail(id) {
|
||||
window.open(`${main_web_site_url}/competitions/${id}/enroll`);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="grid-picture">
|
||||
<div className="homepage-main sixth-main">
|
||||
|
||||
<div className={sixth ? "active complete-des" : "complete-des"}>
|
||||
|
||||
{
|
||||
list && list.map((item, i) => {
|
||||
return (
|
||||
<div className="des-item" key={i}>
|
||||
<img className="des-item-img" alt="竞赛" src={iconArr[i]}></img>
|
||||
<div className="des-item-content">
|
||||
<h4 className="des-item-title ellipsis-1 link" onClick={() => { goDetail(item.id) }}>{item.title}</h4>
|
||||
<p className="des-item-time">竞赛时间:{item.start_time && item.start_time.split(' ')[0]}-{item.end_time && item.end_time.split(' ')[0]}</p>
|
||||
<p className="des-item-intro ellipsis-2">赛事简介: {item.content||'暂无简介'}</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="sixth-right">
|
||||
<div className="sixth-right-title">
|
||||
<h2 className="homePage-white-tit">开放竞赛</h2>
|
||||
<h4 className="homePage-white-subhead">开放竞赛版块通过赛事和学术活动组织,为验证技术成果、挖掘优秀人才提供有效途径</h4>
|
||||
<Line />
|
||||
</div>
|
||||
|
||||
<div className="sixth-play-img">
|
||||
<img alt="images-not_found" className="overall" src={overall}></img>
|
||||
<img alt="images-not_found" className="ball" src={ball}></img>
|
||||
<img alt="images-not_found" className="cup" src={cup}></img>
|
||||
<img alt="images-not_found" className="net" src={net}></img>
|
||||
<img alt="images-not_found" className="yLetter" src={yLetter}></img>
|
||||
<img alt="images-not_found" className="pillar3" src={pillar3}></img>
|
||||
<img alt="images-not_found" className="pillar2" src={pillar2}></img>
|
||||
<img alt="images-not_found" className="pillar1" src={pillar1}></img>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<Button className="homepage-btn" type="primary" onClick={() => { window.open(`${main_web_site_url}/competitions`) }}>我要参赛 <i className="iconfont icon-gengduoicon"></i></Button>
|
||||
<svg className="waves"
|
||||
viewBox="0 24 150 28" preserveAspectRatio="none" shapeRendering="auto">
|
||||
<defs>
|
||||
<path id="wave-path" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
|
||||
</defs>
|
||||
<g className="parallax">
|
||||
<use xlinkHref="#wave-path" x="50" y="3" fill="rgba(255,255,255,0.5)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="0" fill="rgba(255,255,255,0.4)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="9" fill="#fff" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default memo(SixthSection);
|
|
@ -0,0 +1,293 @@
|
|||
.home-sixth-section {
|
||||
position: relative;
|
||||
color: #fff;
|
||||
background: linear-gradient(#0037AF 0%, #2951da 100%);
|
||||
text-align: center;
|
||||
margin-bottom: -2px;
|
||||
z-index: 10;
|
||||
.grid-picture {
|
||||
background: url(../img/grid.png) no-repeat;
|
||||
background-size: auto 100%;
|
||||
padding-bottom: 6.25em;
|
||||
}
|
||||
|
||||
.sixth-main {
|
||||
display: flex;
|
||||
padding-top: 10vh;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.des-item {
|
||||
position: relative;
|
||||
opacity: 0;
|
||||
display: flex;
|
||||
padding: .9375em;
|
||||
margin: 1.875em 0;
|
||||
align-items: center;
|
||||
width: 30em;
|
||||
height: 10.625em;
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
box-shadow: 0px 0px .625em .3125em rgba(38, 118, 255, 0.04);
|
||||
border-radius: .625em;
|
||||
border: 1px transparent solid;
|
||||
border-image: linear-gradient(
|
||||
to right,
|
||||
rgba(255, 255, 255, 0.2),
|
||||
rgba(255, 255, 255, 1),
|
||||
rgba(255, 255, 255, 0.2)
|
||||
)
|
||||
1 10;
|
||||
|
||||
p{
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
}
|
||||
|
||||
.des-item:nth-child(2) {
|
||||
margin: 3.75em 0 0 1.25em;
|
||||
}
|
||||
|
||||
.des-item:nth-child(3) {
|
||||
margin: 3.75em 0 0 2.5em;
|
||||
}
|
||||
|
||||
.des-item-img {
|
||||
width: 6.25em;
|
||||
height: 6.25em;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.des-item-content {
|
||||
width: 21.75em;
|
||||
text-align: left;
|
||||
font-size: .9375em;
|
||||
font-weight: 400;
|
||||
line-height: 1.75em;
|
||||
opacity: .8;
|
||||
.des-item-title {
|
||||
font-size: 1.125em;
|
||||
font-family: PingFangSC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #ff9931;
|
||||
line-height: 1.5625em;
|
||||
}
|
||||
}
|
||||
|
||||
.sixth-right {
|
||||
width: 42.5em;
|
||||
overflow: visible;
|
||||
}
|
||||
.sixth-right-title {
|
||||
margin-left: 5em;
|
||||
width: 28.125em;
|
||||
text-align: left;
|
||||
|
||||
.home-line {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
.sixth-play-img {
|
||||
width: 48.1825em;
|
||||
position: relative;
|
||||
|
||||
.ball {
|
||||
position: absolute;
|
||||
top: 18.75em;
|
||||
left: 6.875em;
|
||||
z-index: 1;
|
||||
width: 2.0625em;
|
||||
animation: ball infinite 5s linear;
|
||||
}
|
||||
|
||||
.cup {
|
||||
position: absolute;
|
||||
top: 15%;
|
||||
left: 45%;
|
||||
z-index: 1;
|
||||
width: 5.75em;
|
||||
animation: cup infinite 4s;
|
||||
}
|
||||
|
||||
.net {
|
||||
position: absolute;
|
||||
top: 9%;
|
||||
left: 22%;
|
||||
z-index: 1;
|
||||
width: 3.75em;
|
||||
animation: net infinite 4s 1s;
|
||||
}
|
||||
|
||||
.yLetter {
|
||||
position: absolute;
|
||||
top: 6%;
|
||||
right: 17%;
|
||||
z-index: 1;
|
||||
width: 3.4375em;
|
||||
animation: yLetter infinite 4s 1.5s;
|
||||
}
|
||||
|
||||
.pillar1 {
|
||||
position: absolute;
|
||||
bottom: 10%;
|
||||
left: 43%;
|
||||
z-index: 1;
|
||||
width: 2.25em;
|
||||
height: 2.625em;
|
||||
animation: pillar1 infinite 3s;
|
||||
}
|
||||
.pillar2 {
|
||||
position: absolute;
|
||||
bottom: 12%;
|
||||
left: 40%;
|
||||
z-index: 1;
|
||||
width: 1.75em;
|
||||
height: 3.125em;
|
||||
animation: pillar2 infinite 3s;
|
||||
}
|
||||
.pillar3 {
|
||||
position: absolute;
|
||||
bottom: 12%;
|
||||
left: 42%;
|
||||
z-index: 1;
|
||||
width: 1.75em;
|
||||
height: 3.6875em;
|
||||
animation: pillar3 infinite 3s;
|
||||
}
|
||||
}
|
||||
|
||||
.overall {
|
||||
width: 47.4375em;
|
||||
}
|
||||
|
||||
.homepage-btn{
|
||||
margin-top: 0;
|
||||
background-color: #4F7DFF ;
|
||||
}
|
||||
|
||||
.waves {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -2px;
|
||||
}
|
||||
|
||||
.complete-des.active {
|
||||
.des-item {
|
||||
animation: showTop 1s 1 forwards;
|
||||
}
|
||||
.des-item:nth-child(2) {
|
||||
animation: showTop 1s 1 .75s forwards;
|
||||
}
|
||||
.des-item:nth-child(3) {
|
||||
animation: showTop 1s 1 1.5s forwards;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes showTop {
|
||||
0% {
|
||||
opacity: 0;
|
||||
top: 30vh;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ball {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes cup {
|
||||
0% {
|
||||
top: 12%;
|
||||
}
|
||||
45% {
|
||||
top: 20%;
|
||||
}
|
||||
55% {
|
||||
top: 20%;
|
||||
}
|
||||
100% {
|
||||
top: 12%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes net {
|
||||
0% {
|
||||
top: 2%;
|
||||
}
|
||||
45% {
|
||||
top: 9%;
|
||||
}
|
||||
55% {
|
||||
top: 9%;
|
||||
}
|
||||
100% {
|
||||
top: 2%;
|
||||
}
|
||||
}
|
||||
@keyframes yLetter {
|
||||
0% {
|
||||
top: 0%;
|
||||
}
|
||||
45% {
|
||||
top: 6%;
|
||||
}
|
||||
55% {
|
||||
top: 6%;
|
||||
}
|
||||
100% {
|
||||
top: 0%;
|
||||
}
|
||||
}
|
||||
@keyframes pillar1 {
|
||||
0% {
|
||||
height: 2.5em;
|
||||
}
|
||||
48% {
|
||||
height: 2em;
|
||||
}
|
||||
52% {
|
||||
height: 2em;
|
||||
}
|
||||
100% {
|
||||
height: 2.5em;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pillar2 {
|
||||
0% {
|
||||
height: 2.5em;
|
||||
}
|
||||
48% {
|
||||
height: 4.0625em;
|
||||
}
|
||||
52% {
|
||||
height: 4.0625em;
|
||||
}
|
||||
100% {
|
||||
height: 2.5em;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pillar3 {
|
||||
0% {
|
||||
height: 4.0625em;
|
||||
}
|
||||
48% {
|
||||
height: 2.5em;
|
||||
}
|
||||
52% {
|
||||
height: 2.5em;
|
||||
}
|
||||
100% {
|
||||
height: 4.0625em;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
import React, { memo, useEffect, useState } from 'react';
|
||||
import CountUp from 'react-countup';
|
||||
import axios from 'axios';
|
||||
import Line from '../Line';
|
||||
import './index.scss';
|
||||
|
||||
const countUpProps = {
|
||||
redraw: true,
|
||||
start: 0,
|
||||
duration: 1
|
||||
};
|
||||
|
||||
|
||||
function ThirdSection({ third }) {
|
||||
const [statisticsNum, setStatisticsNum] = useState({});
|
||||
|
||||
useEffect(() => {
|
||||
const url = `/home/platform_statistics.json`;
|
||||
axios.get(url).then(result => {
|
||||
if (result && result.data) {
|
||||
setStatisticsNum(result.data);
|
||||
}
|
||||
}).catch(error => { });
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="ball-background">
|
||||
<h2 className="third-tit">数据统计总览</h2>
|
||||
<Line />
|
||||
<div className="homepage-main third-main ">
|
||||
<div className="circle-item">
|
||||
<div className="circle-item-box">
|
||||
<div className="circle-item-num" style={{fontSize:statisticsNum.visits>9999999?'24px':statisticsNum.visits>99999?'36px':'48px'}}>
|
||||
<CountUp
|
||||
{...countUpProps}
|
||||
end={statisticsNum.visits}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<h4>平台点击量</h4>
|
||||
</div>
|
||||
|
||||
<div className="circle-item">
|
||||
<div className="circle-item-box">
|
||||
<div className="circle-item-num">
|
||||
<CountUp {...countUpProps} end={statisticsNum.users_count} />
|
||||
</div>
|
||||
</div>
|
||||
<h4 >平台用户数</h4>
|
||||
</div>
|
||||
|
||||
<div className="circle-item">
|
||||
<div className="circle-item-box">
|
||||
<div className="circle-item-num">
|
||||
<CountUp {...countUpProps} end={statisticsNum.projects_count} />
|
||||
</div>
|
||||
</div>
|
||||
<h4 >开源项目托管数</h4>
|
||||
</div>
|
||||
|
||||
<div className="circle-item">
|
||||
<div className="circle-item-box">
|
||||
<div className="circle-item-num">
|
||||
<CountUp {...countUpProps} end={statisticsNum.tasks_count} />
|
||||
</div>
|
||||
</div>
|
||||
<h4 >创客任务发布数</h4>
|
||||
</div>
|
||||
|
||||
<div className="circle-item">
|
||||
<div className="circle-item-box">
|
||||
<div className="circle-item-num">
|
||||
<CountUp {...countUpProps} end={statisticsNum.memos_count} />
|
||||
</div>
|
||||
</div>
|
||||
<h4 >论坛发帖数量</h4>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<svg className="waves waves-low "
|
||||
viewBox="0 24 150 28" preserveAspectRatio="none" shapeRendering="auto">
|
||||
<defs>
|
||||
<path id="wave-path" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
|
||||
</defs>
|
||||
<g className="parallax">
|
||||
<use xlinkHref="#wave-path" x="50" y="0" fill="rgba(255,255,255,0.7" />
|
||||
<use xlinkHref="#wave-path" x="50" y="0" fill="rgba(255,255,255,0.4)" />
|
||||
<use xlinkHref="#wave-path" x="50" y="9" fill="#fff" />
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(ThirdSection);
|
|
@ -0,0 +1,168 @@
|
|||
.home-third-section {
|
||||
color: #fff;
|
||||
background: linear-gradient(
|
||||
#0037AF 0%,
|
||||
#2951DA 100%,
|
||||
);
|
||||
text-align: center;
|
||||
// #041670 0%,
|
||||
|
||||
.ball-background{
|
||||
background: url(../img/3-ballBg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.third-tit {
|
||||
padding-top: 1.75em;
|
||||
color: #fff;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.third-main {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
max-width: 100%;
|
||||
margin: 10vh auto;
|
||||
}
|
||||
|
||||
.circle-item > h4 {
|
||||
margin-top: 1.25em;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
|
||||
.circle-item-box {
|
||||
position: relative;
|
||||
width: 10.25em;
|
||||
height: 10.25em;
|
||||
box-sizing: border-box;
|
||||
padding: .25em;
|
||||
border-radius: 50%;
|
||||
background-image: linear-gradient(
|
||||
to bottom right,
|
||||
rgba(255, 255, 255, 0.63) 0%,
|
||||
rgba(55, 236, 255, 0.56) 33%,
|
||||
rgba(255, 255, 255, 0.42) 67%,
|
||||
rgba(255, 255, 255, 0.45) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.circle-item-num {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
background: #12277b;
|
||||
font-size: 3em;
|
||||
font-weight: 600;
|
||||
span {
|
||||
background-image: -webkit-linear-gradient(bottom, red, #fd8403, yellow);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
left: -5%;
|
||||
top: -5%;
|
||||
content: "";
|
||||
background-image: url(../img/3-dashCircle.png);
|
||||
width: 110%;
|
||||
height: 110%;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
z-index: 9;
|
||||
opacity: 1;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover::before{
|
||||
visibility: visible;
|
||||
animation: dashCircle infinite 4s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.circle-item:nth-child(2) {
|
||||
.circle-item-box {
|
||||
background-image: linear-gradient(
|
||||
to bottom left,
|
||||
rgba(255, 255, 255, 0.88) 0%,
|
||||
rgba(7, 188, 207, 0.56) 33%,
|
||||
rgba(255, 255, 255, 0.16) 67%,
|
||||
rgba(255, 255, 255, 1) 100%
|
||||
);
|
||||
}
|
||||
span {
|
||||
background-image: -webkit-linear-gradient(bottom, #f5f65b, #15ccf6);
|
||||
}
|
||||
}
|
||||
|
||||
.circle-item:nth-child(3) {
|
||||
.circle-item-box {
|
||||
background-image: linear-gradient(
|
||||
to bottom left,
|
||||
rgba(255, 255, 255, 1) 0%,
|
||||
rgba(255, 255, 255, 0.16) 0%,
|
||||
rgba(7, 188, 207, 0.56) 33%,
|
||||
rgba(255, 255, 255, 0.88) 100%
|
||||
);
|
||||
}
|
||||
span {
|
||||
background-image: -webkit-linear-gradient(bottom, #bad3ff, #00a0dd);
|
||||
}
|
||||
}
|
||||
|
||||
.circle-item:nth-child(4) {
|
||||
.circle-item-box {
|
||||
background-image: linear-gradient(
|
||||
to bottom left,
|
||||
rgba(255, 255, 255, 0.88) 0%,
|
||||
rgba(7, 188, 207, 0.56) 33%,
|
||||
rgba(255, 255, 255, 0.16) 67%,
|
||||
rgba(255, 255, 255, 1) 100%
|
||||
);
|
||||
}
|
||||
span {
|
||||
background-image: -webkit-linear-gradient(bottom, #f0a3ff, #b33dff);
|
||||
}
|
||||
}
|
||||
|
||||
.circle-item:nth-child(5) {
|
||||
.circle-item-box {
|
||||
background-image: linear-gradient(
|
||||
to bottom left,
|
||||
rgba(255, 255, 255, 0.45) 0%,
|
||||
rgba(7, 188, 207, 0.56) 33%,
|
||||
rgba(255, 255, 255, 0.16) 67%,
|
||||
rgba(255, 255, 255, 1) 100%
|
||||
);
|
||||
}
|
||||
span {
|
||||
background-image: -webkit-linear-gradient(bottom, #08ece1, #ff7e3d);
|
||||
}
|
||||
}
|
||||
|
||||
.circle-item .circle-item-box {
|
||||
&:hover{
|
||||
background:rgba(255, 255, 255, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.waves{
|
||||
position: relative;
|
||||
bottom: -1.5vh;
|
||||
}
|
||||
|
||||
@keyframes dashCircle {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 130 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 108 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 211 KiB |
After Width: | Height: | Size: 207 KiB |
After Width: | Height: | Size: 157 KiB |
After Width: | Height: | Size: 1.6 MiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 282 KiB |
After Width: | Height: | Size: 182 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 751 KiB |