merge dev_bei to sponsor, fix conflict
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"presets": [
|
||||
"es2015",
|
||||
"react",
|
||||
"stage-2"
|
||||
],
|
||||
"plugins": [[
|
||||
"transform-runtime",
|
||||
{
|
||||
"helpers": false,
|
||||
"polyfill": false,
|
||||
"regenerator": true,
|
||||
"moduleName": "babel-runtime"
|
||||
}
|
||||
]]
|
||||
}
|
|
@ -10,7 +10,6 @@
|
|||
"array-flatten": "^2.1.2",
|
||||
"autoprefixer": "7.1.6",
|
||||
"axios": "^0.18.1",
|
||||
"babel-core": "6.26.0",
|
||||
"babel-eslint": "7.2.3",
|
||||
"babel-jest": "20.0.3",
|
||||
"babel-loader": "7.1.2",
|
||||
|
@ -23,6 +22,7 @@
|
|||
"chalk": "1.1.3",
|
||||
"classnames": "^2.2.5",
|
||||
"clipboard": "^2.0.6",
|
||||
"code-prettify": "^0.1.0",
|
||||
"codemirror": "^5.53.0",
|
||||
"connected-react-router": "4.4.1",
|
||||
"css-loader": "^3.5.2",
|
||||
|
@ -181,7 +181,13 @@
|
|||
"port": "3007",
|
||||
"devDependencies": {
|
||||
"@babel/runtime": "7.0.0-beta.51",
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-plugin-import": "^1.13.0",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-preset-stage-2": "^6.24.1",
|
||||
"compression-webpack-plugin": "^1.1.12",
|
||||
"concat": "^1.0.3",
|
||||
"happypack": "^5.0.1",
|
||||
|
|
|
@ -2325,6 +2325,9 @@ input::-ms-clear {
|
|||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
.ant-modal-close{
|
||||
top:8px!important;
|
||||
}
|
||||
|
||||
.newContainer {
|
||||
min-height: 100%;
|
||||
|
@ -2658,7 +2661,7 @@ a.color-green:hover {
|
|||
|
||||
/*百分比宽度*/
|
||||
.width100 {
|
||||
width: 100%;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.width89 {
|
||||
|
@ -3944,7 +3947,7 @@ html>body #ajax-indicator {
|
|||
|
||||
.head-nav {
|
||||
text-align: center;
|
||||
height: 60px;
|
||||
height: 70px;
|
||||
box-sizing: border-box;
|
||||
min-width: 780px;
|
||||
overflow: hidden;
|
||||
|
@ -3957,29 +3960,29 @@ html>body #ajax-indicator {
|
|||
position: absolute;
|
||||
top: 0px;
|
||||
z-index: 3;
|
||||
height: 60px;
|
||||
height: 70px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li {
|
||||
float: left;
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
margin-right: 30px;
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
padding:0px 20px;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li a {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
color: #333333;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li a:hover {
|
||||
.head-nav ul#header-nav li a:hover,.head-nav ul#header-nav li.active a {
|
||||
color: #5091FF;
|
||||
}
|
||||
|
||||
|
@ -3987,13 +3990,10 @@ html>body #ajax-indicator {
|
|||
margin-right: 0px
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li.active a:first-child {
|
||||
color: #459be5 !important;
|
||||
.head-nav ul#header-nav li.active{
|
||||
/* background-color: #3B3B3B; */
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li.active p {
|
||||
color: #459be5 !important;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li p:hover {
|
||||
color: #cccccc;
|
||||
|
@ -4006,23 +4006,23 @@ html>body #ajax-indicator {
|
|||
color: #fff
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li.active div ul li a {
|
||||
/* .head-nav ul#header-nav li.active div ul li a {
|
||||
color: #000 !important;
|
||||
}
|
||||
} */
|
||||
|
||||
.head-nav ul#header-nav li.active div ul li a:hover {
|
||||
/* .head-nav ul#header-nav li.active div ul li a:hover {
|
||||
color: #FFF !important;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li.active ul li a {
|
||||
color: #000 !important;
|
||||
}
|
||||
} */
|
||||
|
||||
.head-nav ul#header-nav li.active ul li a:hover {
|
||||
/* .head-nav ul#header-nav li.active ul li a:hover {
|
||||
color: #FFF !important;
|
||||
}
|
||||
} */
|
||||
|
||||
.head-nav ul#header-nav li.active:after {
|
||||
/* .head-nav ul#header-nav li.active:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
|
@ -4032,7 +4032,7 @@ html>body #ajax-indicator {
|
|||
height: 2px;
|
||||
width: 32px;
|
||||
background-color: #459be5;
|
||||
}
|
||||
} */
|
||||
|
||||
.head-right {
|
||||
box-sizing: border-box;
|
||||
|
|
|
@ -5,6 +5,559 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "17567215",
|
||||
"name": "主页",
|
||||
"font_class": "zhuye1",
|
||||
"unicode": "e7e4",
|
||||
"unicode_decimal": 59364
|
||||
},
|
||||
{
|
||||
"icon_id": "17542255",
|
||||
"name": "项目简介",
|
||||
"font_class": "xiangmujianjie",
|
||||
"unicode": "e7e7",
|
||||
"unicode_decimal": 59367
|
||||
},
|
||||
{
|
||||
"icon_id": "17542254",
|
||||
"name": "参与成员",
|
||||
"font_class": "canyuchengyuan",
|
||||
"unicode": "e7e6",
|
||||
"unicode_decimal": 59366
|
||||
},
|
||||
{
|
||||
"icon_id": "17542253",
|
||||
"name": "使用文档",
|
||||
"font_class": "shiyongwendang",
|
||||
"unicode": "e7e5",
|
||||
"unicode_decimal": 59365
|
||||
},
|
||||
{
|
||||
"icon_id": "17541348",
|
||||
"name": "代码库",
|
||||
"font_class": "daimaku",
|
||||
"unicode": "e7d9",
|
||||
"unicode_decimal": 59353
|
||||
},
|
||||
{
|
||||
"icon_id": "17541349",
|
||||
"name": "forc",
|
||||
"font_class": "forc",
|
||||
"unicode": "e7da",
|
||||
"unicode_decimal": 59354
|
||||
},
|
||||
{
|
||||
"icon_id": "17541350",
|
||||
"name": "点赞",
|
||||
"font_class": "dianzan3",
|
||||
"unicode": "e7dd",
|
||||
"unicode_decimal": 59357
|
||||
},
|
||||
{
|
||||
"icon_id": "17541351",
|
||||
"name": "里程碑",
|
||||
"font_class": "lichengbei",
|
||||
"unicode": "e7de",
|
||||
"unicode_decimal": 59358
|
||||
},
|
||||
{
|
||||
"icon_id": "17541352",
|
||||
"name": "取消点赞",
|
||||
"font_class": "quxiaodianzan",
|
||||
"unicode": "e7df",
|
||||
"unicode_decimal": 59359
|
||||
},
|
||||
{
|
||||
"icon_id": "17541353",
|
||||
"name": "fork2",
|
||||
"font_class": "fork2",
|
||||
"unicode": "e7e0",
|
||||
"unicode_decimal": 59360
|
||||
},
|
||||
{
|
||||
"icon_id": "17541354",
|
||||
"name": "合并请求",
|
||||
"font_class": "hebingqingqiu1",
|
||||
"unicode": "e7e1",
|
||||
"unicode_decimal": 59361
|
||||
},
|
||||
{
|
||||
"icon_id": "17541355",
|
||||
"name": "任务",
|
||||
"font_class": "renwu",
|
||||
"unicode": "e7e2",
|
||||
"unicode_decimal": 59362
|
||||
},
|
||||
{
|
||||
"icon_id": "17541356",
|
||||
"name": "通知",
|
||||
"font_class": "tongzhi",
|
||||
"unicode": "e7e3",
|
||||
"unicode_decimal": 59363
|
||||
},
|
||||
{
|
||||
"icon_id": "17481990",
|
||||
"name": "金币",
|
||||
"font_class": "jinbi",
|
||||
"unicode": "e7c5",
|
||||
"unicode_decimal": 59333
|
||||
},
|
||||
{
|
||||
"icon_id": "17468131",
|
||||
"name": "未开摄像头",
|
||||
"font_class": "weikaishexiangtou1",
|
||||
"unicode": "e7d8",
|
||||
"unicode_decimal": 59352
|
||||
},
|
||||
{
|
||||
"icon_id": "17435144",
|
||||
"name": "关卡菜单",
|
||||
"font_class": "guankacaidan",
|
||||
"unicode": "e7ce",
|
||||
"unicode_decimal": 59342
|
||||
},
|
||||
{
|
||||
"icon_id": "17416333",
|
||||
"name": "重置实训",
|
||||
"font_class": "zhongzhishixun",
|
||||
"unicode": "e7d5",
|
||||
"unicode_decimal": 59349
|
||||
},
|
||||
{
|
||||
"icon_id": "17416337",
|
||||
"name": "复制粘贴",
|
||||
"font_class": "fuzhiniantie",
|
||||
"unicode": "e7d6",
|
||||
"unicode_decimal": 59350
|
||||
},
|
||||
{
|
||||
"icon_id": "17416342",
|
||||
"name": "共享桌面",
|
||||
"font_class": "gongxiangzhuomian",
|
||||
"unicode": "e7d7",
|
||||
"unicode_decimal": 59351
|
||||
},
|
||||
{
|
||||
"icon_id": "17415865",
|
||||
"name": "退出全屏",
|
||||
"font_class": "tuichuquanping",
|
||||
"unicode": "e7d4",
|
||||
"unicode_decimal": 59348
|
||||
},
|
||||
{
|
||||
"icon_id": "17415856",
|
||||
"name": "全屏",
|
||||
"font_class": "quanping",
|
||||
"unicode": "e7d2",
|
||||
"unicode_decimal": 59346
|
||||
},
|
||||
{
|
||||
"icon_id": "17415080",
|
||||
"name": "复制版本库地址",
|
||||
"font_class": "fuzhibanbenkudizhi1",
|
||||
"unicode": "e7d3",
|
||||
"unicode_decimal": 59347
|
||||
},
|
||||
{
|
||||
"icon_id": "17400088",
|
||||
"name": "实验环境倒计时",
|
||||
"font_class": "shiyanhuanjingdaojishi",
|
||||
"unicode": "e7d1",
|
||||
"unicode_decimal": 59345
|
||||
},
|
||||
{
|
||||
"icon_id": "17399931",
|
||||
"name": "vnc实训界面-工具栏",
|
||||
"font_class": "vncshixunjiemian-gongjulan",
|
||||
"unicode": "e7d0",
|
||||
"unicode_decimal": 59344
|
||||
},
|
||||
{
|
||||
"icon_id": "17399816",
|
||||
"name": "vnc实训界面-展开",
|
||||
"font_class": "vncshixunjiemian-zhankai",
|
||||
"unicode": "e7cf",
|
||||
"unicode_decimal": 59343
|
||||
},
|
||||
{
|
||||
"icon_id": "17399289",
|
||||
"name": "vnc实训界面-收起",
|
||||
"font_class": "vncshixunjiemian-shouqi",
|
||||
"unicode": "e7cd",
|
||||
"unicode_decimal": 59341
|
||||
},
|
||||
{
|
||||
"icon_id": "17393121",
|
||||
"name": "撤销分组",
|
||||
"font_class": "chexiaofenzu",
|
||||
"unicode": "e7ca",
|
||||
"unicode_decimal": 59338
|
||||
},
|
||||
{
|
||||
"icon_id": "17393122",
|
||||
"name": "撤销共享",
|
||||
"font_class": "chexiaogongxiang",
|
||||
"unicode": "e7cb",
|
||||
"unicode_decimal": 59339
|
||||
},
|
||||
{
|
||||
"icon_id": "17393123",
|
||||
"name": "选中",
|
||||
"font_class": "xuanzhong1",
|
||||
"unicode": "e7cc",
|
||||
"unicode_decimal": 59340
|
||||
},
|
||||
{
|
||||
"icon_id": "17347836",
|
||||
"name": "警示",
|
||||
"font_class": "jingshi1",
|
||||
"unicode": "e7c9",
|
||||
"unicode_decimal": 59337
|
||||
},
|
||||
{
|
||||
"icon_id": "17338109",
|
||||
"name": "删除",
|
||||
"font_class": "shanchu21",
|
||||
"unicode": "e7c8",
|
||||
"unicode_decimal": 59336
|
||||
},
|
||||
{
|
||||
"icon_id": "17338062",
|
||||
"name": "收藏",
|
||||
"font_class": "shoucang3",
|
||||
"unicode": "e7c7",
|
||||
"unicode_decimal": 59335
|
||||
},
|
||||
{
|
||||
"icon_id": "17320656",
|
||||
"name": "搜索",
|
||||
"font_class": "sousuo2",
|
||||
"unicode": "e7c6",
|
||||
"unicode_decimal": 59334
|
||||
},
|
||||
{
|
||||
"icon_id": "17272329",
|
||||
"name": "光标",
|
||||
"font_class": "guangbiao",
|
||||
"unicode": "e7c4",
|
||||
"unicode_decimal": 59332
|
||||
},
|
||||
{
|
||||
"icon_id": "17215358",
|
||||
"name": "QQ",
|
||||
"font_class": "QQ",
|
||||
"unicode": "e7c3",
|
||||
"unicode_decimal": 59331
|
||||
},
|
||||
{
|
||||
"icon_id": "675739",
|
||||
"name": "用户",
|
||||
"font_class": "yonghu",
|
||||
"unicode": "e7c2",
|
||||
"unicode_decimal": 59330
|
||||
},
|
||||
{
|
||||
"icon_id": "12703761",
|
||||
"name": "oschina",
|
||||
"font_class": "oschina",
|
||||
"unicode": "e7c1",
|
||||
"unicode_decimal": 59329
|
||||
},
|
||||
{
|
||||
"icon_id": "17189615",
|
||||
"name": "右",
|
||||
"font_class": "you",
|
||||
"unicode": "e7bf",
|
||||
"unicode_decimal": 59327
|
||||
},
|
||||
{
|
||||
"icon_id": "17189616",
|
||||
"name": "左",
|
||||
"font_class": "zuo",
|
||||
"unicode": "e7c0",
|
||||
"unicode_decimal": 59328
|
||||
},
|
||||
{
|
||||
"icon_id": "17126010",
|
||||
"name": "编程语言",
|
||||
"font_class": "bianchengyuyan",
|
||||
"unicode": "e7bd",
|
||||
"unicode_decimal": 59325
|
||||
},
|
||||
{
|
||||
"icon_id": "4550494",
|
||||
"name": "箭头",
|
||||
"font_class": "jiantou",
|
||||
"unicode": "e7bc",
|
||||
"unicode_decimal": 59324
|
||||
},
|
||||
{
|
||||
"icon_id": "17078373",
|
||||
"name": "自用试卷",
|
||||
"font_class": "ziyongshijuan",
|
||||
"unicode": "e7b3",
|
||||
"unicode_decimal": 59315
|
||||
},
|
||||
{
|
||||
"icon_id": "17078374",
|
||||
"name": "已公开试卷",
|
||||
"font_class": "yigongkaishijuan",
|
||||
"unicode": "e7bb",
|
||||
"unicode_decimal": 59323
|
||||
},
|
||||
{
|
||||
"icon_id": "17077771",
|
||||
"name": "视频",
|
||||
"font_class": "shipin",
|
||||
"unicode": "e7b4",
|
||||
"unicode_decimal": 59316
|
||||
},
|
||||
{
|
||||
"icon_id": "17077772",
|
||||
"name": "实训",
|
||||
"font_class": "shixun2",
|
||||
"unicode": "e7be",
|
||||
"unicode_decimal": 59326
|
||||
},
|
||||
{
|
||||
"icon_id": "17060498",
|
||||
"name": "放大",
|
||||
"font_class": "fangda2",
|
||||
"unicode": "e7ba",
|
||||
"unicode_decimal": 59322
|
||||
},
|
||||
{
|
||||
"icon_id": "17060439",
|
||||
"name": "开启防作弊",
|
||||
"font_class": "fangzuobi",
|
||||
"unicode": "e7b9",
|
||||
"unicode_decimal": 59321
|
||||
},
|
||||
{
|
||||
"icon_id": "17027771",
|
||||
"name": "闹钟",
|
||||
"font_class": "shizhong",
|
||||
"unicode": "e7b8",
|
||||
"unicode_decimal": 59320
|
||||
},
|
||||
{
|
||||
"icon_id": "16923000",
|
||||
"name": "上传视频 (1)",
|
||||
"font_class": "shangchuanshipin1",
|
||||
"unicode": "e7b7",
|
||||
"unicode_decimal": 59319
|
||||
},
|
||||
{
|
||||
"icon_id": "16922942",
|
||||
"name": "对勾",
|
||||
"font_class": "duigou1",
|
||||
"unicode": "e7b2",
|
||||
"unicode_decimal": 59314
|
||||
},
|
||||
{
|
||||
"icon_id": "16922946",
|
||||
"name": "链接 (1)",
|
||||
"font_class": "lianjie1",
|
||||
"unicode": "e7b5",
|
||||
"unicode_decimal": 59317
|
||||
},
|
||||
{
|
||||
"icon_id": "16922947",
|
||||
"name": "章节",
|
||||
"font_class": "zhangjie",
|
||||
"unicode": "e7b6",
|
||||
"unicode_decimal": 59318
|
||||
},
|
||||
{
|
||||
"icon_id": "16771382",
|
||||
"name": "模版管理2",
|
||||
"font_class": "mobanguanli2",
|
||||
"unicode": "e7b1",
|
||||
"unicode_decimal": 59313
|
||||
},
|
||||
{
|
||||
"icon_id": "16771348",
|
||||
"name": "分组作业",
|
||||
"font_class": "fenzuzuoye2",
|
||||
"unicode": "e7b0",
|
||||
"unicode_decimal": 59312
|
||||
},
|
||||
{
|
||||
"icon_id": "16771344",
|
||||
"name": "毕业作业",
|
||||
"font_class": "biyezuoye1",
|
||||
"unicode": "e7af",
|
||||
"unicode_decimal": 59311
|
||||
},
|
||||
{
|
||||
"icon_id": "16771343",
|
||||
"name": "统计",
|
||||
"font_class": "tongji3",
|
||||
"unicode": "e7ae",
|
||||
"unicode_decimal": 59310
|
||||
},
|
||||
{
|
||||
"icon_id": "16771339",
|
||||
"name": "签到",
|
||||
"font_class": "qiandao1",
|
||||
"unicode": "e7ad",
|
||||
"unicode_decimal": 59309
|
||||
},
|
||||
{
|
||||
"icon_id": "16771338",
|
||||
"name": "分班",
|
||||
"font_class": "fenban2",
|
||||
"unicode": "e7ac",
|
||||
"unicode_decimal": 59308
|
||||
},
|
||||
{
|
||||
"icon_id": "16771329",
|
||||
"name": "讨论",
|
||||
"font_class": "taolun2",
|
||||
"unicode": "e7ab",
|
||||
"unicode_decimal": 59307
|
||||
},
|
||||
{
|
||||
"icon_id": "16771324",
|
||||
"name": "视频直播",
|
||||
"font_class": "shipinzhibo1",
|
||||
"unicode": "e7aa",
|
||||
"unicode_decimal": 59306
|
||||
},
|
||||
{
|
||||
"icon_id": "16771321",
|
||||
"name": "考试试卷",
|
||||
"font_class": "kaoshishijuan1",
|
||||
"unicode": "e7a9",
|
||||
"unicode_decimal": 59305
|
||||
},
|
||||
{
|
||||
"icon_id": "16771320",
|
||||
"name": "考试问卷",
|
||||
"font_class": "kaoshiwenjuan1",
|
||||
"unicode": "e7a7",
|
||||
"unicode_decimal": 59303
|
||||
},
|
||||
{
|
||||
"icon_id": "16768917",
|
||||
"name": "学习资源",
|
||||
"font_class": "xuexiziyuan1",
|
||||
"unicode": "e7a8",
|
||||
"unicode_decimal": 59304
|
||||
},
|
||||
{
|
||||
"icon_id": "16767292",
|
||||
"name": "普通作业",
|
||||
"font_class": "putongzuoye1",
|
||||
"unicode": "e782",
|
||||
"unicode_decimal": 59266
|
||||
},
|
||||
{
|
||||
"icon_id": "16766394",
|
||||
"name": "实训作业",
|
||||
"font_class": "shixunzuoye1",
|
||||
"unicode": "e7a6",
|
||||
"unicode_decimal": 59302
|
||||
},
|
||||
{
|
||||
"icon_id": "15852679",
|
||||
"name": "Last updated",
|
||||
"font_class": "Lastupdated",
|
||||
"unicode": "e7a5",
|
||||
"unicode_decimal": 59301
|
||||
},
|
||||
{
|
||||
"icon_id": "15852678",
|
||||
"name": "CONTACTS",
|
||||
"font_class": "CONTACTS",
|
||||
"unicode": "e7a4",
|
||||
"unicode_decimal": 59300
|
||||
},
|
||||
{
|
||||
"icon_id": "15852677",
|
||||
"name": "SPONSORS",
|
||||
"font_class": "SPONSORS",
|
||||
"unicode": "e7a3",
|
||||
"unicode_decimal": 59299
|
||||
},
|
||||
{
|
||||
"icon_id": "15852676",
|
||||
"name": "FINAL REPORTS",
|
||||
"font_class": "FINALREPORTS",
|
||||
"unicode": "e7a2",
|
||||
"unicode_decimal": 59298
|
||||
},
|
||||
{
|
||||
"icon_id": "15852675",
|
||||
"name": "STEERING COMMITTEE",
|
||||
"font_class": "STEERINGCOMMITTEE",
|
||||
"unicode": "e7a1",
|
||||
"unicode_decimal": 59297
|
||||
},
|
||||
{
|
||||
"icon_id": "15852674",
|
||||
"name": "ORGANIZING ICSE - MOU",
|
||||
"font_class": "ORGANIZINGICSE-MOU",
|
||||
"unicode": "e7a0",
|
||||
"unicode_decimal": 59296
|
||||
},
|
||||
{
|
||||
"icon_id": "15852673",
|
||||
"name": "INFLUENTIAL PAPERS",
|
||||
"font_class": "INFLUENTIALPAPERS",
|
||||
"unicode": "e79f",
|
||||
"unicode_decimal": 59295
|
||||
},
|
||||
{
|
||||
"icon_id": "15852672",
|
||||
"name": "BIBLIOGRAPHIES",
|
||||
"font_class": "BIBLIOGRAPHIES",
|
||||
"unicode": "e79e",
|
||||
"unicode_decimal": 59294
|
||||
},
|
||||
{
|
||||
"icon_id": "15852671",
|
||||
"name": "PROCEEDINGS",
|
||||
"font_class": "PROCEEDINGS",
|
||||
"unicode": "e79d",
|
||||
"unicode_decimal": 59293
|
||||
},
|
||||
{
|
||||
"icon_id": "15852670",
|
||||
"name": "HISTORY",
|
||||
"font_class": "HISTORY",
|
||||
"unicode": "e79c",
|
||||
"unicode_decimal": 59292
|
||||
},
|
||||
{
|
||||
"icon_id": "15852669",
|
||||
"name": "CONDUCT & SAFETY",
|
||||
"font_class": "CONDUCTSAFETY",
|
||||
"unicode": "e79b",
|
||||
"unicode_decimal": 59291
|
||||
},
|
||||
{
|
||||
"icon_id": "15852667",
|
||||
"name": "EDI STATEMENT",
|
||||
"font_class": "EDISTATEMENT",
|
||||
"unicode": "e79a",
|
||||
"unicode_decimal": 59290
|
||||
},
|
||||
{
|
||||
"icon_id": "15852666",
|
||||
"name": "MAILING LIST",
|
||||
"font_class": "MAILINGLIST",
|
||||
"unicode": "e799",
|
||||
"unicode_decimal": 59289
|
||||
},
|
||||
{
|
||||
"icon_id": "15852665",
|
||||
"name": "HOME",
|
||||
"font_class": "HOME",
|
||||
"unicode": "e798",
|
||||
"unicode_decimal": 59288
|
||||
},
|
||||
{
|
||||
"icon_id": "15792809",
|
||||
"name": "准备中",
|
||||
|
@ -131,13 +684,6 @@
|
|||
"unicode": "e783",
|
||||
"unicode_decimal": 59267
|
||||
},
|
||||
{
|
||||
"icon_id": "15590916",
|
||||
"name": "普通作业",
|
||||
"font_class": "putongzuoye1",
|
||||
"unicode": "e782",
|
||||
"unicode_decimal": 59266
|
||||
},
|
||||
{
|
||||
"icon_id": "15590913",
|
||||
"name": "实训作业",
|
||||
|
|
|
@ -20,6 +20,243 @@ Created by iconfont
|
|||
/>
|
||||
<missing-glyph />
|
||||
|
||||
<glyph glyph-name="zhuye1" unicode="" d="M992.192 559.616L546.816 882.304A73.6 73.6 0 0 1 503.808 896c-15.104 0-30.336-4.48-42.88-13.568L27.712 570.368a62.272 62.272 0 0 1-26.752-50.432V-128h1017.792V509.44a62.08 62.08 0 0 1-26.496 50.176z m-363.584-615.616H390.976V256.576h237.632v-312.576z m311.808 0h-233.6V292.608c0 19.84-17.472 35.968-39.04 35.968H351.808c-21.632 0-39.168-16.064-39.168-35.968v-348.608h-233.6v572.16L503.808 821.76l436.608-316.416v-561.408z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="xiangmujianjie" unicode="" d="M399.847619-93.866667H175.542857C97.52381-93.866667 34.133333-30.47619 34.133333 47.542857V744.838095C34.133333 822.857143 97.52381 886.247619 175.542857 886.247619h653.409524c78.019048 0 141.409524-63.390476 141.409524-141.409524v-263.314285h-78.019048V744.838095c0 34.133333-29.257143 63.390476-63.390476 63.390476H175.542857c-34.133333 0-63.390476-29.257143-63.390476-63.390476v-702.171428c0-34.133333 29.257143-63.390476 63.390476-63.390477h229.180953v-73.142857zM785.066667 408.380952l-180.419048 146.285715L414.47619 408.380952V822.857143h78.019048v-253.561905L604.647619 652.190476 707.047619 569.295238V822.857143h78.019048zM575.390476-15.847619h385.219048v-78.019048h-385.219048zM575.390476 369.371429h385.219048v-78.019048h-385.219048zM575.390476 164.571429h385.219048v-78.019048h-385.219048z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="canyuchengyuan" unicode="" d="M307.2-118.690909H116.363636c-60.509091 0-107.054545 46.545455-107.054545 107.054545v791.272728C9.309091 840.145455 55.854545 886.690909 116.363636 886.690909h758.690909c60.509091 0 107.054545-46.545455 107.054546-107.054545v-167.563637h-74.472727V779.636364c0 18.618182-13.963636 32.581818-32.581819 32.581818H116.363636c-18.618182 0-32.581818-13.963636-32.581818-32.581818v-791.272728c0-18.618182 13.963636-32.581818 32.581818-32.581818h190.836364v-74.472727zM716.8 123.345455c-102.4 0-190.836364 83.781818-190.836364 190.836363 0 102.4 83.781818 190.836364 190.836364 190.836364s190.836364-83.781818 190.836364-190.836364c0-102.4-83.781818-190.836364-190.836364-190.836363z m0 307.2c-65.163636 0-116.363636-51.2-116.363636-116.363637S651.636364 197.818182 716.8 197.818182s116.363636 51.2 116.363636 116.363636-51.2 116.363636-116.363636 116.363637zM1014.690909-114.036364h-74.472727c0 130.327273-107.054545 237.381818-237.381818 237.381819S465.454545 16.290909 465.454545-114.036364H386.327273c0 172.218182 139.636364 311.854545 311.854545 311.854546s316.509091-139.636364 316.509091-311.854546zM162.909091 695.854545h386.327273v-74.472727H162.909091zM162.909091 453.818182h246.690909v-74.472727H162.909091z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shiyongwendang" unicode="" d="M861.090909-118.690909H162.909091c-69.818182 0-130.327273 55.854545-130.327273 121.018182V719.127273C32.581818 784.290909 93.090909 840.145455 162.909091 840.145455h121.018182c18.618182 0 37.236364-18.618182 37.236363-37.236364s-18.618182-37.236364-37.236363-37.236364H162.909091c-32.581818 0-55.854545-23.272727-55.854546-46.545454v-716.8c0-27.927273 23.272727-46.545455 55.854546-46.545455h698.181818c32.581818 0 55.854545 23.272727 55.854546 46.545455V719.127273c0 27.927273-23.272727 46.545455-55.854546 46.545454h-116.363636c-18.618182 0-37.236364 18.618182-37.236364 37.236364s18.618182 37.236364 37.236364 37.236364H861.090909c69.818182 0 130.327273-55.854545 130.327273-121.018182v-716.8c0-65.163636-60.509091-121.018182-130.327273-121.018182zM242.036364 584.145455h539.927272v-74.472728H242.036364zM242.036364 211.781818h539.927272v-74.472727H242.036364zM242.036364 397.963636h539.927272v-74.472727H242.036364zM581.818182 779.636364H442.181818c-27.927273 0-46.545455 18.618182-46.545454 46.545454s18.618182 46.545455 46.545454 46.545455h139.636364c27.927273 0 46.545455-18.618182 46.545454-46.545455s-18.618182-46.545455-46.545454-46.545454z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="daimaku" unicode="" d="M1024-128H0V561.664L512 896l512-334.336zM72-53.184h880V521.984L512 807.744 72 521.984zM307.136 105.344l-60.928 40.896L376.576 293.76l-146.56 128.768 55.552 47.616 193.664-171.008z m206.784 96h254.592v-67.072H514.048z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="forc" unicode="" d="M796.376006 894.867675a171.32651 171.32651 0 0 0 169.950598-142.687158 169.695799 169.695799 0 0 0-116.035236-188.550889 342.60206 342.60206 0 0 0-340.410792-291.5914h-229.318648v-66.24761a170.256356 170.256356 0 0 0 114.353565-150.229194l0.305759-10.19194a171.683228 171.683228 0 1 0-229.318648 160.268255V564.750742a169.695799 169.695799 0 0 0-112.111339 188.907606 172.345704 172.345704 0 0 0 339.034881 0 169.695799 169.695799 0 0 0-112.111339-189.009526v-179.378142h229.318648a228.605212 228.605212 0 0 1 224.630355 181.263651 169.491961 169.491961 0 0 0-107.423046 189.672002A171.32651 171.32651 0 0 0 796.376006 894.867675zM223.283225 102.138589a56.616226 56.616226 0 1 1 57.329662-56.616226 56.972944 56.972944 0 0 1-57.329662 56.616226z m0 679.496634a56.616226 56.616226 0 1 1 57.329662-56.616226 56.972944 56.972944 0 0 1-57.329662 56.616226z m573.092781 0a56.616226 56.616226 0 1 1 57.329662-56.616226 56.972944 56.972944 0 0 1-57.329662 56.616226z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="dianzan3" unicode="" d="M1068.085662 794.870057a352.143618 352.143618 0 0 1-482.689072 10.604533 352.143618 352.143618 0 0 1-482.689072-10.604533 343.733127 343.733127 0 0 1-3.364196-486.784615l3.217927-3.217927 404.288665-400.119987a109.702062 109.702062 0 0 1 155.04558-1.462694l1.462695 1.389559 404.288665 399.827448a343.733127 343.733127 0 0 1 3.437331 486.784616l-3.437331 3.510466z m-52.364451-438.808247l-404.21553-399.754313a36.567354 36.567354 0 0 0-51.706239 0L154.998834 356.427484a271.476036 271.476036 0 0 0-2.559714 384.396024l2.559714 2.559715a277.91189 277.91189 0 0 0 380.739289 6.21645l49.731602-42.783804 49.292793 42.710669a277.91189 277.91189 0 0 0 380.885558-7.898548 271.69544 271.69544 0 0 0 0.731347-384.688563l-0.658212-0.585078z" horiz-adv-x="1171" />
|
||||
|
||||
|
||||
<glyph glyph-name="lichengbei" unicode="" d="M677.82464 694.784a97.6 97.6 0 1 0 0-192h-345.6a97.6 97.6 0 1 0 0 192z m0-68.608h-345.6a27.904 27.904 0 1 1 0-54.848h345.6a27.904 27.904 0 1 1 0 54.848zM521.28064-128a39.232 39.232 0 0 0-13.696 2.496l-323.264 120.512C173.12064-1.28 63.87264 37.696 63.87264 122.56V673.344a21.632 21.632 0 0 0 0 2.752 24.96 24.96 0 0 1 0 3.072C64.12864 802.752 256.44864 896 512.12864 896s448-93.248 448-216.832a22.016 22.016 0 0 0 0-2.816 24.192 24.192 0 0 1 0-2.944v-550.848c0-66.752-78.912-111.616-94.784-119.872a35.072 35.072 0 0 0-4.032-1.856l-325.632-126.144a39.36 39.36 0 0 0-14.208-2.624zM140.92864 671.68v-549.12c0-23.872 45.44-48.96 69.824-57.088l310.528-115.776 309.376 119.872c25.152 13.888 52.608 38.976 52.608 52.992V671.424v6.08 3.52c-2.88 66.496-160.64 140.096-371.2 140.096S143.55264 747.52 140.92864 680.96a41.024 41.024 0 0 0 0-9.344zM741.69664 233.344H281.98464a34.048 34.048 0 1 0 0 65.664h459.712a34.048 34.048 0 1 0 0-65.664z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="quxiaodianzan" unicode="" d="M511.851263 19.736907a32.884449 32.884449 0 0 0 16.186315-4.222516l247.784965-137.999528a45.871887 45.871887 0 0 1 48.047124 2.687056 43.504719 43.504719 0 0 1 17.84973 42.673011L793.352386 221.330098a36.211281 36.211281 0 0 0 9.596629 30.901146l208.310831 215.092449a43.568696 43.568696 0 0 1 10.108449 44.208471 44.272449 44.272449 0 0 1-35.507528 29.749551l-284.124201 43.760629a34.291955 34.291955 0 0 0-25.591011 19.641101L552.540971 869.998253a44.78427 44.78427 0 0 1-81.123505 0l-123.476629-265.250831a34.291955 34.291955 0 0 0-25.591011-19.641101l-284.188179-43.760629a44.78427 44.78427 0 0 1-35.507528-29.813528 43.440741 43.440741 0 0 1 10.108449-44.080516l208.246853-215.156427a36.275258 36.275258 0 0 0 9.59663-30.901146l-48.303034-298.327212a43.568696 43.568696 0 0 1 17.977685-42.800966 45.80791 45.80791 0 0 1 48.047124-2.495124l247.65701 137.871573A32.820472 32.820472 0 0 0 511.851263 19.736907z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="fork2" unicode="" d="M808.294199 889.365588a139.04645 139.04645 0 0 1-140.75293-137.466377 137.655986 137.655986 0 0 1 90.506599-128.365155v-33.876771L506.626604 274.021842 255.268544 589.657285v33.876771a137.655986 137.655986 0 0 1 90.506598 128.365155 140.816133 140.816133 0 1 1-181.013197-131.71491v-42.219559a53.406478 53.406478 0 0 1 11.692542-33.118336l284.918818-357.855001v-41.208312a140.816133 140.816133 0 1 1 90.506598 0v41.208312l284.918818 357.855001a53.406478 53.406478 0 0 1 11.692542 33.118336v42.219559a137.08716 137.08716 0 0 1-40.197064 269.118084z m-663.630787-137.466377a60.3588 60.3588 0 1 0 60.358801-58.905133 59.600365 59.600365 0 0 0-60.358801 58.905133z m422.321992-736.314158A60.3588 60.3588 0 1 0 506.626604 74.490186a59.600365 59.600365 0 0 0 60.3588-58.905133z m241.308795 677.409025a58.905133 58.905133 0 1 0 60.3588 58.905133 59.600365 59.600365 0 0 0-60.3588-58.905133z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="hebingqingqiu1" unicode="" d="M724.710387 544.712656a22.806357 22.806357 0 0 0-37.511352-17.291984L492.221699 691.626445a22.602121 22.602121 0 0 0 0 34.583969L687.199035 890.416187a22.874436 22.874436 0 0 0 32.133137-2.655069 22.602121 22.602121 0 0 0 5.378215-14.636916v-123.494723h77.473537a145.484136 145.484136 0 0 0 145.892608-142.965225v-374.432733a182.38278 182.38278 0 1 0-82.034808 0V604.553815a63.653565 63.653565 0 0 1-62.768542 63.449328h-78.562795z m182.382781-389.00157a99.735264 99.735264 0 1 1 100.279893-99.735265 100.007579 100.007579 0 0 1-100.279893 99.667186zM182.599868 890.143872a181.293521 181.293521 0 0 0 40.847208-358.09385v-299.546187a182.38278 182.38278 0 1 0-82.034808 0v299.546187a181.293521 181.293521 0 0 0 40.847207 358.09385z m0-734.500865a99.735264 99.735264 0 1 1 100.279894-99.735264 100.007579 100.007579 0 0 1-100.279894 99.735264z m0 652.942608a99.735264 99.735264 0 1 1 100.279894-99.735264 100.007579 100.007579 0 0 1-100.279894 99.599107z" horiz-adv-x="1092" />
|
||||
|
||||
|
||||
<glyph glyph-name="renwu" unicode="" d="M983.055019-128H40.975019a42.325333 42.325333 0 0 0-40.96 43.281067V754.2784a42.325333 42.325333 0 0 0 40.96 43.4176h214.903466v-77.277867H73.196885v-771.413333h877.636267v771.413333h-182.749867V797.764267H983.055019a42.325333 42.325333 0 0 0 40.96-43.4176v-838.929067a42.3936 42.3936 0 0 0-40.96-43.4176z m-217.770667 441.7536L427.023019 72.704a39.799467 39.799467 0 0 0-58.231467 0l-132.642133 139.810133a44.714667 44.714667 0 0 0-12.014934 30.651734 42.325333 42.325333 0 0 0 40.96 43.4176 39.936 39.936 0 0 0 29.149867-12.765867l103.492267-109.226667 309.111466 210.466134a40.072533 40.072533 0 0 0 29.0816 12.629333 42.257067 42.257067 0 0 0 40.96-43.4176 44.032 44.032 0 0 0-11.810133-30.5152z m-362.973867 484.010667h219.477334v-77.277867H402.310485z m0 0M49.644885 502.3744h875.042134v-98.372267H49.644885zM312.130219 896h35.0208c9.6256 0 17.544533-10.990933 17.544533-24.644267v-196.744533c0-13.653333-7.850667-24.644267-17.544533-24.644267h-35.0208c-9.6256 0-17.544533 10.990933-17.544534 24.644267V871.355733c0.136533 13.653333 7.645867 24.644267 17.544534 24.644267zM662.201685 896h35.0208c9.6256 0 17.544533-10.990933 17.544534-24.644267v-196.744533c0-13.653333-7.850667-24.644267-17.544534-24.644267H662.201685c-9.6256 0-17.544533 10.990933-17.544533 24.644267V871.355733c0 13.653333 7.918933 24.644267 17.544533 24.644267z m0 0" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="tongzhi" unicode="" d="M965.27314 383.870204a285.184828 285.184828 0 0 1-146.24863 248.622671c-7.312431 0-14.624863 7.312431-21.937295 7.312432a34.075931 34.075931 0 0 1-36.562157-35.538418 36.562157 36.562157 0 0 1 14.624863-28.445358A211.183021 211.183021 0 0 0 884.836393 391.182636a207.234308 207.234308 0 0 0-116.998904-191.951327 36.562157 36.562157 0 0 1-14.624863-28.445358 34.075931 34.075931 0 0 1 36.562158-35.538417 25.739759 25.739759 0 0 1 14.624863 7.312431A266.757501 266.757501 0 0 1 965.27314 383.870204z m-43.874589 419.441071c-7.312431 0-14.624863 7.312431-21.937295 7.312431a34.075931 34.075931 0 0 1-36.562157-35.538417c0-14.186117 7.312431-21.3523 21.937294-28.445358a416.004227 416.004227 0 0 0 0-725.173831c-14.624863-7.312431-21.937294-14.186117-21.937294-28.445359a34.075931 34.075931 0 0 1 36.562157-35.538417 27.348494 27.348494 0 0 1 21.937295 7.312432 478.159895 478.159895 0 0 1 0 838.88214zM87.781361 618.453007h175.498356c21.937294 0 58.499452 7.312431 212.060513 120.874492a557.865398 557.865398 0 0 0 80.436746 56.890717v-440.79337a36.562157 36.562157 0 0 1 73.124315 0v504.557773a38.97526 38.97526 0 0 1-21.937294 35.538417 111.222083 111.222083 0 0 1-51.187021-7.312432L424.153209 789.125158a567.810305 567.810305 0 0 0-160.873492-99.522193h-219.372945c-29.249726 0-43.874589-14.186117-43.874589-35.538417v-540.315563a34.075931 34.075931 0 0 1 36.562157-35.538417H292.529442c7.312431 0 36.562157-14.186117 146.24863-99.522193L555.776976-120.687569c7.312431-7.312431 14.624863-7.312431 29.249726-7.312431 7.312431 0 14.624863 0 14.624863 7.312431a38.97526 38.97526 0 0 1 21.937295 35.538418v191.731953A33.198439 33.198439 0 0 1 585.026702 135.247534a34.075931 34.075931 0 0 1-36.562157-35.538417v-120.874493a333.373752 333.373752 0 0 0-51.187021 49.797659c-138.936198 113.781434-175.498356 120.874493-197.43565 120.874492H109.718655c-21.937294 0-29.249726 7.312431-29.249726 28.445359V590.007648c-14.624863 21.3523-7.312431 28.445358 7.312432 28.445359z" horiz-adv-x="1170" />
|
||||
|
||||
|
||||
<glyph glyph-name="jinbi" unicode="" d="M0 384c0-283.29 228.71-512 512-512s512 228.71 512 512S795.29 896 512 896 0 667.29 0 384zM119.45 384c0-139.93 75.11-269.67 194.56-337.92 119.5-68.25 269.67-71.68 392.55 0S901.12 244.07 901.12 384c0 215.04-174.08 392.55-392.55 392.55-218.42 0-389.12-177.51-389.12-392.55zM904.55 384c0 85.35-27.34 167.27-78.54 232.09-61.44 47.82-146.74 75.11-228.66 75.11A390.4 390.4 0 0 1 204.8 298.65c0-85.3 27.29-167.22 78.49-232.09 61.44-47.77 146.79-78.49 232.14-78.49A394.854 394.854 0 0 1 904.55 384zM552.96 609.28l85.35-170.65 180.89-34.15-126.31-139.93 20.48-187.75-160.41 81.92-167.27-81.92 27.34 187.75-126.31 139.93 177.51 34.15 88.73 170.65M512 650.24l92.16-167.27 174.08-37.53-126.31-139.93 20.48-187.75L512 203.11l-160.41-85.35 20.48 187.75-126.31 139.93 174.08 37.53L512 650.24" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="weikaishexiangtou1" unicode="" d="M516.877174 39.855494A428.075239 428.075239 0 1 1 94.646693 467.930733a425.046204 425.046204 0 0 1 422.230481-428.075239z m0 781.149854a354.098514 354.098514 0 1 0-346.7819-354.098514A350.57886 350.57886 0 0 0 516.877174 820.984017z m0 0M937.721124 173.026399a45.179557 45.179557 0 0 1-42.065197-79.650834c30.780973-16.553039 37.9696-28.967818 38.993499-31.996854-3.071698-29.991717-149.787938-98.273003-422.699768-98.273003-268.773571 0-419.606739 70.393078-421.675868 98.273003 0 2.133124 7.188626 14.483909 36.9457 31.036948a45.712838 45.712838 0 0 1 16.425052 62.073896 44.795595 44.795595 0 0 1-59.514148 17.576938C15.401152 134.822156 0 91.370429 0 61.378711c0-130.333851 265.723204-189.314717 511.949658-189.314717s511.949658 58.959536 511.949659 189.314717c0 29.927724-14.355922 73.379451-86.178193 111.647688zM511.949658 728.534441a222.420795 222.420795 0 1 1 220.586309-222.399464A221.162252 221.162252 0 0 1 511.949658 728.534441z m-75.917868-223.53002a91.041714 91.041714 0 1 0 90.27379 91.020383 91.468339 91.468339 0 0 0-90.27379-91.020383z m0 0M983.668606 837.409068L50.640354-73.925317a13.694653 13.694653 0 0 0-19.006131 0l-21.331236 20.883279a12.94806 12.94806 0 0 0 0 18.558176L943.331239 876.850523a13.694653 13.694653 0 0 0 19.006131 0l21.331236-20.88328a12.94806 12.94806 0 0 0 0-18.558175z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="guankacaidan" unicode="" d="M0-128V896h1024v-1024H0z m731.428571 694.857143H292.571429v-36.571429h438.857142v36.571429z m0-164.571429H292.571429v-36.571428h438.857142v36.571428z m0-164.571428H292.571429v-36.571429h438.857142v36.571429z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="zhongzhishixun" unicode="" d="M758.328889 384a108.544 108.544 0 1 1-109.226667-113.777778h1.137778a110.876444 110.876444 0 0 1 108.088889 113.777778z m-108.088889 512a499.939556 499.939556 0 0 1-487.537778-512H0l216.746667-227.555556 216.746666 227.555556H270.791111a380.074667 380.074667 0 1 0 758.897778 5.688889 406.243556 406.243556 0 0 0-205.368889-359.651556 364.544 364.544 0 0 0-394.24 29.866667l-76.8-81.92a468.707556 468.707556 0 0 1 576.284444-13.198222A525.198222 525.198222 0 0 1 1115.022222 538.112 490.439111 490.439111 0 0 1 650.24 896z" horiz-adv-x="1138" />
|
||||
|
||||
|
||||
<glyph glyph-name="fuzhiniantie" unicode="" d="M872.106667 896H397.084444a151.552 151.552 0 0 1-151.324444-151.722667v-475.136a151.552 151.552 0 0 1 151.324444-151.665777h475.022223A152.007111 152.007111 0 0 1 1024 269.141333V744.277333A152.064 152.064 0 0 1 872.106667 896z m62.008889-626.858667a61.781333 61.781333 0 0 0-62.008889-62.065777H397.084444a62.179556 62.179556 0 0 0-62.008888 62.065777V744.277333a62.179556 62.179556 0 0 0 62.008888 62.122667h475.022223a61.838222 61.838222 0 0 0 62.008889-62.122667v-475.136z m-245.191112-245.475555a62.122667 62.122667 0 0 0-62.008888-62.065778H151.893333a62.577778 62.577778 0 0 0-62.577777 62.065778V498.801778a62.577778 62.577778 0 0 0 62.577777 62.122666h35.271111V650.524444h-35.271111A152.064 152.064 0 0 1 0 498.801778v-475.136A152.007111 152.007111 0 0 1 151.893333-128h475.022223a151.552 151.552 0 0 1 151.324444 151.665778v35.669333h-89.315556v-35.669333z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="gongxiangzhuomian" unicode="" d="M942.084119 257.42158A92.842512 92.842512 0 0 1 1024.003982 353.449864V796.386015A98.531391 98.531391 0 0 1 928.999696 895.998293H282.742995A94.435398 94.435398 0 0 1 187.738709 801.107785l81.919864 0.625777h672.994434v-450.04725z m-163.839727 490.950293H95.009975A98.58828 98.58828 0 0 1 0.005689 648.759594v-480.312088a92.44429 92.44429 0 0 1 95.004286-92.501179h299.235057v-141.08421H209.925339a33.393722 33.393722 0 0 1-23.893293-33.223055 29.183951 29.183951 0 0 1 23.893293-29.639062h452.265913a29.695951 29.695951 0 0 1 24.462181 29.639062 33.791944 33.791944 0 0 1-24.462181 33.223055H469.907128v141.08421h308.337264a92.44429 92.44429 0 0 1 95.004286 92.501179V648.759594A98.190059 98.190059 0 0 1 778.244392 748.087429z m13.65331-578.103926H81.356664v483.55475h710.541038v-483.55475zM473.889344 477.979434l-12.515535-27.875509s-10.808871-27.249732 24.462181-21.333297l98.986502 23.722627a17.91997 17.91997 0 0 1 12.515535 26.055067l-54.044355 97.279838a17.066638 17.066638 0 0 1-27.875509-2.958217l-11.946647-27.875509s-182.044141 74.694987-225.848512-120.376688c0 0 48.924363 112.070924 196.26634 53.361688zM412.449446 350.491647l11.946647 27.875509s9.671095 27.249732-24.462182 20.76441l-98.986501-26.111957a17.46486 17.46486 0 0 1-11.946647-26.055067l56.319906-95.459397a16.725305 16.725305 0 0 1 27.306621 3.527106l11.377759 27.875509s183.750805-69.973217 222.435185 126.293122c0.568888 0-44.942147-113.265589-193.990788-58.709235z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="tuichuquanping" unicode="" d="M604.728889-9.614222l-3.413333 304.014222 304.355555-3.185778-115.484444-115.2L1024-57.628444 953.457778-128l-233.244445 233.585778z m-185.457778 0l2.844445 304.014222-303.786667-3.185778 115.484444-115.2L0-57.628444 70.542222-128l233.244445 233.585778z m185.457778 787.228444l-3.413333-304.014222 304.355555 3.185778-115.484444 115.2L1024 825.628444 953.457778 896l-233.244445-233.585778z m-185.457778 0l2.844445-304.014222-303.786667 3.185778 115.484444 115.2L0 825.628444 70.542222 896l233.244445-233.585778z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="quanping" unicode="" d="M731.022222 896l116.053334-116.224-225.848889-226.417778 56.888889-56.888889 225.848888 226.417778L1024 602.510222V896h-292.977778z m-43.804444-620.088889l-56.888889-56.888889L853.333333-5.233778 731.591111-128H1024v294.172444l-113.777778-114.232888-223.004444 224.199111zM336.782222 491.633778l56.888889 56.888889L170.666667 772.778667 292.408889 895.601778H0v-294.172445L113.777778 715.662222z m9.102222-220.16l-225.848888-226.474667L0 165.432889V-128h292.977778l-116.053334 116.224 225.848889 226.417778z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="fuzhibanbenkudizhi1" unicode="" d="M796.444444-128H227.555556a170.666667 170.666667 0 0 0-170.666667 170.666667V668.444444a170.666667 170.666667 0 0 0 170.666667 170.666667v-113.777778a56.888889 56.888889 0 0 1-56.888889-56.888889v-625.777777a56.888889 56.888889 0 0 1 56.888889-56.888889h568.888888a56.888889 56.888889 0 0 1 56.888889 56.888889V668.444444a56.888889 56.888889 0 0 1-56.888889 56.888889V839.111111a170.666667 170.666667 0 0 0 170.666667-170.666667v-625.777777a170.666667 170.666667 0 0 0-170.666667-170.666667zM284.444444 896h455.111112v-341.333333H284.444444V896z m113.777778-227.555556h227.555556V782.222222H398.222222v-113.777778z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shiyanhuanjingdaojishi" unicode="" d="M512 896a512 512 0 1 1 512-512 513.536 513.536 0 0 1-512 512z m0-953.628444A441.628444 441.628444 0 1 0 953.457778 384 442.197333 442.197333 0 0 0 512-57.628444z m153.6 230.4a38.912 38.912 0 0 1 51.2 0 39.822222 39.822222 0 0 1 0 51.2L556.942222 396.8c0 6.371556-6.826667 6.371556-6.826666 12.8v307.2A40.903111 40.903111 0 0 1 512 755.2a41.472 41.472 0 0 1-38.684444-38.4v-326.428444a59.221333 59.221333 0 0 1 19.342222-44.771556l172.942222-172.828444z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="vncshixunjiemian-gongjulan" unicode="" d="M1069.401234 738.420432h-164.474038V817.201576A80.253091 80.253091 0 0 1 823.010166 895.982721H328.948076a80.253091 80.253091 0 0 1-81.917031-78.781145v-78.781144H82.557007A80.82907 80.82907 0 0 1 0 659.639288v-708.838305A80.82907 80.82907 0 0 1 82.557007-127.980161h986.844227A80.82907 80.82907 0 0 1 1151.958242-49.199017V659.703286a80.82907 80.82907 0 0 1-82.557008 78.717146zM328.948076 817.201576h494.06209v-78.781144H328.948076V817.201576z m740.453158-866.400593H82.557007V265.861563h369.906591v-39.358574a80.82907 80.82907 0 0 1 82.557008-78.781144h81.91703a80.82907 80.82907 0 0 1 82.557007 78.781144v39.358574h369.906591v-315.06058z m-534.380628 275.702006V384.00128h81.91703v-157.562288H535.020606z m164.474037 118.139718V384.00128a80.82907 80.82907 0 0 1-82.557007 78.781144H535.020606A80.82907 80.82907 0 0 1 452.463598 384.00128v-39.358573H82.557007V659.703286h986.844227v-315.060579h-369.906591z" horiz-adv-x="1152" />
|
||||
|
||||
|
||||
<glyph glyph-name="vncshixunjiemian-zhankai" unicode="" d="M359.799168 896h204.8a51.2 51.2 0 0 0 51.2-51.2v-921.6a51.2 51.2 0 0 0-51.2-51.2H359.799168V896zM410.999168 473.6m12.8 0l0 0q12.8 0 12.8-12.8l0-153.6q0-12.8-12.8-12.8l0 0q-12.8 0-12.8 12.8l0 153.6q0 12.8 12.8 12.8ZM551.799168 396.8l-89.6-102.4V473.6l89.6-76.8" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="vncshixunjiemian-shouqi" unicode="" d="M375.43616 896h204.8v-1024H375.43616a51.2 51.2 0 0 0-51.2 51.2V844.8a51.2 51.2 0 0 0 51.2 51.2zM503.43616 473.6m12.8 0l0 0q12.8 0 12.8-12.8l0-153.6q0-12.8-12.8-12.8l0 0q-12.8 0-12.8 12.8l0 153.6q0 12.8 12.8 12.8ZM388.23616 396.8l89.6-102.4V473.6l-89.6-76.8" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="chexiaofenzu" unicode="" d="M1228.790784-127.995733H51.199616a50.602287 50.602287 0 0 0-51.199616 49.919625V846.076961A50.602287 50.602287 0 0 0 51.199616 895.996587h406.695616a13.3119 13.3119 0 0 0 8.53327-3.413308l187.731925-175.188019H1228.790784a50.602287 50.602287 0 0 0 51.199616-49.919626v-745.551742a50.602287 50.602287 0 0 0-51.199616-49.919625zM426.663467 384.000427v-85.332694h426.663466V384.000427z" horiz-adv-x="1280" />
|
||||
|
||||
|
||||
<glyph glyph-name="chexiaogongxiang" unicode="" d="M1190.570667-128h-1100.8c-59.733333 0-89.429333 24.064-89.429334 71.594667V824.405333C0.341333 871.936 30.464 896 89.770667 896h1100.8c59.733333 0 89.429333-24.064 89.429333-71.594667v-880.810666c0-47.445333-30.122667-71.594667-89.429333-71.594667zM267.434667 625.92l-9.642667-218.965333-9.130667-204.8a13.482667 13.482667 0 0 1 3.584-9.728 13.312 13.312 0 0 1 9.642667-4.096h375.466667a13.312 13.312 0 0 1 12.032 7.68 13.397333 13.397333 0 0 1-1.962667 14.250666L550.912 322.389333a10.069333 10.069333 0 0 1 1.194667 1.450667 372.650667 372.650667 0 0 0 294.997333 187.733333 276.48 276.48 0 0 0 89.941333-15.36 15.701333 15.701333 0 0 1 5.12-0.853333 14.592 14.592 0 0 1 13.482667 8.533333 11.434667 11.434667 0 0 1-2.986667 12.970667 398.421333 398.421333 0 0 1-270.165333 123.904A409.6 409.6 0 0 1 392.789333 496.64a12.117333 12.117333 0 0 1-1.962666-2.56L267.349333 626.261333z" horiz-adv-x="1280" />
|
||||
|
||||
|
||||
<glyph glyph-name="xuanzhong1" unicode="" d="M943.108257-127.946108h-862.270406A80.837851 80.837851 0 0 0 0-47.108257v862.270406A80.837851 80.837851 0 0 0 80.837851 896h862.270406A80.837851 80.837851 0 0 0 1023.946108 815.162149v-862.270406a80.837851 80.837851 0 0 0-80.837851-80.837851zM258.142203 434.63144l-69.574443-53.460765L459.913478 114.567444A1603.176254 1603.176254 0 0 0 835.324457 615.762118l-16.490922 37.72433v-0.377243a1722.277354 1722.277354 0 0 1-403.54255-337.201621l-157.148782 118.562181z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="jingshi1" unicode="" d="M512 896A512 512 0 1 0 0 384 512.605091 512.605091 0 0 0 512 896z m-28.392727-256a13.451636 13.451636 0 0 1-13.591273-13.963636l15.592727-328.517819a7.493818 7.493818 0 0 1 7.447273-6.981818h52.177455a7.540364 7.540364 0 0 1 7.447272 6.981818l15.546182 328.517819a13.312 13.312 0 0 1-13.591273 13.963636H483.607273z m35.514182-512a49.943273 49.943273 0 1 1-49.757091 49.943273 49.850182 49.850182 0 0 1 49.757091-49.943273z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shanchu21" unicode="" d="M519.469714 896a192.512 192.512 0 0 1-191.780571-186.916571H85.549714a49.225143 49.225143 0 0 1 0-98.450286h53.979429v-550.729143c0-103.387429 69.485714-187.904 155.721143-187.904h438.637714c85.942857 0 155.721143 84.114286 155.721143 187.904V610.304h48.932571a49.225143 49.225143 0 0 1 0 98.450286h-227.620571A191.963429 191.963429 0 0 1 519.469714 896z m-100.132571-186.916571a100.205714 100.205714 0 0 0 200.082286 0z m-124.342857-745.033143c-30.500571 0-64.073143 39.387429-64.073143 95.853714V610.304h566.857143v-550.912c0-56.283429-33.609143-95.853714-64.073143-95.853714H295.067429z m0 0M355.300571 78.518857a48.018286 48.018286 0 0 1 42.24 52.224v297.728a43.190857 43.190857 0 1 1-84.48 0v-297.910857a47.762286 47.762286 0 0 1 42.24-52.041143z m152.905143 0a48.018286 48.018286 0 0 1 42.24 52.224v297.728a43.190857 43.190857 0 1 1-84.48 0v-297.910857a48.128 48.128 0 0 1 42.24-52.041143z m160.914286 0a48.018286 48.018286 0 0 1 42.24 52.224v297.728a43.190857 43.190857 0 1 1-84.48 0v-297.910857a47.542857 47.542857 0 0 1 42.203429-52.041143z m0 0" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shoucang3" unicode="" d="M797.52334 896A304.639238 304.639238 0 0 1 554.66528 769.706982 303.743241 303.743241 0 0 1 311.80722 896C139.775651 896 0 743.979047 0 557.39818a447.657548 447.657548 0 0 1 90.453107-252.543369c116.991708-182.82621 411.732304-409.598976 424.361606-419.028286a64.341172 64.341172 0 0 1 79.701134 0c12.799968 9.42931 306.7299 236.842075 424.361606 419.028286A447.657548 447.657548 0 0 1 1109.33056 557.39818C1109.33056 743.979047 969.554909 896 797.52334 896z" horiz-adv-x="1109" />
|
||||
|
||||
|
||||
<glyph glyph-name="sousuo2" unicode="" d="M475.189041-54.326884a475.163442 475.163442 0 1 0 475.163441 475.163442 475.163442 475.163442 0 0 0-475.163441-475.163442z m0 814.551273a339.387831 339.387831 0 1 1 339.38783-339.387831 339.387831 339.387831 0 0 1-339.38783 339.387831zM958.288086-127.79521a65.481526 65.481526 0 0 0-46.436079 19.250237L772.543773 30.763262a65.686316 65.686316 0 1 0 92.872156 92.872156l139.308235-139.308234a65.686316 65.686316 0 0 0-46.436078-112.122394z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="guangbiao" unicode="" d="M0 541.675558m59.054074 0l1653.514063 0q59.054074 0 59.054074-59.054074l0 0q0-59.054074-59.054074-59.054074l-1653.514063 0q-59.054074 0-59.054074 59.054074l0 0q0 59.054074 59.054074 59.054074ZM874.827048 891.629999a29.527037 29.527037 0 0 0 21.909061 0l437.000145-174.859113a29.527037 29.527037 0 0 0-10.925003-56.987181h-874.000291a29.527037 29.527037 0 0 0-10.984058 56.928127zM896.795163 73.61297a29.527037 29.527037 0 0 0-21.909061 0l-437.000146 174.859112a29.527037 29.527037 0 0 0 10.925004 56.987181h874.000291a29.527037 29.527037 0 0 0 10.984057-56.928127z" horiz-adv-x="2194" />
|
||||
|
||||
|
||||
<glyph glyph-name="QQ" unicode="" d="M510.72 886.016c-276.992 0-501.76-224.768-501.76-501.76s224.768-501.76 501.76-501.76 501.76 224.768 501.76 501.76S787.712 886.016 510.72 886.016z m230.912-636.672c-10.496-5.376-26.88 6.912-42.496 29.952-6.144-25.088-21.248-47.616-42.752-65.792 22.784-8.448 37.376-22.016 37.376-37.632 0-25.344-40.192-46.08-89.6-46.08-44.544 0-81.664 16.896-88.32 38.656h-10.752c-6.912-22.016-43.776-38.656-88.32-38.656-49.408 0-89.6 20.48-89.6 46.08 0 15.616 14.848 29.184 37.376 37.632-21.504 18.176-36.864 40.96-42.752 65.792-15.36-23.04-32-35.584-42.496-29.952-15.36 7.936-12.288 50.688 6.912 95.488 14.848 35.072 35.328 61.184 50.688 66.816-0.256 2.304-0.256 4.608-0.256 6.656 0 13.568 3.84 26.112 10.24 36.352v2.304c0 6.144 1.536 12.032 4.096 17.152 3.84 91.392 63.488 164.096 159.744 164.096s155.904-72.704 159.744-164.096c2.56-5.12 4.096-11.008 4.096-17.152v-2.304c6.4-10.24 10.24-22.784 10.24-36.352 0-2.304 0-4.608-0.256-6.656 15.616-5.632 35.84-31.744 50.688-66.816 18.688-44.8 21.76-87.552 6.4-95.488z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="yonghu" unicode="" d="M637.953132 347.721749c71.730695 40.298821 120.348995 116.815519 120.348995 204.542536 0 129.46256-105.705484 234.781234-235.641835 234.781234-129.936351 0-235.628532-105.318674-235.628532-234.781234 0-84.393085 45.041846-158.307516 112.302739-199.683878-152.041812-47.787376-262.605953-189.523471-262.605953-356.600721 0-5.058203 0.560772-9.956769 0.762363-14.97404l52.356438 0c-0.230244 4.986571-0.76134 9.914814-0.76134 14.97404 0 177.279612 144.855132 321.502341 322.909387 321.502341 178.054255 0 322.910411-144.222729 322.910411-321.502341 0-5.058203-0.532119-9.987468-0.775666-14.97404l52.371788 0c0.200568 5.016247 0.760317 9.914814 0.760317 14.97404C887.263268 158.068318 783.009855 295.982364 637.953132 347.721749zM339.389222 552.264285c0 100.588953 82.208327 182.423773 183.27107 182.423773 101.06479 0 183.272094-81.83482 183.272094-182.423773 0-100.589976-82.207303-182.423773-183.272094-182.423773C421.597549 369.840512 339.389222 451.674309 339.389222 552.264285z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="oschina" unicode="" d="M996.072727 211.781818C923.927273 13.963636 735.418182-128 512-128 230.4-128 0 100.072727 0 384S230.4 896 512 896c221.090909 0 411.927273-141.963636 481.745455-339.781818l-321.163637-116.363637c-23.272727 65.163636-86.109091 114.036364-160.581818 114.036364-95.418182 0-169.890909-76.8-169.890909-169.890909s76.8-169.890909 169.890909-169.890909c74.472727 0 137.309091 46.545455 160.581818 114.036364l323.490909-116.363637z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="you" unicode="" d="M972.772848 435.172848a72.405869 72.405869 0 0 0 0-102.381899L563.172848-76.809051a72.405869 72.405869 0 1 0-102.381899 102.418102l358.409051 358.40905-358.409051 358.372848a72.405869 72.405869 0 0 0 102.381899 102.381899z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="zuo" unicode="" d="M460.807241-76.807241L51.228963 332.807241a72.408429 72.408429 0 0 0 0 102.385518L460.807241 844.807241a72.408429 72.408429 0 0 0 102.421722 0 72.408429 72.408429 0 0 0 0-102.421723l-358.421722-358.421722 358.421722-358.385519a72.408429 72.408429 0 0 0 0-102.385518 72.408429 72.408429 0 0 0-102.421722 0z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="bianchengyuyan" unicode="" d="M969.386667-114.346667H259.413333C157.013333-114.346667 68.266667-32.426667 68.266667 76.8V704.853333C68.266667 814.08 150.186667 896 259.413333 896h716.8C1078.613333 896 1160.533333 814.08 1160.533333 704.853333v-634.88c0-102.4-81.92-184.32-191.146666-184.32zM259.413333 793.6c-47.786667 0-81.92-40.96-81.92-81.92V76.8c0-47.786667 40.96-81.92 81.92-81.92h716.8c47.786667 0 81.92 40.96 81.92 81.92V704.853333c0 47.786667-40.96 81.92-81.92 81.92H259.413333zM54.613333 561.493333h1112.746667v-102.4H54.613333zM273.066667 670.72m-68.266667 0a68.266667 68.266667 0 1 1 136.533333 0 68.266667 68.266667 0 1 1-136.533333 0ZM498.346667 670.72m-68.266667 0a68.266667 68.266667 0 1 1 136.533333 0 68.266667 68.266667 0 1 1-136.533333 0ZM750.933333 670.72m-68.266666 0a68.266667 68.266667 0 1 1 136.533333 0 68.266667 68.266667 0 1 1-136.533333 0ZM384.477867 62.805333c-6.826667 0-13.653333 0-20.48 6.826667l-129.706667 102.4c-6.826667 6.826667-13.653333 13.653333-13.653333 27.306667 0 6.826667 6.826667 20.48 13.653333 27.306666l129.706667 122.88c13.653333 13.653333 34.133333 13.653333 47.786666 0 13.653333-13.653333 13.653333-34.133333 0-47.786666l-102.4-95.573334 102.4-81.92c6.826667-13.653333 13.653333-34.133333 0-47.786666-6.826667-6.826667-13.653333-13.653333-27.306666-13.653334zM814.557867 62.805333c-13.653333 0-20.48 6.826667-27.306667 13.653334-13.653333 13.653333-6.826667 34.133333 6.826667 47.786666l102.4 81.92-102.4 88.746667c-13.653333 13.653333-13.653333 34.133333 0 47.786667 6.826667 20.48 27.306667 20.48 40.96 6.826666l129.706666-122.88c6.826667-6.826667 13.653333-13.653333 13.653334-27.306666 0-6.826667-6.826667-20.48-13.653334-27.306667l-129.706666-102.4c-6.826667-6.826667-13.653333-6.826667-20.48-6.826667zM471.586133 77.6192l226.986667 324.4032 55.978667-39.1168-226.986667-324.471467z" horiz-adv-x="1228" />
|
||||
|
||||
|
||||
<glyph glyph-name="jiantou" unicode="" d="M512 896c-281.6 0-512-230.4-512-512s230.4-512 512-512 512 230.4 512 512-230.4 512-512 512z m0-938.666667c-234.666667 0-426.666667 192-426.666667 426.666667s192 426.666667 426.666667 426.666667 426.666667-192 426.666667-426.666667-192-426.666667-426.666667-426.666667zM793.6 499.2c-17.066667 17.066667-42.666667 17.066667-59.733333 0l-221.866667-221.866667-221.866667 221.866667c-17.066667 17.066667-42.666667 17.066667-59.733333 0-17.066667-17.066667-17.066667-42.666667 0-59.733333l251.733333-251.733334c17.066667-17.066667 42.666667-17.066667 59.733334 0l251.733333 251.733334c17.066667 12.8 17.066667 42.666667 0 59.733333z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="ziyongshijuan" unicode="" d="M875.91961-115.537171H148.055415a28.572098 28.572098 0 0 0-28.572098 28.522147V854.940098A28.597073 28.597073 0 0 0 148.055415 883.512195h578.035512l178.40078-322.584975v-647.942244a28.572098 28.572098 0 0 0-28.572097-28.522147zM269.361951 248.407415v-35.665171h285.446244v35.665171z m0 99.902439v-35.665171h478.108098v35.665171z m0 107.045463v-35.715122h478.108098v35.715122z m0 99.902439v-35.715122h478.108098v35.715122zM726.065951 705.086439l178.400781-178.40078V705.086439zM726.065951 705.086439h178.400781L726.065951 883.48722z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="yigongkaishijuan" unicode="" d="M875.898246-115.487525H148.076779a28.596376 28.596376 0 0 0-28.571401 28.571401V854.966074A28.596376 28.596376 0 0 0 148.076779 883.537475h577.996439l178.396429-322.577108v-647.901466a28.596376 28.596376 0 0 0-28.571401-28.546426zM444.555011 287.68391c-60.939001 0-116.783103-34.965001-165.958879-103.945952l-1.54845-2.172825-1.423575-2.072925a35.214751 35.214751 0 0 1 0-39.960001c49.950001-71.753177 106.693203-108.116778 168.905929-108.116778 60.988951 0 116.858028 34.965001 166.008829 103.945952l1.473525 2.122875 1.44855 2.072926a35.289676 35.289676 0 0 1 0 39.960001c-49.875076 71.778152-106.818078 108.166728-168.880954 108.166727z m-175.224604 114.160728v-35.664301h478.146386v35.664301z m0 107.067828v-35.714251h478.146386V508.887491z m0 99.900002v-35.714251h478.146386V608.787493z m175.224604-518.980513a70.729202 70.729202 0 0 0-70.629302 70.654277 70.729202 70.729202 0 0 0 70.629302 70.654277 70.729202 70.729202 0 0 0 70.654277-70.654277 70.729202 70.729202 0 0 0-70.629302-70.654277z m0 113.161728a42.582376 42.582376 0 0 1-42.457501-42.457501 42.607351 42.607351 0 0 1 42.457501-42.457501 42.607351 42.607351 0 0 1 42.457501 42.457501 42.582376 42.582376 0 0 1-42.432526 42.457501zM726.073218 705.11607l178.396429-178.396429V705.11607zM726.073218 705.11607h178.396429L726.073218 883.5125z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shipin" unicode="" d="M512.000213-127.998293a508.627426 508.627426 0 0 0-362.025309 149.972771A508.627426 508.627426 0 0 0 0.002133 383.999787a508.670092 508.670092 0 0 0 149.972771 362.067975A508.627426 508.627426 0 0 0 512.000213 895.997867a508.670092 508.670092 0 0 0 362.067976-149.972771A508.670092 508.670092 0 0 0 1023.998293 383.999787a508.627426 508.627426 0 0 0-149.972771-362.025309A508.712759 508.712759 0 0 0 512.000213-127.998293zM256.001173 492.628713v-324.64945a31.743881 31.743881 0 0 1 33.365209-31.402548h445.224997a31.743881 31.743881 0 0 1 33.365208 31.402548V492.628713zM652.202354 597.33232l75.690383-83.797019H767.999253V565.929771A31.701214 31.701214 0 0 1 734.634045 597.33232z m-111.274249 0l75.690383-83.797019h85.717012L626.645117 597.33232zM429.653855 597.33232l75.647717-83.797019h85.717012L515.328201 597.33232zM318.33694 597.33232l75.690382-83.797019h85.717012L404.053951 597.33232z m-28.970558 0A31.701214 31.701214 0 0 1 256.001173 565.929771v-52.39447h112.383579L292.737036 597.33232z m178.089998-371.795939c-15.402609 0-33.407875 6.869308-33.407874 26.197235v146.602117c0 19.327928 18.005266 26.197235 33.407874 26.197235a37.589192 37.589192 0 0 0 17.8346-4.266651l126.890191-69.11974a29.397223 29.397223 0 0 0 16.682604-26.197236 29.397223 29.397223 0 0 0-16.682604-26.197235l-126.890191-69.11974a34.133205 34.133205 0 0 0-17.8346-4.095985z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shixun2" unicode="" d="M512-127.998676a508.600064 508.600064 0 0 0-361.930098 150.068578A508.68834 508.68834 0 0 0 0.001324 384a508.68834 508.68834 0 0 0 150.068578 361.930098A508.600064 508.600064 0 0 0 512 895.998676a508.68834 508.68834 0 0 0 361.930098-150.068578 508.68834 508.68834 0 0 0 150.068578-361.930098 508.644202 508.644202 0 0 0-150.068578-361.930098 508.68834 508.68834 0 0 0-361.930098-150.068578zM306.450187 648.826901A58.83571 58.83571 0 0 1 247.173099 589.152573V286.896803a58.83571 58.83571 0 0 1 59.277088-59.674329h137.047921l-40.739205-59.718466a20.568223 20.568223 0 0 1-7.415153-18.626159 27.321309 27.321309 0 0 1 29.616475-29.881302h174.123688a24.187524 24.187524 0 0 1 13.241345 4.413782c1.677237 0.971032 3.354474 1.942064 5.340676 2.957234a30.896472 30.896472 0 0 1 12.491002 19.906155 27.012344 27.012344 0 0 1-5.075849 21.142015l-40.739205 59.718466h133.296207A58.83571 58.83571 0 0 1 776.826901 286.896803V589.020159A78.477038 78.477038 0 0 1 706.471221 648.826901z m285.174435-290.956489a143.315491 143.315491 0 0 0-68.899132 26.482691l-12.579278 7.150326a73.842568 73.842568 0 0 0-14.830307 7.459291 73.842568 73.842568 0 0 1-14.830306 7.459291 61.792944 61.792944 0 0 1-34.559911 11.255143 92.689415 92.689415 0 0 1-69.163959-44.844022 22.598562 22.598562 0 0 0-20.347534-13.241345 28.821994 28.821994 0 0 0-20.347533 9.533769 24.893729 24.893729 0 0 0-13.594448 18.008229 22.068908 22.068908 0 0 0 6.135157 19.288226 162.515442 162.515442 0 0 0 118.730727 71.944642 115.552805 115.552805 0 0 0 62.763976-19.729605c3.398612-2.251029 6.444121-4.413782 9.136528-6.576534a71.547401 71.547401 0 0 1 20.479947-12.049624c28.424754-18.40547 41.357134-26.791655 52.700553-26.791655 9.224804 0 17.655127 5.517227 32.441296 15.580649a44.137817 44.137817 0 0 0 19.288226 4.899298 22.598562 22.598562 0 0 0 21.495117-12.358589c2.339304-9.489631 5.958605-32.441295-11.12273-41.04817a99.26595 99.26595 0 0 0-63.072941-22.377873z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="fangda2" unicode="" d="M860.115543 119.677826a480.813387 480.813387 0 1 1-84.350991-84.223573l145.256993-145.193283a59.631818 59.631818 0 1 1 84.287281 84.287281l-145.193283 145.129575zM94.840545 413.186143A387.734236 387.734236 0 1 0 482.511071 25.515617a388.116491 388.116491 0 0 0-387.670526 387.670526z m549.109657 45.552084H528.126864V574.497856a45.679502 45.679502 0 0 1-91.231585 0V458.738227H321.135649a45.615792 45.615792 0 0 1 0-91.167876H436.83157v-115.75963a45.679502 45.679502 0 0 1 91.231584 0V367.570351h115.75963a45.615792 45.615792 0 0 1 0 91.167876z" horiz-adv-x="1028" />
|
||||
|
||||
|
||||
<glyph glyph-name="fangzuobi" unicode="" d="M420.69248 563.665455a36.631273 36.631273 0 0 1-27.415273-9.309091 39.284364 39.284364 0 0 1-12.846545-26.717091 39.749818 39.749818 0 0 1 9.309091-28.299637 37.236364 37.236364 0 0 1 25.786182-13.265454 38.074182 38.074182 0 0 1 40.215272 36.072727 38.539636 38.539636 0 0 1-34.862545 41.611636m441.250909-348.76509a33.466182 33.466182 0 0 0-52.829091-11.450182c-13.963636 13.591273-72.843636 98.909091-72.843636 98.909091L651.325207 239.709091a31.045818 31.045818 0 0 0-43.008 6.004364L464.538298 431.336727a98.164364 98.164364 0 0 0-101.515636 6.050909 106.356364 106.356364 0 0 0-10.519273 165.841455 98.536727 98.536727 0 0 0 73.309091 25.134545 103.470545 103.470545 0 0 0 93.556364-111.429818 111.429818 111.429818 0 0 0-10.100364-38.725818l130.327273-167.563636 86.202182 64.046545a29.556364 29.556364 0 0 0 23.738181 5.399273 32.581818 32.581818 0 0 0 20.48-13.498182l50.315637-74.472727a786.944 786.944 0 0 1 81.733818 369.245091v24.855272a175.197091 175.197091 0 0 0-114.967273 130.653091H237.443025a176.872727 176.872727 0 0 0-115.29309-130.699636l-0.279273-24.808727c0-286.347636 142.382545-572.509091 390.144-705.815273a671.045818 671.045818 0 0 1 161.373091 121.856 36.119273 36.119273 0 0 0 51.618909-1.908364 44.497455 44.497455 0 0 0-4.468364-59.205818 738.304 738.304 0 0 0-191.488-139.636364 35.421091 35.421091 0 0 0-33.466182-0.558545C212.448116 18.245818 46.280844 339.456 46.280844 661.550545c0 7.214545 0 16.430545 1.070545 29.277091 0 10.379636 0.558545 19.595636 1.117091 28.485819a37.655273 37.655273 0 0 0 33.186909 37.236363A99.328 99.328 0 0 1 166.088844 855.505455V856.250182A39.284364 39.284364 0 0 0 203.883753 896h616.401454a39.144727 39.144727 0 0 0 37.981091-39.703273 99.421091 99.421091 0 0 1 84.573091-99.700363 37.469091 37.469091 0 0 0 32.861091-36.305455c0.605091-8.936727 1.117091-18.618182 1.117091-29.649454 0.512-12.846545 0.512-22.062545 0.512-29.277091a841.402182 841.402182 0 0 0-115.432727-446.324364" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shizhong" unicode="" d="M181.527 640l9.31 9.31C218.763 691.2 256 728.435 302.544 756.363c-13.963 18.618-41.89 32.581-69.818 32.581-46.545 0-83.782-37.236-83.782-79.127 0-32.582 9.31-55.854 32.582-69.818z m660.946 0l-9.31 9.31c-27.927 41.89-69.818 79.126-111.708 107.054 13.963 23.272 41.89 37.236 69.818 37.236 46.545 0 83.782-37.236 83.782-83.782 0-32.582-9.31-55.854-32.582-69.818zM521.309 765.673c-200.145 0-363.054-162.91-363.054-363.055s162.909-363.054 363.054-363.054 363.055 162.909 363.055 363.054-162.91 363.055-363.055 363.055zM679.564 332.79999999999995h-204.8V560.873h74.472v-153.6h130.328V332.79999999999995zM232.727-16.289999999999964c-13.963 0-23.272 4.654-32.582 13.963-18.618 18.618-18.618 46.545 0 65.163l97.746 93.091c18.618 18.618 46.545 18.618 65.164 0 18.618-18.618 18.618-46.545 0-65.163l-97.746-93.091c-9.309-9.31-23.273-13.964-32.582-13.964z m572.51-9.31c-13.964 0-23.273 4.655-32.582 13.964l-102.4 102.4c-18.619 18.618-18.619 46.545 0 65.163s46.545 18.618 65.163 0l102.4-102.4c18.618-18.618 18.618-46.545 0-65.163-9.309-9.31-18.618-13.964-32.582-13.964z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="shangchuanshipin1" unicode="" d="M547.584-62.272H0V896h958.272v-581.888H889.6V827.52H68.48V6.4h479.104z m0 0M844.928 16.192h179.2l-242.752 330.432-242.752-330.432h162.176v-144.256h144.256z m0 0l-222.464 396.8-292.16 229.312v-459.136z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="duigou1" unicode="" d="M1155.765578 895.525596a3193.803104 3193.803104 0 0 1-740.069493-640.444753l-288.200139 225.341673L0 378.900162l497.530693-506.425758A3054.209868 3054.209868 0 0 0 1186.008802 824.958073l-30.243224 71.160528m0-0.593005z" horiz-adv-x="1186" />
|
||||
|
||||
|
||||
<glyph glyph-name="lianjie1" unicode="" d="M95.99604 26.958728a63.101397 63.101397 0 0 1 63.99736-61.885447h703.970961a62.909405 62.909405 0 0 1 63.997361 61.885447V741.041272a63.101397 63.101397 0 0 1-63.997361 61.885447h-703.970961a62.909405 62.909405 0 0 1-63.99736-61.885447zM159.9934 895.978881h703.970961A157.689495 157.689495 0 0 0 1023.957762 741.041272v-714.082544A157.497503 157.497503 0 0 0 863.964361-127.978881h-703.970961A157.689495 157.689495 0 0 0 0 26.958728V741.041272A157.497503 157.497503 0 0 0 159.9934 895.978881zM389.743923 262.021032a24.446992 24.446992 0 0 1 34.494577 0L634.213839 471.612386a24.638984 24.638984 0 0 1-35.006556 34.686569L389.551931 296.707601a24.191002 24.191002 0 0 1 0-34.686569z m127.418744 61.117479a24.254999 24.254999 0 0 1-10.623562-32.894644 52.669827 52.669827 0 0 0 4.543813-30.014761 49.917941 49.917941 0 0 0-13.695435-26.622902l-1.279947-1.151953-105.019668-104.827676-1.151953-0.831965a48.509999 48.509999 0 0 0-67.38922 0.831965l-67.38922 67.261226-0.959961 0.831966a48.318007 48.318007 0 0 0-13.247453 33.406622 47.422044 47.422044 0 0 0 14.207414 34.17459l1.471939 1.471939 104.827676 104.827676a49.661951 49.661951 0 0 0 26.622902 13.56744 50.749907 50.749907 0 0 0 29.82277-4.671807 24.574986 24.574986 0 0 1 22.271081 43.838192 99.323903 99.323903 0 0 1-59.965527 9.343614 95.548059 95.548059 0 0 1-53.245803-27.39087l-105.147663-104.95567-1.151952-1.151953v-0.319987a97.339985 97.339985 0 0 1-1.279948-136.442371l1.279948-1.279948v-0.319986l67.069233-67.069234h0.319987a96.892003 96.892003 0 0 1 68.733165-28.670817 95.612056 95.612056 0 0 1 67.709207 27.262875l1.599934 1.47194 105.019668 105.147662 1.471939 0.831966a99.003916 99.003916 0 0 1 27.070883 53.693785 97.275987 97.275987 0 0 1-9.343614 59.64554 24.702981 24.702981 0 0 1-33.086636 11.13554zM831.965681 539.38559a98.043956 98.043956 0 0 1-26.942888 67.389221l-1.471939 1.471939-67.389221 67.38922A97.659972 97.659972 0 0 1 666.980487 703.986801a95.99604 95.99604 0 0 1-67.38922-27.070884l-1.599934-1.279947-105.019668-104.827676-1.151953-1.471939a95.484061 95.484061 0 0 1-27.262875-53.885777 98.235948 98.235948 0 0 1 9.21562-59.837532 24.638984 24.638984 0 0 1 43.710197 22.719063 50.365922 50.365922 0 0 0-4.543813 29.82277 49.533957 49.533957 0 0 0 13.695435 26.302915l1.47194 1.279947L632.933891 640.565417l0.959961 1.471939a50.045936 50.045936 0 0 0 33.21463 12.799472 48.318007 48.318007 0 0 0 34.494577-14.335409l67.069233-67.38922 1.151953-0.511979a50.045936 50.045936 0 0 0 12.799472-33.406622 46.910065 46.910065 0 0 0-14.207414-34.17459v-0.319987l-0.959961-0.95996-105.147662-104.827676a47.486041 47.486041 0 0 0-26.622902-13.887427 49.789946 49.789946 0 0 0-29.82277 4.863799 25.086965 25.086965 0 0 1-33.21463-10.943548 24.766978 24.766978 0 0 1 11.135541-33.086636 96.636014 96.636014 0 0 1 59.64554-9.023627 95.164074 95.164074 0 0 1 53.56579 27.262875l104.827676 104.827676 1.279947 1.471939a96.572016 96.572016 0 0 1 28.414828 68.86116z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="zhangjie" unicode="" d="M773.902013 896A123.083076 123.083076 0 0 0 895.918512 769.84518v-834.789101a63.994667 63.994667 0 0 0-61.008249-63.056079 82.211816 82.211816 0 0 0-28.712274 7.423381l-240.449296 126.154821a110.92409 110.92409 0 0 1-107.63903 0l-240.406633-126.154821a63.141405 63.141405 0 0 0-82.553121 25.981835 71.802016 71.802016 0 0 0-7.167402 29.864178V773.599533a121.547204 121.547204 0 0 0 118.432797 122.44313z m-71.759353-474.84043h-383.968003a40.828598 40.828598 0 0 1 0-81.614532h383.968003a40.529956 40.529956 0 0 1 39.463378 40.828598 43.132406 43.132406 0 0 1-39.463378 40.828597z m0 237.420215h-383.968003a40.529956 40.529956 0 0 1-39.463378-40.828598 39.847346 39.847346 0 0 1 39.463378-37.116907h383.968003a40.529956 40.529956 0 0 1 39.463378 40.828598 42.663111 42.663111 0 0 1-39.463378 37.116907z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="mobanguanli2" unicode="" d="M1133.714286-120.685714H36.571429V201.142857h73.142857v-248.685714h950.857143V201.142857h73.142857zM943.542857 91.428571h-731.428571V896h731.428571v-804.571429z m-658.285714 73.142858h585.142857V822.857143h-585.142857v-658.285714zM416.914286 618.057143h343.771428v-73.142857H416.914286zM416.914286 420.571429h343.771428v-73.142858H416.914286z" horiz-adv-x="1170" />
|
||||
|
||||
|
||||
<glyph glyph-name="fenzuzuoye2" unicode="" d="M585.142857-79.945143l-21.942857 7.314286c-29.257143 14.628571-58.514286 21.942857-80.457143 29.257143-65.828571 21.942857-131.657143 29.257143-204.8 36.571428-51.2 7.314286-117.028571 0-182.857143-14.628571-36.571429-7.314286-80.457143 14.628571-87.771428 58.514286v709.485714c0 36.571429 29.257143 73.142857 65.828571 73.142857 73.142857 7.314286 131.657143 7.314286 168.228572 7.314286h14.628571c51.2-7.314286 109.714286-14.628571 182.857143-36.571429 51.2-14.628571 73.142857-21.942857 87.771428-29.257143 29.257143-7.314286 51.2-7.314286 58.514286-7.314285 14.628571 0 102.4 29.257143 138.971429 36.571428 21.942857 7.314286 36.571429 14.628571 43.885714 14.628572 36.571429 7.314286 65.828571 14.628571 109.714286 21.942857 43.885714 7.314286 124.342857 7.314286 226.742857 0 36.571429 0 65.828571-36.571429 65.828571-73.142857v-702.171429c0-43.885714-29.257143-73.142857-73.142857-73.142857h-14.628571c-73.142857 14.628571-138.971429 21.942857-190.171429 21.942857-73.142857 0-146.285714-14.628571-219.428571-36.571429-21.942857-7.314286-43.885714-14.628571-58.514286-29.257142l-29.257143-14.628572z m-351.085714 153.6h43.885714c73.142857-7.314286 146.285714-21.942857 219.428572-43.885714 29.257143-7.314286 58.514286-14.628571 87.771428-29.257143 21.942857 7.314286 36.571429 21.942857 65.828572 29.257143 80.457143 29.257143 160.914286 43.885714 248.685714 43.885714 58.514286 0 131.657143-7.314286 204.8-21.942857l-7.314286 702.171429c-124.342857 14.628571-182.857143 7.314286-212.114286 0-36.571429-7.314286-73.142857-14.628571-102.4-21.942858-7.314286 0-21.942857-7.314286-43.885714-14.628571-87.771429-21.942857-131.657143-36.571429-153.6-36.571429-14.628571 0-29.257143 0-51.2 7.314286H512l7.314286 21.942857-7.314286-14.628571c-7.314286 0-73.142857 21.942857-95.085714 21.942857-65.828571 21.942857-117.028571 29.257143-168.228572 36.571429h-14.628571c-29.257143 0-87.771429 0-160.914286-7.314286v-694.857143c58.514286 14.628571 109.714286 21.942857 160.914286 21.942857zM548.571429 739.254857h73.142857v-775.314286h-73.142857zM160.914286 578.340571h226.742857v-73.142857H160.914286zM160.914286 344.283429h226.742857v-73.142858H160.914286zM782.628571 578.340571h226.742858v-73.142857h-226.742858zM782.628571 344.283429h226.742858v-73.142858h-226.742858z" horiz-adv-x="1170" />
|
||||
|
||||
|
||||
<glyph glyph-name="biyezuoye1" unicode="" d="M593.92 343.04L6.826667 581.973333 546.133333 841.386667c27.306667 13.653333 61.44 13.653333 88.746667 0l539.306667-238.933334-580.266667-259.413333zM177.493333 588.8L593.92 418.133333l416.426667 184.32L607.573333 786.773333c-6.826667 6.826667-20.48 6.826667-27.306666 0L177.493333 588.8zM54.613333 602.453333h68.266667v-361.813333h-68.266667zM109.226667 254.293333m-68.266667 0a68.266667 68.266667 0 1 1 136.533333 0 68.266667 68.266667 0 1 1-136.533333 0ZM279.893333 124.586667c191.146667-286.72 416.426667-286.72 682.666667-13.653334 163.84 170.666667-129.706667-116.053333-334.506667-116.053333-95.573333 0-211.626667 40.96-348.16 129.706667zM1037.653333 1.706667c-20.48 0-40.96 13.653333-40.96 34.133333-6.826667 47.786667-20.48 81.92-40.96 102.4-20.48 13.653333-40.96 20.48-75.093333 13.653333-20.48 0-40.96 13.653333-47.786667 34.133334 0 20.48 13.653333 40.96 34.133334 47.786666 54.613333 6.826667 102.4 0 136.533333-27.306666 40.96-34.133333 61.44-81.92 68.266667-157.013334 13.653333-20.48-6.826667-40.96-34.133334-47.786666 6.826667 0 0 0 0 0z" horiz-adv-x="1174" />
|
||||
|
||||
|
||||
<glyph glyph-name="tongji3" unicode="" d="M463.811765-73.788235C228.894118-73.788235 30.117647 118.964706 30.117647 353.882353c0 234.917647 192.752941 427.670588 433.694118 427.670588v-60.235294C259.011765 721.317647 90.352941 558.682353 90.352941 353.882353s168.658824-367.435294 373.458824-367.435294c198.776471 0 379.482353 156.611765 391.529411 337.317647H445.741176v60.235294h475.858824V353.882353c-6.023529-228.894118-210.823529-427.670588-457.788235-427.670588zM433.694118 775.529412h60.235294v-457.788236h-60.235294zM433.332706 381.711059l433.694118 4.698353 0.602352-60.235294-433.694117-4.698353zM969.788235 504.470588h-60.235294c0 162.635294-132.517647 301.176471-301.17647 301.176471v60.235294c198.776471 0 361.411765-162.635294 361.411764-361.411765zM969.788235 468.329412H578.258824V859.858824h60.235294v-331.294118h331.294117z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="qiandao1" unicode="" d="M984.615385-128h-866.461539C55.138462-128 0-72.861538 0-9.846154v708.923077C0 762.092308 55.138462 817.230769 118.153846 817.230769h866.461539c63.015385 0 118.153846-55.138462 118.153846-118.153846v-708.923077c0-63.015385-55.138462-118.153846-118.153846-118.153846zM118.153846 738.461538c-23.630769 0-39.384615-15.753846-39.384615-39.384615v-708.923077c0-23.630769 15.753846-39.384615 39.384615-39.384615h866.461539c23.630769 0 39.384615 15.753846 39.384615 39.384615v708.923077c0 23.630769-15.753846 39.384615-39.384615 39.384615h-866.461539zM315.076923 896h78.769231v-236.307692H315.076923zM504.123077 92.553846L299.323077 352.492308l63.015385 47.261538 141.784615-189.046154 299.323077 322.953846 55.138461-55.138461zM669.538462 896h78.76923v-236.307692h-78.76923z" horiz-adv-x="1102" />
|
||||
|
||||
|
||||
<glyph glyph-name="fenban2" unicode="" d="M354.986667 356.693333c-129.706667 0-232.106667 109.226667-232.106667 238.933334S225.28 834.56 354.986667 834.56c109.226667 0 204.8-81.92 232.106666-197.973333l-61.44-13.653334C512 711.68 443.733333 766.293333 354.986667 766.293333c-95.573333 0-170.666667-81.92-170.666667-177.493333s81.92-177.493333 170.666667-177.493333v-54.613334zM559.786667 206.506667c-136.533333 0-238.933333 109.226667-238.933334 238.933333S430.08 691.2 559.786667 691.2s238.933333-109.226667 238.933333-238.933333-102.4-245.76-238.933333-245.76z m0 416.426666C464.213333 622.933333 389.12 547.84 389.12 452.266667S464.213333 281.6 559.786667 281.6s170.666667 75.093333 170.666666 170.666667S655.36 622.933333 559.786667 622.933333zM116.053333 110.933333H61.44C54.613333 281.6 191.146667 418.133333 354.986667 418.133333v-61.44c-129.706667 0-238.933333-109.226667-238.933334-245.76zM921.6-114.346667h-68.266667c0 157.013333-129.706667 286.72-286.72 286.72s-286.72-129.706667-286.72-286.72h-68.266666c0 197.973333 157.013333 354.986667 354.986666 354.986667 191.146667 0 354.986667-157.013333 354.986667-354.986667z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="taolun2" unicode="" d="M118.153846-128c-23.630769 0-31.507692 0-39.384615 7.876923-31.507692 15.753846-23.630769 55.138462-7.876923 126.030769 15.753846 78.769231 15.753846 94.523077 7.876923 118.153846-55.138462 78.769231-78.769231 173.292308-78.769231 267.815385C0 667.569231 244.184615 896 551.384615 896s551.384615-228.430769 551.384616-504.123077-244.184615-504.123077-551.384616-504.123077c-55.138462 0-110.276923 7.876923-157.538461 23.630769-23.630769 7.876923-47.261538 0-141.784616-15.753846h-7.876923c-63.015385-23.630769-102.4-23.630769-126.030769-23.630769zM551.384615 817.230769C291.446154 817.230769 78.769231 628.184615 78.769231 391.876923c0-78.769231 23.630769-157.538462 70.892307-220.553846 31.507692-55.138462 23.630769-102.4 7.876924-181.169231 0-15.753846-7.876923-31.507692-7.876924-39.384615 15.753846 0 39.384615 7.876923 78.769231 15.753846H236.307692c102.4 15.753846 133.907692 23.630769 181.169231 15.753846 47.261538-15.753846 94.523077-15.753846 141.784615-15.753846 259.938462 0 472.615385 189.046154 472.615385 425.353846C1024 628.184615 811.323077 817.230769 551.384615 817.230769zM315.076923 226.461538c-63.015385 0-118.153846 55.138462-118.153846 118.153847S252.061538 462.769231 315.076923 462.769231s118.153846-55.138462 118.153846-118.153846S378.092308 226.461538 315.076923 226.461538z m0 157.538462c-23.630769 0-39.384615-15.753846-39.384615-39.384615s15.753846-39.384615 39.384615-39.384616 39.384615 15.753846 39.384615 39.384616-15.753846 39.384615-39.384615 39.384615zM551.384615 226.461538c-63.015385 0-118.153846 55.138462-118.153846 118.153847S488.369231 462.769231 551.384615 462.769231s118.153846-55.138462 118.153847-118.153846S614.4 226.461538 551.384615 226.461538z m0 157.538462c-23.630769 0-39.384615-15.753846-39.384615-39.384615s15.753846-39.384615 39.384615-39.384616 39.384615 15.753846 39.384616 39.384616-15.753846 39.384615-39.384616 39.384615zM787.692308 226.461538c-63.015385 0-118.153846 55.138462-118.153846 118.153847s55.138462 118.153846 118.153846 118.153846 118.153846-55.138462 118.153846-118.153846-55.138462-118.153846-118.153846-118.153847z m0 157.538462c-23.630769 0-39.384615-15.753846-39.384616-39.384615s15.753846-39.384615 39.384616-39.384616 39.384615 15.753846 39.384615 39.384616-15.753846 39.384615-39.384615 39.384615z" horiz-adv-x="1102" />
|
||||
|
||||
|
||||
<glyph glyph-name="shipinzhibo1" unicode="" d="M884.363636-128h-744.727272C65.163636-128 0-62.836364 0 11.636364v744.727272C0 830.836364 65.163636 896 139.636364 896h744.727272c74.472727 0 139.636364-65.163636 139.636364-139.636364v-744.727272c0-74.472727-65.163636-139.636364-139.636364-139.636364z m-744.727272 930.909091c-27.927273 0-46.545455-18.618182-46.545455-46.545455v-744.727272c0-27.927273 18.618182-46.545455 46.545455-46.545455h744.727272c27.927273 0 46.545455 18.618182 46.545455 46.545455v744.727272c0 27.927273-18.618182 46.545455-46.545455 46.545455h-744.727272zM1340.509091 11.636364l-372.363636 186.181818V495.709091l372.363636 167.563636v-651.636363z m-279.272727 242.036363l186.181818-93.090909V523.636364l-186.181818-83.781819v-186.181818zM186.181818 709.818182h186.181818v-93.090909H186.181818z" horiz-adv-x="1396" />
|
||||
|
||||
|
||||
<glyph glyph-name="kaoshishijuan1" unicode="" d="M443.733333-93.866667H136.533333c-54.613333 0-102.4 47.786667-102.4 102.4V759.466667C34.133333 814.08 81.92 861.866667 136.533333 861.866667h614.4c54.613333 0 102.4-47.786667 102.4-102.4v-327.68h-68.266666V759.466667c0 20.48-13.653333 34.133333-34.133334 34.133333H136.533333c-20.48 0-34.133333-13.653333-34.133333-34.133333v-750.933334c0-20.48 13.653333-34.133333 34.133333-34.133333h307.2v-68.266667zM750.933333 76.8c-75.093333 0-136.533333 61.44-136.533333 136.533333s61.44 136.533333 136.533333 136.533334 136.533333-61.44 136.533334-136.533334-61.44-136.533333-136.533334-136.533333z m0 204.8c-40.96 0-68.266667-27.306667-68.266666-68.266667s27.306667-68.266667 68.266666-68.266666 68.266667 27.306667 68.266667 68.266666-27.306667 68.266667-68.266667 68.266667zM989.866667-93.866667h-68.266667c0 95.573333-75.093333 170.666667-170.666667 170.666667s-170.666667-75.093333-170.666666-170.666667h-68.266667c0 129.706667 109.226667 238.933333 238.933333 238.933334s238.933333-109.226667 238.933334-238.933334zM580.266667 554.666667h-341.333334c-20.48 0-34.133333 13.653333-34.133333 34.133333s13.653333 34.133333 34.133333 34.133333h341.333334c20.48 0 34.133333-13.653333 34.133333-34.133333s-13.653333-34.133333-34.133333-34.133333zM512 349.866667h-273.066667c-20.48 0-34.133333 13.653333-34.133333 34.133333s13.653333 34.133333 34.133333 34.133333h273.066667c20.48 0 34.133333-13.653333 34.133333-34.133333s-13.653333-34.133333-34.133333-34.133333zM204.8 213.333333h204.8v-68.266666H204.8z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="kaoshiwenjuan1" unicode="" d="M471.811482-80.71359H161.957516c-53.887646 0-101.039337 47.151691-101.039337 101.039337V761.280884C60.918179 815.16853 108.06987 862.320221 161.957516 862.320221h606.236021c53.887646 0 101.039337-47.151691 101.039337-101.039337v-282.910143h-67.359558V761.280884c0 20.207867-13.471912 33.679779-33.679779 33.679779H161.957516c-20.207867 0-33.679779-13.471912-33.679779-33.679779v-740.955137c0-20.207867 13.471912-33.679779 33.679779-33.679779h309.853966v-67.359558zM700.83398-47.033811c-114.511249 0-202.078674 87.567425-202.078674 202.078674s87.567425 202.078674 202.078674 202.078673 202.078674-87.567425 202.078673-202.078673-87.567425-202.078674-202.078673-202.078674z m0 336.797789c-74.095514 0-134.719116-60.623602-134.719116-134.719115s60.623602-134.719116 134.719116-134.719116 134.719116 60.623602 134.719115 134.719116-60.623602 134.719116-134.719115 134.719115zM821.946465-13.69083l47.623207 47.623207 114.30917-114.30917-47.623207-47.623207zM599.794643 559.20221h-336.79779c-20.207867 0-33.679779 13.471912-33.679779 33.679779s13.471912 33.679779 33.679779 33.679779h336.79779c20.207867 0 33.679779-13.471912 33.679779-33.679779s-13.471912-33.679779-33.679779-33.679779zM397.715969 357.123536h-134.719116c-20.207867 0-33.679779 13.471912-33.679779 33.679779s13.471912 33.679779 33.679779 33.679779h134.719116c20.207867 0 33.679779-13.471912 33.679779-33.679779s-13.471912-33.679779-33.679779-33.679779z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="xuexiziyuan1" unicode="" d="M1024-64.984615H78.769231c-47.261538 0-78.769231 31.507692-78.769231 78.76923v787.692308c0 47.261538 31.507692 78.769231 78.769231 78.769231h315.076923l157.538461-165.415385h472.615385c47.261538 0 78.769231-31.507692 78.769231-78.769231v-622.276923c0-39.384615-31.507692-78.769231-78.769231-78.76923zM78.769231 801.476923v-787.692308h945.230769V636.061538H519.876923l-157.538461 165.415385H78.769231zM0 462.769231h1024v-78.769231H0zM118.153846 226.461538h315.076923v-78.76923h-315.076923zM984.615385 817.230769h-315.076923C645.907692 817.230769 630.153846 832.984615 630.153846 856.615385s15.753846 39.384615 39.384616 39.384615h315.076923c23.630769 0 39.384615-15.753846 39.384615-39.384615s-15.753846-39.384615-39.384615-39.384616z" horiz-adv-x="1102" />
|
||||
|
||||
|
||||
<glyph glyph-name="putongzuoye1" unicode="" d="M832-96H128c-51.2 0-96 44.8-96 96V768C32 819.2 76.8 864 128 864h544v-64H128c-19.2 0-32-12.8-32-32v-768c0-19.2 12.8-32 32-32h704c19.2 0 32 12.8 32 32V294.4c0 19.2 12.8 32 32 32s32-12.8 32-32V0c0-51.2-44.8-96-96-96zM480 576h-256c-19.2 0-32 12.8-32 32s12.8 32 32 32h256c19.2 0 32-12.8 32-32s-12.8-32-32-32zM416 384h-192c-19.2 0-32 12.8-32 32s12.8 32 32 32h192c19.2 0 32-12.8 32-32s-12.8-32-32-32zM512 230.4V409.6l320 384c19.2 25.6 51.2 44.8 89.6 44.8 32 0 70.4-6.4 96-32 51.2-44.8 64-128 12.8-179.2l-320-384-198.4-12.8zM576 384v-89.6l102.4 6.4 300.8 358.4c25.6 25.6 19.2 70.4-6.4 89.6-12.8 19.2-25.6 25.6-44.8 25.6-19.2 0-32-6.4-44.8-25.6L576 384zM729.6 96H192c-19.2 0-32 12.8-32 32s12.8 32 32 32h537.6c19.2 0 32-12.8 32-32s-12.8-32-32-32z" horiz-adv-x="1088" />
|
||||
|
||||
|
||||
<glyph glyph-name="shixunzuoye1" unicode="" d="M914.285714 91.428571h-804.571428C51.2 91.428571 0 142.628571 0 201.142857v585.142857C0 844.8 51.2 896 109.714286 896h804.571428c58.514286 0 109.714286-51.2 109.714286-109.714286v-585.142857c0-58.514286-51.2-109.714286-109.714286-109.714286zM109.714286 822.857143c-21.942857 0-36.571429-14.628571-36.571429-36.571429v-585.142857c0-21.942857 14.628571-36.571429 36.571429-36.571428h804.571428c21.942857 0 36.571429 14.628571 36.571429 36.571428v585.142857c0 21.942857-14.628571 36.571429-36.571429 36.571429h-804.571428zM0 310.857143h950.857143v-73.142857H0zM256-54.857143H804.571429v-73.142857H256zM248.685714 362.057143l-146.285714 182.857143 146.285714 226.742857 58.514286-43.885714-117.028571-175.542858 117.028571-146.285714zM760.685714 362.057143l-58.514285 43.885714 117.028571 146.285714-117.028571 175.542858 58.514285 43.885714 146.285715-226.742857zM351.085714 413.257143l263.314286 351.085714 58.514286-43.885714-263.314286-351.085714zM365.714286 164.571429h73.142857v-219.428572H365.714286zM585.142857 164.571429h73.142857v-219.428572H585.142857z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="Lastupdated" unicode="" d="M512-107.52c-281.6 0-512 225.28-512 501.76S230.4 896 512 896s512-225.28 512-501.76-230.4-501.76-512-501.76z m0 931.84c-240.64 0-440.32-194.56-440.32-430.08s199.68-430.08 440.32-430.08 440.32 194.56 440.32 430.08-199.68 430.08-440.32 430.08zM547.84 102.4H476.16v215.04H261.12V389.12h215.04V609.28h71.68v-220.16h215.04v-71.68h-215.04z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="CONTACTS" unicode="" d="M599.771429-69.485714l-14.628572 68.266666c107.27619 19.504762 199.92381 87.771429 258.438095 190.171429l58.514286-34.133333c-68.266667-121.904762-180.419048-199.92381-302.323809-224.304762zM146.285714 452.266667l-68.266666 9.752381C107.27619 700.952381 297.447619 881.371429 521.752381 881.371429s414.47619-180.419048 443.733333-419.352381l-68.266666-4.876191c-24.380952 204.8-185.295238 355.961905-375.466667 355.961905-190.171429 0-351.085714-156.038095-375.466667-360.838095zM112.152381 159.695238c-48.761905 0-87.771429 39.009524-87.771429 87.771429v126.780952c0 48.761905 39.009524 87.771429 87.771429 87.771429s87.771429-39.009524 87.771429-87.771429v-131.657143c-4.87619-43.885714-43.885714-82.895238-87.771429-82.895238z m0 234.057143c-9.752381 0-19.504762-9.752381-19.504762-19.504762v-131.657143c0-9.752381 9.752381-19.504762 19.504762-19.504762s19.504762 9.752381 19.504762 19.504762v131.657143c-4.87619 9.752381-14.628571 19.504762-19.504762 19.504762zM536.380952-103.619048h-97.523809c-34.133333 0-63.390476 29.257143-63.390476 63.390477 0 34.133333 29.257143 63.390476 63.390476 63.390476h97.523809c34.133333 0 63.390476-29.257143 63.390477-63.390476 0-39.009524-29.257143-63.390476-63.390477-63.390477zM911.847619 159.695238c-48.761905 0-87.771429 39.009524-87.771429 87.771429v126.780952c0 48.761905 39.009524 87.771429 87.771429 87.771429s87.771429-39.009524 87.771429-87.771429v-131.657143c0-43.885714-39.009524-82.895238-87.771429-82.895238z m0 234.057143c-9.752381 0-19.504762-9.752381-19.504762-19.504762v-131.657143c0-9.752381 9.752381-19.504762 19.504762-19.504762s19.504762 9.752381 19.504762 19.504762v131.657143c0 9.752381-9.752381 19.504762-19.504762 19.504762z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="SPONSORS" unicode="" d="M489.73913 392.904348c-138.017391 0-253.773913 111.304348-253.773913 253.773913S347.269565 896 489.73913 896s253.773913-111.304348 253.773913-253.773913-115.756522-249.321739-253.773913-249.321739z m0 440.765217c-102.4 0-191.443478-84.591304-191.443478-191.443478S382.886957 455.234783 489.73913 455.234783c102.4 0 191.443478 84.591304 191.443479 191.443478s-89.043478 186.991304-191.443479 186.991304zM120.208696-105.73913L115.756522-83.478261c-8.904348 35.617391-13.356522 66.782609-13.356522 102.4 0 222.608696 182.53913 405.147826 405.147826 405.147826s405.147826-182.53913 405.147826-405.147826c0-31.165217-4.452174-66.782609-13.356522-97.947826l-4.452173-22.26087-774.678261-4.452173zM507.547826 361.73913c-186.991304 0-342.817391-155.826087-342.817391-342.817391 0-22.26087 0-44.521739 4.452174-62.330435L845.913043-38.956522c4.452174 17.808696 4.452174 40.069565 4.452174 57.878261 0 186.991304-155.826087 342.817391-342.817391 342.817391zM512-38.956522l-106.852174 289.391305 106.852174 120.208695 97.947826-120.208695L512-38.956522z m-31.165217 276.034783l31.165217-89.043478 31.165217 89.043478-31.165217 35.617391-31.165217-35.617391z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="FINALREPORTS" unicode="" d="M633.904762-98.742857H219.428571c-73.142857 0-131.657143 58.514286-131.657142 131.657143V749.714286C87.771429 822.857143 146.285714 881.371429 219.428571 881.371429h580.266667c73.142857 0 131.657143-58.514286 131.657143-131.657143v-516.876191l-297.447619-331.580952zM219.428571 813.104762c-34.133333 0-63.390476-29.257143-63.390476-63.390476v-716.8c0-34.133333 29.257143-63.390476 63.390476-63.390476h385.219048l263.314286 287.695238V749.714286c0 34.133333-29.257143 63.390476-63.390476 63.390476H219.428571zM653.409524-64.609524h-68.266667v341.333334h312.076191v-68.266667h-243.809524zM238.933333 652.190476h570.514286v-68.266666H238.933333zM238.933333 447.390476h570.514286v-68.266666H238.933333z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="STEERINGCOMMITTEE" unicode="" d="M409.6 389.389474C269.473684 389.389474 156.294737 502.568421 156.294737 642.694737S269.473684 896 409.6 896s253.305263-113.178947 253.305263-253.305263-113.178947-253.305263-253.305263-253.305263z m0 431.157894c-97.010526 0-177.852632-80.842105-177.852632-177.852631S312.589474 464.842105 409.6 464.842105s177.852632 80.842105 177.852632 177.852632-80.842105 177.852632-177.852632 177.852631zM689.852632 340.884211V416.336842c97.010526 0 177.852632 80.842105 177.852631 177.852632 0 75.452632-48.505263 140.126316-118.568421 167.073684l26.947369 70.063158c102.4-37.726316 167.073684-129.347368 167.073684-237.136842 0-140.126316-113.178947-253.305263-253.305263-253.305263zM1050.947368-30.989474l-75.452631 16.168421c5.389474 21.557895 5.389474 43.115789 5.389474 70.063158 0 156.294737-123.957895 280.252632-280.252632 280.252632V416.336842c194.021053 0 355.705263-161.684211 355.705263-355.705263 5.389474-32.336842 0-64.673684-5.389474-91.621053zM37.726316-122.610526l-5.389474 26.947368c-10.778947 32.336842-16.168421 70.063158-16.168421 107.789474 0 226.357895 183.242105 414.989474 409.6 414.989473 226.357895 0 409.6-188.631579 409.6-414.989473 0-32.336842-5.389474-64.673684-10.778947-97.010527l-5.389474-26.947368-781.473684-10.778947z m388.042105 474.273684c-183.242105 0-334.147368-150.905263-334.147368-339.536842 0-21.557895 0-37.726316 5.389473-59.284211l662.905263 5.389474c0 16.168421 5.389474 32.336842 5.389474 53.894737 0 188.631579-150.905263 339.536842-339.536842 339.536842z" horiz-adv-x="1077" />
|
||||
|
||||
|
||||
<glyph glyph-name="ORGANIZINGICSE-MOU" unicode="" d="M614.4 537.6H450.56C373.76 537.6 312.32 604.16 312.32 675.84V757.76C312.32 834.56 373.76 896 450.56 896H614.4c76.8 0 138.24-61.44 138.24-138.24v-81.92C752.64 604.16 691.2 537.6 614.4 537.6zM450.56 824.32c-35.84 0-66.56-30.72-66.56-66.56v-81.92c0-35.84 30.72-66.56 66.56-66.56H614.4c35.84 0 66.56 30.72 66.56 66.56V757.76c0 35.84-30.72 66.56-66.56 66.56H450.56zM302.08-92.16H138.24c-76.8 0-138.24 61.44-138.24 138.24V128c0 76.8 61.44 138.24 138.24 138.24h163.84c76.8 0 138.24-61.44 138.24-138.24v-81.92c0-76.8-61.44-138.24-138.24-138.24z m-163.84 286.72c-35.84 0-66.56-30.72-66.56-66.56v-81.92c0-35.84 30.72-66.56 66.56-66.56h163.84c35.84 0 66.56 30.72 66.56 66.56V128c0 35.84-30.72 66.56-66.56 66.56H138.24zM936.96-92.16h-163.84c-76.8 0-138.24 61.44-138.24 138.24V128c0 76.8 61.44 138.24 138.24 138.24h163.84c76.8 0 138.24-61.44 138.24-138.24v-81.92c0-76.8-61.44-138.24-138.24-138.24z m-163.84 286.72c-35.84 0-66.56-30.72-66.56-66.56v-81.92c0-35.84 30.72-66.56 66.56-66.56h163.84c35.84 0 66.56 30.72 66.56 66.56V128c0 35.84-30.72 66.56-66.56 66.56h-163.84zM890.88 266.24H819.2v107.52H256v-107.52H184.32V445.44h317.44V537.6h71.68v-92.16h317.44z" horiz-adv-x="1075" />
|
||||
|
||||
|
||||
<glyph glyph-name="INFLUENTIALPAPERS" unicode="" d="M791.272727-90.763636H232.727273C162.909091-90.763636 107.054545-34.909091 107.054545 34.909091V756.363636C107.054545 826.181818 162.909091 882.036364 232.727273 882.036364h428.218182l251.345454-209.454546v-637.672727c4.654545-69.818182-51.2-125.672727-121.018182-125.672727zM232.727273 816.872727c-32.581818 0-60.509091-27.927273-60.509091-60.509091v-721.454545c0-32.581818 27.927273-60.509091 60.509091-60.509091h558.545454c32.581818 0 60.509091 27.927273 60.509091 60.509091V644.654545l-209.454545 172.218182H232.727273zM307.2 672.581818H512v-65.163636H307.2zM377.018182 640h65.163636v-125.672727H377.018182zM512 528.290909h228.072727v-65.163636H512zM307.2 337.454545h432.872727v-65.163636H307.2zM307.2 146.618182h316.509091v-65.163637H307.2zM884.363636 626.036364h-265.309091V849.454545h65.163637v-158.254545H884.363636z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="BIBLIOGRAPHIES" unicode="" d="M156.038095 696.07619H87.771429V881.371429h629.028571c73.142857 0 131.657143-58.514286 131.657143-131.657143v-48.761905h-68.266667V749.714286c0 34.133333-29.257143 63.390476-63.390476 63.390476H156.038095v-117.028572zM804.571429-128H87.771429V735.085714H804.571429c73.142857 0 131.657143-58.514286 131.657142-131.657143v-599.771428c0-73.142857-63.390476-131.657143-131.657142-131.657143zM156.038095-59.733333H804.571429c34.133333 0 63.390476 29.257143 63.390476 63.390476V603.428571c0 34.133333-29.257143 63.390476-63.390476 63.390477H156.038095v-726.552381zM302.32381 486.4h380.342857v-68.266667H302.32381zM302.32381 325.485714H512v-68.266666H302.32381z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="PROCEEDINGS" unicode="" d="M481.28 138.24L204.8 445.44l384 358.4 276.48-312.32-384-353.28zM302.08 440.32l184.32-199.68 276.48 256-179.2 204.8-281.6-261.12zM906.24-71.68c-30.72 0-61.44 15.36-87.04 40.96L532.48 281.6l174.08 163.84 291.84-327.68c20.48-20.48 30.72-51.2 25.6-81.92 0-30.72-15.36-56.32-35.84-76.8-25.6-20.48-51.2-30.72-81.92-30.72z m-271.36 348.16l240.64-266.24c15.36-20.48 46.08-20.48 66.56-5.12 10.24 10.24 15.36 15.36 15.36 30.72 0 10.24-5.12 20.48-10.24 30.72l-240.64 276.48-71.68-66.56zM849.92 450.56c-30.72 0-61.44 10.24-87.04 35.84l-194.56 204.8c-46.08 51.2-46.08 128 5.12 174.08 20.48 20.48 51.2 30.72 87.04 30.72 30.72 0 61.44-15.36 87.04-40.96l194.56-204.8c46.08-51.2 40.96-122.88-5.12-163.84-30.72-25.6-61.44-35.84-87.04-35.84z m-194.56 373.76c-10.24 0-25.6-5.12-35.84-15.36-20.48-20.48-20.48-51.2 0-71.68l194.56-204.8c20.48-20.48 46.08-20.48 66.56 0 20.48 15.36 20.48 46.08 5.12 66.56l-194.56 209.92c-10.24 10.24-20.48 15.36-35.84 15.36zM399.36 51.2c-35.84 0-71.68 15.36-97.28 40.96L35.84 368.64 215.04 537.6l358.4-384-76.8-66.56c-30.72-20.48-66.56-35.84-97.28-35.84z m-266.24 317.44l215.04-225.28c25.6-25.6 66.56-25.6 92.16-5.12l20.48 20.48L204.8 435.2l-71.68-66.56zM0-35.84h624.64v-71.68H0z" horiz-adv-x="1025" />
|
||||
|
||||
|
||||
<glyph glyph-name="HISTORY" unicode="" d="M422.956522-61.217391H178.086957c-66.782609 0-120.208696 53.426087-120.208696 120.208695V762.434783C57.878261 829.217391 111.304348 882.643478 178.086957 882.643478h574.330434c66.782609 0 120.208696-53.426087 120.208696-120.208695v-396.243479h-62.330435V762.434783c0 31.165217-26.713043 57.878261-57.878261 57.87826H178.086957c-31.165217 0-57.878261-26.713043-57.878261-57.87826v-703.443479c0-31.165217 26.713043-57.878261 57.878261-57.878261h244.869565v-62.330434zM756.869565-119.095652c-115.756522 0-213.704348 93.495652-213.704348 209.252174s93.495652 209.252174 213.704348 209.252174 213.704348-93.495652 213.704348-209.252174-97.947826-209.252174-213.704348-209.252174z m0 356.173913c-84.591304 0-151.373913-66.782609-151.373913-146.921739 0-80.13913 66.782609-146.921739 151.373913-146.921739s151.373913 66.782609 151.373913 146.921739c-4.452174 80.13913-71.234783 146.921739-151.373913 146.921739zM828.104348 1.113043h-120.208696v169.182609h62.330435v-106.852174h57.878261zM218.156522 668.93913h503.095652v-62.330434H218.156522zM218.156522 450.782609h414.052174v-62.330435H218.156522zM218.156522 245.982609h249.321739V183.652174H218.156522z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="CONDUCTSAFETY" unicode="" d="M499.2-110.933333l-17.066667 8.533333c-166.4 98.133333-273.066667 192-324.266666 294.4C110.933333 290.133333 81.066667 448 76.8 678.4v25.6l25.6 4.266667c98.133333 21.333333 170.666667 46.933333 217.6 68.266666C366.933333 797.866667 422.4 832 482.133333 878.933333l17.066667 12.8 17.066667-12.8c72.533333-46.933333 132.266667-81.066667 179.2-102.4 46.933333-17.066667 119.466667-42.666667 217.6-68.266666l21.333333-4.266667V682.666667c21.333333-204.8 8.533333-354.133333-46.933333-452.266667-55.466667-98.133333-174.933333-204.8-371.2-332.8l-17.066667-8.533333z m-362.666667 768c8.533333-204.8 34.133333-354.133333 76.8-439.466667s140.8-170.666667 285.866667-260.266667c179.2 115.2 290.133333 217.6 337.066667 302.933334 46.933333 85.333333 59.733333 217.6 42.666666 396.8-93.866667 25.6-162.133333 46.933333-204.8 64-42.666667 17.066667-102.4 51.2-170.666666 93.866666-55.466667-42.666667-110.933333-72.533333-157.866667-93.866666-46.933333-21.333333-115.2-42.666667-209.066667-64zM536.405333 205.226667h-59.733333v153.6h-149.333333v59.733333h149.333333v153.6h59.733333v-153.6h153.6v-59.733333h-153.6z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="EDISTATEMENT" unicode="" d="M819.2-128H200.347826C133.565217-128 80.13913-74.573913 80.13913-7.791304V762.434783C80.13913 829.217391 133.565217 882.643478 200.347826 882.643478h618.852174c66.782609 0 120.208696-53.426087 120.208696-120.208695v-770.226087c0-66.782609-53.426087-120.208696-120.208696-120.208696zM200.347826 820.313043C169.182609 820.313043 142.469565 793.6 142.469565 762.434783v-770.226087c0-31.165217 26.713043-57.878261 57.878261-57.878261h618.852174c31.165217 0 57.878261 26.713043 57.878261 57.878261V762.434783c0 31.165217-26.713043 57.878261-57.878261 57.87826H200.347826zM267.130435 308.313043h507.547826v-62.330434H267.130435zM267.130435 107.965217h262.678261v-62.330434H267.130435zM498.643478 744.626087h62.330435v-218.156522H498.643478zM538.713043 441.878261m-44.521739 0a44.521739 44.521739 0 1 1 89.043479 0 44.521739 44.521739 0 1 1-89.043479 0Z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="MAILINGLIST" unicode="" d="M1070.08 66.56h-215.04v71.68h215.04c35.84 0 66.56 30.72 66.56 66.56V742.4c0 35.84-30.72 66.56-66.56 66.56H153.6c-35.84 0-66.56-30.72-66.56-66.56v-537.6c0-35.84 30.72-66.56 66.56-66.56h230.4v-71.68H153.6C76.8 66.56 15.36 128 15.36 204.8V742.4C15.36 819.2 76.8 880.64 153.6 880.64h916.48c76.8 0 138.24-61.44 138.24-138.24v-537.6c0-76.8-61.44-138.24-138.24-138.24zM614.4 394.24L138.24 727.04l40.96 56.32L614.4 481.28l424.96 302.08 46.08-56.32zM134.6048 223.8464L388.7104 483.84l51.2512-50.0736-254.1056-259.9424zM795.648 428.4928l51.2 50.1248 254.2592-259.84-51.2-50.176zM460.8 286.72h307.2v-71.68H460.8zM460.8 189.44h307.2v-71.68H460.8zM460.8 87.04h307.2v-71.68H460.8zM460.8-15.36h307.2v-71.68H460.8z" horiz-adv-x="1228" />
|
||||
|
||||
|
||||
<glyph glyph-name="HOME" unicode="" d="M828.952381-113.371429h-151.161905c-43.885714 0-82.895238 39.009524-82.895238 82.895239v263.314285H477.866667V-30.47619c0-43.885714-39.009524-82.895238-82.895238-82.895239h-146.285715c-43.885714 0-82.895238 39.009524-82.895238 82.895239v360.838095H87.771429c-24.380952 0-48.761905 9.752381-63.390477 29.257143-14.628571 19.504762-19.504762 39.009524-19.504762 58.514285 0 24.380952 14.628571 43.885714 29.257143 53.638096L487.619048 842.361905c29.257143 24.380952 73.142857 24.380952 107.27619 0l443.733333-370.590476c19.504762-14.628571 29.257143-39.009524 29.257143-63.390477 0-43.885714-39.009524-82.895238-82.895238-82.895238h-78.019047v-360.838095c4.87619-39.009524-34.133333-78.019048-78.019048-78.019048z m-419.352381 414.476191h253.561905V-30.47619c0-9.752381 4.87619-14.628571 14.628571-14.628572H828.952381c9.752381 0 14.628571 4.87619 14.628571 14.628572v429.104761h146.285715c9.752381 0 14.628571 4.87619 14.628571 14.628572 0 4.87619 0 9.752381-4.87619 9.752381l-443.733334 370.590476c-4.87619 4.87619-14.628571 4.87619-19.504762 0L82.895238 423.009524c-4.87619-4.87619-4.87619-9.752381-4.87619-9.752381s0-4.87619 4.87619-9.752381 4.87619-4.87619 9.752381-4.876191h146.285714V-30.47619c0-9.752381 4.87619-14.628571 14.628572-14.628572h146.285714c9.752381 0 14.628571 4.87619 14.628571 14.628572v331.580952z" horiz-adv-x="1072" />
|
||||
|
||||
|
||||
<glyph glyph-name="zhunbeizhong" unicode="" d="M512 384m-480 0a480 480 0 1 1 960 0 480 480 0 1 1-960 0ZM512-128c-281.6 0-512 230.4-512 512s230.4 512 512 512 512-230.4 512-512-230.4-512-512-512zM512 832C262.4 832 64 633.6 64 384s198.4-448 448-448 448 198.4 448 448-198.4 448-448 448zM320 384m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM512 384m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM704 384m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0Z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
|
@ -74,9 +311,6 @@ Created by iconfont
|
|||
<glyph glyph-name="fenzuzuoye1" unicode="" d="M21.333333 896h1024v-1024H21.333333zM949.333333 736H718.933333c-51.2 0-96-12.8-140.8-38.4l-44.8-32-51.2 25.6C443.733333 723.2 392.533333 736 347.733333 736H117.333333C98.133333 736 85.333333 723.2 85.333333 704v-569.6c0-19.2 12.8-32 32-32h230.4c51.2 0 96-12.8 140.8-38.4l44.8-25.6h12.8l38.4 25.6c38.4 25.6 89.6 38.4 140.8 38.4h230.4c19.2 0 32 12.8 32 32V704c-6.4 19.2-19.2 32-38.4 32zM347.733333 172.8h-192V665.6H341.333333c38.4 0 70.4-12.8 102.4-32l51.2-32 6.4-6.4v-460.8c-44.8 25.6-102.4 38.4-153.6 38.4z m563.2 0H725.333333c-57.6 0-108.8-12.8-153.6-38.4V595.2l6.4 6.4 51.2 32c32 19.2 64 32 102.4 32H917.333333v-492.8zM418.133333 537.6H232.533333c-6.4 0-6.4-6.4-6.4-6.4v-44.8c0-6.4 0-6.4 6.4-6.4h185.6c6.4 0 6.4 6.4 6.4 6.4v38.4c0 6.4 0 12.8-6.4 12.8z m224-12.8v-44.8c0-6.4 6.4-6.4 6.4-6.4h185.6c6.4 0 6.4 6.4 6.4 6.4v44.8c0 6.4-6.4 6.4-6.4 6.4H648.533333c-6.4 6.4-6.4 0-6.4-6.4z m-224-128H232.533333c-6.4 0-6.4-6.4-6.4-6.4v-44.8c0-6.4 0-6.4 6.4-6.4h185.6c6.4 0 6.4 6.4 6.4 6.4v44.8s0 6.4-6.4 6.4z m416 0H648.533333c-6.4 0-6.4-6.4-6.4-6.4v-44.8c0-6.4 6.4-6.4 6.4-6.4h185.6c6.4 0 6.4 6.4 6.4 6.4v44.8s0 6.4-6.4 6.4z" horiz-adv-x="1365" />
|
||||
|
||||
|
||||
<glyph glyph-name="putongzuoye1" unicode="" d="M4.266667 896h1024v-1024H4.266667zM650.666667 832v-70.4h-512v-755.2h652.8v320h70.4v-358.4c0-19.2-12.8-32-32-32H100.266667c-19.2 0-32 12.8-32 32v832c0 19.2 12.8 32 32 32h550.4zM420.266667 454.4H260.266667c-19.2 0-38.4 19.2-38.4 38.4s19.2 32 38.4 32h160c19.2 0 32-12.8 32-32s-12.8-38.4-32-38.4zM516.266667 601.6H260.266667c-19.2 0-38.4 19.2-38.4 38.4s19.2 32 38.4 32h256c19.2 0 38.4-19.2 38.4-38.4s-19.2-32-38.4-32zM714.666667 89.6H260.266667c-19.2 0-38.4 19.2-38.4 38.4s19.2 38.4 38.4 38.4h454.4c19.2 0 38.4-19.2 38.4-38.4s-19.2-38.4-38.4-38.4zM522.666667 185.6c-25.6 0-51.2 19.2-64 44.8-6.4 12.8-6.4 19.2-6.4 32l12.8 134.4c0 12.8 6.4 25.6 12.8 32l236.8 345.6c19.2 32 51.2 51.2 89.6 57.6 38.4 6.4 70.4 0 102.4-19.2l12.8-6.4c57.6-44.8 70.4-128 32-185.6L708.266667 268.8c-6.4-12.8-19.2-19.2-32-25.6l-134.4-51.2c-6.4 0-12.8-6.4-19.2-6.4z m300.8 576h-12.8c-19.2 0-32-12.8-38.4-25.6L535.466667 390.4l-6.4-128L644.266667 307.2l243.2 345.6c19.2 25.6 12.8 64-12.8 89.6l-6.4 6.4 19.2 25.6-25.6-25.6c-12.8 6.4-25.6 12.8-38.4 12.8z" horiz-adv-x="1092" />
|
||||
|
||||
|
||||
<glyph glyph-name="shixunzuoye" unicode="" d="M4.266667 896h1024v-1024H4.266667zM964.266667 128H68.266667V832h896v-704zM138.666667 204.8h755.2V761.6H138.666667v-556.8zM708.266667-64H324.266667c-19.2 0-38.4 19.2-38.4 38.4s19.2 38.4 38.4 38.4h384c19.2 0 38.4-19.2 38.4-38.4s-19.2-38.4-38.4-38.4zM708.266667 403.2c-12.8 0-19.2 6.4-25.6 12.8-12.8 12.8-12.8 38.4 6.4 51.2L772.266667 544 682.666667 620.8c-12.8 12.8-12.8 38.4 0 51.2 12.8 12.8 38.4 12.8 51.2 0l89.6-83.2c12.8-12.8 19.2-32 19.2-44.8 0-19.2-6.4-38.4-19.2-51.2l-6.4-6.4-83.2-76.8c-12.8 0-19.2-6.4-25.6-6.4zM330.666667 403.2c-6.4 0-19.2 0-25.6 6.4L215.466667 492.8c-25.6 25.6-25.6 70.4 0 96l89.6 83.2c12.8 12.8 38.4 12.8 51.2 0 12.8-12.8 12.8-38.4 0-51.2L266.666667 537.6l83.2-70.4c12.8-12.8 19.2-38.4 6.4-51.2-6.4-6.4-19.2-12.8-25.6-12.8zM465.066667 384H452.266667c-19.2 12.8-25.6 32-19.2 51.2l102.4 243.2c6.4 19.2 25.6 32 44.8 19.2 19.2-6.4 25.6-25.6 19.2-44.8L503.466667 409.6c-6.4-12.8-19.2-25.6-38.4-25.6zM925.866667 256H119.466667c-19.2 0-38.4 19.2-38.4 38.4s19.2 38.4 38.4 38.4h800c19.2 0 38.4-19.2 38.4-38.4s-12.8-38.4-32-38.4zM401.066667 160h70.4V-64H401.066667zM586.666667 160h70.4V-64H586.666667z" horiz-adv-x="1092" />
|
||||
|
||||
|
||||
|
|
Before Width: | Height: | Size: 506 KiB After Width: | Height: | Size: 584 KiB |
|
@ -1,40 +1,111 @@
|
|||
|
||||
.maxW50{max-width: 50%;}
|
||||
.minW50{min-width: 50%;}
|
||||
.width70{width: 70%;}
|
||||
.width30{width: 30%;}
|
||||
.custom-commit-tabs .ant-tabs-bar{border-bottom: none;}
|
||||
.maxW200px{max-width: 200px;}
|
||||
.pr_tags_open{
|
||||
background: #28BD6C !important;
|
||||
color: #fff !important;
|
||||
border: none !important;
|
||||
.CodeMirror-merge {
|
||||
position: relative;
|
||||
white-space: pre;
|
||||
}
|
||||
.pr_tags_closed{
|
||||
background: #FA6400 !important;
|
||||
color: #fff !important;
|
||||
border: none !important;
|
||||
|
||||
.CodeMirror-merge, .CodeMirror-merge .CodeMirror {
|
||||
min-height:50px;
|
||||
}
|
||||
.pr_tags_merged{
|
||||
background: #4C9ED3 !important;
|
||||
color: #fff !important;
|
||||
border: none !important;
|
||||
|
||||
.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 48%; }
|
||||
.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 4%; }
|
||||
.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; }
|
||||
.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; }
|
||||
|
||||
.CodeMirror-merge-pane {
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
vertical-align: top;
|
||||
}
|
||||
.ant-btn-success{
|
||||
border: 1px solid #28BD6C !important;
|
||||
color: #28BD6C !important;
|
||||
.CodeMirror-merge-pane-rightmost {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
z-index: 1;
|
||||
}
|
||||
.ant-btn-success:hover{
|
||||
background: #28BD6C !important;
|
||||
color:#fff !important;
|
||||
|
||||
.CodeMirror-merge-gap {
|
||||
z-index: 2;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
background: #515151;
|
||||
}
|
||||
.display-flex{display: flex !important;}
|
||||
.merge-flex1{flex:1}
|
||||
.ant-tag.pr-branch-tag{
|
||||
border-radius: 12px;
|
||||
height: 24px;
|
||||
background: rgba(241,248,255,1);
|
||||
border: none;
|
||||
font-size: 13px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-scrolllock-wrap {
|
||||
position: absolute;
|
||||
bottom: 0; left: 50%;
|
||||
}
|
||||
.CodeMirror-merge-scrolllock {
|
||||
position: relative;
|
||||
left: -50%;
|
||||
cursor: pointer;
|
||||
color: #d8d8d8;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right {
|
||||
position: absolute;
|
||||
left: 0; top: 0;
|
||||
right: 0; bottom: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copy {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
color: #ce374b;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copy-reverse {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
color: #44c;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
|
||||
.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; }
|
||||
|
||||
.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);
|
||||
background-position: bottom left;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);
|
||||
background-position: bottom left;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
.CodeMirror-merge-r-chunk { background: #9a6868; }
|
||||
.CodeMirror-merge-r-chunk-start { /*border-top: 1px solid #ee8; */}
|
||||
.CodeMirror-merge-r-chunk-end {/* border-bottom: 1px solid #ee8; */}
|
||||
.CodeMirror-merge-r-connect { fill:#9a6868;}
|
||||
|
||||
.CodeMirror-merge-l-chunk { background: #eef; }
|
||||
.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; }
|
||||
.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; }
|
||||
.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }
|
||||
|
||||
.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; }
|
||||
.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; }
|
||||
.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }
|
||||
|
||||
.CodeMirror-merge-collapsed-widget:before {
|
||||
content: "(...)";
|
||||
}
|
||||
.CodeMirror-merge-collapsed-widget {
|
||||
cursor: pointer;
|
||||
color: #88b;
|
||||
background: #eef;
|
||||
border: 1px solid #ddf;
|
||||
font-size: 90%;
|
||||
padding: 0 3px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; }
|
||||
|
|
|
@ -1,53 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name=”Keywords” Content=”EduCoder,信息技术实践教学,精品课程网,慕课MOOC″>
|
||||
<meta name=”Keywords” Content=”实践课程,项目实战,java实训,python实战,人工智能技术,后端开发学习,移动开发入门″>
|
||||
<meta name=”Keywords” Content=”翻转课堂,高效课堂创建,教学模式″>
|
||||
<meta name=”Keywords” Content=”实训项目,python教程,C语言入门,java书,php后端开发,app前端开发,数据库技术″>
|
||||
<meta name=”Keywords” Content=”在线竞赛,计算机应用大赛,编程大赛,大学生计算机设计大赛,全国高校绿色计算机大赛″>
|
||||
<meta name=”Description”
|
||||
Content=”EduCoder是信息技术类实践教学平台。EduCoder涵盖了计算机、大数据、云计算、人工智能、软件工程、物联网等专业课程。超10000个实训案例及22000个技能评测点,建立学、练、评、测一体化实验环境。”>
|
||||
<meta name=”Description”
|
||||
Content=”EduCoder实践课程,旨在于通过企业级实战实训案例,帮助众多程序员提升各项业务能力。解决学生、学员、企业员工等程序设计能力、算法设计能力、问题求解能力、应用开发能力、系统运维能力等。”>
|
||||
<meta name=”Description”
|
||||
Content=”EduCoder翻转课堂教学模式,颠覆了传统教学模式,让教师与学生的关系由“权威”变成了“伙伴”。将学习的主动权转交给学生,使学生可个性化化学,学生的学习主体得到了彰显。”>
|
||||
<meta name=”Description” Content=”EduCoder实训项目为单个知识点关卡实践训练,帮助学生巩固单一弱点,强化学习。 ”>
|
||||
<meta name=”Description” Content=”EduCoder实践教学平台,各类大赛为进一步提高各类学生综合运用高级语言程序设计能力,培养创新意识和实践探索精神,发掘优秀软件人才。 ”>
|
||||
<meta name=”Keywords” Content=”trustie,trustieforge,forge,确实让创建更美好,协同开发平台″>
|
||||
<meta name=”Keywords” Content=”TrustieOpenSourceProject″>
|
||||
<meta name=”Keywords” Content=”issue,bug,tracker,软件工程,课程实践″>
|
||||
<meta name=”Description” Content=”持续构建协同、共享、可信的软件创建生态开源创作与软件生产相结合,支持大规模群体开展软件协同创新活动”>
|
||||
<meta name="theme-color" content="#000000">
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
|
||||
<script type="text/javascript">
|
||||
window.__isR = true;
|
||||
if (
|
||||
(navigator.userAgent.indexOf('MSIE 9') != -1
|
||||
|| navigator.userAgent.indexOf('MSIE 10') != -1)
|
||||
&&
|
||||
location.pathname.indexOf("/compatibility") == -1) {
|
||||
location.href = '/compatibility.html'
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel=" stylesheet" type="text/css" href="%PUBLIC_URL%css/iconfont.css">
|
||||
<link rel=" stylesheet" type="text/css" href="%PUBLIC_URL%css/edu-purge.css">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/iconfont.css">
|
||||
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/edu-purge.css">
|
||||
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/editormd.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="%PUBLIC_URL%css/merge.css">
|
||||
<%= htmlWebpackPlugin.tags.headTags %>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!--用于markdown转html -->
|
||||
<div id="md_div" style="display: none;"></div>
|
||||
<div id="root" class="page -layout-v -fit widthunit"></div>
|
||||
<div id="picture_display" style="display: none;"></div>
|
||||
<script src="%PUBLIC_URL%js/jquery-1.8.3.min.js"></script>
|
||||
<script src="%PUBLIC_URL%js/js_min_all.js"></script>
|
||||
<script src="%PUBLIC_URL%js/codemirror/codemirror.js"></script>
|
||||
<script src="%PUBLIC_URL%js/editormd/editormd.min.js"></script>
|
||||
<script src="%PUBLIC_URL%js/codemirror/merge/merge.js"></script>
|
||||
<%= htmlWebpackPlugin.tags.bodyTags %>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -66,6 +66,7 @@ body {
|
|||
margin:10px 0px!important;
|
||||
font-size: 16px !important;
|
||||
line-height: 2 !important;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.markdown-body>p {
|
||||
|
|
30
src/App.js
|
@ -9,13 +9,7 @@ import {
|
|||
} from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import LoginDialog from './modules/login/LoginDialog';
|
||||
import Notcompletedysl from './modules/user/Notcompletedysl';
|
||||
import Trialapplicationysl from './modules/login/Trialapplicationysl';
|
||||
import Trialapplicationreview from './modules/user/Trialapplicationreview';
|
||||
import AccountProfile from "./modules/user/AccountProfile";
|
||||
import Accountnewprofile from './modules/user/Accountnewprofile';
|
||||
import Certifiedprofessional from './modules/modals/Certifiedprofessional';
|
||||
|
||||
import 'babel-polyfill';
|
||||
import Loading from './Loading'
|
||||
|
||||
import Loadable from 'react-loadable';
|
||||
|
@ -87,6 +81,10 @@ const SponsorConfirmation = Loadable({
|
|||
loader: () => import('./forge/sponsor/SponsorConfirmation'),
|
||||
loading: Loading,
|
||||
})
|
||||
const EducoderLogin = Loadable({
|
||||
loader: () => import('./modules/login/EducoderLogin'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
|
@ -224,18 +222,12 @@ class App extends Component {
|
|||
<Provider store={store}>
|
||||
<ConfigProvider locale={zhCN}>
|
||||
<MuiThemeProvider theme={theme}>
|
||||
<Accountnewprofile {...this.props}{...this.state} />
|
||||
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
|
||||
<Notcompletedysl {...this.props} {...this.state}></Notcompletedysl>
|
||||
<Trialapplicationysl {...this.props} {...this.state}></Trialapplicationysl>
|
||||
<Trialapplicationreview {...this.props} {...this.state}></Trialapplicationreview>
|
||||
<AccountProfile {...this.props} {...this.state} />
|
||||
<Certifiedprofessional {...this.props} {...this.state} ModalCancelsy={this.ModalCancelsy} ModalshowCancelsy={this.ModalshowCancelsy} />
|
||||
<Router>
|
||||
<Switch>
|
||||
{/*项目*/}
|
||||
<Route
|
||||
path={"/projects/:projectId/ops/:opsId/detail"}
|
||||
path={"/projects/:owner/:projectId/devops/:opsId/detail"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<OpsDetail {...this.props} {...props} {...this.state} />)
|
||||
|
@ -251,7 +243,15 @@ class App extends Component {
|
|||
}
|
||||
}>
|
||||
</Route>
|
||||
|
||||
<Route
|
||||
path="/register"
|
||||
render={
|
||||
(props) => {
|
||||
|
||||
return (<EducoderLogin {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}
|
||||
/>
|
||||
{/*403*/}
|
||||
<Route path="/403" component={Shixunauthority} />
|
||||
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import axios from 'axios';
|
||||
import { requestProxy } from "./indexEduplus2RequestProxy";
|
||||
import { broadcastChannelOnmessage , isDev, queryString } from 'educoder';
|
||||
import { broadcastChannelOnmessage, isDev, queryString } from 'educoder';
|
||||
import { notification } from 'antd';
|
||||
import cookie from 'react-cookies';
|
||||
import './index.css';
|
||||
const $ = window.$;
|
||||
let timestamp;
|
||||
let checkSubmitFlg = false;
|
||||
let message501 = false;
|
||||
|
||||
broadcastChannelOnmessage('refreshPage', () => {
|
||||
|
@ -31,7 +28,7 @@ if (isDev) {
|
|||
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
|
||||
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
|
||||
}
|
||||
}
|
||||
function clearAllCookie() {
|
||||
cookie.remove('_educoder_session', { path: '/' });
|
||||
cookie.remove('autologin_trustie', { path: '/' });
|
||||
|
@ -39,11 +36,8 @@ function clearAllCookie() {
|
|||
}
|
||||
clearAllCookie();
|
||||
function setpostcookie() {
|
||||
|
||||
const str = window.location.pathname;
|
||||
let newdomain = ".educoder.net"
|
||||
if (str.indexOf("/wxcode") !== -1) {
|
||||
console.log("123")
|
||||
cookie.remove('_educoder_session', { path: '/' });
|
||||
cookie.remove('autologin_trustie', { path: '/' });
|
||||
const _params = window.location.search;
|
||||
|
@ -53,7 +47,6 @@ function setpostcookie() {
|
|||
cookie.save('_educoder_session', _educoder_sessions[1], { domain: '.educoder.net', path: '/' });
|
||||
let autologin_trusties = _search.split('&')[1].split('=');
|
||||
cookie.save('autologin_trustie', autologin_trusties[1], { domain: '.educoder.net', path: '/' });
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +70,7 @@ export function initAxiosInterceptors(props) {
|
|||
setpostcookie()
|
||||
clearAllCookie()
|
||||
|
||||
if (config.url.indexOf(proxy) !== -1 || config.url.indexOf(':') !== -1) {
|
||||
if (config.url.indexOf(proxy) !== -1) {
|
||||
return config
|
||||
}
|
||||
requestProxy(config)
|
||||
|
@ -109,12 +102,10 @@ export function initAxiosInterceptors(props) {
|
|||
});
|
||||
|
||||
axios.interceptors.response.use(function (response) {
|
||||
|
||||
// console.log(".............")
|
||||
if (response === undefined) {
|
||||
return
|
||||
}
|
||||
const config = response.config
|
||||
const config = response.config;
|
||||
if (response.data.status === -1) {
|
||||
if (window.location.pathname.startsWith('/tasks/')) {
|
||||
props.showSnackbar(response.data.message || '服务器异常,请联系管理员。')
|
||||
|
@ -127,12 +118,10 @@ export function initAxiosInterceptors(props) {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
throw new axios.Cancel('Operation canceled by the user.');
|
||||
}
|
||||
|
||||
if (response.data.status === 403 || response.data.status === "403") {
|
||||
|
||||
locationurl('/403');
|
||||
}
|
||||
|
||||
|
@ -159,8 +148,6 @@ export function initAxiosInterceptors(props) {
|
|||
message501 = false
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
|
||||
requestMap[response.config.url] = false;
|
||||
setpostcookie();
|
||||
return response;
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import React, { Component } from 'react';
|
||||
|
||||
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
|
||||
|
||||
import { Spin } from 'antd';
|
||||
|
||||
class Loading extends Component {
|
||||
|
@ -12,7 +9,6 @@ class Loading extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
// Loading
|
||||
return (
|
||||
<div className="App" style={{ minHeight: '800px', width: "100%" }}>
|
||||
<style>
|
||||
|
|
|
@ -11,13 +11,28 @@ export function getImageUrl(path) {
|
|||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
// const local = 'http://localhost:3000'
|
||||
const local = 'https://testforgeplus.trustie.net/'
|
||||
const local = 'https://testforgeplus.trustie.net';
|
||||
if (isDev) {
|
||||
return `${local}/${path}`
|
||||
}
|
||||
return `/${path}`;
|
||||
}
|
||||
|
||||
export function getImage(path) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
// const local = 'http://localhost:3000'
|
||||
const local = 'https://testforgeplus.trustie.net/';
|
||||
if(path.indexOf("http://")===-1){
|
||||
if (isDev) {
|
||||
return `${local}/images/${path}`
|
||||
}
|
||||
return `/${path}`;
|
||||
}else{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
export function getcdnImageUrl(path) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
|
@ -78,14 +93,6 @@ export function setImagesUrl(path){
|
|||
}
|
||||
|
||||
export function getUrl(path, goTest) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
|
||||
// 如果想所有url定位到测试版,可以反注释掉下面这行
|
||||
//goTest = true
|
||||
// testbdweb.educoder.net testbdweb.trustie.net
|
||||
// const local = goTest ? 'https://testeduplus2.educoder.net' : 'http://localhost:3000'
|
||||
// const local = 'https://testeduplus2.educoder.net'
|
||||
const local = 'https://testforgeplus.trustie.net'
|
||||
if (isDev) {
|
||||
return `${local}${path?path:''}`
|
||||
|
|
|
@ -38,13 +38,11 @@ export const formatDelta = (deltas) => {
|
|||
alt="${alt}"
|
||||
/>
|
||||
`;
|
||||
// text = "<img src="+url+" width='60px' height='30px' onclick='' alt="+alt+"/>";
|
||||
}
|
||||
}
|
||||
|
||||
formatted.push(text);
|
||||
});
|
||||
console.log(formatted);
|
||||
return formatted.join('');
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
export {
|
||||
getUploadLogoActionUrl as getUploadLogoActionUrl,
|
||||
getImageUrl as getImageUrl, getmyUrl as getmyUrl, getRandomNumber as getRandomNumber, getUrl as getUrl, publicSearchs as publicSearchs, getRandomcode as getRandomcode, getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl
|
||||
getImageUrl as getImageUrl,getImage as getImage, getmyUrl as getmyUrl, getRandomNumber as getRandomNumber, getUrl as getUrl, publicSearchs as publicSearchs, getRandomcode as getRandomcode, getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl
|
||||
, getUploadActionUrl as getUploadActionUrl, getUploadActionUrltwo as getUploadActionUrltwo, getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth
|
||||
, getTaskUrlById as getTaskUrlById, TEST_HOST, htmlEncode as htmlEncode, getupload_git_file as getupload_git_file, getcdnImageUrl as getcdnImageUrl
|
||||
} from './UrlTool';
|
||||
|
|
|
@ -12,32 +12,25 @@ function ImageLayer2(props) {
|
|||
setShowImage(false)
|
||||
setImageSrc('')
|
||||
}
|
||||
const onDelegateClick = (event) => {
|
||||
const imageSrc = event.target.src || event.target.getAttribute('src') || event.target.getAttribute('href')
|
||||
// 判断imageSrc是否是图片
|
||||
const fileName = event.target.innerHTML.trim()
|
||||
if (isImageExtension((imageSrc && imageSrc.trim())) || isImageExtension(fileName) || event.target.tagName == 'IMG' || (imageSrc && imageSrc.indexOf('base64,')) != -1) {
|
||||
// 非回复里的头像图片; 非emoticons
|
||||
if (imageSrc.indexOf('/images/avatars/User') === -1 &&
|
||||
imageSrc.indexOf('kindeditor/plugins/emoticons') === -1 ) {
|
||||
setShowImage(true)
|
||||
setImageSrc(imageSrc)
|
||||
}
|
||||
event.stopPropagation()
|
||||
event.preventDefault && event.preventDefault()
|
||||
event.originalEvent.preventDefault()
|
||||
// event.originalEvent.stopPropagation()
|
||||
// event.originalEvent.cancelBubble = true
|
||||
return false;
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
$(parentSel)
|
||||
.delegate(childSel, "click", onDelegateClick);
|
||||
|
||||
return () => {
|
||||
$(parentSel).undelegate(childSel, "click", onDelegateClick )
|
||||
}
|
||||
$(parentSel).delegate(childSel, "click", (event) => {
|
||||
const imageSrc = event.target.src || event.target.getAttribute('src') || event.target.getAttribute('href')
|
||||
// 判断imageSrc是否是图片
|
||||
const fileName = event.target.innerHTML.trim();
|
||||
|
||||
if (isImageExtension((imageSrc && imageSrc.trim())) || isImageExtension(fileName) || event.target.tagName == 'IMG' || (imageSrc && imageSrc.indexOf('base64,')) != -1) {
|
||||
// 非回复里的头像图片; 非emoticons
|
||||
if (imageSrc.indexOf('/images/avatars/User') === -1 &&
|
||||
imageSrc.indexOf('kindeditor/plugins/emoticons') === -1 ) {
|
||||
setShowImage(true)
|
||||
setImageSrc(imageSrc)
|
||||
}
|
||||
event.stopPropagation()
|
||||
event.preventDefault && event.preventDefault()
|
||||
event.originalEvent.preventDefault()
|
||||
return false;
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,12 +1,33 @@
|
|||
import marked from 'marked'
|
||||
import { escape, unescape } from 'marked/src/helpers'
|
||||
import { renderToString } from 'katex';
|
||||
import { escape } from 'marked/src/helpers'
|
||||
|
||||
function indentCodeCompensation(raw, text) {
|
||||
const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
|
||||
if (matchIndentToCode === null) {
|
||||
return text;
|
||||
}
|
||||
const indentToCode = matchIndentToCode[1];
|
||||
return text
|
||||
.split('\n')
|
||||
.map(node => {
|
||||
const matchIndentInNode = node.match(/^\s+/);
|
||||
if (matchIndentInNode === null) {
|
||||
return node;
|
||||
}
|
||||
const [indentInNode] = matchIndentInNode;
|
||||
if (indentInNode.length >= indentToCode.length) {
|
||||
return node.slice(indentToCode.length);
|
||||
}
|
||||
return node;
|
||||
})
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
const latexRegex = /\$+([^\$\n]+?)\$+/g
|
||||
//兼容之前的 ##标题式写法
|
||||
const headingRegex = /^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/
|
||||
let toc = []
|
||||
let ctx = ["<ul>"]
|
||||
const renderer = new marked.Renderer()
|
||||
const headingRegex = /^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/
|
||||
|
||||
export function cleanToc() {
|
||||
toc = []
|
||||
|
@ -40,75 +61,101 @@ export function getTocContent() {
|
|||
|
||||
const tokenizer = {
|
||||
heading(src) {
|
||||
const cap = headingRegex.exec(src);
|
||||
const cap = headingRegex.exec(src)
|
||||
if (cap) {
|
||||
return {
|
||||
type: 'heading',
|
||||
raw: cap[0],
|
||||
depth: cap[1].length,
|
||||
text: cap[2]
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
codespan(src) {
|
||||
const cap = this.rules.inline.code.exec(src);
|
||||
fences(src) {
|
||||
const cap = this.rules.block.fences.exec(src)
|
||||
if (cap) {
|
||||
let text = cap[2].replace(/\n/g, ' ');
|
||||
const hasNonSpaceChars = /[^ ]/.test(text);
|
||||
const hasSpaceCharsOnBothEnds = text.startsWith(' ') && text.endsWith(' ');
|
||||
if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
|
||||
text = text.substring(1, text.length - 1)
|
||||
}
|
||||
let match = text.match(latexRegex)
|
||||
if (match) {
|
||||
text = text.replace(latexRegex, (_, $1) => {
|
||||
return renderToString(unescape($1))
|
||||
})
|
||||
} else {
|
||||
text = escape(text, true);
|
||||
const raw = cap[0]
|
||||
let text = indentCodeCompensation(raw, cap[3] || '')
|
||||
const lang = cap[2] ? cap[2].trim() : cap[2]
|
||||
if (['latex', 'katex', 'math'].indexOf(lang) >= 0) {
|
||||
const id = next_id()
|
||||
const expression = text
|
||||
text = id
|
||||
math_expressions[id] = { type: 'block', expression }
|
||||
}
|
||||
return {
|
||||
type: 'codespan',
|
||||
raw: cap[0],
|
||||
type: 'code',
|
||||
raw,
|
||||
lang,
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const renderer = {
|
||||
code(code, infostring, escaped) {
|
||||
const lang = (infostring || '').match(/\S*/)[0];
|
||||
if (!lang) {
|
||||
return '<pre class="prettyprint linenums"><code>'
|
||||
+ (escaped ? code : escape(code, true))
|
||||
+ '</code></pre>';
|
||||
}
|
||||
const latexRegex = /(?:\${2})([^\n`]+?)(?:\${2})/gi
|
||||
let katex_count = 0
|
||||
const next_id = () => `__special_katext_id_${katex_count++}__`
|
||||
let math_expressions = {}
|
||||
|
||||
if (['latex', 'katex', 'math'].indexOf(lang) >= 0) {
|
||||
return `<p class='editormd-tex'>${renderToString(unescape(code))}</p>`
|
||||
} else {
|
||||
return `<pre class="prettyprint linenums"><code class="language-${infostring}">${escaped ? code : escape(code, true)}</code></pre>\n`
|
||||
}
|
||||
export function getMathExpressions() {
|
||||
return math_expressions
|
||||
}
|
||||
|
||||
export function resetMathExpressions() {
|
||||
katex_count = 0
|
||||
math_expressions = {}
|
||||
}
|
||||
|
||||
function replace_math_with_ids(text) {
|
||||
let rs = text.replace(latexRegex, (_match, expression) => {
|
||||
const id = next_id()
|
||||
math_expressions[id] = { type: 'inline', expression }
|
||||
return id
|
||||
})
|
||||
|
||||
return rs
|
||||
}
|
||||
|
||||
const original_listitem = renderer.listitem
|
||||
renderer.listitem = function (text, task, checked) {
|
||||
return original_listitem(replace_math_with_ids(text), task, checked)
|
||||
}
|
||||
|
||||
const original_paragraph = renderer.paragraph
|
||||
renderer.paragraph = function (text) {
|
||||
return original_paragraph(replace_math_with_ids(text))
|
||||
}
|
||||
|
||||
const original_tablecell = renderer.tablecell
|
||||
renderer.tablecell = function (content, flags) {
|
||||
return original_tablecell(replace_math_with_ids(content), flags)
|
||||
}
|
||||
|
||||
renderer.code = function (code, infostring, escaped) {
|
||||
const lang = (infostring || '').match(/\S*/)[0];
|
||||
if (!lang) {
|
||||
return '<pre class="prettyprint linenums"><code>'
|
||||
+ (escaped ? code : escape(code, true))
|
||||
+ '</code></pre>';
|
||||
}
|
||||
, paragraph(text) {
|
||||
let match = text.match(latexRegex)
|
||||
if (match) {
|
||||
text = text.replace(latexRegex, (_, $1) => {
|
||||
return renderToString(unescape($1))
|
||||
})
|
||||
}
|
||||
return '<p>' + text + '</p>\n';
|
||||
},
|
||||
heading(text, level, raw, slugger) {
|
||||
let anchor = this.options.headerPrefix + raw.toLowerCase().replace(/[^\w\\u4e00-\\u9fa5]]+/g, '-');
|
||||
toc.push({
|
||||
anchor: anchor,
|
||||
level: level,
|
||||
text: text
|
||||
})
|
||||
return '<h' + level + ' id="' + anchor + '">' + text + '</h' + level + '>'
|
||||
|
||||
if (['latex', 'katex', 'math'].indexOf(lang) >= 0) {
|
||||
return `<p class='editormd-tex'>${code}</p>`
|
||||
} else {
|
||||
return `<pre class="prettyprint linenums"><code class="language-${infostring}">${escaped ? code : escape(code, true)}</code></pre>\n`
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
renderer.heading = function (text, level, raw) {
|
||||
let anchor = this.options.headerPrefix + raw.toLowerCase().replace(/[^\w\\u4e00-\\u9fa5]]+/g, '-');
|
||||
toc.push({
|
||||
anchor: anchor,
|
||||
level: level,
|
||||
text: text
|
||||
})
|
||||
return '<h' + level + ' id="' + anchor + '">' + text + '</h' + level + '>'
|
||||
}
|
||||
|
||||
marked.setOptions({
|
||||
|
|
|
@ -1,31 +1,46 @@
|
|||
import React, { useEffect, useRef } from "react";
|
||||
import React, { useEffect, useRef, useMemo } from "react";
|
||||
import "katex/dist/katex.min.css";
|
||||
import { renderToString } from 'katex';
|
||||
import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions } from "../common/marked";
|
||||
import 'code-prettify'
|
||||
|
||||
import marked, { getTocContent, cleanToc } from "../common/marked";
|
||||
const preRegex = /<pre[^>]*>/g
|
||||
|
||||
let preRegex = /<pre[^>]*>/g;
|
||||
function _unescape(str) {
|
||||
let div = document.createElement('div')
|
||||
div.innerHTML = str
|
||||
return div.childNodes.length === 0 ? "" : div.childNodes[0].nodeValue;
|
||||
}
|
||||
|
||||
export default ({ value = "", is_md = true, className, style = {} }) => {
|
||||
let str = String(value);
|
||||
let html = is_md ? marked(str) : value;
|
||||
if (str.match(/\[TOC\]/)) {
|
||||
html = html.replace("<p>[TOC]</p>", getTocContent());
|
||||
cleanToc();
|
||||
}
|
||||
export default ({ value = '', className, style = {} }) => {
|
||||
let str = String(value)
|
||||
|
||||
html = html.replace(/▁/g, "▁▁▁");
|
||||
// html = html.replace(/\n/g,"<br/>");
|
||||
const el = useRef();
|
||||
const html = useMemo(() => {
|
||||
let rs = marked(str)
|
||||
const math_expressions = getMathExpressions()
|
||||
if (str.match(/\[TOC\]/)) {
|
||||
rs = rs.replace("<p>[TOC]</p>", getTocContent())
|
||||
cleanToc()
|
||||
}
|
||||
rs = rs.replace(/(__special_katext_id_\d+__)/g, (_match, capture) => {
|
||||
const { type, expression } = math_expressions[capture]
|
||||
return renderToString(_unescape(expression), { displayMode: type === 'block', throwOnError: false, output: 'html' })
|
||||
})
|
||||
rs = rs.replace(/▁/g, "▁▁▁")
|
||||
resetMathExpressions()
|
||||
return rs
|
||||
}, [str])
|
||||
|
||||
const el = useRef()
|
||||
function onAncherHandler(e) {
|
||||
let target = e.target;
|
||||
if (target.tagName.toUpperCase() === "A") {
|
||||
let ancher = target.getAttribute("href");
|
||||
if (ancher.startsWith("#")) {
|
||||
e.preventDefault();
|
||||
let viewEl = document.getElementById(ancher.replace("#", ""));
|
||||
let target = e.target
|
||||
if (target.tagName.toUpperCase() === 'A') {
|
||||
let ancher = target.getAttribute('href')
|
||||
if (ancher.startsWith('#')) {
|
||||
e.preventDefault()
|
||||
let viewEl = document.getElementById(ancher.replace('#', ''))
|
||||
if (viewEl) {
|
||||
viewEl.parentNode.scrollTop = viewEl.offsetTop;
|
||||
viewEl.parentNode.scrollTop = viewEl.offsetTop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,23 +49,18 @@ export default ({ value = "", is_md = true, className, style = {} }) => {
|
|||
useEffect(() => {
|
||||
if (el.current && html) {
|
||||
if (html.match(preRegex)) {
|
||||
window.PR.prettyPrint();
|
||||
window.PR.prettyPrint()
|
||||
}
|
||||
}
|
||||
if (el.current) {
|
||||
el.current.addEventListener("click", onAncherHandler);
|
||||
el.current.addEventListener('click', onAncherHandler)
|
||||
return () => {
|
||||
el.current.removeEventListener("click", onAncherHandler);
|
||||
};
|
||||
el.current.removeEventListener('click', onAncherHandler)
|
||||
resetMathExpressions()
|
||||
cleanToc()
|
||||
}
|
||||
}
|
||||
}, [html, el.current, onAncherHandler]);
|
||||
}, [html, el.current, onAncherHandler])
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={el}
|
||||
style={style}
|
||||
className={`${className ? className : ""} markdown-body`}
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
></div>
|
||||
);
|
||||
};
|
||||
return (<div ref={el} style={style} className={`${className ? className : ''} markdown-body`} dangerouslySetInnerHTML={{ __html: html }}></div>)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import './index.scss';
|
||||
import { Button } from 'antd';
|
||||
import Upload from "../Upload/Index";
|
||||
import UploadImg from "../Images/upload.png";
|
||||
import MDEditor from "../../modules/tpm/challengesnew/tpm-md-editor";
|
||||
import { AlignCenterBetween } from '../Component/layout';
|
||||
import axios from 'axios';
|
||||
import RenderHtml from '../../components/render-html';
|
||||
import Attachments from "../Upload/attachment";
|
||||
|
||||
function Index(props){
|
||||
const [ attachments , setAttachments ] = useState(undefined);
|
||||
const [ content , setContent ] = useState(undefined);
|
||||
const [ edit , setEdit ] = useState(false);
|
||||
const [ fileList , setFileList ] = useState(undefined);
|
||||
const [ editOpration , setEditOpration ] = useState(false);
|
||||
const { owner , projectsId } = props.match.params;
|
||||
|
||||
const { isManager , isDeveloper , current_user } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
if(owner && projectsId){
|
||||
Init();
|
||||
}
|
||||
},[owner,projectsId])
|
||||
|
||||
useEffect(()=>{
|
||||
if( (current_user && current_user.login) && (isManager === true || isDeveloper === true)){
|
||||
setEditOpration(true);
|
||||
}
|
||||
},[isManager , isDeveloper])
|
||||
function Init(){
|
||||
const url = `/${owner}/${projectsId}/about.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
setContent(result.data.content);
|
||||
setAttachments(result.data.attachments);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function editContent(){
|
||||
setEdit(true);
|
||||
}
|
||||
|
||||
|
||||
function onContentChange(value){
|
||||
setContent(value);
|
||||
};
|
||||
|
||||
function UploadFunc(fileList){
|
||||
setFileList(fileList);
|
||||
};
|
||||
|
||||
function sureSubmit(){
|
||||
const url = `/${owner}/${projectsId}/about.json`;
|
||||
axios.post(url,{
|
||||
content,attachment_ids:fileList
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
props.showNotification("项目主页编辑成功!");
|
||||
Init();
|
||||
setEdit(false);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
return(
|
||||
<div className="aboutPanels">
|
||||
|
||||
<div className="aboutContent">
|
||||
<AlignCenterBetween style={{padding:"14px 0px"}}>
|
||||
<span className="font-16"><i className="iconfont icon-xiangmujianjie mr5 font-16 color-blue"></i>项目简介</span>
|
||||
{ editOpration && !edit && <a onClick={editContent} className="color-blue">编辑</a> }
|
||||
</AlignCenterBetween>
|
||||
{
|
||||
edit ?
|
||||
<div>
|
||||
<MDEditor
|
||||
placeholder={"请输入描述信息"}
|
||||
height={200}
|
||||
mdID={"order-new-description"}
|
||||
initValue={content}
|
||||
onChange={onContentChange}
|
||||
className="mt20"
|
||||
></MDEditor>
|
||||
<div className="pb20">
|
||||
<Upload
|
||||
className="commentStyle mt20"
|
||||
isComplete={true}
|
||||
load={UploadFunc}
|
||||
icon={
|
||||
<img
|
||||
src={UploadImg}
|
||||
width="58"
|
||||
alt=""
|
||||
style={{ marginBottom: 15 }}
|
||||
/>
|
||||
}
|
||||
size={100}
|
||||
showNotification={props.showNotification}
|
||||
/>
|
||||
{attachments && attachments.length > 0 &&
|
||||
<Attachments
|
||||
attachments={attachments}
|
||||
showNotification={props.showNotification}
|
||||
canDelete={true}
|
||||
></Attachments>
|
||||
}
|
||||
</div>
|
||||
<div className="pb30">
|
||||
<Button type="primary" onClick={sureSubmit}>确定</Button>
|
||||
<Button className="ml30" onClick={()=>setEdit(false)}>取消</Button>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div style={{padding:"20px 0px"}}>
|
||||
{content ?
|
||||
<RenderHtml className="break_word_comments imageLayerParent" value={content} />
|
||||
:
|
||||
<div>暂无简介~</div>
|
||||
}
|
||||
{attachments && attachments.length > 0 &&
|
||||
<Attachments
|
||||
attachments={attachments}
|
||||
showNotification={props.showNotification}
|
||||
></Attachments>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Index;
|
|
@ -0,0 +1,13 @@
|
|||
.aboutPanels{
|
||||
max-width: 1200px;
|
||||
margin:0px auto;
|
||||
.aboutContent{
|
||||
border-radius: 2px;
|
||||
border: 1px solid #EEEEEE;
|
||||
padding:0px 30px;
|
||||
width:100%;
|
||||
background-color: #fff;
|
||||
margin-top:20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
|
@ -52,8 +52,8 @@ class Activity extends Component{
|
|||
}
|
||||
|
||||
getInfo =(time,type,status,page)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/project_trends.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/activity.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
time,type,status,page
|
||||
|
@ -177,7 +177,7 @@ class Activity extends Component{
|
|||
}
|
||||
</div>
|
||||
:
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
<NoneData _html="暂时还没有相关数据!" />
|
||||
}
|
||||
</Spin>
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@ import { getImageUrl } from 'educoder';
|
|||
|
||||
class ActivityItem extends Component {
|
||||
render() {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId ,owner } = this.props.match.params;
|
||||
const { item } = this.props;
|
||||
return (
|
||||
<div className="activity_item">
|
||||
|
@ -14,24 +14,24 @@ class ActivityItem extends Component {
|
|||
{/* 如果是版本发布 */}
|
||||
{item.trend_type === "VersionRelease" ?
|
||||
<p className="itemLine">
|
||||
<Link to={`/projects/${projectsId}/version`} className="color-blue font-16">{item.name}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/version`} 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={`/projects/${projectsId}/orders/${item.trend_id}/detail`} className="color-blue font-16">{item.name}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/issues/${item.trend_id}/detail`} className="color-blue font-16">{item.name}</Link>
|
||||
<span className="activity_type">{item.trend_type}</span>
|
||||
</p >
|
||||
:
|
||||
// 如果是合并请求
|
||||
<p className="itemLine">
|
||||
<Link to={`/projects/${projectsId}/merge/${item.trend_id}/Messagecount`} className="color-blue font-16">{item.name}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/pulls/${item.trend_id}/Messagecount`} className="color-blue font-16">{item.name}</Link>
|
||||
<span className="activity_type">{item.trend_type}</span>
|
||||
</p >
|
||||
}
|
||||
<p className="itemLine mt15">
|
||||
<p className="itemLine mt10">
|
||||
<Link to={`/users/${item && item.login}`} className="show-user-link">
|
||||
<img alt="" src={getImageUrl(`images/${item.user_avatar}`)} className="createImage" />
|
||||
<span className="mr20">{item.user_name}</span>
|
||||
|
|
|
@ -66,6 +66,9 @@
|
|||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.activity_list .activity_item:last-child{
|
||||
border-bottom: none;
|
||||
}
|
||||
.prPercent > p{
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
|
@ -98,6 +101,7 @@
|
|||
height: 22px;
|
||||
line-height: 22px;
|
||||
border-radius: 50%;
|
||||
width: 22px;
|
||||
}
|
||||
.change{
|
||||
color: black;
|
||||
|
|
|
@ -14,7 +14,7 @@ class CloneAddress extends Component {
|
|||
const { http_url, downloadUrl } = this.props;
|
||||
return (
|
||||
<div className="gitAddressClone">
|
||||
<p className="addressTips"><span>版本库地址已变更,请基于新地址提交代码</span></p>
|
||||
{/* <p className="addressTips"><span>版本库地址已变更,请基于新地址提交代码</span></p> */}
|
||||
{
|
||||
http_url && <span>HTTP</span>
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import './branch.css';
|
|||
import { getBranch , getTag } from '../GetData/getData';
|
||||
|
||||
|
||||
export default (({ projectsId , repo_id , changeBranch , branch })=>{
|
||||
export default (({ projectsId , branch , owner , history , changeBranch })=>{
|
||||
const [ showValue , setShowValue ] = useState(branch);
|
||||
const [ inputValue , setInputValue] = useState(undefined);
|
||||
const [ nav , setNav ] = useState(0);
|
||||
|
@ -17,10 +17,11 @@ export default (({ projectsId , repo_id , changeBranch , branch })=>{
|
|||
useEffect(()=>{
|
||||
setShowValue(branch);
|
||||
},[branch])
|
||||
|
||||
useEffect(()=>{
|
||||
document.body.addEventListener('click', e => {
|
||||
let name = e.target.className;
|
||||
let turn = name == "ant-input OptionsInput" || name == "navli active"|| name == "navli" || name == "padding10 bor-bottom-greyE";
|
||||
let turn = name === "ant-input OptionsInput" || name === "navli active"|| name === "navli" || name === "padding10 bor-bottom-greyE";
|
||||
if(turn){
|
||||
return;
|
||||
}else{
|
||||
|
@ -30,18 +31,18 @@ export default (({ projectsId , repo_id , changeBranch , branch })=>{
|
|||
})
|
||||
|
||||
useEffect(()=>{
|
||||
getBranchs(projectsId);
|
||||
},[projectsId])
|
||||
getBranchs(projectsId,owner);
|
||||
},[owner])
|
||||
|
||||
|
||||
async function getBranchs(id){
|
||||
let result = await getBranch(id);
|
||||
async function getBranchs(id,owner){
|
||||
let result = await getBranch(id,owner);
|
||||
setData(result);
|
||||
setDatas(result);
|
||||
setIsSpin(false);
|
||||
}
|
||||
async function getTags(id){
|
||||
let result = await getTag(id);
|
||||
async function getTags(id,owner){
|
||||
let result = await getTag(id,owner);
|
||||
setData(result);
|
||||
setDatas(result);
|
||||
setIsSpin(false);
|
||||
|
@ -57,13 +58,13 @@ export default (({ projectsId , repo_id , changeBranch , branch })=>{
|
|||
setNav(nav);
|
||||
setIsSpin(true);
|
||||
if(nav === 0){
|
||||
getBranchs(projectsId);
|
||||
getBranchs(projectsId,owner);
|
||||
}else{
|
||||
getTags(repo_id);
|
||||
getTags(projectsId,owner);
|
||||
}
|
||||
}
|
||||
function chooseitem(value){
|
||||
setShowValue(value);
|
||||
// setShowValue(value);
|
||||
changeBranch(value);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
width: 240px;
|
||||
min-width: 240px;
|
||||
}
|
||||
.branch-tagBox-list .ant-popover-arrow{
|
||||
display: none;
|
||||
|
|
|
@ -8,6 +8,10 @@ li.ant-menu-item{
|
|||
margin:0px!important;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.flags{
|
||||
border: 1px solid red;
|
||||
border-radius: 5px;
|
||||
}
|
||||
// Cards
|
||||
.cards{
|
||||
display: flex;
|
||||
|
@ -72,6 +76,7 @@ li.ant-menu-item{
|
|||
border-radius:11px;
|
||||
color: #fff;
|
||||
margin-left: 5px;
|
||||
font-size: 12px;
|
||||
&.running{
|
||||
background:#5091FF;
|
||||
color: #F1F8FF;
|
||||
|
@ -88,6 +93,10 @@ li.ant-menu-item{
|
|||
background:#F73030;
|
||||
color:#FCEEEE ;
|
||||
}
|
||||
&.killed{
|
||||
background:#eee;
|
||||
color:#999 ;
|
||||
}
|
||||
}
|
||||
.handleBox{
|
||||
position: fixed;
|
||||
|
@ -95,6 +104,7 @@ li.ant-menu-item{
|
|||
right:240px;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1800px){
|
||||
.handleBox{
|
||||
right:190px;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import React , { useState , useEffect } from 'react';
|
||||
import { Select } from 'antd';
|
||||
|
||||
import axios from 'axios';
|
||||
const Option = Select.Option;
|
||||
const LANGUAGE = [
|
||||
"apex",
|
||||
|
@ -54,11 +54,30 @@ const LANGUAGE = [
|
|||
"xml",
|
||||
"yaml",
|
||||
];
|
||||
|
||||
export default (({ language , select_language })=>{
|
||||
const [ languages , setLanguage ] = useState(undefined);
|
||||
|
||||
// useEffect(()=>{
|
||||
// const url = '/dev_ops/languages.json';
|
||||
// axios.get(url).then(result=>{
|
||||
// if(result){
|
||||
// setLanguage(result.data);
|
||||
// }
|
||||
// }).catch(error=>{
|
||||
// console.log(error);
|
||||
// })
|
||||
// },[])
|
||||
|
||||
function changelanguage(value){
|
||||
// let array = value ? languages.filter(item=>item.name === value) :undefined;
|
||||
select_language(value);
|
||||
}
|
||||
|
||||
return(
|
||||
<Select showSearch={true} placeholder={"请选择文本语言"} style={{ width: 200 }} value={language} onChange={select_language}>
|
||||
<Select showSearch={true} placeholder={"请选择文本语言"} style={{ width: 200 }} value={language} onChange={changelanguage}>
|
||||
<Option value={undefined}>请选择文本语言</Option>
|
||||
{LANGUAGE.map((item, key) => {
|
||||
{LANGUAGE && LANGUAGE.map((item, key) => {
|
||||
return <Option value={item}>{item}</Option>;
|
||||
})}
|
||||
</Select>
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
|
||||
|
||||
export default ({title , value , className})=>{
|
||||
const Keys = styled.span`
|
||||
display:flex;
|
||||
align-item:center;
|
||||
align-items:center;
|
||||
& span{
|
||||
display:block;
|
||||
height:20px;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import React from 'react';
|
||||
import { Modal , Button } from 'antd';
|
||||
import './Component.scss';
|
||||
|
||||
function Modals({visible,title,content,onOk,onCancel}){
|
||||
return(
|
||||
<Modal
|
||||
className="modalsStyle"
|
||||
visible={visible}
|
||||
title={title}
|
||||
onCancel={onCancel}
|
||||
closable={true}
|
||||
footer={
|
||||
<div>
|
||||
<Button onClick={onCancel}>取消</Button>
|
||||
<Button type={"primary"} style={{marginLeft:"20px"}} onClick={onOk}>确定</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div style={{fontSize:"16px"}}>{content}</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default Modals;
|
|
@ -0,0 +1,61 @@
|
|||
import React , { useState , useEffect } from 'react';
|
||||
import { Select } from 'antd';
|
||||
import { getUrl } from 'educoder';
|
||||
|
||||
import axios from 'axios';
|
||||
const Option = Select.Option;
|
||||
|
||||
export default (({ language , select_language })=>{
|
||||
const [ six , setSix ] = useState(undefined);
|
||||
const [ languages , setLanguage ] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
const url = '/ci/languages.json';
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
setLanguage(result.data);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
},[])
|
||||
|
||||
function changelanguage(value){
|
||||
let array = value ? languages.filter(item=>item.name === value) :undefined;
|
||||
select_language(value,array && array[0]);
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
const url = '/ci/languages/common.json';
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
setSix(result.data);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
},[])
|
||||
|
||||
return(
|
||||
<React.Fragment>
|
||||
{
|
||||
six &&
|
||||
<ul className="language">
|
||||
{
|
||||
six.map((item,key)=>{
|
||||
return(
|
||||
key < 6 ? <li className={language ===item.name ? "active":""} onClick={()=>changelanguage(item.name)}><img alt="" src={item.cover_url && getUrl(item.cover_url)} /></li> : ""
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
<Select showSearch={true} placeholder={"请选择文本语言"} style={{ width: 200 }} value={language} onChange={changelanguage}>
|
||||
<Option value={undefined}>请选择文本语言</Option>
|
||||
{languages && languages.map((item, key) => {
|
||||
return <Option value={item.name}>{item.name}</Option>;
|
||||
})}
|
||||
</Select>
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
|
@ -3,42 +3,54 @@ import './Component.scss';
|
|||
|
||||
export const Tags = (status)=>{
|
||||
switch(status){
|
||||
case 1:
|
||||
case "running":
|
||||
return(
|
||||
<span className="statusColor running">运行中</span>
|
||||
);
|
||||
case 2:
|
||||
case "failure":case"error":
|
||||
return (
|
||||
<span className="statusColor failed">未通过</span>
|
||||
);
|
||||
case 3:
|
||||
case "success":
|
||||
return (
|
||||
<span className="statusColor pass">已通过</span>
|
||||
);
|
||||
default:
|
||||
case "pending":
|
||||
return (
|
||||
<span className="statusColor Preparing">准备中</span>
|
||||
);
|
||||
case 'killed':
|
||||
return (
|
||||
<span className="statusColor killed">已撤销</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const TagsLine = (status)=>{
|
||||
switch(status){
|
||||
case 1:
|
||||
case "running":
|
||||
return(
|
||||
<span className="statuslineColor running">运行中</span>
|
||||
);
|
||||
case 2:
|
||||
case "failure":case "error":
|
||||
return (
|
||||
<span className="statuslineColor failed">未通过</span>
|
||||
);
|
||||
case 3:
|
||||
case "success":
|
||||
return (
|
||||
<span className="statuslineColor pass">已通过</span>
|
||||
);
|
||||
default:
|
||||
case "pending":
|
||||
return (
|
||||
<span className="statuslineColor Preparing">准备中</span>
|
||||
);
|
||||
case 'killed':
|
||||
return (
|
||||
<span className="statuslineColor killed">已撤销</span>
|
||||
);
|
||||
case 'skipped':
|
||||
return (
|
||||
<span className="statuslineColor skipped">已跳过</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import React ,{ useState } from 'react';
|
||||
import { Modal , Input , Spin } from 'antd';
|
||||
import { AlignCenter } from "./layout";
|
||||
import axios from 'axios';
|
||||
import './Component.scss';
|
||||
|
||||
function PasswordAuthority({ authorityValBox , successFunc , cancelFunc }){
|
||||
const [ authorityVal , setAuthorityVal ] = useState(undefined);
|
||||
const [ authorityValFlag , setAuthorityValFlag ] = useState(false);
|
||||
const [ isSpin , setIsSpin ] = useState(false);
|
||||
|
||||
// 取消授权-登录密码的输入
|
||||
function cancelAuthority(){
|
||||
cancelFunc();
|
||||
}
|
||||
// 确认授权
|
||||
function okAuthority(){
|
||||
if(!authorityVal){
|
||||
setAuthorityValFlag(true);
|
||||
return;
|
||||
}
|
||||
setIsSpin(true);
|
||||
const url = `/users/ci/oauth_grant.json`;
|
||||
axios.get(url,{
|
||||
params:{password:authorityVal}
|
||||
}).then(result=>{
|
||||
setIsSpin(false);
|
||||
if(result){
|
||||
successFunc(result.data.step);
|
||||
}
|
||||
}).catch(error=>{setIsSpin(false);});
|
||||
}
|
||||
return(
|
||||
<Modal visible={authorityValBox} centered={true} title="授权" onCancel={cancelAuthority} onOk={okAuthority}>
|
||||
<Spin spinning={isSpin}>
|
||||
<p style={{textAlign:"center"}}>请输入您的登录密码,确认授权DevOps应用</p>
|
||||
<AlignCenter style={{justifyContent:"center",marginTop:"20px"}}>
|
||||
<span>密码:</span>
|
||||
<Input.Password value={authorityVal} className={authorityValFlag===true && "flags"} onChange={(e)=>setAuthorityVal(e.target.value)} style={{width:"220px"}}></Input.Password>
|
||||
</AlignCenter>
|
||||
</Spin>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default PasswordAuthority;
|
|
@ -1,26 +1,66 @@
|
|||
import React , { forwardRef , useCallback } from 'react';
|
||||
import activate from '../Images/activate.png';
|
||||
import { Blueback } from '../Component/layout';
|
||||
import styled from 'styled-components';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Form , Input } from 'antd';
|
||||
import axios from 'axios';
|
||||
import React, { forwardRef, useCallback, useState , useEffect } from "react";
|
||||
import activate from "../Images/activate.png";
|
||||
import { Blueback , AlignCenter } from "../Component/layout";
|
||||
import PasswordAuthority from "../Component/PasswordAuthority";
|
||||
import styled from "styled-components";
|
||||
import { Form, Input , Spin , Modal } from "antd";
|
||||
import axios from "axios";
|
||||
|
||||
const P = styled.p`
|
||||
{
|
||||
width: 230px;
|
||||
line-height: 30px;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px !important;
|
||||
}
|
||||
`;
|
||||
function About(props, ref) {
|
||||
const { form: { getFieldDecorator, validateFields , setFieldsValue } } = props;
|
||||
const [isSpining, setIsSpining] = useState(true);
|
||||
const [ authorityValBox , setAuthorityValBox ] = useState(false);
|
||||
const [ authorityVal , setAuthorityVal ] = useState(undefined);
|
||||
const [ authorityValFlag , setAuthorityValFlag ] = useState(false);
|
||||
//0: 标识未开启devops
|
||||
//1: 标识用户已填写了云服务器相关信息,但并未开启认证
|
||||
const [step, setStep] = useState(undefined);
|
||||
// step大于1时:为true,不能再修改服务器信息
|
||||
const owner = props.match.params.owner;
|
||||
const projectsId = props.match.params.projectsId;
|
||||
|
||||
|
||||
const AuthorLogin = props.author && props.author.login;
|
||||
const CurrentLogin = props.current_user && props.current_user.login;
|
||||
useEffect(()=>{
|
||||
if(CurrentLogin === AuthorLogin){
|
||||
auth('get');
|
||||
}else{
|
||||
setIsSpining(false);
|
||||
}
|
||||
},[AuthorLogin,CurrentLogin])
|
||||
|
||||
function auth(type){
|
||||
const url = `/${owner}/${projectsId}/ci_authorize.json`;
|
||||
axios({
|
||||
method:`${type}`,
|
||||
url
|
||||
}).then(result=>{
|
||||
if(result && result.data ){
|
||||
setIsSpining(false);
|
||||
setStep(result.data.step);
|
||||
setFieldsValue({...result.data.cloud_account});
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
const P = styled.p`{
|
||||
width:200px;
|
||||
line-height:30px;
|
||||
font-size:16px;
|
||||
color:#333;
|
||||
text-align:center;
|
||||
margin-top:30px;
|
||||
margin-bottom:30px!important;
|
||||
}`;
|
||||
function About( props , ref){
|
||||
const { form: { getFieldDecorator , validateFields } } = props;
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget, isRequired) => (
|
||||
<React.Fragment>
|
||||
<span className={isRequired?"required":""}>{label}</span>
|
||||
<span className={isRequired ? "required" : ""}>{label}</span>
|
||||
<Form.Item>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
</Form.Item>
|
||||
|
@ -28,51 +68,122 @@ function About( props , ref){
|
|||
),
|
||||
[]
|
||||
);
|
||||
|
||||
function startActive(){
|
||||
console.log(props);
|
||||
validateFields((error,values)=>{
|
||||
if(!error){
|
||||
const url = `/dev_ops/cloud_accounts.json`;
|
||||
axios.post(url,{
|
||||
...values,
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
// 下一步
|
||||
function goStep() {
|
||||
validateFields((error, values) => {
|
||||
if (!error) {
|
||||
if(step > 0){
|
||||
setAuthorityValBox(true);
|
||||
}else{
|
||||
setIsSpining(true);
|
||||
const url = `/${owner}/${projectsId}/cloud_accounts.json`;
|
||||
axios.post(url, {...values,ip_num:values.ip}).then((result) => {
|
||||
setIsSpining(false);
|
||||
if (result && result.data.redirect_url) {
|
||||
props.showNotification("服务器信息配置完成!");
|
||||
setStep(1);
|
||||
setAuthorityValBox(true);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
setIsSpining(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 开始激活
|
||||
function startActive(){
|
||||
setIsSpining(true);
|
||||
const url = `/${owner}/${projectsId}/activate.json`;
|
||||
axios.post(url).then(result=>{
|
||||
setIsSpining(false);
|
||||
if(result && result.data.status === 0){
|
||||
props.history.push(`/projects/${owner}/${projectsId}/devops/dispose`);
|
||||
// 需要将顶部的open_devops修改
|
||||
let { changeOpenDevops } = props;
|
||||
changeOpenDevops && changeOpenDevops(true);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
setIsSpining(false);
|
||||
})
|
||||
}
|
||||
return(
|
||||
<div className="activatePanel">
|
||||
<img src={activate} alt="" width="250px"/>
|
||||
<P>定义DevOps工作流,帮助您检测bug、发布代码…</P>
|
||||
<Link to={""} style={{color:"#5091FF",marginBottom:"20px"}}>了解什么是DevOps?</Link>
|
||||
<Form>
|
||||
{helper(
|
||||
"服务器IP地址:",
|
||||
"ip_num",
|
||||
[{ required: true, message: "请输入服务器IP地址" }],
|
||||
<Input placeholder="请输入服务器IP地址" style={{width:"368px"}} size="large" />,true
|
||||
)}
|
||||
{helper(
|
||||
"服务器用户名:",
|
||||
"account",
|
||||
[{ required: true, message: "请输入服务器用户名" }],
|
||||
<Input placeholder="请输入服务器用户名" size="large" />,true
|
||||
)}
|
||||
{helper(
|
||||
"服务器密码:",
|
||||
"secret",
|
||||
[{ required: true, message: "请输入服务器密码" }],
|
||||
<Input.Password placeholder="请输入服务器密码" size="large" />,true
|
||||
)}
|
||||
</Form>
|
||||
<Blueback onClick={startActive}>开始激活</Blueback>
|
||||
</div>
|
||||
)
|
||||
// 取消授权-登录密码的输入
|
||||
function cancelAuthority(){
|
||||
setAuthorityValBox(false);
|
||||
}
|
||||
// 确认授权
|
||||
function okAuthority(step){
|
||||
setAuthorityValBox(false);
|
||||
setStep(step);
|
||||
}
|
||||
return (
|
||||
<Spin spinning={isSpining}>
|
||||
<PasswordAuthority authorityValBox={authorityValBox} successFunc={okAuthority} cancelFunc={cancelAuthority}></PasswordAuthority>
|
||||
<div className="activatePanel">
|
||||
<img src={activate} alt="" width="250px" />
|
||||
<P>定义DevOps工作流,帮助您检测bug、发布代码…</P>
|
||||
{
|
||||
CurrentLogin !== AuthorLogin && (step === undefined || (step && step < 1)) &&
|
||||
<div className="noOperation">DevOps开启功能暂未对项目创建者以外的角色开放,可以联系项目创建者进行开启,开启后便可查看构建信息。</div>
|
||||
}
|
||||
<a href={"https://forum.trustie.net/forums/3080/detail"} target="_blank" style={{ color: "#5091FF"}}>
|
||||
了解什么是DevOps?
|
||||
</a>
|
||||
<a href={"https://forum.trustie.net/forums/3110/detail"} target="_blank" style={{ color: "#5091FF"}}>
|
||||
如何使用DevOps?
|
||||
</a>
|
||||
{
|
||||
AuthorLogin === CurrentLogin ?
|
||||
<React.Fragment>
|
||||
{ step <=1 ?
|
||||
<React.Fragment>
|
||||
<Input.Password style={{display:'none'}} size="large" />
|
||||
<Form style={{marginTop:"20px"}}>
|
||||
<p className="mb20" style={{width:"370px"}}>请仔细核对您的服务器信息,一旦确认提交将无法修改</p>
|
||||
{helper(
|
||||
"服务器IP地址:",
|
||||
"ip",
|
||||
[{ required: true, message: "请输入服务器IP地址" }],
|
||||
<Input
|
||||
placeholder="请输入服务器IP地址"
|
||||
style={{ width: "368px" }}
|
||||
size="large"
|
||||
disabled={step > 0}
|
||||
/>,
|
||||
true
|
||||
)}
|
||||
{helper(
|
||||
"服务器用户名:",
|
||||
"account",
|
||||
[{ required: true, message: "请输入服务器用户名" }],
|
||||
<Input placeholder="请输入服务器用户名" size="large" disabled={step > 0}/>,
|
||||
true
|
||||
)}
|
||||
{helper(
|
||||
"服务器密码:",
|
||||
"secret",
|
||||
[{ required: true, message: "请输入服务器密码" }],
|
||||
<Input.Password placeholder="请输入服务器密码" size="large" disabled={step > 0}/>,
|
||||
true
|
||||
)}
|
||||
</Form>
|
||||
<Blueback onClick={goStep}>下一步</Blueback>
|
||||
</React.Fragment>
|
||||
:""}
|
||||
{step > 1 &&
|
||||
<div style={{textAlign:'center',marginTop:"20px"}}>
|
||||
<Blueback onClick={startActive} className="mt20">开始激活</Blueback>
|
||||
</div>
|
||||
}
|
||||
</React.Fragment>
|
||||
:""
|
||||
}
|
||||
</div>
|
||||
</Spin>
|
||||
);
|
||||
}
|
||||
export default Form.create()(forwardRef(About));
|
||||
export default Form.create()(forwardRef(About));
|
||||
|
|
|
@ -1,91 +1,119 @@
|
|||
import React , { forwardRef , useCallback , useState } from 'react';
|
||||
import { Form , AutoComplete } from 'antd';
|
||||
import React , { useState , useEffect } from 'react';
|
||||
import { Spin } from 'antd';
|
||||
import { Blueback } from '../Component/layout';
|
||||
import Editor from "react-monaco-editor";
|
||||
import Modals from './DisposeModal';
|
||||
import FileLanguage from '../Component/FileLanguage';
|
||||
|
||||
import docker from '../Images/docker.png';
|
||||
import gradle from '../Images/gradle.png';
|
||||
import java from '../Images/java.png';
|
||||
import js from '../Images/js.png';
|
||||
import php from '../Images/php.png';
|
||||
import python from '../Images/python.png';
|
||||
import FileLanguage from '../Component/OpsFileLanguage';
|
||||
import axios from 'axios';
|
||||
|
||||
|
||||
const Option = AutoComplete.Option;
|
||||
export default Form.create()(
|
||||
forwardRef(({ form })=>{
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const [ ymlValue , setYmlValue ] = useState("class Main 1111");
|
||||
const [ fileLanguage , setFileLanguage ] = useState(undefined);
|
||||
function Dispose(props){
|
||||
const [ spining , setSpining ] = useState(true);
|
||||
const [ info , setInfo ] = useState('.trustie-pipeline.yml');
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const [ ymlValue , setYmlValue ] = useState("");
|
||||
const [ sha , setSha ] = useState(undefined);
|
||||
const [ fileLanguage , setFileLanguage ] = useState(undefined);
|
||||
const [ first , setFirst ] = useState(false);
|
||||
|
||||
const { getFieldDecorator , validateFields } = form;
|
||||
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget, isRequired = false) => (
|
||||
<React.Fragment>
|
||||
<span required={isRequired}>{label}</span>
|
||||
<Form.Item>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
</Form.Item>
|
||||
</React.Fragment>
|
||||
),
|
||||
[]
|
||||
)
|
||||
// 修改文件内容
|
||||
function changeEditor(value){
|
||||
setYmlValue(value);
|
||||
}
|
||||
|
||||
// 切换语言
|
||||
function select_language(value){
|
||||
setFileLanguage(value);
|
||||
}
|
||||
|
||||
// 确定提交
|
||||
function submit(){
|
||||
validateFields((error,value)=>{
|
||||
if(!error){
|
||||
console.log(value);
|
||||
let projectsId = props.match.params.projectsId;
|
||||
let owner = props.match.params.owner;
|
||||
useEffect(()=>{
|
||||
if(projectsId){
|
||||
const url = `/${owner}/${projectsId}/get_trustie_pipeline.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
project_id:projectsId
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data.content){
|
||||
setInfo(result.data.name);
|
||||
setYmlValue(result.data.content);
|
||||
setFirst(true);
|
||||
setSha(result.data.sha);
|
||||
}else{
|
||||
setFirst(false);
|
||||
}
|
||||
setSpining(false);
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
return(
|
||||
<React.Fragment>
|
||||
<Modals visible={visible} closeFunc={(flag)=>setVisible(flag)}></Modals>
|
||||
<Form>
|
||||
<p>编程语言:</p>
|
||||
<ul className="language">
|
||||
<li><img alt="" src={docker} /></li>
|
||||
<li><img alt="" src={gradle} /></li>
|
||||
<li><img alt="" src={java} /></li>
|
||||
<li><img alt="" src={js} /></li>
|
||||
<li><img alt="" src={php} /></li>
|
||||
<li><img alt="" src={python} /></li>
|
||||
</ul>
|
||||
<div className="mt20 mb20">
|
||||
<FileLanguage language={fileLanguage} select_language={select_language}/>
|
||||
</div>
|
||||
<p>配置脚本:</p>
|
||||
<div className="editorBody">
|
||||
<p className="editorHead">
|
||||
<span>.trustie-pipeline.yml</span>
|
||||
<a><i className="iconfont icon-bianji6 font-14"></i></a>
|
||||
</p>
|
||||
<Editor
|
||||
height="300px"
|
||||
language={"java"}
|
||||
theme={"vs-grey"}
|
||||
defaultValue="请输入内容"
|
||||
value={ymlValue}
|
||||
options={"editor_options"}
|
||||
onChange={changeEditor}
|
||||
></Editor>
|
||||
</div>
|
||||
<Blueback onClick={submit}>确定提交</Blueback>
|
||||
</Form>
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
||||
)
|
||||
},[projectsId])
|
||||
|
||||
// 修改文件内容
|
||||
function changeEditor(value){
|
||||
setYmlValue(value);
|
||||
}
|
||||
|
||||
// 切换语言
|
||||
function select_language(value,array){
|
||||
setFileLanguage(value);
|
||||
setYmlValue( array && array.content);
|
||||
}
|
||||
|
||||
// 确定提交
|
||||
function submit(){
|
||||
let url = '';
|
||||
const { defaultBranch } = props;
|
||||
let params = {
|
||||
branch: defaultBranch,
|
||||
content:ymlValue,
|
||||
filepath:info,
|
||||
message:''
|
||||
}
|
||||
if(first){
|
||||
// 为true,则是编辑否则是新建
|
||||
url = `/${owner}/${projectsId}/update_trustie_pipeline.json`;
|
||||
axios.put(url,{
|
||||
...params,
|
||||
sha
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
setVisible(true);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}else{
|
||||
url = `/${owner}/${projectsId}/create_file.json`;
|
||||
axios.post(url,params).then(result=>{
|
||||
if(result){
|
||||
setVisible(true);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
}
|
||||
function suresubmit(){
|
||||
setVisible(false);
|
||||
props.history.push(`/projects/${owner}/${projectsId}/devops/list`);
|
||||
}
|
||||
|
||||
return(
|
||||
<Spin spinning={spining}>
|
||||
<Modals visible={visible} closeFunc={(flag)=>setVisible(flag)} sureFunc={suresubmit}></Modals>
|
||||
<p>编程语言:</p>
|
||||
|
||||
<div className="mt20 mb20">
|
||||
<FileLanguage language={fileLanguage} select_language={select_language}/>
|
||||
</div>
|
||||
<p>配置脚本:</p>
|
||||
<div className="editorBody">
|
||||
<p className="editorHead">{info}</p>
|
||||
<Editor
|
||||
height="300px"
|
||||
language={"yml"}
|
||||
theme={"vs-grey"}
|
||||
defaultValue="请输入内容"
|
||||
value={ymlValue}
|
||||
options={"editor_options"}
|
||||
onChange={changeEditor}
|
||||
></Editor>
|
||||
</div>
|
||||
<Blueback onClick={submit}>确定提交</Blueback>
|
||||
</Spin>
|
||||
)
|
||||
}
|
||||
export default Dispose;
|
|
@ -8,7 +8,7 @@ const Div = styled.div`{
|
|||
text-align:center;
|
||||
color:#333;
|
||||
}`
|
||||
export default (({visible , closeFunc})=>{
|
||||
export default (({visible , closeFunc , sureFunc})=>{
|
||||
return(
|
||||
<Modal
|
||||
title="提示"
|
||||
|
@ -17,7 +17,7 @@ export default (({visible , closeFunc})=>{
|
|||
footer={
|
||||
<div>
|
||||
<Button onClick={()=>closeFunc(false)}>取消</Button>
|
||||
<Button type={"primary"} onClick={()=>closeFunc(false)} style={{marginLeft:"20px"}}>确定</Button>
|
||||
<Button type={"primary"} onClick={()=>sureFunc()} style={{marginLeft:"20px"}}>确定</Button>
|
||||
</div>
|
||||
}
|
||||
onCancel={()=>closeFunc(false)}
|
||||
|
|
|
@ -18,17 +18,17 @@ export default ((props)=>{
|
|||
return(
|
||||
<WhiteBack className="opsPanel">
|
||||
<Switch {...props}>
|
||||
<Route path="/projects/:projectsId/ops/dispose"
|
||||
<Route path="/projects/:owner/:projectsId/devops/dispose"
|
||||
render={
|
||||
() => (<Infos {...props} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/ops/list"
|
||||
<Route path="/projects/:owner/:projectsId/devops/list"
|
||||
render={
|
||||
() => (<Infos {...props} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/ops"
|
||||
<Route path="/projects/:owner/:projectsId/devops"
|
||||
render={
|
||||
() => (<About {...props} />)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import React , { useEffect , useState , useRef } from 'react';
|
||||
import { Banner } from '../Component/layout';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
|
@ -12,30 +12,45 @@ const Div = styled.div`{
|
|||
}`;
|
||||
export default ((props)=>{
|
||||
const [ menu , setMenu ] = useState(false);
|
||||
const [ permission , setPermission ] = useState("");
|
||||
const childRef = useRef();
|
||||
|
||||
const path = props.location.pathname;
|
||||
const owner = props.match.params.owner;
|
||||
const projectsId = props.match.params.projectsId;
|
||||
|
||||
const projectDetail = props.projectDetail;
|
||||
useEffect(()=>{
|
||||
console.log(props.match.params.projectsId)
|
||||
if(path === `/projects/${props.match.params.projectsId}/ops/list`){
|
||||
if(path === `/projects/${owner}/${projectsId}/devops/list`){
|
||||
setMenu(true);
|
||||
}else{
|
||||
setMenu(false);
|
||||
}
|
||||
},[path])
|
||||
|
||||
useEffect(()=>{
|
||||
if(projectDetail){
|
||||
setPermission(props.projectDetail.permission);
|
||||
}
|
||||
},[projectDetail])
|
||||
|
||||
const updateChildState = () => {
|
||||
// changeVal就是子组件暴露给父组件的方法
|
||||
if (childRef.current) {
|
||||
childRef.current.changeVal();
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="disposePanel">
|
||||
<Banner>
|
||||
<Link to={`/projects/${props.match.params.projectsId}/ops/dispose`}>工作流配置</Link>
|
||||
{ menu ? <Link to={`/projects/${props.match.params.projectsId}/ops/list`} style={{ marginLeft:"66px",color:"#5091FF" }}>构建列表</Link>:""}
|
||||
{ permission !=="Reporter" && <Link to={`/projects/${owner}/${props.match.params.projectsId}/devops/dispose`} className={menu===false && "color-blue"} style={{ marginRight:"66px"}}>工作流配置</Link>}
|
||||
<Link to={`/projects/${owner}/${props.match.params.projectsId}/devops/list`}className={menu===true && "color-blue"}>构建列表</Link>
|
||||
{ menu===true && <a onClick={updateChildState} style={{float:"right",fontSize:"14px",color:"#FF6E21",marginTop:"5px"}}>刷新</a>}
|
||||
</Banner>
|
||||
<Div>
|
||||
{
|
||||
menu ?
|
||||
<Structure {...props}/>
|
||||
:
|
||||
<Dispost {...props}/>
|
||||
}
|
||||
{ menu === true && <Structure {...props} wrappedComponentRef={(form) => childRef.current = form} ref={childRef}/> }
|
||||
{ menu === false && permission !=="Reporter" && <Dispost {...props}/> }
|
||||
</Div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -1,42 +1,127 @@
|
|||
import React from 'react';
|
||||
import { FlexAJ , Blueline , AlignCenter } from '../Component/layout';
|
||||
import styled from 'styled-components';
|
||||
import { Menu } from 'antd';
|
||||
import { TagsLine } from '../Component/OpsStatus';
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { FlexAJ, Blueline, AlignCenter } from "../Component/layout";
|
||||
import styled from "styled-components";
|
||||
import { Menu, Popconfirm } from "antd";
|
||||
import { TagsLine } from "../Component/OpsStatus";
|
||||
import { Time } from "../Utils/Time";
|
||||
import { truncateCommitId } from "../common/util";
|
||||
import { getUrl } from 'educoder';
|
||||
|
||||
const SubMenu = Menu.SubMenu;
|
||||
const Img = styled.img`{
|
||||
width:25px;
|
||||
height:25px;
|
||||
border-radius:50%;
|
||||
margin-right:10px;
|
||||
}`
|
||||
export default (()=>{
|
||||
return(
|
||||
const Img = styled.img`
|
||||
{
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
`;
|
||||
export default ({ data, repeatSet , chooseSteps }) => {
|
||||
const [tamp, setTamp] = useState(undefined);
|
||||
const [sha, setSha] = useState(undefined);
|
||||
useEffect(() => {
|
||||
if (data && data.started) {
|
||||
let t = parseInt(data.started) * 1000;
|
||||
let time = Time(t);
|
||||
setTamp(time);
|
||||
}
|
||||
if (data && data.after) {
|
||||
setSha(truncateCommitId(data.after));
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
function renderStatusBtn() {
|
||||
let status = data && data.status;
|
||||
let number = data && data.number;
|
||||
if (status === "failure" || status === "error" || status === "success") {
|
||||
return "";
|
||||
}else if(status === "killed"){
|
||||
return(
|
||||
<Popconfirm
|
||||
title="确认重新构建?"
|
||||
onConfirm={(e) => repeatSet(e,'repeat',number)}
|
||||
onCancel={(e)=>{e.stopPropagation()}}
|
||||
cancelText="取消"
|
||||
okText="确定"
|
||||
>
|
||||
<Blueline onClick={(e)=>{e.stopPropagation()}}>重新构建</Blueline>
|
||||
</Popconfirm>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Popconfirm
|
||||
title="确认撤销构建?"
|
||||
onConfirm={(e) => repeatSet(e,'cancel',number)}
|
||||
onCancel={(e)=>{e.stopPropagation()}}
|
||||
cancelText="取消"
|
||||
okText="确定"
|
||||
>
|
||||
<Blueline onClick={(e)=>{e.stopPropagation()}}>撤销构建</Blueline>
|
||||
</Popconfirm>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function clickSub(e,stageN,stepN){
|
||||
chooseSteps(stageN,stepN);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FlexAJ className="leftheader">
|
||||
<AlignCenter>
|
||||
<Img src="https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2091711702,2468700162&fm=111&gp=0.jpg"/>
|
||||
<span className="nest">开始时间:<span>2020.07.10 15:30</span></span>
|
||||
<span className="nest">运行时间:<span>20s</span></span>
|
||||
<Img src={getUrl(`/images/${data && data.author && data.author.image_url}`)} />
|
||||
{data && data.started &&
|
||||
<span className="nest">
|
||||
开始时间:<span> {data.started}</span>
|
||||
</span>
|
||||
}
|
||||
{
|
||||
data && data.duration_time &&
|
||||
<span className="nest">
|
||||
运行时间:<span>{data.duration_time}</span>
|
||||
</span>
|
||||
}
|
||||
</AlignCenter>
|
||||
<Blueline>重新创建</Blueline>
|
||||
{renderStatusBtn()}
|
||||
</FlexAJ>
|
||||
<div className="leftMainContent">
|
||||
<AlignCenter className="contentBranch">
|
||||
<i className="iconfont icon-fenzhi1"></i>
|
||||
<span>分支:</span>
|
||||
<span className="branchname">master</span>
|
||||
<span className="branchsha">8b3476f5</span>
|
||||
<span className="branchname">{data && data.branch_target}</span>
|
||||
<span className="branchsha">{data && truncateCommitId(data.build_after_sha)}</span>
|
||||
</AlignCenter>
|
||||
</div>
|
||||
<Menu mode='inline' className="leftMenu">
|
||||
<SubMenu title={<div><i className="iconfont icon-gongzuoliu font-14 mr4"></i><span>CI</span></div>}>
|
||||
<Menu.Item>
|
||||
<FlexAJ><span>Build setup 01 {TagsLine(1)}</span><span>20s</span></FlexAJ>
|
||||
</Menu.Item>
|
||||
</SubMenu>
|
||||
<Menu mode="inline" className="leftMenu" defaultOpenKeys={[`0`]} defaultSelectedKeys={[`0`]}>
|
||||
{data && data.stages ? data.stages.map((item, key) => {
|
||||
return item.steps && item.steps.length > 0 ?
|
||||
<SubMenu
|
||||
title={
|
||||
<div>
|
||||
<i className="iconfont icon-gongzuoliu font-14 mr4"></i>
|
||||
<span>{item.name}</span>
|
||||
</div>
|
||||
}
|
||||
key={`${key}`}
|
||||
>
|
||||
{item.steps.map((i, k) => {
|
||||
return (
|
||||
<Menu.Item key={`${k}`} onClick={(e)=>clickSub(e,item.number,i.id)}>
|
||||
<FlexAJ>
|
||||
<span>
|
||||
{i.name} {i.status ? TagsLine(i.status) : ""}
|
||||
</span>
|
||||
<span>{i.duration_time}</span>
|
||||
</FlexAJ>
|
||||
</Menu.Item>
|
||||
);
|
||||
})}
|
||||
</SubMenu>
|
||||
: "";
|
||||
})
|
||||
: ""}
|
||||
</Menu>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,21 +1,107 @@
|
|||
import React from 'react';
|
||||
import { FlexAJ , AlignCenter } from '../Component/layout';
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Spin } from "antd";
|
||||
import { FlexAJ, AlignCenter } from "../Component/layout";
|
||||
import axios from "axios";
|
||||
|
||||
export default (()=>{
|
||||
return(
|
||||
<div className="rightMainContent">
|
||||
<div>
|
||||
<FlexAJ className="items">
|
||||
<span>Build setup 01</span>
|
||||
<AlignCenter>20<i className="iconfont icon-triangle"></i></AlignCenter>
|
||||
</FlexAJ>
|
||||
export default ({
|
||||
data,
|
||||
stepN,
|
||||
stageN,
|
||||
projectId,
|
||||
owner,
|
||||
opsId,
|
||||
rightSpin,
|
||||
}) => {
|
||||
const [coders, setCoders] = useState(undefined);
|
||||
const [empty, setEmpty] = useState(false);
|
||||
const [spining, setSpining] = useState(true);
|
||||
const [stage, setStage] = useState(undefined);
|
||||
const [step, setStep] = useState(undefined);
|
||||
useEffect(() => {
|
||||
setSpining(rightSpin);
|
||||
}, [rightSpin]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
let stages = data.stages;
|
||||
if (stages && stages.length > 0) {
|
||||
let pre = stageN
|
||||
? stages.filter((item) => item.number === stageN)[0]
|
||||
: stages[0];
|
||||
setStage(pre);
|
||||
let p = pre && pre.steps;
|
||||
let sub = stepN
|
||||
? p && p.length > 0 && p.filter((item) => item.id === stepN)[0]
|
||||
: p[0];
|
||||
|
||||
setStep(sub);
|
||||
if (sub && sub.status !== "skipped") {
|
||||
getStep(pre.number, sub.number);
|
||||
}
|
||||
// 如果状态是skipped就不用去调用接口查询对应的out信息了
|
||||
if(sub.status === "skipped"){
|
||||
setCoders(undefined);
|
||||
setEmpty(true);
|
||||
setSpining(false);
|
||||
}
|
||||
} else {
|
||||
setSpining(false);
|
||||
}
|
||||
}
|
||||
}, [data, stageN, stepN]);
|
||||
|
||||
function getStep(stageN, stepN) {
|
||||
if (stageN && stepN) {
|
||||
const url = `/${owner}/${projectId}/builds/${opsId}/logs/${stageN}/${stepN}.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
setCoders(result.data);
|
||||
setSpining(false);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Spin spinning={spining}>
|
||||
<div className="rightMainContent">
|
||||
{data && data.status !== "error" ? (
|
||||
<div>
|
||||
<FlexAJ className="items">
|
||||
<span>{step && step.name}</span>
|
||||
<AlignCenter>
|
||||
{step && step.duration_time}
|
||||
<i className="iconfont icon-sanjiaoxing-down"></i>
|
||||
</AlignCenter>
|
||||
</FlexAJ>
|
||||
<div>
|
||||
{coders && coders.length > 0 ? (
|
||||
coders.map((item, key) => {
|
||||
return (
|
||||
<div className="opsDetailOut">
|
||||
<span>{key + 1}</span>
|
||||
<p>{item.out}</p>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
) : empty ? (
|
||||
<div className="opsDetailOut">
|
||||
<span>1</span>
|
||||
<p>
|
||||
{stage && stage.name} – {step && step.name}: Skipped
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ color: "red" }}>error:{data && data.error}</div>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<FlexAJ className="items"></FlexAJ>
|
||||
</div>
|
||||
<div>
|
||||
<FlexAJ className="items"></FlexAJ>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
</Spin>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,204 +1,320 @@
|
|||
import React , { useState } from 'react';
|
||||
import { FlexAJ , Blueback } from '../Component/layout';
|
||||
import { Table , Pagination } from 'antd';
|
||||
import styled from 'styled-components';
|
||||
import React, { useState, useEffect , useImperativeHandle ,forwardRef } from "react";
|
||||
import { FlexAJ, AlignCenter } from "../Component/layout";
|
||||
import { Table, Pagination, Popconfirm } from "antd";
|
||||
import { truncateCommitId } from "../common/util";
|
||||
import {getUrl} from 'educoder';
|
||||
import axios from "axios";
|
||||
|
||||
const STATUS = [
|
||||
{name:"所有",value:"1"},
|
||||
{name:"准备中",value:"2"},
|
||||
{name:"运行中",value:"3"},
|
||||
{name:"已完成",value:"4"}
|
||||
]
|
||||
const LIMIT = 15;
|
||||
const datasource = [
|
||||
{
|
||||
status:2,
|
||||
author:"caishi",
|
||||
message:{
|
||||
branch:"master",
|
||||
sha:"8b3476f5",
|
||||
image:"https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2034740944,4251903193&fm=26&gp=0.jpg",
|
||||
message:"将分支“ 221063-improve-buy-ci-minutes-link”"
|
||||
},
|
||||
begin:"2020-07-08",
|
||||
run:"20s"
|
||||
},
|
||||
{
|
||||
status:1,
|
||||
author:"caishi",
|
||||
message:{
|
||||
branch:"master",
|
||||
sha:"8b3476f5",
|
||||
image:"https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2034740944,4251903193&fm=26&gp=0.jpg",
|
||||
message:"将分支“ 221063-improve-buy-ci-minutes-link”"
|
||||
},
|
||||
begin:"2020-07-08",
|
||||
run:""
|
||||
}
|
||||
{ name: "所有"},
|
||||
{ name: "运行中", value: "running" },
|
||||
{ name: "已撤销", value: "killed" },
|
||||
{ name: "构建失败", value: "failure" },
|
||||
{ name: "已完成", value: "success" },
|
||||
];
|
||||
const LIMIT = 15;
|
||||
function Structure(props,ref){
|
||||
const [status, setStatus] = useState(undefined);
|
||||
const [page, setPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [data, setData] = useState(undefined);
|
||||
const [tableLoading, setTableLoading] = useState(true);
|
||||
|
||||
const Img = styled.img`{
|
||||
border-radius:50%;
|
||||
margin-rigth:10px;
|
||||
width:25px;
|
||||
height:25px;
|
||||
}`
|
||||
export default (()=>{
|
||||
const [ status ,setStatus ] = useState("1");
|
||||
const [ page ,setPage ] = useState(1);
|
||||
const [ total ,setTotal ] = useState(10);
|
||||
let projectsId = props.match.params.projectsId;
|
||||
let owner = props.match.params.owner;
|
||||
const permission = props.projectDetail && props.projectDetail.permission;
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
changeVal: () => {
|
||||
setTableLoading(true);
|
||||
Init();
|
||||
}
|
||||
}))
|
||||
|
||||
function ChangeStatus(value){
|
||||
setStatus(value)
|
||||
useEffect(() => {
|
||||
if (projectsId) {
|
||||
Init();
|
||||
}
|
||||
}, [page]);
|
||||
|
||||
let current_user = props.current_user;
|
||||
function Init(status) {
|
||||
const url = `/${owner}/${projectsId}/builds.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
search:status,
|
||||
page,limit:LIMIT
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result && result.data) {
|
||||
let list = result.data.builds && result.data.builds.map((item, key) => {
|
||||
return {
|
||||
...item,
|
||||
author:item.author && item.author.name,
|
||||
message: {
|
||||
branch: item.branch_target,
|
||||
message: item.message,
|
||||
sha: truncateCommitId(item.build_after_sha),
|
||||
},
|
||||
started: item.started || "--"
|
||||
};
|
||||
});
|
||||
setTotal(result.data.total_count);
|
||||
setData(list);
|
||||
setTableLoading(false);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
function ChangeStatus(value) {
|
||||
setStatus(value);
|
||||
Init(value);
|
||||
}
|
||||
// 切换分页
|
||||
function ChangePage(page){
|
||||
setPage(page)
|
||||
function ChangePage(page) {
|
||||
setPage(page);
|
||||
}
|
||||
function renderStatus() {
|
||||
return(
|
||||
return (
|
||||
<ul className="listNav">
|
||||
{
|
||||
STATUS.map((item,key)=>{
|
||||
return <li onClick={()=>ChangeStatus(item.value)} className={ status === item.value ? "active":""}>{item.name}</li>
|
||||
})
|
||||
}
|
||||
{STATUS.map((item, key) => {
|
||||
return (
|
||||
<li
|
||||
onClick={() => ChangeStatus(item.value)}
|
||||
className={status === item.value ? "active" : ""}
|
||||
>
|
||||
{item.name}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
)
|
||||
);
|
||||
}
|
||||
function renderStatusBtn(status){
|
||||
if(status >1 && status <=3){
|
||||
function renderStatusBtn(status, number) {
|
||||
if (status === "error" || status === "success") {
|
||||
return "";
|
||||
}else if(status === "killed" || status === "failure"){
|
||||
return(
|
||||
<a className="color-blue">重新构建</a>
|
||||
)
|
||||
}else{
|
||||
return(
|
||||
<a className="color-red">撤销构建</a>
|
||||
)
|
||||
<Popconfirm
|
||||
title="确认重新构建?"
|
||||
onConfirm={(e) => repeatSet(e,number)}
|
||||
onCancel={(e)=>{e.stopPropagation()}}
|
||||
cancelText="取消"
|
||||
okText="确定"
|
||||
>
|
||||
<a className="color-blue" onClick={(e)=>{e.stopPropagation()}}>重新构建</a>
|
||||
</Popconfirm>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Popconfirm
|
||||
title="确认撤销构建?"
|
||||
onConfirm={(e) => cancelSet(e,number)}
|
||||
onCancel={(e)=>{e.stopPropagation()}}
|
||||
cancelText="取消"
|
||||
okText="确定"
|
||||
>
|
||||
<a className="color-red" onClick={(e)=>{e.stopPropagation()}}>撤销构建</a>
|
||||
</Popconfirm>
|
||||
);
|
||||
}
|
||||
}
|
||||
function renderTableStatus (status){
|
||||
switch (status){
|
||||
case 1:
|
||||
return(
|
||||
<span className="statusTag running"><i className="iconfont icon-yunhangzhong"></i>运行中</span>
|
||||
);
|
||||
case 2:
|
||||
// 重新构建
|
||||
function repeatSet(e,number) {
|
||||
e.stopPropagation();
|
||||
setTableLoading(true);
|
||||
const url = `/${owner}/${projectsId}/builds/${number}/restart.json`;
|
||||
axios.post(url).then((result) => {
|
||||
if (result) {
|
||||
props.showNotification("工作流正在重新构建!");
|
||||
Init();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
// 撤销构建
|
||||
function cancelSet(e,number) {
|
||||
e.stopPropagation();
|
||||
setTableLoading(true);
|
||||
const url = `/${owner}/${projectsId}/builds/${number}/stop.json`;
|
||||
axios.delete(url).then((result) => {
|
||||
if (result) {
|
||||
props.showNotification("撤销构建成功!");
|
||||
Init(projectsId);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
function renderTableStatus(status) {
|
||||
switch (status) {
|
||||
case "running":
|
||||
return (
|
||||
<span className="statusTag failed"><i className="iconfont icon-weitongguo"></i>未通过</span>
|
||||
<span className="statusTag running">
|
||||
<i className="iconfont icon-yunhangzhong"></i>运行中
|
||||
</span>
|
||||
);
|
||||
case 3:
|
||||
case "failure": case 'error':
|
||||
return (
|
||||
<span className="statusTag pass"><i className="iconfont icon-yitongguo"></i>已通过</span>
|
||||
<span className="statusTag failed">
|
||||
<i className="iconfont icon-weitongguo"></i>未通过
|
||||
</span>
|
||||
);
|
||||
default:
|
||||
case "success":
|
||||
return (
|
||||
<span className="statusTag Preparing"><i className="iconfont icon-zhunbeizhong"></i>准备中</span>
|
||||
<span className="statusTag pass">
|
||||
<i className="iconfont icon-yitongguo"></i>已通过
|
||||
</span>
|
||||
);
|
||||
case 'killed':
|
||||
return (
|
||||
<span className="statusTag killed">
|
||||
<i className="iconfont icon-weitongguo"></i>已撤销
|
||||
</span>
|
||||
);
|
||||
case 'pending':
|
||||
return (
|
||||
<span className="statusTag Preparing">
|
||||
<i className="iconfont icon-zhunbeizhong"></i>准备中
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function clickRows(event,e){
|
||||
props.history.push(`/projects/${owner}/${projectsId}/devops/${e.number}/detail`);
|
||||
}
|
||||
const column = [
|
||||
{
|
||||
title:'序号',
|
||||
dataIndex:"No",
|
||||
key:"No",
|
||||
width:"8%",
|
||||
render:(item,value,key)=>{
|
||||
return(
|
||||
<span>#{key+1}</span>
|
||||
)
|
||||
}
|
||||
title: "序号",
|
||||
dataIndex: "number",
|
||||
key: "number",
|
||||
width: "8%",
|
||||
render: ( value, item, key) => {
|
||||
return <span>#{value}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title:'状态',
|
||||
dataIndex:"status",
|
||||
key:"status",
|
||||
width:"12%",
|
||||
render:(value,item,key)=>{
|
||||
return(renderTableStatus(value))
|
||||
}
|
||||
title: "状态",
|
||||
dataIndex: "status",
|
||||
key: "status",
|
||||
width: "12%",
|
||||
render: (value, item, key) => {
|
||||
return renderTableStatus(value);
|
||||
},
|
||||
},
|
||||
{
|
||||
title:'构建人',
|
||||
dataIndex:"author",
|
||||
key:"author",
|
||||
width:"12%",
|
||||
align:"center"
|
||||
title: "构建人",
|
||||
dataIndex: "author",
|
||||
key: "author",
|
||||
width: "12%",
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title:'提交信息',
|
||||
dataIndex:"message",
|
||||
key:"message",
|
||||
width:"30%",
|
||||
render:(value,item,key)=>{
|
||||
title: "提交信息",
|
||||
dataIndex: "message",
|
||||
key: "message",
|
||||
width: "30%",
|
||||
render: (value, item, key) => {
|
||||
let meg = item.message;
|
||||
return (
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div>
|
||||
{ meg.branch && <span className="mr10 color-grey-8"><i className="iconfont icon-fenzhi1 font-16 mr5"></i>分支{meg.branch}</span>}
|
||||
{ meg.sha && <span className="color-orange">{meg.sha}</span>}
|
||||
{meg.branch && (
|
||||
<span className="mr10 color-grey-8">
|
||||
<i className="iconfont icon-fenzhi1 font-16 mr5"></i>分支
|
||||
{meg.branch}
|
||||
</span>
|
||||
)}
|
||||
{meg.sha && <span className="color-orange">{meg.sha}</span>}
|
||||
</div>
|
||||
<FlexAJ>
|
||||
<Img src={meg.image} />
|
||||
<div className="task-hide" style={{maxWidth:"300px"}}>{meg.message}</div>
|
||||
</FlexAJ>
|
||||
<AlignCenter>
|
||||
<img style={{borderRadius:"50%",marginRight:"10px",width:"25px",height:"25px"}} src={`${current_user && getUrl(`/images/${current_user.image_url}`)}`} />
|
||||
<div className="task-hide ml5" style={{ maxWidth: "300px" }}>
|
||||
{meg.message}
|
||||
</div>
|
||||
</AlignCenter>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title:'开始时间',
|
||||
dataIndex:"begin",
|
||||
key:"begin",
|
||||
width:"15%",
|
||||
render:(value,item,key)=>{
|
||||
return (
|
||||
<span>{value || "--"}</span>
|
||||
)
|
||||
}
|
||||
title: "开始时间",
|
||||
dataIndex: "started",
|
||||
key: "started",
|
||||
width: "15%",
|
||||
render: (value, item, key) => {
|
||||
return <span>{value || "--"}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title:'运行时间',
|
||||
dataIndex:"run",
|
||||
key:"run",
|
||||
width:"15%",
|
||||
render:(value,item,key)=>{
|
||||
return (
|
||||
<span>{value || "--"}</span>
|
||||
)
|
||||
}
|
||||
title: "运行时间",
|
||||
dataIndex: "duration_time",
|
||||
key: "duration_time",
|
||||
width: "15%",
|
||||
render: (value, item, key) => {
|
||||
return <span>{value || "--"}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title:'操作',
|
||||
dataIndex:"operation",
|
||||
key:"operation",
|
||||
render:(value,item,key)=>{
|
||||
return(renderStatusBtn(item.status));
|
||||
}
|
||||
}
|
||||
]
|
||||
return(
|
||||
title: "操作",
|
||||
dataIndex: "operation",
|
||||
key: "operation",
|
||||
render: (value, item, key) => {
|
||||
if(permission === "Admin" || permission === "Owner"){
|
||||
return renderStatusBtn(item.status, item.number);
|
||||
}else{
|
||||
return "--";
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
return (
|
||||
<div className="listPart">
|
||||
<FlexAJ>
|
||||
{renderStatus()}
|
||||
<span>
|
||||
<Blueback className="mr30">手动创建</Blueback>
|
||||
<span className="mr30"><i className="iconfont icon-fenzhi1 font-16 mr5 color-blue"></i>分支</span>
|
||||
<span><i className="iconfont icon-biaoqian3 font-16 mr5 color-blue"></i>标签</span>
|
||||
</span>
|
||||
{/* <Blueback>手动创建</Blueback> */}
|
||||
{/* <span className="mr30">
|
||||
<i className="iconfont icon-fenzhi1 font-16 mr5 color-blue"></i>分支
|
||||
</span>
|
||||
<span>
|
||||
<i className="iconfont icon-biaoqian3 font-16 mr5 color-blue"></i>
|
||||
标签
|
||||
</span> */}
|
||||
</FlexAJ>
|
||||
<Table
|
||||
onRow={(record,index)=>{
|
||||
return{
|
||||
onClick:(event)=>clickRows(event,record)
|
||||
}
|
||||
}}
|
||||
columns={column}
|
||||
className="normalTable"
|
||||
dataSource={datasource}
|
||||
dataSource={data}
|
||||
pagination={false}
|
||||
loading={tableLoading}
|
||||
></Table>
|
||||
{
|
||||
total > LIMIT ?
|
||||
<div style={{textAlign:'center',margin:"30px 50px"}}>
|
||||
<Pagination showQuickJumper defaultCurrent={page} total={total} pageSize={LIMIT} onChange={ChangePage}></Pagination>
|
||||
</div>:""
|
||||
}
|
||||
{total > LIMIT ?
|
||||
<div style={{ textAlign: "center", margin: "30px 50px" }}>
|
||||
<Pagination
|
||||
showQuickJumper
|
||||
defaultCurrent={page}
|
||||
total={total}
|
||||
pageSize={LIMIT}
|
||||
onChange={ChangePage}
|
||||
></Pagination>
|
||||
</div>
|
||||
:
|
||||
"" }
|
||||
</div>
|
||||
)
|
||||
})
|
||||
);
|
||||
};
|
||||
export default forwardRef(Structure);
|
||||
|
|
|
@ -12,8 +12,14 @@
|
|||
.disposePanel{
|
||||
.language{
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
li{
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
border:1px solid #fff;
|
||||
&.active{
|
||||
border:1px solid #5091FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
.editorBody{
|
||||
|
@ -36,6 +42,7 @@
|
|||
top:7px;
|
||||
}
|
||||
.listPart{
|
||||
min-height: 400px;
|
||||
.listNav{
|
||||
display: flex;
|
||||
li{
|
||||
|
@ -63,6 +70,7 @@
|
|||
.ant-table-thead > tr > th, .ant-table-tbody > tr > td{
|
||||
padding:10px 5px;
|
||||
color:#333;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ant-table-thead{
|
||||
border:1px solid rgba(238,238,238,1)
|
||||
|
@ -70,6 +78,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.ant-modal-close{
|
||||
top:7px;
|
||||
}
|
||||
// 列表
|
||||
.listPart{
|
||||
.statusTag{
|
||||
|
@ -103,8 +114,13 @@
|
|||
border:1px solid #F73030;
|
||||
color:#F73030 ;
|
||||
}
|
||||
&.killed{
|
||||
background:#eee;
|
||||
border:1px solid #999;
|
||||
color:#999 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -205,6 +221,14 @@
|
|||
border:1px solid rgba(255,110,33,1);
|
||||
color:rgba(255,110,33,1);
|
||||
}
|
||||
&.killed{
|
||||
border:1px solid #999;
|
||||
color:#999;
|
||||
}
|
||||
&.skipped{
|
||||
border:1px solid #d4d9de;
|
||||
color:#798390;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.rightSection{
|
||||
|
@ -212,6 +236,8 @@
|
|||
background-color: #081930;
|
||||
.rightMainContent{
|
||||
padding:24px 30px;
|
||||
height:100vh;
|
||||
overflow-y: auto;
|
||||
& > div{
|
||||
margin-bottom: 12px;
|
||||
.items{
|
||||
|
@ -264,4 +290,27 @@
|
|||
cursor: col-resize;
|
||||
}
|
||||
}
|
||||
}
|
||||
.opsDetailOut{
|
||||
display: flex;
|
||||
color: #fff;
|
||||
line-height: 22px;
|
||||
align-items: flex-start;
|
||||
margin-top: 5px;
|
||||
&>span{
|
||||
margin-right: 10px;
|
||||
min-width: 20px;
|
||||
text-align: left;
|
||||
padding-left: 3px;
|
||||
}
|
||||
&>p{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
.noOperation{
|
||||
margin-bottom:20px;
|
||||
width:380px;
|
||||
text-align:center;
|
||||
line-height:22px;
|
||||
color:#666;
|
||||
}
|
|
@ -1,33 +1,114 @@
|
|||
import React from 'react';
|
||||
import './ops.scss';
|
||||
import { FlexAJ, AlignCenter } from '../Component/layout';
|
||||
import { Tags } from '../Component/OpsStatus';
|
||||
import SplitPane from 'react-split-pane';
|
||||
import LeftPanel from './OpsDetailLeftpanel';
|
||||
import RightPanel from './OpsDetailRightpanel';
|
||||
import React, { useEffect, useState, useRef, useContext } from "react";
|
||||
import "./ops.scss";
|
||||
import { FlexAJ, AlignCenter } from "../Component/layout";
|
||||
import { Tags } from "../Component/OpsStatus";
|
||||
import SplitPane from "react-split-pane";
|
||||
import LeftPanel from "./OpsDetailLeftpanel";
|
||||
import RightPanel from "./OpsDetailRightpanel";
|
||||
import axios from "axios";
|
||||
import { Spin } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export default (props) => {
|
||||
const [data, setData] = useState(undefined);
|
||||
const [stageN, setStageN] = useState(undefined);
|
||||
const [stepN, setStepN] = useState(undefined);
|
||||
const [rightSpin, setRightSpin] = useState(false);
|
||||
const [spinning, setSpinning] = useState(true);
|
||||
|
||||
export default (()=>{
|
||||
return(
|
||||
<div className="opsDetailPanel">
|
||||
<FlexAJ className="opsInfos">
|
||||
<AlignCenter>
|
||||
<span>#1</span>
|
||||
<span className="ml10">将分支“221063-improve-buy-ci-minutes-link”合并到“221063-improve-buy-ci-minutes-link"</span>
|
||||
{Tags(1)}
|
||||
</AlignCenter>
|
||||
<a style={{color:"#ddd"}}><i className="iconfont icon-yiguanbi font-15 mr5"></i>退出</a>
|
||||
</FlexAJ>
|
||||
<div className="opsSection">
|
||||
<SplitPane className="outer-split-pane" split="vertical" minSize={468} maxSize={-350} defaultSize="40%">
|
||||
<section className="leftSection">
|
||||
<LeftPanel />
|
||||
</section>
|
||||
<section className="rightSection">
|
||||
<RightPanel />
|
||||
</section>
|
||||
</SplitPane>
|
||||
let projectId = props.match.params.projectId;
|
||||
let owner = props.match.params.owner;
|
||||
let opsId = props.match.params.opsId;
|
||||
|
||||
useEffect(() => {
|
||||
if (opsId && projectId) {
|
||||
Init();
|
||||
}
|
||||
}, [opsId]);
|
||||
|
||||
function Init() {
|
||||
const url = `/${owner}/${projectId}/builds/${opsId}.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
setSpinning(false);
|
||||
setData(result.data);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
setSpinning(false);
|
||||
});
|
||||
}
|
||||
|
||||
// 重新构建
|
||||
function repeatSet(e,type,number) {
|
||||
if(type==="repeat"){
|
||||
// 重新构建
|
||||
const url = `/${owner}/${projectId}/builds/${number}/restart.json`;
|
||||
axios.post(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
props.showNotification("工作流正在重新构建!");
|
||||
props.history.push(`/projects/${owner}/${projectId}/devops/${result.data.number}/detail`);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}else{
|
||||
// 撤销构建
|
||||
const url = `/${owner}/${projectId}/builds/${number}/stop.json`;
|
||||
axios.delete(url).then((result) => {
|
||||
if (result) {
|
||||
props.showNotification("撤销构建成功!");
|
||||
Init();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function chooseSteps(pre,sub){
|
||||
if(pre && sub){
|
||||
setStepN(sub);
|
||||
setStageN(pre);
|
||||
setRightSpin(true);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Spin spinning={spinning}>
|
||||
<div className="opsDetailPanel">
|
||||
<FlexAJ className="opsInfos">
|
||||
<AlignCenter>
|
||||
<span>#{data && data.number}</span>
|
||||
<span className="ml10">{data && data.message}</span>
|
||||
{Tags(`${data && data.status}`)}
|
||||
</AlignCenter>
|
||||
<Link
|
||||
style={{ color: "#ddd" }}
|
||||
to={`/projects/${owner}/${projectId}/devops/list`}
|
||||
>
|
||||
<i className="iconfont icon-yiguanbi font-15 mr5"></i>退出
|
||||
</Link>
|
||||
</FlexAJ>
|
||||
<div className="opsSection">
|
||||
<SplitPane
|
||||
className="outer-split-pane"
|
||||
split="vertical"
|
||||
minSize={468}
|
||||
maxSize={-350}
|
||||
defaultSize="40%"
|
||||
>
|
||||
<section className="leftSection">
|
||||
<LeftPanel data={data} repeatSet={repeatSet} chooseSteps={chooseSteps} />
|
||||
</section>
|
||||
<section className="rightSection">
|
||||
<RightPanel data={data} rightSpin={rightSpin} stepN={stepN} stageN={stageN} owner={owner} projectId={projectId} opsId={opsId} />
|
||||
</section>
|
||||
</SplitPane>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
});
|
||||
</Spin>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import axios from 'axios';
|
||||
// 获取分支列表
|
||||
export const getBranch = async (id)=>{
|
||||
return (await axios.get(`/projects/${id}/branches.json`)).data;
|
||||
export const getBranch = async (id,owner)=>{
|
||||
return (await axios.get(`/${owner}/${id}/branches.json`)).data;
|
||||
}
|
||||
// 获取标签列表
|
||||
export const getTag = async (id)=>{
|
||||
return (await axios.get(`/repositories/${id}/tags.json`)).data;
|
||||
export const getTag = async (id,owner)=>{
|
||||
return (await axios.get(`/${owner}/${id}/tags.json`)).data;
|
||||
}
|
||||
// 获取hooks(仓库设置-管理web钩子)列表
|
||||
export const getHooks = async (id,params)=>{
|
||||
|
|
After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 590 KiB After Width: | Height: | Size: 590 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 64 KiB |
|
@ -46,13 +46,12 @@ class Index extends Component {
|
|||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/projects/:projectsId"
|
||||
path="/projects/:owner/:projectsId"
|
||||
render={(props) => (
|
||||
<ProjectDetail {...this.props} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
exact
|
||||
path="/projects"
|
||||
render={(props) => (
|
||||
<ProjectIndex {...this.props} {...props} />
|
||||
|
|
|
@ -10,14 +10,14 @@ export default ((props)=>{
|
|||
const [ data , setData ] =useState(undefined);
|
||||
const [ isSpin , setIsSpin ] =useState(true);
|
||||
|
||||
const { projectsId } = props.match.params;
|
||||
const { projectsId , owner } = props.match.params;
|
||||
|
||||
useEffect(()=>{
|
||||
getBranchs(projectsId);
|
||||
getBranchs(projectsId, owner);
|
||||
},[projectsId])
|
||||
|
||||
async function getBranchs(id){
|
||||
let result = await getBranch(id);
|
||||
async function getBranchs(id,owner){
|
||||
let result = await getBranch(id,owner);
|
||||
setData(result);
|
||||
setIsSpin(false);
|
||||
}
|
||||
|
@ -32,15 +32,15 @@ export default ((props)=>{
|
|||
return(
|
||||
<li key={key}>
|
||||
<div>
|
||||
<Link to={`/projects/${projectsId}/coders?branch=${item.name}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/branch/${item.name}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
|
||||
<p className="f-wrap-alignCenter mt15">
|
||||
<span className="mr5 commitKey" style={{marginLeft:0}}>{item.last_commit && truncateCommitId(item.last_commit.sha)}</span>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.last_commit.sha}`)}`} className="mr5 commitKey" style={{marginLeft:0}}>{item.last_commit && truncateCommitId(item.last_commit.sha)}</Link>
|
||||
<span className="color-grey-3 hide-1 messages leftPoint">{item.last_commit && item.last_commit.message}</span>
|
||||
<span className="color-grey-8 ml30">最后更新于{item.last_commit && item.last_commit.time_from_now}</span>
|
||||
</p>
|
||||
</div>
|
||||
<span>
|
||||
<Link to={`/projects/${projectsId}/merge/new`} className="mr20 color-blue mr30">创建合并请求</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/pulls/new`} className="mr20 color-blue mr30">创建合并请求</Link>
|
||||
<Dropdown overlay={menu(item.zip_url,item.tar_url)} trigger={['click']} placement="bottomRight" className="color-green-file">
|
||||
<a className="ant-dropdown-link">
|
||||
<Tooltip title={`下载分支${item.name}`}><Icon type="cloud-download" className="font-18"/></Tooltip>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Spin , Pagination } from 'antd';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import { truncateCommitId } from '../common/util'
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import SelectBranch from '../Branch/Select';
|
||||
import Nodata from '../Nodata';
|
||||
|
||||
|
@ -12,7 +12,6 @@ class CoderRootCommit extends Component{
|
|||
constructor(props){
|
||||
super(props)
|
||||
this.state={
|
||||
branch:"master",
|
||||
commitDatas:undefined,
|
||||
dataCount:undefined,
|
||||
limit:20,
|
||||
|
@ -22,19 +21,31 @@ class CoderRootCommit extends Component{
|
|||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
const { branch , page , limit } = this.state;
|
||||
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 { page , limit } = this.state;
|
||||
this.setState({
|
||||
isSpining:true
|
||||
})
|
||||
this.getCommitList( branch , page , limit );
|
||||
this.getCommitList( branchName , page , limit );
|
||||
}
|
||||
|
||||
getCommitList=(branch , page , limit)=>{
|
||||
this.setState({
|
||||
isSpining:true
|
||||
})
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/repositories/${projectsId}/commits.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/commits.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
sha:branch,
|
||||
|
@ -68,26 +79,28 @@ class CoderRootCommit extends Component{
|
|||
|
||||
// 切换分支 search:tag为根据标签搜索
|
||||
changeBranch=(value)=>{
|
||||
const { page , limit } = this.state;
|
||||
const { getTopCount } = this.props;
|
||||
this.setState({
|
||||
isSpining:true,
|
||||
branch:value,
|
||||
})
|
||||
this.getCommitList(value , page , limit);
|
||||
getTopCount && getTopCount(value);
|
||||
// const { page , limit } = this.state;
|
||||
// const { getTopCount } = this.props;
|
||||
// this.setState({
|
||||
// isSpining:true,
|
||||
// branch:value,
|
||||
// })
|
||||
// this.getCommitList(value , page , limit);
|
||||
// getTopCount && getTopCount(value);
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/commits/branch/${value}`);
|
||||
}
|
||||
|
||||
ChangePage=(page)=>{
|
||||
|
||||
const { branch , limit } = this.state;
|
||||
this.getCommitList(branch , page , limit);
|
||||
const { branchName } = this.props.match.params;
|
||||
const { limit } = this.state;
|
||||
this.getCommitList(branchName , page , limit);
|
||||
}
|
||||
render(){
|
||||
const { branch , commitDatas , dataCount , limit , page , isSpining } = this.state;
|
||||
const { branchs , projectDetail, commit_class } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
const { commitDatas , dataCount , limit , page , isSpining } = this.state;
|
||||
const { projectDetail, commit_class , defaultBranch } = this.props;
|
||||
const { projectsId , owner , branchName } = this.props.match.params;
|
||||
let branch = branchName || defaultBranch;
|
||||
return(
|
||||
<React.Fragment>
|
||||
<div className={commit_class}>
|
||||
|
@ -97,6 +110,8 @@ class CoderRootCommit extends Component{
|
|||
projectsId={projectsId}
|
||||
branch={branch}
|
||||
changeBranch={this.changeBranch}
|
||||
owner={owner}
|
||||
history={this.props.history}
|
||||
></SelectBranch>
|
||||
</div>
|
||||
<Spin spinning={isSpining}>
|
||||
|
@ -112,8 +127,8 @@ class CoderRootCommit extends Component{
|
|||
return(
|
||||
<div key={k}>
|
||||
<p className="f-wrap-alignCenter">
|
||||
<span className="commitKey" style={{marginLeft:0}}>{truncateCommitId(`${item.sha}`)}</span>
|
||||
<span className="flex1 ml20 font-16 color-grey-3">{item.message}</span>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="commitKey" style={{marginLeft:0}}>{truncateCommitId(`${item.sha}`)}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="flex1 ml20 font-16 color-grey-3">{item.message}</Link>
|
||||
</p>
|
||||
<p className="f-wrap-alignCenter mt15">
|
||||
<Link to={`/users/${item.login}`} className="show-user-link">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { Component } from "react";
|
||||
import { Menu, Spin, Button } from "antd";
|
||||
import { Menu, Spin } from "antd";
|
||||
import { getImageUrl } from "educoder";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
|
@ -10,22 +10,29 @@ import RootTable from './RootTable';
|
|||
import CoderRootFileDetail from './CoderRootFileDetail';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import RenderHtml from '../../components/render-html';
|
||||
import Nodata from '../Nodata';
|
||||
|
||||
import axios from "axios";
|
||||
/**
|
||||
* address:http和SSH,http_url(对应git地址)
|
||||
* branch:当前分支
|
||||
* filePath:点击目录时当前目录的路径
|
||||
* subfileType:保存当前点击目录的文件类型(显示目录列表时才显示新建文件,如果点击的是文件就不显示新建文件按钮)
|
||||
* readMeContent:根目录下面的readme文件内容
|
||||
*/
|
||||
|
||||
function getPathUrl(array,index){
|
||||
if(array && array.length>0 && index){
|
||||
let str = "";
|
||||
for(let i=0;i<index;i++){
|
||||
str += `/${array[i]}`;
|
||||
}
|
||||
return str.substr(1);
|
||||
}
|
||||
}
|
||||
class CoderRootDirectory extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
address: "http",
|
||||
branch: "master",
|
||||
filePath: undefined,
|
||||
subFileType: undefined,
|
||||
readMeContent: undefined,
|
||||
|
@ -70,75 +77,64 @@ class CoderRootDirectory extends Component {
|
|||
|
||||
Init = () => {
|
||||
let { search } = this.props.history.location;
|
||||
let branchName = undefined;
|
||||
if (search && search.indexOf("?branch=") > -1) {
|
||||
branchName = search.split("?branch=")[1];
|
||||
this.setState({
|
||||
branch: branchName,
|
||||
});
|
||||
}
|
||||
if (search && search.indexOf("?url=") > -1) {
|
||||
let url = search.split("?url=")[1];
|
||||
this.setState({
|
||||
filePath: url,
|
||||
});
|
||||
this.getFileDetail(url);
|
||||
const { branchName } = this.props.match.params;
|
||||
const { defaultBranch } = this.props;
|
||||
let branch = branchName || defaultBranch;
|
||||
if (search && (search.indexOf("?url=") > -1 || search.indexOf("&url=") > -1)) {
|
||||
let url = search.split("url=")[1];
|
||||
if(url && decodeURI(url).indexOf("&")){
|
||||
url=decodeURI(url).split("&")[0];
|
||||
}
|
||||
this.getFileDetail(decodeURI(url),branch);
|
||||
} else {
|
||||
const { branch } = this.state;
|
||||
this.getProjectRoot(branchName || branch);
|
||||
this.getProjectRoot(branch);
|
||||
}
|
||||
};
|
||||
|
||||
// 页面地址返回到主目录
|
||||
returnMain = (branch) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner , branchName } = this.props.match.params;
|
||||
this.setState({
|
||||
readOnly:true
|
||||
})
|
||||
this.props.history.push(`/projects/${projectsId}/coders`);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}${branchName?`/branch/${branchName}`:""}`);
|
||||
this.getProjectRoot(branch);
|
||||
};
|
||||
|
||||
// 获取根目录
|
||||
getProjectRoot = (branch) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/repositories/${projectsId}/entries.json`;
|
||||
axios
|
||||
.get(url, {
|
||||
params: {
|
||||
ref: branch,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
let last_commit = result.data && result.data.last_commit;
|
||||
let entries = result.data && result.data.entries;
|
||||
this.setState({
|
||||
filePath: undefined,
|
||||
fileDetail: undefined,
|
||||
isSpin: false,
|
||||
branchLastCommit: last_commit && last_commit.commit,
|
||||
lastCommitAuthor:
|
||||
last_commit && (last_commit.author || (last_commit.commit && last_commit.commit.author)),
|
||||
zip_url: result.data.zip_url,
|
||||
tar_url: result.data.tar_url
|
||||
});
|
||||
if (entries && entries.length > 0) {
|
||||
this.renderData(entries);
|
||||
}
|
||||
this.setState({
|
||||
rootList: entries,
|
||||
subFileType: true,
|
||||
});
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/entries.json`;
|
||||
axios.get(url, { params: { ref: branch } })
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
let last_commit = result.data && result.data.last_commit;
|
||||
let entries = result.data && result.data.entries;
|
||||
this.setState({
|
||||
filePath: undefined,
|
||||
fileDetail: undefined,
|
||||
isSpin: false,
|
||||
branchLastCommit: last_commit && last_commit.commit,
|
||||
lastCommitAuthor:
|
||||
last_commit && (last_commit.author || (last_commit.commit && last_commit.commit.author)),
|
||||
zip_url: result.data.zip_url,
|
||||
tar_url: result.data.tar_url
|
||||
});
|
||||
if (entries && entries.length > 0) {
|
||||
this.renderData(entries);
|
||||
}
|
||||
})
|
||||
.catch((error) => {});
|
||||
this.setState({
|
||||
rootList: entries,
|
||||
subFileType: true,
|
||||
});
|
||||
}
|
||||
}).catch((error) => {});
|
||||
};
|
||||
|
||||
ChangeFile = (arr, readOnly) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
//点击直接跳转页面 加载一次路由
|
||||
this.props.history.push(`/projects/${projectsId}/coders?url=${arr.path}`);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}?url=${arr.path}`);
|
||||
this.setState({
|
||||
readOnly: readOnly,
|
||||
chooseType:"file"
|
||||
|
@ -158,19 +154,12 @@ class CoderRootDirectory extends Component {
|
|||
index: k,
|
||||
name: i,
|
||||
path: str.substr(1),
|
||||
type:
|
||||
filePath && filePath.length > 0
|
||||
? filePath[k]
|
||||
? filePath[k].type
|
||||
: type
|
||||
: type,
|
||||
type: filePath && filePath.length > 0 ? filePath[k] ? filePath[k].type : type : type,
|
||||
});
|
||||
});
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
//点击直接跳转页面 加载一次路由
|
||||
this.props.history.push(
|
||||
`/projects/${projectsId}/coders?url=${str.substr(1)}`
|
||||
);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}?url=${str.substr(1)}`);
|
||||
} else {
|
||||
list.push({
|
||||
index: 0,
|
||||
|
@ -186,60 +175,74 @@ class CoderRootDirectory extends Component {
|
|||
|
||||
// 获取子目录
|
||||
getFileDetail = (path, ref) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { branch } = this.state;
|
||||
const url = `/repositories/${projectsId}/sub_entries.json`;
|
||||
|
||||
this.setState({
|
||||
filePath: decodeURI(path),
|
||||
});
|
||||
const { projectsId , owner , branchName } = this.props.match.params;
|
||||
const { chooseType } = this.state;
|
||||
const url = `/${owner}/${projectsId}/sub_entries.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
filepath:path,
|
||||
ref:ref || branch
|
||||
ref:ref || branchName,
|
||||
type:chooseType
|
||||
}
|
||||
}).then((result)=>{
|
||||
let entries = result.data && result.data.entries
|
||||
if( entries && entries.length > 0){
|
||||
let { chooseType } = this.state;
|
||||
// 当前返回的子目录只有一条数据,且这条数据返回的是文件类型
|
||||
if(entries.length === 1 && entries[0].type === "file" && chooseType ==="file"){
|
||||
let entries = result.data && result.data.entries;
|
||||
this.setState({
|
||||
isSpin:false
|
||||
})
|
||||
if(result){
|
||||
if(entries){
|
||||
// 返回对象entries.type则是文件类型,否则是文件夹
|
||||
if(entries.type){
|
||||
this.setState({
|
||||
fileDetail:[entries],
|
||||
rootList:undefined,
|
||||
subFileType:false
|
||||
})
|
||||
}else{
|
||||
this.setState({
|
||||
fileDetail:undefined,
|
||||
rootList:entries,
|
||||
branchLastCommit:result.data.last_commit && result.data.last_commit.commit,
|
||||
lastCommitAuthor:result.data.last_commit && (result.data.last_commit.author || (result.data.last_commit.commit && result.data.last_commit.commit.author))
|
||||
})
|
||||
this.renderData(entries);
|
||||
}
|
||||
}else{
|
||||
this.setState({
|
||||
fileDetail:entries,
|
||||
fileDetail:undefined,
|
||||
rootList:undefined,
|
||||
isSpin:false,
|
||||
subFileType:false
|
||||
})
|
||||
}else{
|
||||
this.setState({
|
||||
fileDetail:undefined,
|
||||
rootList:entries,
|
||||
isSpin:false,
|
||||
branchLastCommit:result.data.last_commit && result.data.last_commit.commit,
|
||||
lastCommitAuthor:result.data.last_commit && (result.data.last_commit.author || (result.data.last_commit.commit && result.data.last_commit.commit.author))
|
||||
})
|
||||
this.renderData(entries);
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
isSpin:false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
renderData = (data) => {
|
||||
const rootList = [];
|
||||
const readMeContent = [];
|
||||
const readMeFile = [];
|
||||
data &&
|
||||
data.map((item, key) => {
|
||||
rootList.push({
|
||||
key,
|
||||
message: item.commit && item.commit.message,
|
||||
...item,
|
||||
});
|
||||
if (item.is_readme_file) {
|
||||
readMeContent.push({ ...item });
|
||||
readMeFile.push({ ...item });
|
||||
}
|
||||
data && data.map((item, key) => {
|
||||
rootList.push({
|
||||
key,
|
||||
message: item.commit && item.commit.message,
|
||||
...item,
|
||||
});
|
||||
if (item.is_readme_file) {
|
||||
readMeContent.push({ ...item });
|
||||
readMeFile.push({ ...item });
|
||||
}
|
||||
});
|
||||
this.setState({
|
||||
rootList: rootList,
|
||||
readMeContent,
|
||||
|
@ -252,8 +255,8 @@ class CoderRootDirectory extends Component {
|
|||
this.setState({
|
||||
chooseType:type
|
||||
})
|
||||
const { projectsId } = this.props.match.params;
|
||||
this.props.history.push(`/projects/${projectsId}/coders?url=${path}`);
|
||||
const { projectsId, owner , branchName } = this.props.match.params;
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}${branchName?`/branch/${branchName}`:""}?url=${path}`);
|
||||
if(filename.substring(filename.length - 3) === ".md"){
|
||||
this.setState({
|
||||
md:true
|
||||
|
@ -281,26 +284,23 @@ class CoderRootDirectory extends Component {
|
|||
<span className="commonBox-title-read">
|
||||
{readMeContent[0].name}
|
||||
</span>
|
||||
{permission ? (
|
||||
{permission ?
|
||||
<a
|
||||
onClick={() => this.ChangeFile(readMeFile[0], false)}
|
||||
className="ml20 pull-right"
|
||||
>
|
||||
<i className="iconfont icon-bianji6 font-16 color-blue"></i>
|
||||
</a>
|
||||
) : (
|
||||
:
|
||||
""
|
||||
)}
|
||||
}
|
||||
</div>
|
||||
<div className="commonBox-info">
|
||||
{readMeContent[0].content ? (
|
||||
<RenderHtml
|
||||
className="break_word_comments"
|
||||
value={readMeContent[0].content}
|
||||
/>
|
||||
) : (
|
||||
{readMeContent[0].content ?
|
||||
<RenderHtml className="break_word_comments imageLayerParent" value={readMeContent[0].content} />
|
||||
:
|
||||
<span>暂无~</span>
|
||||
)}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -309,24 +309,18 @@ class CoderRootDirectory extends Component {
|
|||
|
||||
// 选择分支
|
||||
changeBranch = (value) => {
|
||||
this.setState({
|
||||
branch: value,
|
||||
isSpin: true,
|
||||
readOnly:true
|
||||
});
|
||||
const { getTopCount } = this.props;
|
||||
getTopCount && getTopCount(value);
|
||||
|
||||
let { search } = this.props.history.location;
|
||||
if (search && search.indexOf("?url=") > -1) {
|
||||
let url = search.split("?url=")[1];
|
||||
this.setState({
|
||||
filePath: url,
|
||||
});
|
||||
this.getFileDetail(url, value);
|
||||
} else {
|
||||
this.getProjectRoot(value);
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
|
||||
let url = `/projects/${owner}/${projectsId}${value && `/branch/${value}`}`;
|
||||
if (search && (search.indexOf("?url=") > -1 || search.indexOf("&url=") > -1)) {
|
||||
let u = search.split("url=")[1];
|
||||
if(u && decodeURI(u).indexOf("&")){
|
||||
u=decodeURI(u).split("&")[0];
|
||||
}
|
||||
url += `?url=${u}`;
|
||||
}
|
||||
this.props.history.push(url);
|
||||
}
|
||||
|
||||
// 子目录路径返回链接
|
||||
|
@ -335,8 +329,8 @@ class CoderRootDirectory extends Component {
|
|||
chooseType:"dir",
|
||||
readOnly:true
|
||||
})
|
||||
const { projectsId } = this.props.match.params;
|
||||
this.props.history.push(`/projects/${projectsId}/coders?url=${url}`);
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}?url=${url}`);
|
||||
}
|
||||
|
||||
onEdit=(readOnly)=>{
|
||||
|
@ -363,8 +357,8 @@ class CoderRootDirectory extends Component {
|
|||
}
|
||||
|
||||
title = (branchLastCommit,lastCommitAuthor) => {
|
||||
console.log(branchLastCommit)
|
||||
if (branchLastCommit) {
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
return (
|
||||
<div className="f-wrap-alignCenter">
|
||||
{lastCommitAuthor ? (
|
||||
|
@ -390,13 +384,13 @@ class CoderRootDirectory extends Component {
|
|||
) : (
|
||||
""
|
||||
)}
|
||||
<span className="color-blue flex-1 hide-1">
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${branchLastCommit.sha}`)}`} className="color-blue flex-1 hide-1">
|
||||
{branchLastCommit.message}
|
||||
</span>
|
||||
</Link>
|
||||
<span>{branchLastCommit.time_from_now}</span>
|
||||
<span className="commitKey">
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${branchLastCommit.sha}`)}`} className="commitKey">
|
||||
{truncateCommitId(branchLastCommit.sha)}
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}else{
|
||||
|
@ -405,32 +399,36 @@ class CoderRootDirectory extends Component {
|
|||
}
|
||||
|
||||
render(){
|
||||
const { branchLastCommit , lastCommitAuthor , rootList , branch ,filePath , fileDetail , subFileType , readMeContent, isSpin , zip_url , tar_url} = this.state;
|
||||
const { isManager , isDeveloper , projectDetail } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { branchLastCommit , lastCommitAuthor , rootList ,filePath , fileDetail , subFileType , readMeContent, isSpin , zip_url , tar_url} = this.state;
|
||||
const { isManager , isDeveloper , projectDetail , platform , defaultBranch } = this.props;
|
||||
|
||||
const { projectsId , owner , branchName } = this.props.match.params;
|
||||
let branch = branchName || defaultBranch;
|
||||
const columns = [
|
||||
{
|
||||
key:"name",
|
||||
dataIndex: 'name',
|
||||
width:"30%",
|
||||
render: (text,item) => (
|
||||
<a onClick={()=>this.goToSubRoot(item.path,item.type,text)} className="ml12 task-hide" style={{ display: "block", maxWidth: "345px" }}>
|
||||
<i className={ item.type === "file" ? "iconfont icon-wenjia font-15 color-green-file mr5":"iconfont icon-wenjianjia1 color-green-file font-15 mr5"}></i>{text}
|
||||
<i className={ item.type === "file" ? "iconfont icon-wenjia font-15 color-green-file mr5" : "iconfont icon-wenjianjia1 color-green-file font-15 mr5"}></i>{text}
|
||||
</a>
|
||||
),
|
||||
},
|
||||
{
|
||||
dataIndex: "commit",
|
||||
key:"message",
|
||||
dataIndex: "message",
|
||||
width: "60%",
|
||||
render: (text, item) =>
|
||||
item.commit && item.commit.message ?
|
||||
<span className="task-hide" style={{ display: "block", maxWidth: "670px" }} >
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.commit.sha}`)}`} title={item.commit.message} className="task-hide" style={{ display: "block", maxWidth: "670px" }} >
|
||||
{item.commit.message}
|
||||
</span>
|
||||
</Link>
|
||||
: ""
|
||||
},
|
||||
{
|
||||
dataIndex: "commit",
|
||||
key:"time_from_now",
|
||||
dataIndex: "time_from_now",
|
||||
width: "10%",
|
||||
className: "edu-txt-right",
|
||||
render: (text, item) =>
|
||||
|
@ -449,12 +447,20 @@ class CoderRootDirectory extends Component {
|
|||
<div className="main">
|
||||
<div className="f-wrap-between mb20">
|
||||
<div className="f-wrap-alignCenter">
|
||||
<SelectBranch
|
||||
repo_id={projectDetail && projectDetail.repo_id}
|
||||
projectsId={projectsId}
|
||||
branch={branch}
|
||||
changeBranch={this.changeBranch}
|
||||
></SelectBranch>
|
||||
{
|
||||
platform ?
|
||||
<SelectBranch
|
||||
repo_id={projectDetail && projectDetail.repo_id}
|
||||
projectsId={projectsId}
|
||||
branch={branch}
|
||||
changeBranch={this.changeBranch}
|
||||
owner={owner}
|
||||
history={this.props.history}
|
||||
></SelectBranch>
|
||||
:
|
||||
<span>分支:<span className="color-grey-6">master</span></span>
|
||||
}
|
||||
|
||||
|
||||
{filePath && (
|
||||
<span className="ml20 font-16">
|
||||
|
@ -472,7 +478,7 @@ class CoderRootDirectory extends Component {
|
|||
key === array.length-1 ?
|
||||
<span className="color-grey-6 subFileName" key={key}>{item}</span>
|
||||
:
|
||||
<a onClick={()=>this.returnUlr(`${key === 0 ? `${item}` :`${array[key-1]}/${item}`}`)} className="color-blue subFileName">{item}</a>
|
||||
<a onClick={()=>this.returnUlr(`${getPathUrl(array,key+1)}`)} className="color-blue subFileName">{item}</a>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
@ -481,18 +487,16 @@ class CoderRootDirectory extends Component {
|
|||
)}
|
||||
</div>
|
||||
<div className="f-wrap-alignCenter">
|
||||
{subFileType && (projectDetail && parseInt(projectDetail.type)) !== 2 && (isManager || isDeveloper) && (
|
||||
{subFileType && (projectDetail && parseInt(projectDetail.type)) !== 2 && (isManager || isDeveloper) && platform && (
|
||||
<div>
|
||||
<span>
|
||||
<Link
|
||||
to={`/projects/${projectsId}/coders/${branch}/uploadfile${urlRoot}`}
|
||||
>
|
||||
<Link to={`/projects/${owner}/${projectsId}/${branch}/uploadfile${urlRoot}`} >
|
||||
<span className="color-green mr30">上传文件</span>
|
||||
</Link>
|
||||
</span>
|
||||
<span className="mr30">
|
||||
<Link
|
||||
to={`/projects/${projectsId}/coders/${branch}/newfile${urlRoot}`}
|
||||
to={`/projects/${owner}/${projectsId}/${branch}/newfile${urlRoot}`}
|
||||
>
|
||||
<span className="color-blue">新建文件</span>
|
||||
</Link>
|
||||
|
@ -524,10 +528,13 @@ class CoderRootDirectory extends Component {
|
|||
{...this.state}
|
||||
readOnly={this.state.readOnly}
|
||||
onEdit={this.onEdit}
|
||||
currentBranch={branch}
|
||||
></CoderRootFileDetail>
|
||||
)}
|
||||
{/* readme.txt (isManager || isDeveloper)*/}
|
||||
{this.renderReadMeContent(readMeContent, isManager || isDeveloper)}
|
||||
{
|
||||
!rootList && !fileDetail && <Nodata _html="暂未发现当前文件!"/>
|
||||
}
|
||||
{ rootList && this.renderReadMeContent(readMeContent, isManager || isDeveloper)}
|
||||
</div>
|
||||
</Spin>
|
||||
);
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import React, { Component } from "react";
|
||||
import { Popconfirm, Select } from "antd";
|
||||
import { Popconfirm , Select } from "antd";
|
||||
import "./list.css";
|
||||
import axios from "axios";
|
||||
import Meditor from "../Newfile/m_editor";
|
||||
import MDEditor from "../../modules/tpm/challengesnew/tpm-md-editor";
|
||||
import RenderHtml from "../../components/render-html";
|
||||
|
||||
|
||||
function bytesToSize(bytes) {
|
||||
if (bytes === 0) return "0 B";
|
||||
let k = 1024,
|
||||
|
@ -21,7 +19,7 @@ class CoderRootFileDetail extends Component {
|
|||
value: undefined,
|
||||
language: undefined,
|
||||
languages: undefined,
|
||||
description:props.detail.content
|
||||
description: props.detail.content
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -95,8 +93,10 @@ class CoderRootFileDetail extends Component {
|
|||
default_language = item;
|
||||
}
|
||||
}
|
||||
this.state.languages = languages;
|
||||
this.state.language = default_language;
|
||||
this.setState({
|
||||
languages,
|
||||
language: default_language
|
||||
})
|
||||
};
|
||||
|
||||
select_language = (e) => {
|
||||
|
@ -107,11 +107,13 @@ class CoderRootFileDetail extends Component {
|
|||
EditFile = (flag) => {
|
||||
const { onEdit } = this.props;
|
||||
onEdit && onEdit(flag);
|
||||
// this.setState({
|
||||
// readOnly: false,
|
||||
// });
|
||||
};
|
||||
|
||||
DownLoadFile = (url) => {
|
||||
let download_url = "/attachments/entries/get_file?download_url=" + url
|
||||
window.open(download_url)
|
||||
}
|
||||
|
||||
// 编辑文件
|
||||
|
||||
changeMmirror = (e, e1, value) => {
|
||||
|
@ -122,21 +124,20 @@ class CoderRootFileDetail extends Component {
|
|||
|
||||
deleteFile = () => {
|
||||
const { branch, detail } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId, owner } = this.props.match.params;
|
||||
|
||||
const url = `/repositories/${projectsId}/delete_file.json`;
|
||||
axios
|
||||
.delete(url, {
|
||||
params: {
|
||||
filepath: detail.path,
|
||||
branch,
|
||||
sha: detail.sha,
|
||||
},
|
||||
})
|
||||
const url = `/${owner}/${projectsId}/delete_file.json`;
|
||||
axios.delete(url, {
|
||||
params: {
|
||||
filepath: detail.path,
|
||||
branch,
|
||||
sha: detail.sha,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.props.showNotification("删除成功!");
|
||||
this.props.history.push(`/projects/${projectsId}`);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}`);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
@ -163,12 +164,13 @@ class CoderRootFileDetail extends Component {
|
|||
current_user,
|
||||
isManager,
|
||||
isDeveloper,
|
||||
md
|
||||
md,
|
||||
currentBranch,
|
||||
platform
|
||||
} = this.props;
|
||||
const { language, languages , description } = this.state;
|
||||
const { language, languages, description } = this.state;
|
||||
let flag = current_user && current_user.login && (isManager || isDeveloper);
|
||||
const Option = Select.Option;
|
||||
|
||||
return (
|
||||
<div className="mb20">
|
||||
<div className="grid-item branchTitle">
|
||||
|
@ -178,40 +180,52 @@ class CoderRootFileDetail extends Component {
|
|||
</span>
|
||||
</div>
|
||||
<p className="text-right">
|
||||
{flag && (
|
||||
{flag && platform && (
|
||||
<div>
|
||||
{readOnly ? (
|
||||
<a onClick={() => this.EditFile(false)} className="ml20">
|
||||
<i className="iconfont icon-bianji1 font-15 color-grey-6"></i>
|
||||
</a>
|
||||
<span>
|
||||
{
|
||||
detail.direct_download ?
|
||||
""
|
||||
:
|
||||
<span>
|
||||
<a onClick={() => this.DownLoadFile(detail.download_url)} className="ml20">
|
||||
<i className="iconfont icon-xiazai1 font-15 color-grey-6"></i>
|
||||
</a>
|
||||
<a onClick={() => this.EditFile(false)} className="ml20">
|
||||
<i className="iconfont icon-bianji1 font-15 color-grey-6"></i>
|
||||
</a>
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<Select
|
||||
showSearch={true}
|
||||
placeholder={"请选择文本语言"}
|
||||
style={{ width: 200 }}
|
||||
value={language}
|
||||
onChange={this.select_language}
|
||||
>
|
||||
<Option value={undefined}>请选择文本语言</Option>
|
||||
{languages &&
|
||||
languages.map((item, key) => {
|
||||
return (
|
||||
<Option value={item} key={key}>
|
||||
{item}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
<button
|
||||
type="button"
|
||||
className="ant-btn ant-btn-sm ml20"
|
||||
onClick={() => this.EditFile(true)}
|
||||
>
|
||||
<span>取 消</span>
|
||||
</button>
|
||||
</React.Fragment>
|
||||
)}
|
||||
<React.Fragment>
|
||||
<Select
|
||||
showSearch={true}
|
||||
placeholder={"请选择文本语言"}
|
||||
style={{ width: 200 }}
|
||||
value={language}
|
||||
onChange={this.select_language}
|
||||
>
|
||||
<Option value={undefined}>请选择文本语言</Option>
|
||||
{languages &&
|
||||
languages.map((item, key) => {
|
||||
return (
|
||||
<Option value={item} key={key}>
|
||||
{item}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
<button
|
||||
type="button"
|
||||
className="ant-btn ant-btn-sm ml20"
|
||||
onClick={() => this.EditFile(true)}
|
||||
>
|
||||
<span>取 消</span>
|
||||
</button>
|
||||
</React.Fragment>
|
||||
)}
|
||||
|
||||
<Popconfirm
|
||||
title="确认删除这个文件?"
|
||||
|
@ -245,20 +259,21 @@ class CoderRootFileDetail extends Component {
|
|||
</div>
|
||||
) : (
|
||||
md && readOnly ?
|
||||
<div className="files-md">
|
||||
<RenderHtml className="file-md" value={description} />
|
||||
</div>
|
||||
:
|
||||
<Meditor
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
language={language ? language : "javascript"}
|
||||
filepath={`/${detail.path}`}
|
||||
content={detail.content}
|
||||
readOnly={readOnly}
|
||||
editorType="update"
|
||||
></Meditor>
|
||||
)}
|
||||
<div className="files-md">
|
||||
<RenderHtml className="file-md imageLayerParent" value={description} />
|
||||
</div>
|
||||
:
|
||||
<Meditor
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
language={language ? language : "javascript"}
|
||||
filepath={`/${detail.path}`}
|
||||
content={detail.content}
|
||||
readOnly={readOnly}
|
||||
editorType="update"
|
||||
currentBranch={currentBranch}
|
||||
></Meditor>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -55,17 +55,25 @@ class CoderRootIndex extends Component{
|
|||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
let { search } = this.props.history.location;
|
||||
let branchName = undefined;
|
||||
if (search && search.indexOf("?branch=") > -1) {
|
||||
branchName = search.split("?branch=")[1];
|
||||
this.Init();
|
||||
}
|
||||
componentDidUpdate=(prevProps)=>{
|
||||
const { location } = this.props;
|
||||
const prevlocation = prevProps && prevProps.location;
|
||||
if (location !== prevlocation) {
|
||||
this.Init();
|
||||
}
|
||||
this.getTopCount(branchName);
|
||||
}
|
||||
|
||||
Init=()=>{
|
||||
const { branchName } = this.props.match.params;
|
||||
const { defaultBranch } = this.props;
|
||||
this.getTopCount(branchName || defaultBranch);
|
||||
}
|
||||
|
||||
getTopCount=(branch)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/repositories/${projectsId}/top_counts.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/top_counts.json`;
|
||||
axios.get(url,{params:{
|
||||
ref:branch
|
||||
}}).then(result=>{
|
||||
|
@ -82,65 +90,72 @@ class CoderRootIndex extends Component{
|
|||
<Top {...this.props} {...this.state}/>
|
||||
<Switch {...this.props}>
|
||||
{/* 新建文件 */}
|
||||
<Route path="/projects/:projectsId/coders/:branch/newfile/:path"
|
||||
<Route path="/projects/:owner/:projectsId/:branch/newfile/:path"
|
||||
render={
|
||||
(props) => (<FileNew {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coders/:branch/uploadfile"
|
||||
<Route path="/projects/:owner/:projectsId/:branch/uploadfile"
|
||||
render={
|
||||
(props) => (<UploadFile {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coders/:branch/newfile"
|
||||
<Route path="/projects/:owner/:projectsId/:branch/newfile"
|
||||
render={
|
||||
(props) => (<FileNew {...this.props} {...props} {...this.state} getTopCount={this.getTopCount} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coders/commit"
|
||||
|
||||
{/* diff */}
|
||||
<Route path="/projects/:owner/:projectsId/commits/branch/:branchName"
|
||||
render={
|
||||
(props) => (<CoderRootCommit {...this.props} {...props} {...this.state} commit_class="main" getTopCount={this.getTopCount} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:owner/:projectsId/commits/:sha"
|
||||
render={
|
||||
(props) => (<Diff {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:owner/:projectsId/commits"
|
||||
render={
|
||||
() => (<CoderRootCommit {...this.props} {...this.state} commit_class="main" getTopCount={this.getTopCount} />)
|
||||
}
|
||||
></Route>
|
||||
{/* diff */}
|
||||
<Route path="/projects/:projectsId/diff/:sha"
|
||||
|
||||
<Route path="/projects/:owner/:projectsId/releases/:versionId/update"
|
||||
render={
|
||||
() => (<Diff {...this.props} {...this.state}/>)
|
||||
(props) => (<CoderRootVersionUpdate {...this.props} {...this.state} {...props} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coders/version/new"
|
||||
<Route path="/projects/:owner/:projectsId/releases/new"
|
||||
render={
|
||||
() => (<CoderRootVersionNew {...this.props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
|
||||
<Route path="/projects/:projectsId/coders/version/:versionId/update"
|
||||
render={
|
||||
() => (<CoderRootVersionUpdate {...this.props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
|
||||
<Route path="/projects/:projectsId/coders/version"
|
||||
<Route path="/projects/:owner/:projectsId/releases"
|
||||
render={
|
||||
() => (<CoderRootVersion {...this.props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coders/tag"
|
||||
|
||||
<Route path="/projects/:owner/:projectsId/tag"
|
||||
render={
|
||||
() => (<CoderRootTag {...this.props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coders/branch"
|
||||
<Route path="/projects/:owner/:projectsId/branch/:branchName"
|
||||
render={
|
||||
(props) => (<CoderRootDirectory {...this.props} {...this.state} getTopCount={this.getTopCount} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:owner/:projectsId/branchs"
|
||||
render={
|
||||
() => (<CoderRootBranch {...this.props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coders"
|
||||
render={
|
||||
() => (<CoderRootDirectory {...this.props} {...this.state} getTopCount={this.getTopCount} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId"
|
||||
<Route path="/projects/:owner/:projectsId"
|
||||
render={
|
||||
() => (<CoderRootDirectory {...this.props} {...this.state} getTopCount={this.getTopCount} />)
|
||||
}
|
||||
|
|
|
@ -3,18 +3,17 @@ import axios from 'axios';
|
|||
import { Spin } from 'antd';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import Nodata from '../Nodata';
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
|
||||
export default ({
|
||||
projectDetail
|
||||
}) => {
|
||||
export default (( props, { projectDetail }) => {
|
||||
const [isSpin, setSpin] = useState(true);
|
||||
const [data, setData] = useState(undefined);
|
||||
|
||||
const repo_id = projectDetail && projectDetail.repo_id;
|
||||
const { projectsId , owner } = props.match.params;
|
||||
|
||||
useEffect(() => {
|
||||
if (repo_id) {
|
||||
const url = `/repositories/${repo_id}/tags.json`;
|
||||
if (projectsId) {
|
||||
const url = `/${owner}/${projectsId}/tags.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
setSpin(false);
|
||||
|
@ -24,7 +23,7 @@ export default ({
|
|||
console.log(error);
|
||||
})
|
||||
}
|
||||
}, [repo_id]);
|
||||
}, [owner, projectsId]);
|
||||
|
||||
return (
|
||||
<div className="main">
|
||||
|
@ -49,7 +48,7 @@ export default ({
|
|||
<span className="font-16">{item.name}</span>
|
||||
</span>
|
||||
<span className="ul_tbody_third">
|
||||
<span className="commitKey" style={{ "marginLeft": 0 }}>{truncateCommitId(`${item.id}`)}</span>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.id}`)}`} className="commitKey" style={{ "marginLeft": 0 }}>{truncateCommitId(`${item.id}`)}</Link>
|
||||
</span>
|
||||
<span className="ul_tbody_forth">
|
||||
<a href={item.tarball_url} style={{ color: "#4CC1DA" }} className="mr30"><i className="iconfont icon-TAR font-18 mr5"></i>TAR</a>
|
||||
|
@ -67,4 +66,4 @@ export default ({
|
|||
</Spin>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
|
@ -114,6 +114,10 @@ const TrendsIndex = Loadable({
|
|||
loading: Loading,
|
||||
})
|
||||
|
||||
const DevAbout = Loadable({
|
||||
loader: () => import('../About/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
const DevIndex = Loadable({
|
||||
loader: () => import('../DevOps/Index'),
|
||||
loading: Loading,
|
||||
|
@ -121,7 +125,27 @@ const DevIndex = Loadable({
|
|||
/**
|
||||
* permission:Manager:管理员,Reporter:报告人员(只有读取权限),Developer:开发人员(除不能设置仓库信息外)
|
||||
*/
|
||||
|
||||
function checkPathname(pathname){
|
||||
let name = "";
|
||||
if(pathname){
|
||||
if(pathname.indexOf("/about")>-1){
|
||||
name="about"
|
||||
}else if(pathname.indexOf("/issues")>-1 ||pathname.indexOf("Milepost") > 0){
|
||||
name = "issues";
|
||||
}else if(pathname.indexOf("/pulls")>-1){
|
||||
name="pulls"
|
||||
}else if(pathname.indexOf("/milestones")>-1){
|
||||
name="milestones"
|
||||
}else if(pathname.indexOf("/activity")>-1){
|
||||
name="activity"
|
||||
}else if(pathname.indexOf("/setting")>-1){
|
||||
name="setting"
|
||||
}else if(pathname.indexOf("/devops")>-1){
|
||||
name="devops"
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
class Detail extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -143,6 +167,12 @@ class Detail extends Component {
|
|||
project: null,
|
||||
firstSync:false,
|
||||
secondSync:false,
|
||||
open_devops:false,
|
||||
// 默认分支
|
||||
defaultBranch:undefined,
|
||||
|
||||
// 非本平台项目
|
||||
platform:false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,19 +181,35 @@ class Detail extends Component {
|
|||
}
|
||||
|
||||
componentDidUpdate = (prevState) => {
|
||||
if ((prevState.match.params.projectsId !== this.props.match.params.projectsId)) {
|
||||
let prevParam = prevState.match.params;
|
||||
let propsParam = this.props.match.params;
|
||||
if (prevState && this.props && (prevParam.projectsId !== propsParam.projectsId || prevParam.owner !== propsParam.owner)) {
|
||||
this.getProject();
|
||||
}
|
||||
}
|
||||
|
||||
getProject = (num) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/simple.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/simple.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
this.setState({
|
||||
project: result.data
|
||||
project: result.data,
|
||||
open_devops:result.data.open_devops,
|
||||
platform:result.data.platform && result.data.platform !== 'educoder'
|
||||
})
|
||||
|
||||
// 工作流:两种状态进入的链接不同
|
||||
const pathname = this.props.history.location.pathname;
|
||||
let p = checkPathname(pathname);
|
||||
if(p==="devops"){
|
||||
if(result.data.open_devops && pathname === `/projects/${owner}/${projectsId}/devops`){
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/devops/list`);
|
||||
}else if(result.data.open_devops===false && pathname !== `/projects/${owner}/${projectsId}/devops`){
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/devops`);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.data.type !== 0 && result.data.mirror_status === 1) {
|
||||
console.log("--------start channel --------");
|
||||
// 是镜像项目,且未完成迁移
|
||||
|
@ -189,6 +235,13 @@ class Detail extends Component {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 工作流激活后修改状态
|
||||
changeOpenDevops=(flag)=>{
|
||||
this.setState({
|
||||
open_devops:flag
|
||||
})
|
||||
}
|
||||
canvasChannel = () => {
|
||||
const name = window.location.hostname === "localhost" ? "testforgeplus.trustie.net" : window.location.hostname;
|
||||
const actioncable = require("actioncable");
|
||||
|
@ -204,7 +257,6 @@ class Detail extends Component {
|
|||
disconnected: () => { },
|
||||
received: data => {
|
||||
console.log(`###### ---received data--- ######`);
|
||||
console.log(data);
|
||||
if (data) {
|
||||
this.getDetail();
|
||||
cable.subscriptions.consumer.disconnect();
|
||||
|
@ -214,14 +266,14 @@ class Detail extends Component {
|
|||
}
|
||||
|
||||
getDetail = () => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/repositories/${projectsId}.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
if (result && result.data) {
|
||||
this.setState({
|
||||
projectDetail: result.data,
|
||||
project_id: result.data.project_id,
|
||||
isManager: result.data.permission && result.data.permission === "Manager",
|
||||
isManager: result.data.permission && (result.data.permission === "Manager" || result.data.permission === "Admin" || result.data.permission === "Owner"),
|
||||
isReporter: result.data.permission && result.data.permission === "Reporter",
|
||||
isDeveloper: result.data.permission && result.data.permission === "Developer",
|
||||
http_url: result.data.clone_url,
|
||||
|
@ -231,6 +283,7 @@ class Detail extends Component {
|
|||
watchers_count: result.data.watchers_count,
|
||||
praises_count: result.data.praises_count,
|
||||
forked_count: result.data.forked_count,
|
||||
defaultBranch:result.data.default_branch
|
||||
})
|
||||
}
|
||||
}).catch((error) => { })
|
||||
|
@ -238,8 +291,10 @@ class Detail extends Component {
|
|||
|
||||
// 关注和取消关注
|
||||
focusFunc = (flag) => {
|
||||
const { project_id } = this.state;
|
||||
const { platform } = this.state;
|
||||
if(!platform)return;
|
||||
|
||||
const { project_id } = this.state;
|
||||
axios({
|
||||
method: flag ? 'delete' : 'post',
|
||||
url: `/watchers/${flag ? 'unfollow' : 'follow'}.json`,
|
||||
|
@ -247,32 +302,32 @@ class Detail extends Component {
|
|||
target_type: "project",
|
||||
id: project_id
|
||||
}
|
||||
}).then(result => {
|
||||
if (result && result.data.status === 0) {
|
||||
this.setWatchersCount(result.data.watchers_count, result.data.watched);
|
||||
}
|
||||
})
|
||||
.then(result => {
|
||||
if (result && result.data.status === 0) {
|
||||
this.setWatchersCount(result.data.watchers_count, result.data.watched);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
// 点赞和取消点赞
|
||||
pariseFunc = (flag) => {
|
||||
const { platform } = this.state;
|
||||
if(!platform)return;
|
||||
const { project_id } = this.state;
|
||||
axios({
|
||||
method: flag ? 'delete' : 'post',
|
||||
url: `/projects/${project_id}/praise_tread/${flag ? 'unlike' : 'like'}.json`
|
||||
}).then(result => {
|
||||
if (result && result.data.status === 0) {
|
||||
this.setPraisesCount(result.data.praises_count, result.data.praised)
|
||||
}
|
||||
})
|
||||
.then(result => {
|
||||
if (result && result.data.status === 0) {
|
||||
this.setPraisesCount(result.data.praises_count, result.data.praised)
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
setWatchersCount = (count, is_watched) => {
|
||||
|
@ -291,11 +346,14 @@ class Detail extends Component {
|
|||
|
||||
// fork项目
|
||||
forkFunc = () => {
|
||||
const { project_id } = this.state;
|
||||
const url = `/projects/${project_id}/forks.json`;
|
||||
const { platform } = this.state;
|
||||
if(!platform)return;
|
||||
const { current_user } = this.props
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/forks.json`;
|
||||
axios.post(url).then(result => {
|
||||
if (result && result.data.status === 0) {
|
||||
this.props.history.push(`/projects/${result.data.id}/coders`);
|
||||
this.props.history.push(`/projects/${current_user && current_user.login}/${result.data.identifier}`);
|
||||
this.props.showNotification(result.data.message);
|
||||
}
|
||||
}).catch(error => {
|
||||
|
@ -303,11 +361,12 @@ class Detail extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
// 同步镜像
|
||||
synchronismMirror = () => {
|
||||
const { repo_id } = this.state.projectDetail;
|
||||
const url = `/repositories/${repo_id}/sync_mirror.json`;
|
||||
const { platform } = this.state;
|
||||
if(!platform)return;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/sync_mirror.json`;
|
||||
axios.post(url).then(result => {
|
||||
if (result && result.data && result.data.status === 0) {
|
||||
this.getProject(2);
|
||||
|
@ -319,48 +378,55 @@ class Detail extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
const { projectDetail, watchers_count, praises_count, forked_count, firstSync , secondSync , isManager, watched, praised, project } = this.state;
|
||||
const { projectDetail, watchers_count, praises_count,
|
||||
forked_count, firstSync , secondSync ,
|
||||
isManager, watched, praised,
|
||||
project , open_devops , platform , defaultBranch } = this.state;
|
||||
const url = this.props.history.location.pathname;
|
||||
const urlArr = url.split("/");
|
||||
const urlFlag = (urlArr.length === 3);
|
||||
let pathname = checkPathname(url);
|
||||
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
|
||||
const { state } = this.props.history.location;
|
||||
const { current_user } = this.props;
|
||||
const checkLogin = current_user && current_user.login;
|
||||
|
||||
const text = (
|
||||
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
||||
<React.Fragment>
|
||||
<span>forked from </span>
|
||||
<Link to={`/users/${projectDetail.fork_info.fork_project_user_login}`} className="show-user-link color-grey-ccc">{projectDetail.fork_info.fork_project_user_name}</Link>
|
||||
<span> / </span>
|
||||
<Link to={`/projects/${projectDetail.forked_from_project_id}/coders`} className="color-grey-ccc">{projectDetail.fork_info.fork_form_name}</Link>
|
||||
<Link to={`/projects/${projectDetail.fork_info.fork_project_user_login}/${projectDetail.fork_info.fork_project_identifier}`} className="color-grey-ccc">{projectDetail.fork_info.fork_form_name}</Link>
|
||||
</React.Fragment> : ""
|
||||
);
|
||||
|
||||
|
||||
const common = {
|
||||
getDetail: this.getDetail
|
||||
getDetail: this.getDetail,
|
||||
changeOpenDevops:this.changeOpenDevops,
|
||||
defaultBranch
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<div className="detailHeader-wrapper">
|
||||
<div className="normal">
|
||||
<div className="f-wrap-between pb15" style={{ position: "relative" }}>
|
||||
<p className="font-22 color-white df flex-1 lineH2 mt15" style={{ alignItems: "center" }}>
|
||||
<p className="font-22 df flex-1 lineH2 mt15" style={{ alignItems: "center" }}>
|
||||
{project && project.author &&
|
||||
<Link to={`/users/${project.author.login}`} className="show-user-link color-white">
|
||||
<Link to={`/users/${project.author.login}`} className="show-user-link">
|
||||
{project.author.name}
|
||||
</Link>
|
||||
}
|
||||
<span className="ml5 mr5">/</span>
|
||||
<span className="hide-1 flex-1 df">
|
||||
<Link to={`/projects/${projectsId}/coders`} className="color-white font-22">{project && project.name}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}`} className="font-22">{project && project.name}</Link>
|
||||
{
|
||||
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
||||
<Tooltip placement={'right'} title={text}>
|
||||
<Link to={`/projects/${projectDetail.forked_from_project_id}/coders`}
|
||||
<Link to={`/projects/${projectDetail.fork_info.fork_project_user_login}/${projectDetail.fork_info.fork_project_identifier}`}
|
||||
className="ml10" >
|
||||
<i className="iconfont icon-fork font-18 fl mt6" style={{ color: "#8D90E3" }}></i>
|
||||
</Link>
|
||||
|
@ -371,10 +437,11 @@ class Detail extends Component {
|
|||
projectDetail.type === 2 ?
|
||||
<Tooltip title={"镜像自: " + projectDetail.mirror_url} className="ml5" placement={'right'}>
|
||||
<i className="iconfont icon-banbenku font-18 mt6" style={{ color: "#8D90E3" }}/>
|
||||
</Tooltip>:
|
||||
</Tooltip>
|
||||
:
|
||||
<Tooltip title={"镜像自: " + projectDetail.mirror_url} className="ml5" placement={'right'}>
|
||||
<i className="iconfont icon-jingxiang font-18 color-green mt6" />
|
||||
</Tooltip>
|
||||
<i className="iconfont icon-jingxiang font-18 color-green mt6" />
|
||||
</Tooltip>
|
||||
:""
|
||||
}
|
||||
</span>
|
||||
|
@ -387,77 +454,113 @@ class Detail extends Component {
|
|||
<a className="synchronism ml30" onClick={this.synchronismMirror}>同步镜像</a> : ""
|
||||
}
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={() => this.focusFunc(watched)}>
|
||||
<img src={watched ? img_focused : img_focus} alt="" width="14px" />
|
||||
{watched ? '取消关注' : '关注'}
|
||||
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={() => this.focusFunc(watched)}>
|
||||
<i className={watched ? "iconfont icon-shixing color-orange font-16 mr3":"iconfont icon-kongxing color-grey-9 font-16 mr3"}></i>
|
||||
<span>{watched ? '取消关注' : '关注'}</span>
|
||||
</a>
|
||||
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${projectsId}/watch_users`, state }}>
|
||||
{watchers_count}
|
||||
</Link>
|
||||
{
|
||||
platform ?
|
||||
<Link className="detail_tag_btn_count" style={{color:`${watched?"#2878FF":"#666"}`}} to={platform?{ pathname: `/projects/${owner}/${projectsId}/watchers`, state }:""}>
|
||||
{watchers_count}
|
||||
</Link>
|
||||
:
|
||||
<span className="detail_tag_btn_count">{watchers_count}</span>
|
||||
}
|
||||
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={() => this.pariseFunc(praised)}>
|
||||
<img src={praised ? img_parised : img_parise} width="13px" alt="" />
|
||||
{praised ? '取消点赞' : '点赞'}
|
||||
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={() => this.pariseFunc(praised)}>
|
||||
<i className={praised ? "iconfont icon-weibiaoti105 color-orange font-14 mr3":"iconfont icon-guanzhu color-grey-9 font-14 mr3"}></i>
|
||||
<span>{praised ? '取消点赞' : '点赞'}</span>
|
||||
</a>
|
||||
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${projectsId}/praise_users`, state }}>
|
||||
{praises_count}
|
||||
</Link>
|
||||
{
|
||||
platform ?
|
||||
<Link className="detail_tag_btn_count" style={{color:`${praised?"#2878FF":"#666"}`}} to={{ pathname: `/projects/${owner}/${projectsId}/stargazers`, state }}>
|
||||
{praises_count}
|
||||
</Link>:
|
||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||
}
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={this.forkFunc}>
|
||||
<img src={img_fork} alt="" width="10px" />Fork</a>
|
||||
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${projectsId}/fork_users`, state }}>
|
||||
{forked_count}
|
||||
</Link>
|
||||
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={this.forkFunc}>
|
||||
<i className="iconfont icon-fork color-grey-9 mr3"></i>Fork
|
||||
</a>
|
||||
{
|
||||
platform ?
|
||||
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${owner}/${projectsId}/fork_users`, state }}>
|
||||
{forked_count}
|
||||
</Link>
|
||||
:
|
||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||
}
|
||||
</span>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
{
|
||||
firstSync ? "" :
|
||||
<div className="f-wrap-between pb20">
|
||||
<div className="f-wrap-between mt15">
|
||||
<ul className="headerMenu-wrapper">
|
||||
<li className={(url.indexOf("coders") > -1 || urlFlag) ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${projectsId}/coders`, state }}>
|
||||
<img alt="" src={img_1} width="18" />代码库
|
||||
<li className={pathname==="about" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/about`, state }}>
|
||||
<i className={(pathname==="" || urlFlag) ? "iconfont icon-zhuye1 color-grey-3 mr5 font-14":"iconfont icon-zhuye1 color-grey-6 font-14 mr5"}></i>
|
||||
<span>主页</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className={(url.indexOf("/orders") > -1 && !(url.indexOf("Milepost") > 0 || url.indexOf("meilpost") > 0 || url.indexOf("tags") > 0)) ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${projectsId}/orders`, state }}>
|
||||
<img alt="" src={img_2} width="12" />任务
|
||||
{projectDetail && projectDetail.issues_count ? <span>{projectDetail.issues_count}</span> : ""}
|
||||
<li className={(pathname==="" || urlFlag) ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}`, state }}>
|
||||
<i className={(pathname==="" || urlFlag) ? "iconfont icon-daimaku color-grey-3 mr5 font-14":"iconfont icon-daimaku color-grey-6 font-14 mr5"}></i>
|
||||
<span>代码库</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className={pathname==="issues" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/issues`, state }}>
|
||||
<i className={pathname==="issues" ? "iconfont icon-renwu color-grey-3 mr5 font-14":"iconfont icon-renwu color-grey-6 font-14 mr5"}></i>
|
||||
<span>任务</span>
|
||||
{projectDetail && projectDetail.issues_count ? <span className="num">{projectDetail.issues_count}</span> : ""}
|
||||
</Link>
|
||||
</li>
|
||||
{
|
||||
projectDetail && parseInt(projectDetail.type) !== 2 &&
|
||||
<li className={url.indexOf("merge") > -1 ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${projectsId}/merge`, state }}>
|
||||
<img alt="" src={img_3} width="13" />合并请求
|
||||
{projectDetail && projectDetail.pull_requests_count ? <span>{projectDetail.pull_requests_count}</span> : ""}
|
||||
projectDetail && parseInt(projectDetail.type) !== 2 && platform &&
|
||||
<li className={pathname==="pulls" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/pulls`, state }}>
|
||||
<i className={pathname==="pulls" ? "iconfont icon-hebingqingqiu1 color-grey-3 mr5 font-14":"iconfont icon-hebingqingqiu1 color-grey-6 font-14 mr5"}></i>
|
||||
<span>合并请求</span>
|
||||
{projectDetail && projectDetail.pull_requests_count ? <span className="num">{projectDetail.pull_requests_count}</span> : ""}
|
||||
</Link>
|
||||
</li>
|
||||
}
|
||||
{/* <li className={url.indexOf("/ops") > -1 ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${projectsId}/ops`, state }}>
|
||||
<i className="iconfont icon-gongzuoliu font-13 mr8"></i>工作流
|
||||
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
|
||||
</Link>
|
||||
</li> */}
|
||||
<li className={(url.indexOf("/Milepost") > -1 || url.indexOf("meilpost") > -1) ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${projectsId}/orders/Milepost`, state }}>
|
||||
<img alt="" src={img_milepost} width="16" />里程碑
|
||||
{projectDetail && projectDetail.versions_count ? <span>{projectDetail.versions_count}</span> :""}
|
||||
{
|
||||
platform &&
|
||||
<li className={pathname==="devops" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/devops${open_devops ? `/list`:""}`, state }}>
|
||||
<i className="iconfont icon-gongzuoliu font-13 mr8"></i>工作流(beta版)
|
||||
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
|
||||
</Link>
|
||||
</li>
|
||||
}
|
||||
|
||||
<li className={pathname==="milestones" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/milestones`, state }}>
|
||||
<i className={pathname==="milestones" ? "iconfont icon-lichengbei color-grey-3 mr5 font-14":"iconfont icon-lichengbei color-grey-6 font-14 mr5"}></i>
|
||||
<span>里程碑</span>
|
||||
{projectDetail && projectDetail.versions_count ? <span className="num">{projectDetail.versions_count}</span> :""}
|
||||
</Link>
|
||||
</li>
|
||||
<li className={url.indexOf("/trends") > -1 ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${projectsId}/trends`, state }}>
|
||||
<img alt="" src={img_6} width="16" />动态
|
||||
</Link>
|
||||
<li className={pathname==="activity" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/activity`, state }}>
|
||||
<i className={pathname==="activity" ? "iconfont icon-tongzhi color-grey-3 mr5 font-14":"iconfont icon-tongzhi color-grey-6 font-14 mr5"}></i>
|
||||
<span>动态</span>
|
||||
</Link>
|
||||
</li>
|
||||
{
|
||||
isManager &&
|
||||
<li className={url.indexOf("/setting") > 0 ? "active" : ""}><Link to={`/projects/${projectsId}/setting`}><img alt="" src={img_7} width="19" />仓库设置</Link></li>
|
||||
isManager && platform &&
|
||||
<li className={url.indexOf("/setting") > 0 ? "active" : ""}>
|
||||
<Link to={`/projects/${owner}/${projectsId}/setting`}>
|
||||
<i className={url.indexOf("/setting") > 0 ? "iconfont icon-cangku color-grey-3 mr5 font-14":"iconfont icon-cangku color-grey-6 font-14 mr5"}></i>
|
||||
<span>仓库设置</span>
|
||||
</Link>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -473,142 +576,153 @@ class Detail extends Component {
|
|||
:
|
||||
<Spin spinning={secondSync} className="spinstyle" tip="正在同步镜像" size="large">
|
||||
<Switch {...this.props}>
|
||||
{/* 主页 */}
|
||||
<Route path="/projects/:owner/:projectsId/about"
|
||||
render={
|
||||
() => (<DevAbout {...this.props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 工作流 */}
|
||||
<Route path="/projects/:projectsId/ops"
|
||||
<Route path="/projects/:owner/:projectsId/devops"
|
||||
render={
|
||||
() => (<DevIndex {...this.props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 标签列表 */}
|
||||
<Route path="/projects/:projectsId/orders/tags"
|
||||
<Route path="/projects/:owner/:projectsId/issues/tags"
|
||||
render={
|
||||
(props) => (<TagList {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 仓库设置 */}
|
||||
<Route path="/projects/:projectsId/setting"
|
||||
<Route path="/projects/:owner/:projectsId/setting"
|
||||
render={
|
||||
(props) => (<Setting {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 任务详情 */}
|
||||
<Route path="/projects/:projectsId/orders/:orderId/detail"
|
||||
<Route path="/projects/:owner/:projectsId/issues/:orderId/detail"
|
||||
render={
|
||||
(props) => (<OrderDetail {...this.props} {...props} {...this.state} {...common} />)
|
||||
(props) => (<OrderDetail {...this.props} {...this.state} {...props} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 里程碑 */}
|
||||
<Route path="/projects/:projectsId/orders/Milepost"
|
||||
{/*修改里程碑*/}
|
||||
<Route path="/projects/:owner/:projectsId/milestones/:meilid/edit"
|
||||
render={
|
||||
(props) => (<OrderMilepost {...this.props} {...props} {...this.state} {...common} />)
|
||||
(props) => (<OrderupdateMilepost {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 新建里程碑 */}
|
||||
<Route path="/projects/:projectsId/orders/meilpost"
|
||||
<Route path="/projects/:owner/:projectsId/milestones/new"
|
||||
render={
|
||||
(props) => (<OrdernewMilepost {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/*里程碑详情*/}
|
||||
<Route path="/projects/:projectsId/orders/:meilid/MilepostDetail"
|
||||
<Route path="/projects/:owner/:projectsId/milestones/:meilid"
|
||||
render={
|
||||
(props) => (<MilepostDetail {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/*修改里程碑*/}
|
||||
<Route path="/projects/:projectsId/orders/:meilid/meilpost"
|
||||
{/* 里程碑 */}
|
||||
<Route path="/projects/:owner/:projectsId/milestones"
|
||||
render={
|
||||
(props) => (<OrderupdateMilepost {...this.props} {...props} {...this.state} {...common} />)
|
||||
(props) => (<OrderMilepost {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 里程碑页面新建任务 */}
|
||||
<Route path="/projects/:projectsId/orders/:milepostId/new"
|
||||
<Route path="/projects/:owner/:projectsId/issues/:milepostId/new"
|
||||
render={
|
||||
(props) => (<OrderNew {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 新建任务 */}
|
||||
<Route path="/projects/:projectsId/orders/new"
|
||||
<Route path="/projects/:owner/:projectsId/issues/new"
|
||||
render={
|
||||
(props) => (<OrderNew {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 修改详情 */}
|
||||
<Route path="/projects/:projectsId/orders/:orderId/updatedetail"
|
||||
<Route path="/projects/:owner/:projectsId/issues/:orderId/updatedetail"
|
||||
render={
|
||||
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 复制详情 */}
|
||||
<Route path="/projects/:projectsId/orders/:orderId/copyetail"
|
||||
<Route path="/projects/:owner/:projectsId/issues/:orderId/copyetail"
|
||||
render={
|
||||
(props) => (<OrdercopyDetail {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 动态 */}
|
||||
<Route path="/projects/:projectsId/trends"
|
||||
<Route path="/projects/:owner/:projectsId/activity"
|
||||
render={
|
||||
(props) => (<TrendsIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 代码Index */}
|
||||
<Route path="/projects/:projectsId/orders"
|
||||
<Route path="/projects/:owner/:projectsId/issues"
|
||||
render={
|
||||
(props) => (<OrderIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/merge/new"
|
||||
<Route path="/projects/:owner/:projectsId/pulls/new"
|
||||
render={
|
||||
(props) => (<CreateMerge {...this.props} {...props} {...this.state} {...common} is_fork={true} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/merge/:mergeId/UpdateMerge"
|
||||
<Route path="/projects/:owner/:projectsId/pulls/:mergeId/UpdateMerge"
|
||||
render={
|
||||
(props) => (<UpdateMerge {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/merge/:mergeId/Messagecount"
|
||||
<Route path="/projects/:owner/:projectsId/pulls/:mergeId/Messagecount"
|
||||
render={
|
||||
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/merge/:mergeId/MergeSubmit"
|
||||
<Route path="/projects/:owner/:projectsId/pulls/:mergeId/MergeSubmit"
|
||||
render={
|
||||
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
|
||||
<Route path="/projects/:projectsId/merge"
|
||||
<Route path="/projects/:owner/:projectsId/pulls"
|
||||
render={
|
||||
(props) => (<MergeIndexDetail {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coders/filesurl"
|
||||
<Route path="/projects/:owner/:projectsId/coders/filesurl"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coders"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/watch_users"
|
||||
<Route path="/projects/:owner/:projectsId/watchers"
|
||||
render={
|
||||
(props) => (<WatchUsers {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/praise_users"
|
||||
<Route path="/projects/:owner/:projectsId/stargazers"
|
||||
render={
|
||||
(props) => (<PraiseUsers {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/fork_users"
|
||||
<Route path="/projects/:owner/:projectsId/fork_users"
|
||||
render={
|
||||
(props) => (<ForkUsers {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId"
|
||||
<Route path="/projects/:owner/:projectsId/commits/branch/:branchName"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:owner/:projectsId/branch/:branchName"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:owner/:projectsId"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
|
|
|
@ -3,27 +3,53 @@ import { Link } from 'react-router-dom';
|
|||
|
||||
class DetailTop extends Component {
|
||||
render() {
|
||||
const { coderCount } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { coderCount , platform } = this.props;
|
||||
const { projectsId, owner } = this.props.match.params;
|
||||
const { pathname } = this.props.location;
|
||||
return (
|
||||
<p className="branch-wrapper">
|
||||
<Link to={`/projects/${projectsId}/coders/commit`} className={pathname.indexOf("/coders/commit") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-tijiaojilu font-20 mr3 font-bd"></i>
|
||||
<span>{(coderCount && coderCount.commits_count) || 0}</span>个提交
|
||||
</Link>
|
||||
<Link to={`/projects/${projectsId}/coders/branch`} className={pathname.indexOf("/coders/branch") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-fenzhi1 font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.branches_count) || 0}</span>个分支
|
||||
</Link>
|
||||
<Link to={`/projects/${projectsId}/coders/tag`} className={pathname.indexOf("/coders/tag") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-biaoqian3 font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.tags_count) || 0}</span>个标签
|
||||
</Link>
|
||||
<Link to={`/projects/${projectsId}/coders/version`} className={pathname.indexOf("/coders/version") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-fahangban font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.version_releasesed_count) || 0}</span>个发行版
|
||||
</Link>
|
||||
|
||||
{
|
||||
platform ?
|
||||
<React.Fragment>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits`} className={pathname.indexOf("/commits") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-tijiaojilu font-20 mr3 font-bd"></i>
|
||||
<span>{(coderCount && coderCount.commits_count) || 0}</span>个提交
|
||||
</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/branchs`} className={pathname.indexOf("/branchs") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-fenzhi1 font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.branches_count) || 0}</span>个分支
|
||||
</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/tag`} className={pathname.indexOf("/tag") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-biaoqian3 font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.tags_count) || 0}</span>个标签
|
||||
</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/releases`} className={pathname.indexOf("/releases") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-fahangban font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.version_releasesed_count) || 0}</span>个发行版
|
||||
</Link>
|
||||
</React.Fragment>
|
||||
:
|
||||
<React.Fragment>
|
||||
<a href="javscript:void(0)" style={{cursor:"default"}}>
|
||||
<i className="iconfont icon-tijiaojilu font-20 mr3 font-bd"></i>
|
||||
<span>{(coderCount && coderCount.commits_count) || 0}</span>个提交
|
||||
</a>
|
||||
<a href="javscript:void(0)" style={{cursor:"default"}}>
|
||||
<i className="iconfont icon-fenzhi1 font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.branches_count) || 0}</span>个分支
|
||||
</a>
|
||||
<a href="javscript:void(0)" style={{cursor:"default"}}>
|
||||
<i className="iconfont icon-biaoqian3 font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.tags_count) || 0}</span>个标签
|
||||
</a>
|
||||
<a href="javscript:void(0)" style={{cursor:"default"}}>
|
||||
<i className="iconfont icon-fahangban font-18 mr3"></i>
|
||||
<span>{(coderCount && coderCount.version_releasesed_count) || 0}</span>个发行版
|
||||
</a>
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
<a href="javscript:void(0)" style={{cursor:"default"}}>
|
||||
<i className="iconfont icon-cangku font-18 mr3"></i>
|
||||
仓库 <span className="ml3">{(coderCount && coderCount.size) || 0}</span>
|
||||
|
|
|
@ -2,7 +2,8 @@ import React, { useEffect, useState } from "react";
|
|||
import styled from "styled-components";
|
||||
import { Button ,Spin } from "antd";
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import Nodata from '../Nodata';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import Files from '../Merge/Files';
|
||||
|
||||
import User from "../Component/User";
|
||||
import Keys from "../Component/Keys";
|
||||
|
@ -11,65 +12,34 @@ import axios from "axios";
|
|||
|
||||
const Infos = styled.div`
|
||||
border: 1px solid #dddddd;
|
||||
margin-bottom:15px;
|
||||
& .commitinfos {
|
||||
background-color: #f1f8ff;
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 20px;
|
||||
}
|
||||
& > .f-wrap-between {
|
||||
padding: 10px 24px;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
`;
|
||||
const Operation = styled.p`
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 12px 0px;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const FileUl = styled.ul`
|
||||
padding-top: 10px;
|
||||
& li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
`;
|
||||
const DetailP = styled.p`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 20px 12px 12px;
|
||||
background-color: #fafafa;
|
||||
border: 1px solid #dddddd;
|
||||
`;
|
||||
|
||||
export default ({ projectDetail, match }) => {
|
||||
export default ({ match , history }) => {
|
||||
const [data, setData] = useState({undefined});
|
||||
const [commit, setCommit] = useState(undefined);
|
||||
const [files, setFiles] = useState(undefined);
|
||||
const [parents, setParents] = useState(undefined);
|
||||
const [committer, setCommitter] = useState(undefined);
|
||||
const [fileflag , setFileflag] = useState(false);
|
||||
const [isSpin, setIsSpin] = useState(true);
|
||||
|
||||
const repo_id = projectDetail && projectDetail.repo_id;
|
||||
const { sha } = match.params;
|
||||
const { sha , projectsId, owner } = match.params;
|
||||
useEffect(() => {
|
||||
if (repo_id && sha) {
|
||||
const url = `/repositories/${repo_id}/commits/${sha}.json`;
|
||||
if (projectsId && owner && sha) {
|
||||
const url = `/${owner}/${projectsId}/commits/${sha}.json`;
|
||||
axios
|
||||
.get(url)
|
||||
.then(result => {
|
||||
if (result) {
|
||||
setData(result.data);
|
||||
setCommit(result.data.commit);
|
||||
setFiles(result.data.files);
|
||||
setParents(result.data.parents);
|
||||
setCommitter(result.data.committer || (result.data.commit && result.data.commit.committer));
|
||||
setIsSpin(false);
|
||||
|
@ -79,78 +49,32 @@ export default ({ projectDetail, match }) => {
|
|||
console.log(error);
|
||||
});
|
||||
}
|
||||
}, [repo_id, sha]);
|
||||
const renderFiles = () => {
|
||||
return (
|
||||
<FileUl>
|
||||
{
|
||||
files && files.length > 0 && files.map((item,key)=>{
|
||||
return(
|
||||
<li>
|
||||
<span className="mr30 task-hide flex1">
|
||||
<i className="iconfont icon-wenjia color-grey-3 font-16 mr8"></i>
|
||||
{item.Name}
|
||||
</span>
|
||||
<span>
|
||||
<label className="color-green mr20">+{item.Addition}</label>
|
||||
<label className="color-red">-{item.Deletion}</label>
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</FileUl>
|
||||
);
|
||||
};
|
||||
|
||||
function changeFlag(){
|
||||
let flag = !fileflag;
|
||||
setFileflag(flag);
|
||||
}
|
||||
|
||||
const filesDetail = () => {
|
||||
return (
|
||||
<div>
|
||||
<DetailP>
|
||||
<span>
|
||||
<i className="iconfont icon-youjiantou mr4 font-15 color-grey-9"></i>
|
||||
<span className="font-16 color-grey-3">README.md</span>
|
||||
</span>
|
||||
<Button>查看文件</Button>
|
||||
</DetailP>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
}, [projectsId , owner, sha]);
|
||||
return (
|
||||
<div className="main">
|
||||
<Spin spinning={isSpin}>
|
||||
<Infos>
|
||||
<div className="commitinfos">
|
||||
<p className="f-wrap-between">
|
||||
<span className="font-20 color-grey-3">
|
||||
{ commit && commit.title }
|
||||
</span>
|
||||
<Button type="primary">浏览代码</Button>
|
||||
</p>
|
||||
{commit && commit.message ? (
|
||||
<pre className="mt10">{commit.message}</pre>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<div className="f-wrap-between">
|
||||
{commit && commit.message &&
|
||||
<pre className="task-hide" style={{marginBottom:"0px",height:"28px",whiteSpace:"pre-wrap"}}>{commit.message}</pre>
|
||||
}
|
||||
<Button type="primary" onClick={()=>{history.push(`/projects/${owner}/${projectsId}/branch/${truncateCommitId(sha)}`)}} className="ml30">浏览代码</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="f-wrap-between" style={{ alignItems: "center" }}>
|
||||
<ul className="df">
|
||||
<User
|
||||
url={(committer && committer.image_url)|| "https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3025493530,1989042357&fm=26&gp=0.jpg"}
|
||||
url={(committer && getImageUrl(`images/${committer.image_url}`))|| "https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3025493530,1989042357&fm=26&gp=0.jpg"}
|
||||
name={committer && committer.name}
|
||||
/>
|
||||
{committer && committer.time_from_now && <li className="ml20 mt2">{committer.time_from_now}</li>}
|
||||
</ul>
|
||||
<li className="df">
|
||||
{
|
||||
parents && parents.length > 0 && parents.map((item,key)=>{
|
||||
return(
|
||||
<Keys title="父节点" value={truncateCommitId(item.sha) } className="mr20"></Keys>
|
||||
<Keys title="父节点" value={truncateCommitId(item.sha)} key={key} className="mr20"></Keys>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -158,35 +82,12 @@ export default ({ projectDetail, match }) => {
|
|||
</li>
|
||||
</div>
|
||||
</Infos>
|
||||
{
|
||||
files && files.length > 0 ?
|
||||
<React.Fragment>
|
||||
<Operation>
|
||||
<span className="files_info" onClick={changeFlag}>
|
||||
<i className={fileflag ? "iconfont icon-sanjiaoxing-down mr8 color-grey-9 font-16":"iconfont icon-triangle mr8 color-grey-9 font-16"}></i>
|
||||
<span className="color-grey-9">
|
||||
共有<span>{files && files.length}个文件被更改</span>,包括
|
||||
{data && data.additions ? (
|
||||
<span className="color-green">{data.additions}次插入</span>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{data && data.additions && data.deletions ? "和" : ""}
|
||||
{data && data.deletions ? (
|
||||
<span className="color-red">{data.deletions}次删除</span>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</span>
|
||||
</span>
|
||||
<Button>双栏查看</Button>
|
||||
</Operation>
|
||||
{fileflag && renderFiles()}
|
||||
{filesDetail()}
|
||||
</React.Fragment>
|
||||
:
|
||||
<Nodata _html="暂无文件修改信息!"/>
|
||||
}
|
||||
<Files
|
||||
history={history}
|
||||
data={data}
|
||||
owner={owner}
|
||||
projectsId={projectsId}
|
||||
/>
|
||||
</Spin>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Menu, Input , Spin, Pagination , Popover } from 'antd';
|
||||
import { Menu, Input , Spin, Pagination , Popover , Select } from 'antd';
|
||||
import { getUrl } from 'educoder';
|
||||
import '../css/index.scss'
|
||||
import './list.css';
|
||||
import './Index.scss';
|
||||
import ListItem from './IndexItem'
|
||||
import axios from 'axios';
|
||||
import img_new from '../Images/new.png';
|
||||
import img_array from '../Images/array.png';
|
||||
|
||||
import banner from '../Images/banner_list.jpg';
|
||||
const Search = Input.Search;
|
||||
|
||||
class Index extends Component {
|
||||
|
@ -25,22 +27,53 @@ class Index extends Component {
|
|||
category_id: undefined,
|
||||
|
||||
typeList: undefined,
|
||||
categoryList: undefined
|
||||
categoryList: undefined,
|
||||
recommendList:undefined,
|
||||
|
||||
languageList:undefined,
|
||||
languageId:undefined
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
const { page, limit, search, sort, project_type, category_id } = this.state;
|
||||
this.getListData(page, limit, search, sort, project_type, category_id);
|
||||
const { page, limit, search, sort, project_type, category_id , languageId } = this.state;
|
||||
this.getListData(page, limit, search, sort, project_type, category_id , languageId);
|
||||
|
||||
this.getType();
|
||||
|
||||
this.getCategory();
|
||||
|
||||
this.getRecommand();
|
||||
|
||||
this.getLanguage();
|
||||
}
|
||||
|
||||
// 获取语言列表
|
||||
getLanguage=()=>{
|
||||
const url = '/project_languages.json';
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
languageList:result.data.project_languages
|
||||
})
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
// 获取推荐列表
|
||||
getRecommand=()=>{
|
||||
const url = `/projects/recommend.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
recommendList:result.data
|
||||
})
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
// 获取列表
|
||||
getListData = (page, limit, search, sort, project_type, category_id) => {
|
||||
getListData = (page, limit, search, sort, project_type, category_id,languageId) => {
|
||||
const { current_user } = this.props;
|
||||
const url = `/projects.json`;
|
||||
axios.get(url, {
|
||||
|
@ -51,7 +84,8 @@ class Index extends Component {
|
|||
search,
|
||||
sort_by: sort,
|
||||
project_type,
|
||||
category_id
|
||||
category_id,
|
||||
language_id:languageId
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
|
@ -97,8 +131,8 @@ class Index extends Component {
|
|||
search: undefined
|
||||
})
|
||||
this.setTypeList(list, type)
|
||||
const { page, limit, sort, category_id } = this.state;
|
||||
this.getListData(page, limit, undefined, sort, type, category_id);
|
||||
const { page, limit, sort, category_id , languageId } = this.state;
|
||||
this.getListData(page, limit, undefined, sort, type, category_id , languageId);
|
||||
}
|
||||
|
||||
// 获取类型
|
||||
|
@ -133,8 +167,8 @@ class Index extends Component {
|
|||
page: 1
|
||||
});
|
||||
this.setCategoryList(list, id)
|
||||
const { limit, sort, project_type } = this.state;
|
||||
this.getListData(1, limit, undefined, sort, project_type, id);
|
||||
const { limit, sort, project_type , languageId } = this.state;
|
||||
this.getListData(1, limit, undefined, sort, project_type, id , languageId);
|
||||
}
|
||||
|
||||
// 排序
|
||||
|
@ -145,8 +179,8 @@ class Index extends Component {
|
|||
search: undefined,
|
||||
isSpin: true
|
||||
})
|
||||
const { limit, project_type, category_id } = this.state;
|
||||
this.getListData(1, limit, undefined, e.key, project_type, category_id);
|
||||
const { limit, project_type, category_id , languageId } = this.state;
|
||||
this.getListData(1, limit, undefined, e.key, project_type, category_id , languageId);
|
||||
}
|
||||
|
||||
// 搜索
|
||||
|
@ -158,8 +192,8 @@ class Index extends Component {
|
|||
project_type: undefined,
|
||||
sort: "updated_on"
|
||||
})
|
||||
const { limit, sort, category_id } = this.state;
|
||||
this.getListData(1, limit, value, sort, undefined, category_id);
|
||||
const { limit, sort, category_id , languageId } = this.state;
|
||||
this.getListData(1, limit, value, sort, undefined, category_id , languageId);
|
||||
}
|
||||
changeSearchValue = (e) => {
|
||||
this.setState({
|
||||
|
@ -171,13 +205,26 @@ class Index extends Component {
|
|||
this.setState({
|
||||
page
|
||||
})
|
||||
const { limit, search, sort, project_type, category_id } = this.state;
|
||||
this.getListData(page, limit, search, sort, project_type, category_id);
|
||||
const { limit, search, sort, project_type, category_id , languageId } = this.state;
|
||||
this.getListData(page, limit, search, sort, project_type, category_id , languageId);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { current_user } = this.props;
|
||||
const menu = (
|
||||
getoDetail=(login,identifier)=>{
|
||||
this.props.history.push(`/projects/${login}/${identifier}`);
|
||||
}
|
||||
|
||||
// 选择语言类别
|
||||
changeLanguage=(e)=>{
|
||||
this.setState({
|
||||
isSpin:true,
|
||||
languageId:e === 0 ?undefined:e
|
||||
})
|
||||
const { page, limit, sort , project_type , category_id } = this.state;
|
||||
this.getListData(page, limit, undefined, sort, project_type, category_id ,e === 0 ?undefined:e);
|
||||
}
|
||||
|
||||
menu =()=> {
|
||||
return(
|
||||
<Menu onClick={this.ChangeSoryBy}>
|
||||
<Menu.Item key="updated_on">更新时间排序</Menu.Item>
|
||||
<Menu.Item key="created_on">创建时间排序</Menu.Item>
|
||||
|
@ -185,24 +232,60 @@ class Index extends Component {
|
|||
<Menu.Item key="praises_count">点赞数量排序</Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
const newItem = (
|
||||
}
|
||||
|
||||
newItem = ()=>{
|
||||
return(
|
||||
<Menu>
|
||||
<Menu.Item key="created_mirror"><Link to={`/projects/mirror/new`}>新建镜像项目</Link></Menu.Item>
|
||||
<Menu.Item key="created_deposit"><Link to={`/projects/deposit/new`}>新建托管项目</Link></Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
|
||||
const { projectsList, isSpin, total, search, limit, page, typeList, categoryList } = this.state;
|
||||
|
||||
const pagination = (
|
||||
total && total > limit ?
|
||||
<div className="edu-txt-center pt30 mb30 border-top-grey">
|
||||
<Pagination simple defaultCurrent={page} total={total} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||||
</div> : ""
|
||||
pagination=(total,limit,page)=>{
|
||||
return(
|
||||
total && total > limit &&
|
||||
<div className="edu-txt-center pt30 mb30 border-top-grey">
|
||||
<Pagination simple defaultCurrent={page} total={total} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { current_user } = this.props;
|
||||
|
||||
const { projectsList , recommendList , languageList , languageId ,
|
||||
isSpin, total, search, limit, page, typeList, categoryList } = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p className="t_project_banner"></p>
|
||||
<p className="t_project_banner">
|
||||
<img src={banner} width="100%" alt=""/>
|
||||
</p>
|
||||
{
|
||||
recommendList && recommendList.length>0 &&
|
||||
<div className="recommandProjects">
|
||||
{
|
||||
recommendList.map((item,key)=>{
|
||||
return(
|
||||
<div onClick={()=>this.getoDetail(item.author && item.author.login,item.identifier)}>
|
||||
<div className="mainInfo">
|
||||
<img src={getUrl(`/images/${item.author && item.author.image_url}`)} alt=""/>
|
||||
<p className="school">{item.name}</p>
|
||||
<p className="name">{item.author && item.author.name}</p>
|
||||
</div>
|
||||
<div className="baseInfo">
|
||||
<span className="look"><i className="iconfont icon-dianjiliang font-12"></i>{item.visits}</span>
|
||||
<span className="type">{item.category && item.category.name}</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div className="ProjectListIndex">
|
||||
<div className="list-left">
|
||||
<ul className="list-l-Menu">
|
||||
|
@ -217,26 +300,50 @@ class Index extends Component {
|
|||
<div className="list-right boxShandow radius-2" style={{padding:0}}>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="list-r-operation">
|
||||
<Search
|
||||
placeholder="输入项目名称关键字进行搜索"
|
||||
enterButton="搜索"
|
||||
size="large"
|
||||
onSearch={this.searchFun}
|
||||
className="list-r-Search"
|
||||
value={search}
|
||||
onChange={this.changeSearchValue}
|
||||
/>
|
||||
<div>
|
||||
<Select
|
||||
showSearch
|
||||
placeholder="请选择语言"
|
||||
style={{width:"150px",marginRight:"20px"}}
|
||||
size={"large"}
|
||||
onChange={this.changeLanguage}
|
||||
value={languageId}
|
||||
allowClear={true}
|
||||
optionFilterProp="children"
|
||||
filterOption={(input,option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
|
||||
>
|
||||
<Select.Option key={0} value={0}>请选择语言</Select.Option>
|
||||
{
|
||||
languageList && languageList.length>0 && languageList.map((item,key)=>{
|
||||
return(
|
||||
<Select.Option key={item.id} value={item.id}>
|
||||
{item.name}
|
||||
</Select.Option>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Select>
|
||||
<Search
|
||||
placeholder="输入项目名称关键字进行搜索"
|
||||
enterButton="搜索"
|
||||
size="large"
|
||||
onSearch={this.searchFun}
|
||||
className="list-r-Search"
|
||||
value={search}
|
||||
onChange={this.changeSearchValue}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{
|
||||
current_user && current_user.login &&
|
||||
<Popover content={newItem} trigger={["click"]} placement='bottom' className="mr50">
|
||||
<Popover content={this.newItem()} trigger={["click"]} placement='bottom' className="mr50">
|
||||
<a className="ant-dropdown-link">
|
||||
<span className="color-blue font-16"><img src={img_new} alt="" width="13px" /> 新建</span>
|
||||
</a>
|
||||
</Popover>
|
||||
}
|
||||
|
||||
<Popover content={menu} trigger={['click']} placement='bottom'>
|
||||
<Popover content={this.menu()} trigger={['click']} placement='bottom'>
|
||||
<a className="ant-dropdown-link">
|
||||
<span className="color-blue font-16">排序 <img src={img_array} alt="" width="10px" /></span>
|
||||
</a>
|
||||
|
@ -244,7 +351,7 @@ class Index extends Component {
|
|||
</div>
|
||||
</div>
|
||||
<ListItem {...this.props} {...this.state} projects={projectsList}></ListItem>
|
||||
{pagination}
|
||||
{this.pagination(total,limit,page)}
|
||||
</Spin>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/* recommandProjects */
|
||||
.recommandProjects{
|
||||
display: flex;
|
||||
max-width: 1200px;
|
||||
margin:20px auto;
|
||||
}
|
||||
.recommandProjects >div{
|
||||
background-color: #fff;
|
||||
border-radius: 10px;
|
||||
width: 220px;
|
||||
margin-right: 25px;
|
||||
cursor: pointer;
|
||||
&:last-child{
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
.recommandProjects > div:hover{
|
||||
box-shadow: 0px 2px 20px 0px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.recommandProjects > div .mainInfo{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 160px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding:20px;
|
||||
box-sizing: border-box;
|
||||
img{
|
||||
height: 50px;
|
||||
width:50px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.name{
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
margin-top:12px;
|
||||
}
|
||||
.school{
|
||||
margin-top:12px;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
max-width:100%;
|
||||
}
|
||||
}
|
||||
.recommandProjects{
|
||||
.baseInfo{
|
||||
padding:18px 15px;
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
color:#888;
|
||||
.look{
|
||||
i{
|
||||
margin-right: 5px;
|
||||
}
|
||||
margin-right: 10px;
|
||||
}
|
||||
.type{
|
||||
flex:1;
|
||||
width:0;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Tooltip } from 'antd';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import { getImageUrl , getImage } from 'educoder';
|
||||
import { Link } from 'react-router-dom';
|
||||
import '../css/index.scss'
|
||||
import '../css/index.scss';
|
||||
import Nodata from '../Nodata';
|
||||
import './list.css';
|
||||
import img_parise from '../Images/parise.png';
|
||||
|
||||
|
@ -19,12 +20,19 @@ class IndexItem extends Component {
|
|||
projects && projects.length > 0 ? projects.map((item, key) => {
|
||||
return (
|
||||
<div className="p-r-Item" key={key}>
|
||||
<Link to={`/users/${item.author.login}`} className="show-user-link">
|
||||
<img className="p-r-photo" alt="" src={getImageUrl(`images/${item.author && item.author.image_url}`)} ></img>
|
||||
</Link>
|
||||
{
|
||||
item.platform === "educoder" ?
|
||||
<a href="javascript:void(0)" style={{cursor:"default"}} className="show-user-link">
|
||||
<img className="p-r-photo" alt="" src={item.author && item.author.image_url} ></img>
|
||||
</a>
|
||||
:
|
||||
<Link to={`/users/${item.author.login}`} className="show-user-link">
|
||||
<img className="p-r-photo" alt="" src={getImageUrl(`${item.author && item.author.image_url}`)} ></img>
|
||||
</Link>
|
||||
}
|
||||
<div className="p-r-Infos">
|
||||
<div className="p-r-name">
|
||||
<Link to={`/projects/${item.id}/coders`} className="hide-1 color-grey-3 font-18 task-hide " style={{ whiteSpace: "wrap", display: 'flex', width: 400 }}>
|
||||
<Link to={`/projects/${item.author.login}/${item.identifier}`} className="hide-1 color-grey-3 font-18 task-hide " style={{ whiteSpace: "wrap", display: 'flex', width: 400 }}>
|
||||
{item.author.name}/{item.name}
|
||||
{
|
||||
item.forked_from_project_id ?
|
||||
|
@ -45,16 +53,16 @@ class IndexItem extends Component {
|
|||
}
|
||||
</Link>
|
||||
<span className="p-r-tags">
|
||||
<span className="pariseTag"><img src={img_parise} alt="" className="pariseImg" />赞 ({item.praises_count})</span>
|
||||
<span><i className="iconfont icon-fork mr3 font-16" style={{ color: "#1B8FFF" }} />fork ({item.forked_count})</span>
|
||||
<span className="pariseTag"><img src={img_parise} alt="" className="pariseImg" />赞 {item.praises_count}</span>
|
||||
<span><i className="iconfont icon-fork mr3 font-16" style={{ color: "#1B8FFF" }} />fork {item.forked_count}</span>
|
||||
</span>
|
||||
</div>
|
||||
<p className="break_word task-hide-2 mt10" style={{ maxHeight: "44px",lineHeight:"22px" }}>{item.description}</p>
|
||||
|
||||
<div className="p-r-about">
|
||||
<span className="p-r-detail">
|
||||
<span><label>浏览量:</label>{item.visits}</span>
|
||||
{item.category && item.category.id && <span><label>项目类别:</label>{item.category.name}</span>}
|
||||
{/* <span><label>浏览量:</label>{item.visits}</span> */}
|
||||
{/* {item.category && item.category.id && <span>{item.category.name}</span>} */}
|
||||
{item.last_update_time ? <span ><label>更新于</label>{item.time_ago}</span> : ""}
|
||||
{item.language && item.language.id ? <span className="color-grey-3">{item.language.name}</span> : ""}
|
||||
</span>
|
||||
|
@ -62,7 +70,7 @@ class IndexItem extends Component {
|
|||
</div>
|
||||
</div>
|
||||
)
|
||||
}) : ""
|
||||
}) : <Nodata _html="暂无数据~"></Nodata>
|
||||
)
|
||||
return (
|
||||
<div className="project-list minH-670">
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
.lineH2{line-height:2}
|
||||
.t_project_banner {
|
||||
height: 260px;
|
||||
background: url(../Images/banner_list.png) no-repeat center;
|
||||
/* height: 260px;
|
||||
background: url(../Images/banner_list.jpg) no-repeat center; */
|
||||
background-color: #050d34;
|
||||
}
|
||||
.ProjectListIndex{
|
||||
|
@ -69,6 +69,7 @@
|
|||
color: #fff!important;
|
||||
}
|
||||
|
||||
|
||||
/* 列表 */
|
||||
.project-list{
|
||||
padding:0px 30px;
|
||||
|
@ -207,7 +208,9 @@
|
|||
}
|
||||
/* -----------详情------------ */
|
||||
.detailHeader-wrapper{
|
||||
background:linear-gradient(82deg,rgba(82,91,215,1) 0%,rgba(34,24,171,1) 100%);
|
||||
background-color:#FAFBFC;
|
||||
/* background: url(../Images/forgeBanner.jpg) no-repeat center; */
|
||||
/* background-size:cover; */
|
||||
}
|
||||
.headerMenu-wrapper{
|
||||
font-size: 16px;
|
||||
|
@ -215,39 +218,40 @@
|
|||
flex-direction: row;
|
||||
}
|
||||
.headerMenu-wrapper li{
|
||||
padding:0px 18px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
height: 40px;
|
||||
line-height: 28px;
|
||||
margin-right: 40px;
|
||||
}
|
||||
.headerMenu-wrapper li a{
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #666;
|
||||
}
|
||||
.headerMenu-wrapper li a > img{
|
||||
margin-right: 8px;
|
||||
}
|
||||
.headerMenu-wrapper li a > span{
|
||||
background-color: #676AF1;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
border-radius: 10px;
|
||||
display: block;
|
||||
padding:0px 6px;
|
||||
margin-left: 5px;
|
||||
font-size: 11px;
|
||||
.headerMenu-wrapper li a > span.num{
|
||||
height: 28px;
|
||||
line-height: 29px;
|
||||
margin-left: 8px;
|
||||
font-size: 12px;
|
||||
color: #2878FF;
|
||||
float: right;
|
||||
}
|
||||
.headerMenu-wrapper li.active{
|
||||
border-radius: 15px;
|
||||
border:1px solid #71A6FF;
|
||||
.headerMenu-wrapper li.active::after{
|
||||
position: absolute;
|
||||
bottom:0px;
|
||||
height:2px;
|
||||
background-color: #5091FF;
|
||||
content:'';
|
||||
left: 0px;
|
||||
width:100%;
|
||||
}
|
||||
.detail_tag_btn{
|
||||
height:26px;
|
||||
line-height: 26px;
|
||||
border-radius:5px;
|
||||
border:1px solid #71A6FF;
|
||||
border:1px solid #f1f1f1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 30px
|
||||
|
@ -257,23 +261,17 @@
|
|||
}
|
||||
.detail_tag_btn_name{
|
||||
padding:0px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
color: #666!important;
|
||||
}
|
||||
.detail_tag_btn_name img{
|
||||
margin-right: 10px;
|
||||
}
|
||||
.detail_tag_btn_count{
|
||||
padding:0px 10px;
|
||||
color: #fff !important;
|
||||
background: rgba(255,255,255,0.2);
|
||||
background: #fff;
|
||||
border-radius: 0px 4px 4px 0px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.detail_tag_btn_count:hover{
|
||||
/* color: #1C91FF !important; */
|
||||
background: rgba(255,255,255,0.5);
|
||||
height:100%;
|
||||
}
|
||||
.files-md{
|
||||
border:1px solid #eee;
|
||||
|
@ -296,6 +294,7 @@
|
|||
.branch-wrapper > a >i{
|
||||
color: #5091FF;
|
||||
margin-right: 5px;
|
||||
cursor: default;
|
||||
}
|
||||
.branch-wrapper a{
|
||||
display: flex;
|
||||
|
@ -413,6 +412,7 @@
|
|||
padding: 13px 16px!important;
|
||||
}
|
||||
.commitKey{
|
||||
cursor: pointer;
|
||||
border:1px solid #FD7700;
|
||||
background-color:#FFF3DC;
|
||||
color: #FD7700!important;
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import React from 'react';
|
||||
import { AlignCenter , FlexAJ } from '../Component/layout';
|
||||
import User from '../Component/User';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
function Commits({ commits , projectsId , owner }){
|
||||
return(
|
||||
<div className="pb20">
|
||||
{
|
||||
commits.map((item,key)=>{
|
||||
return(
|
||||
<div className="prCommits">
|
||||
<p className="prCreate">{item.created_at}</p>
|
||||
<div className="prInfo">
|
||||
<FlexAJ>
|
||||
<AlignCenter>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="commitKey" style={{marginLeft:0}}>{truncateCommitId(`${item.sha}`)}</Link>
|
||||
<p className="ml15 font-16 color-grey-3 task-hide" style={{maxWidth:"700px"}}>{item.message}</p>
|
||||
</AlignCenter>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(item.sha)}`} className="color-blue">浏览代码</Link>
|
||||
</FlexAJ>
|
||||
<AlignCenter className="mt15">
|
||||
<User url={getImageUrl(`images/${item.committer && item.committer.image_url}`)} name={`${item.committer && item.committer.name}`}></User><span>:提交于{item.time_from_now}</span>
|
||||
</AlignCenter>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Commits;
|
|
@ -0,0 +1,86 @@
|
|||
import React ,{useEffect,useState } from 'react';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import { AlignCenter , FlexAJ } from '../Component/layout';
|
||||
import { Button } from 'antd';
|
||||
import './merge.css';
|
||||
|
||||
function Files({data,history,owner,projectsId}){
|
||||
const [ files , setFiles ] = useState(data && data.files);
|
||||
|
||||
useEffect(()=>{
|
||||
if(data){
|
||||
setFiles(data.files);
|
||||
}
|
||||
},[data])
|
||||
|
||||
function showDown(flag,index,isBin){
|
||||
if(!isBin){
|
||||
var lists = files.concat();
|
||||
lists[index].flag = !flag ? true : false;
|
||||
lists.splice();
|
||||
setFiles(lists);
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
<div>
|
||||
<AlignCenter className="color-grey-9 pb10" style={{borderBottom:"1px solid #eee"}}>
|
||||
<i className="iconfont icon-sanjiaoxing-down mr5"></i>
|
||||
<span>
|
||||
共有<span className="color-grey-3"> {data && data.files_count} 个文件被更改</span>,包括
|
||||
{ data && data.total_addition ? <span className="color-green"> {data && data.total_addition} 次插入</span>:"" }
|
||||
{ data && data.total_addition && data.total_deletion ? " 和 ":""}
|
||||
{ data && data.total_deletion ? <span className="color-red"> {data && data.total_deletion} 次删除</span>:""}
|
||||
</span>
|
||||
</AlignCenter>
|
||||
{
|
||||
files && files.length>0 &&
|
||||
<div>
|
||||
{
|
||||
files.map((item,key)=>{
|
||||
return(
|
||||
<div className="files" key={key}>
|
||||
<FlexAJ className="filesInfo" style={{cursor:item.isBin ? "default":"pointer"}} onClick={()=>showDown(item.flag,key,item.isBin)}>
|
||||
<AlignCenter>
|
||||
{!item.isBin ? <i className={!item.flag?"iconfont icon-xiajiantou font-16 mr15 color-grey-9":"iconfont icon-youjiantou font-16 mr15 color-grey-9"}></i>:""}
|
||||
<i className="iconfont icon-wenjia font-16 mr8 color-grey-9"></i>
|
||||
<span>{item.name}</span>
|
||||
</AlignCenter>
|
||||
<span>
|
||||
<Button className="mr20" onClick={()=>{history.push(`/projects/${owner}/${projectsId}${item.sha ? `/branch/${truncateCommitId(item.sha)}?`:"?"}url=${item.name}`)}}>查看文件</Button>
|
||||
<span className="color-green">+{item.addition}</span>
|
||||
<span className="color-red ml20">-{item.deletion}</span>
|
||||
</span>
|
||||
</FlexAJ>
|
||||
{
|
||||
item.sections && item.sections.length >= 1 && !item.flag &&
|
||||
<div className="filesContent">
|
||||
{
|
||||
item.sections.map((i,k)=>{
|
||||
return(
|
||||
i.lines && i.lines.length>0 && i.lines.map((item,key)=>{
|
||||
return(
|
||||
<div key={k+key} className={(item.type === 2) ? "linesContent add" : item.type === 3 ? "linesContent reduce": item.type===4?"linesContent translate":"linesContent"}>
|
||||
<span className="lines">
|
||||
<span>{item.leftIdx && item.leftIdx !=="0" ? item.leftIdx :"" }</span>
|
||||
<span>{item.rightIdx && item.rightIdx !=="0" ? item.rightIdx :"" }</span>
|
||||
</span>
|
||||
<p>{item.content}</p>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Files;
|
|
@ -32,8 +32,8 @@ class MergeDetail extends Component {
|
|||
}
|
||||
|
||||
getDetail = () => {
|
||||
const { projectsId, mergeid } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/pull_requests/${mergeid}.json`;
|
||||
const { projectsId, mergeid ,owner } = this.props.match.params;
|
||||
const url = `/projects/${owner}/${projectsId}/pulls/${mergeid}.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
|
@ -107,8 +107,8 @@ class MergeDetail extends Component {
|
|||
|
||||
//关闭任务
|
||||
closedetail = (id) => {
|
||||
const { projectsId, orderId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}/close_issue.json`;
|
||||
const { projectsId, orderId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/issues/${orderId}/close_issue.json`;
|
||||
axios.post(url, {
|
||||
project_id: projectsId,
|
||||
id: orderId,
|
||||
|
@ -161,7 +161,7 @@ class MergeDetail extends Component {
|
|||
})
|
||||
}
|
||||
render() {
|
||||
const { projectsId, mergeid } = this.props.match.params;
|
||||
const { projectsId, mergeid , owner } = this.props.match.params;
|
||||
const { data, journalsdata, showFiles } = this.state;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const url = this.props.history.location.pathname;
|
||||
|
@ -214,7 +214,7 @@ class MergeDetail extends Component {
|
|||
)
|
||||
} else {
|
||||
return (
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
<NoneData _html="暂时还没有相关数据!" />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ class MergeDetail extends Component {
|
|||
<div>
|
||||
{
|
||||
data && data.issue.user_permission ?
|
||||
<Link to={`/projects/${projectsId}/merge/${mergeid}/updatemerge`} className="color-blue fr">编辑</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/pulls/${mergeid}/updatemerge`} className="color-blue fr">编辑</Link>
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
|
@ -248,8 +248,8 @@ class MergeDetail extends Component {
|
|||
<div className="detailHeader-wrapper">
|
||||
<div className="normal f-wrap-between">
|
||||
<ul className="headerMenu-wrapper">
|
||||
<li className={url.indexOf("Messagecount") > 0 ? "active" : ""}><Link to={`/projects/${projectsId}/merge/${mergeid}/Messagecount`}>对话内容</Link></li>
|
||||
<li className={url.indexOf("MergeSubmit") > 0 ? "active" : ""}><Link to={`/projects/${projectsId}/merge/${mergeid}/MergeSubmit`}>代码提交</Link></li>
|
||||
<li className={url.indexOf("Messagecount") > 0 ? "active" : ""}><Link to={`/projects/${owner}/${projectsId}/pulls/${mergeid}/Messagecount`}>对话内容</Link></li>
|
||||
<li className={url.indexOf("MergeSubmit") > 0 ? "active" : ""}><Link to={`/projects/${owner}/${projectsId}/pulls/${mergeid}/MergeSubmit`}>代码提交</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -43,7 +43,7 @@ class MergeItem extends Component {
|
|||
|
||||
render() {
|
||||
const { issues, project_name, project_author_name } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { current_user } = this.props;
|
||||
const renderList = () => {
|
||||
if (issues && issues.length > 0) {
|
||||
|
@ -53,7 +53,7 @@ class MergeItem extends Component {
|
|||
<div className="flex-1">
|
||||
<p className="mb15 df" style={{ alignItems: "center" }}>
|
||||
<Link
|
||||
to={`/projects/${projectsId}/merge/${item.pull_request_id}/Messagecount`}
|
||||
to={`/projects/${owner}/${projectsId}/pulls/${item.pull_request_id}/Messagecount`}
|
||||
className="hide-1 font-15 color-grey-3 fwb lineh-30 mr10"
|
||||
style={{ maxWidth: "300px" }}
|
||||
>
|
||||
|
@ -98,9 +98,7 @@ class MergeItem extends Component {
|
|||
<span className="ml15">
|
||||
<Tag className="pr-branch-tag">
|
||||
<Link
|
||||
to={`/projects/${
|
||||
item.is_original ? item.fork_project_id : projectsId
|
||||
}/coders?branch=${item.pull_request_head}`}
|
||||
to={`/projects/${item.is_original ? item.fork_project_user : owner}/${ item.is_original ? item.fork_project_identifier : projectsId }/branch/${item.pull_request_head}`}
|
||||
className="maxW200px hide-1 ver-middle"
|
||||
>
|
||||
{item.is_original
|
||||
|
@ -118,7 +116,7 @@ class MergeItem extends Component {
|
|||
</span>
|
||||
<Tag className="pr-branch-tag">
|
||||
<Link
|
||||
to={`/projects/${projectsId}/coders?branch=${item.pull_request_base}`}
|
||||
to={`/projects/${owner}/${projectsId}/branch/${item.pull_request_base}`}
|
||||
className="maxW200px hide-1 ver-middle"
|
||||
>
|
||||
{/* {item.is_fork ? item.pull_request_base : `${item.author_name}:${item.pull_request_base}`} */}
|
||||
|
@ -158,7 +156,7 @@ class MergeItem extends Component {
|
|||
{item.journals_count ? (
|
||||
<Link
|
||||
className="mr5 color-grey-8"
|
||||
to={`/projects/${projectsId}/merge/${item.pull_request_id}/Messagecount`}
|
||||
to={`/projects/${owner}/${projectsId}/pulls/${item.pull_request_id}/Messagecount`}
|
||||
>
|
||||
<i className="iconfont icon-huifu1 font-15 mr5 ver-middle"></i>
|
||||
{item.journals_count}
|
||||
|
@ -179,7 +177,7 @@ class MergeItem extends Component {
|
|||
>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<Link
|
||||
to={`/projects/${projectsId}/merge/${item.pull_request_id}/updatemerge`}
|
||||
to={`/projects/${owner}/${projectsId}/merge/${item.pull_request_id}/updatemerge`}
|
||||
className="color-grey-9"
|
||||
>
|
||||
<i className="iconfont icon-bianji3 font-14 mr5"></i>
|
||||
|
|
|
@ -5,6 +5,7 @@ import axios from 'axios';
|
|||
import{ Form , Table , Spin } from 'antd'
|
||||
import { getImageUrl } from 'educoder';
|
||||
import {Link} from "react-router-dom";
|
||||
import { truncateCommitId} from '../common/util';
|
||||
class MergeSubmit extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
@ -36,9 +37,8 @@ class MergeSubmit extends Component{
|
|||
}
|
||||
|
||||
getDetail=()=>{
|
||||
|
||||
const { projectsId , mergeId} = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/pull_requests/${mergeId}.json`;
|
||||
const { projectsId , mergeId, owner} = this.props.match.params;
|
||||
const url = `/projects/${owner}/${projectsId}/pull_requests/${mergeId}.json`;
|
||||
axios.get(url).then((result)=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
|
@ -53,8 +53,8 @@ class MergeSubmit extends Component{
|
|||
|
||||
//获取提交列表
|
||||
getCommitList=(branch , page , limit)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/repositories/${projectsId}/commits.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/commits.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
sha:branch,
|
||||
|
@ -83,8 +83,16 @@ class MergeSubmit extends Component{
|
|||
}).catch((error)=>{console.log(error)})
|
||||
}
|
||||
|
||||
title =()=>{
|
||||
return(
|
||||
<div className="f-wrap-between" style={{alignItems:"center"}}>
|
||||
<span className="font-16">提交列表</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render(){
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { titledata } = this.state;
|
||||
const columns=[{
|
||||
title:"作者",
|
||||
|
@ -102,7 +110,7 @@ class MergeSubmit extends Component{
|
|||
title:"SHA",
|
||||
dataIndex: 'sha',
|
||||
render: (text) => (
|
||||
<span className="commitKey">{text}</span>
|
||||
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${text}`)}`} className="commitKey">{text}</Link>
|
||||
)
|
||||
},{
|
||||
title:"备注",
|
||||
|
@ -118,14 +126,6 @@ class MergeSubmit extends Component{
|
|||
<span>{text}</span>
|
||||
)
|
||||
}]
|
||||
|
||||
const title =()=>{
|
||||
return(
|
||||
<div className="f-wrap-between" style={{alignItems:"center"}}>
|
||||
<span className="font-16">提交列表</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return(
|
||||
<Spin spinning={this.state.isSpin}>
|
||||
|
@ -136,11 +136,9 @@ class MergeSubmit extends Component{
|
|||
showHeader={false}
|
||||
size="small"
|
||||
pagination={false}
|
||||
title={() => title()}
|
||||
title={() => this.title()}
|
||||
/>
|
||||
</Spin>
|
||||
// </div>
|
||||
// </div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, { Component } from "react";
|
||||
import { Tabs } from 'antd';
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { AlignCenter } from '../Component/layout';
|
||||
import axios from "axios";
|
||||
import { getImageUrl } from "educoder";
|
||||
import {
|
||||
|
@ -39,6 +40,8 @@ class MessageCount extends Component {
|
|||
SpinMerge: false,
|
||||
edit_spin: false,
|
||||
pr_status: undefined,
|
||||
|
||||
copyVisible:false,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -47,11 +50,22 @@ class MessageCount extends Component {
|
|||
SpinFlag: true,
|
||||
});
|
||||
this.getDetail();
|
||||
|
||||
// this.clickBody();
|
||||
};
|
||||
clickBody=()=>{
|
||||
document.body.addEventListener('click', e => {
|
||||
let name = e.target.className;
|
||||
if(name.indexOf("notHide")>-1 || name.indexOf("ant-tabs-tab")>-1 || name==="ant-tabs-nav-scroll"){return;}
|
||||
this.setState({
|
||||
copyVisible:false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getDetail = () => {
|
||||
const { projectsId, mergeId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/pull_requests/${mergeId}.json`;
|
||||
const { projectsId, mergeId, owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/pulls/${mergeId}.json`;
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
|
@ -59,7 +73,7 @@ class MessageCount extends Component {
|
|||
this.setState({
|
||||
data: result.data,
|
||||
SpinFlag: false,
|
||||
pr_status: result.data.pull_request.status,
|
||||
pr_status: result.data && result.data.pull_request && result.data.pull_request.status,
|
||||
});
|
||||
} else {
|
||||
this.setState({ SpinFlag: false });
|
||||
|
@ -76,8 +90,8 @@ class MessageCount extends Component {
|
|||
//关闭任务
|
||||
closedetail = () => {
|
||||
this.setState({ isSpin: true });
|
||||
const { projectsId, mergeId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/pull_requests/${mergeId}/refuse_merge.json`;
|
||||
const { projectsId, mergeId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/pulls/${mergeId}/refuse_merge.json`;
|
||||
axios
|
||||
.post(url)
|
||||
.then((result) => {
|
||||
|
@ -105,9 +119,9 @@ class MessageCount extends Component {
|
|||
this.setState({
|
||||
SpinMerge: true,
|
||||
});
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { data, title, body, mergekey, pr_status } = this.state;
|
||||
const url = `/projects/${projectsId}/pull_requests/${data.pull_request.id}/pr_merge.json`;
|
||||
const url = `/${owner}/${projectsId}/pulls/${data.pull_request.id}/pr_merge.json`;
|
||||
axios
|
||||
.post(url, {
|
||||
project_id: projectsId,
|
||||
|
@ -195,11 +209,38 @@ class MessageCount extends Component {
|
|||
};
|
||||
|
||||
commentCtx = (v) => {
|
||||
return <RenderHtml className="break_word_comments" value={v} />;
|
||||
return <RenderHtml className="break_word_comments imageLayerParent" value={v} />;
|
||||
};
|
||||
|
||||
setCopyVisible=(e)=>{
|
||||
e.stopPropagation();
|
||||
this.setState({
|
||||
copyVisible:true
|
||||
})
|
||||
}
|
||||
|
||||
copyItem =()=>{
|
||||
return(
|
||||
<div className="copyTab notHide">
|
||||
<Tabs defaultActiveKey="1" className="notHide" animated={false} size={"small"}>
|
||||
<Tabs.TabPane key="1" tab={<span className="notHide">HTTPS</span>}>{this.returnCopyUrl("https://gitee.com/44886/polhttp.git")}</Tabs.TabPane>
|
||||
<Tabs.TabPane key="2" tab={<span className="notHide">SSH</span>}>{this.returnCopyUrl("https://gitee.com/44886/polssh.git")}</Tabs.TabPane>
|
||||
</Tabs>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
returnCopyUrl=(url)=>{
|
||||
return(
|
||||
<div className="df notHide">
|
||||
<Input value={url} className="notHide" disabled={true}/>
|
||||
<Button type="primary" ghost className="ml15 notHide">复制</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { projectsId, mergeId } = this.props.match.params;
|
||||
const { projectsId, mergeId , owner } = this.props.match.params;
|
||||
|
||||
const {
|
||||
data,
|
||||
|
@ -208,6 +249,7 @@ class MessageCount extends Component {
|
|||
isSpin,
|
||||
ismesrge,
|
||||
SpinFlag,
|
||||
copyVisible
|
||||
} = this.state;
|
||||
const { current_user, projectDetail } = this.props;
|
||||
const menu = (
|
||||
|
@ -258,7 +300,7 @@ class MessageCount extends Component {
|
|||
<div className="mt15">
|
||||
<Tag className="pr-branch-tag">
|
||||
<Link
|
||||
to={`/projects/${data.pull_request.is_original?data.pull_request.fork_project_id:projectsId}/coders?branch=${data.pull_request.head}`}
|
||||
to={`/projects/${owner}/${data.pull_request.is_original?data.pull_request.fork_project_id:projectsId}/branch/${data.pull_request.head}`}
|
||||
className="ver-middle"
|
||||
>
|
||||
{data.pull_request.is_original ? data.pull_request.fork_project_user : data.issue.project_author_name}:{data.pull_request.head}
|
||||
|
@ -273,7 +315,7 @@ class MessageCount extends Component {
|
|||
</span>
|
||||
<Tag className="pr-branch-tag">
|
||||
<Link
|
||||
to={`/projects/${projectsId}/coders?branch=${data.pull_request.base}`}
|
||||
to={`/projects/${owner}/${projectsId}/branch/${data.pull_request.base}`}
|
||||
className="ver-middle"
|
||||
>
|
||||
{/* {data.pull_request.is_fork ? data.pull_request.base : `${data.pull_request.pull_request_user}:${data.pull_request.base}`} */}
|
||||
|
@ -352,14 +394,21 @@ class MessageCount extends Component {
|
|||
</div>
|
||||
</div>
|
||||
<div className="ml10">
|
||||
<div className="mt15 text-right">
|
||||
<div className="mt15 text-right" style={{display:"flex",justifyContent:"flex-end"}}>
|
||||
{/* <span className="composeButton">
|
||||
<Dropdown overlay={this.copyItem()} visible={copyVisible} onClick={(e)=>this.setCopyVisible(e)}>
|
||||
<span>复制</span>
|
||||
</Dropdown>
|
||||
<span>下载为<i className="iconfont icon-sanjiaoxing-down color-blue"></i></span>
|
||||
</span> */}
|
||||
{current_user && projectDetail &&
|
||||
pr_status !== 2 &&
|
||||
pr_status === 0 &&
|
||||
projectDetail.permission !=="Reporter" && (
|
||||
<Button
|
||||
type="success"
|
||||
type="green"
|
||||
ghost
|
||||
href={`/projects/${projectsId}/merge/${mergeId}/UpdateMerge`}
|
||||
className="ml20"
|
||||
onClick={()=>{this.props.history.push(`/projects/${owner}/${projectsId}/pulls/${mergeId}/UpdateMerge`);}}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
|
@ -369,7 +418,7 @@ class MessageCount extends Component {
|
|||
type="danger"
|
||||
ghost
|
||||
onClick={() => this.closedetail()}
|
||||
className="ml15"
|
||||
className="ml20"
|
||||
loading={isSpin}
|
||||
>
|
||||
拒绝
|
||||
|
@ -378,14 +427,12 @@ class MessageCount extends Component {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt15">
|
||||
{data.issue.description &&
|
||||
data.issue.description.length > 0 ? (
|
||||
this.commentCtx(data.issue.description)
|
||||
) : (
|
||||
<span className="color-grey-9 ml3 mr3">没有描述</span>
|
||||
)}
|
||||
</div>
|
||||
{
|
||||
data.issue.description ?
|
||||
<div className="mt15">{this.commentCtx(data.issue.description)}</div>
|
||||
:
|
||||
<p className="color-grey-9 ml3 mr3 mt15">没有描述</p>
|
||||
}
|
||||
</div>
|
||||
<div className="mt15">
|
||||
{pr_status === 2 && (
|
||||
|
@ -473,14 +520,12 @@ class MessageCount extends Component {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className=" main">
|
||||
<MergeFooter
|
||||
footer_type="show"
|
||||
order_id={data && data.issue.id}
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
></MergeFooter>
|
||||
</div>
|
||||
<MergeFooter
|
||||
footer_type={true}
|
||||
order_id={data && data.issue.id}
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
></MergeFooter>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { Component } from "react";
|
||||
import { Input, Select, Button, Spin, Alert } from "antd";
|
||||
import { Input, Select , Spin, Alert } from "antd";
|
||||
import axios from "axios";
|
||||
import "../Order/order.css";
|
||||
import "./merge.css";
|
||||
|
@ -16,6 +16,7 @@ class NewMerge extends Component {
|
|||
merge_projects: undefined,
|
||||
merge: "master",
|
||||
pull: "master",
|
||||
id: undefined,
|
||||
is_fork: false,
|
||||
projects_names: undefined,
|
||||
isSpin: false,
|
||||
|
@ -23,20 +24,43 @@ class NewMerge extends Component {
|
|||
merge_head: false, // 是否向fork后的源项目发起合并请求
|
||||
default_message: "必须选择不同的分支",
|
||||
project_id: undefined, // 当前项目的id,也即开始发送合并请求的源项目id
|
||||
merge_project_user: undefined
|
||||
merge_project_user: undefined,
|
||||
oldProject:undefined,//保存选择目标分支、跳转页面后会刷新的project
|
||||
comparesData:undefined,//提交和文件的内容,保存compare接口返回的数据
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
this.getmergelist(projectsId);
|
||||
// 监听回退事件
|
||||
if (window.history && window.history.pushState) {
|
||||
window.addEventListener('popstate', this.handleBack, false);
|
||||
}
|
||||
};
|
||||
|
||||
//获取新建分枝数据
|
||||
componentDidUpdate=(preProps)=>{
|
||||
const { project } = this.props;
|
||||
let oldProject = preProps.project;
|
||||
if(project && oldProject && (oldProject.id !== project.id)){
|
||||
this.compareProject(this.state.id,"master","master");
|
||||
}
|
||||
}
|
||||
// 页面销毁取消监听
|
||||
componentWillUnmount () {
|
||||
window.removeEventListener('popstate', this.handleBack, false);
|
||||
};
|
||||
|
||||
handleBack=()=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
this.getmergelist(projectsId);
|
||||
}
|
||||
|
||||
//获取新建分支数据
|
||||
getmergelist = (projectsId) => {
|
||||
this.setState({isSpin: true})
|
||||
const url = `/projects/${projectsId}/pull_requests/new.json`;
|
||||
const { owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/pulls/new.json`;
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
|
@ -48,10 +72,12 @@ class NewMerge extends Component {
|
|||
branches: result.data.branches,
|
||||
merge_branches: result.data.branches,
|
||||
project_id: result.data.project_id,
|
||||
id: result.data.id
|
||||
});
|
||||
this.set_default_pull()
|
||||
this.set_default_merge()
|
||||
this.set_default_pull(result.data.branches);
|
||||
this.set_default_merge(result.data.merge_projects);
|
||||
}
|
||||
this.compareProject(result.data.id,"master","master");
|
||||
this.setState({isSpin: false})
|
||||
})
|
||||
.catch((error) => {
|
||||
|
@ -60,110 +86,151 @@ class NewMerge extends Component {
|
|||
});
|
||||
};
|
||||
|
||||
set_default_pull = () => {
|
||||
const {branches} = this.state;
|
||||
let default_pull = branches.filter((e) => e.name === "master")
|
||||
if (default_pull.length > 0){
|
||||
this.state.pull = default_pull[0].name
|
||||
}else{
|
||||
this.state.pull = "master"
|
||||
}
|
||||
}
|
||||
|
||||
set_default_merge = () => {
|
||||
const {merge_branches} = this.state;
|
||||
let default_merge = merge_branches.filter((e) => e.name === "master")
|
||||
if (default_merge.length > 0){
|
||||
this.state.merge = default_merge[0].name
|
||||
}else{
|
||||
this.state.merge = "master"
|
||||
}
|
||||
this.ischeckmerge();
|
||||
}
|
||||
|
||||
newMergelist = (projectsId) => {
|
||||
this.setState({isSpin: true})
|
||||
const url = `/projects/${projectsId}/pull_requests/get_branches.json`;
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
// 获取compare接口
|
||||
compareProject=(baseid , localBranch , mergeBranch)=>{
|
||||
const { project } = this.props;
|
||||
const { owner , projectsId } = this.props.match.params;
|
||||
let url = `/${owner}/${projectsId}/compare`;
|
||||
if(project){
|
||||
if(baseid === project.id){
|
||||
this.setState({
|
||||
oldProject:project
|
||||
})
|
||||
url += `/${localBranch}...${mergeBranch}.json`;
|
||||
}else{
|
||||
const { oldProject } = this.state;
|
||||
const { author , identifier } =oldProject;
|
||||
url += `/${mergeBranch}...${author && author.login}/${identifier}:${localBranch}.json`;
|
||||
}
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
merge_branches: result.data
|
||||
comparesData:result.data
|
||||
})
|
||||
this.set_default_merge()
|
||||
}
|
||||
this.setState({isSpin: false})
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({isSpin: false})
|
||||
console.log(error);
|
||||
});
|
||||
}).catch(error=>{})
|
||||
}
|
||||
}
|
||||
|
||||
set_default_pull = (branches) => {
|
||||
if(branches && branches.length>0){
|
||||
let default_pull = branches.filter((e) => e.name === "master")
|
||||
if (default_pull.length > 0){
|
||||
this.setState({
|
||||
pull:default_pull[0].name
|
||||
})
|
||||
}else{
|
||||
this.setState({
|
||||
pull:"master"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_default_merge = (merge_branches) => {
|
||||
if(merge_branches && merge_branches.length){
|
||||
let default_merge = merge_branches.filter((e) => e.name === "master")
|
||||
if (default_merge.length > 0){
|
||||
this.setState({
|
||||
merge:default_merge[0].name
|
||||
})
|
||||
}else{
|
||||
this.setState({
|
||||
merge:"master"
|
||||
})
|
||||
}
|
||||
this.ischeckmerge();
|
||||
}
|
||||
}
|
||||
|
||||
newMergelist = (login,id) => {
|
||||
this.setState({isSpin: true})
|
||||
|
||||
const url = `/${login}/${id}/pulls/get_branches.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
merge_branches: result.data
|
||||
})
|
||||
this.set_default_merge(result.data)
|
||||
}
|
||||
this.setState({isSpin: false})
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({isSpin: false})
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
selectBrach = (type, value) => {
|
||||
this.state[type] = value;
|
||||
this.ischeckmerge();
|
||||
let { id ,merge , pull } = this.state;
|
||||
if(type==="pull"){
|
||||
this.compareProject(id,value,merge);
|
||||
}else{
|
||||
this.compareProject(id,pull,value);
|
||||
}
|
||||
};
|
||||
|
||||
selectProjectName = (value) => {
|
||||
const { project_id, projects_names } = this.state;
|
||||
|
||||
let is_fork_id = parseInt(value) !== parseInt(project_id)
|
||||
const { projects_names,id } = this.state;
|
||||
let arr = projects_names && projects_names.filter(item=>item.id===value);
|
||||
let identifier = arr && arr[0].project_id;
|
||||
let login = arr && arr[0].project_user_login;
|
||||
let is_fork_id = parseInt(value) !== parseInt(id)
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
merge_head: is_fork_id,
|
||||
data: {
|
||||
is_original: is_fork_id,
|
||||
fork_project_id: is_fork_id ? project_id : "",
|
||||
fork_project_id: is_fork_id ? id : "",
|
||||
merge_user_login: is_fork_id ? projects_names[0].project_user_login : undefined
|
||||
}
|
||||
})
|
||||
this.props.history.push(`/projects/${value}/merge/new`);
|
||||
this.newMergelist(value);
|
||||
|
||||
this.props.history.push(`/projects/${login}/${identifier}/pulls/new`);
|
||||
this.newMergelist(login,identifier);
|
||||
};
|
||||
|
||||
//判断2分支是否可以合并
|
||||
|
||||
ischeckmerge = () => {
|
||||
this.setState({ isSpin: true });
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { pull, merge, project_id, merge_head } = this.state;
|
||||
const url = `/projects/${projectsId}/pull_requests/check_can_merge.json`;
|
||||
axios
|
||||
.post(url, {
|
||||
head: pull,
|
||||
base: merge,
|
||||
is_original: merge_head,
|
||||
fork_project_id: merge_head ? project_id : undefined
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
if (result.data.status === 0) {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
show_message: false,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
show_message: true,
|
||||
default_message: result.data.message,
|
||||
});
|
||||
}
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { pull, merge , merge_head, id } = this.state;
|
||||
const url = `/${owner}/${projectsId}/pulls/check_can_merge.json`;
|
||||
axios.post(url, {
|
||||
head: pull,
|
||||
base: merge,
|
||||
is_original: merge_head,
|
||||
fork_project_id: merge_head ? id : undefined
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
if (result.data.status === 0) {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
show_message: false,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
show_message: true,
|
||||
default_message: "出现错误了",
|
||||
default_message: result.data.message,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({ isSpin: false, show_message: true });
|
||||
console.log(error);
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
show_message: true,
|
||||
default_message: "出现错误了",
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({ isSpin: false, show_message: true });
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -178,9 +245,9 @@ class NewMerge extends Component {
|
|||
show_message,
|
||||
default_message,
|
||||
merge_head,
|
||||
projects_names,
|
||||
projects_names,id,comparesData
|
||||
} = this.state;
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
const renderBrances = (list, type) => {
|
||||
if (list && list.length > 0) {
|
||||
return list.map((item, key) => {
|
||||
|
@ -200,7 +267,7 @@ class NewMerge extends Component {
|
|||
if (list && list.length > 0) {
|
||||
return list.map((item, key) => {
|
||||
return (
|
||||
<Option key={key + 1} value={item.project_id}>
|
||||
<Option key={key + 1} value={item.id}>
|
||||
{item.project_name}
|
||||
</Option>
|
||||
);
|
||||
|
@ -211,27 +278,27 @@ class NewMerge extends Component {
|
|||
const withHtml = (html) => {
|
||||
return <div dangerouslySetInnerHTML={{ __html: html }}></div>;
|
||||
};
|
||||
|
||||
let { project } = this.props;
|
||||
return (
|
||||
<div>
|
||||
<div className="main">
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="merge-header width100 inline-block">
|
||||
<div className="width45 pull-left">
|
||||
<div className="width40 pull-left">
|
||||
<div className="color-grey-3 mb10 fwb">源分支:</div>
|
||||
<Input.Group compact className="display-flex">
|
||||
<Select
|
||||
defaultValue={parseInt(projectsId)}
|
||||
class=" maxW50 hide-1 task-hide"
|
||||
value={id}
|
||||
className="hide-1 task-hide flex1"
|
||||
disabled
|
||||
>
|
||||
{renderProjectNames(projects_names)}
|
||||
</Select>
|
||||
<Select
|
||||
defaultValue={pull}
|
||||
value={pull}
|
||||
onSelect={(e) => this.selectBrach("pull", e)}
|
||||
showSearch
|
||||
className="minW50 merge-flex1"
|
||||
className="merge-flex1 flex1"
|
||||
>
|
||||
{renderBrances(branches, false)}
|
||||
</Select>
|
||||
|
@ -242,23 +309,22 @@ class NewMerge extends Component {
|
|||
className={"iconfont icon-youjiang color-grey-c font-32"}
|
||||
></i>
|
||||
</div>
|
||||
<div className="width45 pull-left">
|
||||
<div className="width40 pull-left">
|
||||
<div>
|
||||
<div className="color-grey-3 mb10 fwb">目标分支:</div>
|
||||
<Input.Group compact className="display-flex">
|
||||
<Select
|
||||
defaultValue={parseInt(projectsId)}
|
||||
class=" maxW50 hide-1 task-hide"
|
||||
value={project && project.id}
|
||||
className="hide-1 task-hide flex1"
|
||||
onSelect={(e) => this.selectProjectName(e)}
|
||||
>
|
||||
{renderProjectNames(merge_projects)}
|
||||
</Select>
|
||||
<Select
|
||||
defaultValue={merge}
|
||||
value={merge}
|
||||
onSelect={(e) => this.selectBrach("merge", e)}
|
||||
showSearch
|
||||
className="minW50 merge-flex1"
|
||||
className="merge-flex1 flex1"
|
||||
>
|
||||
{renderBrances(merge_branches, merge_head)}
|
||||
</Select>
|
||||
|
@ -277,13 +343,20 @@ class NewMerge extends Component {
|
|||
data={data}
|
||||
merge={merge}
|
||||
pull={pull}
|
||||
files_count={comparesData && comparesData.diff && comparesData.diff.files_count}
|
||||
commits_count={comparesData && comparesData.commits_count}
|
||||
></MergeForm>
|
||||
)}
|
||||
</Spin>
|
||||
</div>
|
||||
{/* <div className=" main">
|
||||
<MergeFooter footer_type="new" {...this.props}></MergeFooter>
|
||||
</div> */}
|
||||
<MergeFooter
|
||||
order_id={data && data.issue && data.issue.id}
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
merge={merge}
|
||||
pull={pull}
|
||||
comparesData={comparesData}
|
||||
></MergeFooter>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ class UpdateMerge extends Component {
|
|||
//获取新建分枝数据
|
||||
getmergelist = () => {
|
||||
this.setState({ isSpin: true });
|
||||
const { projectsId, mergeId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/pull_requests/${mergeId}/edit.json`;
|
||||
const { projectsId, mergeId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/pulls/${mergeId}/edit.json`;
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
|
@ -37,11 +37,15 @@ class UpdateMerge extends Component {
|
|||
merge: result.data.base,
|
||||
});
|
||||
} else {
|
||||
this.setState({ isSpin: false });
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({ isSpin: false });
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
@ -52,6 +56,7 @@ class UpdateMerge extends Component {
|
|||
<div>
|
||||
<div className="main">
|
||||
<Spin spinning={isSpin}>
|
||||
{" "}
|
||||
{data ? (
|
||||
<div>
|
||||
<div className="merge-header width100 inline-block">
|
||||
|
@ -66,17 +71,17 @@ class UpdateMerge extends Component {
|
|||
defaultValue={data.is_original ? `${data.fork_project_user}:${pull}` : `${pull}`}
|
||||
className="minW50 merge-flex1"
|
||||
disabled
|
||||
></Select>
|
||||
</Input.Group>
|
||||
</div>
|
||||
></Select>{" "}
|
||||
</Input.Group>{" "}
|
||||
</div>{" "}
|
||||
<div className="width10 pull-left text-center mt25">
|
||||
<i
|
||||
className={"iconfont icon-youjiang color-grey-c font-32"}
|
||||
></i>
|
||||
</div>
|
||||
></i>{" "}
|
||||
</div>{" "}
|
||||
<div className="width45 pull-left">
|
||||
<div>
|
||||
<div className="color-grey-3 mb10 fwb">目标分支:</div>
|
||||
<div className="color-grey-3 mb10 fwb"> 目标分支 : </div>{" "}
|
||||
<Input.Group compact className="display-flex">
|
||||
<Button className="merge-header-button maxW50 hide-1 task-hide">
|
||||
{`${data.project_author}/${data.project_name}`}
|
||||
|
@ -85,19 +90,18 @@ class UpdateMerge extends Component {
|
|||
defaultValue={data.is_original ? `${data.project_login}:${merge}` : `${merge}`}
|
||||
className="minW50 merge-flex1"
|
||||
disabled
|
||||
></Select>
|
||||
</Input.Group>
|
||||
</div>
|
||||
</div>
|
||||
></Select>{" "}
|
||||
</Input.Group>{" "}
|
||||
</div>{" "}
|
||||
</div>{" "}
|
||||
</div>
|
||||
|
||||
<MergeForm
|
||||
{...this.props}
|
||||
merge_type="edit"
|
||||
data={data}
|
||||
merge={merge}
|
||||
pull={pull}
|
||||
></MergeForm>
|
||||
></MergeForm>{" "}
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
|
|
|
@ -40,4 +40,161 @@ form .ant-cascader-picker, form .ant-select {
|
|||
}
|
||||
.merge-header-button{
|
||||
background:rgba(241,248,255,1);
|
||||
}
|
||||
.width70{
|
||||
width:70%;
|
||||
}
|
||||
.width30{
|
||||
width:30%;
|
||||
}
|
||||
.width40{
|
||||
width:40%;
|
||||
}
|
||||
.display-flex{
|
||||
display: flex!important;
|
||||
}
|
||||
.w120{
|
||||
width: 120px;
|
||||
}
|
||||
.w240{
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.custom-commit-tabs .ant-tabs-nav .ant-tabs-tab{
|
||||
padding:14px 0px!important;
|
||||
}
|
||||
.custom-commit-tabs .ant-tabs-bar{
|
||||
border-bottom: none;
|
||||
}
|
||||
.custom-commit-tabs .ant-tabs-nav .ant-tabs-tab-active .tabNum{
|
||||
background-color: #EBF4FE;
|
||||
}
|
||||
.custom-commit-tabs .ant-tabs-ink-bar{
|
||||
width: 34px!important;
|
||||
}
|
||||
.tabNum{
|
||||
display: inline-block;
|
||||
margin-left:8px ;
|
||||
border-radius: 10px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
background-color: #eee;
|
||||
padding:0px 9px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 复制-下载为,组合按钮 */
|
||||
.composeButton{
|
||||
display: flex;
|
||||
border:1px solid #5091FF;
|
||||
border-radius: 5px;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
}
|
||||
.composeButton > span{
|
||||
display: block;
|
||||
padding:0px 18px;
|
||||
color: #5091FF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.composeButton > span:hover{
|
||||
background-color: #F1F8FF;
|
||||
}
|
||||
.composeButton > span:first-child{
|
||||
border-radius: 5px 0px 0px 5px;
|
||||
border-right: 1px solid #5091FF;
|
||||
}
|
||||
.ant-btn{
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* 绿色按钮-type="green" */
|
||||
.ant-btn.ant-btn-green{
|
||||
border:1px solid #28BD6C;
|
||||
color: #28BD6C;
|
||||
}
|
||||
.copyTab{
|
||||
min-width: 370px;
|
||||
padding:0px 18px 22px 18px;
|
||||
box-shadow: 0px 2px 10px rgba(0,0,0,0.2);
|
||||
background-color: #fff;
|
||||
}
|
||||
.copyTab .ant-tabs-tab{
|
||||
padding:12px 0px!important;
|
||||
}
|
||||
|
||||
/* pr--提交tab页面 */
|
||||
.prCommits{
|
||||
border:1px solid #ddd;
|
||||
border-top: none;
|
||||
}
|
||||
.prCommits:first-child{
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
.prCommits .prCreate{
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
padding:0px 25px;
|
||||
background-color:#fafafa;
|
||||
color:#333;
|
||||
font-size: 16px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
.prCommits .prInfo{
|
||||
padding:20px 25px;
|
||||
}
|
||||
/* pr-文件修改信息页面 */
|
||||
.files{
|
||||
border:1px solid #ddd;
|
||||
margin-top: 15px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.filesInfo{
|
||||
padding:10px 15px;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
.filesContent{
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
.linesContent{
|
||||
display: flex;
|
||||
min-height: 30px;
|
||||
line-height: 30px;
|
||||
color: #333;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.linesContent > p{
|
||||
flex:1;
|
||||
}
|
||||
.linesContent .lines{
|
||||
display: flex;
|
||||
border-right: 1px solid #ddd;
|
||||
width: 100px;
|
||||
padding: 0px 8px;
|
||||
box-sizing: border-box;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.linesContent .lines > span:first-child{
|
||||
margin-right: 0px;
|
||||
}
|
||||
.linesContent .lines > span{
|
||||
width: 50%;
|
||||
text-align: right;
|
||||
display: block;
|
||||
color: #888;
|
||||
}
|
||||
.linesContent.translate{
|
||||
background-color:#F1F8FF;
|
||||
}
|
||||
.linesContent.translate .lines > span{
|
||||
border-right: 1px solid transparent;
|
||||
}
|
||||
.linesContent.reduce{
|
||||
background-color:rgba(247, 48, 48, 0.15);;
|
||||
}
|
||||
.linesContent.add{
|
||||
background: rgba(48, 232, 132, 0.15);
|
||||
}
|
|
@ -66,9 +66,9 @@ class merge extends Component {
|
|||
};
|
||||
|
||||
getSelectList = () => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId,owner } = this.props.match.params;
|
||||
|
||||
const url = `/projects/${projectsId}/issues/index_chosen.json`;
|
||||
const url = `/${owner}/${projectsId}/issues/index_chosen.json`;
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
|
@ -86,25 +86,23 @@ class merge extends Component {
|
|||
// 获取列表数据
|
||||
getIssueList = () => {
|
||||
const { select_params } = this.state;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/pull_requests.json`;
|
||||
axios
|
||||
.get(url, {
|
||||
params: select_params,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
data: result.data,
|
||||
issues: result.data.issues,
|
||||
search_count: result.data.search_count,
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/pulls.json`;
|
||||
axios.get(url, {
|
||||
params: select_params,
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
data: result.data,
|
||||
issues: result.data.issues,
|
||||
search_count: result.data.search_count,
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
getMenu = (e, id, name) => {
|
||||
|
@ -218,16 +216,16 @@ class merge extends Component {
|
|||
};
|
||||
|
||||
islogin() {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId,owner } = this.props.match.params;
|
||||
if (this.props.checkIfLogin() === false) {
|
||||
this.props.showLoginDialog();
|
||||
return;
|
||||
} else {
|
||||
this.props.history.push(`/projects/${projectsId}/merge/new`);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/pulls/new`);
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const {
|
||||
issue_chosen,
|
||||
issues,
|
||||
|
@ -275,7 +273,7 @@ class merge extends Component {
|
|||
);
|
||||
return (
|
||||
<div className="main">
|
||||
<div className="topWrapper">
|
||||
<div className="topWrapper" style={{borderBottom:"1px solid #eee"}}>
|
||||
<div className="target-detail-search">
|
||||
<Search
|
||||
placeholder="输入关键字搜索合并请求"
|
||||
|
@ -409,7 +407,7 @@ class merge extends Component {
|
|||
</div>
|
||||
|
||||
{data && data.search_count && data.search_count > 0 ? (
|
||||
<div style={{minHeight:"400px"}}>
|
||||
<div style={{minHeight:"470px"}}>
|
||||
<Spin spinning={isSpin}>
|
||||
<OrderItem
|
||||
issues={issues}
|
||||
|
@ -425,63 +423,8 @@ class merge extends Component {
|
|||
</Spin>
|
||||
</div>
|
||||
) : (
|
||||
<NoneData _html="暂时还没有相关数据哦!" projectsId={projectsId} />
|
||||
<NoneData _html="暂时还没有相关数据!" projectsId={projectsId} owner={owner} />
|
||||
)}
|
||||
{/* <div className="topWrapper" style={{ borderBottom: "none" }}>
|
||||
<p className="topWrapper_type_infos">
|
||||
<li className={status_type === "1" ? "active" : ""} onClick={() => this.openorder("1")}>{data && data.open_count ? data.open_count : 0}个开启中</li>
|
||||
<li className={status_type === "2" ? "active" : ""} onClick={() => this.openorder("2")}>{data && data.close_count ? data.close_count : 0}个已关闭</li>
|
||||
</p>
|
||||
|
||||
<div className="topWrapper_select">
|
||||
<div>
|
||||
<Search
|
||||
placeholder="搜索"
|
||||
enterButton
|
||||
onSearch={this.searchFunc}
|
||||
style={{ width: 300 }}
|
||||
/>
|
||||
</div>
|
||||
<a className="topWrapper_btn ml10" onClick={() => this.islogin()}>创建合并请求</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="f-wrap-between pb20" style={{borderBottom:"1px dashed #ddd"}}>
|
||||
<div></div>
|
||||
<ul className="topWrapper_select">
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.issue_tag, '标签', 'issue_tag_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.issue_tag_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.issue_version, '里程碑', 'fixed_version_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.fixed_version_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.assign_user, '指派人', 'assigned_to_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.assigned_to_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.paix}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{
|
||||
data && data.search_count && data.search_count > 0 ?
|
||||
<div>
|
||||
<Spin spinning={isSpin}>
|
||||
<OrderItem issues={issues} search_count={search_count} page={select_params.page} limit={select_params.limit} {...this.props} {...this.state}></OrderItem>
|
||||
{Paginations}
|
||||
</Spin>
|
||||
</div>
|
||||
:
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
} */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,45 +1,169 @@
|
|||
import React, { Component } from "react";
|
||||
import { Tabs, Empty } from "antd";
|
||||
import { Tabs, Spin } from "antd";
|
||||
import "../Order/order.css";
|
||||
import "./merge.css";
|
||||
import CodesCommit from "../Main/CoderRootCommit";
|
||||
import Commits from "./Commits";
|
||||
import Comments from "../comments/comments";
|
||||
|
||||
import Files from "./Files";
|
||||
import axios from 'axios';
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
class MergeFooter extends Component {
|
||||
constructor(props) {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {};
|
||||
this.state={
|
||||
pageData:undefined,
|
||||
commitsData:undefined,
|
||||
filesData:undefined,
|
||||
isSpin:false,
|
||||
activeKey:"1",
|
||||
commitCount:0,
|
||||
filesCount:0
|
||||
}
|
||||
}
|
||||
componentDidMount=()=>{
|
||||
const { footer_type ,data } = this.props;
|
||||
if(footer_type){
|
||||
const { projectsId , owner , mergeId } = this.props.match.params;
|
||||
this.getCommit(owner,projectsId,mergeId);
|
||||
this.getFile(owner,projectsId,mergeId);
|
||||
}
|
||||
this.setState({
|
||||
activeKey:footer_type ? "1" : "2",
|
||||
commitCount:data && data.commits_count,
|
||||
filesCount:data && data.files_count
|
||||
})
|
||||
}
|
||||
componentDidUpdate=(prevProps)=>{
|
||||
const { comparesData } = this.props;
|
||||
const { footer_type } = this.props;
|
||||
if(footer_type){
|
||||
const { data } = this.props;
|
||||
if(data !== prevProps.data){
|
||||
this.setState({
|
||||
commitCount:data && data.commits_count,
|
||||
filesCount:data && data.files_count
|
||||
})
|
||||
}
|
||||
}
|
||||
if(comparesData !== prevProps.comparesData){
|
||||
this.setState({
|
||||
activeKey:footer_type ? "1" : "2"
|
||||
})
|
||||
this.changeTab(footer_type ? "1" : "2");
|
||||
}
|
||||
}
|
||||
|
||||
changeTab=(index)=>{
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
this.setState({
|
||||
activeKey:index
|
||||
})
|
||||
const { footer_type , comparesData } = this.props;
|
||||
const { projectsId , owner , mergeId } = this.props.match.params;
|
||||
|
||||
if(footer_type){
|
||||
if(index === "2"){
|
||||
this.getCommit(owner,projectsId,mergeId);
|
||||
}else if(index === "3"){
|
||||
this.getFile(owner,projectsId,mergeId);
|
||||
}else{
|
||||
this.setState({
|
||||
isSpin:false
|
||||
})
|
||||
}
|
||||
}else{
|
||||
this.setState({
|
||||
commitsData:comparesData.commits,
|
||||
filesData:comparesData.diff,
|
||||
commitCount:comparesData.commits_count,
|
||||
filesCount:comparesData.diff && comparesData.diff.files_count,
|
||||
isSpin:false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
getCommit =(owner,projectsId,mergeId)=>{
|
||||
const url = `/${owner}/${projectsId}/pulls/${mergeId}/commits.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
commitsData:result.data.commits,
|
||||
isSpin:false,
|
||||
commitCount:result.data.commits_count
|
||||
})
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
getFile =(owner,projectsId,mergeId)=>{
|
||||
const url = `/${owner}/${projectsId}/pulls/${mergeId}/files.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
filesData:result.data,
|
||||
isSpin:false,
|
||||
filesCount:result.data.files_count,
|
||||
})
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
render() {
|
||||
const { footer_type, order_id } = this.props;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
|
||||
const { footer_type, order_id, data , comparesData } = this.props;
|
||||
let { isSpin , activeKey , filesCount, commitCount , filesData , commitsData } = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Tabs
|
||||
defaultActiveKey={footer_type === "show" ? "1" : "2"}
|
||||
className="custom-commit-tabs"
|
||||
>
|
||||
{
|
||||
footer_type === "show" &&
|
||||
<TabPane tab={<span className="ml-3 font-16">评论</span>} key="1">
|
||||
<Comments
|
||||
order_id={order_id}
|
||||
showNotification={this.props.showNotification}
|
||||
only_show_content={true}
|
||||
{...this.props}
|
||||
/>
|
||||
</TabPane>
|
||||
}
|
||||
|
||||
{/* <TabPane tab={<span className="ml-3 font-16">提交</span>} key="2">
|
||||
<CodesCommit {...this.props} main_class="pd10"></CodesCommit>
|
||||
</TabPane> */}
|
||||
{/* <TabPane tab={<span className="ml-3 font-16">文件</span>} key="3">
|
||||
<Empty />
|
||||
</TabPane> */}
|
||||
</Tabs>
|
||||
!footer_type && !comparesData || (comparesData && ((comparesData.commits && comparesData.commits.length===0)||(comparesData && !comparesData.diff)) )?"":
|
||||
<div className="main" style={{paddingTop:"0px"}}>
|
||||
<Spin spinning={isSpin}>
|
||||
<Tabs
|
||||
activeKey={activeKey}
|
||||
className="custom-commit-tabs"
|
||||
animated={false}
|
||||
onChange={this.changeTab}
|
||||
>
|
||||
{
|
||||
footer_type &&
|
||||
<TabPane
|
||||
tab={
|
||||
<span><span className="font-16">评论</span>
|
||||
{data && parseInt(data.comments_count) > 0 && <span className="tabNum">{data.comments_count}</span>}
|
||||
</span>
|
||||
} key="1">
|
||||
<Comments
|
||||
order_id={order_id}
|
||||
showNotification={this.props.showNotification}
|
||||
only_show_content={true}
|
||||
{...this.props}
|
||||
/>
|
||||
</TabPane>
|
||||
}
|
||||
{
|
||||
commitsData && commitsData.length > 0 &&
|
||||
<TabPane tab={<span><span className="font-16">提交</span>
|
||||
{commitCount > 0 && <span className="tabNum">{commitCount}</span>}
|
||||
</span>} key="2">
|
||||
<Commits {...this.props} commits={commitsData} projectsId={projectsId} owner={owner}></Commits>
|
||||
</TabPane>
|
||||
}
|
||||
{
|
||||
filesData && filesData.files && filesData.files.length>0 &&
|
||||
<TabPane tab={
|
||||
<span><span className="font-16">文件</span>
|
||||
{filesCount > 0 && <span className="tabNum">{filesCount}</span>}
|
||||
</span>
|
||||
} key="3">
|
||||
<Files {...this.props} data={filesData} projectsId={projectsId} owner={owner}/>
|
||||
</TabPane>
|
||||
}
|
||||
|
||||
</Tabs>
|
||||
</Spin>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -46,10 +46,10 @@ class MergeForm extends Component {
|
|||
// }
|
||||
// };
|
||||
get_default_selects = () => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId ,owner } = this.props.match.params;
|
||||
this.setState({ isSpin: true });
|
||||
axios
|
||||
.get(`/projects/${projectsId}/pull_requests/create_merge_infos.json`)
|
||||
.get(`/${owner}/${projectsId}/pulls/create_merge_infos.json`)
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
|
@ -137,8 +137,8 @@ class MergeForm extends Component {
|
|||
});
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
const { projectsId, mergeId } = this.props.match.params;
|
||||
const { merge, pull, merge_type, data } = this.props;
|
||||
const { projectsId, mergeId , owner } = this.props.match.params;
|
||||
const { merge, pull, merge_type, data , commits_count , files_count } = this.props;
|
||||
if (values.issue_tag_ids && values.issue_tag_ids.length > 0) {
|
||||
values.issue_tag_ids = [parseInt(values.issue_tag_ids)];
|
||||
} else {
|
||||
|
@ -146,66 +146,67 @@ class MergeForm extends Component {
|
|||
}
|
||||
const { desc } = this.state;
|
||||
if (merge_type === "new") {
|
||||
let url = `/projects/${projectsId}/pull_requests.json`;
|
||||
axios
|
||||
.post(url, {
|
||||
...values,
|
||||
body: desc,
|
||||
head: pull,
|
||||
base: merge,
|
||||
is_original: data && data.is_original,
|
||||
fork_project_id: data && data.fork_project_id,
|
||||
merge_user_login: data && data.merge_user_login
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
this.props.history.push(`/projects/${projectsId}/merge`);
|
||||
const { getDetail } = this.props;
|
||||
getDetail && getDetail();
|
||||
} else {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
let url = `/${owner}/${projectsId}/pulls.json`;
|
||||
axios.post(url, {
|
||||
...values,
|
||||
body: desc,
|
||||
head: pull,
|
||||
base: merge,
|
||||
is_original: data && data.is_original,
|
||||
fork_project_id: data && data.fork_project_id,
|
||||
merge_user_login: data && data.merge_user_login,
|
||||
files_count,
|
||||
commits_count
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
console.log(error);
|
||||
});
|
||||
} else {
|
||||
let url = `/projects/${projectsId}/pull_requests/${mergeId}.json`;
|
||||
axios
|
||||
.put(url, {
|
||||
...values,
|
||||
body: desc,
|
||||
head: pull,
|
||||
base: merge,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
this.props.history.push(
|
||||
`/projects/${projectsId}/merge/${mergeId}/Messagecount`
|
||||
);
|
||||
} else {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/pulls`);
|
||||
const { getDetail } = this.props;
|
||||
getDetail && getDetail();
|
||||
} else {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
console.log(error);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
console.log(error);
|
||||
});
|
||||
} else {
|
||||
let url = `/${owner}/${projectsId}/pulls/${mergeId}.json`;
|
||||
axios
|
||||
.put(url, {
|
||||
...values,
|
||||
body: desc,
|
||||
head: pull,
|
||||
base: merge,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
this.props.history.push(
|
||||
`/projects/${owner}/${projectsId}/pulls/${mergeId}/Messagecount`
|
||||
);
|
||||
} else {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.setState({
|
||||
|
@ -222,9 +223,9 @@ class MergeForm extends Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { merge_type, data } = this.props;
|
||||
const { merge_type } = this.props;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const { projectsId, mergeId } = this.props.match.params;
|
||||
const { projectsId, mergeId ,owner } = this.props.match.params;
|
||||
const {
|
||||
issue_tag_ids,
|
||||
fixed_version_id,
|
||||
|
@ -283,11 +284,9 @@ class MergeForm extends Component {
|
|||
<Button
|
||||
type="default"
|
||||
className="ml30"
|
||||
href={
|
||||
merge_type === "new"
|
||||
? `/projects/${projectsId}/merge`
|
||||
: `/projects/${projectsId}/merge/${mergeId}/detail`
|
||||
}
|
||||
onClick={()=>{
|
||||
this.props.history.push(merge_type === "new" ? `/projects/${owner}/${projectsId}/pulls` : `/projects/${owner}/${projectsId}/pulls/${mergeId}/detail`)
|
||||
}}
|
||||
>
|
||||
<span className="plr10">取消</span>
|
||||
</Button>
|
||||
|
|
|
@ -2,7 +2,7 @@ import React , { Component } from 'react';
|
|||
import { Link } from "react-router-dom";
|
||||
class Nodata extends Component{
|
||||
render(){
|
||||
const { _html, projectsId } = this.props;
|
||||
const { _html, projectsId , owner } = this.props;
|
||||
return(
|
||||
<div className="none_panels">
|
||||
<div>
|
||||
|
@ -12,7 +12,7 @@ class Nodata extends Component{
|
|||
<h3>欢迎使用合并请求!</h3>
|
||||
|
||||
<div className="color-grey-8">
|
||||
合并请求可以帮助您与他人协作编写代码。在使用之前,请先创建一个 <Link className="color-blue" to={`/projects/${projectsId}/merge/new`}>合并请求</Link>
|
||||
合并请求可以帮助您与他人协作编写代码。在使用之前,请先创建一个 <Link className="color-blue" to={`/projects/${owner}/${projectsId}/pulls/new`}>合并请求</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -150,7 +150,7 @@ class Index extends Component {
|
|||
isSpin: false
|
||||
})
|
||||
this.props.showNotification(`${projectsType === "deposit" ? "托管" : "镜像"}项目创建成功!`);
|
||||
this.props.history.push(`/projects/${result.data.id}/coders`);
|
||||
this.props.history.push(`/projects/${current_user && current_user.login}/${result.data.identifier}`);
|
||||
}
|
||||
}
|
||||
}).catch((error) => {
|
||||
|
|
|
@ -51,9 +51,7 @@ class Index extends Component {
|
|||
<div className="grid-item">
|
||||
<div className="setInputAddon">
|
||||
<Input
|
||||
addonBefore={`/${
|
||||
projectDetail && projectDetail.identifier
|
||||
}${urlroot}/`}
|
||||
addonBefore={`/${ projectDetail && projectDetail.identifier }${urlroot}/`}
|
||||
value={filename}
|
||||
onChange={this.changeFileName}
|
||||
placeholder="命名文件..."
|
||||
|
|
|
@ -32,39 +32,36 @@ class UserSubmitComponent extends Component {
|
|||
// 提交变更
|
||||
subMitFrom = () => {
|
||||
const { filepath, content, editor_type } = this.props;
|
||||
const { branch, projectsId } = this.props.match.params;
|
||||
const { branch, projectsId , owner } = this.props.match.params;
|
||||
const { submitType, filename } = this.state;
|
||||
this.setState({ isSpin: true });
|
||||
let path = editor_type === "upload" ? filepath : filepath.substr(1);
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
const url = `/repositories/${projectsId}/create_file.json`;
|
||||
axios
|
||||
.post(url, {
|
||||
filepath: filename ? filename : path,
|
||||
branch: branch,
|
||||
new_branch: submitType === "1" ? values.branchname : undefined,
|
||||
content,
|
||||
message: values.desc,
|
||||
})
|
||||
.then((result) => {
|
||||
this.setState({ isSpin: false });
|
||||
if (result.data && result.data.name) {
|
||||
this.props.showNotification("文件新建成功!");
|
||||
if(submitType === "1"){
|
||||
const { getTopCount } = this.props;
|
||||
getTopCount && getTopCount(values.branchname);
|
||||
}
|
||||
let url = values.branchname
|
||||
? `/projects/${projectsId}/coders?branch=${values.branchname}`
|
||||
: `/projects/${projectsId}/coders`;
|
||||
this.props.history.push(url);
|
||||
const url = `/${owner}/${projectsId}/create_file.json`;
|
||||
axios.post(url, {
|
||||
filepath: filename ? filename : path,
|
||||
branch: branch,
|
||||
new_branch: submitType === "1" ? values.branchname : undefined,
|
||||
content,
|
||||
message: values.desc,
|
||||
})
|
||||
.then((result) => {
|
||||
this.setState({ isSpin: false });
|
||||
if (result.data && result.data.name) {
|
||||
this.props.showNotification("文件新建成功!");
|
||||
if(submitType === "1"){
|
||||
const { getTopCount } = this.props;
|
||||
getTopCount && getTopCount(values.branchname);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({ isSpin: false });
|
||||
console.log(error);
|
||||
});
|
||||
let url = `/projects/${owner}/${projectsId}${values.branchname ? `/branch/${values.branchname}`: (branch ? `/branch/${branch}` : "")}`;
|
||||
this.props.history.push(url);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({ isSpin: false });
|
||||
console.log(error);
|
||||
});
|
||||
} else {
|
||||
this.setState({ isSpin: false });
|
||||
}
|
||||
|
@ -74,16 +71,16 @@ class UserSubmitComponent extends Component {
|
|||
// 确认修改文件
|
||||
UpdateFile = () => {
|
||||
this.setState({ isSpin: true });
|
||||
const { branch, detail, content, filepath } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { branch, detail, content , currentBranch } = this.props;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { submitType } = this.state;
|
||||
const url = `/repositories/${projectsId}/update_file.json`;
|
||||
const url = `/${owner}/${projectsId}/update_file.json`;
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
axios
|
||||
.put(url, {
|
||||
filepath: detail.path,
|
||||
branch: branch,
|
||||
branch: submitType === "1" ? undefined : (currentBranch || branch),
|
||||
new_branch: submitType === "1" ? values.branchname : undefined,
|
||||
content: content,
|
||||
sha: detail.sha,
|
||||
|
@ -92,12 +89,10 @@ class UserSubmitComponent extends Component {
|
|||
.then((result) => {
|
||||
this.setState({ isSpin: false });
|
||||
if (result.data && result.data.status === 1) {
|
||||
let url = values.branchname
|
||||
? `/projects/${projectsId}/coders?branch=${values.branchname}`
|
||||
: `/projects/${projectsId}/coders`;
|
||||
|
||||
debugger;
|
||||
let url = `/projects/${owner}/${projectsId}${(values.branchname ? `/branch/${values.branchname}` : ((currentBranch || branch) ? `/branch/${currentBranch || branch}`:""))}`;
|
||||
this.props.history.push(url);
|
||||
this.props.showNotification("修改成功!");
|
||||
this.props.showNotification("文件修改成功!");
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
@ -114,22 +109,16 @@ class UserSubmitComponent extends Component {
|
|||
const { submitType, filename, isSpin } = this.state;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
|
||||
const { branch, projectsId } = this.props.match.params;
|
||||
const { branch, projectsId , owner } = this.props.match.params;
|
||||
|
||||
const { current_user, filepath, projectDetail } = this.props;
|
||||
const { current_user, filepath, projectDetail , currentBranch } = this.props;
|
||||
const { editor_type } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<span className="df mt30" style={{ alignItems: "center" }}>
|
||||
<Link
|
||||
to={`/users/${current_user && current_user.login}`}
|
||||
className="show-user-link"
|
||||
>
|
||||
<Link to={`/users/${current_user && current_user.login}`} className="show-user-link" >
|
||||
<img
|
||||
src={getImageUrl(
|
||||
`images/${current_user && current_user.image_url}`
|
||||
)}
|
||||
src={getImageUrl(`images/${current_user && current_user.image_url}`)}
|
||||
alt=""
|
||||
className="screwImg"
|
||||
/>
|
||||
|
@ -137,7 +126,6 @@ class UserSubmitComponent extends Component {
|
|||
{current_user && current_user.username}:
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
<span className="color-grey-8">提交变更</span>
|
||||
</span>
|
||||
<Spin spinning={isSpin}>
|
||||
|
@ -154,10 +142,8 @@ class UserSubmitComponent extends Component {
|
|||
})(
|
||||
<div className="setInputAddon">
|
||||
<Input
|
||||
addonBefore={`/${
|
||||
projectDetail && projectDetail.identifier
|
||||
}/`}
|
||||
value={filename ? filename : filepath}
|
||||
addonBefore={`/${ projectDetail && projectDetail.identifier }/`}
|
||||
value={filename || filepath}
|
||||
onChange={this.changeFileName}
|
||||
placeholder="文件路径..."
|
||||
/>
|
||||
|
@ -185,7 +171,7 @@ class UserSubmitComponent extends Component {
|
|||
>
|
||||
<Radio value="0" className="mb10">
|
||||
<i className="iconfont icon-banbenku font-16 mr5"></i>
|
||||
直接提交至<span className="color-orange">{branch}</span>分支
|
||||
直接提交至<span className="color-orange">{currentBranch || branch}</span>分支
|
||||
</Radio>
|
||||
<Radio value="1">
|
||||
<Icon type="pull-request" className="mr5" />
|
||||
|
@ -229,7 +215,7 @@ class UserSubmitComponent extends Component {
|
|||
<Button
|
||||
type="primary grey"
|
||||
onClick={() => {
|
||||
this.props.history.push(`/projects/${projectsId}/coders`);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}`);
|
||||
}}
|
||||
className="mr20"
|
||||
>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React, { Component } from "react";
|
||||
import Editor from "react-monaco-editor";
|
||||
|
||||
import UserSubmitComponent from "./UserSubmitComponent";
|
||||
|
||||
import "./index.css";
|
||||
|
@ -21,7 +20,7 @@ class m_editor extends Component {
|
|||
|
||||
render() {
|
||||
const { editorValue } = this.state;
|
||||
const { readOnly, editorType, language } = this.props;
|
||||
const { readOnly, editorType, language , currentBranch } = this.props;
|
||||
const editor_options = {
|
||||
lineNumbers: "on",
|
||||
wordWrap: true, //强制换行
|
||||
|
@ -29,6 +28,7 @@ class m_editor extends Component {
|
|||
lineHeight: 24,
|
||||
renderLineHighlight: "line",
|
||||
revealHorizontalRightPadding: 5,
|
||||
placeholder:"请输入内容",
|
||||
readOnly: readOnly,
|
||||
cursorStyle: readOnly ? "underline-thin" : "line",
|
||||
folding: true,
|
||||
|
@ -46,16 +46,17 @@ class m_editor extends Component {
|
|||
<div>
|
||||
<div className="branchTable">
|
||||
<Editor
|
||||
height="600px"
|
||||
height="400px"
|
||||
language={language ? language : "plaintext"}
|
||||
theme={"vs-grey"}
|
||||
defaultValue="请输入内容"
|
||||
placeholder="请输入内容"
|
||||
value={editorValue}
|
||||
options={editor_options}
|
||||
onChange={this.changeEditor}
|
||||
editorWillMount={this.editorWillMount}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{!readOnly && (
|
||||
<UserSubmitComponent
|
||||
{...this.props}
|
||||
|
@ -63,6 +64,7 @@ class m_editor extends Component {
|
|||
filepath={`${this.props.filepath}`}
|
||||
content={editorValue}
|
||||
editor_type={editorType}
|
||||
currentBranch={currentBranch}
|
||||
></UserSubmitComponent>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -27,7 +27,7 @@ class UploadFile extends Component {
|
|||
const { pathname } = this.props.location;
|
||||
const { filename, editorValue, attachment_clean } = this.state;
|
||||
const urlroot = pathname.split("uploadfile/")[1];
|
||||
const file_path = !urlroot ? `${filename}` : `${urlroot}/${filename}`;
|
||||
const file_path = !urlroot ? filename : `${urlroot}/${filename}`;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Link } from "react-router-dom";
|
|||
|
||||
import axios from "axios";
|
||||
import { getImageUrl } from "educoder";
|
||||
import { Form , Popconfirm , Tag , Spin } from "antd";
|
||||
import { Form, Popconfirm, Tag, Spin } from "antd";
|
||||
import Attachments from "../Upload/attachment";
|
||||
import RenderHtml from "../../components/render-html";
|
||||
import Comments from "../comments/comments";
|
||||
|
@ -44,15 +44,15 @@ class Detail extends Component {
|
|||
};
|
||||
|
||||
getDetail = () => {
|
||||
const { projectsId, orderId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}.json`;
|
||||
const { projectsId, orderId, owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/issues/${orderId}.json`;
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
data: result.data,
|
||||
isSpins:false
|
||||
isSpins: false
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -74,8 +74,8 @@ class Detail extends Component {
|
|||
|
||||
//删除任务信息
|
||||
deletedetail = (id) => {
|
||||
const { projectsId, orderId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}.json`;
|
||||
const { projectsId, orderId, owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/issues/${orderId}.json`;
|
||||
axios
|
||||
.delete(url, {
|
||||
data: {
|
||||
|
@ -85,7 +85,7 @@ class Detail extends Component {
|
|||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.props.history.push(`/projects/${projectsId}/orders`);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/issues`);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
@ -95,8 +95,8 @@ class Detail extends Component {
|
|||
|
||||
//关闭任务
|
||||
closedetail = (id) => {
|
||||
const { projectsId, orderId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}/close_issue.json`;
|
||||
const { projectsId, orderId, owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/issues/${orderId}/close_issue.json`;
|
||||
axios
|
||||
.post(url, {
|
||||
project_id: projectsId,
|
||||
|
@ -122,8 +122,8 @@ class Detail extends Component {
|
|||
|
||||
//复制
|
||||
copydetail = () => {
|
||||
const { projectsId, orderId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}/copy.json`;
|
||||
const { projectsId, orderId, owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/issues/${orderId}/copy.json`;
|
||||
axios
|
||||
.post(url, {
|
||||
project_id: projectsId,
|
||||
|
@ -132,7 +132,7 @@ class Detail extends Component {
|
|||
.then((result) => {
|
||||
if (result) {
|
||||
this.props.history.push(
|
||||
`/projects/${projectsId}/orders/${result.data.issue_id}/copyetail`
|
||||
`/projects/${owner}/${projectsId}/issues/${result.data.issue_id}/copyetail`
|
||||
);
|
||||
}
|
||||
})
|
||||
|
@ -182,12 +182,12 @@ class Detail extends Component {
|
|||
};
|
||||
|
||||
commentCtx = (v) => {
|
||||
return <RenderHtml className="break_word_comments" value={v} />;
|
||||
return <RenderHtml className="break_word_comments imageLayerParent" value={v} />;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { projectsId, orderId } = this.props.match.params;
|
||||
const { data , isSpins } = this.state;
|
||||
const { projectsId, orderId, owner } = this.props.match.params;
|
||||
const { data, isSpins } = this.state;
|
||||
const get_color = (type) => {
|
||||
if (type === "高") {
|
||||
return "#e67e22";
|
||||
|
@ -269,15 +269,15 @@ class Detail extends Component {
|
|||
</Popconfirm>
|
||||
|
||||
<Link
|
||||
to={`/projects/${projectsId}/orders/${orderId}/updatedetail`}
|
||||
to={`/projects/${owner}/${projectsId}/issues/${orderId}/updatedetail`}
|
||||
className="color-blue fr"
|
||||
>
|
||||
编辑
|
||||
</Link>
|
||||
</span>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -286,8 +286,8 @@ class Detail extends Component {
|
|||
{data && data.description && data.description.length > 0 ? (
|
||||
this.commentCtx(data.description)
|
||||
) : (
|
||||
<span className="color-grey-9 ml3 mr3">没有描述</span>
|
||||
)}
|
||||
<span className="color-grey-9 ml3 mr3">暂无描述</span>
|
||||
)}
|
||||
</div>
|
||||
{data && data.attachments && data.attachments.length > 0 ? (
|
||||
<Attachments
|
||||
|
@ -295,8 +295,8 @@ class Detail extends Component {
|
|||
showNotification={this.props.showNotification}
|
||||
/>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -307,77 +307,66 @@ class Detail extends Component {
|
|||
/>
|
||||
</div>
|
||||
<div className="list-left list-left-padding">
|
||||
<div className="list-right-item-padding background-f boder-4">
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">分支:</span>
|
||||
<span>{data && data.branch_name ? data.branch_name : "--"}</span>
|
||||
</p>
|
||||
{/* <p className="grid-item pb15">
|
||||
<span className="issue_detail_info">是否上链:</span>
|
||||
<span>{data && data.issue_type==="2" ? '是' : "--"}</span>
|
||||
</p>
|
||||
{
|
||||
data && data.issue_type==="2" &&
|
||||
<p className="grid-item pb15">
|
||||
<span className="issue_detail_info">token值:</span>
|
||||
<span>{data && data.token ? data.token : "--"}</span>
|
||||
</p>
|
||||
} */}
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">标签:</span>
|
||||
<span>
|
||||
{data && data.issue_tags ? (
|
||||
<span className="grid-item">
|
||||
<span
|
||||
className="tagColor"
|
||||
style={{ background: data.issue_tags[0].color }}
|
||||
></span>
|
||||
{data.issue_tags[0].name}
|
||||
</span>
|
||||
) : (
|
||||
"--"
|
||||
)}
|
||||
</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">里程碑:</span>
|
||||
<span className="title_overflow">
|
||||
{data && data.version ? data.version : "--"}
|
||||
</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">状态:</span>
|
||||
<span>
|
||||
{data && data.issue_status ? data.issue_status : "--"}
|
||||
</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">分类:</span>
|
||||
<span>{data && data.tracker ? data.tracker : "--"}</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">负责人:</span>
|
||||
<span>
|
||||
{data && data.assign_user_name ? data.assign_user_name : "--"}
|
||||
</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">开始日期:</span>
|
||||
<span>{data && data.start_date ? data.start_date : "--"}</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">结束日期:</span>
|
||||
<span>{data && data.due_date ? data.due_date : "--"}</span>
|
||||
</p>
|
||||
<div className="list-right-item-padding background-f boder-4">
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">负责人:</span>
|
||||
<span>
|
||||
{data && data.assign_user_name ? data.assign_user_name : "--"}
|
||||
</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">标签:</span>
|
||||
<span>
|
||||
{data && data.issue_tags ? (
|
||||
<span className="grid-item">
|
||||
<span
|
||||
className="tagColor"
|
||||
style={{ background: data.issue_tags[0].color }}
|
||||
></span>
|
||||
{data.issue_tags[0].name}
|
||||
</span>
|
||||
) : (
|
||||
"--"
|
||||
)}
|
||||
</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">里程碑:</span>
|
||||
<span className="title_overflow">
|
||||
{data && data.version ? data.version : "--"}
|
||||
</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">状态:</span>
|
||||
<span>
|
||||
{data && data.issue_status ? data.issue_status : "--"}
|
||||
</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">分类:</span>
|
||||
<span>{data && data.tracker ? data.tracker : "--"}</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">开始日期:</span>
|
||||
<span>{data && data.start_date ? data.start_date : "--"}</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">结束日期:</span>
|
||||
<span>{data && data.due_date ? data.due_date : "--"}</span>
|
||||
</p>
|
||||
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">完成度:</span>
|
||||
<span>{data && data.done_ratio ? data.done_ratio : "--"}</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">完成度:</span>
|
||||
<span>{data && data.done_ratio ? data.done_ratio : "--"}</span>
|
||||
</p>
|
||||
<p className="grid-item-left pb15">
|
||||
<span className="issue_detail_info">分支:</span>
|
||||
<span>{data && data.branch_name ? data.branch_name : "--"}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Spin>
|
||||
</Spin>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,9 +31,9 @@ class Milepost extends Component {
|
|||
}
|
||||
|
||||
getList = (page, status, order_type, order_name) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId ,owner } = this.props.match.params;
|
||||
const { limit } = this.state;
|
||||
const url = `/projects/${projectsId}/versions.json`;
|
||||
const url = `/${owner}/${projectsId}/milestones.json`;
|
||||
axios.get(url, {
|
||||
params: {
|
||||
projectsId, page, limit, status, order_type, order_name
|
||||
|
@ -75,8 +75,8 @@ class Milepost extends Component {
|
|||
}
|
||||
|
||||
updatestatusemile = (status, arr) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/versions/${arr.id}/update_status.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/milestones/${arr.id}/update_status.json`;
|
||||
const { current_user } = this.props;
|
||||
axios.post(url, {
|
||||
project_id: projectsId,
|
||||
|
@ -98,8 +98,8 @@ class Milepost extends Component {
|
|||
}
|
||||
|
||||
closemile = (arr) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/versions/${arr.id}.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/milestones/${arr.id}.json`;
|
||||
axios.delete(url, {
|
||||
data: {
|
||||
project_id: projectsId,
|
||||
|
@ -148,7 +148,7 @@ class Milepost extends Component {
|
|||
|
||||
render() {
|
||||
const { data, limit, page, openselect, closeselect, spinings } = this.state;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const menu = (
|
||||
<Menu onClick={this.arrayList}>
|
||||
<Menu.Item key={'created_on'} value="desc">到期日从近到远</Menu.Item>
|
||||
|
@ -169,7 +169,7 @@ class Milepost extends Component {
|
|||
<span>里程碑{data && data.issue_tags_count}已创建</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="topWrapper">
|
||||
<div className="topWrapper" style={{borderBottom:"1px solid #eee"}}>
|
||||
<div className="topWrapper_type_infos">
|
||||
<li className={openselect ? "active" : ""} onClick={() => this.opneMilelist(1)}>{data && data.open_count}个开启中</li>
|
||||
<li className={closeselect ? "active" : ""} onClick={() => this.opneMilelist(2)}>{data && data.closed_count}个已关闭</li>
|
||||
|
@ -184,7 +184,7 @@ class Milepost extends Component {
|
|||
</ul>
|
||||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<Link to={`/projects/${projectsId}/orders/meilpost`} className="topWrapper_btn">新的里程碑</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/milestones/new`} className="topWrapper_btn">新的里程碑</Link>
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
|
@ -201,7 +201,7 @@ class Milepost extends Component {
|
|||
<div className="milepostwidth">
|
||||
<div className="grid-item width100">
|
||||
<i className="iconfont icon-lubiaosignpost3 font-12 mr3"></i>
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/MilepostDetail`} className="font-16">{item.name}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/milestones/${item.id}`} className="font-16">{item.name}</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -223,15 +223,15 @@ class Milepost extends Component {
|
|||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<div className="milepostleft">
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<div className="grid-item ml15 color-grey-9">
|
||||
<i className="iconfont icon-bianji3 font-14 mr5"></i>
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/meilpost`} className="color-grey-9">编辑</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/milestones/${item.id}/edit`} className="color-grey-9">编辑</Link>
|
||||
</div>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<div className="grid-item ml15 color-grey-9">
|
||||
<i className="iconfont icon-yiguanbi1 font-14 mr5"></i>
|
||||
<a onClick={() => this.updatestatusemile(this.state.status === "closed" ? "open" : "closed", item)} className="color-grey-9">{this.state.status === "closed" ? "开启" : "关闭"}</a>
|
||||
</div>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<div className="grid-item ml15 color-grey-9">
|
||||
<i className="iconfont icon-lajitong font-14 mr5" ></i>
|
||||
<Popconfirm placement="bottom" title={'是否删除里程碑?'} okText="是" cancelText="否" onConfirm={() => this.closemile(item)}>
|
||||
<a className="color-grey-9">删除</a>
|
||||
|
@ -251,7 +251,7 @@ class Milepost extends Component {
|
|||
})
|
||||
}
|
||||
</div>
|
||||
: <NoneData _html="暂时还没有相关数据哦!" />
|
||||
: <NoneData _html="暂时还没有相关数据!" />
|
||||
}
|
||||
{
|
||||
data && data.versions_count > limit ?
|
||||
|
|
|
@ -2,6 +2,7 @@ import React, { Component } from "react";
|
|||
import { Link } from 'react-router-dom';
|
||||
import { Dropdown, Menu, Icon, Pagination, Spin } from 'antd';
|
||||
import './order.css';
|
||||
import { FlexAJ } from '../Component/layout'
|
||||
|
||||
import NoneData from '../Nodata';
|
||||
import OrderItem from './OrderItem';
|
||||
|
@ -13,7 +14,6 @@ import axios from 'axios';
|
|||
* data:列表接口返回的所有数据,
|
||||
* issues:列表数组,
|
||||
* isSpin:加载中,
|
||||
* search:搜索关键字,
|
||||
* author_id:发布者id,
|
||||
* assigned_to_id:指派给。。。的id,
|
||||
* limit:每页条数,
|
||||
|
@ -30,8 +30,8 @@ class MilepostDetail extends Component {
|
|||
data: undefined,
|
||||
issues: undefined,
|
||||
isSpin: true,
|
||||
search: undefined,
|
||||
author_id: undefined,
|
||||
status_id: undefined,
|
||||
assigned_to_id: undefined,
|
||||
limit: 15,
|
||||
page: 1,
|
||||
|
@ -39,13 +39,11 @@ class MilepostDetail extends Component {
|
|||
issue_type: undefined,
|
||||
status_type: '1',
|
||||
//设置选择高亮
|
||||
openselect: 1,
|
||||
closeselect: undefined,
|
||||
issue_tag_ids: '标签',
|
||||
tracker_ids: '所有分类',
|
||||
tracker_ids: '类型',
|
||||
author_ids: '发布人',
|
||||
assigned_to_ids: '指派人',
|
||||
priority_ids: '优先度',
|
||||
assigned_to_ids: '负责人',
|
||||
status_ids: "状态",
|
||||
done_ratios: '完成度',
|
||||
paix: '排序'
|
||||
}
|
||||
|
@ -53,12 +51,13 @@ class MilepostDetail extends Component {
|
|||
|
||||
componentDidMount = () => {
|
||||
this.getSelectList();
|
||||
this.getIssueList();
|
||||
const { page } = this.state;
|
||||
this.getIssueList(page);
|
||||
}
|
||||
|
||||
getSelectList = () => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/index_chosen.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/issues/index_chosen.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
|
@ -71,14 +70,23 @@ class MilepostDetail extends Component {
|
|||
}
|
||||
|
||||
// 获取列表数据
|
||||
getIssueList = (page, limit, search, author_id, assigned_to_id, status_type, id, value, order_name, order_type) => {
|
||||
const { projectsId, meilid } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/versions/${meilid}.json`;
|
||||
getIssueList = ( page , item , value , update , updateValue , type ) => {
|
||||
const { projectsId, meilid , owner } = this.props.match.params;
|
||||
const { limit , order_name , order_type , issue_tag_id , author_id , assigned_to_id , tracker_id , status_id , done_ratio , status_type } = this.state;
|
||||
|
||||
const url = `/${owner}/${projectsId}/milestones/${meilid}.json`;
|
||||
let params = update ? {
|
||||
page, limit , order_name:value , order_type:updateValue , issue_tag_id ,
|
||||
author_id , assigned_to_id , tracker_id , status_id , done_ratio,
|
||||
status_type:type || status_type,
|
||||
}:{
|
||||
page, limit , order_name , order_type , issue_tag_id ,
|
||||
author_id , assigned_to_id , tracker_id , status_id , done_ratio,
|
||||
status_type:type || status_type,
|
||||
[item]:value
|
||||
}
|
||||
axios.get(url, {
|
||||
params: {
|
||||
page, limit, search, author_id, assigned_to_id, status_type, order_name, order_type,
|
||||
[id]: value
|
||||
}
|
||||
params: params
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
|
@ -94,85 +102,40 @@ class MilepostDetail extends Component {
|
|||
}
|
||||
|
||||
getOption = (e, id, name) => {
|
||||
if (id + 's' === "issue_tag_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
issue_tag_ids: name
|
||||
})
|
||||
}
|
||||
if (id + 's' === "tracker_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
tracker_ids: name
|
||||
})
|
||||
}
|
||||
if (id + 's' === "author_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
author_ids: name
|
||||
})
|
||||
}
|
||||
if (id + 's' === "assigned_to_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
assigned_to_ids: name
|
||||
})
|
||||
}
|
||||
if (id + 's' === "priority_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
priority_ids: name
|
||||
})
|
||||
}
|
||||
if (id + 's' === "done_ratios") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
done_ratios: name
|
||||
})
|
||||
}
|
||||
|
||||
if (e.key === "created_on") {
|
||||
if (e.item.props.value === "desc") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
paix: '最新创建'
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
paix: '最早创建'
|
||||
})
|
||||
}
|
||||
} else if (e.key === "updated_on") {
|
||||
if (e.item.props.value === "desc") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
paix: '最新更新'
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
paix: '最早更新'
|
||||
})
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
[id]: e.key
|
||||
[id]: e.key,
|
||||
[id+"s"]:name,
|
||||
page:1
|
||||
})
|
||||
|
||||
|
||||
const { page, limit, search, author_id, assigned_to_id, status_type } = this.state;
|
||||
if (e.key === "all") {
|
||||
this.getIssueList(page, limit, search, author_id, assigned_to_id, status_type, id);
|
||||
} else if (e.key === "created_on" || e.key === "updated_on") {
|
||||
if (e.key === "created_on" || e.key === "updated_on") {
|
||||
this.setState({
|
||||
order_name: e.key,
|
||||
order_type: e.item.props.value
|
||||
})
|
||||
this.getIssueList(page, limit, search, author_id, assigned_to_id, status_type, id, undefined, undefined, e.key, e.item.props.value);
|
||||
}
|
||||
else {
|
||||
this.getIssueList(page, limit, search, author_id, assigned_to_id, status_type, id, e.key);
|
||||
this.getIssueList(1,id,e.key,true,e.item.props.value);
|
||||
}else{
|
||||
this.getIssueList(1,id,e.key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,70 +160,35 @@ class MilepostDetail extends Component {
|
|||
page,
|
||||
isSpin: true
|
||||
})
|
||||
const { limit, search, status_type, author_id, assigned_to_id } = this.state;
|
||||
this.getIssueList(page, limit, search, author_id, assigned_to_id, status_type);
|
||||
}
|
||||
|
||||
// 搜索
|
||||
searchFunc = (value) => {
|
||||
this.setState({
|
||||
search: value,
|
||||
isSpin: true
|
||||
})
|
||||
const { page, limit, status_type, author_id, assigned_to_id } = this.state;
|
||||
this.getIssueList(page, limit, value, author_id, assigned_to_id, status_type);
|
||||
this.getIssueList(page);
|
||||
}
|
||||
|
||||
openorder = (type) => {
|
||||
if (type) {
|
||||
|
||||
const { current_user } = this.props;
|
||||
if (type === 1) {
|
||||
this.setState({
|
||||
status_type: '1',
|
||||
openselect: current_user.user_id,
|
||||
closeselect: undefined,
|
||||
issue_tag_ids: '标签',
|
||||
tracker_ids: '所有分类',
|
||||
author_ids: '发布人',
|
||||
assigned_to_ids: '指派人',
|
||||
priority_ids: '优先度',
|
||||
done_ratios: '完成度',
|
||||
paix: '排序'
|
||||
})
|
||||
this.getIssueList("", "", "", "", "", 1, "");
|
||||
|
||||
} else {
|
||||
this.setState({
|
||||
status_type: '2',
|
||||
openselect: undefined,
|
||||
closeselect: current_user.user_id,
|
||||
issue_tag_ids: '标签',
|
||||
tracker_ids: '所有分类',
|
||||
author_ids: '发布人',
|
||||
assigned_to_ids: '指派人',
|
||||
priority_ids: '优先度',
|
||||
done_ratios: '完成度',
|
||||
paix: '排序'
|
||||
})
|
||||
this.getIssueList("", "", "", "", "", 2, "");
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
status_type: type,
|
||||
issue_tag_id : undefined,
|
||||
author_id : undefined,
|
||||
tracker_id : undefined,
|
||||
done_ratio : undefined,
|
||||
status_id: undefined,
|
||||
assigned_to_id: undefined,
|
||||
issue_tag_ids: '标签',
|
||||
tracker_ids: '类型',
|
||||
author_ids: '发布人',
|
||||
assigned_to_ids: '负责人',
|
||||
status_ids: "状态",
|
||||
done_ratios: '完成度',
|
||||
paix: '排序'
|
||||
},() => {
|
||||
this.getIssueList(1,undefined,undefined,undefined,undefined,type);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
Paginations = (search_count) => {
|
||||
const { limit, page } = this.state;
|
||||
if(search_count > limit)
|
||||
return <div className="mt30 mb50 edu-txt-center">
|
||||
<Pagination simple defaultCurrent={page} total={search_count} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||||
</div>;
|
||||
};
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
const { issue_chosen, issues, limit, page, search_count, data, isSpin, openselect, closeselect } = this.state;
|
||||
const { projectsId, meilid } = this.props.match.params;
|
||||
const { issue_chosen, issues, limit, page, search_count, data, isSpin , status_type } = this.state;
|
||||
const { projectsId, meilid ,owner} = this.props.match.params;
|
||||
|
||||
const menu = (
|
||||
<Menu onClick={(e) => this.getOption(e)}>
|
||||
|
@ -271,89 +199,95 @@ class MilepostDetail extends Component {
|
|||
</Menu>
|
||||
)
|
||||
return (
|
||||
<div className="main">
|
||||
<div className="miledetail mb20">
|
||||
<div className="topmilepost">
|
||||
<p className="font-18">{data && data.name}</p>
|
||||
<div className="milepostdiv">
|
||||
<Link to={`/projects/${projectsId}/orders/${meilid}/meilpost`} className="topWrapper_btn" style={{ marginRight: 15 }} >编辑里程碑</Link>
|
||||
<Link to={`/projects/${projectsId}/orders/${meilid}/new`} className="topWrapper_btn">创建任务</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid-item mr10">
|
||||
<span className="mr10">
|
||||
<i className="iconfont icon-rili font-14 mr5">
|
||||
</i>
|
||||
{
|
||||
data && data.effective_date ?
|
||||
<span >{data && data.effective_date}</span>
|
||||
:
|
||||
<span >暂无截止时间</span>
|
||||
}
|
||||
<div className="main" style={{padding:"0px"}}>
|
||||
<div className="miledetail">
|
||||
<p className="font-20">{data && data.name}</p>
|
||||
<FlexAJ>
|
||||
<span className="mt7">
|
||||
<span className="mr10">
|
||||
<i className="iconfont icon-rili font-14 mr5">
|
||||
</i>
|
||||
{
|
||||
data && data.effective_date ?
|
||||
<span >{data && data.effective_date}</span>
|
||||
:
|
||||
<span >暂无截止时间</span>
|
||||
}
|
||||
</span>
|
||||
<span className="font-weight-bold">{data && data.percent && data.percent.toFixed(2)}%完成 </span>
|
||||
</span>
|
||||
<span className="font-weight-bold">
|
||||
{data && data.percent.toFixed(2)}%完成
|
||||
</span>
|
||||
</div>
|
||||
<div className="milepostdiv">
|
||||
<Link to={`/projects/${owner}/${projectsId}/milestones/${meilid}/edit`} className="topWrapper_btn" style={{ marginRight: 15 }} >编辑里程碑</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/issues/${meilid}/new`} className="topWrapper_btn">创建任务</Link>
|
||||
</div>
|
||||
</FlexAJ>
|
||||
</div>
|
||||
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="f-wrap-between pb20 bor-bottom-greyE">
|
||||
<ul className="topWrapper_type_infos">
|
||||
<li className={openselect ? "active" : ""} onClick={() => this.openorder(1)}>{data && data.open_issues_count}个开启中</li>
|
||||
<li className={closeselect ? "active" : ""} onClick={() => this.openorder(2)}>{data && data.close_issues_count}个已关闭</li>
|
||||
</ul>
|
||||
<ul className="topWrapper_select">
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.issue_tag, '标签', 'issue_tag_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.issue_tag_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.assign_user, '发布人', 'author_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.author_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.assign_user, '负责人', 'assigned_to_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.assigned_to_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.tracker, '所有分类', 'tracker_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.tracker_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.priority, '优先度', 'priority_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.priority_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.done_ratio, '完成度', 'done_ratio')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.done_ratios}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.paix}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="pl20 pr20">
|
||||
<div className="f-wrap-between pt15 pb15 bor-bottom-greyE">
|
||||
<ul className="topWrapper_type_infos">
|
||||
<li className={status_type==="1" ? "active" : ""} onClick={() => this.openorder("1")}>{data && data.open_issues_count}个开启中</li>
|
||||
<li className={status_type==="2" ? "active" : ""} onClick={() => this.openorder("2")}>{data && data.close_issues_count}个已关闭</li>
|
||||
</ul>
|
||||
<ul className="topWrapper_select">
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.issue_tag, '标签', 'issue_tag_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.issue_tag_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.assign_user, '发布人', 'author_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.author_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.assign_user, '负责人', 'assigned_to_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.assigned_to_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.tracker, '类型', 'tracker_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.tracker_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.issue_status, '状态', 'status_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.status_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.done_ratio, '完成度', 'done_ratio')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.done_ratios}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.paix}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="setItemStyle">
|
||||
{
|
||||
search_count === 0 ?
|
||||
<NoneData _html="暂时还没有相关数据!" />
|
||||
:
|
||||
issues && issues.length>0 && issues.map((item,key)=>{
|
||||
return(
|
||||
<OrderItem key={key} mile item={item} search_count={search_count} page={page} limit={limit} {...this.props} {...this.state}></OrderItem>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
{
|
||||
search_count > limit?
|
||||
<div className="mt30 mb10 edu-txt-center">
|
||||
<Pagination simple current={page} total={search_count} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||||
</div>:""
|
||||
}
|
||||
</div>
|
||||
{
|
||||
search_count === 0 ?
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
:
|
||||
issues && issues.length>0 && issues.map((item,key)=>{
|
||||
return(
|
||||
<OrderItem key={key} item={item} mile search_count={search_count} page={page} limit={limit} {...this.props} {...this.state}></OrderItem>
|
||||
)
|
||||
})
|
||||
}
|
||||
{this.Paginations(search_count)}
|
||||
</Spin>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class OrderItem extends Component {
|
|||
|
||||
render() {
|
||||
const { data } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -31,13 +31,12 @@ class OrderItem extends Component {
|
|||
<div className="milepostwidth">
|
||||
<div className="grid-item width100">
|
||||
<i className="iconfont icon-lubiaosignpost3 font-12 mr3"></i>
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/MilepostDetail`} className="font-16">{item.name}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/milestones/${item.id}`} className="font-16">{item.name}</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="milepostdiv" style={{ marginTop: 5 }}>
|
||||
<div className="milepostrighe">
|
||||
|
||||
<div className="grid-item mr10">
|
||||
<i className="iconfont icon-rili font-14 mr5">
|
||||
</i>
|
||||
|
@ -64,15 +63,15 @@ class OrderItem extends Component {
|
|||
{
|
||||
data.user_admin_or_member ?
|
||||
<div className="milepostleft">
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<div className="grid-item ml15 color-grey-9">
|
||||
<i className="iconfont icon-bianji3 font-14 mr5"></i>
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/meilpost`} className="color-grey-9">编辑</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/milestones/${item.id}/edit`} className="color-grey-9">编辑</Link>
|
||||
</div>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<div className="grid-item ml15 color-grey-9">
|
||||
<i className="iconfont icon-yiguanbi1 font-14 mr5"></i>
|
||||
<a onClick={() => this.updatestatusemile(this.state.status === "closed" ? "open" : "closed", item)} className="color-grey-9">{this.state.status === "closed" ? "开启" : "关闭"}</a>
|
||||
</div>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<div className="grid-item ml15 color-grey-9">
|
||||
<i className="iconfont icon-lajitong font-14 mr5" ></i>
|
||||
<Popconfirm placement="bottom" title={'是否删除里程碑?'} okText="是" cancelText="否" onConfirm={() => this.closemile(item)}>
|
||||
<a className="color-grey-9">删除</a>
|
||||
|
|
|
@ -4,11 +4,11 @@ import './order.css'
|
|||
class Nav extends Component{
|
||||
|
||||
render(){
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
return(
|
||||
<p className="topWrapper_nav">
|
||||
<NavLink activeClassName="active" className="issue-type-button" to={`/projects/${projectsId}/orders/tags`}>标签</NavLink>
|
||||
<NavLink activeClassName="active" className="issue-type-button" to={`/projects/${projectsId}/orders/Milepost`}>里程碑</NavLink>
|
||||
<NavLink activeClassName="active" className="issue-type-button" to={`/projects/${owner}/${projectsId}/issues/tags`}>标签</NavLink>
|
||||
<NavLink activeClassName="active" className="issue-type-button" to={`/projects/${owner}/${projectsId}/milestones`}>里程碑</NavLink>
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Popconfirm, Tag } from 'antd'
|
||||
import { Popconfirm } from 'antd'
|
||||
import { TagInfo } from '../Utils/TagColor';
|
||||
|
||||
|
||||
class OrderItem extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -45,7 +43,7 @@ class OrderItem extends Component {
|
|||
}
|
||||
render() {
|
||||
const { item , checkbox , mile } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { current_user } = this.props
|
||||
|
||||
return (
|
||||
|
@ -53,8 +51,8 @@ class OrderItem extends Component {
|
|||
<div className="issueItem">
|
||||
{current_user && current_user.login && checkbox}
|
||||
<div className="flex-1">
|
||||
<p className="mb15 df" style={{alignItems:"center"}}>
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/detail`} target="_blank" title={item.name} className="hide-1 font-16 color-grey-3 lineh-30 mr10" style={{maxWidth:"300px"}}>{item.name}</Link>
|
||||
<p className="mb10 df" style={{alignItems:"center"}}>
|
||||
<Link to={`/projects/${owner}/${projectsId}/issues/${item.id}/detail`} target="_blank" title={item.name} className="hide-1 font-16 color-grey-3 lineh-30 mr10" style={{maxWidth:"370px"}}>{item.name}</Link>
|
||||
{TagInfo(item.priority,"mr10")}
|
||||
</p>
|
||||
<p className="color-grey-6 font-12">
|
||||
|
@ -91,12 +89,12 @@ class OrderItem extends Component {
|
|||
<li style={{color:`${item.done_ratio === "100%"?"#28BD6C":"#F73030"}`}}>{item.done_ratio || "--"}</li>
|
||||
<li>
|
||||
<div className="milepostleft">
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/detail`}><i className="iconfont icon-pinglun1 mr3 font-16"></i>{item.journals_count}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/issues/${item.id}/detail`}><i className="iconfont icon-pinglun1 mr3 font-16"></i>{item.journals_count}</Link>
|
||||
{
|
||||
current_user && current_user.login ?
|
||||
<div style={{ display: this.state.orderid === item.id && this.state.isdisplay ? 'flex' : 'none' }}>
|
||||
<div className="mr8 ml8 color-grey-9">
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/updatedetail`} className="color-grey-9"><i className="iconfont icon-bianji3 font-14 mr5"></i></Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}/issues/${item.id}/updatedetail`} className="color-grey-9"><i className="iconfont icon-bianji3 font-14 mr5"></i></Link>
|
||||
</div>
|
||||
<div className="color-grey-9">
|
||||
<Popconfirm placement="bottom" title={'您确定要删除吗'} okText="是" cancelText="否" onConfirm={() => this.deletedetail(item.id)}>
|
||||
|
|
|
@ -80,9 +80,9 @@ class Tags extends Component {
|
|||
|
||||
|
||||
getList = (page, order_name, order_type) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId ,owner } = this.props.match.params;
|
||||
const { limit } = this.state;
|
||||
const url = `/projects/${projectsId}/issue_tags.json`;
|
||||
const url = `/projects/${owner}/${projectsId}/labels.json`;
|
||||
axios.get(url, {
|
||||
params: {
|
||||
page, limit, order_name, order_type
|
||||
|
@ -101,8 +101,8 @@ class Tags extends Component {
|
|||
createtagpost = () => {
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issue_tags.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/projects/${owner}/${projectsId}/labels.json`;
|
||||
axios.post(url, {
|
||||
...values,
|
||||
project_id: projectsId,
|
||||
|
@ -183,9 +183,9 @@ class Tags extends Component {
|
|||
this.updatetag();
|
||||
}
|
||||
updatetag = () => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
let id = this.state.id;
|
||||
const url = `/projects/${projectsId}/issue_tags/${id}.json`;
|
||||
const url = `/projects/${owner}/${projectsId}/labels/${id}.json`;
|
||||
let name = this.state.name;
|
||||
let description = this.state.description;
|
||||
let modalcolor = this.state.newcolor
|
||||
|
@ -208,8 +208,8 @@ class Tags extends Component {
|
|||
}
|
||||
|
||||
deletetag = (id) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issue_tags/${id}.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/projects/${owner}/${projectsId}/labels/${id}.json`;
|
||||
axios.delete(url, {
|
||||
data: {
|
||||
project_id: projectsId,
|
||||
|
@ -362,7 +362,7 @@ class Tags extends Component {
|
|||
</div>
|
||||
</div>
|
||||
:
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
<NoneData _html="暂时还没有相关数据!" />
|
||||
}
|
||||
{
|
||||
data && data.issue_tags_count > limit ?
|
||||
|
|
|
@ -36,9 +36,9 @@ class UpdateMilepost extends Component {
|
|||
}
|
||||
|
||||
getmeil = () => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { meilid } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/versions/${meilid}/edit.json`;
|
||||
const url = `/${owner}/${projectsId}/milestones/${meilid}/edit.json`;
|
||||
axios.get(url, {
|
||||
params: {
|
||||
projectsId, meilid
|
||||
|
@ -64,9 +64,9 @@ class UpdateMilepost extends Component {
|
|||
this.setState({ isSpin: true })
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { meilid } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/versions/${meilid}.json`;
|
||||
const url = `/${owner}/${projectsId}/milestones/${meilid}.json`;
|
||||
|
||||
let time = this.state.selectedValue && this.state.selectedValue.format("YYYY-MM-DD");
|
||||
|
||||
|
@ -79,7 +79,7 @@ class UpdateMilepost extends Component {
|
|||
}).then(result => {
|
||||
if (result) {
|
||||
this.setState({ isSpin: false })
|
||||
this.props.history.push(`/projects/${projectsId}/orders/Milepost`);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/milestones`);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
padding-left: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.attachment-list-div:hover {
|
||||
background-color: #e6f7ff;
|
||||
}
|
||||
.attachment-list-div:hover .attachment-list-delete {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.searchBanner{
|
||||
display: flex;
|
||||
|
|
|
@ -49,15 +49,12 @@ class NewMilepost extends Component {
|
|||
this.setState({ isSpin: true })
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/versions.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/milestones.json`;
|
||||
let time = undefined;
|
||||
if (this.state.selectedValue === undefined) {
|
||||
|
||||
} else {
|
||||
time = this.state.selectedValue.format("YYYY-MM-DD")
|
||||
if (this.state.selectedValue) {
|
||||
time = this.state.selectedValue.format("YYYY-MM-DD");
|
||||
}
|
||||
|
||||
axios.post(url, {
|
||||
...values,
|
||||
project_id: projectsId,
|
||||
|
@ -66,12 +63,10 @@ class NewMilepost extends Component {
|
|||
}).then(result => {
|
||||
if (result) {
|
||||
this.setState({ isSpin: false })
|
||||
this.props.history.push(`/projects/${projectsId}/orders/Milepost`);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/milestones`);
|
||||
}
|
||||
|
||||
}).catch(error => {
|
||||
this.setState({ isSpin: false })
|
||||
console.log(error);
|
||||
})
|
||||
}else{
|
||||
this.setState({ isSpin: false })
|
||||
|
@ -105,7 +100,7 @@ class NewMilepost extends Component {
|
|||
required: true, message: '请输入标题'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder="标题" />
|
||||
<Input placeholder="标题" autoComplete="off"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
}
|
||||
|
||||
.topmilepost {
|
||||
padding: 20px 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
@ -27,7 +26,7 @@
|
|||
}
|
||||
|
||||
.miledetail {
|
||||
padding-bottom: 20px;
|
||||
padding:15px 20px;
|
||||
box-sizing: border-box;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
@ -181,14 +180,16 @@
|
|||
height: 30px;
|
||||
}
|
||||
.title_overflow {
|
||||
max-width: 220px;
|
||||
max-width: 160px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
display: inline-flex;
|
||||
white-space: nowrap;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.topWrapper_select.wrapperStyle li{
|
||||
width:90px;
|
||||
}
|
||||
.topWrapper_select li {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
@ -213,6 +214,12 @@
|
|||
padding: 6px 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.setItemStyle{
|
||||
min-height:440px;
|
||||
}
|
||||
.setItemStyle .issueItem{
|
||||
padding:16px 0px;
|
||||
}
|
||||
.issueItem {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
@ -425,7 +432,7 @@
|
|||
}
|
||||
.milepostrighe {
|
||||
display: flex;
|
||||
width: 80%;
|
||||
flex:1;
|
||||
}
|
||||
.milepostleft {
|
||||
display: flex;
|
||||
|
@ -557,12 +564,6 @@ a.issue-type-button.active:hover {
|
|||
.attachment-list-delete {
|
||||
display: none;
|
||||
}
|
||||
.attachment-list-div:hover {
|
||||
background-color: #e6f7ff;
|
||||
}
|
||||
.attachment-list-div:hover .attachment-list-delete {
|
||||
display: block !important;
|
||||
}
|
||||
.attachment-list-a {
|
||||
color: rgba(0, 0, 0, 0.65) !important;
|
||||
}
|
||||
|
@ -641,7 +642,7 @@ a.issue-type-button.active:hover {
|
|||
|
||||
.custom-comment-tabs .ant-tabs-top-bar{
|
||||
border-bottom: none;
|
||||
padding: 15px 0;
|
||||
padding-top:15px;
|
||||
}
|
||||
.custom-comment-tabs .search-count-button{
|
||||
line-height: 18px;
|
||||
|
|
|
@ -84,9 +84,9 @@ class order extends Component {
|
|||
this.setState({
|
||||
isSpin: true
|
||||
})
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
|
||||
const url = `/projects/${projectsId}/issues/index_chosen.json`;
|
||||
const url = `/${owner}/${projectsId}/issues/index_chosen.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
|
@ -106,8 +106,8 @@ class order extends Component {
|
|||
isSpin: true
|
||||
})
|
||||
const { select_params } = this.state;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues.json`;
|
||||
const { projectsId, owner } = this.props.match.params;
|
||||
const url = `/${owner }/${projectsId}/issues.json`;
|
||||
axios
|
||||
.get(url, {
|
||||
params: {
|
||||
|
@ -239,6 +239,8 @@ class order extends Component {
|
|||
this.setState({
|
||||
search: value,
|
||||
isSpin: true,
|
||||
checkedValue:[],
|
||||
all:undefined
|
||||
});
|
||||
const { status_type } = this.state;
|
||||
|
||||
|
@ -258,7 +260,10 @@ class order extends Component {
|
|||
assigned_to_ids: "负责人",
|
||||
status_ids: "状态",
|
||||
done_ratios: "完成度",
|
||||
fixed_version_ids:"里程碑",
|
||||
paix: "排序",
|
||||
checkedValue:[],
|
||||
all:undefined
|
||||
});
|
||||
this.state.select_params = {
|
||||
search: undefined,
|
||||
|
@ -316,42 +321,40 @@ class order extends Component {
|
|||
};
|
||||
|
||||
deletedetail = (id) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${id}.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/projects/${owner}/${projectsId}/issues/${id}.json`;
|
||||
axios.delete(url, {
|
||||
data: {
|
||||
project_id: projectsId,
|
||||
id: id,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
const { status_type } = this.state;
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
const { status_type } = this.state;
|
||||
|
||||
this.getIssueList(status_type);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
this.getIssueList(status_type);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
islogin() {
|
||||
islogin=()=>{
|
||||
this.props.showLoginDialog();
|
||||
}
|
||||
renderNew =()=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
if (this.props.checkIfLogin()) {
|
||||
return(
|
||||
<Link className="topWrapper_btn ml10" target="_blank" to={`/projects/${projectsId}/orders/new`}>
|
||||
<Link className="topWrapper_btn ml10" target="_blank" to={`/projects/${owner}/${projectsId}/issues/new`}>
|
||||
+ 创建任务
|
||||
</Link>
|
||||
)
|
||||
}else{
|
||||
return(
|
||||
<a className="topWrapper_btn ml10" onClick={this.islogin}>
|
||||
+ 创建任务
|
||||
</a>
|
||||
<a className="topWrapper_btn ml10" onClick={this.islogin}>+ 创建任务</a>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -415,7 +418,7 @@ class order extends Component {
|
|||
// 批量修改
|
||||
updateIssues = () => {
|
||||
const { checkedValue, select_params } = this.state;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
|
||||
if (!select_params.update_author_id && !select_params.update_fixed_version_id && !select_params.update_status_id) {
|
||||
this.resetSelectParams();
|
||||
|
@ -424,7 +427,7 @@ class order extends Component {
|
|||
this.setState({
|
||||
isSpin: true
|
||||
})
|
||||
const url = `/projects/${projectsId}/issues/series_update.json`;
|
||||
const url = `/${owner}/${projectsId}/issues/series_update.json`;
|
||||
axios.post(url, {
|
||||
ids: checkedValue,
|
||||
assigned_to_id: select_params.update_author_id,
|
||||
|
@ -470,8 +473,8 @@ class order extends Component {
|
|||
isSpin: true
|
||||
})
|
||||
const { checkedValue } = this.state;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/clean.json`;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/issues/clean.json`;
|
||||
axios.post(url, {
|
||||
ids: checkedValue
|
||||
}).then(result => {
|
||||
|
@ -608,7 +611,7 @@ class order extends Component {
|
|||
</div>
|
||||
{
|
||||
checkedValue && checkedValue.length > 0 ?
|
||||
<ul className="topWrapper_select">
|
||||
<ul className="topWrapper_select wrapperStyle">
|
||||
<li className="mr20">
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
|
@ -628,7 +631,7 @@ class order extends Component {
|
|||
</li>
|
||||
<li className="mr20">
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
className="topWrapperSelect wrapperStyle"
|
||||
overlay={this.renderMenu(
|
||||
issue_chosen && issue_chosen.issue_version,
|
||||
"更换里程碑",
|
||||
|
@ -645,7 +648,7 @@ class order extends Component {
|
|||
</li>
|
||||
<li className="mr20">
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
className="topWrapperSelect wrapperStyle"
|
||||
overlay={this.renderMenu(
|
||||
issue_chosen && issue_chosen.issue_status,
|
||||
"修改状态",
|
||||
|
@ -802,7 +805,7 @@ class order extends Component {
|
|||
|
||||
</div>
|
||||
{search_count === 0 ? (
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
<NoneData _html="暂时还没有相关数据!" />
|
||||
) : (
|
||||
<div style={{ minHeight: "500px" }}>
|
||||
<Checkbox.Group name="issues" onChange={this.checkIssues} value={checkedValue} style={{ width: "100%" }}>
|
||||
|
@ -826,7 +829,7 @@ class order extends Component {
|
|||
)}
|
||||
{
|
||||
search_count > select_params.limit ?
|
||||
<div className="mt30 mb50 edu-txt-center">
|
||||
<div className="mt30 mb10 edu-txt-center">
|
||||
<Pagination
|
||||
simple
|
||||
defaultCurrent={select_params.page}
|
||||
|
|
|
@ -17,11 +17,11 @@ class order_form extends Component {
|
|||
branch_name: "",
|
||||
issue_tag_ids: "",
|
||||
fixed_version_id: "",
|
||||
tracker_id: "1",
|
||||
tracker_id: "4",
|
||||
issue_type: "1",
|
||||
status_id: "1",
|
||||
assigned_to_id: "",
|
||||
priority_id: "1",
|
||||
priority_id: "2",
|
||||
done_ratio: "0%",
|
||||
issue_chosen: undefined,
|
||||
branches: undefined,
|
||||
|
@ -34,6 +34,8 @@ class order_form extends Component {
|
|||
subject: "",
|
||||
get_attachments: undefined,
|
||||
show_token: false,
|
||||
cannot_edit: false,
|
||||
issue_current_user: true
|
||||
};
|
||||
}
|
||||
componentDidUpdate=(prevPros)=>{
|
||||
|
@ -44,14 +46,13 @@ class order_form extends Component {
|
|||
}
|
||||
componentDidMount = () => {
|
||||
this.getSelectList();
|
||||
|
||||
};
|
||||
get_detail = () => {
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
const { projectsId, orderId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}/edit.json`;
|
||||
const { projectsId, orderId, owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/issues/${orderId}/edit.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
let data ={
|
||||
|
@ -87,16 +88,9 @@ class order_form extends Component {
|
|||
});
|
||||
};
|
||||
getSelectList = () => {
|
||||
let projectsId = "";
|
||||
if (this.props.match.params.milepostId) {
|
||||
projectsId = this.props.match.params.projectsId;
|
||||
this.props.form.setFieldsValue({
|
||||
fixed_version_id: this.props.match.params.milepostId,
|
||||
});
|
||||
} else {
|
||||
projectsId = this.props.match.params.projectsId;
|
||||
}
|
||||
const url = `/projects/${projectsId}/issues/new.json`;
|
||||
let {projectsId, owner , milepostId} = this.props.match.params;
|
||||
|
||||
const url = `/${owner}/${projectsId}/issues/new.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
|
@ -104,11 +98,13 @@ class order_form extends Component {
|
|||
branches: result.data.branches,
|
||||
isSpin:false
|
||||
});
|
||||
|
||||
if(this.props.form_type !== "new"){
|
||||
this.get_detail();
|
||||
}else{
|
||||
this.props.form.setFieldsValue({
|
||||
...this.state
|
||||
...this.state,
|
||||
fixed_version_id: milepostId || ""
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +133,7 @@ class order_form extends Component {
|
|||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
const { form_type } = this.props;
|
||||
const { projectsId, orderId } = this.props.match.params;
|
||||
const { projectsId , orderId , owner } = this.props.match.params;
|
||||
|
||||
const { fileList } = this.state;
|
||||
|
||||
|
@ -158,7 +154,7 @@ class order_form extends Component {
|
|||
}
|
||||
const { description, start_date, due_date, issue_type } = this.state;
|
||||
if (form_type === "new") {
|
||||
const url = `/projects/${projectsId}/issues.json`;
|
||||
const url = `/${owner}/${projectsId}/issues.json`;
|
||||
axios.post(url, {
|
||||
...values,
|
||||
description: description,
|
||||
|
@ -169,7 +165,7 @@ class order_form extends Component {
|
|||
}).then((result) => {
|
||||
if (result && result.data.id) {
|
||||
this.props.showNotification("任务创建成功!");
|
||||
this.props.history.push(`/projects/${projectsId}/orders/${result.data.id}/detail`);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/issues/${result.data.id}/detail`);
|
||||
this.setState({
|
||||
description: "",
|
||||
isSpin: false,
|
||||
|
@ -185,7 +181,7 @@ class order_form extends Component {
|
|||
console.log(error);
|
||||
});
|
||||
} else {
|
||||
const url = `/projects/${projectsId}/issues/${orderId}.json`;
|
||||
const url = `/${owner}/${projectsId}/issues/${orderId}.json`;
|
||||
axios.put(url, {
|
||||
description: description,
|
||||
attachment_ids: fileList,
|
||||
|
@ -195,9 +191,7 @@ class order_form extends Component {
|
|||
...values,
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
this.props.history.push(
|
||||
`/projects/${projectsId}/orders/${orderId}/detail`
|
||||
);
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/issues/${orderId}/detail`);
|
||||
this.props.showNotification("任务更新成功!");
|
||||
}
|
||||
})
|
||||
|
@ -271,6 +265,7 @@ class order_form extends Component {
|
|||
});
|
||||
this.setState({
|
||||
done_ratio: "0",
|
||||
issue_current_user: true,
|
||||
});
|
||||
} else if (e === "3") {
|
||||
this.props.form.setFieldsValue({
|
||||
|
@ -278,6 +273,11 @@ class order_form extends Component {
|
|||
});
|
||||
this.setState({
|
||||
done_ratio: "100",
|
||||
issue_current_user: true,
|
||||
});
|
||||
}else if (e === "5") {
|
||||
this.setState({
|
||||
issue_current_user: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -299,7 +299,7 @@ class order_form extends Component {
|
|||
|
||||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const projectsId = this.props.match.params.projectsId;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { orderId } = this.props.match.params;
|
||||
const { form_type } = this.props;
|
||||
const {issue_chosen,branches,description,get_attachments,isSpin,start_date,due_date} = this.state;
|
||||
|
@ -370,7 +370,7 @@ class order_form extends Component {
|
|||
type="default"
|
||||
className="ml30"
|
||||
onClick={()=>
|
||||
this.props.history.push(form_type === "new" ? `/projects/${projectsId || orderId}/orders` : `/projects/${projectsId}/orders/${orderId}/detail`)}
|
||||
this.props.history.push(form_type === "new" ? `/projects/${owner}/${projectsId || orderId}/issues` : `/projects/${owner}/${projectsId}/issues/${orderId}/detail`)}
|
||||
>
|
||||
<span className="plr10">取消</span>
|
||||
</Button>
|
||||
|
@ -379,19 +379,13 @@ class order_form extends Component {
|
|||
</div>
|
||||
<div className="list-left list-left-padding issue-edit-form-right">
|
||||
<div className="pd20 background-f issue-form-right">
|
||||
<Form.Item>
|
||||
{getFieldDecorator("branch_name", {
|
||||
rules: []
|
||||
})(
|
||||
<Form.Item label="指派成员">
|
||||
{getFieldDecorator("assigned_to_id", {rules: []})(
|
||||
<Select>
|
||||
<Option value={""}>分支未指定</Option>
|
||||
{branches && branches.length > 0 && branches.map((item, key) => {
|
||||
return (
|
||||
<Option value={item} key={key}>
|
||||
{item}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
<Option value={""}>未指派成员</Option>
|
||||
{this.renderSelect(
|
||||
issue_chosen && issue_chosen.assign_user
|
||||
)}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
|
@ -460,16 +454,6 @@ class order_form extends Component {
|
|||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="指派成员">
|
||||
{getFieldDecorator("assigned_to_id", {rules: []})(
|
||||
<Select>
|
||||
<Option value={""}>未指派成员</Option>
|
||||
{this.renderSelect(
|
||||
issue_chosen && issue_chosen.assign_user
|
||||
)}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="开始日期">
|
||||
<DatePicker
|
||||
value={start_date ? moment(start_date, "YYYY-MM-DD") : null}
|
||||
|
@ -493,28 +477,22 @@ class order_form extends Component {
|
|||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
{/* <Form.Item label="是否上链">
|
||||
<Switch
|
||||
checkedChildren="是"
|
||||
unCheckedChildren="否"
|
||||
defaultChecked={false}
|
||||
checked={issue_type && issue_type === "2"}
|
||||
onChange={this.change_issue_type}
|
||||
/>
|
||||
<Form.Item label="指定分支">
|
||||
{getFieldDecorator("branch_name", {
|
||||
rules: []
|
||||
})(
|
||||
<Select>
|
||||
<Option value={""}>分支未指定</Option>
|
||||
{branches && branches.length > 0 && branches.map((item, key) => {
|
||||
return (
|
||||
<Option value={item} key={key}>
|
||||
{item}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
{(show_token || (issue_type && issue_type === "2")) && (
|
||||
<Form.Item label="token">
|
||||
{getFieldDecorator("token", {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写token值",
|
||||
},
|
||||
],
|
||||
initialValue: token,
|
||||
})(<Input placeholder="请填写token值" />)}
|
||||
</Form.Item>
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React , { useState } from 'react';
|
||||
import React , { useEffect, useState } from 'react';
|
||||
import SelectBranch from '../Branch/Select';
|
||||
import Title from '../Component/Title';
|
||||
import styled from 'styled-components';
|
||||
import { Blueline , FlexAJ , NumUl , GreenUnder , AlignCenter , WhiteBack } from '../Component/layout';
|
||||
|
||||
import axios from 'axios';
|
||||
const Div = styled.div`{
|
||||
padding:20px 30px;
|
||||
min-height:500px;
|
||||
|
@ -11,11 +11,33 @@ const Div = styled.div`{
|
|||
|
||||
export default ((props)=>{
|
||||
const [ branch , setBranch ] = useState("master");
|
||||
const { projectsId } = props.match.params;
|
||||
const { projectsId , owner } = props.match.params;
|
||||
const projectDetail = props.projectDetail;
|
||||
|
||||
function resetSetting(){
|
||||
const { defaultBranch } = props;
|
||||
useEffect(()=>{
|
||||
if(defaultBranch){
|
||||
setBranch(defaultBranch);
|
||||
}
|
||||
},[defaultBranch]);
|
||||
|
||||
|
||||
function resetSetting(){
|
||||
const url = `/${owner}/${projectsId}.json`;
|
||||
axios.put(url, {
|
||||
default_branch:branch
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
props.showNotification(`分支设置成功!`);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
function settingRule(){
|
||||
props.history.push(`/projects/${owner}/${projectsId}/setting/branch/new`);
|
||||
}
|
||||
return(
|
||||
<WhiteBack>
|
||||
|
@ -30,17 +52,19 @@ export default ((props)=>{
|
|||
repo_id={ projectDetail && projectDetail.repo_id}
|
||||
projectsId={projectsId}
|
||||
changeBranch={setBranch}
|
||||
owner={owner}
|
||||
history={props.history}
|
||||
/>
|
||||
<a className="color-blue ml20" onClick={resetSetting()}>设为默认分支</a>
|
||||
<a className="color-blue ml20" onClick={()=>resetSetting()}>设为默认分支</a>
|
||||
</AlignCenter>
|
||||
</div>
|
||||
<div>
|
||||
<FlexAJ className="pt20">
|
||||
<span className="color-grey-3">保护分支规则</span>
|
||||
<Blueline>+ 新建规则</Blueline>
|
||||
<Blueline onClick={()=>settingRule()}>+ 新建规则</Blueline>
|
||||
</FlexAJ>
|
||||
<NumUl>
|
||||
<li>限制分支的推送、合并。强制推送相关请去<GreenUnder>仓库设置</GreenUnder>。</li>
|
||||
<li>限制分支的推送、合并。强制推送相关请去<GreenUnder onClick={()=>{props.history.push(`/projects/${owner}/${projectsId}/setting`)}}>仓库设置</GreenUnder>。</li>
|
||||
<li>一个分支同时只能有一个保护分支规则生效,越早创建的规则优先级越高。</li>
|
||||
<li>保护分支规则只影响状态是【保护分支】的分支。【常规分支】和【只读分支】都不影响。</li>
|
||||
</NumUl>
|
||||
|
|