Compare commits

..

No commits in common. "gitlink_server" and "master" have entirely different histories.

552 changed files with 4443 additions and 21837 deletions

2
.gitignore vendored
View File

@ -37,7 +37,7 @@ bower_components
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/
src/.umi/
# Dependency directories
node_modules/
jspm_packages/

File diff suppressed because it is too large Load Diff

15
.vscode/launch.json vendored
View File

@ -1,15 +0,0 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}"
}
]
}

View File

@ -150,7 +150,7 @@ module.exports = {
{
libraryName: "antd",
libraryDirectory: "es",
style: true,
style: "css",
},
],
],
@ -206,34 +206,8 @@ module.exports = {
{
loader: require.resolve("sass-loader"),
},
{
loader: 'sass-resources-loader',
options: {
resources: ['src/global.scss']
}
}
],
},
{
test: /\.less$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader', // translates CSS into CommonJS
}, {
loader: 'less-loader', // compiles Less to CSS
options: {
modifyVars: {
'primary-color': '#466aff',
'primary-color-hover': '#6684FE',
'primary-color-active': '#1A47FF',
'link-color': '#466aff',
},
javascriptEnabled: true,
},
}]
},
// "file" loader makes sure those assets get served by WebpackDevServer.
// When you `import` an asset, you get its (virtual) filename.
// In production, they would get copied to the `build` folder.
@ -292,7 +266,7 @@ module.exports = {
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new MonacoWebpackPlugin({
features: ["coreCommands", "find"],
languages: ['plaintext', 'apex', 'azcli', 'bat', 'clojure', 'coffee', 'cpp', 'csharp', 'csp', 'css', 'dockerfile', 'fsharp', 'go', 'handlebars', 'html', 'ini', 'java', 'javascript', 'json', 'less', 'lua', 'markdown', 'msdax', 'mysql', 'objective', 'perl', 'pgsql', 'php', 'postiats', 'powerquery', 'powershell', 'pug', 'python', 'r', 'razor', 'redis', 'redshift', 'ruby', 'rust', 'sb', 'scheme', 'scss', 'shell', 'solidity', 'sql', 'st', 'swift', 'typescript', 'vb', 'xml', 'yaml']
languages: ['plaintext','apex', 'azcli', 'bat', 'clojure', 'coffee', 'cpp', 'csharp', 'csp', 'css', 'dockerfile', 'fsharp', 'go', 'handlebars', 'html', 'ini', 'java', 'javascript', 'json', 'less', 'lua', 'markdown', 'msdax', 'mysql', 'objective', 'perl', 'pgsql', 'php', 'postiats', 'powerquery', 'powershell', 'pug', 'python', 'r', 'razor', 'redis', 'redshift', 'ruby', 'rust', 'sb', 'scheme', 'scss', 'shell', 'solidity', 'sql', 'st', 'swift', 'typescript', 'vb', 'xml', 'yaml']
}),
],
// Some libraries import Node modules but don't use them in the browser.

View File

@ -147,7 +147,7 @@ module.exports = {
{
libraryName: "antd",
libraryDirectory: "es",
style: true,
style: "css",
},
],
],
@ -208,31 +208,8 @@ module.exports = {
{
loader: require.resolve("sass-loader"),
},
{
loader: 'sass-resources-loader',
options: {
resources: ['src/global.scss']
}
}
],
},
{
test: /\.less$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader', // translates CSS into CommonJS
}, {
loader: 'less-loader', // compiles Less to CSS
options: {
modifyVars: {
'primary-color': '#466aff',
'link-color': '#466aff',
},
javascriptEnabled: true,
},
}]
},
// "file" loader makes sure assets end up in the `build` folder.
// When you `import` an asset, you get its filename.
// This loader doesn't use a "test" so it will catch all modules

3049
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
"antd": "^3.26.15",
"array-flatten": "^2.1.2",
"autoprefixer": "7.1.6",
"axios": "^0.24.0",
"axios": "^0.18.1",
"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.64.0",
"codemirror": "^5.53.0",
"connected-react-router": "4.4.1",
"cross-env": "^7.0.3",
"css-loader": "^3.5.2",
"dompurify": "^2.3.3",
"dompurify": "^2.0.15",
"dotenv": "4.0.0",
"dotenv-expand": "4.2.0",
"echarts": "^4.9.0",
@ -51,9 +51,7 @@
"js-base64": "^2.5.2",
"js2wordcloud": "^1.1.12",
"katex": "^0.11.1",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"lodash": "^4.17.21",
"lodash": "^4.17.15",
"loglevel": "^1.6.8",
"marked": "^1.0.0",
"material-ui": "^1.0.0-beta.40",
@ -86,8 +84,6 @@
"react-color": "^2.18.0",
"react-content-loader": "^3.1.1",
"react-cookies": "^0.1.1",
"react-countup": "^6.1.0",
"react-cropper": "^2.1.8",
"react-datepicker": "^2.14.1",
"react-dev-utils": "^9.2.0-next.80",
"react-dom": "^16.13.1",
@ -213,7 +209,6 @@
"react-json-view": "^1.21.3",
"reqwest": "^2.0.5",
"resize-observer-polyfill": "^1.5.1",
"sass-resources-loader": "^2.2.5",
"terser-webpack-plugin": "^2.3.5",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack": "^4.42.1",

View File

@ -1268,17 +1268,11 @@ 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: "iconfont";
font-family: "Microsoft YaHei", "SimSun";
color: #05101a;
height: 100%;
position: relative;
@ -1365,12 +1359,12 @@ table {
border: 0;
}
a:link,a:visited{
a:link,
a:visited {
text-decoration: none;
color: #05101a;
}
ol,
ul,
li {
@ -2466,7 +2460,7 @@ a.hoverLine:hover{
}
a:hover{
color: #6684FE;
color: #466AFF !important;
}
.color-grey-98 {
@ -3945,13 +3939,9 @@ html>body #ajax-indicator {
margin-left: 10px;
color: #2FC25B;
}
.privateTag.red{
color: #FF6832;
border:1px solid #FF6832;
}
.head-nav {
text-align: center;
height: 58px;
height: 70px;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
@ -3963,14 +3953,14 @@ html>body #ajax-indicator {
position: absolute;
top: 0px;
z-index: 3;
height: 58px;
height: 70px;
box-sizing: border-box;
}
.head-nav ul#header-nav li {
float: left;
height: 58px;
line-height: 58px;
height: 70px;
line-height: 70px;
cursor: pointer;
position: relative;
font-size: 16px;
@ -3981,7 +3971,7 @@ html>body #ajax-indicator {
display: block;
height: 100%;
width: 100%;
color: #fff;
color: #333;
font-size: 16px;
}
@ -3993,6 +3983,10 @@ 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;

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 2340181 */
src: url('iconfont.woff2?t=1653550272457') format('woff2'),
url('iconfont.woff?t=1653550272457') format('woff'),
url('iconfont.ttf?t=1653550272457') format('truetype');
src: url('iconfont.woff2?t=1634881729644') format('woff2'),
url('iconfont.woff?t=1634881729644') format('woff'),
url('iconfont.ttf?t=1634881729644') format('truetype');
}
.iconfont {
@ -13,338 +13,6 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-tuichuicon:before {
content: "\e936";
}
.icon-bangzhuzhongxinicon1:before {
content: "\e935";
}
.icon-ketixiangqingicon:before {
content: "\e92b";
}
.icon-bianjiicon:before {
content: "\e92c";
}
.icon-baomingxiangqingicon:before {
content: "\e92d";
}
.icon-sousuo4:before {
content: "\e92e";
}
.icon-quxiaoshenqingicon:before {
content: "\e92f";
}
.icon-xiala3:before {
content: "\e930";
}
.icon-tianjia_tianchong:before {
content: "\e931";
}
.icon-a-shanchu2:before {
content: "\e932";
}
.icon-shanchuicon3:before {
content: "\e933";
}
.icon-shenqingketiicon:before {
content: "\e934";
}
.icon-weixin:before {
content: "\e92a";
}
.icon-zanwushuju:before {
content: "\e928";
}
.icon-fuwuicon:before {
content: "\e929";
}
.icon-personal-center:before {
content: "\e927";
}
.icon-bangzhuzhongxinicon:before {
content: "\e926";
}
.icon-kaiyuanxiangmu:before {
content: "\e91d";
}
.icon-luntanjiaoliu:before {
content: "\e91e";
}
.icon-wangzhanpeizhi:before {
content: "\e91f";
}
.icon-weixuanze-chuangkekongjian:before {
content: "\e920";
}
.icon-tubiao:before {
content: "\e921";
}
.icon-gonggaofabu:before {
content: "\e922";
}
.icon-jingsaihuodong:before {
content: "\e923";
}
.icon-yonghuguanli:before {
content: "\e924";
}
.icon-shenpi:before {
content: "\e925";
}
.icon-zhuanli1:before {
content: "\e918";
}
.icon-daimaicon:before {
content: "\e91c";
}
.icon-jiangxiangicon:before {
content: "\e916";
}
.icon-shuju:before {
content: "\e917";
}
.icon-wendang:before {
content: "\e919";
}
.icon-lunwen:before {
content: "\e91a";
}
.icon-zhuanli:before {
content: "\e91b";
}
.icon-gailan1:before {
content: "\e914";
}
.icon-tuandui:before {
content: "\e915";
}
.icon-icon2:before {
content: "\e912";
}
.icon-a-21:before {
content: "\e913";
}
.icon-a-2:before {
content: "\e90f";
}
.icon-a-3:before {
content: "\e910";
}
.icon-icon1:before {
content: "\e911";
}
.icon-ioon:before {
content: "\e90e";
}
.icon-shanchu_tc_icon1:before {
content: "\e90c";
}
.icon-zhuanjiaicon:before {
content: "\e90d";
}
.icon-shengming:before {
content: "\e90b";
}
.icon-chenggong1:before {
content: "\e907";
}
.icon-a-bitian2x1:before {
content: "\e908";
}
.icon-xiala1:before {
content: "\e909";
}
.icon-xiala2:before {
content: "\e90a";
}
.icon-jiantou1:before {
content: "\e905";
}
.icon-zhangjieicon:before {
content: "\e8fe";
}
.icon-chengyuan1:before {
content: "\e903";
}
.icon-a-shangchuan2x:before {
content: "\e8f9";
}
.icon-shanchu7:before {
content: "\e8fa";
}
.icon-zuohuabeifen:before {
content: "\e8fb";
}
.icon-a-bianji11:before {
content: "\e8f4";
}
.icon-a-bitian2x:before {
content: "\e8f5";
}
.icon-a-zuohua2x:before {
content: "\e8f7";
}
.icon-lianjie3:before {
content: "\e8f8";
}
.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";
}

File diff suppressed because one or more lines are too long

View File

