Compare commits
331 Commits
master
...
gitlink_se
Author | SHA1 | Date |
---|---|---|
|
6904116a3a | |
|
421218ef77 | |
|
5f89356679 | |
|
cab540b812 | |
|
2ffa835b84 | |
|
e93778b004 | |
|
232e09c04f | |
|
459e05f465 | |
|
5ee3519c21 | |
|
4270d1d8eb | |
|
dd298380a7 | |
|
255ae11012 | |
|
ec4e70d7f0 | |
|
758600e4d0 | |
|
7d4def6056 | |
|
a1cc59e89b | |
|
9e4ca503df | |
|
472ea69e29 | |
|
3c5e10fa58 | |
|
915bf69e6f | |
|
a00452b960 | |
|
3eeed4620c | |
|
54858bcd39 | |
|
6820fed5b5 | |
|
82ac32d84f | |
|
fe6f8a9349 | |
|
d4f0d21608 | |
|
56c867a4a3 | |
|
bd219c0b41 | |
|
1292019aac | |
|
33e1b7e400 | |
|
9af269061d | |
|
2557b36cea | |
|
f6c84e4fad | |
|
161866aaaf | |
|
3151314529 | |
|
775434d856 | |
|
b802fd2fbd | |
|
cee82314da | |
|
7295a71bc5 | |
|
4971dc0a3d | |
|
e591de00fd | |
|
c331dbb445 | |
|
36a58c0fe3 | |
|
0e949110fd | |
|
4ffb2acc9c | |
|
0991ba4698 | |
|
f82a51fd83 | |
|
98ed1794cf | |
|
6e756826f7 | |
|
684f9dbfe1 | |
|
9577478e97 | |
|
ff9beb0949 | |
|
f4055e50e2 | |
|
af8a5058b8 | |
|
efb918e21d | |
|
a9a3f9c977 | |
|
d6b0eee067 | |
|
ca409857bb | |
|
219590a0cd | |
|
2f88227388 | |
![]() |
a3b943f744 | |
![]() |
8b4fc88b1d | |
|
131d8fa81c | |
|
3c2e899a20 | |
|
07511efbd6 | |
|
3eaf1dc214 | |
|
9608f204e8 | |
|
534a6bdeab | |
|
ca5c279ac0 | |
|
ce3b460717 | |
|
1c87cf6b98 | |
|
614f0ea436 | |
|
a3ae80aa22 | |
|
70f9cd0997 | |
|
fa247e39bf | |
|
97a81572a9 | |
|
e084b015cf | |
|
cbe427a114 | |
|
f842f75065 | |
|
c8eed99f5d | |
|
fbd4273603 | |
|
9299a1667e | |
|
10c9891b7b | |
|
e5f8eac497 | |
|
633dee9655 | |
|
e7b7d20f94 | |
|
801c544f65 | |
|
5a1fcb1443 | |
|
cf1d2dd5ba | |
|
121b1aaab1 | |
|
3e42a620d9 | |
|
33297226ea | |
|
982536b547 | |
|
fd4046af04 | |
|
36683ad69b | |
|
2262508777 | |
|
4f64b840b0 | |
|
a04b8de39e | |
|
4d99c97370 | |
|
58f7c984a2 | |
|
9db8455de8 | |
|
4b1bccd1cd | |
|
eff12234fa | |
|
77fdafd58b | |
|
5fea412ca8 | |
|
5f15b03462 | |
![]() |
a2f63732cf | |
![]() |
abf9b25651 | |
|
bf4ef7023d | |
|
f463b20de7 | |
|
7934f07cea | |
![]() |
f19a9f6ceb | |
![]() |
8b5e159cac | |
![]() |
16dff252c0 | |
|
fe0fab7b61 | |
|
4e18d13b6b | |
|
d81d456d76 | |
|
8c66d817b5 | |
|
7579dc8a59 | |
|
3087e5471a | |
|
4e8f304262 | |
|
48e9ca6706 | |
|
fc8a476aa3 | |
|
89773b5036 | |
|
387387108a | |
|
2617831a9f | |
|
f0747eab05 | |
![]() |
789e84211c | |
|
12ce0aa4f5 | |
|
4a322d1e2e | |
|
a38b4af8bc | |
|
d1743b350d | |
|
7fd790fe7d | |
|
c48e3584c3 | |
|
d0ca09e780 | |
|
ed3bf55f90 | |
|
7ff29fec70 | |
|
79331db271 | |
|
fbfd5f175d | |
|
07101f5770 | |
|
652de9b441 | |
![]() |
f2a660d595 | |
|
711c2e57da | |
![]() |
6fc441d7c5 | |
|
a94d02bb8a | |
|
cc2dd35ff4 | |
|
f003a99779 | |
![]() |
b4e2c6148a | |
|
b1ead191a6 | |
![]() |
0735968e73 | |
![]() |
37f5bce087 | |
![]() |
951792dc11 | |
![]() |
7d7f265ffb | |
|
7495c54f8d | |
![]() |
631f8ceeea | |
![]() |
d70ddfb2f7 | |
![]() |
54741a6d8a | |
|
116c3e531f | |
|
990cfe2781 | |
|
66e1235c3b | |
|
76fdff6737 | |
|
55a6f93fe3 | |
|
4bc79b5153 | |
|
ac4488a907 | |
![]() |
3085e40426 | |
|
ea979b78ee | |
|
b1775e5158 | |
|
3678b8eb72 | |
|
12d8f5bf5d | |
|
e04fb11194 | |
|
010edf3cb2 | |
|
ab26a528b6 | |
|
6d39e25667 | |
![]() |
a2ea832208 | |
![]() |
d1bc3680b9 | |
![]() |
08416390e5 | |
|
190200d1e6 | |
|
b124364203 | |
|
2078a044b6 | |
![]() |
35c2f63c55 | |
![]() |
30c61f0a7d | |
![]() |
743dabd553 | |
![]() |
015296e065 | |
|
48c21ac245 | |
![]() |
a93b8a08c9 | |
![]() |
1c48ffb130 | |
|
0ee9280bb1 | |
|
e785e9a358 | |
|
b3b95e9856 | |
![]() |
5be8ead356 | |
|
7d78919c4a | |
|
d5b4c5425f | |
![]() |
f259f05cdc | |
|
95cd289373 | |
|
e739f5b786 | |
![]() |
c79be9a597 | |
|
fb03565a25 | |
|
7ec53a246c | |
|
56946f94e8 | |
![]() |
61ee3fe36f | |
![]() |
d5f989bbe2 | |
![]() |
f5817e5150 | |
![]() |
1c24baf3b9 | |
![]() |
3d3ef19d4a | |
|
7b77c46915 | |
|
746f552a21 | |
|
7872d5ecab | |
|
60da6bd110 | |
![]() |
a3bbf6b1c1 | |
![]() |
d37709b1a5 | |
|
aeff357660 | |
|
0e6cb3954a | |
|
ae12618c0c | |
|
1c46617144 | |
|
ec133a6880 | |
|
bcdb631c20 | |
|
8021d96cd8 | |
![]() |
914966bd39 | |
![]() |
f89f4b6628 | |
|
7407545d1f | |
![]() |
f0ffc9a29c | |
|
987eb39681 | |
![]() |
848109afe8 | |
![]() |
d7bdb35bb7 | |
![]() |
254b3173d1 | |
![]() |
44f06b7305 | |
|
b16e95923a | |
![]() |
98a7f73c04 | |
![]() |
b6a450a482 | |
|
66c495d6b5 | |
![]() |
42139ef998 | |
|
925d5ea356 | |
![]() |
ad1f0e29e7 | |
|
3498390974 | |
|
4f3e385f78 | |
|
18b289b84c | |
|
e3f49db5c0 | |
|
4add266047 | |
|
4a6012bfa9 | |
|
7fe88aa4d9 | |
|
bc6ef583fb | |
|
b268b540d8 | |
|
7e69c64c9c | |
|
85ef26f70e | |
|
8c7865d2c1 | |
|
999a15761d | |
|
5c2330512e | |
![]() |
3da9306ed6 | |
![]() |
568a632d65 | |
![]() |
5982c0df96 | |
|
21046bbcb7 | |
![]() |
0c816805fb | |
![]() |
28f8b6b54c | |
![]() |
7d087ec1f2 | |
|
beba8975ca | |
![]() |
d4690cc8b5 | |
![]() |
38021c2e4b | |
![]() |
4233811ae3 | |
![]() |
8273acd195 | |
|
cacb8c84ae | |
|
fb8ae3fcdf | |
|
a257d832cb | |
|
ff7d191011 | |
|
9a2c3f1754 | |
|
bcdf506e6c | |
|
ccc6cb5d26 | |
|
0661c6b932 | |
|
99947c0c87 | |
|
03cff6ec2e | |
|
f86acfebdf | |
|
9a62d7806e | |
|
a7df6da5f0 | |
|
eab68ac270 | |
|
a9e3513706 | |
|
6b20391c72 | |
|
3135300fe6 | |
|
ecc6387113 | |
|
990c4e22b0 | |
|
7eea9316dd | |
|
6a546c79e4 | |
|
4c48b6c77a | |
|
4d5430c3ed | |
|
d49af735f1 | |
|
03370e8a07 | |
|
0b43fa8952 | |
|
465c4cc8c7 | |
|
37668ddcd4 | |
|
7102594444 | |
|
b2f2df65bb | |
|
8a577fb263 | |
|
5c491071b6 | |
|
c554237076 | |
|
d22a741bf7 | |
|
383b3f5d74 | |
|
63da7adcf9 | |
|
3243aeebc6 | |
|
1a86a75345 | |
|
3b6cc99d49 | |
|
d872ffc606 | |
|
3b69c01ead | |
|
1e0608aa14 | |
|
9b6816e346 | |
|
6ee257231d | |
|
70edb73f6c | |
|
5c7553d4aa | |
|
278701f24b | |
|
97ab819bf9 | |
|
d870f17b85 | |
|
91ac6c2357 | |
|
3702d1c1a5 | |
|
93d48c359e | |
|
80dace18e9 | |
|
375cbb37df | |
|
10d933e037 | |
|
4fdd3f6f80 | |
|
458b56e33b | |
|
c256887132 | |
|
6a588db7f6 | |
|
6c4e1c6665 | |
|
c554d2c00d | |
|
b69bf5974a | |
|
ecb1691b4d | |
|
6a9f2b31a6 | |
|
4947cd8456 | |
|
8429effe16 | |
|
49ebe450be | |
|
e3c926da77 | |
|
af48da2eb3 | |
|
6630309466 | |
|
a7c3dee7e3 |
|
@ -9,7 +9,7 @@
|
|||
"antd": "^3.26.15",
|
||||
"array-flatten": "^2.1.2",
|
||||
"autoprefixer": "7.1.6",
|
||||
"axios": "^0.18.1",
|
||||
"axios": "^0.24.0",
|
||||
"babel-eslint": "7.2.3",
|
||||
"babel-jest": "20.0.3",
|
||||
"babel-loader": "7.1.2",
|
||||
|
@ -24,11 +24,11 @@
|
|||
"classnames": "^2.2.5",
|
||||
"clipboard": "^2.0.8",
|
||||
"code-prettify": "^0.1.0",
|
||||
"codemirror": "^5.53.0",
|
||||
"codemirror": "^5.64.0",
|
||||
"connected-react-router": "4.4.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^3.5.2",
|
||||
"dompurify": "^2.0.15",
|
||||
"dompurify": "^2.3.3",
|
||||
"dotenv": "4.0.0",
|
||||
"dotenv-expand": "4.2.0",
|
||||
"echarts": "^4.9.0",
|
||||
|
@ -51,7 +51,7 @@
|
|||
"js-base64": "^2.5.2",
|
||||
"js2wordcloud": "^1.1.12",
|
||||
"katex": "^0.11.1",
|
||||
"lodash": "^4.17.15",
|
||||
"lodash": "^4.17.21",
|
||||
"loglevel": "^1.6.8",
|
||||
"marked": "^1.0.0",
|
||||
"material-ui": "^1.0.0-beta.40",
|
||||
|
@ -84,6 +84,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",
|
||||
|
|
|
@ -1268,11 +1268,17 @@ a.shixun-task-btn {
|
|||
|
||||
|
||||
/*-----------实训配置、评测脚本-------------*/
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2340181 */
|
||||
src: url('iconfont.woff2?t=1631773579834') format('woff2'),
|
||||
url('iconfont.woff?t=1631773579834') format('woff'),
|
||||
url('iconfont.ttf?t=1631773579834') format('truetype');
|
||||
}
|
||||
html body {
|
||||
font-size: 14px;
|
||||
line-height: 2.0;
|
||||
background: #fafafa;
|
||||
font-family: "Microsoft YaHei", "SimSun";
|
||||
font-family: "iconfont";
|
||||
color: #05101a;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
@ -3941,7 +3947,7 @@ html>body #ajax-indicator {
|
|||
}
|
||||
.head-nav {
|
||||
text-align: center;
|
||||
height: 70px;
|
||||
height: 58px;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
@ -3953,14 +3959,14 @@ html>body #ajax-indicator {
|
|||
position: absolute;
|
||||
top: 0px;
|
||||
z-index: 3;
|
||||
height: 70px;
|
||||
height: 58px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li {
|
||||
float: left;
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
height: 58px;
|
||||
line-height: 58px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
|
@ -3971,7 +3977,7 @@ html>body #ajax-indicator {
|
|||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
color: #333;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
|
@ -3983,10 +3989,6 @@ html>body #ajax-indicator {
|
|||
margin-right: 0px
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li.active{
|
||||
/* background-color: #3B3B3B; */
|
||||
}
|
||||
|
||||
|
||||
.head-nav ul#header-nav li p:hover {
|
||||
color: #cccccc;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2340181 */
|
||||
src: url('iconfont.woff2?t=1634881729644') format('woff2'),
|
||||
url('iconfont.woff?t=1634881729644') format('woff'),
|
||||
url('iconfont.ttf?t=1634881729644') format('truetype');
|
||||
src: url('iconfont.woff2?t=1637544235157') format('woff2'),
|
||||
url('iconfont.woff?t=1637544235157') format('woff'),
|
||||
url('iconfont.ttf?t=1637544235157') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -13,6 +13,106 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-zhishitupu:before {
|
||||
content: "\e8fc";
|
||||
}
|
||||
|
||||
.icon-jisuanji1:before {
|
||||
content: "\e8fd";
|
||||
}
|
||||
|
||||
.icon-dianzi1:before {
|
||||
content: "\e8ff";
|
||||
}
|
||||
|
||||
.icon-junshililun1:before {
|
||||
content: "\e900";
|
||||
}
|
||||
|
||||
.icon-ruanjiangongcheng1:before {
|
||||
content: "\e901";
|
||||
}
|
||||
|
||||
.icon-yixue1:before {
|
||||
content: "\e902";
|
||||
}
|
||||
|
||||
.icon-tongxin1:before {
|
||||
content: "\e904";
|
||||
}
|
||||
|
||||
.icon-zhengcefagui1:before {
|
||||
content: "\e906";
|
||||
}
|
||||
|
||||
.icon-dashuju:before {
|
||||
content: "\e8f3";
|
||||
}
|
||||
|
||||
.icon-rengongzhineng:before {
|
||||
content: "\e8f6";
|
||||
}
|
||||
|
||||
.icon-a-shuangyinhao12x:before {
|
||||
content: "\e8f2";
|
||||
}
|
||||
|
||||
.icon-dingbu:before {
|
||||
content: "\e8ee";
|
||||
}
|
||||
|
||||
.icon-bangzhu1:before {
|
||||
content: "\e8ef";
|
||||
}
|
||||
|
||||
.icon-yijianfankui2:before {
|
||||
content: "\e8f0";
|
||||
}
|
||||
|
||||
.icon-fenxiang:before {
|
||||
content: "\e8f1";
|
||||
}
|
||||
|
||||
.icon-dizhi:before {
|
||||
content: "\e8eb";
|
||||
}
|
||||
|
||||
.icon-youxiang1:before {
|
||||
content: "\e8ec";
|
||||
}
|
||||
|
||||
.icon-dianhuaicon:before {
|
||||
content: "\e8ed";
|
||||
}
|
||||
|
||||
.icon-tianjiaicon:before {
|
||||
content: "\e8e8";
|
||||
}
|
||||
|
||||
.icon-lingshengicon:before {
|
||||
content: "\e8ea";
|
||||
}
|
||||
|
||||
.icon-gengduoicon:before {
|
||||
content: "\e8e5";
|
||||
}
|
||||
|
||||
.icon-shijianicon:before {
|
||||
content: "\e8e7";
|
||||
}
|
||||
|
||||
.icon-mimaicon:before {
|
||||
content: "\e8e1";
|
||||
}
|
||||
|
||||
.icon-gouicon:before {
|
||||
content: "\e8e2";
|
||||
}
|
||||
|
||||
.icon-zhankaiicon:before {
|
||||
content: "\e8e3";
|
||||
}
|
||||
|
||||
.icon-wenjian7:before {
|
||||
content: "\e8e0";
|
||||
}
|
||||
|
|
|
@ -5,6 +5,181 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "25748537",
|
||||
"name": "知识图谱",
|
||||
"font_class": "zhishitupu",
|
||||
"unicode": "e8fc",
|
||||
"unicode_decimal": 59644
|
||||
},
|
||||
{
|
||||
"icon_id": "25748551",
|
||||
"name": "计算机",
|
||||
"font_class": "jisuanji1",
|
||||
"unicode": "e8fd",
|
||||
"unicode_decimal": 59645
|
||||
},
|
||||
{
|
||||
"icon_id": "25748553",
|
||||
"name": "电子",
|
||||
"font_class": "dianzi1",
|
||||
"unicode": "e8ff",
|
||||
"unicode_decimal": 59647
|
||||
},
|
||||
{
|
||||
"icon_id": "25748554",
|
||||
"name": "军事理论",
|
||||
"font_class": "junshililun1",
|
||||
"unicode": "e900",
|
||||
"unicode_decimal": 59648
|
||||
},
|
||||
{
|
||||
"icon_id": "25748555",
|
||||
"name": "软件工程",
|
||||
"font_class": "ruanjiangongcheng1",
|
||||
"unicode": "e901",
|
||||
"unicode_decimal": 59649
|
||||
},
|
||||
{
|
||||
"icon_id": "25748556",
|
||||
"name": "医学",
|
||||
"font_class": "yixue1",
|
||||
"unicode": "e902",
|
||||
"unicode_decimal": 59650
|
||||
},
|
||||
{
|
||||
"icon_id": "25748558",
|
||||
"name": "通信",
|
||||
"font_class": "tongxin1",
|
||||
"unicode": "e904",
|
||||
"unicode_decimal": 59652
|
||||
},
|
||||
{
|
||||
"icon_id": "25748560",
|
||||
"name": "政策法规",
|
||||
"font_class": "zhengcefagui1",
|
||||
"unicode": "e906",
|
||||
"unicode_decimal": 59654
|
||||
},
|
||||
{
|
||||
"icon_id": "25748528",
|
||||
"name": "大数据",
|
||||
"font_class": "dashuju",
|
||||
"unicode": "e8f3",
|
||||
"unicode_decimal": 59635
|
||||
},
|
||||
{
|
||||
"icon_id": "25748531",
|
||||
"name": "人工智能",
|
||||
"font_class": "rengongzhineng",
|
||||
"unicode": "e8f6",
|
||||
"unicode_decimal": 59638
|
||||
},
|
||||
{
|
||||
"icon_id": "25733167",
|
||||
"name": "双引号(1)@2x",
|
||||
"font_class": "a-shuangyinhao12x",
|
||||
"unicode": "e8f2",
|
||||
"unicode_decimal": 59634
|
||||
},
|
||||
{
|
||||
"icon_id": "25701947",
|
||||
"name": "顶部",
|
||||
"font_class": "dingbu",
|
||||
"unicode": "e8ee",
|
||||
"unicode_decimal": 59630
|
||||
},
|
||||
{
|
||||
"icon_id": "25701948",
|
||||
"name": "帮助",
|
||||
"font_class": "bangzhu1",
|
||||
"unicode": "e8ef",
|
||||
"unicode_decimal": 59631
|
||||
},
|
||||
{
|
||||
"icon_id": "25701949",
|
||||
"name": "意见反馈",
|
||||
"font_class": "yijianfankui2",
|
||||
"unicode": "e8f0",
|
||||
"unicode_decimal": 59632
|
||||
},
|
||||
{
|
||||
"icon_id": "25701950",
|
||||
"name": "分享",
|
||||
"font_class": "fenxiang",
|
||||
"unicode": "e8f1",
|
||||
"unicode_decimal": 59633
|
||||
},
|
||||
{
|
||||
"icon_id": "25580217",
|
||||
"name": "地址",
|
||||
"font_class": "dizhi",
|
||||
"unicode": "e8eb",
|
||||
"unicode_decimal": 59627
|
||||
},
|
||||
{
|
||||
"icon_id": "25580218",
|
||||
"name": "邮箱",
|
||||
"font_class": "youxiang1",
|
||||
"unicode": "e8ec",
|
||||
"unicode_decimal": 59628
|
||||
},
|
||||
{
|
||||
"icon_id": "25580219",
|
||||
"name": "电话icon",
|
||||
"font_class": "dianhuaicon",
|
||||
"unicode": "e8ed",
|
||||
"unicode_decimal": 59629
|
||||
},
|
||||
{
|
||||
"icon_id": "25284174",
|
||||
"name": "添加icon",
|
||||
"font_class": "tianjiaicon",
|
||||
"unicode": "e8e8",
|
||||
"unicode_decimal": 59624
|
||||
},
|
||||
{
|
||||
"icon_id": "25284175",
|
||||
"name": "铃声icon",
|
||||
"font_class": "lingshengicon",
|
||||
"unicode": "e8ea",
|
||||
"unicode_decimal": 59626
|
||||
},
|
||||
{
|
||||
"icon_id": "25204490",
|
||||
"name": "更多icon",
|
||||
"font_class": "gengduoicon",
|
||||
"unicode": "e8e5",
|
||||
"unicode_decimal": 59621
|
||||
},
|
||||
{
|
||||
"icon_id": "25204491",
|
||||
"name": "时间icon",
|
||||
"font_class": "shijianicon",
|
||||
"unicode": "e8e7",
|
||||
"unicode_decimal": 59623
|
||||
},
|
||||
{
|
||||
"icon_id": "25188228",
|
||||
"name": "密码icon",
|
||||
"font_class": "mimaicon",
|
||||
"unicode": "e8e1",
|
||||
"unicode_decimal": 59617
|
||||
},
|
||||
{
|
||||
"icon_id": "25188229",
|
||||
"name": "钩icon",
|
||||
"font_class": "gouicon",
|
||||
"unicode": "e8e2",
|
||||
"unicode_decimal": 59618
|
||||
},
|
||||
{
|
||||
"icon_id": "25188230",
|
||||
"name": "展开icon",
|
||||
"font_class": "zhankaiicon",
|
||||
"unicode": "e8e3",
|
||||
"unicode_decimal": 59619
|
||||
},
|
||||
{
|
||||
"icon_id": "24656750",
|
||||
"name": "文件",
|
||||
|
|
After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.4 KiB |
856
src/App.js
|
@ -3,14 +3,13 @@ import './App.css';
|
|||
import { ConfigProvider } from 'antd'
|
||||
import zhCN from 'antd/lib/locale-provider/zh_CN';
|
||||
import {
|
||||
// BrowserRouter as Router,
|
||||
Route,
|
||||
Switch
|
||||
Route,
|
||||
Switch
|
||||
} from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import LoginDialog from './modules/login/LoginDialog';
|
||||
import 'babel-polyfill';
|
||||
import Loading from './Loading'
|
||||
import Loading from './Loading';
|
||||
|
||||
import Loadable from 'react-loadable';
|
||||
import marked from './common/marked';
|
||||
|
@ -26,18 +25,18 @@ import configureStore from './redux/stores/configureStore';
|
|||
const store = configureStore();
|
||||
window.marked = marked;
|
||||
const theme = createMuiTheme({
|
||||
palette: {
|
||||
primary: {
|
||||
main: '#4CACFF',
|
||||
contrastText: 'rgba(255, 255, 255, 0.87)'
|
||||
},
|
||||
secondary: { main: '#4CACFF' }, // #11cb5f This is just green.A700 as hex.
|
||||
},
|
||||
palette: {
|
||||
primary: {
|
||||
main: '#4CACFF',
|
||||
contrastText: 'rgba(255, 255, 255, 0.87)'
|
||||
},
|
||||
secondary: { main: '#4CACFF' }, // #11cb5f This is just green.A700 as hex.
|
||||
},
|
||||
});
|
||||
//forge项目
|
||||
const Projects = Loadable({
|
||||
loader: () => import('./forge/Index'),
|
||||
loading: Loading,
|
||||
loader: () => import('./forge/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
// forge项目详情
|
||||
const ProjectDetail = Loadable({
|
||||
|
@ -46,470 +45,499 @@ const ProjectDetail = Loadable({
|
|||
});
|
||||
//forge安全设置
|
||||
const Security = Loadable({
|
||||
loader: () => import('./forge/SecuritySetting/Index'),
|
||||
loading: Loading,
|
||||
loader: () => import('./forge/SecuritySetting/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
//forge项目-devOps详情
|
||||
const OpsDetail = Loadable({
|
||||
loader: () => import('./forge/DevOps/opsDetail'),
|
||||
loading: Loading,
|
||||
loader: () => import('./forge/DevOps/opsDetail'),
|
||||
loading: Loading,
|
||||
})
|
||||
//403页面
|
||||
const Shixunauthority = Loadable({
|
||||
loader: () => import('./modules/403/Shixunauthority'),
|
||||
loading: Loading,
|
||||
loader: () => import('./modules/403/Shixunauthority'),
|
||||
loading: Loading,
|
||||
})
|
||||
//404页面
|
||||
const Shixunnopage = Loadable({
|
||||
loader: () => import('./modules/404/Shixunnopage'),
|
||||
loading: Loading,
|
||||
loader: () => import('./modules/404/Shixunnopage'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
//500页面
|
||||
const http500 = Loadable({
|
||||
loader: () => import('./modules/500/http500'),
|
||||
loading: Loading,
|
||||
loader: () => import('./modules/500/http500'),
|
||||
loading: Loading,
|
||||
})
|
||||
const InfosIndex = Loadable({
|
||||
loader: () => import('./forge/users/Index'),
|
||||
loading: Loading,
|
||||
loader: () => import('./forge/users/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
// 组织
|
||||
const OrganizeIndex = Loadable({
|
||||
loader: () => import('./forge/Team/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
const EducoderLogin = Loadable({
|
||||
loader: () => import('./modules/login/EducoderLogin'),
|
||||
loading: Loading,
|
||||
loader: () => import('./forge/Team/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
const Search = Loadable({
|
||||
loader: () => import('./modules/search/'),
|
||||
loading: Loading,
|
||||
loader: () => import('./modules/search/'),
|
||||
loading: Loading,
|
||||
})
|
||||
const WikiPreview = Loadable({
|
||||
loader: () => import('./forge/Wiki/Preview'),
|
||||
loading: Loading,
|
||||
loader: () => import('./forge/Wiki/Preview'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
const ProjectIndex = Loadable({
|
||||
loader: () => import("./forge/Index"),
|
||||
loading: Loading,
|
||||
loader: () => import("./forge/Index"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const Home = Loadable({
|
||||
loader: () => import('./home/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
const LoginRegisterPage = Loadable({
|
||||
loader: () => import("./modules/loginRegister/LoginRegisterPage"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AboutUs = Loadable({
|
||||
loader: () => import("./forge/AboutUs/AboutUs"),
|
||||
loading: Loading,
|
||||
})
|
||||
// const CreateMerge = Loadable({
|
||||
// loader: () => import('./forge/Merge/NewMerge'),
|
||||
// loading: Loading,
|
||||
// })
|
||||
|
||||
// 此处仅维护前端可能的一级路由,不用进行项目或者组织判断的字段。
|
||||
const keyWord = ["explore", "settings", "setting", "mulan", "wiki", "issues", "setting", "trending", "code", "projects", "pulls", "mine", "login", "register", "email", "export", "nopage", "404", "403", "500", "501", "search", "organize"];
|
||||
const keyWord = ["explore", "settings", "setting", "mulan", "wiki", "issues", "setting", "trending", "code", "projects", "pulls", "mine", "login", "register", "email", "export", "nopage", "404", "403", "500", "501", "search", "organize","login","register","resetPassword","aboutus"];
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
Addcoursestype: false,
|
||||
Addcoursestypes: false,
|
||||
mydisplay: false,
|
||||
occupation: 0,
|
||||
mygetHelmetapi: null,
|
||||
pathType: null,
|
||||
pathName: null,
|
||||
}
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
Addcoursestype: false,
|
||||
Addcoursestypes: false,
|
||||
mydisplay: false,
|
||||
occupation: 0,
|
||||
mygetHelmetapi: null,
|
||||
pathType: null,
|
||||
pathName: null,
|
||||
}
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
initAxiosInterceptors(this.props);
|
||||
let pathname = window.location.pathname ? window.location.pathname.split('/')[1] : '';
|
||||
pathname && this.getPathnameType(pathname);
|
||||
UNSAFE_componentWillMount() {
|
||||
initAxiosInterceptors(this.props);
|
||||
let pathname = window.location.pathname ? window.location.pathname.split('/')[1] : '';
|
||||
pathname && this.getPathnameType(pathname);
|
||||
|
||||
// 添加路由监听,决定组织还是个人
|
||||
this.unlisten = this.props.history.listen((location) => {
|
||||
let newPathname = location.pathname.split('/')[1];
|
||||
if (this.state.pathName !== newPathname) {
|
||||
// this.setState({ pathType: '' });
|
||||
newPathname && this.getPathnameType(newPathname);
|
||||
}
|
||||
});
|
||||
}
|
||||
// 添加路由监听,决定组织还是个人
|
||||
this.unlisten = this.props.history.listen((location) => {
|
||||
let newPathname = location.pathname.split('/')[1];
|
||||
if (this.state.pathName !== newPathname) {
|
||||
// this.setState({ pathType: '' });
|
||||
newPathname && this.getPathnameType(newPathname);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
// (!keyWord.includes(this.props.location.pathname.split('/')[1])) &&
|
||||
if (nextProps.location.pathname.split('/')[1] !== this.props.location.pathname.split('/')[1] && nextState.pathType === this.state.pathType) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
if(!nextProps.location.pathname==='/'){
|
||||
return true;
|
||||
}
|
||||
// 阻止个人与组织切换时(组件渲染)请求导致的404
|
||||
if (nextProps.location.pathname.split('/')[1] !== this.props.location.pathname.split('/')[1] && nextState.pathType === this.state.pathType) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
getPathnameType = (pathname) => {
|
||||
if (!keyWord.includes(pathname)) {
|
||||
let url = `/owners/${pathname}.json`;
|
||||
axios.get(url).then((response) => {
|
||||
if (response && response.status === 200) {
|
||||
this.setState({
|
||||
pathType: response.data.type || '404',
|
||||
pathName: pathname,
|
||||
})
|
||||
}
|
||||
});
|
||||
}else{
|
||||
this.setState({
|
||||
pathType: pathname,
|
||||
pathName: pathname,
|
||||
});
|
||||
}
|
||||
}
|
||||
getPathnameType = (pathname) => {
|
||||
if (!keyWord.includes(pathname)) {
|
||||
let url = `/owners/${pathname}.json`;
|
||||
axios.get(url).then((response) => {
|
||||
if (response && response.status === 200) {
|
||||
this.setState({
|
||||
pathType: response.data.type || '404',
|
||||
pathName: pathname,
|
||||
})
|
||||
}
|
||||
});
|
||||
}else{
|
||||
this.setState({
|
||||
pathType: pathname,
|
||||
pathName: pathname,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
HideAddcoursestypess = (i) => {
|
||||
this.setState({
|
||||
Addcoursestype: false,
|
||||
Addcoursestypes: false,
|
||||
mydisplay: true,
|
||||
occupation: i,
|
||||
})
|
||||
};
|
||||
hideAddcoursestypes = () => {
|
||||
this.setState({
|
||||
Addcoursestypes: false
|
||||
})
|
||||
};
|
||||
HideAddcoursestypess = (i) => {
|
||||
this.setState({
|
||||
Addcoursestype: false,
|
||||
Addcoursestypes: false,
|
||||
mydisplay: true,
|
||||
occupation: i,
|
||||
})
|
||||
};
|
||||
hideAddcoursestypes = () => {
|
||||
this.setState({
|
||||
Addcoursestypes: false
|
||||
})
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
document.title = "loading...";
|
||||
componentDidMount() {
|
||||
document.title = "loading...";
|
||||
|
||||
this.getAppdata();
|
||||
this.getAppdata();
|
||||
|
||||
window.addEventListener('error', (event) => {
|
||||
const msg = `${event.type}: ${event.message}`;
|
||||
});
|
||||
window.addEventListener('error', (event) => {
|
||||
const msg = `${event.type}: ${event.message}`;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.unlisten && this.unlisten(); // 执行解绑
|
||||
}
|
||||
componentWillUnmount() {
|
||||
this.unlisten && this.unlisten(); // 执行解绑
|
||||
}
|
||||
|
||||
//修改登录方法
|
||||
Modifyloginvalue = () => {
|
||||
this.setState({
|
||||
isRender: false,
|
||||
})
|
||||
};
|
||||
//修改登录方法
|
||||
Modifyloginvalue = () => {
|
||||
this.setState({
|
||||
isRender: false,
|
||||
})
|
||||
};
|
||||
|
||||
//获取数据为空的时候
|
||||
gettablogourlnull = () => {
|
||||
this.setState({
|
||||
mygetHelmetapi: undefined
|
||||
});
|
||||
document.title = "Forge";
|
||||
var link = document.createElement('link'),
|
||||
oldLink = document.getElementById('dynamic-favicon');
|
||||
link.id = 'dynamic-favicon';
|
||||
link.rel = 'shortcut icon';
|
||||
link.href = "/react/build/./favicon.ico";
|
||||
if (oldLink) {
|
||||
document.head.removeChild(oldLink);
|
||||
}
|
||||
document.head.appendChild(link);
|
||||
};
|
||||
//获取数据为空的时候
|
||||
gettablogourlnull = () => {
|
||||
this.setState({
|
||||
mygetHelmetapi: undefined
|
||||
});
|
||||
document.title = "Forge";
|
||||
var link = document.createElement('link'),
|
||||
oldLink = document.getElementById('dynamic-favicon');
|
||||
link.id = 'dynamic-favicon';
|
||||
link.rel = 'shortcut icon';
|
||||
link.href = "/react/build/./favicon.ico";
|
||||
if (oldLink) {
|
||||
document.head.removeChild(oldLink);
|
||||
}
|
||||
document.head.appendChild(link);
|
||||
};
|
||||
|
||||
//获取数据的时候
|
||||
gettablogourldata = (response) => {
|
||||
document.title = response.data.setting.name;
|
||||
var link = document.createElement('link'),
|
||||
oldLink = document.getElementById('dynamic-favicon');
|
||||
link.id = 'dynamic-favicon';
|
||||
link.rel = 'shortcut icon';
|
||||
link.href = '/' + response.data.setting.tab_logo_url;
|
||||
if (oldLink) {
|
||||
document.head.removeChild(oldLink);
|
||||
}
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
//获取当前定制信息
|
||||
getAppdata = () => {
|
||||
let url = "/setting.json";
|
||||
axios.get(url).then((response) => {
|
||||
if (response) {
|
||||
if (response.data) {
|
||||
this.setState({
|
||||
mygetHelmetapi: response.data.setting
|
||||
});
|
||||
//存储配置到游览器
|
||||
localStorage.setItem('chromesetting', JSON.stringify(response.data.setting));
|
||||
localStorage.setItem('chromesettingresponse', JSON.stringify(response));
|
||||
try {
|
||||
if (response.data.setting.tab_logo_url) {
|
||||
this.gettablogourldata(response);
|
||||
} else {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
} catch (e) {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
} else {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
} else {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
}).catch((error) => {
|
||||
this.gettablogourlnull();
|
||||
});
|
||||
};
|
||||
//获取数据的时候
|
||||
gettablogourldata = (response) => {
|
||||
document.title = response.data.setting.name;
|
||||
var link = document.createElement('link'),
|
||||
oldLink = document.getElementById('dynamic-favicon');
|
||||
link.id = 'dynamic-favicon';
|
||||
link.rel = 'shortcut icon';
|
||||
link.href = '/' + response.data.setting.tab_logo_url;
|
||||
if (oldLink) {
|
||||
document.head.removeChild(oldLink);
|
||||
}
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
//获取当前定制信息
|
||||
getAppdata = () => {
|
||||
let url = "/setting.json";
|
||||
axios.get(url).then((response) => {
|
||||
if (response) {
|
||||
if (response.data) {
|
||||
this.setState({
|
||||
mygetHelmetapi: response.data.setting
|
||||
});
|
||||
//存储配置到游览器
|
||||
localStorage.setItem('chromesetting', JSON.stringify(response.data.setting));
|
||||
localStorage.setItem('chromesettingresponse', JSON.stringify(response));
|
||||
try {
|
||||
if (response.data.setting.tab_logo_url) {
|
||||
this.gettablogourldata(response);
|
||||
} else {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
} catch (e) {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
} else {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
} else {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
}).catch((error) => {
|
||||
this.gettablogourlnull();
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { mygetHelmetapi, pathType} = this.state;
|
||||
let personal = mygetHelmetapi && mygetHelmetapi.personal;
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<ConfigProvider locale={zhCN}>
|
||||
<MuiThemeProvider theme={theme}>
|
||||
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
|
||||
<SiderBar />
|
||||
{/* <Router> */}
|
||||
<Switch>
|
||||
{/* wiki预览 */}
|
||||
<Route path="/:owner/:projectsId/wiki/preview/:projectName/:projectId" render={
|
||||
(props) => {
|
||||
return (<WikiPreview {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
} />
|
||||
render() {
|
||||
const { pathType } = this.state;
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<ConfigProvider locale={zhCN}>
|
||||
<MuiThemeProvider theme={theme}>
|
||||
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
|
||||
<SiderBar />
|
||||
{/* <Router> */}
|
||||
<Switch>
|
||||
{/* wiki预览 */}
|
||||
<Route path="/:owner/:projectsId/wiki/preview/:projectName/:projectId" render={
|
||||
(props) => {
|
||||
return (<WikiPreview {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
} />
|
||||
|
||||
{/* 项目PR */}
|
||||
<Route path="/:owner/:projectsId/compare"
|
||||
render={
|
||||
(props) => (<ProjectDetail {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 项目PR */}
|
||||
<Route path="/:owner/:projectsId/compare"
|
||||
render={
|
||||
(props) => (<ProjectDetail {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
|
||||
{/*项目*/}
|
||||
<Route
|
||||
path={"/:owner/:projectId/devops/:opsId/detail"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OpsDetail {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
<Route
|
||||
path={"/settings"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<Security {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/*项目*/}
|
||||
<Route
|
||||
path={"/:owner/:projectId/devops/:opsId/detail"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OpsDetail {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
<Route
|
||||
path={"/settings"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<Security {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
|
||||
{/*403*/}
|
||||
<Route path="/403" component={Shixunauthority} />
|
||||
|
||||
<Route
|
||||
path="/register"
|
||||
render={
|
||||
(props) => {
|
||||
return (<EducoderLogin {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}
|
||||
/>
|
||||
{/*403*/}
|
||||
<Route path="/403" component={Shixunauthority} />
|
||||
<Route path="/500" component={http500} />
|
||||
|
||||
<Route path="/500" component={http500} />
|
||||
{/*404*/}
|
||||
<Route path="/nopage" component={Shixunnopage} />
|
||||
|
||||
{/*404*/}
|
||||
<Route path="/nopage" component={Shixunnopage} />
|
||||
{/* 查询 */}
|
||||
<Route path="/search" component={Search} />
|
||||
|
||||
{/* 查询 */}
|
||||
<Route path="/search" component={Search} />
|
||||
<Route exact path="/explore/all"
|
||||
render={
|
||||
(props) => (
|
||||
<ProjectIndex {...this.props} {...props} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Route exact path="/explore"
|
||||
render={
|
||||
(props) => (
|
||||
<ProjectIndex {...this.props} {...props} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
<Route exact path="/explore"
|
||||
render={
|
||||
(props) => (
|
||||
<ProjectIndex {...this.props} {...props} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
|
||||
{/* 组织 */}
|
||||
<Route path={"/organize"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/* 登录 */}
|
||||
<Route
|
||||
path="/login"
|
||||
render={(props) =><LoginRegisterPage {...this.props} {...props}/>}
|
||||
></Route>
|
||||
|
||||
{/*新建项目等*/}
|
||||
<Route
|
||||
path={"/projects"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<Projects {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/* 注册 */}
|
||||
<Route
|
||||
path="/register"
|
||||
render={(props) =><LoginRegisterPage {...this.props} {...props}/>}
|
||||
></Route>
|
||||
|
||||
{/* 判断为用户/组织,并进入对应页面 */}
|
||||
{
|
||||
pathType === 'User' ?
|
||||
<Route exact path="/:username"
|
||||
render={
|
||||
(props) => {
|
||||
return (<InfosIndex {...this.props} {...this.state} />)
|
||||
}
|
||||
}
|
||||
/> : pathType === 'Organization' ? <Route path={"/:OIdentifier"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route> : pathType === '404' ? <Route component={Shixunnopage} />:
|
||||
<Route exact path="/"
|
||||
render={
|
||||
(props) => (
|
||||
personal && personal.length > 0 ?
|
||||
<InfosIndex {...this.props} {...props} />
|
||||
:
|
||||
<ProjectIndex {...this.props} {...props} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
// <Route path="/" component={Loading} />
|
||||
// <Route path="/" component={Shixunnopage} />
|
||||
}
|
||||
{/* 忘记密码 */}
|
||||
<Route
|
||||
path="/resetPassword"
|
||||
render={(props) =><LoginRegisterPage {...this.props} {...props}/>}
|
||||
></Route>
|
||||
|
||||
{/* 关于我们 */}
|
||||
<Route
|
||||
path = "/aboutus"
|
||||
render = {(props)=><AboutUs {...this.props} {...props}/>}
|
||||
></Route>
|
||||
|
||||
{/* 组织 */}
|
||||
<Route path={"/organize"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
|
||||
{/*新建项目等*/}
|
||||
<Route
|
||||
path={"/projects"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<Projects {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
|
||||
{/* 判断为用户/组织,并进入对应页面 */}
|
||||
{
|
||||
pathType === 'User' ?
|
||||
<Route exact path="/:username"
|
||||
render={
|
||||
(props) => {
|
||||
return (<InfosIndex {...this.props} {...this.state} />)
|
||||
}
|
||||
}
|
||||
/> : pathType === 'Organization' ? <Route path={"/:OIdentifier"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route> : pathType === '404' ? <Route component={Shixunnopage} />:
|
||||
""
|
||||
}
|
||||
<Route exact path="/"
|
||||
render={
|
||||
(props) => (
|
||||
<Home {...props} {...this.props} {...this.state}/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
{/* 个人主页 */}
|
||||
<Route path="/:username"
|
||||
render={
|
||||
(props) => {
|
||||
return (<InfosIndex {...this.props} {...this.state} />)
|
||||
}
|
||||
}></Route>
|
||||
|
||||
|
||||
|
||||
{/* 个人主页 */}
|
||||
<Route path="/:username"
|
||||
render={
|
||||
(props) => {
|
||||
return (<InfosIndex {...this.props} {...this.state} />)
|
||||
}
|
||||
}></Route>
|
||||
|
||||
|
||||
<Route component={Shixunnopage} />
|
||||
</Switch>
|
||||
{/* </Router> */}
|
||||
</MuiThemeProvider>
|
||||
</ConfigProvider>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
<Route component={Shixunnopage} />
|
||||
</Switch>
|
||||
</MuiThemeProvider>
|
||||
</ConfigProvider>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// moment国际化,设置为中文
|
||||
moment.defineLocale('zh-cn', {
|
||||
months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
|
||||
monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
|
||||
weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
|
||||
weekdaysShort: '周日_周一_周二_周三_周四_周五_周六'.split('_'),
|
||||
weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
|
||||
longDateFormat: {
|
||||
LT: 'Ah点mm分',
|
||||
LTS: 'Ah点m分s秒',
|
||||
L: 'YYYY-MM-DD',
|
||||
LL: 'YYYY年MMMD日',
|
||||
LLL: 'YYYY年MMMD日Ah点mm分',
|
||||
LLLL: 'YYYY年MMMD日ddddAh点mm分',
|
||||
l: 'YYYY-MM-DD',
|
||||
ll: 'YYYY年MMMD日',
|
||||
lll: 'YYYY年MMMD日Ah点mm分',
|
||||
llll: 'YYYY年MMMD日ddddAh点mm分'
|
||||
},
|
||||
meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
|
||||
meridiemHour: function (hour, meridiem) {
|
||||
if (hour === 12) {
|
||||
hour = 0;
|
||||
}
|
||||
if (meridiem === '凌晨' || meridiem === '早上' ||
|
||||
meridiem === '上午') {
|
||||
return hour;
|
||||
} else if (meridiem === '下午' || meridiem === '晚上') {
|
||||
return hour + 12;
|
||||
} else {
|
||||
// '中午'
|
||||
return hour >= 11 ? hour : hour + 12;
|
||||
}
|
||||
},
|
||||
meridiem: function (hour, minute, isLower) {
|
||||
var hm = hour * 100 + minute;
|
||||
if (hm < 600) {
|
||||
return '凌晨';
|
||||
} else if (hm < 900) {
|
||||
return '早上';
|
||||
} else if (hm < 1130) {
|
||||
return '上午';
|
||||
} else if (hm < 1230) {
|
||||
return '中午';
|
||||
} else if (hm < 1800) {
|
||||
return '下午';
|
||||
} else {
|
||||
return '晚上';
|
||||
}
|
||||
},
|
||||
calendar: {
|
||||
sameDay: function () {
|
||||
return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT';
|
||||
},
|
||||
nextDay: function () {
|
||||
return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT';
|
||||
},
|
||||
lastDay: function () {
|
||||
return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT';
|
||||
},
|
||||
nextWeek: function () {
|
||||
var startOfWeek, prefix;
|
||||
startOfWeek = moment().startOf('week');
|
||||
prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]';
|
||||
return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
|
||||
},
|
||||
lastWeek: function () {
|
||||
var startOfWeek, prefix;
|
||||
startOfWeek = moment().startOf('week');
|
||||
prefix = this.unix() < startOfWeek.unix() ? '[上]' : '[本]';
|
||||
return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
|
||||
},
|
||||
sameElse: 'LL'
|
||||
},
|
||||
ordinalParse: /\d{1,2}(日|月|周)/,
|
||||
ordinal: function (number, period) {
|
||||
switch (period) {
|
||||
case 'd':
|
||||
case 'D':
|
||||
case 'DDD':
|
||||
return number + '日';
|
||||
case 'M':
|
||||
return number + '月';
|
||||
case 'w':
|
||||
case 'W':
|
||||
return number + '周';
|
||||
default:
|
||||
return number;
|
||||
}
|
||||
},
|
||||
relativeTime: {
|
||||
future: '%s内',
|
||||
past: '%s前',
|
||||
s: '几秒',
|
||||
m: '1分钟',
|
||||
mm: '%d分钟',
|
||||
h: '1小时',
|
||||
hh: '%d小时',
|
||||
d: '1天',
|
||||
dd: '%d天',
|
||||
M: '1个月',
|
||||
MM: '%d个月',
|
||||
y: '1年',
|
||||
yy: '%d年'
|
||||
},
|
||||
week: {
|
||||
// GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
|
||||
dow: 1, // Monday is the first day of the week.
|
||||
doy: 4 // The week that contains Jan 4th is the first week of the year.
|
||||
}
|
||||
months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
|
||||
monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
|
||||
weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
|
||||
weekdaysShort: '周日_周一_周二_周三_周四_周五_周六'.split('_'),
|
||||
weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
|
||||
longDateFormat: {
|
||||
LT: 'Ah点mm分',
|
||||
LTS: 'Ah点m分s秒',
|
||||
L: 'YYYY-MM-DD',
|
||||
LL: 'YYYY年MMMD日',
|
||||
LLL: 'YYYY年MMMD日Ah点mm分',
|
||||
LLLL: 'YYYY年MMMD日ddddAh点mm分',
|
||||
l: 'YYYY-MM-DD',
|
||||
ll: 'YYYY年MMMD日',
|
||||
lll: 'YYYY年MMMD日Ah点mm分',
|
||||
llll: 'YYYY年MMMD日ddddAh点mm分'
|
||||
},
|
||||
meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
|
||||
meridiemHour: function (hour, meridiem) {
|
||||
if (hour === 12) {
|
||||
hour = 0;
|
||||
}
|
||||
if (meridiem === '凌晨' || meridiem === '早上' ||
|
||||
meridiem === '上午') {
|
||||
return hour;
|
||||
} else if (meridiem === '下午' || meridiem === '晚上') {
|
||||
return hour + 12;
|
||||
} else {
|
||||
// '中午'
|
||||
return hour >= 11 ? hour : hour + 12;
|
||||
}
|
||||
},
|
||||
meridiem: function (hour, minute, isLower) {
|
||||
var hm = hour * 100 + minute;
|
||||
if (hm < 600) {
|
||||
return '凌晨';
|
||||
} else if (hm < 900) {
|
||||
return '早上';
|
||||
} else if (hm < 1130) {
|
||||
return '上午';
|
||||
} else if (hm < 1230) {
|
||||
return '中午';
|
||||
} else if (hm < 1800) {
|
||||
return '下午';
|
||||
} else {
|
||||
return '晚上';
|
||||
}
|
||||
},
|
||||
calendar: {
|
||||
sameDay: function () {
|
||||
return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT';
|
||||
},
|
||||
nextDay: function () {
|
||||
return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT';
|
||||
},
|
||||
lastDay: function () {
|
||||
return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT';
|
||||
},
|
||||
nextWeek: function () {
|
||||
var startOfWeek, prefix;
|
||||
startOfWeek = moment().startOf('week');
|
||||
prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]';
|
||||
return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
|
||||
},
|
||||
lastWeek: function () {
|
||||
var startOfWeek, prefix;
|
||||
startOfWeek = moment().startOf('week');
|
||||
prefix = this.unix() < startOfWeek.unix() ? '[上]' : '[本]';
|
||||
return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
|
||||
},
|
||||
sameElse: 'LL'
|
||||
},
|
||||
ordinalParse: /\d{1,2}(日|月|周)/,
|
||||
ordinal: function (number, period) {
|
||||
switch (period) {
|
||||
case 'd':
|
||||
case 'D':
|
||||
case 'DDD':
|
||||
return number + '日';
|
||||
case 'M':
|
||||
return number + '月';
|
||||
case 'w':
|
||||
case 'W':
|
||||
return number + '周';
|
||||
default:
|
||||
return number;
|
||||
}
|
||||
},
|
||||
relativeTime: {
|
||||
future: '%s内',
|
||||
past: '%s前',
|
||||
s: '几秒',
|
||||
m: '1分钟',
|
||||
mm: '%d分钟',
|
||||
h: '1小时',
|
||||
hh: '%d小时',
|
||||
d: '1天',
|
||||
dd: '%d天',
|
||||
M: '1个月',
|
||||
MM: '%d个月',
|
||||
y: '1年',
|
||||
yy: '%d年'
|
||||
},
|
||||
week: {
|
||||
// GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
|
||||
dow: 1, // Monday is the first day of the week.
|
||||
doy: 4 // The week that contains Jan 4th is the first week of the year.
|
||||
}
|
||||
});
|
||||
export default SnackbarHOC()(App);
|
||||
|
||||
|
|
|
@ -68,6 +68,8 @@ export function initAxiosInterceptors(props) {
|
|||
if (response.data.status === -1) {
|
||||
if (window.location.pathname.startsWith('/tasks/')) {
|
||||
props.showSnackbar(response.data.message || '服务器异常,请联系管理员。')
|
||||
} else if(window.location.pathname.startsWith('/login') || window.location.pathname.startsWith('/register') || window.location.pathname.startsWith('/resetPassword')) {
|
||||
return response;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
|
|
|
@ -0,0 +1,280 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import { TPMIndexHOC} from '../../modules/tpm/TPMIndexHOC';
|
||||
import { Timeline, Carousel } from 'antd';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import CountUp from 'react-countup';
|
||||
import axios from 'axios';
|
||||
import './AboutUs.scss';
|
||||
import subititle from './image/subtitle.png';
|
||||
import achievements from './image/achievements.png';
|
||||
import earth from './image/earth.png';
|
||||
import computer from './image/computer.png';
|
||||
import position from './image/position.png';
|
||||
import quan1 from './image/quan1.png';
|
||||
import quan2 from './image/quan2.png';
|
||||
import fun1 from './image/fun1.png';
|
||||
import fun2 from './image/fun2.png';
|
||||
import fun3 from './image/fun3.png';
|
||||
import fun4 from './image/fun4.png';
|
||||
import fun5 from './image/fun5.png';
|
||||
|
||||
function AboutUs(){
|
||||
const countUpProps = {
|
||||
redraw: true,
|
||||
start: 0,
|
||||
duration: 2,
|
||||
suffix: "+"
|
||||
};
|
||||
const [selectTitle, setSelectTitle] = useState(1);
|
||||
//用于刷新组件
|
||||
const [flush, setFlush] = useState(false);
|
||||
//合作单位
|
||||
const [units, setUnits] = useState([]);
|
||||
|
||||
useEffect(()=>{
|
||||
//添加浏览器滚动监听事件
|
||||
window.addEventListener('scroll', scrollListener);
|
||||
//请求topics.json接口获取合作单位信息
|
||||
axios.get(`/topics.json`, { params: { topic_type: "cooperator", limit: 20, group_size: 5}}).then(response=>{
|
||||
response && setUnits(response.data.topics);
|
||||
});
|
||||
return ()=>window.removeEventListener('scroll', scrollListener);
|
||||
},[])
|
||||
|
||||
function scrollListener(e){
|
||||
const top = e.srcElement.scrollingElement.scrollTop;
|
||||
//回到顶部时导航栏选中【关于我们】
|
||||
top < 555 && setSelectTitle(1);
|
||||
if (top > 2800 && top< 4000){
|
||||
setFlush(true);
|
||||
}else{
|
||||
setFlush(false);
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="aboutUs_body">
|
||||
<div className="aboutUs_head df">
|
||||
<p className="head_title">GitLink 确实开源</p>
|
||||
<p className="head_cont font-20 mt36">新一代开源创新服务平台,让您的创意在这里释放</p>
|
||||
</div>
|
||||
<div className="aboutUs_title df">
|
||||
<a className={selectTitle === 1 ? "active" : ""} href="#value1" onClick={() => setSelectTitle(1)}>关于我们</a>
|
||||
<a className={selectTitle === 2 ? "active" : ""} href="#value2" onClick={() => setSelectTitle(2)}>平台统计</a>
|
||||
<a className={selectTitle === 3 ? "active" : ""} href="#value3" onClick={() => setSelectTitle(3)}>加入我们</a>
|
||||
<a className={selectTitle === 4 ? "active" : ""} href="#value4" onClick={() => setSelectTitle(4)}>合作单位</a>
|
||||
</div>
|
||||
<div className="aboutUs">
|
||||
<a id="value1" className="mao"></a>
|
||||
{/* 关于我们 */}
|
||||
<div className="about_us">
|
||||
<div className="au_bg">
|
||||
<div className="au_title">关于我们</div>
|
||||
{/* 简介 */}
|
||||
<div className="au_cont subt df">
|
||||
<div className="cont1_introduction">
|
||||
<p className="subtitle">简介</p>
|
||||
<div className="font-16">GitLink(确实开源)是CCF官方指定的开源创新服务平台,旨在以“为开源创新服务”为使命,以“成为开源创新的汇聚地”为愿景,秉承“创新、开放、协作、共享”的价值观,致力于为大规模开源开放协同创新助力赋能,打造创新成果孵化和新工科人才培养的开源创新生态!</div>
|
||||
</div>
|
||||
<img src={subititle} className="subtitleImg"></img>
|
||||
</div>
|
||||
</div>
|
||||
{/* 确实开源 一脉传承 */}
|
||||
<div className="au_cont inherit pl30">
|
||||
<p className="subtitle">确实开源 一脉传承</p>
|
||||
<div>本世纪以来,随着软件创新需求和应用规模的飞速增长,软件开发队伍、开发资源、可信评估呈现出规模化、开放化、持续化的新特点,软件开发活动面临协同难、复用难、评估难的制约,经典的工程化软件开发方法面临严峻挑战,严重影响了软件开发效率和质量的提升。在此背景下,国防科技大学联合国内多所知名高校、科研机构和软件企业,围绕开源创新开展了持续性探索,构建形成了以Trustie(确实)为代表的一系列开源创新服务基础设施。自2006年以来,Trustie经过三个阶段的演化发展,于2021年迎来全面升级:在中国计算机学会(CCF)的带领指导下,共同推进产学研用深度融合,共筑新一代开源创新服务平台GitLink!</div>
|
||||
<div className="inherit_items">
|
||||
<img src={quan1} className="quan1Img"/>
|
||||
<img src={quan2} className="quan2Img"/>
|
||||
<Timeline>
|
||||
<Timeline.Item dot={<i className="iconfont icon-a-yuanquan2x font-20"></i>}>
|
||||
<div className="timeline_cont">
|
||||
<p>Trustie 1.0阶段(2006年-2014年)</p>
|
||||
<div>国防科技大学、北京大学、北京航空航天大学、中国科学院软件研究所等单位合作开展了基于网络的软件开发群体化方法与技术研究,揭示了以大众化协同开发、开放式资源共享、持续性可信评估为核心的互联网大规模协同机理,与软件开发工程化方法相结合,系统地提出了基于网络的软件开发群体化方法,并于2008年发布了可信的国家软件资源共享与协同生产环境(简称“Trustie v1.0”,中文简称“确实”),重点解决大规模软件协同开发、可信评估、运行监控和持续演化等问题。</div>
|
||||
</div>
|
||||
</Timeline.Item>
|
||||
<Timeline.Item dot={<i className="iconfont icon-a-yuanquan2x"></i>}>
|
||||
<div className="timeline_cont">
|
||||
<p>Trustie 2.0阶段(2014年-2020年)</p>
|
||||
<div>在科技部项目的持续资助下,国防科技大学联合国内多所知名高校、科研机构和软件企业,致力于系统研究新型软件开发方法,为开源生态建设提供方法指导和实践指南,支撑科教领域原始创新成果的开源孵化和开源人才培养,并于2014年发布了面向软件创新和教育的开源社区Trustie v2.0,重点探索协作开发社区、知识分享社区、应用服务社区等“大外围”软件涉众的联接,以及基于开源大数据的智能化开发等技术。</div>
|
||||
</div>
|
||||
</Timeline.Item>
|
||||
<Timeline.Item dot={<i className="iconfont icon-a-yuanquan2x"></i>}>
|
||||
<div className="timeline_cont">
|
||||
<p>Trustie 3.0阶段 (2020年至今)</p>
|
||||
<div>Trustie在已有的技术积累基础上,进一步联合国内高等院校、科研机构、产业企业和开源组织等,在中国计算机学会(CCF)的带领指导下,共同推进产学研用深度融合,致力于联接互联网海量群智资源,探索开源创新成果开放与共享、开源生态协作与共建的新模式和新方法,升级形成了新一代开源创新服务平台GitLink,力图破解软件开发群智范式背后的本质机理,建立面向“大外围”开放创新的群智激发与汇聚关键机制,实现面向大规模软件涉众的稳态群智激发与汇聚。</div>
|
||||
</div>
|
||||
</Timeline.Item>
|
||||
</Timeline>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 特色功能 确实给力 */}
|
||||
<div className="feature_function_bg">
|
||||
<div className="au_cont">
|
||||
<p className="au_title">特色功能 确实给力</p>
|
||||
<table><tr>
|
||||
<td>
|
||||
<div className="feat_func_cont">
|
||||
<div className="feat_fun_img"><img src={fun1} /></div>
|
||||
<div>
|
||||
<p>分布式协作开发</p>
|
||||
<div>支持在线文件编辑、 <br />分支管理、贡献统计、<br />仓库复刻、合并请求 </div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div className="feat_func_cont">
|
||||
<div className="feat_fun_img"><img src={fun2} /></div>
|
||||
<div>
|
||||
<p>一站式过程管理</p>
|
||||
<div>支持易修、里程碑、 <br />通知提醒、标签归档、Wiki文档、组织管理 </div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div className="feat_func_cont">
|
||||
<div className="feat_fun_img"><img src={fun3} /></div>
|
||||
<div>
|
||||
<p>高效流水线运维</p>
|
||||
<div>提供轻量级工作流引擎<br />并支持自定义配置、 <br/>静态扫描、制品构建 </div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div className="feat_func_cont">
|
||||
<div className="feat_fun_img"><img src={fun4} /></div>
|
||||
<div>
|
||||
<p>多层次代码分析</p>
|
||||
<div>支持代码溯源分析、 <br />许可证风险分析、开源漏洞检测和加固建议 </div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div className="feat_func_cont">
|
||||
<div className="feat_fun_img"><img src={fun5} /></div>
|
||||
<div>
|
||||
<p>多维度用户画像</p>
|
||||
<div>支持开发活动统计、 <br />贡献日历、能力建模、<br />角色与专业定位分析 </div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 成果作用,确实有效 */}
|
||||
<div className="au_cont df pl30">
|
||||
<img src={achievements} className="achievementsImg"></img>
|
||||
<div className="cont1_achievements">
|
||||
<p className="subtitle ml0">成果作用 确实有效</p>
|
||||
<div>GitLink(确实开源)为我国创新型软件产业发展提供了关键技术支撑和实践指南,为各类开源创新活动以及我国军地开源社区建设提供了有效支撑,为推动开源创新发展和创新人才培养发挥了重要作用。<br/>通过10多年的发展,GitLink平台显著提升了大型软件企业软件生产能力,支持了我国航空、航天、国防等多个关键领域的可信软件生产,为包括新一代人工智能启智社区、ARM绿色计算社区、科技部云计算与大数据木兰社区、科技委可控开源创造行动红山社区等的建设提供关键技术支撑,为我国关键领域开源社区生态建设发挥了重要作用!</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 平台统计 */}
|
||||
<div className="about_us statistics">
|
||||
<a id="value2" className="mao"></a>
|
||||
<div className="au_title">平台统计</div>
|
||||
<p>联接海量群智资源,汇聚优秀开源组织,孵化优质创新成果</p>
|
||||
<img src={earth} className="earthImg"/>
|
||||
<div className="statistics_cont df">
|
||||
<div>
|
||||
<CountUp {...countUpProps} start={0} end={50000} />
|
||||
<p>开发者</p>
|
||||
</div>
|
||||
<div>
|
||||
<CountUp {...countUpProps} end={1000} />
|
||||
<p>组织</p>
|
||||
</div>
|
||||
<div>
|
||||
<CountUp {...countUpProps} end={1400000} />
|
||||
<p>仓库</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 加入我们 */}
|
||||
<div className="join_us_bg">
|
||||
<a id="value3" className="mao"></a>
|
||||
<div className="au_cont">
|
||||
<div className="au_title">加入我们</div>
|
||||
<p className="subtitle">探索你的未来</p>
|
||||
<p>GitLink团队在寻找新的小伙伴,期待着您的加入,让我们一起为开源创新贡献力量!</p>
|
||||
<img src={computer} className="joinUsImg"/>
|
||||
{/* 轮播图 */}
|
||||
<Carousel autoplay easing="none">
|
||||
<div className="df">
|
||||
<div className="position">
|
||||
<p className="df"><img src={position} /><span className="ml10">前端开发工程师</span></p>
|
||||
<div>
|
||||
1、全日制本科及以上学历,5年以上Web前端开发经验,熟练使用Gulp、Webpack等构建工具;<br />
|
||||
2、熟练掌握VUE或React编程;有前端模块化、组件化、自动化开发经验者优先;<br />
|
||||
3、精通jQuery、Ajax、Json等技术,对VUE,NodeJs等技术有所涉及;<br />
|
||||
4、熟悉前端开发技术(HTML5、JS、JSON、XHTML、CSS3、ES6),了解各项技术的相关标准,并严格按照标准进行开发。<br />
|
||||
</div>
|
||||
</div>
|
||||
<div className="position right">
|
||||
<p className="df"><img src={position} /><span className="ml10">后端开发工程师</span></p>
|
||||
<div>
|
||||
1、全日制本科及以上学历,计算机、软件工程相关专业者优先;<br />
|
||||
2、3年以上Java开发相关经验,扎实的Java编程基础,参与过1个以上大/中型高并发、高性能系统架构设计、开发和调优;<br />
|
||||
3、熟练掌握Spring、SpringBoot、Spring MVC、MyBatis等开源框架,掌握MVC框架模式及BS架构;<br />
|
||||
4、精通SQL,熟练使用MySQL、Oracle等数据库,并具有一定的SQL优化能力;熟悉Redis、MongoDB等常用NoSQL解决方案,了解各自的优缺点以及使用场景者优先。<br />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="df">
|
||||
<div className="position">
|
||||
<p className="df"><img src={position} /><span className="ml10">软件测试工程师</span></p>
|
||||
<div>
|
||||
1、熟悉主流开发技术框架,具备软件工程的基本知识;<br />
|
||||
2、熟练掌握各种测试理论和测试技术,精通测试过程设计和用例设计方法;<br />
|
||||
3、熟悉性能测试、自动化测试、安全测试其中一种或多种测试工具;(LoadRunner、Jmeter、Selenium、QTP、Robot、Firebug、AppScan,PyCharm等),熟练运用工具从事过相关测试工作;<br />
|
||||
4、熟悉掌握一种编程语言(Java/Python/C++等);<br />
|
||||
5、熟悉Oracle/MySQL数据库,并能熟练编写SQL语句,熟练常用Linux命令;<br />
|
||||
6、有整体质量意识,测试管理经验。<br />
|
||||
</div>
|
||||
</div>
|
||||
<div className="position right">
|
||||
<p className="df"><img src={position} /><span className="ml10">产品经理</span></p>
|
||||
<div>
|
||||
1、计算机或相关专业本科以上学历;3年以上工作经验;<br />
|
||||
2、熟悉开源软件项目的管理流程,了解软件需求的调研方法,具备需求分析能力;<br />
|
||||
3、能以专业的方式向客户提供技术咨询,良好的方案设计能力和文字功底;<br />
|
||||
4、具备良好的交流、沟通和表达能力,良好的方案演示和介绍技巧;<br />
|
||||
5、了解互联网产品的基本思路及基础方法论,能够基于数据提出产品优化策略;<br />
|
||||
6、承受较强的工作压力,强烈的团队合作意识与工作责任心;<br />
|
||||
7、有良好人际交往能力,工作积极主动,自信心强,有较强的学习能力。<br />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Carousel>
|
||||
<p className="delivery">简历投递邮箱:zengyt#csxjy.com.cn 曾先生 (用@符号替换#)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 合作单位 */}
|
||||
<div className="unit">
|
||||
<a id="value4" className="mao"></a>
|
||||
<div className="au_title">合作单位</div>
|
||||
<table>
|
||||
{units && units.map(group =>{
|
||||
return (
|
||||
<tr>
|
||||
{group.map(item =>{
|
||||
return(
|
||||
<td><a href={item.url} target="_blank"><img src={getImageUrl(item.image)}></img></a></td>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default TPMIndexHOC(AboutUs);
|
|
@ -0,0 +1,338 @@
|
|||
.aboutUs_body{
|
||||
font-size: 16px;
|
||||
color: #182332;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
& table{
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
& .df{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
& .join_us_bg, .feature_function_bg, .feat_fun_img, .aboutUs_head{
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
& .mao{
|
||||
position: relative;
|
||||
top: -70px;
|
||||
}
|
||||
}
|
||||
.aboutUs_head.df{
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 500px;
|
||||
line-height: 500px;
|
||||
background-image: url('./image/banner.png');
|
||||
& p{
|
||||
text-align: center;
|
||||
}
|
||||
& .head_title{
|
||||
line-height: 50px;
|
||||
font-size: 48px;
|
||||
font-weight: 600;
|
||||
background-image: -webkit-linear-gradient(bottom,#4CDBF5,#5AACFF);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
& .head_cont{
|
||||
line-height: 39px;
|
||||
color: #FFFFFF;
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
.aboutUs_title{
|
||||
width: 800px;
|
||||
height: 62px;
|
||||
margin: 0 auto;
|
||||
&>table{
|
||||
width: 800px;
|
||||
font-weight: 400;
|
||||
}
|
||||
& a.active{
|
||||
color: #466AFF;
|
||||
height: 62px;
|
||||
line-height: 62px;
|
||||
border-bottom: 2px solid;
|
||||
}
|
||||
}
|
||||
.aboutUs{
|
||||
& .au_title{
|
||||
font-size: 38px;
|
||||
font-weight: 500;
|
||||
color: #1E1E1E;
|
||||
text-align: center;
|
||||
padding-top: 50px;
|
||||
// line-height: 53px;
|
||||
}
|
||||
& .subtitle{
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
margin-bottom: 23px !important;
|
||||
}
|
||||
}
|
||||
.about_us{
|
||||
// 关于我们
|
||||
& .au_cont.df{
|
||||
justify-content: space-between;
|
||||
}
|
||||
& .au_bg{ background: linear-gradient(180deg, #F3F9FF 0%, rgba(255, 255, 255, 0) 100%);}
|
||||
& .cont1_introduction{
|
||||
width: 472px;
|
||||
&>div{
|
||||
line-height: 34px;
|
||||
}
|
||||
}
|
||||
& .cont1_achievements{
|
||||
width: 581px;
|
||||
& .subtitle.ml0{margin-left: 0;}
|
||||
&>div{
|
||||
font-size: 15px;
|
||||
line-height: 36px;
|
||||
}
|
||||
}
|
||||
& .subtitleImg{
|
||||
width: 650px;
|
||||
height: 330px;
|
||||
}
|
||||
& .achievementsImg{
|
||||
width: 507px;
|
||||
height: 384px;
|
||||
}
|
||||
//时间轴
|
||||
& .inherit_items{
|
||||
position: relative;
|
||||
& .quan1Img{
|
||||
width: 140px;
|
||||
height: 167px;
|
||||
position: absolute;
|
||||
left: -290px;
|
||||
top: 90px;
|
||||
}
|
||||
& .quan2Img{
|
||||
width: 100px;
|
||||
height: 120px;
|
||||
position: absolute;
|
||||
right: -170px;
|
||||
bottom: 80px;
|
||||
}
|
||||
}
|
||||
.inherit{
|
||||
& .icon-a-yuanquan2x{
|
||||
color: #466aff;
|
||||
}
|
||||
& .ant-timeline-item-tail{
|
||||
border-left: 2px solid rgba(108, 134, 172, 0.42);
|
||||
height: calc(100% - -30px);
|
||||
}
|
||||
& .ant-timeline-item:last-child .ant-timeline-item-tail{
|
||||
display: block;
|
||||
height: calc(100% - 18px);
|
||||
}
|
||||
& .ant-timeline-item-content{
|
||||
margin: 0 0 -15px 18px;
|
||||
}
|
||||
}
|
||||
.timeline_cont{
|
||||
margin-left: 35px;
|
||||
&>p{
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: #466AFF;
|
||||
margin: 45px 0 30px !important;
|
||||
}
|
||||
&>div{
|
||||
width: 980px;
|
||||
padding: 20px 35px;
|
||||
background: #F5F7FA;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
color: #182332;
|
||||
line-height: 33px;
|
||||
&:after,&:before{
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 21px;
|
||||
top: 100px;
|
||||
border-top: 10px solid transparent;
|
||||
border-bottom: 10px solid transparent;
|
||||
border-right: 14px solid #F5F7FA;
|
||||
}
|
||||
}
|
||||
}
|
||||
//特色功能 确实给力
|
||||
& .feature_function_bg{
|
||||
position: relative;
|
||||
height: 630px;
|
||||
background-image: url(./image/funBg.png);
|
||||
& .au_cont p.au_title{
|
||||
font-size: 30px;
|
||||
padding: 50px 0 70px;
|
||||
color: #FFFFFF;
|
||||
opacity: 0.9;
|
||||
}
|
||||
& table{
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 1200px;}
|
||||
& .funBg2 {
|
||||
width: 1600px;
|
||||
left: 50%;
|
||||
margin-left: -800px;
|
||||
position: absolute;
|
||||
bottom: -15px;
|
||||
}
|
||||
}
|
||||
|
||||
& .feat_func_cont{
|
||||
width: 200px;
|
||||
& .feat_fun_img{
|
||||
height: 205px;
|
||||
line-height: 205px;
|
||||
background-image: url('./image/funBg3.png');
|
||||
&:hover{background-image: url('./image/funBg4.png');}
|
||||
}
|
||||
& img{ width: 175px;}
|
||||
& p{
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
line-height: 28px;
|
||||
background-image: -webkit-linear-gradient(bottom,#4FFDFF,#0183FF);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
& div>div{
|
||||
margin: 10px auto;
|
||||
width: 142px;
|
||||
font-size: 14px;
|
||||
line-height: 28px;
|
||||
color: #FFFFFF;
|
||||
opacity: 0.76;
|
||||
}
|
||||
}
|
||||
|
||||
// 平台统计
|
||||
&.statistics{
|
||||
text-align: center;
|
||||
background: linear-gradient(180deg, #ECF3FF 0%, #FFFFFF 100%);
|
||||
height: 640px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
& .statistics_cont{
|
||||
width: 1014px;
|
||||
height: 203px;
|
||||
background: #FFFFFF;
|
||||
opacity: 0.83;
|
||||
position: absolute;
|
||||
top: 230px;
|
||||
left: 50%;
|
||||
margin-left: -500px;
|
||||
& span{
|
||||
font-size: 48px;
|
||||
font-weight: bold;
|
||||
color: #1338D1;
|
||||
}
|
||||
& p{
|
||||
width: 111px;
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
border: 1px solid #182332;
|
||||
margin: 0 auto;
|
||||
font-size: 22px;
|
||||
color: #1E1E1E;
|
||||
}
|
||||
}
|
||||
& .earthImg{
|
||||
width: 1500px;
|
||||
margin-top: -120px;
|
||||
animation: moving 60s linear infinite;
|
||||
}
|
||||
@keyframes moving {
|
||||
0% { transform: rotate(0deg);}
|
||||
50% { transform: rotate(180deg);}
|
||||
100% { transform: rotate(360deg);}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 加入我们
|
||||
.join_us_bg{
|
||||
height: 710px;
|
||||
margin-top: 40px;
|
||||
background-image: url(./image/joinUs.png);
|
||||
& .au_cont{position: relative;}
|
||||
& .joinUsImg{
|
||||
width: 260px;
|
||||
height: 265px;
|
||||
position: absolute;
|
||||
top: 27px;
|
||||
right: 10px;
|
||||
}
|
||||
& .df{
|
||||
display: flex !important;
|
||||
margin-top: 30px;
|
||||
}
|
||||
& .position{
|
||||
width: 540px;
|
||||
&.right{ margin-right: -30px;}
|
||||
& p{
|
||||
justify-content: flex-start;
|
||||
height: 60px;
|
||||
background: #253DA0;
|
||||
line-height: 60px;
|
||||
padding-left: 20px;
|
||||
& img{width: 30px;}
|
||||
& span{
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
& div{
|
||||
height: 306px;
|
||||
font-size: 14px;
|
||||
line-height: 34px;
|
||||
padding: 20px;
|
||||
background: #FFFFFF;}
|
||||
}
|
||||
& .ant-carousel .slick-dots-bottom{bottom: -30px;}
|
||||
& .ant-carousel .slick-dots li button{
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 10px;
|
||||
background: #466AFF;
|
||||
}
|
||||
& .delivery{
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
margin-left: 35px;
|
||||
}
|
||||
}
|
||||
//合作单位
|
||||
.unit{
|
||||
margin-bottom: 60px;
|
||||
& table{
|
||||
width: 1200px;
|
||||
height: 550px;
|
||||
margin-top: 15px;
|
||||
border-collapse: separate;
|
||||
border-spacing: 10px 10px;
|
||||
& td{
|
||||
width: 224px;
|
||||
height: 122px;
|
||||
box-shadow: 0px 1px 8px 1px rgba(0, 0, 0, 0.06);
|
||||
border-radius: 6px;
|
||||
border: 2px solid #FFFFFF;
|
||||
&:hover{ border: 1px solid #466AFF;}
|
||||
}
|
||||
}
|
||||
}
|
||||
.au_cont{
|
||||
width: 1200px;
|
||||
margin: 50px auto;
|
||||
&.pl30 .subtitle{ margin-left: -30px;}
|
||||
}
|
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 1.7 MiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 130 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 454 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 859 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 172 KiB |
|
@ -124,7 +124,9 @@ class Activity extends Component{
|
|||
</Menu>
|
||||
)
|
||||
render(){
|
||||
const { time , data , page , project_trends , isSpin , pr_count , new_pr_count , close_issues_count , open_issues_count , pr_all_count ,issues_count } = this.state;
|
||||
const { time , data , page , project_trends , isSpin ,
|
||||
pr_count , new_pr_count , close_issues_count , open_issues_count , pr_all_count ,issues_count,
|
||||
type,status } = this.state;
|
||||
let name = time ? ARRAY.filter(item=>item.id === parseInt(time)) :[{name:"全部"}];
|
||||
|
||||
const first_per = pr_all_count > 0 ? `${parseFloat(pr_count/pr_all_count).toFixed(2)*100}%` :"50%";
|
||||
|
@ -156,19 +158,19 @@ class Activity extends Component{
|
|||
<ul className="percentBox">
|
||||
<li>
|
||||
<span className="purple">{data && data.pr_count}</span>
|
||||
<span className="change" onClick={()=>this.changeTrends("PullRequest","delay")}>已处理的合并请求</span>
|
||||
<span className={type==="PullRequest" && status==="delay" ?`change active`:"change"} onClick={()=>this.changeTrends("PullRequest","delay")}>已处理的合并请求</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="green">{data && data.new_pr_count}</span>
|
||||
<span className="change" onClick={()=>this.changeTrends("PullRequest","not_delay")}>未处理的合并请求</span>
|
||||
<span className={type==="PullRequest"&& status==="not_delay" ?`change active`:"change"} onClick={()=>this.changeTrends("PullRequest","not_delay")}>未处理的合并请求</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="red">{data && data.close_issues_count}</span>
|
||||
<span className="change" onClick={()=>this.changeTrends("Issue","delay")}>已关闭的易修</span>
|
||||
<span className={type==="Issue"&& status==="delay" ?`change active`:"change"} onClick={()=>this.changeTrends("Issue","delay")}>已关闭的易修</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="green">{data && data.open_issues_count}</span>
|
||||
<span className="change" onClick={()=>this.changeTrends("Issue","not_delay")}>未处理的易修</span>
|
||||
<span className={type==="Issue"&& status==="not_delay" ?`change active`:"change"} onClick={()=>this.changeTrends("Issue","not_delay")}>未处理的易修</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -14,20 +14,20 @@ class ActivityItem extends Component {
|
|||
{/* 如果是版本发布 */}
|
||||
{item.trend_type === "VersionRelease" ?
|
||||
<p className="itemLine">
|
||||
<Link to={`/${owner}/${projectsId}/releases`} className="color-blue font-16">{item.name}</Link>
|
||||
<Link to={`/${owner}/${projectsId}/releases`} className="font-16">{item.name}</Link>
|
||||
<span className="activity_type">{item.trend_type}</span>
|
||||
</p >
|
||||
:
|
||||
// 如果是任务
|
||||
item.trend_type === "Issue" ?
|
||||
<p className="itemLine">
|
||||
<Link to={`/${owner}/${projectsId}/issues/${item.trend_id}`} className="color-blue font-16">{item.name}</Link>
|
||||
<Link to={`/${owner}/${projectsId}/issues/${item.trend_id}`} className="font-16">{item.name}</Link>
|
||||
<span className="activity_type">{item.trend_type}</span>
|
||||
</p >
|
||||
:
|
||||
// 如果是合并请求
|
||||
<p className="itemLine">
|
||||
<Link to={`/${owner}/${projectsId}/pulls/${item.trend_id}`} className="color-blue font-16">{item.name}</Link>
|
||||
<Link to={`/${owner}/${projectsId}/pulls/${item.trend_id}`} className="font-16">{item.name}</Link>
|
||||
<span className="activity_type">{item.trend_type}</span>
|
||||
</p >
|
||||
}
|
||||
|
|
|
@ -107,6 +107,10 @@
|
|||
color: black;
|
||||
cursor: pointer;
|
||||
}
|
||||
.change.active{
|
||||
color: #466AFF !important;
|
||||
}
|
||||
|
||||
.change:hover{
|
||||
color: #4183c4;
|
||||
color: #466AFF;
|
||||
}
|
|
@ -7,10 +7,10 @@ function CloneAddress({http_url , ssh_url , zip_url , tar_url}) {
|
|||
const [ key , setKey ] = useState("HTTP");
|
||||
return (
|
||||
<div className="downMenu">
|
||||
<div style={{borderBottom:"1px solid #eee"}}>
|
||||
<div>
|
||||
<Menu className="urlMenu" selectedKeys={[key]} mode={"horizontal"}>
|
||||
<Menu.Item key="HTTP" onClick={(e)=>{setKey(e.key)}}>HTTP</Menu.Item>
|
||||
<Menu.Item key="SSH" onClick={(e)=>{setKey(e.key)}}>SSH</Menu.Item>
|
||||
{ssh_url && <Menu.Item key="SSH" onClick={(e)=>{setKey(e.key)}}>SSH</Menu.Item>}
|
||||
</Menu>
|
||||
<div className="gitAddressClone">
|
||||
<input type="text" id="copy_rep_content" value={key==="HTTP" ? http_url:ssh_url} />
|
||||
|
@ -18,8 +18,8 @@ function CloneAddress({http_url , ssh_url , zip_url , tar_url}) {
|
|||
</div>
|
||||
</div>
|
||||
<Menu className="edu-txt-center">
|
||||
<Menu.Item><a href={zip_url}>下载 ZIP</a></Menu.Item>
|
||||
<Menu.Item><a href={tar_url}>下载 TAR.GZ</a></Menu.Item>
|
||||
{zip_url && <Menu.Item style={{borderTop:"1px solid #eee"}}><a href={zip_url}>下载 ZIP</a></Menu.Item>}
|
||||
{tar_url && <Menu.Item><a href={tar_url}>下载 TAR.GZ</a></Menu.Item>}
|
||||
</Menu>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -66,9 +66,10 @@ function AddMember({getID,login,showNotification}){
|
|||
};
|
||||
|
||||
function addCollaborator(){
|
||||
if(source && source.length>0){
|
||||
if(source && source.length>0&&searchKey){
|
||||
getID && getID(id);
|
||||
setSearchKey(undefined);
|
||||
setID(undefined)
|
||||
}else{
|
||||
showNotification("请选择存在的用户!");
|
||||
}
|
||||
|
|
|
@ -313,17 +313,17 @@ li.ant-menu-item{
|
|||
}
|
||||
}
|
||||
.-task-sidebar>div {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
box-sizing: border-box;
|
||||
width: 40px;
|
||||
width: 48px;
|
||||
color: #999;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 50%;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 10px 1px #F1F1F1;
|
||||
box-shadow: 0px 0px 12px 5px rgba(208, 208, 208, 0.2);
|
||||
}
|
||||
|
||||
.-task-sidebar>div i {
|
||||
|
@ -334,36 +334,40 @@ li.ant-menu-item{
|
|||
color: #fff !important;
|
||||
}
|
||||
.-task-sidebar>div:hover{
|
||||
background: #1890FF;
|
||||
background: #466AFF;
|
||||
box-shadow: 0px 0px 10px 2px #B6D0FC;
|
||||
}
|
||||
.helpBox{
|
||||
width: 260px;
|
||||
z-index: 103;
|
||||
&.shareContent{
|
||||
width: 200px;
|
||||
width: 160px;
|
||||
}
|
||||
.ant-popover-title{
|
||||
font-size: 16px;
|
||||
}
|
||||
.ant-popover-inner-content{
|
||||
padding:0px;
|
||||
}
|
||||
p.titlecontent{
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
line-height: 20px;
|
||||
padding:15px 20px;
|
||||
}
|
||||
.faqUl{
|
||||
padding:0px 20px 10px;
|
||||
padding:10px 15px;
|
||||
max-height: 230px;
|
||||
overflow-y: auto;
|
||||
font-size: 13px;
|
||||
li{
|
||||
background: #F5F5F5;
|
||||
border-radius: 20px;
|
||||
padding:0px 20px;
|
||||
padding:0px 15px;
|
||||
color: #333;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
margin-bottom: 10px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
margin-bottom: 3px !important;
|
||||
a{
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
|
@ -379,19 +383,18 @@ li.ant-menu-item{
|
|||
}
|
||||
}
|
||||
.shareUl{
|
||||
padding:10px 0px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.titlecontent{
|
||||
margin-right: 20px;
|
||||
}
|
||||
li > i{
|
||||
font-size: 32px!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// tooltip样式
|
||||
.tooltipBox .ant-tooltip-inner{
|
||||
padding: 8px 12px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.-task-desc {
|
||||
background: #494949;
|
||||
|
@ -439,3 +442,21 @@ li.ant-menu-item{
|
|||
border-left: 5px solid #494949;
|
||||
border-bottom: 6px solid transparent
|
||||
}
|
||||
//头部输入框样式
|
||||
.headSerach{
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 4px;
|
||||
padding-left: 20px;
|
||||
//修改antd输入框默认样式
|
||||
.ant-input,.ant-input:focus{
|
||||
border: none !important;
|
||||
background-color: rgba(255, 255, 255, 0) !important;
|
||||
}
|
||||
&:hover{
|
||||
padding: 2px 20px 2px 20px;
|
||||
background: #FFF;
|
||||
& i{
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import './Component.scss';
|
|||
import { getUser } from '../GetData/getData';
|
||||
import axios from 'axios';
|
||||
|
||||
function Contributors({contributors,owner,projectsId,currentLogin}){
|
||||
function Contributors({owner,projectsId,currentLogin}){
|
||||
const [ menuList ,setMenuList ]= useState([]);
|
||||
const [ list , setList ]= useState(undefined);
|
||||
const [ total , setTotal ]= useState(0);
|
||||
|
@ -16,11 +16,18 @@ function Contributors({contributors,owner,projectsId,currentLogin}){
|
|||
const [ isSpin , setIsSpin ] = useState(false);
|
||||
|
||||
useEffect(()=>{
|
||||
if(contributors && contributors.total_count>0){
|
||||
setTotal(contributors.total_count);
|
||||
setList(contributors.list);
|
||||
}
|
||||
},[contributors])
|
||||
getData();
|
||||
},[])
|
||||
|
||||
function getData(){
|
||||
const url = `/${owner}/${projectsId}/contributors.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
setTotal(result.data.total_count);
|
||||
setList(result.data.list);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
if(login){
|
||||
|
@ -148,15 +155,15 @@ function Contributors({contributors,owner,projectsId,currentLogin}){
|
|||
}
|
||||
|
||||
return(
|
||||
total > 0 ?
|
||||
<div className="halfs">
|
||||
<Link to={`/${owner}/${projectsId}/contribute`} className="font-16 color-ooo hoverA">
|
||||
<span>贡献者</span>
|
||||
{ contributors && contributors.total_count > 0 && <span className="infoCount">{contributors.total_count}</span>}
|
||||
{ total > 0 && <span className="infoCount">{total}</span>}
|
||||
</Link>
|
||||
<div className="attrPerson" onMouseLeave={()=>setVisibleFunc(false)}>
|
||||
{
|
||||
total > 0 ?
|
||||
list.map((item,key)=>{
|
||||
list && list.length>0 && list.map((item,key)=>{
|
||||
return(
|
||||
<Popover content={menu} visible={item.visible} overlayClassName="menuPanels" placement="top">
|
||||
<Link key={key} to={`/${item.login}`}>
|
||||
|
@ -165,10 +172,9 @@ function Contributors({contributors,owner,projectsId,currentLogin}){
|
|||
</Popover>
|
||||
)
|
||||
})
|
||||
:""
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>:""
|
||||
)
|
||||
}
|
||||
export default Contributors;
|
|
@ -32,7 +32,7 @@ export default ({history}) => {
|
|||
/>
|
||||
</div>
|
||||
:
|
||||
<i className="iconfont icon-sousuo font-18 color-grey-6 ml30" onClick={() => {
|
||||
<i className="iconfont icon-sousuo font-18 ml30" style={{color:"#a5a5a5"}} onClick={() => {
|
||||
setOpenSearch(true)
|
||||
}} />
|
||||
}
|
||||
|
|
|
@ -1,18 +1,41 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { FlexAJ } from '../Component/layout';
|
||||
import { Divider } from 'antd';
|
||||
import axios from 'axios';
|
||||
|
||||
function LanguagePower({languages}){
|
||||
function LanguagePower({owner,projectsId}){
|
||||
const [ array , setArray ] = useState(undefined);
|
||||
|
||||
|
||||
useEffect(()=>{
|
||||
if(languages){
|
||||
let arr = [];
|
||||
Object.keys(languages).map((item,key)=>{
|
||||
arr.push({name:item,percent:languages[item],color:getColor()});
|
||||
})
|
||||
setArray(arr);
|
||||
}
|
||||
},[languages])
|
||||
getData();
|
||||
},[])
|
||||
|
||||
function getData(){
|
||||
const url = `/${owner}/${projectsId}/languages.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
let languages = result.data;
|
||||
if(languages){
|
||||
let arr = [];
|
||||
Object.keys(languages).map((item,key)=>{
|
||||
arr.push({name:item,percent:languages[item],color:getColor()});
|
||||
})
|
||||
setArray(arr);
|
||||
}
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
// useEffect(()=>{
|
||||
// if(languages){
|
||||
// let arr = [];
|
||||
// Object.keys(languages).map((item,key)=>{
|
||||
// arr.push({name:item,percent:languages[item],color:getColor()});
|
||||
// })
|
||||
// setArray(arr);
|
||||
// }
|
||||
// },[languages])
|
||||
|
||||
function getColor(){
|
||||
let str = "#";
|
||||
|
@ -24,7 +47,9 @@ function LanguagePower({languages}){
|
|||
return str;
|
||||
}
|
||||
return(
|
||||
(array && array.length > 0) ?
|
||||
<div>
|
||||
<Divider />
|
||||
<p className="font-16 color-ooo aboutSubTitle">开发语言</p>
|
||||
<div className="progress">
|
||||
{
|
||||
|
@ -47,8 +72,7 @@ function LanguagePower({languages}){
|
|||
}
|
||||
</FlexAJ>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>:""
|
||||
)
|
||||
}
|
||||
export default LanguagePower;
|
|
@ -3,25 +3,40 @@ import { Modal , Button } from 'antd';
|
|||
import './Index.scss';
|
||||
import '../../css/index.scss';
|
||||
import RenderHtml from '../../../components/render-html';
|
||||
import cookie from 'react-cookies';
|
||||
// import cookie from 'react-cookies';
|
||||
import axios from 'axios';
|
||||
|
||||
function SystemNotice({system_notification,history}){
|
||||
function SystemNotice({showNotice,system_notification,history,login,hideSystemNotice}){
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
|
||||
useEffect(()=>{
|
||||
if(system_notification && !cookie.load('notice_stage')){
|
||||
if(system_notification && !system_notification.is_read && showNotice && login){
|
||||
setVisible(true);
|
||||
}
|
||||
},[system_notification,history.location])
|
||||
},[system_notification])
|
||||
|
||||
function sureContinue() {
|
||||
cookie.remove('notice_stage');
|
||||
if(login && ( system_notification && system_notification.id )){
|
||||
const url = `/users/${login}/system_notification_histories.json`;
|
||||
axios.post(url,{
|
||||
system_notification_id:system_notification.id
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
setVisible(false);
|
||||
hideSystemNotice();
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}else{
|
||||
setVisible(false);
|
||||
hideSystemNotice();
|
||||
}
|
||||
// cookie.remove('notice_stage');
|
||||
|
||||
let inFifteenMinutes = new Date(new Date().getTime() + 24 * 3600 * 1000);//一天
|
||||
// let inFifteenMinutes = new Date(new Date().getTime() + 60 * 1000);//一分钟
|
||||
cookie.save('notice_stage', true,{ expires: inFifteenMinutes,path:"/" });
|
||||
// let inFifteenMinutes = new Date(new Date().getTime() + 24 * 3600 * 1000);//一天
|
||||
// // let inFifteenMinutes = new Date(new Date().getTime() + 60 * 1000);//一分钟
|
||||
// cookie.save('notice_stage', true,{ expires: inFifteenMinutes,path:"/" });
|
||||
|
||||
setVisible(false);
|
||||
// setVisible(false);
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -23,9 +23,13 @@ $(window).scroll(function () {
|
|||
function SiderBar() {
|
||||
const [ data , setData ] = useState([]);
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const [ login , setLogin ]= useState(false);
|
||||
|
||||
useEffect(()=>{
|
||||
getFAQ();
|
||||
getCurrentUser();
|
||||
//页面加载完成之后隐藏回到顶点
|
||||
$(".-task-sidebar .gotop").hide();
|
||||
},[])
|
||||
|
||||
function getFAQ(){
|
||||
|
@ -36,9 +40,19 @@ function SiderBar() {
|
|||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
//获取当前登录账号信息->用于建议反馈
|
||||
function getCurrentUser(){
|
||||
let url = `/users/get_user_info.json`;
|
||||
axios.get(url).then((response) => {
|
||||
if (response && response.data && response.data.login) {
|
||||
setLogin(response.data.login);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function content(list){
|
||||
return <div>
|
||||
<p className="titlecontent">帮助</p>
|
||||
<ul className="faqUl">
|
||||
{
|
||||
list && list.map((i,k)=>{
|
||||
|
@ -59,31 +73,46 @@ function SiderBar() {
|
|||
</ul>
|
||||
</div>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={"-task-sidebar"} >
|
||||
<ShareModal visible={visible} urlValue={window.location.href} onCancel={()=>setVisible(false)}/>
|
||||
{/* 平台反馈 */}
|
||||
<Tooltip title="意见反馈" placement={"left"} overlayClassName="tooltipBox">
|
||||
<div className="consult">
|
||||
<a href={login ? `/Gitlink/forgeplus/issues/new?type=feedback`:`/login?go_page=/Gitlink/forgeplus/issues/new?type=feedback`}>
|
||||
<i className="iconfont icon-yijianfankui2"></i>
|
||||
</a>
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
{/* 帮助 */}
|
||||
{
|
||||
data && data.length > 0 && (data[0] && data[0].question) ?
|
||||
<Popover content={content(data)} overlayClassName="helpBox" placement={"left"}>
|
||||
<Popover title="帮助" content={content(data)} overlayClassName="helpBox" placement={"left"}>
|
||||
<div className="feedback">
|
||||
<i className="iconfont icon-bangzhu font-22"></i>
|
||||
<i className="iconfont icon-bangzhu1 font-22"></i>
|
||||
</div>
|
||||
</Popover>
|
||||
:""
|
||||
}
|
||||
|
||||
{/* 分享 */}
|
||||
{/* <div className="scan pr" title="微信扫一扫">
|
||||
<span className="inline erweima"><i className="iconfont icon-erweima color-white font-22 fl"></i></span>
|
||||
</div>*/}
|
||||
<ShareModal visible={visible} urlValue={window.location.href} onCancel={()=>setVisible(false)}/>
|
||||
<Popover content={shareContent()} overlayClassName="helpBox shareContent" placement={"left"}>
|
||||
<div className="consult">
|
||||
<i className="iconfont icon-fenxiang1"></i>
|
||||
<i className="iconfont icon-fenxiang"></i>
|
||||
</div>
|
||||
</Popover>
|
||||
<div className="gotop">
|
||||
<Tooltip title="返回顶部" placement={"right"}>
|
||||
|
||||
{/* 返回顶部 */}
|
||||
<Tooltip title="返回顶部" placement={"left"} overlayClassName="tooltipBox">
|
||||
<div className="gotop">
|
||||
<a><i className="iconfont icon-huidaodingbu1"></i></a>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -17,9 +17,9 @@ function SiderBarShareModal({visible,urlValue,onCancel}) {
|
|||
value={urlValue}
|
||||
size={200}
|
||||
fgColor="#000000"
|
||||
style={{margin:"20px"}}
|
||||
style={{margin:"0 20px 20px"}}
|
||||
/>}
|
||||
<p>打开微信“扫一扫”,点击右上角菜单,即可将网页分享至朋友圈</p>
|
||||
<p>打开微信“扫一扫”,点击右上角菜单,即可将网页分享至朋友圈</p>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
|
|
|
@ -174,7 +174,7 @@ function About(props, ref) {
|
|||
了解什么是DevOps?
|
||||
</a>
|
||||
<a href={"https://forum.trustie.net/forums/3080/detail"} target="_blank" style={{ color: "#5091FF"}}>
|
||||
如何使用DevOps?
|
||||
如何使用引擎(Engine)功能?
|
||||
</a>
|
||||
{
|
||||
AuthorLogin === CurrentLogin ?
|
||||
|
|
|
@ -5,7 +5,7 @@ import { AlignCenterBetween , Blueline , FlexAJ } from '../../Component/layout';
|
|||
function head({manager , parameter}){
|
||||
return(
|
||||
<AlignCenterBetween>
|
||||
<span className="font-20">工作流配置</span>
|
||||
<span className="font-20">引擎配置</span>
|
||||
<FlexAJ>
|
||||
{
|
||||
parameter && <Blueline onClick={parameter}>参数管理</Blueline>
|
||||
|
|
|
@ -66,7 +66,7 @@ export default ((props)=>{
|
|||
{/* 原本的两种合为一个 */}
|
||||
<Route path="/:owner/:projectsId/devops"
|
||||
render={
|
||||
(p) =>{return( p.location.state.open_devops?<Dispose {...props} {...p}/>:<About {...props} {...p}/>)}
|
||||
(p) =>{return( p.location && p.location.state && p.location.state.open_devops?<Dispose {...props} {...p}/>:<About {...props} {...p}/>)}
|
||||
}
|
||||
></Route>
|
||||
</Switch>
|
||||
|
|
|
@ -2,84 +2,84 @@ import React, { useState , forwardRef, useEffect } from 'react';
|
|||
import { Form , Modal , Input , Radio } from 'antd';
|
||||
import Axios from 'axios';
|
||||
import CheckProfile from '../Component/ProfileModal/Profile';
|
||||
function AddProjectModal(props){
|
||||
const { getFieldDecorator, validateFields , setFieldsValue } = props && props.form;
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
|
||||
export default Form.create()(
|
||||
forwardRef((props)=>{
|
||||
const { getFieldDecorator, validateFields , setFieldsValue } = props && props.form;
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
|
||||
useEffect(()=>{
|
||||
if(!visible){
|
||||
setFieldsValue({
|
||||
code:undefined,
|
||||
role:"developer"
|
||||
})
|
||||
}
|
||||
},[visible])
|
||||
|
||||
function onOk() {
|
||||
validateFields((error,values)=>{
|
||||
if(!error){
|
||||
const url = `/applied_projects.json`;
|
||||
Axios.post(url,{
|
||||
applied_project:{
|
||||
...values
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setVisible(false);
|
||||
props.showNotification("申请加入项目成功,等待审核!");
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
useEffect(()=>{
|
||||
if(!visible){
|
||||
setFieldsValue({
|
||||
code:undefined,
|
||||
role:"developer"
|
||||
})
|
||||
}
|
||||
function checkValue(rule, value, callback){
|
||||
if(!value){
|
||||
callback();
|
||||
},[visible])
|
||||
|
||||
function onOk() {
|
||||
validateFields((error,values)=>{
|
||||
console.log(error)
|
||||
if(!error){
|
||||
const url = `/applied_projects.json`;
|
||||
Axios.post(url,{
|
||||
applied_project:{
|
||||
...values
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setVisible(false);
|
||||
props.showNotification("申请加入项目成功,等待审核!");
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
})
|
||||
}
|
||||
function checkValue(rule, value, callback){
|
||||
if(!value){
|
||||
callback("请输入6位数的邀请码");
|
||||
}else{
|
||||
if(value.length < 6 || value.length > 6){
|
||||
callback("请输入6位数的邀请码");
|
||||
}
|
||||
callback();
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
return(
|
||||
<React.Fragment>
|
||||
<Modal
|
||||
title="加入项目"
|
||||
width="480px"
|
||||
visible={visible}
|
||||
centered={true}
|
||||
onOk={onOk}
|
||||
onCancel={()=>setVisible(false)}
|
||||
>
|
||||
<Form layout={'inline'} className="inviteForm">
|
||||
<Form.Item label="项目邀请码">
|
||||
{getFieldDecorator("code",{
|
||||
rules:[
|
||||
{required:true,message:"请输入6位项目邀请码"},
|
||||
{validator:checkValue}
|
||||
]
|
||||
})(
|
||||
<Input placeholder="请输入6位项目邀请码" autoComplete={"off"} maxLength="6" style={{width:"300px"}}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="选择角色">
|
||||
{getFieldDecorator("role",{
|
||||
rules:[{required:true,message:"请选择角色"}]
|
||||
})(
|
||||
<Radio.Group defaultValue={"developer"}>
|
||||
<Radio value="manager">管理员</Radio>
|
||||
<Radio value="developer">开发者</Radio>
|
||||
<Radio value="reporter">报告者</Radio>
|
||||
</Radio.Group>
|
||||
)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
<CheckProfile {...props} sureFunc={()=>setVisible(true)}>加入项目</CheckProfile>
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
||||
)
|
||||
return(
|
||||
<React.Fragment>
|
||||
<Modal
|
||||
title="加入项目"
|
||||
width="480px"
|
||||
visible={visible}
|
||||
centered={true}
|
||||
onOk={onOk}
|
||||
onCancel={()=>setVisible(false)}
|
||||
>
|
||||
<Form layout={'inline'} className="inviteForm">
|
||||
<Form.Item label="项目邀请码">
|
||||
{getFieldDecorator("code",{
|
||||
rules:[
|
||||
{required:true,message:" "},
|
||||
{validator:checkValue}
|
||||
]
|
||||
})(
|
||||
<Input placeholder="请输入6位项目邀请码" autoComplete={"off"} maxLength={6} style={{width:"300px"}}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="选择角色">
|
||||
{getFieldDecorator("role",{
|
||||
rules:[{required:true,message:"请选择角色"}]
|
||||
})(
|
||||
<Radio.Group>
|
||||
<Radio value="manager">管理员</Radio>
|
||||
<Radio value="developer">开发者</Radio>
|
||||
<Radio value="reporter">报告者</Radio>
|
||||
</Radio.Group>
|
||||
)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
<CheckProfile {...props} sureFunc={()=>setVisible(true)}>加入项目</CheckProfile>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
export default Form.create()(forwardRef(AddProjectModal));
|
|
@ -19,48 +19,44 @@ function Footer(){
|
|||
|
||||
return(
|
||||
<div>
|
||||
<div style={{height:"543px"}}></div>
|
||||
<div className="newFooter edu-txt-center">
|
||||
{value && showhtml(value)}
|
||||
{/* <div className="footerInfos">
|
||||
<ul>
|
||||
<li>社区</li>
|
||||
<li><a href={`/`} target="_blank">网站首页</a></li>
|
||||
<li><a href={`https://www.trustie.net/agreement`} target="_blank">服务协议</a></li>
|
||||
<li><a href={`https://forum.trustie.net/forums/1168/detail`} target="_blank">帮助中心</a></li>
|
||||
<li><a href={`https://forum.trustie.net/`} target="_blank">问吧交流</a></li>
|
||||
<li><a href={`https://www.trustie.net/cooperation`} target="_blank">合作伙伴</a></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>支持与服务</li>
|
||||
<li><a href={`https://forgeplus.trustie.net/docs/api`} target="_blank">API文档</a></li>
|
||||
<li><a href={`https://forum.trustie.net/forums/1168/detail`} target="_blank">帮助中心</a></li>
|
||||
<li><a href={`https://git-scm.com`} target="_blank">Git常用命令</a></li>
|
||||
<li><a href={`https://forum.trustie.net/forums/3080/detail`} target="_blank">DevOps使用文档</a></li>
|
||||
<li><a href={`https://forgeplus.trustie.net/projects/jasder/forgeplus/tree/master/CHANGELOG.md`} target="_blank">日志更新</a></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>合作伙伴</li>
|
||||
<li><a href={`http://www.sei.pku.edu.cn`} target="_blank">北京大学</a></li>
|
||||
<li><a href={`http://scse.buaa.edu.cn`} target="_blank">北京航空航天大学</a></li>
|
||||
<li><a href={`https://www.nju.edu.cn`} target="_blank">南京大学</a></li>
|
||||
<li><a href={`https://www.xtu.edu.cn`} target="_blank">湘潭大学</a></li>
|
||||
<li><a href={`http://www.iscas.ac.cn`} target="_blank">ISCAS</a></li>
|
||||
<li><a href={`https://www.ucloud.cn`} target="_blank">UCloud优刻得</a></li>
|
||||
<li><a href={`http://www.inforbus.com`} target="_blank">中创软件</a></li>
|
||||
<li><a href={`https://www.inspur.com`} target="_blank">浪潮集团</a></li>
|
||||
<li><a href={`http://www.copu.org.cn`} target="_blank">中国开源软件推进联盟</a></li>
|
||||
<li><a href={`https://www.sjtu.edu.cn`} target="_blank">上海交通大学</a></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>合作伙伴</li>
|
||||
<li><span>热线:</span></li>
|
||||
<li><span>QQ群:1071514693</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<p className="footerCopy">© Copyright 2007~2021 国防科技大学Trustie团队 & IntelliDE <a href="https://beian.miit.gov.cn">湘ICP备 17009477号</a></p> */}
|
||||
</div>
|
||||
{value && showhtml(value)}
|
||||
</div>
|
||||
// {/* <div className="footEdition">
|
||||
// <div className="footContent">
|
||||
// <ul className="center">
|
||||
// <img src={""} alt="Gitlink(确实开源)" height="29px"/>
|
||||
// <p>(确实开源)</p>
|
||||
// </ul>
|
||||
// <ul>
|
||||
// <li className="thehead">社区</li>
|
||||
// <li><a href="/">网站首页</a></li>
|
||||
// <li><a href="https://forum.trustie.net/forums/1168/detail">帮助中心</a></li>
|
||||
// <li><a href="https://forum.trustie.net/">论坛交流</a></li>
|
||||
// <li><a href="https://www.trustie.net/cooperation">合作伙伴</a></li>
|
||||
// </ul>
|
||||
// <ul>
|
||||
// <li className="thehead">支持与服务</li>
|
||||
// <li><a href="https://forgeplus.trustie.net/docs/api">API文档</a></li>
|
||||
// <li><a href="https://git-scm.com">Git常用命令</a></li>
|
||||
// <li><a href="https://forum.trustie.net/forums/3080/detail">DevOps使用文档</a></li>
|
||||
// <li><a href='https://www.trustie.net/agreement'>服务协议</a></li>
|
||||
// </ul>
|
||||
// <ul>
|
||||
// <li className="thehead">加入我们</li>
|
||||
// <li className="theline">
|
||||
// <div className="mr50">
|
||||
// <li>公众号</li>
|
||||
// <img src={"Img"} alt="公众号"/>
|
||||
// </div>
|
||||
// <div>
|
||||
// <li>QQ群</li>
|
||||
// <img src={"qqImg"} alt="QQ群"/>
|
||||
// </div>
|
||||
// </li>
|
||||
// </ul>
|
||||
// </div>
|
||||
// <p className="copyrightDesc">©Copyright 2007~2021 国防科技大学Gitlink团队 & IntelliDE <br/>湘ICP备 17009477号</p>
|
||||
// </div> */}
|
||||
)
|
||||
}
|
||||
export default Footer;
|
||||
|
|
|
@ -2,7 +2,8 @@ import React, { Component } from 'react';
|
|||
import AccountProfile from "../../modules/user/AccountProfile";
|
||||
import { getImageUrl } from 'educoder'
|
||||
import axios from 'axios';
|
||||
import { Input , notification , Dropdown ,Popover, Menu,Badge, Button } from 'antd';
|
||||
import cookie from 'react-cookies';
|
||||
import { notification , Dropdown ,Popover, Menu,Badge } from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import LoginDialog from '../../modules/login/LoginDialog';
|
||||
|
@ -14,10 +15,8 @@ import CheckProfile from '../Component/ProfileModal/Profile';
|
|||
|
||||
import './header.scss';
|
||||
import NoticeContent from './NoticeContent';
|
||||
const $ = window.$
|
||||
import MainLogo from './img/logo.png';
|
||||
// TODO 这部分脚本从公共脚本中直接调用
|
||||
const { Search } = Input;
|
||||
let old_url;
|
||||
|
||||
window._header_componentHandler = null;
|
||||
// 非trustie链接则新开页跳转
|
||||
|
@ -55,28 +54,6 @@ class NewHeader extends Component {
|
|||
this.geturlsdata();
|
||||
window._header_componentHandler = this;
|
||||
|
||||
//下拉框的显示隐藏
|
||||
var hoverTimeout;
|
||||
var hoveredPanel;
|
||||
$(".edu-menu-panel").hover(function () {
|
||||
if (hoverTimeout) { // 一次只显示一个panel
|
||||
if (hoveredPanel && hoveredPanel !== this) {
|
||||
$(hoveredPanel).find(".edu-menu-list").hide()
|
||||
}
|
||||
clearTimeout(hoverTimeout);
|
||||
hoverTimeout = null;
|
||||
}
|
||||
hoveredPanel = this;
|
||||
$(this).find(".edu-menu-list").show();
|
||||
}, function () {
|
||||
var that = this;
|
||||
// 延迟hide
|
||||
hoverTimeout = setTimeout(function () {
|
||||
$(that).find(".edu-menu-list").hide();
|
||||
}, 800)
|
||||
|
||||
});
|
||||
//获取游览器地址
|
||||
try {
|
||||
window.sessionStorage.setItem("yslgeturls", JSON.stringify(window.location.href))
|
||||
} catch (e) {}
|
||||
|
@ -98,11 +75,17 @@ class NewHeader extends Component {
|
|||
|
||||
educoderlogin = () => {
|
||||
//登录账号
|
||||
this.setState({
|
||||
isRender: true
|
||||
})
|
||||
if(window.location.pathname === "/"){
|
||||
window.location.href="/login";
|
||||
}else{
|
||||
this.setState({
|
||||
isRender: true
|
||||
})
|
||||
}
|
||||
}
|
||||
educoderloginysl = () => {
|
||||
//退出账号时清除登录页面的下次自动登录(用户再次打开登录页面时下次自动登录框不勾选)
|
||||
cookie.remove("autologin");
|
||||
//退出账号
|
||||
var url = `/accounts/logout.json`;
|
||||
axios.get((url)).then((result) => {
|
||||
|
@ -213,12 +196,19 @@ class NewHeader extends Component {
|
|||
|
||||
matchpaths = (url) => {
|
||||
const { match } = this.props;
|
||||
if(url){
|
||||
if (match.path.indexOf(url) > -1) {
|
||||
return true
|
||||
}else {
|
||||
return false
|
||||
}
|
||||
const isDev = window.location.port == 3007;
|
||||
const isdev2= isDev ?'https://testforgeplus.trustie.net':`https://${window.location.hostname}`;
|
||||
let str = "";
|
||||
if(url.indexOf("http")>-1){
|
||||
str = isdev2+match.path;
|
||||
}else{
|
||||
str = match.path;
|
||||
}
|
||||
|
||||
if (url && str === url) {
|
||||
return true
|
||||
}else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,96 +269,18 @@ class NewHeader extends Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { match ,resetUserInfo ,showNotification} = this.props;
|
||||
const { resetUserInfo ,showNotification,publicNav} = this.props;
|
||||
let current_user = this.props.user;
|
||||
let {
|
||||
AccountProfiletype,
|
||||
user,
|
||||
isRender,
|
||||
headtypesonClickbool,
|
||||
headtypess,
|
||||
settings,
|
||||
visible,
|
||||
} = this.state;
|
||||
/*用户名称 用户头像url*/
|
||||
let activeIndex = false;
|
||||
let activeForums = false;
|
||||
let activeShixuns = false;
|
||||
let activePaths = false;
|
||||
let coursestype = false;
|
||||
let activePackages = false;
|
||||
let activeMoopCases = false;
|
||||
let activeCompetitions = false;
|
||||
|
||||
if (match.path === '/forums') {
|
||||
activeForums = true;
|
||||
} else if (match.path.startsWith('/shixuns')) {
|
||||
activeShixuns = true;
|
||||
} else if (match.path.startsWith('/paths')) {
|
||||
activePaths = true;
|
||||
} else if (match.path.startsWith('/courses')) {
|
||||
coursestype = true;
|
||||
} else if (match.path.startsWith('/crowdsourcing')) {
|
||||
activePackages = true;
|
||||
} else if (match.path.startsWith('/moop_cases')) {
|
||||
activeMoopCases = true;
|
||||
} else if (match.path.startsWith('/competitions')) {
|
||||
activeCompetitions = true;
|
||||
} else {
|
||||
activeIndex = true;
|
||||
}
|
||||
|
||||
let headtypes = '/';
|
||||
if (settings) {
|
||||
if (settings.navbar) {
|
||||
if (settings.navbar.length > 0) {
|
||||
if (match.path === '/') {
|
||||
if (headtypesonClickbool === false) {
|
||||
headtypes = undefined;
|
||||
} else {
|
||||
headtypes = headtypess;
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < settings.navbar.length; i++) {
|
||||
if (match.path === settings.navbar[i].link) {
|
||||
headtypes = settings.navbar[i].link;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let shixuntype = false;
|
||||
let pathstype = false;
|
||||
let coursestypes = false;
|
||||
if (this.props && this.props.mygetHelmetapi != null) {
|
||||
let shixun = "/shixuns";
|
||||
let paths = "/paths";
|
||||
let courses = "/courses";
|
||||
this.props.mygetHelmetapi && this.props.mygetHelmetapi.navbar && this.props.mygetHelmetapi.navbar.map((item, key) => {
|
||||
var reg = RegExp(item.link);
|
||||
if (shixun.match(reg)) {
|
||||
if (item.hidden === true) {
|
||||
shixuntype = true
|
||||
}
|
||||
}
|
||||
if (paths.match(reg)) {
|
||||
if (item.hidden === true) {
|
||||
pathstype = true
|
||||
}
|
||||
}
|
||||
if (courses.match(reg)) {
|
||||
if (item.hidden === true) {
|
||||
coursestypes = true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let search_url = settings && settings.common && settings.common.search;
|
||||
return (
|
||||
<div className="newHeaders" id="nHeader">
|
||||
<div className={publicNav ? `newHeaders publicNav`:`newHeaders`} id="nHeader">
|
||||
<div className="headerContent">
|
||||
{isRender === true ?
|
||||
<LoginDialog
|
||||
|
@ -383,10 +295,16 @@ class NewHeader extends Component {
|
|||
{...this.props}
|
||||
{...this.state}
|
||||
/> : ""}
|
||||
{
|
||||
publicNav &&
|
||||
<a href={'https://www.ccf.org.cn/'} className={"fl pr15"}>
|
||||
<img src={MainLogo} alt="ccf" />
|
||||
</a>
|
||||
}
|
||||
{
|
||||
settings && settings.nav_logo_url ?
|
||||
<a href={settings && settings.new_course.default_url} className={"fl mr50"} style={{minWidth:"45px"}}>
|
||||
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={getImageUrl(`/${settings.nav_logo_url}`)}></img>
|
||||
<a href={settings && settings.new_course.default_url} className={"fl mr50"}>
|
||||
<img alt="可控开源社区" className="logoimg" src={getImageUrl(`/${settings.nav_logo_url}`)}></img>
|
||||
</a>
|
||||
:
|
||||
""
|
||||
|
@ -414,11 +332,14 @@ class NewHeader extends Component {
|
|||
if (user_login && (new_link && new_link.indexOf("homes") > -1)) {
|
||||
new_link = new_link.replace(/homes/g, user_login + "/user_activities")
|
||||
}
|
||||
|
||||
//【关于我们】页面
|
||||
if(item.name === "关于我们"){
|
||||
new_link = `/aboutus`;
|
||||
}
|
||||
var waiLian = (new_link && str.filter(item=>new_link.indexOf(item)>-1) );
|
||||
var wl = waiLian && waiLian.length>0;
|
||||
return (
|
||||
<li key={key} onClick={() => this.headtypesonClick(item.link, true)} className={`${this.matchpaths(item.link) === true ? 'pr active' : 'pr'}`} style={!is_hidden ? { display: 'flex' } : { display: 'none' }}>
|
||||
<li key={key} onClick={() => this.headtypesonClick(item.link, true)} className={`${this.matchpaths(new_link) === true ? 'pr active' : 'pr'}`} style={!is_hidden ? { display: 'flex' } : { display: 'none' }}>
|
||||
<a href={new_link} target={wl ? "_self":"_blank"}>{item.name}</a>
|
||||
</li>
|
||||
)
|
||||
|
@ -433,7 +354,8 @@ class NewHeader extends Component {
|
|||
{
|
||||
current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)?
|
||||
<Dropdown overlay={this.addMenu(settings && settings.add)} placement="bottomRight">
|
||||
<i className="iconfont icon-tianjiafangda color-grey-6 ml30 mr15"></i>
|
||||
{/* <i className="iconfont icon-tianjiafangda ml30 mr15"></i> */}
|
||||
<img src={require(`./img/add.png`)} alt="" width="16px" className="mr15 ml30"/>
|
||||
</Dropdown>:""
|
||||
}
|
||||
|
||||
|
@ -448,7 +370,7 @@ class NewHeader extends Component {
|
|||
>
|
||||
<Link to={"/settings/notice"} className="message-icon">
|
||||
{current_user && <Badge count={current_user.message_unread_total}>
|
||||
<i className="iconfont icon-xiaoxilingdang color-grey-6 ml15 mr15"></i>
|
||||
<img src={require(`./img/ring.png`)} alt="" width="16px" className="ml15 mr15"/>
|
||||
</Badge>}
|
||||
</Link>
|
||||
</Popover>
|
||||
|
@ -457,10 +379,14 @@ class NewHeader extends Component {
|
|||
</div>
|
||||
{!user || (user && !user.login) ?
|
||||
<span className="font-15 ml30">
|
||||
<a onClick={() => this.educoderlogin()} className="mr5 color-grey-6">登录</a>
|
||||
<a onClick={() => this.educoderlogin()} className="mr5 color-white">登录</a>
|
||||
{
|
||||
settings && settings.common && settings.common.register &&
|
||||
<span><em className="vertical-line"></em><a className="ml5 color-grey-6" href={`${settings.common.register}`} target="_blank">注册</a></span>
|
||||
(settings && settings.common && settings.common.register) ?
|
||||
publicNav ?
|
||||
<a href='/register' className="regBtn">立即注册</a>
|
||||
:
|
||||
<span><em className="vertical-line"></em><a className="ml5 color-white" href='/register'>注册</a></span>
|
||||
:""
|
||||
}
|
||||
</span>
|
||||
:
|
||||
|
|
|
@ -23,6 +23,9 @@ function NoticeContent({ visible, showNotification, resetUserInfo, current_user:
|
|||
const [atPage, setAtPage] = useState(0);
|
||||
const [atUnreadList, setAtUnreadList] = useState([]);//未读@我列表
|
||||
|
||||
//记录用户点击的消息
|
||||
const [clickItem, setClickItem] = useState(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
resetUserInfo();
|
||||
}, [noticeUnreadCount,atUnreadCount]);
|
||||
|
@ -150,23 +153,26 @@ function NoticeContent({ visible, showNotification, resetUserInfo, current_user:
|
|||
|
||||
|
||||
function changeReadMark(item) {
|
||||
if (item.type === "notification") {
|
||||
let list = noticeUnreadList.slice();
|
||||
let index = noticeUnreadList.indexOf(item);
|
||||
list[index].status = 2;
|
||||
setNoticeUnreadList(list);
|
||||
if (noticeUnreadCount > 0) {
|
||||
setNoticeUnreadCount(noticeUnreadCount - 1);
|
||||
}
|
||||
} else if (item.type === "atme") {
|
||||
let list = atUnreadList.slice();
|
||||
let index = atUnreadList.indexOf(item);
|
||||
list[index].status = 2;
|
||||
setAtUnreadList(list);
|
||||
if (atUnreadCount > 0) {
|
||||
setAtUnreadCount(atUnreadCount - 1);
|
||||
if (!clickItem || clickItem.id !== item.id){
|
||||
if (item.type === "notification") {
|
||||
let list = noticeUnreadList.slice();
|
||||
let index = noticeUnreadList.indexOf(item);
|
||||
if (list[index].status === 1 && noticeUnreadCount > 0) {
|
||||
setNoticeUnreadCount(noticeUnreadCount - 1);
|
||||
}
|
||||
list[index].status = 2;
|
||||
setNoticeUnreadList(list);
|
||||
} else if (item.type === "atme") {
|
||||
let list = atUnreadList.slice();
|
||||
let index = atUnreadList.indexOf(item);
|
||||
if (list[index].status === 1 && atUnreadCount > 0) {
|
||||
setAtUnreadCount(atUnreadCount - 1);
|
||||
}
|
||||
list[index].status = 2;
|
||||
setAtUnreadList(list);
|
||||
}
|
||||
}
|
||||
setClickItem(item);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -219,12 +225,12 @@ function NoticeContent({ visible, showNotification, resetUserInfo, current_user:
|
|||
{atUnreadList.map(item => {
|
||||
return (
|
||||
<div key={item.id + Math.random()} className="noticeCont-back" onClick={() => { readItem(item) }}>
|
||||
<div className="noticeCont">
|
||||
<div className={`noticeCont ${item.notification_url ? 'pointer' : ''}`}>
|
||||
<span style={{ visibility: item.status === 1 ? 'visible' : 'hidden' }}>
|
||||
<Badge color="#FA2020" />
|
||||
</span>
|
||||
<div className="noticeCont-text">
|
||||
<span className="content-span atme-cont-span" dangerouslySetInnerHTML={{ __html: "<b>" + (item.sender ? item.sender.name : '') + "</b> " + item.content + " 中@我" }}></span>
|
||||
<span className="content-span atme-cont-span" dangerouslySetInnerHTML={{ __html: item.content }}></span>
|
||||
<span className="timeSpan">{item.time_ago}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -127,6 +127,9 @@
|
|||
width: 110px;
|
||||
text-align: right;
|
||||
}
|
||||
.ant-form-explain{
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
// 右上角小铃铛单独样式
|
||||
|
@ -262,4 +265,101 @@
|
|||
|
||||
.text-center{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footEdition{
|
||||
background-color: #171B23;
|
||||
.footContent{
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding:86px 0px;
|
||||
justify-content: space-around;
|
||||
width: 1200px;
|
||||
margin:0px auto;
|
||||
ul{
|
||||
min-width: 120px;
|
||||
text-align: left;
|
||||
margin-right: 80px;
|
||||
&.center{
|
||||
text-align: center;
|
||||
}
|
||||
&>p{
|
||||
height: 22px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: #FFFFFF;
|
||||
line-height: 22px;
|
||||
}
|
||||
&>img{
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
margin-bottom: 30px;
|
||||
margin-top: 25px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
li{
|
||||
height: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
color: #BDC2D1;
|
||||
margin-bottom: 15px!important;
|
||||
a{
|
||||
color: #BDC2D1!important;
|
||||
&:hover{
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
&.thehead{
|
||||
height: 25px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #FFFFFF;
|
||||
line-height: 25px;
|
||||
margin-bottom: 20px!important;
|
||||
}
|
||||
}
|
||||
.theline{
|
||||
.imgCon{
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
padding:5px;
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
img{
|
||||
width: 100%;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.copyrightDesc{
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #BDC2D1;
|
||||
line-height: 28px;
|
||||
padding:15px 0px;
|
||||
text-align: center;
|
||||
background-color: #1B212C;
|
||||
a{
|
||||
color: #BDC2D1!important;
|
||||
}
|
||||
}
|
||||
.regBtn{
|
||||
height: 40px;
|
||||
background: #466AFF;
|
||||
border-radius: 2px;
|
||||
display: inline-block;
|
||||
padding:0px 18px;
|
||||
margin-left: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #FFFFFF!important;
|
||||
line-height: 40px;
|
||||
&:hover{
|
||||
color: #FFFFFF!important;
|
||||
background-color: #355CFF;
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 749 B |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 615 B |
After Width: | Height: | Size: 52 KiB |
|
@ -22,11 +22,10 @@ const ProjectIndex = Loadable({
|
|||
loading: Loading,
|
||||
});
|
||||
|
||||
// 项目详情放在用户和组织下作为二级菜单存在
|
||||
// const ProjectDetail = Loadable({
|
||||
// loader: () => import("./Main/Detail"),
|
||||
// loading: Loading,
|
||||
// });
|
||||
const ProjectHome = Loadable({
|
||||
loader: () => import("./Main/projecthome/Index"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
class Index extends Component {
|
||||
|
||||
|
@ -60,23 +59,17 @@ class Index extends Component {
|
|||
<ProjectNew {...this.props} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
{/* <Route
|
||||
path="/:owner/:projectsId"
|
||||
render={(props) => (
|
||||
<ProjectDetail {...this.props} {...props} />
|
||||
)}
|
||||
></Route> */}
|
||||
<Route
|
||||
path="/explore"
|
||||
path="/explore/all"
|
||||
render={(props) => (
|
||||
<ProjectIndex {...this.props} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
<Route
|
||||
path="/"
|
||||
path="/explore"
|
||||
render={(props) => (
|
||||
<ProjectIndex {...this.props} {...props} />
|
||||
<ProjectHome {...this.props} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
</Switch>
|
||||
|
@ -90,10 +83,3 @@ export default withRouter(
|
|||
parentSelector: ".newMain",
|
||||
})(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Index))))
|
||||
);
|
||||
|
||||
// export default withRouter(
|
||||
// ImageLayerOfCommentHOC({
|
||||
// imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
|
||||
// parentSelector: ".newMain",
|
||||
// })(Index)
|
||||
// );
|
||||
|
|
|
@ -138,7 +138,7 @@ function CoderDepot(props){
|
|||
if(result && result.data){
|
||||
const release = {
|
||||
"list":result.data.releases,
|
||||
"total_count":result.data.releases.length
|
||||
"total_count":result.data.releases && result.data.releases.length
|
||||
}
|
||||
setReleaseVersions(release);
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ function CoderDepot(props){
|
|||
let ele = document.getElementById("ptxt");
|
||||
if(ele){
|
||||
let h = ele.offsetHeight;
|
||||
if( h > 35 ) setHideBtn(true);
|
||||
if( h > 36 ) setHideBtn(true);
|
||||
}
|
||||
}
|
||||
},[projectDetail,lastCommit])
|
||||
|
@ -319,16 +319,16 @@ function CoderDepot(props){
|
|||
const downloadMenu = (
|
||||
<CloneAddress
|
||||
http_url={projectDetail && projectDetail.clone_url}
|
||||
ssh_url = {projectDetail && projectDetail.ssh_url}
|
||||
zip_url={zip_url}
|
||||
tar_url={tar_url}
|
||||
ssh_url = {(projectDetail && props && props.platform) && projectDetail.ssh_url}
|
||||
zip_url={(props && props.platform) && zip_url}
|
||||
tar_url={(props && props.platform) && tar_url}
|
||||
showNotification={props.showNotification}/>
|
||||
)
|
||||
// 确认修改简介、website、实践课程链接
|
||||
function okUpdate(d,w,l){
|
||||
const url = `/${owner}/${projectsId}.json`;
|
||||
axios.put(url,{
|
||||
description:d,website:w,lesson_url:l
|
||||
description:d,website:w || "",lesson_url:l||""
|
||||
}).then(result=>{
|
||||
if(result && result.data && result.data.id){
|
||||
setDesc(result.data.description);
|
||||
|
@ -337,6 +337,15 @@ function CoderDepot(props){
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
function createIssue(){
|
||||
if(baseOper){
|
||||
props.history.push(`/${owner}/${projectsId}/issues/new`);
|
||||
}else{
|
||||
props.showLoginDialog(`/${owner}/${projectsId}/issues/new`);
|
||||
}
|
||||
}
|
||||
|
||||
let n = fileInfo && fileInfo.name;
|
||||
const mdFlag = n && n.substring(n.length-3,n.length) === ".md";
|
||||
|
||||
|
@ -422,16 +431,16 @@ function CoderDepot(props){
|
|||
</AlignCenter>
|
||||
<AlignCenter className="depotBtn">
|
||||
{
|
||||
(baseOperate || baseOper) &&
|
||||
<div className="addOptionBtn">
|
||||
{
|
||||
baseOperate &&
|
||||
<CheckProfile {...props} sureFunc={()=>urlLink(`/${owner}/${projectsId}/compare/master...${branchName || defaultBranch}`)} >+ 合并请求</CheckProfile>
|
||||
}
|
||||
{
|
||||
<a onClick={createIssue}>+ 易修</a>
|
||||
{/* {
|
||||
baseOper &&
|
||||
<CheckProfile {...props} sureFunc={()=>urlLink(`/${owner}/${projectsId}/issues/new`)} >+ 易修</CheckProfile>
|
||||
}
|
||||
} */}
|
||||
</div>
|
||||
}
|
||||
{ fileOperate &&
|
||||
|
@ -519,7 +528,7 @@ function CoderDepot(props){
|
|||
<i onClick={()=>setOpenModal(true)} className="iconfont icon-a-shezhi color-grey-9 font-15"></i>
|
||||
}
|
||||
</FlexAJ>
|
||||
{desc && <p className="font-14 color-grey-3 mb15 task-hide-2" style={{lineHeight:"24px",WebkitLineClamp:"4",textAlign:"justify",wordBreak:"break-all"}}>{desc}</p>}
|
||||
{desc && <p className="font-14 color-grey-3 mb15 task-hide-2" style={{lineHeight:"24px",WebkitLineClamp:"4",textAlign:"justify",wordBreak:"break-all"}} title={desc}>{desc}</p>}
|
||||
{
|
||||
website &&
|
||||
<div className="color-grey-6 df pinfos mb5">
|
||||
|
@ -573,17 +582,9 @@ function CoderDepot(props){
|
|||
</React.Fragment>
|
||||
}
|
||||
{/* 贡献者 */}
|
||||
{
|
||||
projectDetail && projectDetail.contributors && projectDetail.contributors.total_count >0 &&
|
||||
<Contributors contributors={projectDetail.contributors} owner={owner} projectsId={projectsId} />
|
||||
}
|
||||
<Contributors owner={owner} projectsId={projectsId} />
|
||||
{/* 语言 */}
|
||||
{ projectDetail && projectDetail.languages &&
|
||||
<React.Fragment>
|
||||
<Divider />
|
||||
<LanguagePower languages={projectDetail.languages}/>
|
||||
</React.Fragment>
|
||||
}
|
||||
<LanguagePower owner={owner} projectsId={projectsId}/>
|
||||
</Gap>
|
||||
</ShortWidth>
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ function CoderDepotReadme({ operate , history , readme , ChangeFile }){
|
|||
|
||||
return(
|
||||
<div className="commonBox readBox" id="readme">
|
||||
<Anchor offsetTop={70} targetOffset={160}>
|
||||
<Anchor offsetTop={58}>
|
||||
<div className="commonBox-title boxTitle">
|
||||
<AlignCenter>
|
||||
<Dropdown overlay={menu()} trigger={['hover']} overlayClassName="menuslist">
|
||||
|
|
|
@ -73,7 +73,6 @@ export default ((props)=>{
|
|||
<Menu.Item key={'1'}><a href={tar_url}>TAR.GZ</a></Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
|
||||
return(
|
||||
<React.Fragment>
|
||||
<div className="main">
|
||||
|
|
|
@ -133,7 +133,7 @@ class CoderRootCommit extends Component{
|
|||
|
||||
render(){
|
||||
const { commitDatas , dataCount , limit , page , isSpining , branchList } = this.state;
|
||||
const { projectDetail, commit_class , defaultBranch } = this.props;
|
||||
const { projectDetail, commit_class , defaultBranch , platform } = this.props;
|
||||
const { projectsId , owner , branchName } = this.props.match.params;
|
||||
let branch = returnbar(branchName || defaultBranch);
|
||||
return(
|
||||
|
@ -159,7 +159,16 @@ class CoderRootCommit extends Component{
|
|||
<div className="commitList-item f-wrap-between">
|
||||
<div>
|
||||
<AlignTop>
|
||||
<div className="commitDesc"><Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="font-14 color-grey-3 font-bd"><RenderHtml value={item.message}/></Link></div>
|
||||
<div className="commitDesc">
|
||||
{
|
||||
platform ?
|
||||
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="font-14 color-grey-3 font-bd">
|
||||
<RenderHtml value={item.message}/>
|
||||
</Link>
|
||||
:
|
||||
<RenderHtml value={item.message}/>
|
||||
}
|
||||
</div>
|
||||
</AlignTop>
|
||||
<p className="f-wrap-alignCenter mt15 pb5">
|
||||
<User
|
||||
|
@ -176,7 +185,12 @@ class CoderRootCommit extends Component{
|
|||
<div>
|
||||
<span className="treecopy-cont shadow">
|
||||
<img src={Tree} alt="sha" width={"16px"}/>
|
||||
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`}>{truncateCommitId(`${item.sha}`)}</Link>
|
||||
{
|
||||
platform ?
|
||||
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`}>{truncateCommitId(`${item.sha}`)}</Link>
|
||||
:
|
||||
<span style={{color:"#466AFF",cursor:"default"}}>{truncateCommitId(`${item.sha}`)}</span>
|
||||
}
|
||||
<input type="text" id={`value${k}`} value={`${truncateCommitId(`${item.sha}`)}`}/>
|
||||
</span>
|
||||
<CopyTool beforeText="复制commit id" afterText="复制成功" inputId={`value${k}`}/>
|
||||
|
|
|
@ -215,7 +215,7 @@ class CoderRootFileDetail extends Component {
|
|||
const Option = Select.Option;
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Anchor className="griditemAnchor" offsetTop={70}>
|
||||
<Anchor className="griditemAnchor" offsetTop={58}>
|
||||
<div className="griditemCate">
|
||||
{
|
||||
md && readOnly &&
|
||||
|
|
|
@ -242,6 +242,7 @@ class Detail extends Component {
|
|||
} else if (result.data.mirror_status === 2) {
|
||||
this.deleteProjectBack();
|
||||
} else {
|
||||
this.getBanner();
|
||||
this.getDetail();
|
||||
this.setState({
|
||||
firstSync: false,
|
||||
|
@ -287,6 +288,7 @@ class Detail extends Component {
|
|||
this.deleteProjectBack();
|
||||
}
|
||||
this.getDetail();
|
||||
this.getBanner();
|
||||
}
|
||||
this.setState({
|
||||
firstSync: false,
|
||||
|
@ -317,7 +319,6 @@ class Detail extends Component {
|
|||
|
||||
getDetail = () => {
|
||||
const { projectsId, owner } = this.props.match.params;
|
||||
this.getBanner();
|
||||
const url = `/${owner}/${projectsId}/detail.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
|
@ -422,6 +423,10 @@ class Detail extends Component {
|
|||
const url = `/${owner}/${projectsId}/forks.json`;
|
||||
axios.post(url).then(result => {
|
||||
if (result && result.data.status === 0) {
|
||||
if(result.data.message === "fork失败,你已拥有了这个项目"){
|
||||
this.props.history.push(`/${current_user && current_user.login}/${projectsId}`);
|
||||
return;
|
||||
}
|
||||
this.props.history.push(`/${current_user && current_user.login}/${result.data.identifier}`);
|
||||
this.props.showNotification(result.data.message);
|
||||
}
|
||||
|
@ -509,11 +514,6 @@ class Detail extends Component {
|
|||
this.textFunc(projectDetail.forked_from_project_id, projectDetail.fork_info)
|
||||
: ""
|
||||
}
|
||||
{
|
||||
projectDetail && projectDetail.type && projectDetail.type !== 0 ?
|
||||
<span className="color-grey-9">导入于 <a className="color-grey-6" target="_blank" href={projectDetail.mirror_url}>{projectDetail.mirror_url}</a></span>
|
||||
: ""
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -50,7 +50,7 @@ class Index extends Component {
|
|||
|
||||
this.getCategory();
|
||||
|
||||
this.getRecommand();
|
||||
// this.getRecommand();
|
||||
|
||||
this.getLanguage();
|
||||
|
||||
|
@ -304,9 +304,9 @@ class Index extends Component {
|
|||
|
||||
return (
|
||||
<div>
|
||||
<p className="t_project_banner">
|
||||
{/* <p className="t_project_banner">
|
||||
<img src={banner} width="100%" alt=""/>
|
||||
</p>
|
||||
</p> */}
|
||||
{/* {
|
||||
recommendOriList && recommendOriList.length>0?
|
||||
<Slider {...settings} className="recommandOri">
|
||||
|
@ -320,7 +320,7 @@ class Index extends Component {
|
|||
</Slider>
|
||||
:""
|
||||
} */}
|
||||
{
|
||||
{/* {
|
||||
recommendList && recommendList.length>0 &&
|
||||
<Slider {...setting} className={recommendList.length>5 ? "recommandProjects":"recommandProjects mb20"}>
|
||||
{
|
||||
|
@ -341,7 +341,7 @@ class Index extends Component {
|
|||
})
|
||||
}
|
||||
</Slider>
|
||||
}
|
||||
} */}
|
||||
<div className="ProjectListIndex">
|
||||
<div className="list-left">
|
||||
<ul className="list-l-Menu">
|
||||
|
|
|
@ -52,12 +52,6 @@ class IndexItem extends Component {
|
|||
<i className="iconfont icon-banbenku font-18 color-green" />
|
||||
</Tooltip>:""
|
||||
}
|
||||
{
|
||||
item.type && item.type === 1 ?
|
||||
<Tooltip title="该项目是一个导入于其他网站的仓库" className="ml5">
|
||||
<i className="iconfont icon-jingxiang font-18 color-green" />
|
||||
</Tooltip>:""
|
||||
}
|
||||
</AlignCenter>
|
||||
<span className="p-r-tags">
|
||||
{
|
||||
|
|
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 460 B |
After Width: | Height: | Size: 463 B |
After Width: | Height: | Size: 435 B |
After Width: | Height: | Size: 969 B |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 367 B |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,161 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import './Index.scss';
|
||||
import SubBanner from './SubBanner';
|
||||
import SubUnitBanner from './SubUnitBanner';
|
||||
import Icon from '../img/index/icon.png';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Spin , Input } from 'antd';
|
||||
import SubList from './SubList';
|
||||
import more from '../img/index/more.png';
|
||||
import axios from 'axios';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import Nodata from '../../Nodata';
|
||||
|
||||
const { Search } = Input;
|
||||
|
||||
const LIMIT = 20;
|
||||
function Index() {
|
||||
|
||||
const [ cateList , setCateList ] = useState(undefined);
|
||||
const [ projectsList , setProjectsList ] = useState(undefined);
|
||||
const [ search , setSearch ] = useState(undefined);
|
||||
const [ cateID, setCateID ] = useState(undefined);
|
||||
const [ isSpin, setIsSpin ] = useState(true);
|
||||
|
||||
useEffect(()=>{
|
||||
getCate();
|
||||
},[])
|
||||
|
||||
useEffect(()=>{
|
||||
setIsSpin(true);
|
||||
getProject();
|
||||
},[cateID])
|
||||
|
||||
function getCate() {
|
||||
const url = `/project_categories/pinned_index.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
setCateList(result.data.project_categories);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function getProject(searchValue) {
|
||||
const url = `/projects.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
pinned:"d",
|
||||
category_id:cateID,
|
||||
limit:LIMIT,
|
||||
search:searchValue
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setProjectsList(result.data.projects);
|
||||
setIsSpin(false);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function changeSearchValue(e){
|
||||
setSearch(e.target.value);
|
||||
}
|
||||
|
||||
function searchFun(value){
|
||||
setIsSpin(true);
|
||||
getProject(value);
|
||||
}
|
||||
|
||||
return(
|
||||
<div>
|
||||
<SubBanner />
|
||||
<SubUnitBanner />
|
||||
<div className="dataPanel">
|
||||
<div className="left">
|
||||
<ul className="leftTypes">
|
||||
<a className={cateID ? "" : "active"} onClick={()=>setCateID(undefined)}><img src={Icon} alt="" /><span>最近更新</span></a>
|
||||
{
|
||||
cateList && cateList.length>0?
|
||||
cateList.map((i,k)=>{
|
||||
return(
|
||||
<a className={cateID === i.id ?"active":""} onClick={()=>setCateID(i.id)}><img src={i.logo_url || Icon} alt="" /><span>{i.name}</span></a>
|
||||
)
|
||||
})
|
||||
:""
|
||||
}
|
||||
</ul>
|
||||
<div className="leftLists">
|
||||
<div className="leftTitles">
|
||||
<span>开源项目</span>
|
||||
|
||||
<Search
|
||||
placeholder="输入项目名称关键字进行搜索"
|
||||
enterButton="搜索"
|
||||
size="middle"
|
||||
onSearch={searchFun}
|
||||
className="list-r-Search"
|
||||
value={search}
|
||||
onChange={changeSearchValue}
|
||||
style={{width:"300px"}}
|
||||
allowClear={true}
|
||||
/>
|
||||
<Link to={`/explore/all`} target="_blank">更多<i className="iconfont icon-triangle font-12"></i></Link>
|
||||
</div>
|
||||
<Spin spinning={isSpin}>
|
||||
<div style={{minHeight:"400px"}}>
|
||||
{
|
||||
projectsList && projectsList.length > 0 ?
|
||||
<div className="leftlistItem">
|
||||
{
|
||||
projectsList.map((i,k)=>{
|
||||
return(
|
||||
<li>
|
||||
{
|
||||
i.platform === "educoder" ?
|
||||
<a href="javascript:void(0)" style={{cursor:"default"}}>
|
||||
<img className="p-r-photo" alt="" src={i.author && i.author.image_url} ></img>
|
||||
</a>
|
||||
:
|
||||
<Link to={`/${i.author && i.author.login}`} target="_blank"><img src={getImageUrl(`/${i.author && i.author.image_url}`)} alt="" /></Link>
|
||||
}
|
||||
<div className="itemTitle">
|
||||
<div className="item-title-infos">
|
||||
<Link to={`/${i.author && i.author.login}/${i.identifier}`} target="_blank" className="infotitle task-hide">{i.author && i.author.name}/{i.name}</Link>
|
||||
{i.praises_count > 0 ? <span><i className="iconfont icon-dianzan11 mr3 font-16"></i>{i.praises_count}</span> :"" }
|
||||
{i.forked_count > 0 ? <span><i className="iconfont icon-fork2 mr3 font-13"></i>{i.forked_count}</span>:""}
|
||||
</div>
|
||||
<div className="item-desc task-hide-2">
|
||||
{i.description}
|
||||
</div>
|
||||
<div className="item-data">
|
||||
{i.category && i.category.id ? <span className="category">{i.category.name}</span> :"" }
|
||||
{i.language && i.language.id ? <span className="language mr30">{i.language.name}</span> :""}
|
||||
<span style={{lineHeight:"15px",display:"flex"}}><i className="iconfont icon-shijian font-15 mr5"></i>更新于{i.time_ago}</span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
:""
|
||||
}
|
||||
{
|
||||
projectsList && projectsList.length === 0 && <Nodata _html="暂无数据" />
|
||||
}
|
||||
</div>
|
||||
</Spin>
|
||||
{
|
||||
projectsList && projectsList.length > 0 &&
|
||||
<div className="left-bottom-btn">
|
||||
<Link to={`/explore/all`} target="_blank">查看更多开源项目<img src={more} alt="" /></Link>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<SubList />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Index;
|
|
@ -0,0 +1,561 @@
|
|||
.banners{
|
||||
background: url('../img/index/banner.png') no-repeat top;
|
||||
min-height: 516px;
|
||||
background-size: cover;
|
||||
background-color: #0C2A5B;
|
||||
.bannersCenter{
|
||||
padding-top: 30px;
|
||||
max-width: 1200px;
|
||||
margin: 0px auto;
|
||||
position: relative;
|
||||
height: 516px;
|
||||
}
|
||||
.bTitle{
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 30px;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
margin-bottom: 20px!important;
|
||||
text-align: center;
|
||||
span{
|
||||
background: linear-gradient(to right,#289AF6 0%, #9E84FF 40%, #FFB03B 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
}
|
||||
.bSubTitle{
|
||||
text-align: center;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.bannerBox{
|
||||
background: url('../img/index/box.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
height: 240px;
|
||||
width: 380px;
|
||||
margin:0px auto;
|
||||
padding:25px 30px 34px;
|
||||
.bannersProject{
|
||||
position: relative;
|
||||
.slick-list{
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.slick-track{
|
||||
display: flex;
|
||||
li{
|
||||
padding:15px 20px;
|
||||
.projectinfos{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin-bottom: 13px;
|
||||
img{
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-right: 7px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.name{
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 250px;
|
||||
color: #25EBFF;
|
||||
a{
|
||||
color: #25EBFF!important;
|
||||
}
|
||||
}
|
||||
.company{
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #FFFFFF;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 250px;
|
||||
a{
|
||||
color: #FFFFFF!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.desc{
|
||||
height: 40px;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #FFFFFF;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
.infoData{
|
||||
display: flex;
|
||||
margin-top: 16px;
|
||||
justify-content: space-around;
|
||||
&>span{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&>span{
|
||||
color: #FFB729;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
img{
|
||||
width: 16px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.airBubble{
|
||||
&>div{
|
||||
position: absolute;
|
||||
height: 410px;
|
||||
width: 415px;
|
||||
bottom: 0px;
|
||||
&.right{
|
||||
right: 0px;
|
||||
}
|
||||
&.left{
|
||||
left: 0px;
|
||||
}
|
||||
&.right div, &.left div{
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
span{
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(124deg, rgba(255, 255, 255, 0.1) 0%, rgba(5, 200, 220, 0.04) 50%, rgba(5, 200, 220, 0.03) 100%);
|
||||
box-shadow: 0px 0px 7px 3px rgba(0, 154, 255, 0.19);
|
||||
border: 1px solid rgba(0, 154, 255, 0.19);
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 17px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
word-break: break-all;
|
||||
text-align: center;
|
||||
padding:5px;
|
||||
animation: zoomin 1.3s infinite alternate;
|
||||
&:hover{
|
||||
animation:none
|
||||
}
|
||||
}
|
||||
}
|
||||
&.right span:nth-child(4) a,&.left span:nth-child(1) a,&.left span:nth-child(2) a{
|
||||
color: #25EBFF!important;
|
||||
}
|
||||
&.right span:nth-child(1) a,&.left span:nth-child(5) a{
|
||||
color: #CD8AFF!important;
|
||||
}
|
||||
&.right span:nth-child(3) a,&.right span:nth-child(5) a,&.left span:nth-child(6) a{
|
||||
color: #FF6125!important;
|
||||
}
|
||||
&.left span:nth-child(3) a{
|
||||
color: #FF8425!important;
|
||||
}
|
||||
&.right span:nth-child(2) a,&.left span:nth-child(4) a{
|
||||
color: #8CC2FF!important;
|
||||
}
|
||||
&.right span:nth-child(1){
|
||||
right: 0px;
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
}
|
||||
&.right span:nth-child(2){
|
||||
right: 160px;
|
||||
height: 72px;
|
||||
width: 72px;
|
||||
bottom: 220px;
|
||||
padding:0px;
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
&.right span:nth-child(3){
|
||||
right: 300px;
|
||||
height: 94px;
|
||||
width: 94px;
|
||||
bottom: 99px;
|
||||
padding:8px;
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
&.right span:nth-child(4){
|
||||
right: 156px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
bottom: 39px;
|
||||
font-size: 12px;
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
&.right span:nth-child(5){
|
||||
right: 10px;
|
||||
height: 94px;
|
||||
width: 94px;
|
||||
bottom: 97px;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
&.left span:nth-child(1){
|
||||
left: 80px;
|
||||
height: 110px;
|
||||
width: 110px;
|
||||
padding:8px;
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
&.left span:nth-child(2){
|
||||
right: 60px;
|
||||
height: 96px;
|
||||
width: 96px;
|
||||
top: 85px;
|
||||
font-size: 13px;
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
&.left span:nth-child(3){
|
||||
left: 0px;
|
||||
height: 86px;
|
||||
width: 86px;
|
||||
top: 145px;
|
||||
font-size: 13px;
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
&.left span:nth-child(4){
|
||||
left: 164px;
|
||||
height: 70px;
|
||||
width: 70px;
|
||||
bottom: 158px;
|
||||
font-size: 12px;
|
||||
font-size: 12px;
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
&.left span:nth-child(5){
|
||||
left: 35px;
|
||||
height: 102px;
|
||||
width: 102px;
|
||||
bottom: 32px;
|
||||
font-size: 13px;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
&.left span:nth-child(6){
|
||||
right: 10px;
|
||||
height: 114px;
|
||||
width: 114px;
|
||||
bottom: 26px;
|
||||
padding:8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@keyframes zoomin{
|
||||
0%{-webkit-transform:scale(1.05);transform:scale(1.05)}
|
||||
100%{-webkit-transform:scale(0.8);transform:scale(0.8)}
|
||||
}
|
||||
@-webkit-keyframes zoomin{
|
||||
0%{-webkit-transform:scale(1.05);transform:scale(1.05)}
|
||||
100%{-webkit-transform:scale(0.8);transform:scale(0.8)}
|
||||
}
|
||||
.unitBanner{
|
||||
padding:29px 0px;
|
||||
background: #F9F9F9;
|
||||
.unitContent{
|
||||
max-width: 1200px;
|
||||
margin:0px auto;
|
||||
.unitTitle{
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: #1E1E1E;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
img{
|
||||
margin-left: 9px;
|
||||
}
|
||||
}
|
||||
.unitSlider{
|
||||
padding:30px 0px 10px;
|
||||
.slick-list{
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
overflow: hidden;
|
||||
.slickline{
|
||||
display: flex!important;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.dataPanel{
|
||||
width: 1200px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding:30px 0px 60px;
|
||||
margin:0px auto;
|
||||
.left{
|
||||
width: 850px;
|
||||
display: flex;
|
||||
.leftTypes{
|
||||
width: 220px;
|
||||
height: 1576px;
|
||||
background: url('../img/index/typebg.png');
|
||||
background-size: 100% 100%;
|
||||
box-shadow: 0px 0px 4px 5px rgba(0, 0, 0, 0.02);
|
||||
a{
|
||||
padding:0px 20px;
|
||||
height: 44px;
|
||||
margin-top: 10px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
&:hover{
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
&.active{
|
||||
background: linear-gradient(to right,#07228F , #466AFF);
|
||||
color: #fff!important;
|
||||
}
|
||||
img{
|
||||
margin-right: 12px;
|
||||
width: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.leftLists{
|
||||
flex:1;
|
||||
box-shadow: 0px 0px 4px 5px rgba(0, 0, 0, 0.02);
|
||||
.leftTitles{
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid rgba(153, 153, 153, 0.16);
|
||||
padding:0px 20px;
|
||||
.ant-btn-primary{
|
||||
background-color: #466AFF;
|
||||
border-color: #466AFF;
|
||||
&:hover,&:active{
|
||||
background-color: rgba(70,106,255,0.8);
|
||||
border-color: rgba(70,106,255,0.8);
|
||||
}
|
||||
}
|
||||
&>span{
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #000000;
|
||||
}
|
||||
a{
|
||||
color: #466AFF!important;
|
||||
}
|
||||
}
|
||||
.leftlistItem{
|
||||
padding:0px 20px;
|
||||
li{
|
||||
border-bottom: 1px solid rgba(153, 153, 153, 0.16);
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding:20px 0px ;
|
||||
&>a img{
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.itemTitle{
|
||||
flex:1;
|
||||
.item-title-infos{
|
||||
height: 22px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.infotitle{
|
||||
flex:1;
|
||||
height: 21px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 21px;
|
||||
color: #333!important;
|
||||
max-width: 458px;
|
||||
&:hover{
|
||||
color: #466AFF!important;
|
||||
}
|
||||
}
|
||||
span{
|
||||
margin-left:20px ;
|
||||
color: #333;
|
||||
i{
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
.item-desc{
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #414141;
|
||||
line-height: 24px;
|
||||
max-width: 548px;
|
||||
margin: 5px 0px;
|
||||
}
|
||||
.item-data{
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #7D7D7D;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.category{
|
||||
position: relative;
|
||||
padding-left: 11px;
|
||||
margin-right: 10px;
|
||||
&::before{
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background-color: #466AFF;
|
||||
top: 7px;
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
.language{
|
||||
position: relative;
|
||||
padding-left: 11px;
|
||||
&::before{
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 1px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
border-left: 1px solid #9e9e9e;
|
||||
bottom: 5px;
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.left-bottom-btn{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding:18px 0px;
|
||||
a{
|
||||
height: 38px;
|
||||
line-height: 36px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #466AFF;
|
||||
color: #466AFF;
|
||||
font-size: 16px;
|
||||
padding:0px 20px;
|
||||
img{
|
||||
height: 16px;
|
||||
margin-top: -1px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.right{
|
||||
width: 330px;
|
||||
&>div{
|
||||
box-shadow: 0px 0px 4px 5px rgba(0, 0, 0, 0.02);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.partTitle{
|
||||
padding:15px;
|
||||
background: #F6F9FF;
|
||||
font-size: 18px;
|
||||
color: #000000;
|
||||
font-weight: 500;
|
||||
margin-bottom: 10px;
|
||||
img{
|
||||
width: 33px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
.righthotAuthor{
|
||||
padding-bottom: 15px;
|
||||
li{
|
||||
padding-left: 15px;
|
||||
&>div{
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding:10px 15px 10px 0px;
|
||||
border-bottom: 1px solid rgba(153, 153, 153, 0.1);
|
||||
img{
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
background-color: #F3F3F3;
|
||||
}
|
||||
&:last-child > div{
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.hotProjects{
|
||||
li{
|
||||
padding:10px 15px;
|
||||
margin-bottom: 10px;
|
||||
&:hover{
|
||||
background-color: #F3F3F3;
|
||||
}
|
||||
.mInfos{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 20px;
|
||||
.num{
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background: #466AFF;
|
||||
border-radius: 2px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 18px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.name{
|
||||
flex:1;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
.sInfos{
|
||||
background: #F7F8F9;
|
||||
padding:0px 5px;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
line-height: 24px;
|
||||
word-break: break-all;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import Slider from 'react-slick';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import Eye from '../img/index/eye.png';
|
||||
import Data from '../img/index/data.png';
|
||||
import Earth from '../img/index/earth.png';
|
||||
import axios from 'axios';
|
||||
|
||||
// const list =[
|
||||
// {img:Imgs,name:"矽璓工业物联操作系统XiUOS",company:"泛在操作系统实验室",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"},
|
||||
// {img:Imgs,name:"openGauss-operator",company:"华为技术有限公司",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"},
|
||||
// {img:Imgs,name:"PaddleDetection 2.0",company:"TrustieMirrors",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"},
|
||||
// {img:Imgs,name:"skyline",company:"浪潮信息",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"},
|
||||
// {img:Imgs,name:"BitXHub",company:"开放原子开源基金会",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"},
|
||||
// {img:Imgs,name:"Device Model",company:"openDACS",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"},
|
||||
// {img:Imgs,name:"Gitlink",company:"Gitlink",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"},
|
||||
// {img:Imgs,name:"openEuler-datenlord",company:"华为技术有限公司",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"},
|
||||
// {img:Imgs,name:"OpenAtom XuperChain",company:"开放原子开源基金会",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"},
|
||||
// {img:Imgs,name:"xuos-web",company:"泛在操作系统实验室",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"},
|
||||
// {img:Imgs,name:"CrowdOS开源项目开发",company:"西北工业大学",desc:"此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情此处为项目介绍详情",look:432,cloud:"云原声",type:"C++"},
|
||||
// ]
|
||||
const settings={
|
||||
dots: false,
|
||||
infinite: true,
|
||||
speed: 1000,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
autoplay:true,
|
||||
arrows:false,
|
||||
adaptiveHeight:true
|
||||
}
|
||||
|
||||
function SubBanner() {
|
||||
|
||||
const [ list , setList ] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
getList();
|
||||
},[])
|
||||
|
||||
function getList() {
|
||||
const url = `/projects/banner_recommend.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
setList(result.data.projects);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
return(
|
||||
<div className="banners">
|
||||
<div className="bannersCenter">
|
||||
<p className="bTitle"><span>GitLink 确实开源</span></p>
|
||||
<p className="bSubTitle">新一代开发创新服务平台 让你的创意在这里释放</p>
|
||||
<div className="bannerBox">
|
||||
{
|
||||
list && list.length > 0 ?
|
||||
<Slider {...settings} className="bannersProject">
|
||||
{
|
||||
list.map((i,k)=>{
|
||||
return(
|
||||
<li>
|
||||
<div className="projectinfos">
|
||||
<Link to={`/${i.author && i.author.login}`}><img src={getImageUrl(`/${i.author && i.author.image_url}`)} alt="" /></Link>
|
||||
<div>
|
||||
<p className="name"><Link to={`/${i.author && i.author.login}/${i.identifier}`}>{i.name}</Link></p>
|
||||
<p className="company"><Link to={`/${i.author && i.author.login}`}>{i.author && i.author.name}</Link></p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="desc">{i.description}</p>
|
||||
<div className="infoData">
|
||||
<span><img src={Eye} alt="" /><span>{i.visits}</span></span>
|
||||
{i.category && i.category.id && <span><img src={Data} alt="" /><span>{i.category.name}</span></span>}
|
||||
{i.language && i.language.id && <span><img src={Earth} alt="" /><span>{i.language.name}</span></span>}
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Slider>
|
||||
:""
|
||||
}
|
||||
</div>
|
||||
<div className="airBubble">
|
||||
<div className="left">
|
||||
<div>
|
||||
{
|
||||
list && list.length > 0 && list.map((i,k)=>{
|
||||
return(
|
||||
k%2 === 0? <span><Link to={`/${i.author && i.author.login}/${i.identifier}`}>{i.author && i.author.name}/{i.name}</Link></span> : ""
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="right">
|
||||
<div>
|
||||
{
|
||||
list && list.length > 0 && list.map((i,k)=>{
|
||||
return(
|
||||
k%2 > 0 ? <span><Link to={`/${i.author && i.author.login}/${i.identifier}`}>{i.author && i.author.name}/{i.name}</Link></span> : ""
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default SubBanner
|
|
@ -0,0 +1,138 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import hotAuthor from '../img/index/hotAuthor.png';
|
||||
import week from '../img/index/week.png';
|
||||
import month from '../img/index/month.png';
|
||||
import { Link } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import { getImageUrl } from 'educoder';
|
||||
|
||||
|
||||
function SubList() {
|
||||
|
||||
const [ weekList ,setWeekList ] = useState(undefined);
|
||||
const [ monthList ,setMonthList ] = useState(undefined);
|
||||
const [ authorList ,setAuthorList ] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
getList(7);
|
||||
getList(30);
|
||||
getAuthorList(7);
|
||||
},[])
|
||||
|
||||
function getList(time){
|
||||
const url = `/project_rank.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
time
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
time === 7 ? setWeekList(result.data.projects) : setMonthList(result.data.projects);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
function getAuthorList(time){
|
||||
const url = `/user_rank.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
time
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setAuthorList(result.data.users);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="right">
|
||||
{
|
||||
authorList && authorList.length > 0?
|
||||
<div>
|
||||
<div className="partTitle"><img src={hotAuthor} alt="" /><span>本周热门开发者</span></div>
|
||||
<div className="righthotAuthor">
|
||||
{
|
||||
authorList.map((i,k)=>{
|
||||
return(
|
||||
<li>
|
||||
<div>
|
||||
<Link target="_blank" to={`/${i.login}`}><img src={getImageUrl(`/${i.avatar_url}`)} alt=""/></Link>
|
||||
<div>
|
||||
<Link target="_blank" to={`/${i.login}`} className="font-15">{i.name}</Link>
|
||||
<p className="task-hide" style={{maxWidth:"260px"}}>
|
||||
<Link target="_blank" to={`/${i.login}/${i.project && i.project.identifier}`}><i className="iconfont icon-daimakuicon1 font-14 mr8"></i>{i.project && i.project.name}</Link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
:""
|
||||
}
|
||||
|
||||
{
|
||||
weekList && weekList.length > 0 ?
|
||||
<div>
|
||||
<div className="partTitle"><img src={week} alt="" /><span>本周热门项目</span></div>
|
||||
<div className="hotProjects">
|
||||
{
|
||||
weekList.map((i,k)=>{
|
||||
return(
|
||||
<li>
|
||||
<div className="mInfos">
|
||||
<span className="num">{k+1}</span>
|
||||
<Link target="_blank" to={`/${i.owner && i.owner.login}/${i.identifier}`} className="name task-hide">{i.owner && i.owner.name}/{i.name}</Link>
|
||||
<span>
|
||||
<i className="iconfont icon-dianzan11 font-16 mr4"></i>{i.praises}
|
||||
</span>
|
||||
</div>
|
||||
{i.description &&
|
||||
<div className="sInfos task-hide-2">
|
||||
{i.description}
|
||||
</div>
|
||||
}
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
:""
|
||||
}
|
||||
{
|
||||
monthList && monthList.length > 0?
|
||||
<div>
|
||||
<div className="partTitle"><img src={month} alt="" /><span>本月热门项目</span></div>
|
||||
<div className="hotProjects">
|
||||
{
|
||||
monthList.map((i,k)=>{
|
||||
return(
|
||||
<li>
|
||||
<div className="mInfos">
|
||||
<span className="num">{k+1}</span>
|
||||
<Link target="_blank" to={`/${i.owner && i.owner.login}/${i.identifier}`} className="name task-hide">{i.owner && i.owner.name}/{i.name}</Link>
|
||||
<span>
|
||||
<i className="iconfont icon-dianzan11 font-16 mr4"></i>{i.praises}
|
||||
</span>
|
||||
</div>
|
||||
{i.description &&
|
||||
<div className="sInfos task-hide-2">
|
||||
{i.description}
|
||||
</div>
|
||||
}
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
:""
|
||||
}
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default SubList;
|
|
@ -0,0 +1,92 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import Hot from '../img/index/hot.png';
|
||||
import Slider from "react-slick";
|
||||
import huawei from '../img/index/unit/huawei.png';
|
||||
import langchao from '../img/index/unit/langchao.png';
|
||||
import jijinhui from '../img/index/unit/jijinhui.png';
|
||||
import mulan from '../img/index/unit/mulan.png';
|
||||
import xigongye from '../img/index/unit/xigongye.png';
|
||||
import feiteng from '../img/index/unit/feiteng.png';
|
||||
import xiuos from '../img/index/unit/xiuos.png';
|
||||
import huake from '../img/index/unit/huake.png';
|
||||
import axios from 'axios';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getImageUrl } from 'educoder';
|
||||
|
||||
const settings = {
|
||||
dots: false,
|
||||
infinite: true,
|
||||
slidesToShow: 1,
|
||||
slidesToScroll: 1,
|
||||
vertical: true,
|
||||
verticalSwiping: true,
|
||||
autoplay:true,
|
||||
arrows:false
|
||||
};
|
||||
// const group_size = 6;
|
||||
const list =[
|
||||
[
|
||||
{url:"/Huawei_Technology",avatar_url:huawei,name:"华为技术有限公司"},
|
||||
{url:"/openatom_foundation",avatar_url:jijinhui,name:"开放原子开源基金会"},
|
||||
{url:"/Inspur",avatar_url:langchao,name:"浪潮信息"},
|
||||
{url:"/mulan-community",avatar_url:mulan,name:"木兰开源社区"},
|
||||
],
|
||||
[
|
||||
{url:"/CrowdOS_WeSense",avatar_url:xigongye,name:"西北工业大学"},
|
||||
{url:"/pkecosystem",avatar_url:feiteng,name:"PK开源生态项目组"},
|
||||
{url:"/xuos",avatar_url:xiuos,name:"泛在操作系统实验室"},
|
||||
{url:"/hustos",avatar_url:huake,name:"华中科技大学操作系统团队"},
|
||||
]
|
||||
]
|
||||
function SubUnitBanner() {
|
||||
|
||||
// const [ list , setlist ] = useState(undefined);
|
||||
|
||||
// useEffect(()=>{
|
||||
// getRecommandOrz();
|
||||
// },[])
|
||||
|
||||
// function getRecommandOrz(params) {
|
||||
// const url = `/organizations/recommend.json`;
|
||||
// axios.get(url,{
|
||||
// params:{
|
||||
// group_size
|
||||
// }
|
||||
// }).then(result=>{
|
||||
// if(result){
|
||||
// setlist(result.data.organizations)
|
||||
// }
|
||||
// }).catch(error=>{})
|
||||
// }
|
||||
return(
|
||||
list && list.length > 0 ?
|
||||
<div className="unitBanner">
|
||||
<div className="unitContent">
|
||||
<div className="unitTitle">
|
||||
<span>精选开源组织</span>
|
||||
<img src={Hot} alt="" width="47px"/>
|
||||
</div>
|
||||
<Slider {...settings} className="unitSlider">
|
||||
{
|
||||
list.map((i,k)=>{
|
||||
return(
|
||||
<div className="slickline">
|
||||
{
|
||||
i.map((j,k1)=>{
|
||||
return(
|
||||
<Link to={j.url}><img src={j.avatar_url} title={j.name} alt={j.name} height="56px" style={{maxWidth:"180px"}}/></Link>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Slider>
|
||||
</div>
|
||||
</div>
|
||||
:""
|
||||
|
||||
)
|
||||
}
|
||||
export default SubUnitBanner;
|
|
@ -48,7 +48,7 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
|
|||
item.menu_name === "issues" &&
|
||||
<li className={pathname==="issues" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/${owner}/${projectsId}/issues`, state }}>
|
||||
<Tooltip title="易修是Issue的中文名,即问题列表" placement="bottom">
|
||||
<Tooltip placement="bottom">
|
||||
<i className={"iconfont icon-yixiuicon1 color-grey-3 mr5 font-14"}></i>
|
||||
<span>易修(Issue)</span>
|
||||
</Tooltip>
|
||||
|
@ -61,26 +61,26 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
|
|||
<li className={pathname==="pulls" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/${owner}/${projectsId}/pulls`, state }}>
|
||||
<i className={"iconfont icon-hebingqingqiu1 color-grey-3 mr5 font-14"}></i>
|
||||
<span>合并请求</span>
|
||||
<span>合并请求(PR)</span>
|
||||
{projectDetail && projectDetail.pull_requests_count ? <span className="num">{numFormat(projectDetail.pull_requests_count)}</span> : ""}
|
||||
</Link>
|
||||
</li>:""
|
||||
}
|
||||
{
|
||||
item.menu_name === "wiki" &&
|
||||
item.menu_name === "versions" &&
|
||||
<li className={pathname === "wiki" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/${owner}/${projectsId}/wiki`, state }}>
|
||||
<i className={"iconfont icon-a-wikiicon1 color-grey-3 mr5 font-14"}></i>
|
||||
<span>Wiki</span>
|
||||
<span>维基(Wiki)</span>
|
||||
</Link>
|
||||
</li>
|
||||
}
|
||||
{
|
||||
item.menu_name === "devops" && platform ?
|
||||
item.menu_name === "wiki" && platform ?
|
||||
<li className={pathname==="devops" ? "active" : ""}>
|
||||
{/* <Link to={{ pathname: `/${owner}/${projectsId}/devops${open_devops ? `/dispose`:""}`, state }}> */}
|
||||
<Link to={{ pathname: `/${owner}/${projectsId}/devops`, state:{...state,open_devops} }}>
|
||||
<i className="iconfont icon-gongzuoliuicon font-13 mr5 color-grey-3"></i>工作流(beta版)
|
||||
<i className="iconfont icon-gongzuoliuicon font-13 mr5 color-grey-3"></i>引擎(Engine)
|
||||
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
|
||||
</Link>
|
||||
</li>
|
||||
|
@ -97,9 +97,9 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
|
|||
</li>
|
||||
} */}
|
||||
{
|
||||
item.menu_name === "versions" &&
|
||||
item.menu_name === "devops" &&
|
||||
<li className={pathname==="milestones" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/${owner}/${projectsId}/milestones`, state }}>
|
||||
<Link to={{ pathname: `/${owner}/${projectsId}/milestones`, state }}>
|
||||
<i className={pathname==="milestones" ? "iconfont icon-lichengbeiicon color-grey-3 mr5 font-14":"iconfont icon-lichengbeiicon color-grey-6 font-14 mr5"}></i>
|
||||
<span>里程碑</span>
|
||||
{projectDetail && projectDetail.versions_count ? <span className="num">{numFormat(projectDetail.versions_count)}</span> :""}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React , { useState } from 'react';
|
||||
import { Anchor , Input } from 'antd';
|
||||
import './sub.scss';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
const { Link } = Anchor;
|
||||
|
||||
|
@ -36,11 +35,11 @@ function ReadmeCatelogue({ menuList , hash }) {
|
|||
{
|
||||
menu && menu.length>0?
|
||||
<div className="anchorBox">
|
||||
<Anchor affix={false} onChange={onChange}>
|
||||
<Anchor affix={false} onChange={onChange} offsetTop={140}>
|
||||
{
|
||||
menu.map((item,key)=>{
|
||||
return(
|
||||
<div style={{paddingLeft:`${item.level *10}px`}} className={goHref===item.href?"items active":"items"}>
|
||||
<div style={{paddingLeft:`${item.level *15}px`}} className={goHref===item.href?"items active":"items"}>
|
||||
<Link href={`#${item.text}`} title={item.text} />
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -46,14 +46,14 @@ function UpdateDescModal({form , visible , onCancel , onOk,desc,website,lesson_u
|
|||
{getFieldDecorator("website",{
|
||||
rules:[]
|
||||
})(
|
||||
<Input placeholder="website链接"/>
|
||||
<Input placeholder="website链接" maxLength={200}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="实践课程">
|
||||
{getFieldDecorator("lesson_url",{
|
||||
rules:[]
|
||||
})(
|
||||
<Input placeholder="实践课程链接" />
|
||||
<Input placeholder="实践课程链接" maxLength={200}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
|
|
@ -34,10 +34,17 @@
|
|||
padding:15px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.ant-anchor{
|
||||
padding-left: 0px!important;
|
||||
.ant-anchor-ink::before{
|
||||
width: 0px;
|
||||
}
|
||||
}
|
||||
.ant-anchor-wrapper{
|
||||
margin-left: 0px;
|
||||
padding:5px 15px;
|
||||
padding:5px 0px;
|
||||
max-height: 255px!important;
|
||||
padding-left: 0px!important;
|
||||
.items{
|
||||
border-radius: 4px;
|
||||
margin-bottom: 5px;
|
||||
|
|
|
@ -46,7 +46,7 @@ function Index(props) {
|
|||
|
||||
return(
|
||||
<Spin spinning={isSpin}>
|
||||
<div style={{paddingTop:"10px",minHeight:"400px"}}>
|
||||
<div style={{paddingTop:"10px",minHeight:"400px",paddingBottom:"30px"}}>
|
||||
{
|
||||
list && list.length>0 && list.map((item,key)=>{
|
||||
return(
|
||||
|
|
|
@ -224,7 +224,7 @@ export default Form.create()(
|
|||
<Checkbox defaultChecked={!stable}>这是一个预览版本</Checkbox>
|
||||
)}
|
||||
</Form.Item>
|
||||
<p className="pt20" style={{borderTop:"1px solid #eee"}}>
|
||||
<p className="pt20 pb20" style={{borderTop:"1px solid #eee"}}>
|
||||
<Button onClick={submit} type="primary" className="mr30 btnblue">
|
||||
{versionId ? "保存" : "创建"}发行版
|
||||
</Button>
|
||||
|
|
|
@ -6,9 +6,11 @@ import {truncateCommitId} from '../../common/util';
|
|||
import Empty from './Empty';
|
||||
import './version.scss';
|
||||
import axios from 'axios';
|
||||
import { Popconfirm } from 'antd'
|
||||
import Tree from '../img/tree-black.png';
|
||||
import RenderHtml from '../../../components/render-html';
|
||||
import User from "../../Component/User";
|
||||
import DeleteBox from "../../Component/DeleteModal/Index";
|
||||
|
||||
function version(props) {
|
||||
const [ data , setData ] = useState(undefined);
|
||||
|
@ -73,7 +75,17 @@ function version(props) {
|
|||
<Link to={`/${owner}/${projectsId}/tree/${item.tag_name}`} className="task-hide color-blue hover font-18">{item.name}</Link>
|
||||
<span>
|
||||
{data && data.user_admin_permission && type !== 2 && <Link to={{pathname:`/${owner}/${projectsId}/releases/${item.version_id}/update`,state:{"stable":item.draft==="稳定"}}} className="ml15"><i className="iconfont icon-a-bianji1 font-16 color-grey-6"></i></Link>}
|
||||
{data && data.user_admin_permission && type !== 2 && <i className ="iconfont icon-shanchuicon1 font-16 ml15" onClick={()=>{deleteRelease(item.version_id)}}></i>}
|
||||
{data && data.user_admin_permission && type !== 2 &&
|
||||
<Popconfirm
|
||||
placement="bottom"
|
||||
title={'您确定要删除当前发行版吗?'}
|
||||
okText="是"
|
||||
cancelText="否"
|
||||
onConfirm={() =>{deleteRelease(item.version_id)}}
|
||||
>
|
||||
<i className ="iconfont icon-shanchuicon1 font-16 ml15"></i>
|
||||
</Popconfirm>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
<span className="color-grey-3 mb15 version-user">
|
||||
|
|
|
@ -96,7 +96,7 @@ class CreateMerge extends Component {
|
|||
// 再获取对应的仓库列表、分支列表
|
||||
// 再调用比较接口
|
||||
const branchParams = getBranchParams(this.props.location.pathname);
|
||||
this.getMergeInfo(branchParams);
|
||||
this.getMergeInfo(branchParams,true);
|
||||
};
|
||||
|
||||
componentDidUpdate = (preProps) => {
|
||||
|
@ -110,15 +110,20 @@ class CreateMerge extends Component {
|
|||
};
|
||||
|
||||
//获取新建合并请求数据
|
||||
getMergeInfo = (branchParams) => {
|
||||
getMergeInfo = (branchParams,init) => {
|
||||
this.setState({ isSpin: true });
|
||||
const { pullOwner, pullBranch, mergeOwner, mergeBranch, projectId } =
|
||||
branchParams;
|
||||
const { pullOwner, pullBranch, mergeOwner, mergeBranch, projectId } = branchParams;
|
||||
const url = `/${pullOwner}/${projectId}/pulls/new.json`;
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
if(init){
|
||||
//页面初始化时调用selectProjectName,给is_original、fork_project_id、merge_user_login赋值
|
||||
const initUser = result.data.projects_names && result.data.projects_names.filter((item)=>item.project_user_login === branchParams.mergeOwner);
|
||||
initUser && initUser[0] && this.selectProjectName(initUser[0].id,false,{projects_names: result.data.projects_names,id: result.data.id});
|
||||
}
|
||||
this.setState({isSpin: false});
|
||||
// 如果url上的分支不存在,取默认值master
|
||||
const noMergeBranch =
|
||||
(result.data.branches || []).filter(
|
||||
|
@ -175,8 +180,7 @@ class CreateMerge extends Component {
|
|||
compareProject = (sameProject, branchParams) => {
|
||||
// const { project } = this.props;
|
||||
// const { owner, projectsId } = this.props.match.params;
|
||||
const { pullOwner, pullBranch, mergeOwner, mergeBranch, projectId } =
|
||||
branchParams;
|
||||
const { pullOwner, pullBranch, mergeOwner, mergeBranch, projectId } = branchParams;
|
||||
|
||||
let url = `/${mergeOwner}/${projectId}/compare`;
|
||||
if (sameProject) {
|
||||
|
@ -262,8 +266,8 @@ class CreateMerge extends Component {
|
|||
};
|
||||
|
||||
// 切换仓库响应事件,目前仅目标分支可切换仓库
|
||||
selectProjectName = (value) => {
|
||||
const { projects_names, id } = this.state;
|
||||
selectProjectName = (value, isChangeProject, initPro) => {
|
||||
const { projects_names, id } = isChangeProject ? this.state : initPro;
|
||||
const { pullOwner, pullBranch } = getBranchParams(
|
||||
this.props.location.pathname
|
||||
);
|
||||
|
@ -274,7 +278,8 @@ class CreateMerge extends Component {
|
|||
// 目标仓库与源仓库不是一个仓库
|
||||
let is_fork = parseInt(value, 10) !== parseInt(id, 10);
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
// 切换目标仓库时url会发生变化,即有spin效果
|
||||
// isSpin: true,
|
||||
// merge_head: is_fork,
|
||||
data: {
|
||||
is_original: is_fork,
|
||||
|
@ -284,15 +289,18 @@ class CreateMerge extends Component {
|
|||
: undefined,
|
||||
},
|
||||
});
|
||||
if (login === pullOwner) {
|
||||
// 如果切换后, 仓库与源仓库一致了
|
||||
this.props.history.push(
|
||||
`/${login}/${identifier}/compare/master...${pullBranch}`
|
||||
);
|
||||
} else {
|
||||
this.props.history.push(
|
||||
`/${login}/${identifier}/compare/master...${pullOwner}:${pullBranch}`
|
||||
);
|
||||
// 加上是否需要切换url判断
|
||||
if(isChangeProject){
|
||||
if (login === pullOwner) {
|
||||
// 如果切换后, 仓库与源仓库一致了
|
||||
this.props.history.push(
|
||||
`/${login}/${identifier}/compare/master...${pullBranch}`
|
||||
);
|
||||
} else {
|
||||
this.props.history.push(
|
||||
`/${login}/${identifier}/compare/master...${pullOwner}:${pullBranch}`
|
||||
);
|
||||
}
|
||||
}
|
||||
// this.newMergelist(login, identifier);
|
||||
};
|
||||
|
@ -354,7 +362,7 @@ class CreateMerge extends Component {
|
|||
<div className="main">
|
||||
<div className="merge-header width100 inline-block">
|
||||
<div className="width40 pull-left">
|
||||
<div className="color-grey-3 mb10 fwb">源分支:</div>
|
||||
<div className="color-grey-3 mb10 fwb">源分支 : </div>
|
||||
<Input.Group compact className="display-flex">
|
||||
<Select
|
||||
value={id}
|
||||
|
@ -382,12 +390,12 @@ class CreateMerge extends Component {
|
|||
</div>
|
||||
<div className="width40 pull-left">
|
||||
<div>
|
||||
<div className="color-grey-3 mb10 fwb">目标分支:</div>
|
||||
<div className="color-grey-3 mb10 fwb">目标分支 : </div>
|
||||
<Input.Group compact className="display-flex">
|
||||
<Select
|
||||
value={project && project.id}
|
||||
className="hide-1 task-hide flex1"
|
||||
onSelect={(e) => this.selectProjectName(e)}
|
||||
onSelect={(e) => this.selectProjectName(e, true)}
|
||||
>
|
||||
{this.renderProjectNames(mergeProjects)}
|
||||
</Select>
|
||||
|
|