@ -5,587 +5,6 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "29934961",
"name": "退出icon",
"font_class": "tuichuicon",
"unicode": "e936",
"unicode_decimal": 59702
},
{
"icon_id": "29811507",
"name": "帮助中心icon",
"font_class": "bangzhuzhongxinicon1",
"unicode": "e935",
"unicode_decimal": 59701
},
{
"icon_id": "29701613",
"name": "课题详情icon",
"font_class": "ketixiangqingicon",
"unicode": "e92b",
"unicode_decimal": 59691
},
{
"icon_id": "29701614",
"name": "编辑icon",
"font_class": "bianjiicon",
"unicode": "e92c",
"unicode_decimal": 59692
},
{
"icon_id": "29701615",
"name": "报名详情icon",
"font_class": "baomingxiangqingicon",
"unicode": "e92d",
"unicode_decimal": 59693
},
{
"icon_id": "29701616",
"name": "搜索",
"font_class": "sousuo4",
"unicode": "e92e",
"unicode_decimal": 59694
},
{
"icon_id": "29701617",
"name": "取消申请icon",
"font_class": "quxiaoshenqingicon",
"unicode": "e92f",
"unicode_decimal": 59695
},
{
"icon_id": "29701618",
"name": "下拉",
"font_class": "xiala3",
"unicode": "e930",
"unicode_decimal": 59696
},
{
"icon_id": "29701619",
"name": "添加_填充",
"font_class": "tianjia_tianchong",
"unicode": "e931",
"unicode_decimal": 59697
},
{
"icon_id": "29701620",
"name": "删除 (2)",
"font_class": "a-shanchu2",
"unicode": "e932",
"unicode_decimal": 59698
},
{
"icon_id": "29701621",
"name": "删除icon",
"font_class": "shanchuicon3",
"unicode": "e933",
"unicode_decimal": 59699
},
{
"icon_id": "29701622",
"name": "申请课题icon",
"font_class": "shenqingketiicon",
"unicode": "e934",
"unicode_decimal": 59700
},
{
"icon_id": "29665762",
"name": "微信",
"font_class": "weixin",
"unicode": "e92a",
"unicode_decimal": 59690
},
{
"icon_id": "29467269",
"name": "暂无数据",
"font_class": "zanwushuju",
"unicode": "e928",
"unicode_decimal": 59688
},
{
"icon_id": "29467272",
"name": "服务icon",
"font_class": "fuwuicon",
"unicode": "e929",
"unicode_decimal": 59689
},
{
"icon_id": "29206429",
"name": "personal-center",
"font_class": "personal-center",
"unicode": "e927",
"unicode_decimal": 59687
},
{
"icon_id": "28888753",
"name": "帮助中心icon",
"font_class": "bangzhuzhongxinicon",
"unicode": "e926",
"unicode_decimal": 59686
},
{
"icon_id": "28163416",
"name": "开源项目",
"font_class": "kaiyuanxiangmu",
"unicode": "e91d",
"unicode_decimal": 59677
},
{
"icon_id": "28163417",
"name": "论坛交流",
"font_class": "luntanjiaoliu",
"unicode": "e91e",
"unicode_decimal": 59678
},
{
"icon_id": "28163418",
"name": "网站配置",
"font_class": "wangzhanpeizhi",
"unicode": "e91f",
"unicode_decimal": 59679
},
{
"icon_id": "28163419",
"name": "未选择-创客空间",
"font_class": "weixuanze-chuangkekongjian",
"unicode": "e920",
"unicode_decimal": 59680
},
{
"icon_id": "28163420",
"name": "图标",
"font_class": "tubiao",
"unicode": "e921",
"unicode_decimal": 59681
},
{
"icon_id": "28163421",
"name": "公告发布",
"font_class": "gonggaofabu",
"unicode": "e922",
"unicode_decimal": 59682
},
{
"icon_id": "28163422",
"name": "竞赛活动",
"font_class": "jingsaihuodong",
"unicode": "e923",
"unicode_decimal": 59683
},
{
"icon_id": "28163423",
"name": "用户管理",
"font_class": "yonghuguanli",
"unicode": "e924",
"unicode_decimal": 59684
},
{
"icon_id": "28163424",
"name": "审批",
"font_class": "shenpi",
"unicode": "e925",
"unicode_decimal": 59685
},
{
"icon_id": "22773568",
"name": "专利",
"font_class": "zhuanli1",
"unicode": "e918",
"unicode_decimal": 59672
},
{
"icon_id": "27680124",
"name": "代码icon",
"font_class": "daimaicon",
"unicode": "e91c",
"unicode_decimal": 59676
},
{
"icon_id": "27664463",
"name": "奖项icon",
"font_class": "jiangxiangicon",
"unicode": "e916",
"unicode_decimal": 59670
},
{
"icon_id": "27664464",
"name": "数据",
"font_class": "shuju",
"unicode": "e917",
"unicode_decimal": 59671
},
{
"icon_id": "27664466",
"name": "文档",
"font_class": "wendang",
"unicode": "e919",
"unicode_decimal": 59673
},
{
"icon_id": "27664467",
"name": "论文",
"font_class": "lunwen",
"unicode": "e91a",
"unicode_decimal": 59674
},
{
"icon_id": "27664468",
"name": "专利",
"font_class": "zhuanli",
"unicode": "e91b",
"unicode_decimal": 59675
},
{
"icon_id": "27664392",
"name": "概览",
"font_class": "gailan1",
"unicode": "e914",
"unicode_decimal": 59668
},
{
"icon_id": "27664393",
"name": "团队",
"font_class": "tuandui",
"unicode": "e915",
"unicode_decimal": 59669
},
{
"icon_id": "27299393",
"name": "icon",
"font_class": "icon2",
"unicode": "e912",
"unicode_decimal": 59666
},
{
"icon_id": "27299394",
"name": "2",
"font_class": "a-21",
"unicode": "e913",
"unicode_decimal": 59667
},
{
"icon_id": "27200759",
"name": "2",
"font_class": "a-2",
"unicode": "e90f",
"unicode_decimal": 59663
},
{
"icon_id": "27200760",
"name": "3",
"font_class": "a-3",
"unicode": "e910",
"unicode_decimal": 59664
},
{
"icon_id": "27200761",
"name": "icon",
"font_class": "icon1",
"unicode": "e911",
"unicode_decimal": 59665
},
{
"icon_id": "27041503",
"name": "ioon",
"font_class": "ioon",
"unicode": "e90e",
"unicode_decimal": 59662
},
{
"icon_id": "26470602",
"name": "shanchu_tc_icon",
"font_class": "shanchu_tc_icon1",
"unicode": "e90c",
"unicode_decimal": 59660
},
{
"icon_id": "26470603",
"name": "专家icon",
"font_class": "zhuanjiaicon",
"unicode": "e90d",
"unicode_decimal": 59661
},
{
"icon_id": "12505154",
"name": "声明",
"font_class": "shengming",
"unicode": "e90b",
"unicode_decimal": 59659
},
{
"icon_id": "26470597",
"name": "成功",
"font_class": "chenggong1",
"unicode": "e907",
"unicode_decimal": 59655
},
{
"icon_id": "26470599",
"name": "必填@2x",
"font_class": "a-bitian2x1",
"unicode": "e908",
"unicode_decimal": 59656
},
{
"icon_id": "26470600",
"name": "下拉",
"font_class": "xiala1",
"unicode": "e909",
"unicode_decimal": 59657
},
{
"icon_id": "26470601",
"name": "下拉2",
"font_class": "xiala2",
"unicode": "e90a",
"unicode_decimal": 59658
},
{
"icon_id": "26363219",
"name": "箭头",
"font_class": "jiantou1",
"unicode": "e905",
"unicode_decimal": 59653
},
{
"icon_id": "26359564",
"name": "章节icon ",
"font_class": "zhangjieicon",
"unicode": "e8fe",
"unicode_decimal": 59646
},
{
"icon_id": "26359565",
"name": "成员",
"font_class": "chengyuan1",
"unicode": "e903",
"unicode_decimal": 59651
},
{
"icon_id": "26325702",
"name": "上传@2x",
"font_class": "a-shangchuan2x",
"unicode": "e8f9",
"unicode_decimal": 59641
},
{
"icon_id": "26325703",
"name": "删除 ",
"font_class": "shanchu7",
"unicode": "e8fa",
"unicode_decimal": 59642
},
{
"icon_id": "26325704",
"name": "左滑备份",
"font_class": "zuohuabeifen",
"unicode": "e8fb",
"unicode_decimal": 59643
},
{
"icon_id": "26325698",
"name": "编辑 (1)",
"font_class": "a-bianji11",
"unicode": "e8f4",
"unicode_decimal": 59636
},
{
"icon_id": "26325699",
"name": "必填@2x",
"font_class": "a-bitian2x",
"unicode": "e8f5",
"unicode_decimal": 59637
},
{
"icon_id": "26325700",
"name": "左滑@2x",
"font_class": "a-zuohua2x",
"unicode": "e8f7",
"unicode_decimal": 59639
},
{
"icon_id": "26325701",
"name": "链接",
"font_class": "lianjie3",
"unicode": "e8f8",
"unicode_decimal": 59640
},
{
"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": "文件",

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -7,7 +7,6 @@
<meta name=”Keywords” Content=”issue,bug,tracker,软件工程,课程实践″>
<meta name=”Description” Content=”持续构建协同、共享、可信的软件创建生态开源创作与软件生产相结合,支持大规模群体开展软件协同创新活动”>
<meta name="theme-color" content="#000000">
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/iconfont.css">

View File

@ -60,13 +60,8 @@ body {
.ant-progress-textno {
color: #f5222d;
}
.CodeMirror .CodeMirror-lines pre.CodeMirror-line{
font-size: 16px;
line-height: 20px;
font-family:"PingFang SC", "Segoe UI", Helvetica, Arial, "Apple Color Emoji", SimHei, SimSun, sans-serif, "Microsoft YaHei";
}
.react-codemirror2 .CodeMirror .CodeMirror-lines pre.CodeMirror-line{
font-size: 12px;
.CodeMirror pre.CodeMirror-line{
font-size: 16px!important;
}
/* md多空格 */
.markdown-body p {
@ -98,9 +93,6 @@ body {
.editormd-preview .markdown-body{
padding:0px !important;
}
.editormd-preview{
width: 50%!important;
}
/* 图片点击放大的场景,隐藏图片链接 */
.editormd-image-click-expand .editormd-image-dialog {

View File

@ -3,22 +3,21 @@ import './App.css';
import { ConfigProvider } from 'antd'
import zhCN from 'antd/lib/locale-provider/zh_CN';
import {
Route,
Switch
// BrowserRouter as Router,
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';
import moment from 'moment'
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
import SiderBar from './forge/Component/SiderBar';
import SiderBarHelp from './glcc/siderBarHelp';
// import GlccModal from './modules/glccModal';
import SiderBar from './forge/Component/SiderBar'
import { SnackbarHOC } from 'educoder';
import { initAxiosInterceptors } from './AppConfig'
@ -27,18 +26,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({
@ -47,78 +46,56 @@ 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,
loader: () => import('./forge/Team/Index'),
loading: Loading,
})
const EducoderLogin = Loadable({
loader: () => import('./modules/login/EducoderLogin'),
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,
})
const ProjectIndex = Loadable({
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"),
loader: () => import('./forge/Wiki/Preview'),
loading: Loading,
})
const Teaching = Loadable({
loader : () => import("./forge/TeachingPractice/Teaching"),
loading: Loading,
})
const Glcc = Loadable({
loader : () => import("./glcc"),
loading: Loading,
})
const ProjectIndex = Loadable({
loader: () => import("./forge/Index"),
loading: Loading,
});
// const CreateMerge = Loadable({
// loader: () => import('./forge/Merge/NewMerge'),
@ -126,444 +103,413 @@ const Glcc = Loadable({
// })
// 此处仅维护前端可能的一级路由,不用进行项目或者组织判断的字段。
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","educoder", "glcc"];
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"];
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,history) => {
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) {
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;
}
}
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;
}
}
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 { pathType, pathName } = this.state;
return (
<Provider store={store}>
<ConfigProvider locale={zhCN}>
<MuiThemeProvider theme={theme}>
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
{/* <GlccModal /> */}
{!pathName || (pathName && pathName.indexOf("glcc") === -1) ? <SiderBar /> : <SiderBarHelp/>}
{/* <Router> */}
<Switch>
{/* wiki预览 */}
<Route path="/:owner/:projectsId/wiki/preview/:projectName/:projectId" render={
(props) => {
return (<WikiPreview {...this.props} {...props} {...this.state} />)
}
} />
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} />)
}
} />
{/* 项目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
path="/login"
render={(props) =><LoginRegisterPage {...this.props} {...props}/>}
></Route>
{/* 注册 */}
<Route
path="/register"
render={(props) =><LoginRegisterPage {...this.props} {...props}/>}
></Route>
{/* 忘记密码 */}
<Route
path="/resetPassword"
render={(props) =><LoginRegisterPage {...this.props} {...props}/>}
></Route>
{/* 关于我们 */}
<Route
path = "/aboutus"
render = {(props)=><AboutUs {...this.props} {...props}/>}
></Route>
{/* 教学实践 */}
<Route
path="/educoder"
render={(props) => <Teaching {...this.props} {...props} />}
></Route>
{/*glcc */}
<Route
path="/glcc"
render={(props) => <Glcc {...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 exact path="/explore"
render={
(props) => (
<ProjectIndex {...this.props} {...props} />
)
}
/>
<Route component={Shixunnopage} />
</Switch>
</MuiThemeProvider>
</ConfigProvider>
</Provider>
);
}
{/* 组织 */}
<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) => (
personal && personal.length > 0 ?
<InfosIndex {...this.props} {...props} />
:
<ProjectIndex {...this.props} {...props} />
)
}
/>
// <Route path="/" component={Loading} />
// <Route path="/" component={Shixunnopage} />
}
{/* 个人主页 */}
<Route path="/:username"
render={
(props) => {
return (<InfosIndex {...this.props} {...this.state} />)
}
}></Route>
<Route component={Shixunnopage} />
</Switch>
{/* </Router> */}
</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);

View File

@ -33,11 +33,10 @@ export function initAxiosInterceptors(props) {
initOnlineOfflineListener();
var proxy = "https://testforgeplus.trustie.net";
//响应前的设置
axios.interceptors.request.use(
config => {
if(config.url.substr(0, 4) === "http") {
if(config.url.indexOf("http") !== -1) {
return config
}
requestProxy(config);
@ -69,8 +68,6 @@ 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: "提示",
@ -89,13 +86,8 @@ export function initAxiosInterceptors(props) {
if (response.data.status === 404) {
let responseURL = response.request ? response.request.responseURL:'';
// 组织和个人的拥有情况404不跳转
if (responseURL.indexOf('/api/users/') === -1 && responseURL.indexOf('/api/organizations/') === -1 ) {
// 邀请页面不进行404跳转
if( window.location.pathname.includes('/invite') && (responseURL.includes('/simple.json')||responseURL.includes('/detail.json')||responseURL.includes('/menu_list.json'))){
}else{
locationurl('/nopage');
}
locationurl('/nopage');
}
}

View File

@ -11,7 +11,6 @@ export function getImageUrl(path) {
// https://www.educoder.net
// https://testbdweb.trustie.net
// const local = 'http://localhost:3000'
path && !path.startsWith('/') && !path.startsWith('http') && (path = '/'.concat(path));
const local = 'https://testforgeplus.trustie.net';
if (isDev) {
return `${local}/${path}`
@ -251,36 +250,3 @@ export function publicSearchs(Placeholder,onSearch,onInputs,onChanges,loadings)
allowClear={true}
></Search>)
}
export function turnbar(str){
let s = str;
if(s && s.length>0){
if(s.indexOf("%")>-1){
s = s.replaceAll('%','_25');
}
if(s.indexOf("#")>-1){
s = s.replaceAll('#','%23');
}
if(s.indexOf("/")>-1){
s = s.replaceAll('/','%2F');
}
}
return s;
}
export function returnbar(str){
let s = str;
if(s && s.length>0){
if(str.indexOf("_25")>-1){
s = s.replaceAll('_25','%');
}
if(s.indexOf("%23")>-1){
s = s.replaceAll('%23','#');
}
if(s.indexOf("%2F")>-1){
s = s.replaceAll('%2F','/');
}
}
return s;
}

View File

@ -6,8 +6,7 @@ export {
getUploadLogoActionUrl as getUploadLogoActionUrl,numFormat as numFormat,
getImageUrl as getImageUrl,getImage as getImage, getmyUrl as getmyUrl, getRandomNumber as getRandomNumber, getUrl as getUrl, publicSearchs as publicSearchs, getRandomcode as getRandomcode, getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl
, getUploadActionUrl as getUploadActionUrl, getUploadActionUrltwo as getUploadActionUrltwo, getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth
, getTaskUrlById as getTaskUrlById, TEST_HOST, htmlEncode as htmlEncode, getupload_git_file as getupload_git_file, getcdnImageUrl as getcdnImageUrl,
turnbar,returnbar
, getTaskUrlById as getTaskUrlById, TEST_HOST, htmlEncode as htmlEncode, getupload_git_file as getupload_git_file, getcdnImageUrl as getcdnImageUrl
} from './UrlTool';
export { setmiyah as setmiyah } from './Component';

View File

@ -1,117 +0,0 @@
/* eslint-disable react/jsx-no-duplicate-props */
import React, { useState } from 'react';
import * as ReactDOM from 'react-dom';
import { Modal, Button } from 'antd';
import './index.scss';
InitModal.defaultProps = {
okText: '确认', //
cancelText: '取消', //
className: '', //
inputId: 'copyText', //ID
};
// 使
export default function DelModal(props) {
renderModal({ ...props, type: 'delete' })
}
// 使
export function Confirm(props) {
renderModal({ ...props, type: 'confirm' })
}
function renderModal(props) {
const { type, afterClose } = props;
const div = document.createElement('div');
document.body.appendChild(div);
function destroy() {
afterClose && afterClose();
const unmountResult = ReactDOM.unmountComponentAtNode(div);
if (unmountResult && div.parentNode) {
div.parentNode.removeChild(div);
}
}
function modalType(type) {
if (type === 'delete') {
return <InitModal
title="删除"
contentTitle="确定要删除吗?"
okText="确认删除"
{...props}
afterClose={destroy}
contentTitle={<React.Fragment>
<i className="red-circle iconfont icon-shanchu_tc_icon mr3"></i>
{props.contentTitle}
</React.Fragment>}
/>
} else if (type === 'confirm') {
return <InitModal title="选择" afterClose={destroy} {...props} />
} else {
return <InitModal title="选择" afterClose={destroy} {...props} />
}
}
function render() {
setTimeout(() => {
ReactDOM.render(
modalType(type),
div,
);
});
}
render();
}
//
function InitModal({
onCancel,
onOk,
title,
contentTitle,
content,
okText,
cancelText,
afterClose,
className,
}) {
const [visible, setVisible] = useState(true);
function onCancelModal() {
setVisible(false);
onCancel && onCancel()
}
function onSuccess() {
setVisible(false);
onOk && onOk();
}
return (
<Modal
visible={visible}
onCancel={onCancelModal}
afterClose={afterClose}
title={title}
className={`myself-modal ${className}`}
centered
footer={[
<Button type="default" key="back" onClick={onCancelModal}>
{cancelText}
</Button>,
<Button className="foot-submit" key="submit" onClick={onSuccess}>
{okText}
</Button>,
]}
>
<div>
{contentTitle && <p className="content-title">{contentTitle}</p>}
<p className="content-descibe">{content}</p>
</div>
</Modal>
)
}

View File

@ -1,63 +0,0 @@
.myself-modal {
.ant-modal-header {
padding: 9px 24px;
background: #f8f8f8;
border-bottom: 1px solid #eee;
}
.ant-modal-title {
text-align: left;
}
.ant-modal-close {
top: 0px !important;
}
.ant-modal-close-x {
font-size: 24px;
}
.ant-modal-body {
text-align: center;
}
.content-title {
display: flex;
justify-content: center;
align-items: center;
margin: 2rem 0 1rem !important;
font-size: 16px;
color: #333;
letter-spacing: 0;
line-height: 29px;
font-weight: 400;
}
.red-circle {
align-self: flex-start;
color: #ca0002;
font-size: 1.5rem !important;
}
.content-descibe {
font-size: 14px;
color: #666;
line-height: 33px;
font-weight: 400;
}
.ant-modal-footer {
padding: 2rem 0;
text-align: center;
border: 0;
.ant-btn {
width: 6rem;
}
}
.foot-submit {
margin-left: 3rem;
color: #df0002;
&:hover {
border-color: #df0002;
}
}
.ant-btn-default:hover,
.ant-btn-default:active,
.ant-btn-default:focus {
background: #f3f4f6;
color: #333;
border-color: #d0d0d0;
}
}

View File

@ -30,7 +30,7 @@ export default ({
cleanToc()
}
rs = rs.replace(/(__special_katext_id_\d+__)/g, (_match, capture) => {
const { type, expression } = math_expressions[capture];
const { type, expression } = math_expressions[capture]
return renderToString(_unescape(expression) || '', { displayMode: type === 'block', throwOnError: false, output: 'html' })
})
rs = rs.replace(/▁/g, "▁▁▁")

View File

@ -1,280 +0,0 @@
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">确实开源&nbsp;&nbsp;一脉传承</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">特色功能&nbsp;&nbsp;确实给力</p>
<table><tr>
<td>
<div className="feat_func_cont">
<div className="feat_fun_img"><img src={fun1} /></div>
<div>
<p>分布式协作开发</p>
<div>支持在线文件编辑&nbsp;&nbsp;<br />分支管理贡献统计<br />仓库复刻合并请求&nbsp;&nbsp;&nbsp;</div>
</div>
</div>
</td>
<td>
<div className="feat_func_cont">
<div className="feat_fun_img"><img src={fun2} /></div>
<div>
<p>一站式过程管理</p>
<div>支持疑修里程碑&nbsp;&nbsp;&nbsp;<br />通知提醒标签归档Wiki文档组织管理&nbsp;&nbsp;&nbsp;</div>
</div>
</div>
</td>
<td>
<div className="feat_func_cont">
<div className="feat_fun_img"><img src={fun3} /></div>
<div>
<p>高效流水线运维</p>
<div>提供轻量级工作流引擎<br />并支持自定义配置&nbsp;&nbsp;&nbsp;<br/>静态扫描制品构建&nbsp;&nbsp;&nbsp;</div>
</div>
</div>
</td>
<td>
<div className="feat_func_cont">
<div className="feat_fun_img"><img src={fun4} /></div>
<div>
<p>多层次代码分析</p>
<div>支持代码溯源分析&nbsp;&nbsp;&nbsp;<br />许可证风险分析开源漏洞检测和加固建议&nbsp;&nbsp;&nbsp;</div>
</div>
</div>
</td>
<td>
<div className="feat_func_cont">
<div className="feat_fun_img"><img src={fun5} /></div>
<div>
<p>多维度用户画像</p>
<div>支持开发活动统计&nbsp;&nbsp;&nbsp;<br />贡献日历能力建模<br />角色与专业定位分析&nbsp;&nbsp;&nbsp;</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">成果作用&nbsp;&nbsp;确实有效</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前端开发经验熟练使用GulpWebpack等构建工具<br />
2熟练掌握VUE或React编程有前端模块化组件化自动化开发经验者优先<br />
3精通jQueryAjaxJson等技术对VUENodeJs等技术有所涉及<br />
4熟悉前端开发技术(HTML5JSJSONXHTMLCSS3ES6)了解各项技术的相关标准并严格按照标准进行开发<br />
</div>
</div>
<div className="position right">
<p className="df"><img src={position} /><span className="ml10">后端开发工程师</span></p>
<div>
1全日制本科及以上学历计算机软件工程相关专业者优先<br />
23年以上Java开发相关经验扎实的Java编程基础参与过1个以上大/中型高并发高性能系统架构设计开发和调优<br />
3熟练掌握SpringSpringBootSpring MVCMyBatis等开源框架掌握MVC框架模式及BS架构<br />
4精通SQL熟练使用MySQLOracle等数据库并具有一定的SQL优化能力熟悉RedisMongoDB等常用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熟悉性能测试自动化测试安全测试其中一种或多种测试工具LoadRunnerJmeterSeleniumQTPRobotFirebugAppScanPyCharm等熟练运用工具从事过相关测试工作<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);

View File

@ -1,338 +0,0 @@
.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{
min-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;}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 859 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

View File

@ -124,9 +124,7 @@ 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,
type,status } = 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 } = 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%";
@ -152,25 +150,25 @@ class Activity extends Component{
<p className="percent_red" style={{width:`${third_per}`}}></p>
<p className="percent_green" style={{width:`${fourth_per}`}}></p>
</div>
<span>{data && data.issues_count}</span>
<span>{data && data.issues_count}</span>
</div>
</div>
<ul className="percentBox">
<li>
<span className="purple">{data && data.pr_count}</span>
<span className={type==="PullRequest" && status==="delay" ?`change active`:"change"} onClick={()=>this.changeTrends("PullRequest","delay")}>已处理的合并请求</span>
<span className="change" onClick={()=>this.changeTrends("PullRequest","delay")}>已处理的合并请求</span>
</li>
<li>
<span className="green">{data && data.new_pr_count}</span>
<span className={type==="PullRequest"&& status==="not_delay" ?`change active`:"change"} onClick={()=>this.changeTrends("PullRequest","not_delay")}>未处理的合并请求</span>
<span className="change" onClick={()=>this.changeTrends("PullRequest","not_delay")}>未处理的合并请求</span>
</li>
<li>
<span className="red">{data && data.close_issues_count}</span>
<span className={type==="Issue"&& status==="delay" ?`change active`:"change"} onClick={()=>this.changeTrends("Issue","delay")}>已关闭的</span>
<span className="change" onClick={()=>this.changeTrends("Issue","delay")}>已关闭的</span>
</li>
<li>
<span className="green">{data && data.open_issues_count}</span>
<span className={type==="Issue"&& status==="not_delay" ?`change active`:"change"} onClick={()=>this.changeTrends("Issue","not_delay")}>未处理的</span>
<span className="change" onClick={()=>this.changeTrends("Issue","not_delay")}>未处理的</span>
</li>
</ul>
</div>

View File

@ -14,20 +14,20 @@ class ActivityItem extends Component {
{/* 如果是版本发布 */}
{item.trend_type === "VersionRelease" ?
<p className="itemLine">
<Link to={`/${owner}/${projectsId}/releases`} className="font-16">{item.name}</Link>
<Link to={`/${owner}/${projectsId}/releases`} className="color-blue 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="font-16">{item.name}</Link>
<Link to={`/${owner}/${projectsId}/issues/${item.trend_id}`} className="color-blue 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="font-16">{item.name}</Link>
<Link to={`/${owner}/${projectsId}/pulls/${item.trend_id}`} className="color-blue font-16">{item.name}</Link>
<span className="activity_type">{item.trend_type}</span>
</p >
}

View File

@ -107,10 +107,6 @@
color: black;
cursor: pointer;
}
.change.active{
color: #466AFF !important;
}
.change:hover{
color: #466AFF;
color: #4183c4;
}

View File

@ -7,10 +7,10 @@ function CloneAddress({http_url , ssh_url , zip_url , tar_url}) {
const [ key , setKey ] = useState("HTTP");
return (
<div className="downMenu">
<div>
<div style={{borderBottom:"1px solid #eee"}}>
<Menu className="urlMenu" selectedKeys={[key]} mode={"horizontal"}>
<Menu.Item key="HTTP" onClick={(e)=>{setKey(e.key)}}>HTTP</Menu.Item>
{ssh_url && <Menu.Item key="SSH" onClick={(e)=>{setKey(e.key)}}>SSH</Menu.Item>}
<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">
{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.Item><a href={zip_url}>下载 ZIP</a></Menu.Item>
<Menu.Item><a href={tar_url}>下载 TAR.GZ</a></Menu.Item>
</Menu>
</div>
)

View File

@ -3,7 +3,6 @@ import { Dropdown} from 'antd';
import './branch.scss';
import SelectOverlay from './SelectOverlay';
import { findDOMNode } from 'react-dom';
import { turnbar } from 'educoder';
export default (({ projectsId , branch , owner , changeBranch , branchList , tagflag = true })=>{
const [ showValue , setShowValue ] = useState(branch);
@ -36,8 +35,7 @@ export default (({ projectsId , branch , owner , changeBranch , branchList , tag
function ChangeB(params) {
setVisible(false);
let en = turnbar(params);
changeBranch(en);
changeBranch(params);
}
const menu = (

View File

@ -66,10 +66,9 @@ function AddMember({getID,login,showNotification}){
};
function addCollaborator(){
if(source && source.length>0&&searchKey){
if(source && source.length>0){
getID && getID(id);
setSearchKey(undefined);
setID(undefined)
}else{
showNotification("请选择存在的用户!");
}
@ -80,7 +79,7 @@ function AddMember({getID,login,showNotification}){
<AutoComplete
dataSource={source}
value={searchKey}
style={{ width: 250 }}
style={{ width: 300 }}
onChange={changeInputUser}
onSelect={selectInputUser}
placeholder="搜索需要添加的用户..."
@ -92,8 +91,7 @@ function AddMember({getID,login,showNotification}){
onClick={addCollaborator}
className="ml15"
>
{/* <Icon type="plus" size="16"></Icon> */}
<i className="iconfont icon-tianjiafangda mr3"></i>
<Icon type="plus" size="16"></Icon>
添加成员
</Button>
</div>

View File

@ -276,36 +276,36 @@ li.ant-menu-item{
.-task-sidebar {
position: fixed;
width: 40px;
right: 30px;
right: 0;
bottom: 80px;
z-index: 10;
}
// @media screen and (max-width: 1920px){
// .-task-sidebar{
// right:220px;
// }
// }
// @media screen and (max-width: 1750px){
// .-task-sidebar{
// right:160px;
// }
// }
// @media screen and (max-width: 1650px){
// .-task-sidebar{
// right:115px;
// }
// }
// @media screen and (max-width: 1550px){
// .-task-sidebar{
// right:90px;
// }
// }
// @media screen and (max-width: 1450px){
// .-task-sidebar{
// right:45px;
// }
// }
@media screen and (max-width: 1920px){
.-task-sidebar{
right:220px;
}
}
@media screen and (max-width: 1750px){
.-task-sidebar{
right:160px;
}
}
@media screen and (max-width: 1650px){
.-task-sidebar{
right:115px;
}
}
@media screen and (max-width: 1550px){
.-task-sidebar{
right:90px;
}
}
@media screen and (max-width: 1450px){
.-task-sidebar{
right:45px;
}
}
@media screen and (max-width: 1200px){
.-task-sidebar{
right:0px;
@ -313,17 +313,17 @@ li.ant-menu-item{
}
}
.-task-sidebar>div {
height: 48px;
line-height: 48px;
height: 40px;
line-height: 40px;
box-sizing: border-box;
width: 48px;
width: 40px;
color: #999;
font-size: 20px;
text-align: center;
margin-bottom: 20px;
border-radius: 50%;
background: #FFFFFF;
box-shadow: 0px 0px 12px 5px rgba(208, 208, 208, 0.2);
box-shadow: 0px 0px 10px 1px #F1F1F1;
}
.-task-sidebar>div i {
@ -334,40 +334,36 @@ li.ant-menu-item{
color: #fff !important;
}
.-task-sidebar>div:hover{
background: #466AFF;
background: #1890FF;
box-shadow: 0px 0px 10px 2px #B6D0FC;
}
.helpBox{
width: 260px;
z-index: 103;
&.shareContent{
width: 160px;
}
.ant-popover-title{
font-size: 16px;
width: 200px;
}
.ant-popover-inner-content{
padding:0px;
}
p.titlecontent{
font-size: 16px;
font-size: 18px;
color: #333;
line-height: 20px;
padding:15px 20px;
}
.faqUl{
padding:10px 15px;
padding:0px 20px 10px;
max-height: 230px;
overflow-y: auto;
font-size: 13px;
li{
background: #F5F5F5;
border-radius: 20px;
padding:0px 15px;
padding:0px 20px;
color: #333;
height: 30px;
line-height: 30px;
margin-bottom: 3px !important;
height: 34px;
line-height: 34px;
margin-bottom: 10px;
a{
display: block;
overflow: hidden;
@ -383,18 +379,19 @@ 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;
@ -442,21 +439,3 @@ 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;
}
}
}

View File

@ -7,7 +7,7 @@ import './Component.scss';
import { getUser } from '../GetData/getData';
import axios from 'axios';
function Contributors({owner,projectsId,currentLogin}){
function Contributors({contributors,owner,projectsId,currentLogin}){
const [ menuList ,setMenuList ]= useState([]);
const [ list , setList ]= useState(undefined);
const [ total , setTotal ]= useState(0);
@ -16,18 +16,11 @@ function Contributors({owner,projectsId,currentLogin}){
const [ isSpin , setIsSpin ] = useState(false);
useEffect(()=>{
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=>{})
}
if(contributors && contributors.total_count>0){
setTotal(contributors.total_count);
setList(contributors.list);
}
},[contributors])
useEffect(()=>{
if(login){
@ -155,15 +148,15 @@ function Contributors({owner,projectsId,currentLogin}){
}
return(
total > 0 ?
<div className="halfs">
<Link to={`/${owner}/${projectsId}/contribute`} className="font-16 color-ooo hoverA">
<span>贡献者</span>
{ total > 0 && <span className="infoCount">{total}</span>}
{ contributors && contributors.total_count > 0 && <span className="infoCount">{contributors.total_count}</span>}
</Link>
<div className="attrPerson" onMouseLeave={()=>setVisibleFunc(false)}>
{
list && list.length>0 && list.map((item,key)=>{
total > 0 ?
list.map((item,key)=>{
return(
<Popover content={menu} visible={item.visible} overlayClassName="menuPanels" placement="top">
<Link key={key} to={`/${item.login}`}>
@ -172,9 +165,10 @@ function Contributors({owner,projectsId,currentLogin}){
</Popover>
)
})
:""
}
</div>
</div>:""
</div>
)
}
export default Contributors;

View File

@ -25,7 +25,7 @@ function DeleteBox({
>
<div className="desc">
<AlignCenter className="descMain"><i className="iconfont icon-shanchu_tc_icon mr10"></i>{content}</AlignCenter>
<p className="task-hide-2" style={{WebkitLineClamp:5}}>删除后未来事件将不会推送至此Webhook地址<span title={subTitle}>{subTitle}</span></p>
<p>{subTitle}</p>
</div>
</Modals>
)

View File

@ -1,10 +1,15 @@
import React, { useEffect, useState } from 'react';
import { Drawer , Tree , Spin } from 'antd';
import { turnbar} from 'educoder';
import './Component.scss';
import axios from 'axios';
const { TreeNode , DirectoryTree } = Tree;
function turnbar(str){
if(str && str.length>0 && str.indexOf("/")>-1){
return str.replaceAll('/','%2F');
}
return str;
}
function DrawerPanel({visible,onClose,branch,owner,projectsId,history, name , list}){
const [ treeData , setTreeData ] = useState(undefined);
const [ isSpin , setIsSpin ] = useState(true);

View File

@ -32,7 +32,7 @@ export default ({history}) => {
/>
</div>
:
<i className="iconfont icon-sousuo font-18 ml30" style={{color:"#a5a5a5"}} onClick={() => {
<i className="iconfont icon-sousuo font-18 color-grey-6 ml30" onClick={() => {
setOpenSearch(true)
}} />
}

View File

@ -1,41 +1,18 @@
import React, { useEffect, useState } from 'react';
import { FlexAJ } from '../Component/layout';
import { Divider } from 'antd';
import axios from 'axios';
function LanguagePower({owner,projectsId}){
function LanguagePower({languages}){
const [ array , setArray ] = useState(undefined);
useEffect(()=>{
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])
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 = "#";
@ -47,15 +24,13 @@ function LanguagePower({owner,projectsId}){
return str;
}
return(
(array && array.length > 0) ?
<div>
<Divider />
<p className="font-16 color-ooo aboutSubTitle">开发语言</p>
<div className="progress">
{
array && array.map((item,key)=>{
return(
<span key={item.id||key} style={{width:item.percent,backgroundColor:item.color}}></span>
<span style={{width:item.percent,backgroundColor:item.color}}></span>
)
})
}
@ -66,13 +41,14 @@ function LanguagePower({owner,projectsId}){
{
array.map((item,key)=>{
return(
<span key={item.id||key}><i className="zero" style={{backgroundColor:`${item.color}`}}></i><span>{item.name}</span><span>{item.percent}</span></span>
<span><i className="zero" style={{backgroundColor:`${item.color}`}}></i><span>{item.name}</span><span>{item.percent}</span></span>
)
})
}
</FlexAJ>
}
</div>:""
</div>
)
}
export default LanguagePower;

View File

@ -29,12 +29,12 @@
font-weight: 500;
color: #FFFFFF;
margin-top: 60px;
padding-left: 20px;
}
.markdown-body{
box-shadow: 0px 0px 17px rgba(0,0,0,0.2);
border-radius: 4px;
margin-top: 17px!important;
color: white;
}
.nContent{
padding:20px 34px;

View File

@ -3,42 +3,25 @@ import { Modal , Button } from 'antd';
import './Index.scss';
import '../../css/index.scss';
import RenderHtml from '../../../components/render-html';
// import cookie from 'react-cookies';
import axios from 'axios';
import cookie from 'react-cookies';
function SystemNotice({showNotice,system_notification,history,login,hideSystemNotice}){
function SystemNotice({system_notification,history}){
const [ visible , setVisible ] = useState(false);
useEffect(()=>{
if((system_notification && !system_notification.is_read) && showNotice && login){
if(system_notification && !cookie.load('notice_stage')){
setVisible(true);
}
},[system_notification,login])
},[system_notification,history.location])
function sureContinue() {
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=>{
setVisible(false);
hideSystemNotice();
}).catch(error=>{
setVisible(false);
hideSystemNotice();
})
}else{
setVisible(false);
hideSystemNotice();
}
// cookie.remove('notice_stage');
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 (

View File

@ -23,13 +23,9 @@ $(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(){
@ -40,19 +36,9 @@ 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)=>{
@ -73,46 +59,31 @@ function SiderBar() {
</ul>
</div>
}
return (
<div className={"-task-sidebar"} >
{/* 平台反馈 */}
<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>
{/* 帮助 */}
<ShareModal visible={visible} urlValue={window.location.href} onCancel={()=>setVisible(false)}/>
{
data && data.length > 0 && (data[0] && data[0].question) ?
<Popover title="帮助" content={content(data)} overlayClassName="helpBox" placement={"left"}>
<Popover content={content(data)} overlayClassName="helpBox" placement={"left"}>
<div className="feedback">
<i className="iconfont icon-bangzhu1 font-22"></i>
<i className="iconfont icon-bangzhu 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-fenxiang"></i>
<i className="iconfont icon-fenxiang1"></i>
</div>
</Popover>
{/* 返回顶部 */}
<Tooltip title="返回顶部" placement={"left"} overlayClassName="tooltipBox">
<div className="gotop">
<div className="gotop">
<Tooltip title="返回顶部" placement={"right"}>
<a><i className="iconfont icon-huidaodingbu1"></i></a>
</div>
</Tooltip>
</Tooltip>
</div>
</div>
)
}

View File

@ -17,9 +17,9 @@ function SiderBarShareModal({visible,urlValue,onCancel}) {
value={urlValue}
size={200}
fgColor="#000000"
style={{margin:"0 20px 20px"}}
style={{margin:"20px"}}
/>}
<p>打开微信扫一扫点击右上角菜单即可将网页分享至朋友圈</p>
<p>打开微信扫一扫,点击右上角菜单即可将网页分享至朋友圈</p>
</div>
</Modal>
)

View File

@ -5,7 +5,7 @@ const Nav = styled.div`{
background-color:#fff;
padding:20px 30px;
border-bottom:1px solid #eee;
font-size:18px;
font-size:16px;
color:#333;
display:flex;
justify-content: space-between;

View File

@ -7,8 +7,6 @@ export const Banner = styled.div`{
border-bottom:1px solid #eee;
background-color:#fff;
border-radius:5px 5px 0px 0px;
justify-content: space-between;
display: flex;
}`
export const AlignCenterBetween = styled.div`{
display:flex;
@ -73,8 +71,8 @@ export const Blueline = styled.a`{
height:30px;
line-height:28px;
border-radius:2px;
border:1px solid #466AFF;
color:#466AFF;
border:1px solid rgba(80,145,255,1);
color:rgba(80,145,255,1);
padding:0px 12px;
display:inline-block;
}`
@ -117,8 +115,7 @@ export const Blueback = styled.a`{
height:30px;
line-height:30px;
border-radius:2px;
// background-color:rgba(80,145,255,1);
background-color:#466AFF;
background-color:rgba(80,145,255,1);
color:#fff!important;
padding:0px 12px;
display:inline-block;

View File

@ -36,15 +36,15 @@ function About(props, ref) {
const [ disabled, setDisabled ] = useState(false);
const [ typeFlag, setTypeFlag] = useState(false);
const isPermission = props.projectDetail && props.projectDetail.permission && props.projectDetail.permission!=="Reporter";
const AuthorLogin = props.projectDetail && props.projectDetail.author && props.projectDetail.author.login;
const CurrentLogin = props.current_user && props.current_user.login;
useEffect(()=>{
if(isPermission){
if(CurrentLogin === AuthorLogin){
auth('get');
}else{
setIsSpining(false);
}
},[isPermission,CurrentLogin])
},[AuthorLogin,CurrentLogin])
function auth(type){
const url = `/${owner}/${projectsId}/ci_authorize.json`;
@ -136,7 +136,7 @@ function About(props, ref) {
params:{password:authorityVal}
}).then(result=>{
setIsSpining(false);
if(result && result.data.status === 0){
if(result){
setStep(result.data.step);
}
}).catch(error=>{setIsSpining(false)});
@ -149,10 +149,7 @@ function About(props, ref) {
axios.post(url).then(result=>{
setIsSpining(false);
if(result && result.data.status === 0){
props.history.push({
pathname: `/${owner}/${projectsId}/devops`,
state:{open_devops:true}
});
props.history.push(`/${owner}/${projectsId}/devops`);
// open_devops
let { changeOpenDevops } = props;
changeOpenDevops && changeOpenDevops(true);
@ -170,17 +167,17 @@ function About(props, ref) {
<img src={activate} alt="" width="250px" />
<P>定义DevOps工作流帮助您检测bug发布代码</P>
{
!isPermission ?
CurrentLogin !== AuthorLogin ?
<div className="noOperation">DevOps开启功能暂未对项目创建者以外的角色开放可以联系项目创建者进行开启开启后便可查看构建信息</div>:""
}
<a href={"https://forum.trustie.net/forums/3110/detail"} target="_blank" style={{ color: "#5091FF"}}>
了解什么是DevOps
</a>
<a href={"https://forum.trustie.net/forums/3080/detail"} target="_blank" style={{ color: "#5091FF"}}>
如何使用引擎Engine功能
如何使用DevOps
</a>
{
isPermission ?
AuthorLogin === CurrentLogin ?
<React.Fragment>
{
step === 0 && !typeFlag ?

View File

@ -1,7 +1,6 @@
import React from 'react';
import { Table , Popconfirm } from 'antd';
import { Link } from 'react-router-dom';
import { turnbar } from "educoder";
// const STATUS = {
// running:"",
@ -11,6 +10,12 @@ import { turnbar } from "educoder";
// killed:"",
// pending:""
// }
function turnbar(str){
if(str && str.length>0 && str.indexOf("/")>-1){
return str.replaceAll('/','%2F');
}
return str;
}
function renderTableStatus(status) {
switch (status) {
case "running":

View File

@ -17,7 +17,7 @@ function Sure({datas , name , saveFunc , sureSubmit , loading}){
return(
<div>
<div style={{padding:"0px 15px 15px 15px"}}>
水线名称{name}
工作流名称{name}
</div>
<div className="editorBody" style={{marginTop:"0px"}}>
<Editors value={value} theme={"vs-grey"} height={"600px"} visible/>

View File

@ -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>

View File

@ -1,4 +1,4 @@
import React from 'react';
import React , { useEffect } from 'react';
import { WhiteBack } from '../Component/layout';
import './ops.scss';
@ -7,7 +7,7 @@ import Loadable from 'react-loadable';
import Loading from '../../Loading';
const About = Loadable({
loader: () => import('./subIndex'),
loader: () => import('./About'),
loading: Loading,
})
const New = Loadable({
@ -66,8 +66,7 @@ export default ((props)=>{
{/* 原本的两种合为一个 */}
<Route path="/:owner/:projectsId/devops"
render={
// (p) =>{return( p.location && p.location.state && p.location.state.open_devops?<Dispose {...props} {...p}/>:<About {...props} {...p}/>)}
(p) =>{return(<About {...props} {...p}/>)}
(p) =>{return( p.location.state.open_devops?<Dispose {...props} {...p}/>:<About {...props} {...p}/>)}
}
></Route>
</Switch>

View File

@ -103,8 +103,8 @@ function Params(props){
<New visble={visible} successFunc={successFunc} CancelFunc={CancelFunc} editList={editList}/>
<Banner>
<FlexAJ>
<span className="font-18">引擎 - 参数管理</span>
<Link to={{pathname:`/${owner}/${projectsId}/devops`,state:{open_devops:true}}} className="font-14 color-grey-9 ml20">返回</Link>
<span className="font-18">工作流 - 参数管理</span>
<Link to={`/${owner}/${projectsId}/devops`} className="font-14 color-grey-9 ml20">返回</Link>
</FlexAJ>
</Banner>
<Div className="disposeList">

View File

@ -126,7 +126,7 @@ function Mould(props){
<div>
<New wrappedComponentRef={(f) => childRef.current = f} ref={childRef} visible={visible} onCancel={()=>setVisible(false)} onOk={onOk}></New>
<Banner>
<FlexAJ><span>引擎 - 模板管理</span><Link to={`/${owner}/${projectsId}/devops`} className="font-14 color-grey-9">返回</Link></FlexAJ>
<FlexAJ><span>工作流 - 模板管理</span><Link to={`/${owner}/${projectsId}/devops`} className="font-14 color-grey-9">返回</Link></FlexAJ>
</Banner>
<Div className="disposeList">
<FlexAJ>

View File

@ -5,7 +5,7 @@ import { Menu, Popconfirm } from "antd";
import { TagsLine } from "../Component/OpsStatus";
import { Time } from "../Utils/Time";
import { truncateCommitId } from "../common/util";
import { getImageUrl } from 'educoder';
import { getUrl } from 'educoder';
const SubMenu = Menu.SubMenu;
const Img = styled.img`
@ -70,7 +70,7 @@ export default ({ data, repeatSet , chooseSteps }) => {
<div>
<FlexAJ className="leftheader">
<AlignCenter>
<Img src={getImageUrl(`/${data && data.author && data.author.image_url}`)} />
<Img src={getUrl(`/images/${data && data.author && data.author.image_url}`)} />
{data && data.started &&
<span className="nest">
开始时间<span> {data.started}</span>

View File

@ -12,7 +12,7 @@ function ServiceModal({sureModal}){
<div className="mt30" style={{textAlign:"center"}}>
<Radio.Group value={type} onChange={changeType}>
<Radio value={1}>自有服务器</Radio>
<Radio value={2}>GitLink服务器</Radio>
<Radio value={2}>Trustie服务器</Radio>
</Radio.Group>
<p className="mt30"><Button type="primary" onClick={()=>sureModal(type)}>下一步</Button></p>
</div>

View File

@ -290,7 +290,7 @@ function Structure(props,ref){
<Banner>
<FlexAJ>
<span>构建列表</span>
<Link to={{pathname:`/${owner}/${projectsId}/devops`,state:{open_devops:true}}} className="font-15 color-grey-9">返回</Link>
<Link to={`/${owner}/${projectsId}/devops`} className="font-15 color-grey-9">返回</Link>
</FlexAJ>
</Banner>
<Div>

View File

@ -275,10 +275,7 @@ function disposePipeline(props){
...params
}).then(result=>{
if(result){
props.history.push({
pathname:`/${owner}/${projectsId}/devops`,
state:{open_devops:true}
});
props.history.push(`/${owner}/${projectsId}/devops`);
}
setLoading(false);
}).catch(error=>{

View File

@ -1,13 +0,0 @@
import React from 'react';
import About from './About';
import Dispose from './Dispose';
function SubIndex(props) {
return(
props && props.open_devops ?
<Dispose {...props} />
:
<About {...props} />
)
}
export default SubIndex;

View File

@ -1,8 +1,7 @@
import axios from 'axios';
//
export const getBranch = async (id,owner)=>{
let res = await axios.get(`/${owner}/${id}/branches.json`);
return res&&res.data;
return (await axios.get(`/${owner}/${id}/branches.json`)).data;
}
//
export const getTag = async (id,owner)=>{

View File

@ -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);
useEffect(()=>{
if(!visible){
setFieldsValue({
code:undefined,
role:"developer"
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=>{})
}
})
}
},[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();
}
})
}
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:" "},
{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));
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>
)
})
)

View File

@ -19,44 +19,48 @@ function Footer(){
return(
<div>
{value && showhtml(value)}
<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>
</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 20072021 Gitlink & IntelliDE <br/>ICP 17009477</p>
// </div> */}
)
}
export default Footer;

View File

@ -2,8 +2,7 @@ import React, { Component } from 'react';
import AccountProfile from "../../modules/user/AccountProfile";
import { getImageUrl } from 'educoder'
import axios from 'axios';
import cookie from 'react-cookies';
import { notification , Dropdown ,Popover, Menu,Badge } from 'antd';
import { Input , notification , Dropdown ,Popover, Menu,Badge, Button } from 'antd';
import { Link } from 'react-router-dom';
import LoginDialog from '../../modules/login/LoginDialog';
@ -15,8 +14,10 @@ import CheckProfile from '../Component/ProfileModal/Profile';
import './header.scss';
import NoticeContent from './NoticeContent';
import MainLogo from './img/logo.png';
const $ = window.$
// TODO 这部分脚本从公共脚本中直接调用
const { Search } = Input;
let old_url;
window._header_componentHandler = null;
// 非trustie链接则新开页跳转
@ -42,8 +43,8 @@ class NewHeader extends Component {
setevaluatinghides: false,
occupation: 0,
mydisplay: false,
// headtypesonClickbool: false,
// headtypess: "/",
headtypesonClickbool: false,
headtypess: "/",
settings: null,
visiblemyss: false,
openSearch:false,
@ -54,6 +55,28 @@ 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) {}
@ -75,17 +98,11 @@ class NewHeader extends Component {
educoderlogin = () => {
//登录账号
if(window.location.pathname === "/"){
window.location.href="/login";
}else{
this.setState({
isRender: true
})
}
this.setState({
isRender: true
})
}
educoderloginysl = () => {
//退出账号时清除登录页面的下次自动登录(用户再次打开登录页面时下次自动登录框不勾选)
cookie.remove("autologin");
//退出账号
var url = `/accounts/logout.json`;
axios.get((url)).then((result) => {
@ -137,12 +154,12 @@ class NewHeader extends Component {
AccountProfiletype: false
})
};
// headtypesonClick = (url, bool) => {
// this.setState({
// headtypess: url,
// headtypesonClickbool: bool,
// })
// }
headtypesonClick = (url, bool) => {
this.setState({
headtypess: url,
headtypesonClickbool: bool,
})
}
//获取数据为空的时候
gettablogourlnull = () => {
this.setState({
@ -196,18 +213,12 @@ class NewHeader extends Component {
matchpaths = (url) => {
const { match } = this.props;
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.url;
}else{
str = match.path;
}
if (url && (str === url || (str === url+'/'))) {
return true
}else {
return false
if(url){
if (match.path.indexOf(url) > -1) {
return true
}else {
return false
}
}
}
@ -268,18 +279,96 @@ class NewHeader extends Component {
};
render() {
const { resetUserInfo ,showNotification,publicNav} = this.props;
const { match ,resetUserInfo ,showNotification} = 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={publicNav ? `newHeaders publicNav`:`newHeaders`} id="nHeader">
<div className="newHeaders" id="nHeader">
<div className="headerContent">
{isRender === true ?
<LoginDialog
@ -294,18 +383,10 @@ class NewHeader extends Component {
{...this.props}
{...this.state}
/> : ""}
<div style={{width:"78px"}}>
{
publicNav &&
<a href={'https://www.ccf.org.cn/'} className={"fl"}>
<img src={MainLogo} alt="ccf" width="63px"/>
</a>
}
</div>
{
settings && settings.nav_logo_url ?
<a href={settings && settings.new_course.default_url} className={"fl mr50"}>
<img alt="可控开源社区" className="logoimg" src={getImageUrl(`/${settings.nav_logo_url}`)}></img>
<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>
:
""
@ -317,26 +398,27 @@ class NewHeader extends Component {
{
settings.navbar && settings.navbar.map((item, key) => {
var new_link = item.link;
// var user_login = current_user && current_user.login;
var is_hidden = item.hidden;
// if (new_link && (new_link.indexOf("courses") > -1 || new_link.indexOf("contests") > -1)) {
// if (user_login) {
// if (new_link.indexOf("courses") > -1) {
// new_link = new_link.replace(/courses/g, user_login + "/courses")
// } else if (new_link.indexOf("contests") > -1) {
// new_link = new_link.replace(/contests/g, user_login + "/contests")
// }
// } else {
// is_hidden = true
// }
// }
// if (user_login && (new_link && new_link.indexOf("homes") > -1)) {
// new_link = new_link.replace(/homes/g, user_login + "/user_activities")
// }
var user_login = current_user && current_user.login;
var is_hidden = item.hidden
if (new_link && (new_link.indexOf("courses") > -1 || new_link.indexOf("contests") > -1)) {
if (user_login) {
if (new_link.indexOf("courses") > -1) {
new_link = new_link.replace(/courses/g, user_login + "/courses")
} else if (new_link.indexOf("contests") > -1) {
new_link = new_link.replace(/contests/g, user_login + "/contests")
}
} else {
is_hidden = true
}
}
if (user_login && (new_link && new_link.indexOf("homes") > -1)) {
new_link = new_link.replace(/homes/g, user_login + "/user_activities")
}
var waiLian = (new_link && str.filter(item=>new_link.indexOf(item)>-1) );
var wl = waiLian && waiLian.length>0;
return (
<li key={key} className={`${this.matchpaths(new_link) === true ? 'pr active' : 'pr'}`} style={{display:!is_hidden ? 'flex' : 'none'} }>
<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' }}>
<a href={new_link} target={wl ? "_self":"_blank"}>{item.name}</a>
</li>
)
@ -351,7 +433,7 @@ 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">
<img src={require(`./img/add.png`)} alt="" width="16px" className="mr15 ml30"/>
<i className="iconfont icon-tianjiafangda color-grey-6 ml30 mr15"></i>
</Dropdown>:""
}
@ -366,7 +448,7 @@ class NewHeader extends Component {
>
<Link to={"/settings/notice"} className="message-icon">
{current_user && <Badge count={current_user.message_unread_total}>
<img src={require(`./img/ring.png`)} alt="" width="16px" className="ml15 mr15"/>
<i className="iconfont icon-xiaoxilingdang color-grey-6 ml15 mr15"></i>
</Badge>}
</Link>
</Popover>
@ -375,14 +457,10 @@ class NewHeader extends Component {
</div>
{!user || (user && !user.login) ?
<span className="font-15 ml30">
<a onClick={() => this.educoderlogin()} className="mr5 color-white">登录</a>
<a onClick={() => this.educoderlogin()} className="mr5 color-grey-6">登录</a>
{
(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>
:""
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>
}
</span>
:

View File

@ -23,9 +23,6 @@ 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]);
@ -153,26 +150,23 @@ function NoticeContent({ visible, showNotification, resetUserInfo, current_user:
function changeReadMark(item) {
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);
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);
}
}
setClickItem(item);
}
return (
@ -190,11 +184,11 @@ function NoticeContent({ visible, showNotification, resetUserInfo, current_user:
className='hoverNotice-body' // className
onPullRefresh={() => { setNoticePage(noticePage + 1); }} //ajaxfunction
// type={2} //
count={noticeUnreadList&&noticeUnreadList.length} //
count={noticeUnreadList.length} //
pageSize={10} //
>
{
Array.isArray(noticeUnreadList)&& noticeUnreadList.map(item => {
noticeUnreadList.map(item => {
return (
<div key={item.id + Math.random()} className="noticeCont-back" onClick={() => { readItem(item) }}>
<div className={`noticeCont ${item.notification_url?'pointer':''}`}>
@ -225,12 +219,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 ${item.notification_url ? 'pointer' : ''}`}>
<div className="noticeCont">
<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: item.content }}></span>
<span className="content-span atme-cont-span" dangerouslySetInnerHTML={{ __html: "<b>" + (item.sender ? item.sender.name : '') + "</b>&nbsp;&nbsp;&nbsp;" + item.content + " 中@我" }}></span>
<span className="timeSpan">{item.time_ago}</span>
</div>
</div>

View File

@ -27,7 +27,7 @@
margin-left: 15px;
}
.ant-dropdown-menu.currentMenu{
.currentMenu{
width: 120px;
text-align: center;
padding:0px;
@ -62,8 +62,7 @@
color: #666;
&:hover{
color: #fff;
// background: #4CACFF;
background: #829BFF;
background: #4CACFF;
}
}
}
@ -128,9 +127,6 @@
width: 110px;
text-align: right;
}
.ant-form-explain{
position: absolute;
}
}
// 右上角小铃铛单独样式
@ -267,100 +263,3 @@
.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;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 615 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

View File

@ -22,10 +22,11 @@ const ProjectIndex = Loadable({
loading: Loading,
});
const ProjectHome = Loadable({
loader: () => import("./Main/projecthome/Index"),
loading: Loading,
});
// 项目详情放在用户和组织下作为二级菜单存在
// const ProjectDetail = Loadable({
// loader: () => import("./Main/Detail"),
// loading: Loading,
// });
class Index extends Component {
@ -59,17 +60,23 @@ class Index extends Component {
<ProjectNew {...this.props} {...props} />
)}
></Route>
{/* <Route
path="/:owner/:projectsId"
render={(props) => (
<ProjectDetail {...this.props} {...props} />
)}
></Route> */}
<Route
path="/explore/all"
path="/explore"
render={(props) => (
<ProjectIndex {...this.props} {...props} />
)}
></Route>
<Route
path="/explore"
path="/"
render={(props) => (
<ProjectHome {...this.props} {...props} />
<ProjectIndex {...this.props} {...props} />
)}
></Route>
</Switch>
@ -83,3 +90,10 @@ export default withRouter(
parentSelector: ".newMain",
})(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Index))))
);
// export default withRouter(
// ImageLayerOfCommentHOC({
// imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
// parentSelector: ".newMain",
// })(Index)
// );

View File

@ -1,92 +0,0 @@
import React, { useState, useEffect } from 'react';
import { Modal, Button, } from 'antd';
import { Base64 } from 'js-base64';
import './index.scss';
import { Link } from 'react-router-dom';
import { getImageUrl } from 'educoder'
import axios from 'axios';
const identify = {
manager: "管理员",
developer: "开发者",
reporter: "报告者",
owner: "所有者",
}
function Invite({ history, current_user, match, projectDetail, showNotification }) {
if (!current_user.login) {
let { pathname, search } = window.location;
window.location.href = `/login?go_page=${pathname}${search}`;
}
let permission = projectDetail && projectDetail.permission;
const { projectsId, owner } = match.params;
let inviteString = window.location.search && window.location.search.split('?invite=')[1];
let data = inviteString && JSON.parse(Base64.decode(inviteString));
const [detail, setDetail] = useState({});
const [visible, setVisible] = useState(true);
useEffect(() => {
if (permission && detail.role && detail.role == permission.toLocaleLowerCase() || permission == 'Owner') {
showNotification(`您已经是${identify[detail.role]}`)
setTimeout(() => {
history.push(`/${owner}/${projectsId}`);
}, 2000)
} else {
setVisible(true)
}
}, [permission, detail.role]);
useEffect(() => {
const url = `/${owner}/${projectsId}/project_invite_links/show_link.json?invite_sign=${data.sign}`;
axios.get(url).then(res => {
if (res && res.data) {
setDetail(res.data);
} else {
showNotification('查询邀请链接失败');
}
})
}, [])
function accept() {
const url = `/${owner}/${projectsId}/project_invite_links/redirect_link.json?invite_sign=${data.sign}`;
axios.post(url).then(res => {
if (res && res.data.message == 'success') {
if (detail.is_apply) {
setVisible(false);
Modal.success({ content: '提交申请成功,请等待该仓库管理员审核' });
} else {
history.push(`/${owner}/${projectsId}`);
}
}
}).catch(error => { })
}
return (
<div className="">
{data && <Modal
visible={visible}
className="invite_development"
title={<div className="ownerImage"><img src={detail.project && getImageUrl(detail.project.owner.image_url)} /></div>}
width="548px"
closable={true}
onCancel={() => { setVisible(false); history.push(`/${current_user.login}`) }}
centered
okText={'接受'}
cancelText={'拒绝'}
onOk={accept}
maskClosable={false}
>
<Link className="invite_project link" target="_blank" to={`/${data.ownerLogin}/${data.projectId}`}>{detail.project && detail.project.owner.name}/{detail.project && detail.project.name}</Link>
<div className="invite_content">
<Link className="link" to={`/${detail.user && detail.user.login}`}>{detail.user && detail.user.name}</Link> {identify[detail.role]}
是否接受邀请
</div>
</Modal>}
</div>
)
}
export default Invite;

View File

@ -1,100 +0,0 @@
.invite_development {
font-family: PingFang SC;
height: 366px;
background-image: linear-gradient(
359.37deg,
#ebf3ff 0%,
#eff5ff 55.01%,
#cfdeff 100%
);
border: 1.5px solid #ffffff;
border-radius: 4px;
.ant-modal-close{
top:0 !important;
}
.ant-modal-close-x{
font-size: 30px;
color: #666;
width: 48px;
height: 48px;
line-height: 48px;
transform: scaleX(1.05);
}
.ant-modal-content {
background-color: inherit;
}
.ant-modal-header {
background: inherit;
border: 0;
padding-bottom: 0;
}
.ownerImage {
position: relative;
top:-66px;
width: 100px;
height: 100px;
background-color: #e9f1ff;
border: 1px solid #ffffff;
border-radius: 50%;
margin:0 auto;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
img{
width: 100%;
}
}
.invite_project {
display: block;
margin: 0 auto;
font-weight: 500;
font-size: 20px;
line-height: 22px;
text-align: center;
margin-bottom: 30px;
}
.invite_content {
width: 422px;
padding: 24px 48px;
background-color: rgba(225, 231, 255, 0.71);
border-radius: 4px 4px 0px 0px;
margin: 10px auto;
font-weight: 500;
font-size: 17px;
line-height: 32px;
text-align: center;
color: #151d40;
}
.link {
cursor: pointer;
color: $primary-color;
&:hover {
color: $primary-color-hover;
}
}
.ant-modal-footer {
text-align: center;
border: 0;
padding-bottom: 55px;
button {
width: 150px;
height: 42px;
border-radius: 5px;
font-size: 15px;
&:first-child {
background-color: rgba(196, 0, 14, 0.07);
border: 1px solid;
border-color: #f60011;
color: #f60011;
&:hover {
opacity: 0.75;
}
}
& + button {
margin-left: 30px;
}
}
}
}

View File

@ -1,7 +1,7 @@
import React , { useEffect , useState } from 'react';
import { WhiteBack , Box , LongWidth , ShortWidth , Gap , AlignCenter , FlexAJ } from '../Component/layout';
import { Dropdown , Menu , Divider , Spin, Button , Typography } from 'antd';
import { getImageUrl , turnbar , returnbar } from "educoder";
import { getImageUrl } from "educoder";
import { Link } from 'react-router-dom';
import { truncateCommitId } from "../common/util";
import CloneAddress from '../Branch/CloneAddress';
@ -26,6 +26,20 @@ import RenderHtml from '../../components/render-html';
/**
* projectDetail.type:0是托管项目1是镜像项目2是同步镜像项目(为2时不支持在线创建在线上传在线修改在线删除创建合并请求等功能)
*/
const { Paragraph } = Typography;
function turnbar(str){
if(str && str.length>0 && str.indexOf("/")>-1){
return str.replaceAll('/','%2F');
}
return str;
}
function returnbar(str){
if(str && str.length>0 && str.indexOf("%2F")>-1){
return str.replaceAll('%2F','/');
}
return str;
}
function CoderDepot(props){
const [ projectDetail , setProjectDetail ]= useState(undefined);
const [ inviteCode , setInviteCode ] = useState(undefined);
@ -75,8 +89,6 @@ function CoderDepot(props){
}
if(i && i.length === 0){
setIssuesFlag(false);
console.log(bannerList);
}
}
},[bannerList])
@ -110,10 +122,13 @@ function CoderDepot(props){
setTreeValue(url);
getFileInfo(url,branchName);
setType("file");
// getReadmeInfo(url,branchName);
// setReadme(undefined);
}else{
setTreeValue(undefined);
getDirInfo(branchName || defaultBranch);
setType("dir");
// getReadmeInfo('', branchName || defaultBranch);
}
}
},[projectsId,owner,pathname,defaultBranch])
@ -123,7 +138,7 @@ function CoderDepot(props){
if(result && result.data){
const release = {
"list":result.data.releases,
"total_count":result.data.releases && result.data.releases.length
"total_count":result.data.releases.length
}
setReleaseVersions(release);
}
@ -154,7 +169,7 @@ function CoderDepot(props){
const url = `/${owner}/${projectsId}/entries.json`;
axios.get(url, {
params: { ref:branch}
params: { ref: branch }
}).then((result) => {
if (result) {
setCommitCount(result.data.commits_count);
@ -182,7 +197,7 @@ function CoderDepot(props){
let ele = document.getElementById("ptxt");
if(ele){
let h = ele.offsetHeight;
if( h > 36 ) setHideBtn(true);
if( h > 35 ) setHideBtn(true);
}
}
},[projectDetail,lastCommit])
@ -192,7 +207,7 @@ function CoderDepot(props){
const url = `/${owner}/${projectsId}/sub_entries.json`;
axios.get(url, {
params:{
filepath:returnbar(path),
filepath:path,
ref:ref || branchName,
type
}
@ -224,9 +239,9 @@ function CoderDepot(props){
//
function changeBranch(value){
let checkvalue = value;
let u = `/${owner}/${projectsId}${checkvalue && `/tree/${checkvalue}`}${treeValue ? `/${treeValue}`:""}`;
props.history.push(u);
let checkvalue = turnbar(value);
let url = `/${owner}/${projectsId}${value && `/tree/${checkvalue}`}${treeValue ? `/${treeValue}`:""}`;
props.history.push(url);
}
//
@ -264,7 +279,6 @@ function CoderDepot(props){
//
function returnUlr(url){
let enBranch = turnbar(branchName);
setType('dir');
props.history.push(`/${owner}/${projectsId}/tree${enBranch?`/${enBranch}`:""}/${url}`);
}
//
@ -272,9 +286,8 @@ function CoderDepot(props){
if(type!=="submodule"){
let enBranch = branchName || defaultBranch;
let checkvalue = turnbar(enBranch);
let enPath = turnbar(path);
setType(type);
props.history.push(`/${owner}/${projectsId}${`/tree/${checkvalue}`}${enPath?`/${enPath}`:""}`);
props.history.push(`/${owner}/${projectsId}${`/tree/${checkvalue}`}${path?`/${path}`:""}`);
}
}
@ -306,16 +319,16 @@ function CoderDepot(props){
const downloadMenu = (
<CloneAddress
http_url={projectDetail && projectDetail.clone_url}
ssh_url = {(projectDetail && props && props.platform) && projectDetail.ssh_url}
zip_url={(props && props.platform) && zip_url}
tar_url={(props && props.platform) && tar_url}
ssh_url = {projectDetail && projectDetail.ssh_url}
zip_url={zip_url}
tar_url={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);
@ -324,21 +337,12 @@ 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";
const { current_user } = props;
const baseOper = current_user && current_user.login && issuesFlag;
const baseOperate = projectDetail && projectDetail.permission && projectDetail.permission !=="Reporter" && projectDetail.type !== 2 && pullsFlag && props.platform;
const baseOperate = projectDetail && projectDetail.permission && projectDetail.permission !=="Reporter" && projectDetail.type !== 2 && pullsFlag;
const fileOperate = type === "dir" && projectDetail && projectDetail.type !== 2 && ((projectDetail.permission && projectDetail.permission !=="Reporter") || (current_user && current_user.admin));
return(
@ -388,7 +392,7 @@ function CoderDepot(props){
<span>分支<span className="color-grey-6">{branchName || defaultBranch}</span></span>
}
</div>
{
{
treeValuePath && treeValuePath.length > 0 ?
<Path
identifier={projectDetail && projectDetail.identifier}
@ -400,50 +404,36 @@ function CoderDepot(props){
:
<React.Fragment>
<AlignCenter className="mr20">
{
props.platform ?
<Link to={`/${owner}/${projectsId}/branches`} className="iconBtn">
<i className="iconfont icon-master_icon font-16"></i>
<span>分支</span>
<span>{projectDetail && projectDetail.branches_count}</span>
</Link>
:
<span>
<i className="iconfont icon-master_icon font-16 color-grey-6"></i>
<span className="ml3 color-grey-6">分支</span>
<span className="ml3">{projectDetail && projectDetail.branches_count}</span>
</span>
}
<Link to={`/${owner}/${projectsId}/branches`} className="iconBtn">
<i className="iconfont icon-master_icon font-16"></i>
<span>分支</span>
<span>{projectDetail && projectDetail.branches_count}</span>
</Link>
</AlignCenter>
<AlignCenter className="mr20">
{
props.platform ?
<Link to={`/${owner}/${projectsId}/tags`} className="iconBtn">
<i className="iconfont icon-biaoqianicon font-16"></i>
<span>标签</span>
<span>{projectDetail && projectDetail.tags_count}</span>
</Link>:
<span>
<i className="iconfont icon-biaoqianicon font-16 color-grey-6"></i>
<span className="ml3 color-grey-6">标签</span>
<span className="ml3">{projectDetail && projectDetail.tags_count}</span>
</span>
}
<i className="iconfont icon-biaoqianicon font-16"></i>
<span>标签</span>
<span>{projectDetail && projectDetail.tags_count}</span>
</Link>
</AlignCenter>
</React.Fragment>
}
</AlignCenter>
<AlignCenter className="depotBtn">
<div className="addOptionBtn">
{
baseOperate &&
<CheckProfile {...props} sureFunc={()=>urlLink(`/${owner}/${projectsId}/compare/${turnbar(branchName || defaultBranch)}...${turnbar(branchName || defaultBranch)}`)} >+ 合并请求</CheckProfile>
}
{
issuesFlag &&
<a onClick={createIssue}>+ 疑修</a>
}
</div>
{
(baseOperate || baseOper) &&
<div className="addOptionBtn">
{
baseOperate &&
<CheckProfile {...props} sureFunc={()=>urlLink(`/${owner}/${projectsId}/compare/master...${branchName || defaultBranch}`)} >+ 合并请求</CheckProfile>
}
{
baseOper &&
<CheckProfile {...props} sureFunc={()=>urlLink(`/${owner}/${projectsId}/issues/new`)} >+ 易修</CheckProfile>
}
</div>
}
{ fileOperate &&
<Dropdown
overlay={fileMenu()}
@ -464,18 +454,12 @@ function CoderDepot(props){
(dirInfo && dirInfo.length>0) || fileInfo ?
<div className="listtable">
{
((lastCommit && lastCommit.message) || lastCommitAuthor) &&
lastCommit &&
<div className="listtablehead">
{
lastCommitAuthor &&
<User url={getImageUrl(`/${lastCommitAuthor.image_url}`)} name={lastCommitAuthor.name} id={lastCommitAuthor.id} login={lastCommitAuthor.login}/>
}
{
lastCommit.message &&
<div className={hideBtn && hide ? "ellipsistxt hidetxt" :"ellipsistxt"}>
<pre id="ptxt"><Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(lastCommit.sha)}`}><RenderHtml value={lastCommit.message}/></Link></pre>
</div>
}
<User url={getImageUrl(`/${lastCommitAuthor && lastCommitAuthor.image_url}`)} name={lastCommitAuthor && lastCommitAuthor.name} id={lastCommitAuthor && lastCommitAuthor.id} login={lastCommitAuthor && lastCommitAuthor.login}/>
<div className={hideBtn && hide ? "ellipsistxt hidetxt" :"ellipsistxt"}>
<pre id="ptxt"><Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(lastCommit.sha)}`}><RenderHtml value={lastCommit.message}/></Link></pre>
</div>
{ hideBtn && <span className="ellipsis" onClick={()=>changeHide(hide)}><i className="iconfont icon-shenglvehao"></i></span> }
<span className="ml20 color-grey-6 font-12 mt3">{lastCommit.time_from_now}</span>
@ -493,12 +477,10 @@ function CoderDepot(props){
dirInfo.map((item,key)=>{
return(
<Catalogue
key={item.id||key}
owner={owner}
item={item}
projectsId={projectsId}
goToSubRoot={goToSubRoot}
platform={props.platform}
/>
)
})
@ -523,7 +505,7 @@ function CoderDepot(props){
(dirInfo && dirInfo.length === 0) && !fileInfo ? <Nodata _html="暂未发现文件"/> :""
}
{/* readme文件显示(显示文件详情时不显示readme文件) */}
{ (readme && readme.replace_content) ? <ReadMe ChangeFile={ChangeFile} readme={readme} operate={props && (props.isManager || props.isDeveloper) && projectDetail.type !==2 } history={props.history} /> :"" }
{ (readme && readme.content) ? <ReadMe ChangeFile={ChangeFile} readme={readme} operate={props && (props.isManager || props.isDeveloper) && projectDetail.type !==2 } history={props.history} /> :"" }
</div>
</LongWidth>
{
@ -534,10 +516,10 @@ function CoderDepot(props){
<FlexAJ className="font-18 color-ooo mb20" style={{lineHeight:"28px"}}>关于
{
projectDetail.permission && (projectDetail.permission==="Admin" || projectDetail.permission==="Owner" || projectDetail.permission==="Manager") &&
<i onClick={()=>setOpenModal(true)} className="iconfont icon-a-shezhi color-grey-9 font-15 pointer"></i>
<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"}} title={desc}>{desc}</p>}
{desc && <p className="font-14 color-grey-3 mb15 task-hide-2" style={{lineHeight:"24px",WebkitLineClamp:"4",textAlign:"justify",wordBreak:"break-all"}}>{desc}</p>}
{
website &&
<div className="color-grey-6 df pinfos mb5">
@ -557,7 +539,7 @@ function CoderDepot(props){
projectDetail && projectDetail.license_name &&
<div className="pinfos">
<i className="iconfont icon-xieyiicon font-16 mr10"></i>
<Link to={`/${owner}/${projectsId}/tree/${turnbar(branchName || defaultBranch)}/LICENSE`} className="color-grey-6">{projectDetail.license_name}</Link>
<Link to={`/${owner}/${projectsId}/tree/${branchName || defaultBranch}/LICENSE`} className="color-grey-6">{projectDetail.license_name}</Link>
</div>
}
</div>
@ -578,7 +560,7 @@ function CoderDepot(props){
}
{/* 发布 */}
{
releaseVersions && props.platform &&
releaseVersions &&
<React.Fragment>
<Divider />
<Releases
@ -591,9 +573,17 @@ function CoderDepot(props){
</React.Fragment>
}
{/* 贡献者 */}
<Contributors owner={owner} projectsId={projectsId} />
{
projectDetail && projectDetail.contributors && projectDetail.contributors.total_count >0 &&
<Contributors contributors={projectDetail.contributors} owner={owner} projectsId={projectsId} />
}
{/* 语言 */}
<LanguagePower owner={owner} projectsId={projectsId}/>
{ projectDetail && projectDetail.languages &&
<React.Fragment>
<Divider />
<LanguagePower languages={projectDetail.languages}/>
</React.Fragment>
}
</Gap>
</ShortWidth>
}

View File

@ -8,27 +8,17 @@ const typeIco = {
"dir":"icon-wenjianjia4 font-15 color-blue_4C"
}
function CoderDepotCatalogue({item , goToSubRoot , owner , projectsId , platform }){
//
function getMessage(value){
let str = value.indexOf('\n') > 0 && value.split('\n');
return str[0];
}
function CoderDepotCatalogue({item , goToSubRoot , owner , projectsId }){
return(
<li>
<span>
{
(!platform && item.image_type) ?
<span><i className={`iconfont ${typeIco[`${item.type}`]} mr8`}></i>{item.name}</span>
:
<a onClick={()=>goToSubRoot(item.path,item.type,item.name)} className={item.type === "submodule" ? "submoduleStyle":''}>
<i className={`iconfont ${typeIco[`${item.type}`]} mr8`}></i>{item.name}
</a>
}
<a onClick={()=>goToSubRoot(item.path,item.type,item.name)} className={item.type === "submodule" && "submoduleStyle"}>
<i className={`iconfont ${typeIco[`${item.type}`]} mr8`}></i>{item.name}
</a>
</span>
<span title="init project">
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.commit && item.commit.sha}`)}`} title={item.commit && item.commit.message}>
{getMessage(item.commit && item.commit.message)}
{item.commit && item.commit.message}
</Link>
</span>
<span title={item.commit && item.commit.created_at}>{item.commit && item.commit.time_from_now}</span>

View File

@ -1,5 +1,5 @@
import { result } from 'lodash';
import React from 'react';
import { returnbar } from 'educoder';
function CoderDepotPath({treeValuePath , returnUlr , returnMain , getPathUrl , identifier}){
@ -17,9 +17,9 @@ function CoderDepotPath({treeValuePath , returnUlr , returnMain , getPathUrl , i
<React.Fragment>
{
key === treeValuePath.length-1 ?
<span className="color-grey-6 subFileName" key={key}>{returnbar(item)}</span>
<span className="color-grey-6 subFileName" key={key}>{item}</span>
:
<a onClick={()=>returnUlr(`${getPathUrl(treeValuePath,key+1)}`)} className="color-blue subFileName">{returnbar(item)}</a>
<a onClick={()=>returnUlr(`${getPathUrl(treeValuePath,key+1)}`)} className="color-blue subFileName">{item}</a>
}
</React.Fragment>
);

View File

@ -11,8 +11,8 @@ function CoderDepotReadme({ operate , history , readme , ChangeFile }){
const [ content ,setContent ] = useState(undefined);
useEffect(()=>{
if(readme && readme.replace_content){
setContent(readme.replace_content);
if(readme && readme.content){
setContent(readme.content);
}else{
setContent(undefined);
}
@ -41,7 +41,7 @@ function CoderDepotReadme({ operate , history , readme , ChangeFile }){
return(
<div className="commonBox readBox" id="readme">
<Anchor offsetTop={58}>
<Anchor offsetTop={70} targetOffset={160}>
<div className="commonBox-title boxTitle">
<AlignCenter>
<Dropdown overlay={menu()} trigger={['hover']} overlayClassName="menuslist">

View File

@ -3,10 +3,15 @@ import { Link } from "react-router-dom";
import { Dropdown , Menu , Icon , Tooltip , Spin } from 'antd';
import { truncateCommitId } from '../common/util';
import { getBranch } from '../GetData/getData';
import { turnbar } from "educoder";
import Nodata from '../Nodata';
import './list.scss';
function turnbar(str){
if(str && str.length>0 && str.indexOf("/")>-1){
return str.replaceAll('/','%2F');
}
return str;
}
export default ((props)=>{
const [ data , setData ] =useState(undefined);
const [ isSpin , setIsSpin ] =useState(true);
@ -68,6 +73,7 @@ export default ((props)=>{
<Menu.Item key={'1'}><a href={tar_url}>TAR.GZ</a></Menu.Item>
</Menu>
)
return(
<React.Fragment>
<div className="main">

View File

@ -1,6 +1,6 @@
import React , { Component } from 'react';
import { Spin , Pagination, Timeline } from 'antd';
import { getImageUrl , returnbar } from 'educoder';
import { getImageUrl } from 'educoder';
import { truncateCommitId ,timeFormat } from '../common/util';
import { AlignTop } from '../Component/layout';
import SelectBranch from '../Branch/Select';
@ -15,6 +15,12 @@ import CopyTool from '../Component/CopyTool';
import './tree/Index.scss'
function returnbar(str){
if(str && str.length>0 && str.indexOf("%2F")>-1){
return str.replaceAll('%2F','/');
}
return str;
}
//代码库--提交页面
class CoderRootCommit extends Component{
@ -73,7 +79,7 @@ class CoderRootCommit extends Component{
isSpining:true,
page:realPage
})
this.getCommitList( returnbar(branchName) , realPage , limit );
this.getCommitList( branchName , realPage , limit );
}
getCommitList=(branch , page , limit)=>{
@ -127,7 +133,7 @@ class CoderRootCommit extends Component{
render(){
const { commitDatas , dataCount , limit , page , isSpining , branchList } = this.state;
const { projectDetail, commit_class , defaultBranch , platform } = this.props;
const { projectDetail, commit_class , defaultBranch } = this.props;
const { projectsId , owner , branchName } = this.props.match.params;
let branch = returnbar(branchName || defaultBranch);
return(
@ -153,16 +159,7 @@ class CoderRootCommit extends Component{
<div className="commitList-item f-wrap-between">
<div>
<AlignTop>
<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>
<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>
</AlignTop>
<p className="f-wrap-alignCenter mt15 pb5">
<User
@ -179,12 +176,7 @@ class CoderRootCommit extends Component{
<div>
<span className="treecopy-cont shadow">
<img src={Tree} alt="sha" width={"16px"}/>
{
platform ?
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`}>{truncateCommitId(`${item.sha}`)}</Link>
:
<span style={{color:"#466AFF",cursor:"default"}}>{truncateCommitId(`${item.sha}`)}</span>
}
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`}>{truncateCommitId(`${item.sha}`)}</Link>
<input type="text" id={`value${k}`} value={`${truncateCommitId(`${item.sha}`)}`}/>
</span>
<CopyTool beforeText="复制commit id" afterText="复制成功" inputId={`value${k}`}/>

View File

@ -21,7 +21,7 @@ class CoderRootFileDetail extends Component {
value: undefined,
language: undefined,
languages: undefined,
description: props.detail.replace_content,
description: props.detail.content,
menuList:undefined
};
}
@ -36,12 +36,12 @@ class CoderRootFileDetail extends Component {
};
componentDidUpdate=(prevProps)=>{
const { replace_content } = this.props && this.props.detail;
const prevcontent = prevProps.detail && prevProps.detail.replace_content;
if (replace_content && prevcontent) {
if (prevcontent !== replace_content){
const { content } = this.props && this.props.detail;
const prevcontent = prevProps.detail && prevProps.detail.content;
if (content && prevcontent) {
if (prevcontent !== content){
this.setState({
description: replace_content
description: content
});
}
}
@ -215,7 +215,7 @@ class CoderRootFileDetail extends Component {
const Option = Select.Option;
return (
<React.Fragment>
<Anchor className="griditemAnchor" offsetTop={58}>
<Anchor className="griditemAnchor" offsetTop={70}>
<div className="griditemCate">
{
md && readOnly &&
@ -319,7 +319,7 @@ class CoderRootFileDetail extends Component {
{...this.state}
language={language ? language : "javascript"}
filepath={`/${detail.path}`}
content={detail.content}
content={description}
readOnly={readOnly}
editorType="update"
currentBranch={currentBranch}

View File

@ -29,6 +29,14 @@ const CoderRootVersion = Loadable({
loader: () => import('./version/Index'),
loading: Loading,
})
// const CoderRootVersionNew = Loadable({
// loader: () => import('./version/New'),
// loading: Loading,
// })
// const CoderRootVersionUpdate = Loadable({
// loader: () => import('./version/New'),
// loading: Loading,
// })
const Diff = Loadable({
loader: () => import('./Diff'),
loading: Loading,
@ -42,6 +50,37 @@ class CoderRootIndex extends Component{
}
}
// componentDidMount=()=>{
// this.Init();
// }
// componentDidUpdate=(prevProps)=>{
// const { location } = this.props;
// const prevlocation = prevProps && prevProps.location;
// if (location !== prevlocation) {
// this.Init();
// }
// }
// Init=()=>{
// const { branchName } = this.props.match.params;
// const { defaultBranch } = this.props;
// this.getTopCount(branchName || defaultBranch);
// }
// 获取<Top />组件里要显示的数据
// getTopCount=(branch)=>{
// const { projectsId , owner } = this.props.match.params;
// const url = `/${owner}/${projectsId}/top_counts.json`;
// axios.get(url,{params:{
// ref:branch
// }}).then(result=>{
// if(result){
// this.setState({
// coderCount:result.data
// })
// }
// }).catch(error=>{console.log(error);})
// }
render(){
return(
<div className="coderSubPage">

View File

@ -3,8 +3,7 @@ import { Spin, Tooltip } from 'antd';
import { Link, Route, Switch } from 'react-router-dom';
import { Content, AlignTop } from '../Component/layout';
import DetailBanner from './sub/DetailBanner';
import cookie from 'react-cookies';
import { Base64 } from 'js-base64';
import { numFormat } from 'educoder';
import '../css/index.scss'
import './list.scss';
@ -56,8 +55,7 @@ const OrderupdateMilepost = Loadable({
})
const OrderupdateDetail = Loadable({
// loader: () => import('../Order/UpdateDetail'),
loader: () => import('../Order/order_form'),
loader: () => import('../Order/UpdateDetail'),
loading: Loading,
})
@ -130,10 +128,6 @@ const Source = Loadable({
loader: () => import('../Source/Index'),
loading: Loading,
})
const Server = Loadable({
loader: () => import('../Server/Index'),
loading: Loading,
})
const DevIndex = Loadable({
loader: () => import('../DevOps/Index'),
loading: Loading,
@ -146,10 +140,6 @@ const WikiEdit = Loadable({
loader: () => import('../Wiki/EditWiki'),
loading: Loading,
});
const Invite = Loadable({
loader: () => import('../Invite/Index'),
loading: Loading,
});
/**
* permissionManager:管理员Reporter报告人员(只有读取权限)Developer开发人员除不能设置仓库信息外
*/
@ -177,8 +167,6 @@ function checkPathname(projectsId, owner, pathname) {
name = "source"
} else if (url.indexOf(`/wiki`) > -1) {
name = "wiki"
} else if (url.indexOf(`/server`) > -1) {
name = "server"
}
}
return name;
@ -215,8 +203,6 @@ class Detail extends Component {
componentDidMount = () => {
this.getProject();
let history = this.props.location;
this.clearIssueCookies(history);
}
componentDidUpdate = (prevState) => {
@ -225,24 +211,6 @@ class Detail extends Component {
if (prevState && this.props && (prevParam.projectsId !== propsParam.projectsId || prevParam.owner !== propsParam.owner)) {
this.getProject();
}
this.props.history.listen((history) => {
// 非issue链接地址清除cookie states具体保存和操作在order.js页面
this.clearIssueCookies(history);
})
}
clearIssueCookies = (history) => {
const { pathname } = history;
const { projectsId, owner } = this.props.match.params;
let currentIssue = pathname.indexOf(`/${owner}/${projectsId}/issues`) === -1;
if (currentIssue) {
cookie.save('states', undefined, { expires: 0, path: `/` });
}
}
componentWillUnmount() {
this.timerChannel && clearTimeout(this.timerChannel);
}
getProject = (num) => {
@ -274,7 +242,6 @@ class Detail extends Component {
} else if (result.data.mirror_status === 2) {
this.deleteProjectBack();
} else {
this.getBanner();
this.getDetail();
this.setState({
firstSync: false,
@ -307,22 +274,19 @@ class Detail extends Component {
connected: () => {
console.log("###### channel connected! ######");
},
disconnected: () => {
console.log("###### cannot connected! ######");
},
disconnected: () => { },
received: data => {
console.log(`###### ---received data--- ######`);
console.log(data);
if (data) {
if (deleteFlag) {
if(deleteFlag){
this.props.showNotification("镜像同步成功!");
window.location.reload();
} else {
}else{
if (data.project && data.project.mirror_status === 2) {
this.deleteProjectBack();
}
this.getDetail();
this.getBanner();
}
this.setState({
firstSync: false,
@ -330,22 +294,10 @@ class Detail extends Component {
});
cable.subscriptions.consumer.disconnect();
}
},
onerror: () => {
console.log("###### cannot connected! ######");
}
});
this.timerChannel = setTimeout(this.reloadDetail, 5000);
})
}
reloadDetail = () => {
if (this.state.firstSync || this.state.secondSync) {
window.location.reload();
}
}
deleteProjectBack = () => {
const { history } = this.props;
const { projectsId, owner } = this.props.match.params;
@ -365,37 +317,27 @@ 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) {
if (result.data.status === 404) {
if (window.location.pathname.includes('/invite')) {
let inviteString = window.location.search && window.location.search.split('?invite=')[1];
let data = inviteString && JSON.parse(Base64.decode(inviteString));
const { project = {}, projectDetail = {} } = this.state
this.setState({
project: Object.assign(project, { author: { name: data.ownerName } }),
projectDetail: Object.assign(projectDetail, { name: data.projectName })
});
} else {
this.props.history.push('/nopage');
}
} else {
this.setState({
projectDetail: result.data,
project_id: result.data.project_id,
isManager: result.data.permission && (result.data.permission === "Manager" || result.data.permission === "Admin" || result.data.permission === "Owner"),
isReporter: result.data.permission && result.data.permission === "Reporter",
isDeveloper: result.data.permission && result.data.permission === "Developer",
http_url: result.data.clone_url,
praised: result.data.praised,
watched: result.data.watched,
watchers_count: result.data.watchers_count,
praises_count: result.data.praises_count,
forked_count: result.data.forked_count,
defaultBranch: result.data.default_branch
})
this.props.history.push('/nopage');
}
this.setState({
projectDetail: result.data,
project_id: result.data.project_id,
isManager: result.data.permission && (result.data.permission === "Manager" || result.data.permission === "Admin" || result.data.permission === "Owner"),
isReporter: result.data.permission && result.data.permission === "Reporter",
isDeveloper: result.data.permission && result.data.permission === "Developer",
http_url: result.data.clone_url,
praised: result.data.praised,
watched: result.data.watched,
watchers_count: result.data.watchers_count,
praises_count: result.data.praises_count,
forked_count: result.data.forked_count,
defaultBranch: result.data.default_branch
})
}
}).catch((error) => { })
}
@ -480,10 +422,6 @@ 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);
}
@ -506,7 +444,7 @@ class Detail extends Component {
axios.post(url).then(result => {
if (result && result.data && result.data.status === 0) {
this.setState({
secondSync: true
secondSync:true
})
this.canvasChannel(true);
} else {
@ -543,9 +481,9 @@ class Detail extends Component {
let pathname = checkPathname(projectsId, owner, url);
const { state } = this.props.history.location;
const common = {
getDetail: this.getDetail,
getBanner: this.getBanner,
changeOpenDevops: this.changeOpenDevops,
defaultBranch
}
@ -564,7 +502,6 @@ class Detail extends Component {
<Link to={`/${owner}/${projectsId}`} className="projectN mt6">{projectDetail && projectDetail.name}</Link>
</div>
{projectDetail && projectDetail.private && <span className="privateTag mt6">私有</span>}
{!platform && <span className="privateTag red mt6">只读</span>}
</AlignTop>
<div className="mt8">
{
@ -572,6 +509,11 @@ 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>
@ -659,8 +601,7 @@ class Detail extends Component {
open_devops={open_devops}
platform={platform}
urlFlag={urlFlag}
showNotification={this.props.showNotification}
current_user={current_user}
isManager={isManager}
/>
}
</div>
@ -673,12 +614,6 @@ class Detail extends Component {
:
<Spin spinning={secondSync} className="spinstyle" tip="正在同步镜像" size="large">
<Switch {...this.props}>
{/* 服务 */}
<Route path="/:owner/:projectsId/server"
render={
() => (<Server {...this.props} {...this.state} {...common} />)
}
></Route>
{/* 资源 */}
<Route path="/:owner/:projectsId/source"
render={
@ -703,12 +638,6 @@ class Detail extends Component {
() => (<WikiEdit {...this.props} {...this.state} {...common} />)
}
></Route>
{/* wiki具体某一个地址 */}
<Route path="/:owner/:projectsId/wiki/:wikiName"
render={
(props) => (<Wiki {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* wiki */}
<Route path="/:owner/:projectsId/wiki"
render={
@ -770,21 +699,21 @@ class Detail extends Component {
(props) => (<OrderNew {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* 修改详情 edit*/}
<Route path="/:owner/:projectsId/issues/:orderId/edit"
{/* 修改详情 updatedetail*/}
<Route path="/:owner/:projectsId/issues/:orderId/:operateName"
render={
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} form_type={"edit"} />)
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* 复制详情 copyetail*/}
<Route path="/:owner/:projectsId/issues/:orderId/copyetail"
render={
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} form_type={"copy"} />)
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* 任务详情 */}
<Route path="/:owner/:projectsId/issues/:orderId"
{/* 任务详情 */}
<Route path="/:owner/:projectsId/issues/:orderId"
render={
(props) => (<OrderDetail {...this.props} {...this.state} {...props} {...common} />)
}
@ -876,12 +805,6 @@ class Detail extends Component {
(props) => (<CoderDepot {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* 邀请 */}
<Route path="/:owner/:projectsId/invite"
render={
(props) => (<Invite {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/:subIndex"
render={
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} {...common} />)

View File

@ -36,9 +36,8 @@ const Infos = styled.div`
}
& > .f-wrap-between {
padding: 14px 20px 14px 16px;
border-radius: 0px 0px 3px 3px;
border-radius: 3px 3px 0px 0px;
border: 1px solid #D0D0D0;
border-top: none;
.df{
align-items: center;
& .underline:hover{
@ -47,6 +46,12 @@ const Infos = styled.div`
}
}
`;
function turnbar(str){
if(str && str.length>0 && str.indexOf("/")>-1){
return str.replaceAll('/','%2F');
}
return str;
}
//
export default (props) => {
const {match , history } = props;

View File

@ -37,10 +37,7 @@ class Index extends Component {
recommendOriList:undefined,
languageList:undefined,
languageId:undefined,
CategoryList:undefined
languageId:undefined
}
}
@ -53,7 +50,7 @@ class Index extends Component {
this.getCategory();
// this.getRecommand();
this.getRecommand();
this.getLanguage();
@ -150,13 +147,11 @@ class Index extends Component {
this.setState({
isSpin: true,
project_type: type,
search: undefined,
category_id: undefined,
},()=>{
this.setTypeList(list, type)
const { page, limit, sort , languageId } = this.state;
this.getListData(page, limit, undefined, sort, type, undefined , languageId);
search: undefined
})
this.setTypeList(list, type)
const { page, limit, sort, category_id , languageId } = this.state;
this.getListData(page, limit, undefined, sort, type, category_id , languageId);
}
// 获取类型
@ -165,15 +160,23 @@ class Index extends Component {
axios.get(url).then((result) => {
if (result && result.data) {
this.setCategoryList(result.data, undefined);
}
}).catch((error) => { })
}
setCategoryList = (list) => {
setCategoryList = (list, active_id) => {
this.setState({
CategoryList: list
categoryList: list.map((item, key) => {
return (
<li key={key} className={active_id && parseInt(active_id) === item.id ? 'active' : ''} onClick={() => this.changeCategory(`${item.id}`, list)}>
<p>
<span className="font-16">{item.name}</span>
<span className="color-blue">{item.projects_count}</span>
</p>
</li>
)
})
})
}
@ -181,10 +184,10 @@ class Index extends Component {
this.setState({
category_id: id,
page: 1
},()=>{
const { limit, sort, project_type , languageId } = this.state;
this.getListData(1, limit, undefined, sort, project_type, id , languageId);
});
this.setCategoryList(list, id)
const { limit, sort, project_type , languageId } = this.state;
this.getListData(1, limit, undefined, sort, project_type, id , languageId);
}
// 排序
@ -244,7 +247,7 @@ class Index extends Component {
<Menu onClick={this.ChangeSoryBy}>
<Menu.Item key="updated_on">更新时间排序</Menu.Item>
<Menu.Item key="created_on">创建时间排序</Menu.Item>
<Menu.Item key="forked_count">fork数排序</Menu.Item>
<Menu.Item key="forked_count">fork数排序</Menu.Item>
<Menu.Item key="praises_count">点赞数量排序</Menu.Item>
</Menu>
)
@ -276,35 +279,34 @@ class Index extends Component {
const { current_user } = this.props;
const { projectsList , recommendList , languageList , languageId ,
isSpin, total, search, limit, page, typeList, categoryList ,
recommendOriList , CategoryList , category_id } = this.state;
isSpin, total, search, limit, page, typeList, categoryList , recommendOriList } = this.state;
// const setting={
// dots: true,
// infinite: true,
// speed: 500,
// slidesToShow: 5,
// slidesToScroll: 5,
// autoplay:false,
// arrows:false,
// adaptiveHeight:true
// }
// const settings={
// dots: true,
// infinite: true,
// speed: 500,
// slidesToShow: 6,
// slidesToScroll: 6,
// autoplay:false,
// arrows:false,
// adaptiveHeight:true
// }
const setting={
dots: true,
infinite: true,
speed: 500,
slidesToShow: 5,
slidesToScroll: 5,
autoplay:false,
arrows:false,
adaptiveHeight:true
}
const settings={
dots: true,
infinite: true,
speed: 500,
slidesToShow: 6,
slidesToScroll: 6,
autoplay:false,
arrows:false,
adaptiveHeight:true
}
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">
@ -318,7 +320,7 @@ class Index extends Component {
</Slider>
:""
} */}
{/* {
{
recommendList && recommendList.length>0 &&
<Slider {...setting} className={recommendList.length>5 ? "recommandProjects":"recommandProjects mb20"}>
{
@ -339,7 +341,7 @@ class Index extends Component {
})
}
</Slider>
} */}
}
<div className="ProjectListIndex">
<div className="list-left">
<ul className="list-l-Menu">
@ -348,19 +350,7 @@ class Index extends Component {
</ul>
<ul className="list-l-Menu">
<li className="MenuTitle"><i className="iconfont icon-xiangmuleibie color-grey-9 font-15 mr5"></i></li>
{
CategoryList && CategoryList.length > 0 ? CategoryList.map((item,key)=>{
return(
<li key={key} className={category_id && parseInt(category_id) === item.id ? 'active' : ''} onClick={() => this.changeCategory(`${item.id}`)}>
<p>
<span className="font-16">{item.name}</span>
<span className="color-blue">{item.projects_count}</span>
</p>
</li>
)
})
:""
}
{categoryList}
</ul>
</div>
<div className="list-right boxShandow radius-2" style={{padding:0}}>

View File

@ -246,14 +246,11 @@
display: flex;
justify-content: space-between;
align-items: flex-start;
border-bottom: 1px solid #d9d9d9;
padding:12px 20px 11px;
border-radius: 4px 4px 0px 0px;
border: 1px solid rgba(42, 97, 255, 0.23);
border-bottom: none;
background-color: #FAFCFF;
&+.listtablebody{
border-top-color: rgba(42, 97, 255, 0.23);
}
.ellipsistxt{
&:hover .markdown-body{
color: #466AFF;
@ -334,14 +331,7 @@
.listtablebody{
border-radius:0px 0px 4px 4px ;
border: 1px solid #D0D0D0;
li{
a{
color: #05101a;
&:hover{
color:$primary-color;
}
}
}
border-top: none;
li.listtablepath{
a{color: #40a9ff;}
p{

View File

@ -35,7 +35,7 @@ class IndexItem extends Component {
<div className="p-r-Infos">
<div className="p-r-name">
<AlignCenter>
<Link to={`/${item.author.login}/${item.identifier}`} target="_blank" title={`${item.author.name}/${item.name}`} className="color-grey-3 font-18 task-hide " style={{maxWidth: 470 }}>
<Link to={`/${item.author.login}/${item.identifier}`} title={`${item.author.name}/${item.name}`} className="color-grey-3 font-18 task-hide " style={{maxWidth: 470 }}>
{item.author.name}/{item.name}
</Link>
{ !item.is_public && <span className="privateTag">私有</span> }
@ -52,6 +52,12 @@ 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">
{

Some files were not shown because too many files have changed in this diff Show More