Compare commits
246 Commits
master
...
dev_milita
Author | SHA1 | Date |
---|---|---|
|
97f62a5684 | |
|
e74a3b6a95 | |
|
38878183d5 | |
|
0e0c13f1a4 | |
|
a667a32de0 | |
|
230e597787 | |
|
f0ea3a53c4 | |
|
51a4680481 | |
|
61a4882e58 | |
|
148e8f91eb | |
|
8f52a091fa | |
|
62eabdf7c0 | |
|
d5490d5e71 | |
|
cef374c52d | |
|
7be60d3140 | |
|
feafa5b6f3 | |
|
2dd6ed108f | |
|
969323fdde | |
|
a73b4ff79a | |
|
16ca2a359e | |
|
444d954e72 | |
|
6fc31c0bb8 | |
|
cf73f72e19 | |
|
745a25a003 | |
|
b080df1449 | |
|
0aa2a4aec3 | |
|
4dc1c4c814 | |
|
ddc576b054 | |
|
caef7a0ab3 | |
|
85f0578302 | |
|
bff55b6810 | |
|
01f71bca87 | |
|
d3cea0ff3b | |
|
be6e3d273b | |
|
6b8f1e3749 | |
|
b5e145b4b5 | |
|
15b63be594 | |
|
032127bef6 | |
|
f4f843a7b9 | |
|
4cf8357463 | |
|
0ff1367ad8 | |
|
0e44cbbcdd | |
|
e736591a4f | |
|
d15900fc7c | |
|
4f87542f1f | |
|
94ee3601c9 | |
|
19d09c7901 | |
|
3b29605321 | |
|
6e82862307 | |
|
700ac5862e | |
|
4ccab2ed4f | |
|
3f3299a3b8 | |
|
b73a38351b | |
|
586c5d6d1d | |
|
819772d180 | |
|
e733f1886e | |
|
86d2442958 | |
|
b7fc83edf9 | |
|
74325b5dc7 | |
|
a25959bfa0 | |
|
fe72be2f30 | |
|
4d41f44100 | |
|
afa839e0b1 | |
|
83d59a2e64 | |
|
758f4267ed | |
|
38948a84cd | |
|
51d739f4a0 | |
|
706830928e | |
|
8dc08c3992 | |
|
70ec86569f | |
|
00b41844bb | |
|
81c93d2580 | |
|
a87e55103c | |
|
05101c5e32 | |
|
e72b3e687f | |
|
f25a52622d | |
|
f5fa216b23 | |
|
a57b96a1b8 | |
|
8efbea44ab | |
|
fa80b5d1df | |
|
6c95ff98f4 | |
|
cb7170a87c | |
|
7757e4b6b7 | |
|
cad9a4fc3a | |
|
dc20d3e270 | |
|
4503e1b176 | |
|
91fe328eaf | |
|
8d9d5c3ce3 | |
|
a2aa344e31 | |
|
981e199273 | |
|
b6d6309c3c | |
|
16aac3b835 | |
|
bdf3a8e72a | |
|
507976bf10 | |
|
b6c2c66321 | |
|
0b7fbe564c | |
|
ce958f3369 | |
|
0e176d9334 | |
|
3608b7b712 | |
|
b9888a81f6 | |
|
0bb6ec51c2 | |
|
7d2c90dfd1 | |
|
66c5f09813 | |
|
a4d38f8c86 | |
|
21a3c54754 | |
|
4493711521 | |
|
76b23f88db | |
|
bca9499844 | |
|
3137048aed | |
|
62b5d86082 | |
|
7a472651f1 | |
|
99c90295c0 | |
|
d7fd642f7f | |
|
97bc41e771 | |
|
6156d98af2 | |
|
6facc3e65f | |
|
c8f6891239 | |
|
11b5c87888 | |
|
2f538ff394 | |
|
48a153d434 | |
|
9c3ecabf47 | |
|
f18070da47 | |
|
1e87e0c8ec | |
|
bec68aa090 | |
|
aed83337fa | |
|
e5b7110090 | |
|
716916b7b6 | |
|
b5ccdbfcd6 | |
|
1e7df569e6 | |
|
701d9dfc99 | |
|
e7b3a01c47 | |
|
b19c084ac8 | |
|
1d4bb3f4fc | |
|
e0b267bd6c | |
|
4bf4aa7c78 | |
|
e3643be01b | |
|
9c8add0152 | |
|
edb7099131 | |
|
cce818d4e0 | |
![]() |
909663bc47 | |
|
9ea9da9672 | |
|
97bd7673e1 | |
|
2aa89426ad | |
|
5131dacf05 | |
|
6b63cd25aa | |
![]() |
8162b8b908 | |
|
7a59d43eec | |
![]() |
008ba8d1de | |
|
98a9344b02 | |
|
b8342288dd | |
|
09e81b9e78 | |
![]() |
7cf5e23cb9 | |
|
8594168d33 | |
![]() |
2d7c6cb82d | |
![]() |
c36925c136 | |
|
6ec6ab2308 | |
|
4109e4b07e | |
|
216e984740 | |
|
92f3934d5e | |
|
2ed7e0d4c4 | |
|
6cfe81aea3 | |
|
4dcbd51482 | |
|
c32b333bc2 | |
|
c965da7dd5 | |
|
b44399968f | |
|
2591f28ccc | |
|
5530e8c723 | |
|
fa26dc9fa5 | |
|
4cf40f9dfc | |
|
2c034f5dff | |
|
d68d8318c1 | |
|
41ae6b1f8d | |
|
a6e2171fca | |
|
916cc293ac | |
|
5565eac601 | |
|
860b71c7c6 | |
|
f1c2841fe0 | |
|
c6d5078d42 | |
|
ebe2d625fa | |
|
b5e1a91af5 | |
|
4b8d72a6eb | |
|
f0e1858cd4 | |
|
a92468953a | |
|
fdab967b6a | |
|
7e8929f166 | |
|
0a39ed80da | |
|
5ed44f1d63 | |
|
64e639ebea | |
|
3fb9eb40f3 | |
|
efc2443bb8 | |
|
2c3d917bd4 | |
|
617f139f52 | |
|
de550d5f42 | |
|
f12230dc91 | |
|
1df2639cd5 | |
|
c746e9e634 | |
|
d8d464a332 | |
|
83e337b2e9 | |
|
5a6b7bd717 | |
|
c68a3dbd6f | |
|
350f9426ea | |
|
5bda100e32 | |
|
dde7fa730a | |
|
3f8f1b8083 | |
|
6eef4bd09e | |
|
0dcaea3db4 | |
|
033134fa83 | |
|
1bab0b01f7 | |
|
7b2f233cae | |
|
2ecdd73c7f | |
|
4e7a2fa3d7 | |
|
91662e2e3e | |
|
c2129c994a | |
|
e968ece34c | |
|
70d407963e | |
|
00ccba74a1 | |
|
0790abb6f9 | |
|
6c4c161a1b | |
|
65a2bd43cf | |
|
10f813a443 | |
|
e79ec30c81 | |
|
2a7fea3612 | |
|
cc46a3ac30 | |
|
cca5f98c9b | |
|
d4535005c8 | |
|
73d128e0c9 | |
|
f09457a0ac | |
|
78c218b12b | |
|
d9f87fdd18 | |
|
33c3395221 | |
|
74d26a40d3 | |
|
3f78ed249c | |
|
07e1525f09 | |
|
a9161b86a2 | |
|
e0e6cdcc79 | |
|
3b0c708d82 | |
|
0922df3875 | |
|
ad3fe09cfb | |
|
91f4327eb4 | |
|
f2f910b5e4 | |
|
85d924db70 | |
![]() |
f1614a4b62 | |
![]() |
2fa71241db | |
![]() |
13c6556574 | |
|
5601b71937 | |
![]() |
1a024f8011 |
|
@ -86,3 +86,6 @@ typings/
|
|||
|
||||
.DS_Store
|
||||
.idea/*
|
||||
|
||||
package.json
|
||||
package-lock.json
|
|
@ -101,9 +101,13 @@ module.exports = {
|
|||
extensions: [".web.js", ".mjs", ".js", ".json", ".web.jsx", ".jsx"],
|
||||
alias: {
|
||||
educoder: __dirname + "/../src/common/educoder.js",
|
||||
src: path.join(paths.appSrc), // 整个源代码目录
|
||||
forge: path.join(paths.appSrc, 'forge'),
|
||||
military: path.join(paths.appSrc, 'military'),
|
||||
// Support React Native Web
|
||||
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
||||
"react-native": "react-native-web",
|
||||
'react-dom': '@hot-loader/react-dom',
|
||||
},
|
||||
plugins: [
|
||||
// Prevents users from importing files from outside of src/ (or node_modules/).
|
||||
|
|
|
@ -87,6 +87,9 @@ module.exports = {
|
|||
extensions: [".web.js", ".mjs", ".js", ".json", ".web.jsx", ".jsx"],
|
||||
alias: {
|
||||
educoder: __dirname + "/../src/common/educoder.js",
|
||||
src: path.join(paths.appSrc),
|
||||
forge: path.join(paths.appSrc, 'forge'),
|
||||
military: path.join(paths.appSrc, 'military'),
|
||||
// Support React Native Web
|
||||
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
||||
"react-native": "react-native-web",
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"educoder": ["./src/common/educoder.js"],
|
||||
"forge":["./src/forge"],
|
||||
"military":["./src/military"],
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"build"
|
||||
]
|
||||
}
|
|
@ -107,6 +107,7 @@
|
|||
"styled-components": "^4.4.1",
|
||||
"sw-precache-webpack-plugin": "0.11.4",
|
||||
"url-loader": "0.6.2",
|
||||
"wangeditor-for-react": "^1.4.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"webpack-dev-server": "^3.10.3",
|
||||
"webpack-manifest-plugin": "^2.2.0",
|
||||
|
@ -115,7 +116,7 @@
|
|||
},
|
||||
"scripts": {
|
||||
"start": "node --max_old_space_size=15360 scripts/start.js",
|
||||
"build": "NODE_ENV=production node --max_old_space_size=15360 scripts/build.js",
|
||||
"build": "cross-env NODE_ENV=production node --max_old_space_size=15360 scripts/build.js",
|
||||
"test-build": "NODE_ENV=testBuild node --max_old_space_size=15360 scripts/build.js",
|
||||
"pre-build": "NODE_ENV=preBuild node --max_old_space_size=15360 scripts/build.js",
|
||||
"gen_stats": "NODE_ENV=production webpack --profile --config=./config/webpack.config.prod.js --json > stats.json",
|
||||
|
@ -182,6 +183,7 @@
|
|||
"port": "3007",
|
||||
"devDependencies": {
|
||||
"@babel/runtime": "7.0.0-beta.51",
|
||||
"@hot-loader/react-dom": "^16.14.0",
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-plugin-import": "^1.13.0",
|
||||
|
@ -191,6 +193,7 @@
|
|||
"babel-preset-stage-2": "^6.24.1",
|
||||
"compression-webpack-plugin": "^1.1.12",
|
||||
"concat": "^1.0.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"happypack": "^5.0.1",
|
||||
"mockjs": "^1.1.0",
|
||||
"node-sass": "^4.12.0",
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*头部导航条样式---2018-03-19--by-cs*/
|
||||
.newHeader {
|
||||
background: #24292D !important;
|
||||
width: 100%;
|
||||
height: 60px !important;
|
||||
min-width: 1200px;
|
||||
|
|
|
@ -3971,7 +3971,9 @@ html>body #ajax-indicator {
|
|||
cursor: pointer;
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
padding:0px 20px;
|
||||
margin-right: 40px;
|
||||
}.head-nav ul#header-nav li:first-child{
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.head-nav ul#header-nav li a {
|
||||
|
|
|
@ -5,6 +5,741 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "23791639",
|
||||
"name": "项目公告",
|
||||
"font_class": "xiangmugonggao",
|
||||
"unicode": "e8c2",
|
||||
"unicode_decimal": 59586
|
||||
},
|
||||
{
|
||||
"icon_id": "23791640",
|
||||
"name": "成果",
|
||||
"font_class": "chengguo",
|
||||
"unicode": "e8c3",
|
||||
"unicode_decimal": 59587
|
||||
},
|
||||
{
|
||||
"icon_id": "23791410",
|
||||
"name": "成交公告",
|
||||
"font_class": "chengjiaogonggao",
|
||||
"unicode": "e8c0",
|
||||
"unicode_decimal": 59584
|
||||
},
|
||||
{
|
||||
"icon_id": "23791411",
|
||||
"name": "技术资产",
|
||||
"font_class": "jishuzichan",
|
||||
"unicode": "e8c1",
|
||||
"unicode_decimal": 59585
|
||||
},
|
||||
{
|
||||
"icon_id": "23790928",
|
||||
"name": "废标公告",
|
||||
"font_class": "feibiaogonggao",
|
||||
"unicode": "e8bc",
|
||||
"unicode_decimal": 59580
|
||||
},
|
||||
{
|
||||
"icon_id": "23790929",
|
||||
"name": "中标公告",
|
||||
"font_class": "zhongbiaogonggao",
|
||||
"unicode": "e8bd",
|
||||
"unicode_decimal": 59581
|
||||
},
|
||||
{
|
||||
"icon_id": "23790930",
|
||||
"name": "更正公告",
|
||||
"font_class": "gengzhenggonggao",
|
||||
"unicode": "e8be",
|
||||
"unicode_decimal": 59582
|
||||
},
|
||||
{
|
||||
"icon_id": "23790931",
|
||||
"name": "招标公告",
|
||||
"font_class": "zhaobiaogonggao",
|
||||
"unicode": "e8bf",
|
||||
"unicode_decimal": 59583
|
||||
},
|
||||
{
|
||||
"icon_id": "23732532",
|
||||
"name": "文件",
|
||||
"font_class": "wenjian6",
|
||||
"unicode": "e8ba",
|
||||
"unicode_decimal": 59578
|
||||
},
|
||||
{
|
||||
"icon_id": "23732533",
|
||||
"name": "文件夹",
|
||||
"font_class": "wenjianjia4",
|
||||
"unicode": "e8bb",
|
||||
"unicode_decimal": 59579
|
||||
},
|
||||
{
|
||||
"icon_id": "23642443",
|
||||
"name": "取消关注",
|
||||
"font_class": "quxiaoguanzhu",
|
||||
"unicode": "e89a",
|
||||
"unicode_decimal": 59546
|
||||
},
|
||||
{
|
||||
"icon_id": "23642444",
|
||||
"name": "点赞_icon",
|
||||
"font_class": "dianzan_icon",
|
||||
"unicode": "e8a2",
|
||||
"unicode_decimal": 59554
|
||||
},
|
||||
{
|
||||
"icon_id": "23639530",
|
||||
"name": "文件",
|
||||
"font_class": "wenjian5",
|
||||
"unicode": "e896",
|
||||
"unicode_decimal": 59542
|
||||
},
|
||||
{
|
||||
"icon_id": "23639533",
|
||||
"name": "文件夹",
|
||||
"font_class": "wenjianjia3",
|
||||
"unicode": "e8a9",
|
||||
"unicode_decimal": 59561
|
||||
},
|
||||
{
|
||||
"icon_id": "23639440",
|
||||
"name": "复制icon",
|
||||
"font_class": "fuzhiicon",
|
||||
"unicode": "e886",
|
||||
"unicode_decimal": 59526
|
||||
},
|
||||
{
|
||||
"icon_id": "23639422",
|
||||
"name": "主页-fill",
|
||||
"font_class": "zhuye-fill",
|
||||
"unicode": "e876",
|
||||
"unicode_decimal": 59510
|
||||
},
|
||||
{
|
||||
"icon_id": "23639423",
|
||||
"name": "代码库icon",
|
||||
"font_class": "daimakuicon",
|
||||
"unicode": "e884",
|
||||
"unicode_decimal": 59524
|
||||
},
|
||||
{
|
||||
"icon_id": "23572260",
|
||||
"name": "新建",
|
||||
"font_class": "xinjian2",
|
||||
"unicode": "e8b0",
|
||||
"unicode_decimal": 59568
|
||||
},
|
||||
{
|
||||
"icon_id": "23567674",
|
||||
"name": "协议icon",
|
||||
"font_class": "xieyiicon",
|
||||
"unicode": "e870",
|
||||
"unicode_decimal": 59504
|
||||
},
|
||||
{
|
||||
"icon_id": "23567675",
|
||||
"name": "内存icon",
|
||||
"font_class": "neicunicon",
|
||||
"unicode": "e891",
|
||||
"unicode_decimal": 59537
|
||||
},
|
||||
{
|
||||
"icon_id": "23567676",
|
||||
"name": "自述文件_icon",
|
||||
"font_class": "zishuwenjian_icon",
|
||||
"unicode": "e8a6",
|
||||
"unicode_decimal": 59558
|
||||
},
|
||||
{
|
||||
"icon_id": "23472253",
|
||||
"name": "标签icon",
|
||||
"font_class": "biaoqianicon",
|
||||
"unicode": "e882",
|
||||
"unicode_decimal": 59522
|
||||
},
|
||||
{
|
||||
"icon_id": "23472254",
|
||||
"name": "编 辑",
|
||||
"font_class": "a-bianji",
|
||||
"unicode": "e883",
|
||||
"unicode_decimal": 59523
|
||||
},
|
||||
{
|
||||
"icon_id": "23472256",
|
||||
"name": "仓库设置icon",
|
||||
"font_class": "cangkushezhiicon",
|
||||
"unicode": "e885",
|
||||
"unicode_decimal": 59525
|
||||
},
|
||||
{
|
||||
"icon_id": "23472258",
|
||||
"name": "链接icon",
|
||||
"font_class": "lianjieicon",
|
||||
"unicode": "e887",
|
||||
"unicode_decimal": 59527
|
||||
},
|
||||
{
|
||||
"icon_id": "23472259",
|
||||
"name": "合并请求icon",
|
||||
"font_class": "hebingqingqiuicon",
|
||||
"unicode": "e888",
|
||||
"unicode_decimal": 59528
|
||||
},
|
||||
{
|
||||
"icon_id": "23472260",
|
||||
"name": "里程碑icon",
|
||||
"font_class": "lichengbeiicon",
|
||||
"unicode": "e889",
|
||||
"unicode_decimal": 59529
|
||||
},
|
||||
{
|
||||
"icon_id": "23472261",
|
||||
"name": "工作流icon",
|
||||
"font_class": "gongzuoliuicon",
|
||||
"unicode": "e88a",
|
||||
"unicode_decimal": 59530
|
||||
},
|
||||
{
|
||||
"icon_id": "23472262",
|
||||
"name": "动态icon",
|
||||
"font_class": "dongtaiicon",
|
||||
"unicode": "e88b",
|
||||
"unicode_decimal": 59531
|
||||
},
|
||||
{
|
||||
"icon_id": "23472263",
|
||||
"name": "默认点赞_icon",
|
||||
"font_class": "morendianzan_icon",
|
||||
"unicode": "e88e",
|
||||
"unicode_decimal": 59534
|
||||
},
|
||||
{
|
||||
"icon_id": "23472265",
|
||||
"name": "目录icon",
|
||||
"font_class": "muluicon",
|
||||
"unicode": "e894",
|
||||
"unicode_decimal": 59540
|
||||
},
|
||||
{
|
||||
"icon_id": "23472267",
|
||||
"name": "设 置",
|
||||
"font_class": "a-shezhi",
|
||||
"unicode": "e899",
|
||||
"unicode_decimal": 59545
|
||||
},
|
||||
{
|
||||
"icon_id": "23472269",
|
||||
"name": "提交icon",
|
||||
"font_class": "tijiaoicon",
|
||||
"unicode": "e89e",
|
||||
"unicode_decimal": 59550
|
||||
},
|
||||
{
|
||||
"icon_id": "23472270",
|
||||
"name": "默认关注_ICON",
|
||||
"font_class": "morenguanzhu_ICON",
|
||||
"unicode": "e89f",
|
||||
"unicode_decimal": 59551
|
||||
},
|
||||
{
|
||||
"icon_id": "23472272",
|
||||
"name": "下拉按钮",
|
||||
"font_class": "xialaanniu1",
|
||||
"unicode": "e8a4",
|
||||
"unicode_decimal": 59556
|
||||
},
|
||||
{
|
||||
"icon_id": "23472276",
|
||||
"name": "左滑icon",
|
||||
"font_class": "zuohuaicon",
|
||||
"unicode": "e8b5",
|
||||
"unicode_decimal": 59573
|
||||
},
|
||||
{
|
||||
"icon_id": "23472277",
|
||||
"name": "master_icon",
|
||||
"font_class": "master_icon",
|
||||
"unicode": "e8b6",
|
||||
"unicode_decimal": 59574
|
||||
},
|
||||
{
|
||||
"icon_id": "23472278",
|
||||
"name": "默认复刻_icon",
|
||||
"font_class": "morenfuke_icon",
|
||||
"unicode": "e8b7",
|
||||
"unicode_decimal": 59575
|
||||
},
|
||||
{
|
||||
"icon_id": "23472279",
|
||||
"name": "wiki icon",
|
||||
"font_class": "a-wikiicon",
|
||||
"unicode": "e8b8",
|
||||
"unicode_decimal": 59576
|
||||
},
|
||||
{
|
||||
"icon_id": "23472280",
|
||||
"name": "易修icon",
|
||||
"font_class": "yixiuicon",
|
||||
"unicode": "e8b9",
|
||||
"unicode_decimal": 59577
|
||||
},
|
||||
{
|
||||
"icon_id": "23436350",
|
||||
"name": "缩放",
|
||||
"font_class": "suofang",
|
||||
"unicode": "e87f",
|
||||
"unicode_decimal": 59519
|
||||
},
|
||||
{
|
||||
"icon_id": "23436351",
|
||||
"name": "放大icon",
|
||||
"font_class": "fangdaicon",
|
||||
"unicode": "e881",
|
||||
"unicode_decimal": 59521
|
||||
},
|
||||
{
|
||||
"icon_id": "23384231",
|
||||
"name": "搜索_icon",
|
||||
"font_class": "sousuo_icon1",
|
||||
"unicode": "e873",
|
||||
"unicode_decimal": 59507
|
||||
},
|
||||
{
|
||||
"icon_id": "23384232",
|
||||
"name": "欢迎_icon",
|
||||
"font_class": "huanying_icon",
|
||||
"unicode": "e878",
|
||||
"unicode_decimal": 59512
|
||||
},
|
||||
{
|
||||
"icon_id": "23384233",
|
||||
"name": "文件夹",
|
||||
"font_class": "wenjianjia2",
|
||||
"unicode": "e879",
|
||||
"unicode_decimal": 59513
|
||||
},
|
||||
{
|
||||
"icon_id": "23384234",
|
||||
"name": "删除icon",
|
||||
"font_class": "shanchuicon1",
|
||||
"unicode": "e87a",
|
||||
"unicode_decimal": 59514
|
||||
},
|
||||
{
|
||||
"icon_id": "23261798",
|
||||
"name": "请求icon",
|
||||
"font_class": "qingqiuicon",
|
||||
"unicode": "e871",
|
||||
"unicode_decimal": 59505
|
||||
},
|
||||
{
|
||||
"icon_id": "23261799",
|
||||
"name": "响应icon",
|
||||
"font_class": "xiangyingicon",
|
||||
"unicode": "e87c",
|
||||
"unicode_decimal": 59516
|
||||
},
|
||||
{
|
||||
"icon_id": "23144143",
|
||||
"name": "多选选中",
|
||||
"font_class": "duoxuanxuanzhong",
|
||||
"unicode": "e88f",
|
||||
"unicode_decimal": 59535
|
||||
},
|
||||
{
|
||||
"icon_id": "23144144",
|
||||
"name": "错误icon",
|
||||
"font_class": "cuowuicon",
|
||||
"unicode": "e890",
|
||||
"unicode_decimal": 59536
|
||||
},
|
||||
{
|
||||
"icon_id": "23144146",
|
||||
"name": "成功icon",
|
||||
"font_class": "chenggongicon",
|
||||
"unicode": "e892",
|
||||
"unicode_decimal": 59538
|
||||
},
|
||||
{
|
||||
"icon_id": "23144147",
|
||||
"name": "未选中响应icon",
|
||||
"font_class": "weixuanzhongxiangyingicon",
|
||||
"unicode": "e893",
|
||||
"unicode_decimal": 59539
|
||||
},
|
||||
{
|
||||
"icon_id": "23144149",
|
||||
"name": "必填icon",
|
||||
"font_class": "bitianicon",
|
||||
"unicode": "e895",
|
||||
"unicode_decimal": 59541
|
||||
},
|
||||
{
|
||||
"icon_id": "23144151",
|
||||
"name": "未选中项目标签icon",
|
||||
"font_class": "weixuanzhongxiangmubiaoqianicon",
|
||||
"unicode": "e897",
|
||||
"unicode_decimal": 59543
|
||||
},
|
||||
{
|
||||
"icon_id": "23144152",
|
||||
"name": "列表icon",
|
||||
"font_class": "liebiaoicon",
|
||||
"unicode": "e898",
|
||||
"unicode_decimal": 59544
|
||||
},
|
||||
{
|
||||
"icon_id": "23144155",
|
||||
"name": "未选中请求icon",
|
||||
"font_class": "weixuanzhongqingqiuicon",
|
||||
"unicode": "e89b",
|
||||
"unicode_decimal": 59547
|
||||
},
|
||||
{
|
||||
"icon_id": "23144158",
|
||||
"name": "协作者管理icon",
|
||||
"font_class": "xiezuozheguanliicon",
|
||||
"unicode": "e8a1",
|
||||
"unicode_decimal": 59553
|
||||
},
|
||||
{
|
||||
"icon_id": "23144160",
|
||||
"name": "选中分支icon",
|
||||
"font_class": "xuanzhongfenzhiicon",
|
||||
"unicode": "e8a3",
|
||||
"unicode_decimal": 59555
|
||||
},
|
||||
{
|
||||
"icon_id": "23144162",
|
||||
"name": "选中基本设置icon",
|
||||
"font_class": "xuanzhongjibenshezhiicon",
|
||||
"unicode": "e8a5",
|
||||
"unicode_decimal": 59557
|
||||
},
|
||||
{
|
||||
"icon_id": "23144165",
|
||||
"name": "选中项目标签icon",
|
||||
"font_class": "xuanzhongxiangmubiaoqianicon",
|
||||
"unicode": "e8aa",
|
||||
"unicode_decimal": 59562
|
||||
},
|
||||
{
|
||||
"icon_id": "23144167",
|
||||
"name": "选中webhook icon",
|
||||
"font_class": "a-xuanzhongwebhookicon",
|
||||
"unicode": "e8af",
|
||||
"unicode_decimal": 59567
|
||||
},
|
||||
{
|
||||
"icon_id": "23046290",
|
||||
"name": "shanchu_tc_icon",
|
||||
"font_class": "shanchu_tc_icon",
|
||||
"unicode": "e88c",
|
||||
"unicode_decimal": 59532
|
||||
},
|
||||
{
|
||||
"icon_id": "23046293",
|
||||
"name": "wiki_icon",
|
||||
"font_class": "wiki_icon",
|
||||
"unicode": "e88d",
|
||||
"unicode_decimal": 59533
|
||||
},
|
||||
{
|
||||
"icon_id": "23046244",
|
||||
"name": "导入模版_icon",
|
||||
"font_class": "daorumoban_icon",
|
||||
"unicode": "e86f",
|
||||
"unicode_decimal": 59503
|
||||
},
|
||||
{
|
||||
"icon_id": "23046252",
|
||||
"name": "错误",
|
||||
"font_class": "cuowu",
|
||||
"unicode": "e872",
|
||||
"unicode_decimal": 59506
|
||||
},
|
||||
{
|
||||
"icon_id": "23046255",
|
||||
"name": "更多_icon",
|
||||
"font_class": "gengduo_icon",
|
||||
"unicode": "e874",
|
||||
"unicode_decimal": 59508
|
||||
},
|
||||
{
|
||||
"icon_id": "23046258",
|
||||
"name": "复层关闭_icon",
|
||||
"font_class": "fucengguanbi_icon",
|
||||
"unicode": "e875",
|
||||
"unicode_decimal": 59509
|
||||
},
|
||||
{
|
||||
"icon_id": "23046268",
|
||||
"name": "删除icon",
|
||||
"font_class": "shanchuicon",
|
||||
"unicode": "e877",
|
||||
"unicode_decimal": 59511
|
||||
},
|
||||
{
|
||||
"icon_id": "23046273",
|
||||
"name": "搜索_删除icon",
|
||||
"font_class": "sousuo_shanchuicon",
|
||||
"unicode": "e87b",
|
||||
"unicode_decimal": 59515
|
||||
},
|
||||
{
|
||||
"icon_id": "23046275",
|
||||
"name": "搜索_icon",
|
||||
"font_class": "sousuo_icon",
|
||||
"unicode": "e87d",
|
||||
"unicode_decimal": 59517
|
||||
},
|
||||
{
|
||||
"icon_id": "23046276",
|
||||
"name": "文档预览_icon",
|
||||
"font_class": "wendangyulan_icon",
|
||||
"unicode": "e87e",
|
||||
"unicode_decimal": 59518
|
||||
},
|
||||
{
|
||||
"icon_id": "23046278",
|
||||
"name": "下拉按钮",
|
||||
"font_class": "xialaanniu",
|
||||
"unicode": "e880",
|
||||
"unicode_decimal": 59520
|
||||
},
|
||||
{
|
||||
"icon_id": "22906287",
|
||||
"name": "二次确认_icon",
|
||||
"font_class": "erciqueren_icon",
|
||||
"unicode": "e867",
|
||||
"unicode_decimal": 59495
|
||||
},
|
||||
{
|
||||
"icon_id": "22906288",
|
||||
"name": "选中ssh_icon",
|
||||
"font_class": "xuanzhongssh_icon",
|
||||
"unicode": "e868",
|
||||
"unicode_decimal": 59496
|
||||
},
|
||||
{
|
||||
"icon_id": "22906289",
|
||||
"name": "未选中安全设置_icon",
|
||||
"font_class": "weixuanzhonganquanshezhi_icon",
|
||||
"unicode": "e869",
|
||||
"unicode_decimal": 59497
|
||||
},
|
||||
{
|
||||
"icon_id": "22906290",
|
||||
"name": "未选中ssh_icon",
|
||||
"font_class": "weixuanzhongssh_icon",
|
||||
"unicode": "e86a",
|
||||
"unicode_decimal": 59498
|
||||
},
|
||||
{
|
||||
"icon_id": "22906291",
|
||||
"name": "选中安全设置_icon",
|
||||
"font_class": "xuanzhonganquanshezhi_icon",
|
||||
"unicode": "e86b",
|
||||
"unicode_decimal": 59499
|
||||
},
|
||||
{
|
||||
"icon_id": "22906292",
|
||||
"name": "删除_icon",
|
||||
"font_class": "shanchu_icon",
|
||||
"unicode": "e86c",
|
||||
"unicode_decimal": 59500
|
||||
},
|
||||
{
|
||||
"icon_id": "22906293",
|
||||
"name": "列表ssh_icon",
|
||||
"font_class": "liebiaossh_icon",
|
||||
"unicode": "e86e",
|
||||
"unicode_decimal": 59502
|
||||
},
|
||||
{
|
||||
"icon_id": "17575494",
|
||||
"name": "file-submodule",
|
||||
"font_class": "file-submodule",
|
||||
"unicode": "e866",
|
||||
"unicode_decimal": 59494
|
||||
},
|
||||
{
|
||||
"icon_id": "7539612",
|
||||
"name": "nv",
|
||||
"font_class": "nv1",
|
||||
"unicode": "e864",
|
||||
"unicode_decimal": 59492
|
||||
},
|
||||
{
|
||||
"icon_id": "7539613",
|
||||
"name": "nan",
|
||||
"font_class": "nan1",
|
||||
"unicode": "e865",
|
||||
"unicode_decimal": 59493
|
||||
},
|
||||
{
|
||||
"icon_id": "21936935",
|
||||
"name": "邮箱",
|
||||
"font_class": "youxiang",
|
||||
"unicode": "e8b2",
|
||||
"unicode_decimal": 59570
|
||||
},
|
||||
{
|
||||
"icon_id": "21936924",
|
||||
"name": "单位",
|
||||
"font_class": "danwei",
|
||||
"unicode": "e8a7",
|
||||
"unicode_decimal": 59559
|
||||
},
|
||||
{
|
||||
"icon_id": "21936925",
|
||||
"name": "待办事项",
|
||||
"font_class": "daibanshixiang",
|
||||
"unicode": "e8a8",
|
||||
"unicode_decimal": 59560
|
||||
},
|
||||
{
|
||||
"icon_id": "21936928",
|
||||
"name": "概览",
|
||||
"font_class": "gailan",
|
||||
"unicode": "e8ab",
|
||||
"unicode_decimal": 59563
|
||||
},
|
||||
{
|
||||
"icon_id": "21936929",
|
||||
"name": "男",
|
||||
"font_class": "nan",
|
||||
"unicode": "e8ac",
|
||||
"unicode_decimal": 59564
|
||||
},
|
||||
{
|
||||
"icon_id": "21936930",
|
||||
"name": "女",
|
||||
"font_class": "nv",
|
||||
"unicode": "e8ad",
|
||||
"unicode_decimal": 59565
|
||||
},
|
||||
{
|
||||
"icon_id": "21936931",
|
||||
"name": "工作流",
|
||||
"font_class": "gongzuoliu1",
|
||||
"unicode": "e8ae",
|
||||
"unicode_decimal": 59566
|
||||
},
|
||||
{
|
||||
"icon_id": "21936934",
|
||||
"name": "数据统计",
|
||||
"font_class": "shujutongji",
|
||||
"unicode": "e8b1",
|
||||
"unicode_decimal": 59569
|
||||
},
|
||||
{
|
||||
"icon_id": "21936936",
|
||||
"name": "项目",
|
||||
"font_class": "xiangmu",
|
||||
"unicode": "e8b3",
|
||||
"unicode_decimal": 59571
|
||||
},
|
||||
{
|
||||
"icon_id": "21936937",
|
||||
"name": "组织",
|
||||
"font_class": "zuzhi",
|
||||
"unicode": "e8b4",
|
||||
"unicode_decimal": 59572
|
||||
},
|
||||
{
|
||||
"icon_id": "14835599",
|
||||
"name": "右箭头",
|
||||
"font_class": "arrowRight",
|
||||
"unicode": "e863",
|
||||
"unicode_decimal": 59491
|
||||
},
|
||||
{
|
||||
"icon_id": "21151489",
|
||||
"name": "箭头镂空-左",
|
||||
"font_class": "jiantouloukong-zuo",
|
||||
"unicode": "e861",
|
||||
"unicode_decimal": 59489
|
||||
},
|
||||
{
|
||||
"icon_id": "21151557",
|
||||
"name": "箭头镂空-右",
|
||||
"font_class": "jiantouloukong-you",
|
||||
"unicode": "e862",
|
||||
"unicode_decimal": 59490
|
||||
},
|
||||
{
|
||||
"icon_id": "21568989",
|
||||
"name": "分享",
|
||||
"font_class": "fenxiang1",
|
||||
"unicode": "e89c",
|
||||
"unicode_decimal": 59548
|
||||
},
|
||||
{
|
||||
"icon_id": "21568990",
|
||||
"name": "回到顶部",
|
||||
"font_class": "huidaodingbu1",
|
||||
"unicode": "e89d",
|
||||
"unicode_decimal": 59549
|
||||
},
|
||||
{
|
||||
"icon_id": "21568993",
|
||||
"name": "帮助",
|
||||
"font_class": "bangzhu",
|
||||
"unicode": "e8a0",
|
||||
"unicode_decimal": 59552
|
||||
},
|
||||
{
|
||||
"icon_id": "991344",
|
||||
"name": "提交",
|
||||
"font_class": "tijiao",
|
||||
"unicode": "e860",
|
||||
"unicode_decimal": 59488
|
||||
},
|
||||
{
|
||||
"icon_id": "1852052",
|
||||
"name": "数据库",
|
||||
"font_class": "dataBase",
|
||||
"unicode": "e85a",
|
||||
"unicode_decimal": 59482
|
||||
},
|
||||
{
|
||||
"icon_id": "4165948",
|
||||
"name": "文件",
|
||||
"font_class": "wenjian4",
|
||||
"unicode": "e85b",
|
||||
"unicode_decimal": 59483
|
||||
},
|
||||
{
|
||||
"icon_id": "17165148",
|
||||
"name": "链接",
|
||||
"font_class": "lianjie2",
|
||||
"unicode": "e85c",
|
||||
"unicode_decimal": 59484
|
||||
},
|
||||
{
|
||||
"icon_id": "17463741",
|
||||
"name": "分支",
|
||||
"font_class": "fenzhi2",
|
||||
"unicode": "e85d",
|
||||
"unicode_decimal": 59485
|
||||
},
|
||||
{
|
||||
"icon_id": "17972521",
|
||||
"name": "分支-3",
|
||||
"font_class": "fenzhi-3",
|
||||
"unicode": "e85e",
|
||||
"unicode_decimal": 59486
|
||||
},
|
||||
{
|
||||
"icon_id": "18682391",
|
||||
"name": "天平",
|
||||
"font_class": "tianping",
|
||||
"unicode": "e85f",
|
||||
"unicode_decimal": 59487
|
||||
},
|
||||
{
|
||||
"icon_id": "1770896",
|
||||
"name": "撤销",
|
||||
|
@ -4187,7 +4922,7 @@
|
|||
{
|
||||
"icon_id": "1004630",
|
||||
"name": "点赞2",
|
||||
"font_class": "dianzan1",
|
||||
"font_class": "dianzaned",
|
||||
"unicode": "e639",
|
||||
"unicode_decimal": 58937
|
||||
},
|
||||
|
|
After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 9.7 KiB |
|
@ -2,10 +2,11 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name=”Keywords” Content=”trustie,trustieforge,forge,确实让创建更美好,协同开发平台″>
|
||||
<meta name=”Keywords” Content=”TrustieOpenSourceProject″>
|
||||
<meta name=”Keywords” Content=”issue,bug,tracker,软件工程,课程实践″>
|
||||
<meta name=”Description” Content=”持续构建协同、共享、可信的软件创建生态开源创作与软件生产相结合,支持大规模群体开展软件协同创新活动”>
|
||||
<title>红山开源社区</title>
|
||||
<meta name="keywords" content="红山开源,创客空间,群智共享">
|
||||
<meta name="keywords" content="红山开源社区,开源开放,众创,论坛">
|
||||
<meta name="keywords" content="issue,bug,tracker">
|
||||
<meta name="description" content="红山开源是一个依托互联网群体智慧实现世界范围内资源深度融合、开放共享和协同创新的开源社区" />
|
||||
<meta name="theme-color" content="#000000">
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
|
||||
|
|
22
src/App.js
|
@ -45,6 +45,16 @@ const OpsDetail = Loadable({
|
|||
loader: () => import('./forge/DevOps/opsDetail'),
|
||||
loading: Loading,
|
||||
})
|
||||
// Notice项目公告
|
||||
const Notice = Loadable({
|
||||
loader: () => import('./military/notice'),
|
||||
loading: Loading,
|
||||
})
|
||||
//任务/需求
|
||||
const Task = Loadable({
|
||||
loader: () => import('./military/task'),
|
||||
loading: Loading,
|
||||
})
|
||||
//403页面
|
||||
const Shixunauthority = Loadable({
|
||||
loader: () => import('./modules/403/Shixunauthority'),
|
||||
|
@ -240,6 +250,18 @@ class App extends Component {
|
|||
}
|
||||
}
|
||||
/>
|
||||
{/*公告*/}
|
||||
<Route
|
||||
path={"/notice"}
|
||||
render={
|
||||
(props) => {
|
||||
return (<Notice {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
}>
|
||||
</Route>
|
||||
{/*任务*/}
|
||||
<Route path="/task" component={Task} />
|
||||
|
||||
{/*403*/}
|
||||
<Route path="/403" component={Shixunauthority} />
|
||||
|
||||
|
|
|
@ -4,16 +4,14 @@ import { broadcastChannelOnmessage, isDev, queryString } from 'educoder';
|
|||
import { notification } from 'antd';
|
||||
import cookie from 'react-cookies';
|
||||
import './index.css';
|
||||
|
||||
let message501 = false;
|
||||
|
||||
broadcastChannelOnmessage('refreshPage', () => {
|
||||
window.location.reload();
|
||||
window.location.reload()
|
||||
})
|
||||
|
||||
function locationurl(list) {
|
||||
if (window.location.port === "3007") {
|
||||
|
||||
} else {
|
||||
if (window.location.port !== "3007") {
|
||||
window.location.href = list
|
||||
}
|
||||
}
|
||||
|
@ -27,14 +25,14 @@ if (isDev) {
|
|||
}
|
||||
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
|
||||
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
|
||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 's'
|
||||
}
|
||||
function clearAllCookie() {
|
||||
cookie.remove('_educoder_session', { path: '/' });
|
||||
cookie.remove('autologin_trustie', { path: '/' });
|
||||
setpostcookie()
|
||||
}
|
||||
clearAllCookie();
|
||||
// clearAllCookie();
|
||||
function setpostcookie() {
|
||||
const str = window.location.pathname;
|
||||
if (str.indexOf("/wxcode") !== -1) {
|
||||
|
@ -54,9 +52,11 @@ setpostcookie();
|
|||
|
||||
window._debugType = debugType;
|
||||
export function initAxiosInterceptors(props) {
|
||||
initOnlineOfflineListener();
|
||||
var proxy = "http://localhost:3000";
|
||||
proxy = "https://testforgeplus.trustie.net";
|
||||
initOnlineOfflineListener()
|
||||
// TODO 避免重复的请求 https://github.com/axios/axios#cancellation
|
||||
var
|
||||
proxy = "http://localhost:3000";
|
||||
proxy = "https://forge.osredm.com";
|
||||
|
||||
const requestMap = {};
|
||||
window.setfalseInRequestMap = function (keyName) {
|
||||
|
@ -90,7 +90,6 @@ export function initAxiosInterceptors(props) {
|
|||
}
|
||||
if (config.url.indexOf('update_file') === -1) {
|
||||
requestMap[config.url] = true;
|
||||
|
||||
window.setTimeout("setfalseInRequestMap('" + config.url + "')", 900)
|
||||
}
|
||||
return config;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import moment from "moment";
|
||||
import moment from "moment";
|
||||
|
||||
// 处理整点 半点
|
||||
// 取传入时间往后的第一个半点
|
||||
|
@ -12,7 +12,7 @@ export function handleDateString(dateString) {
|
|||
if (miniute < 30 || miniute == 60) {
|
||||
return [ar[0], '30'].join(':')
|
||||
}
|
||||
if (miniute < 60) {
|
||||
if (miniute < 60) {
|
||||
// 加一个小时
|
||||
const tempStr = [ar[0], '00'].join(':');
|
||||
const format = "YYYY-MM-DD HH:mm";
|
||||
|
@ -20,7 +20,7 @@ export function handleDateString(dateString) {
|
|||
_moment.add(1, 'hours')
|
||||
return _moment.format(format)
|
||||
}
|
||||
|
||||
|
||||
return dateString
|
||||
}
|
||||
|
||||
|
@ -38,62 +38,91 @@ export function getNextHalfHourOfMoment(moment) {
|
|||
return moment
|
||||
}
|
||||
|
||||
export function formatSeconds(value) {
|
||||
export function formatSeconds(value) {
|
||||
|
||||
var theTime = parseInt(value);// 秒
|
||||
var middle= 0;// 分
|
||||
var hour= 0;// 小时
|
||||
|
||||
if(theTime > 60) {
|
||||
middle= parseInt(theTime/60);
|
||||
theTime = parseInt(theTime%60);
|
||||
if(middle> 60) {
|
||||
hour= parseInt(middle/60);
|
||||
middle= parseInt(middle%60);
|
||||
}
|
||||
}
|
||||
var result = ""+parseInt(theTime)+"秒";
|
||||
if(middle > 0) {
|
||||
if(hour>0){
|
||||
result = ""+parseInt(middle)+"分";
|
||||
}else{
|
||||
result = ""+parseInt(middle)+"分"+result;
|
||||
}
|
||||
|
||||
}
|
||||
if(hour> 0) {
|
||||
result = ""+parseInt(hour)+"小时"+result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var theTime = parseInt(value);// 秒
|
||||
var middle = 0;// 分
|
||||
var hour = 0;// 小时
|
||||
|
||||
export function formatDuring(mss){
|
||||
var days = parseInt(mss / (1000 * 60 * 60 * 24));
|
||||
var hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||
var minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
|
||||
// console.log("formatDuringformatDuring");
|
||||
// console.log(days);
|
||||
// console.log(hours);
|
||||
// console.log(minutes);
|
||||
// console.log(Math.abs(days));
|
||||
// console.log(Math.abs(hours));
|
||||
// console.log(Math.abs(minutes));
|
||||
if (theTime > 60) {
|
||||
middle = parseInt(theTime / 60);
|
||||
theTime = parseInt(theTime % 60);
|
||||
if (middle > 60) {
|
||||
hour = parseInt(middle / 60);
|
||||
middle = parseInt(middle % 60);
|
||||
}
|
||||
}
|
||||
var result = "" + parseInt(theTime) + "秒";
|
||||
if (middle > 0) {
|
||||
if (hour > 0) {
|
||||
result = "" + parseInt(middle) + "分";
|
||||
} else {
|
||||
result = "" + parseInt(middle) + "分" + result;
|
||||
}
|
||||
|
||||
try {
|
||||
days = Math.abs(days);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
try {
|
||||
hours = Math.abs(hours);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
try {
|
||||
minutes = Math.abs(minutes);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
return days + "天" + hours + "小时" + minutes + "分";
|
||||
}
|
||||
if (hour > 0) {
|
||||
result = "" + parseInt(hour) + "小时" + result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
export function formatDuring(s) {
|
||||
s = Math.abs(s);
|
||||
let days = Math.floor(s / (60 * 60 * 24));
|
||||
let hours = Math.floor((s % (60 * 60 * 24)) / (60 * 60));
|
||||
let minutes = Math.floor((s % (60 * 60)) / (60));
|
||||
let second = Math.floor(s % 60);
|
||||
|
||||
if (days) {
|
||||
if(hours){
|
||||
return days + "天" + hours + "小时";
|
||||
}
|
||||
return days + "天";
|
||||
}
|
||||
if (hours) {
|
||||
if(minutes){
|
||||
return hours + "小时" + minutes + "分";
|
||||
}
|
||||
return hours + "小时" ;
|
||||
}
|
||||
if (minutes) {
|
||||
return minutes + "分";
|
||||
}
|
||||
return second + "秒";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
返回:多久以前
|
||||
backDate:以前的某个日期
|
||||
*/
|
||||
export function timeAgo(backDate) {
|
||||
try {
|
||||
moment(backDate);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
let time = new Date() - moment(backDate);
|
||||
var days = Math.floor(time / (1000 * 60 * 60 * 24));
|
||||
var hours = Math.floor((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||
var minutes = Math.floor((time % (1000 * 60 * 60)) / (1000 * 60));
|
||||
var seconds = Math.floor((time % (1000 * 60 * 60)) / 1000);
|
||||
if (time <= 0) {
|
||||
return "刚刚";
|
||||
}
|
||||
if (days) {
|
||||
return days + "天前";
|
||||
}
|
||||
if (hours) {
|
||||
return hours + "小时前";
|
||||
}
|
||||
if (minutes) {
|
||||
return minutes + "分前";
|
||||
}
|
||||
if (seconds) {
|
||||
return seconds + "秒前";
|
||||
}
|
||||
}
|
|
@ -68,7 +68,7 @@ export function appendFileSizeToUploadFile(item) {
|
|||
return `${item.title}${uploadNameSizeSeperator}${item.filesize}`
|
||||
}
|
||||
export function appendFileSizeToUploadFileAll(fileList) {
|
||||
return fileList.map(item => {
|
||||
return fileList && fileList.map(item => {
|
||||
if (item.name.indexOf(uploadNameSizeSeperator) == -1) {
|
||||
return Object.assign({}, item, { name: `${item.name}${uploadNameSizeSeperator}${bytesToSize(item.size)}` })
|
||||
}
|
||||
|
|
|
@ -6,12 +6,13 @@ const { Search } = Input;
|
|||
const $ = window.$;
|
||||
const isDev = window.location.port == 3007;
|
||||
const isdev2= window.location.hostname ==='www.educoder.net'
|
||||
export const TEST_HOST = "https://testforgeplus.trustie.net/"
|
||||
export const TEST_HOST = "http://39.105.176.215:49999"
|
||||
export function getImageUrl(path) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
// const local = 'http://localhost:3000'
|
||||
const local = 'https://testforgeplus.trustie.net';
|
||||
const local = 'http://39.105.176.215:49999';
|
||||
|
||||
if (isDev) {
|
||||
return `${local}/${path}`
|
||||
}
|
||||
|
@ -22,7 +23,7 @@ export function getImage(path) {
|
|||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
// const local = 'http://localhost:3000'
|
||||
const local = 'https://testforgeplus.trustie.net/';
|
||||
const local = 'http://39.105.176.215:49999';
|
||||
if(path.indexOf("http://")===-1){
|
||||
if (isDev) {
|
||||
return `${local}/images/${path}`
|
||||
|
@ -93,7 +94,7 @@ export function setImagesUrl(path){
|
|||
}
|
||||
|
||||
export function getUrl(path, goTest) {
|
||||
const local = 'https://testforgeplus.trustie.net'
|
||||
const local = 'http://39.105.176.215:49999'
|
||||
if (isDev) {
|
||||
return `${local}${path?path:''}`
|
||||
}
|
||||
|
@ -162,7 +163,7 @@ export function getmyUrl(geturl) {
|
|||
}
|
||||
|
||||
export function getUploadActionUrl(path, goTest) {
|
||||
return `${getUrl()}/api/attachments.json?debug=${window._debugType || 'admin'}`;
|
||||
return `${getUrl()}/api/attachments.json`;
|
||||
}
|
||||
|
||||
export function getUploadLogoActionUrl() {
|
||||
|
|
|
@ -27,7 +27,7 @@ export {
|
|||
markdownToHTML, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, isImageExtension,
|
||||
downloadFile, sortDirections, validateLength, mdJSONParse, exportMdtoHtml
|
||||
} from './TextUtil'
|
||||
export { handleDateString, getNextHalfHourOfMoment, formatDuring, formatSeconds } from './DateUtil'
|
||||
export { handleDateString, getNextHalfHourOfMoment, formatDuring, formatSeconds ,timeAgo} from './DateUtil'
|
||||
|
||||
export { configShareForIndex, configShareForPaths, configShareForShixuns, configShareForCourses, configShareForCustom } from './util/ShareUtil'
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class CloneAddress extends Component {
|
|||
const { http_url, downloadUrl } = this.props;
|
||||
return (
|
||||
<div className="gitAddressClone">
|
||||
{/* <p className="addressTips"><span>版本库地址已变更,请基于新地址提交代码</span></p> */}
|
||||
<p className="addressTips"><span>版本库地址已变更,请基于新地址提交代码</span></p>
|
||||
{
|
||||
http_url && <span>HTTP</span>
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
|
||||
|
||||
import React , { useState , useEffect } from 'react';
|
||||
import { Select } from 'antd';
|
||||
import axios from 'axios';
|
||||
|
@ -57,7 +59,6 @@ const LANGUAGE = [
|
|||
|
||||
export default (({ language , select_language })=>{
|
||||
const [ languages , setLanguage ] = useState(undefined);
|
||||
|
||||
// useEffect(()=>{
|
||||
// const url = '/dev_ops/languages.json';
|
||||
// axios.get(url).then(result=>{
|
||||
|
|
Before Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 222 KiB |
|
@ -145,7 +145,7 @@ class CoderRootCommit extends Component{
|
|||
)
|
||||
})
|
||||
}
|
||||
{commitDatas && commitDatas.length > 0 && <Nodata _html="暂无数据"/>}
|
||||
{commitDatas && commitDatas.length === 0 && <Nodata _html="暂无数据"/>}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
|
|
|
@ -251,7 +251,7 @@ class CoderRootDirectory extends Component {
|
|||
// readme文件内容
|
||||
renderReadMeContent = (readMeContent, permission) => {
|
||||
const { fileDetail, readMeFile } = this.state;
|
||||
if (fileDetail) {
|
||||
if (fileDetail && fileDetail.length !== 0) {
|
||||
return;
|
||||
}
|
||||
if (readMeContent && readMeContent.length > 0) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import { Link, Route, Switch } from 'react-router-dom';
|
|||
import { Content } from '../Component/layout';
|
||||
import '../css/index.scss'
|
||||
import './list.css';
|
||||
import SpecialModal from './SpecialModal';
|
||||
|
||||
import Loadable from 'react-loadable';
|
||||
import Loading from '../../Loading';
|
||||
|
@ -117,19 +118,20 @@ const DevIndex = Loadable({
|
|||
function checkPathname(projectsId,owner,pathname){
|
||||
let name = "";
|
||||
if(pathname && pathname !== `/projects/${owner}/${projectsId}`){
|
||||
if(pathname.indexOf("/about")>-1){
|
||||
let url = pathname.split(`/projects/${owner}/${projectsId}`)[1];
|
||||
if(url.indexOf("/about")>-1){
|
||||
name="about"
|
||||
}else if(pathname.indexOf("/issues")>-1 ||pathname.indexOf("Milepost") > 0){
|
||||
}else if(url.indexOf("/issues")>-1 ||url.indexOf("Milepost") > 0){
|
||||
name = "issues";
|
||||
}else if(pathname.indexOf("/pulls")>-1){
|
||||
}else if(url.indexOf("/pulls")>-1){
|
||||
name="pulls"
|
||||
}else if(pathname.indexOf("/milestones")>-1){
|
||||
}else if(url.indexOf("/milestones")>-1){
|
||||
name="milestones"
|
||||
}else if(pathname.indexOf("/activity")>-1){
|
||||
}else if(url.indexOf("/activity")>-1){
|
||||
name="activity"
|
||||
}else if(pathname.indexOf("/setting")>-1){
|
||||
}else if(url.indexOf("/setting")>-1){
|
||||
name="setting"
|
||||
}else if(pathname.indexOf(`/devops`)>-1){
|
||||
}else if(url.indexOf(`/devops`)>-1){
|
||||
name="devops"
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +163,9 @@ class Detail extends Component {
|
|||
defaultBranch:undefined,
|
||||
|
||||
// 非本平台项目
|
||||
platform:false
|
||||
platform:false,
|
||||
visible:false,
|
||||
user_apply_signatures:[]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,6 +182,7 @@ class Detail extends Component {
|
|||
}
|
||||
|
||||
getProject = (num) => {
|
||||
const {user} = this.props;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/simple.json`;
|
||||
axios.get(url).then((result) => {
|
||||
|
@ -187,6 +192,24 @@ class Detail extends Component {
|
|||
open_devops:result.data.open_devops,
|
||||
platform:result.data.platform && result.data.platform !== 'educoder'
|
||||
})
|
||||
let signa = result.data.user_apply_signatures && result.data.user_apply_signatures[0];
|
||||
if(result.data.is_secret && !result.data.is_member && (!signa || (signa && signa.status !== "passed")) && user.login !== owner){
|
||||
this.setState({
|
||||
visible:true,
|
||||
is_secret:result.data.is_secret,
|
||||
user_apply_signatures:signa
|
||||
})
|
||||
}
|
||||
|
||||
// 工作流:两种状态进入的链接不同
|
||||
const pathname = this.props.history.location.pathname;
|
||||
if(pathname===`/projects/${owner}/${projectsId}/devops`){
|
||||
if(result.data.open_devops && pathname === `/projects/${owner}/${projectsId}/devops`){
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/devops/list`);
|
||||
}else if(result.data.open_devops===false && pathname !== `/projects/${owner}/${projectsId}/devops`){
|
||||
this.props.history.push(`/projects/${owner}/${projectsId}/devops`);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.data.type !== 0 && result.data.mirror_status === 1) {
|
||||
console.log("--------start channel --------");
|
||||
|
@ -357,13 +380,24 @@ class Detail extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
hideModal=()=>{
|
||||
this.setState({
|
||||
visible:false
|
||||
})
|
||||
}
|
||||
|
||||
sureModal=()=>{
|
||||
this.hideModal();
|
||||
this.props.history.push('/projects');
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
const { projectDetail, watchers_count, praises_count,
|
||||
forked_count, firstSync , secondSync ,
|
||||
isManager, watched, praised,
|
||||
project , open_devops , platform , defaultBranch } = this.state;
|
||||
project , open_devops , platform , defaultBranch , project_id , user_apply_signatures , visible } = this.state;
|
||||
const url = this.props.history.location.pathname;
|
||||
const urlArr = url.split("/");
|
||||
const urlFlag = (urlArr.length === 3);
|
||||
|
@ -390,18 +424,19 @@ class Detail extends Component {
|
|||
}
|
||||
return (
|
||||
<div>
|
||||
<SpecialModal {...this.props} visible={visible} hideModal={this.sureModal} user_apply_signatures={user_apply_signatures} project_id={project_id} sureModal={this.sureModal}></SpecialModal>
|
||||
<div className="detailHeader-wrapper">
|
||||
<div className="normal">
|
||||
<div className="f-wrap-between pb15" style={{ position: "relative" }}>
|
||||
<p className="font-22 df flex-1 lineH2 mt15" style={{ alignItems: "center" }}>
|
||||
<p className="color-white font-22 df flex-1 lineH2 mt15" style={{ alignItems: "center" }}>
|
||||
{project && project.author &&
|
||||
<Link to={`${project.author.type ==="Organization" ? "/organize":'/users'}/${project.author.login}`} className="show-user-link">
|
||||
<Link to={`/users/${project.author.login}`} className="show-user-link color-white">
|
||||
{project.author.name}
|
||||
</Link>
|
||||
}
|
||||
<span className="ml5 mr5">/</span>
|
||||
<span className="hide-1 flex-1 df">
|
||||
<Link to={`/projects/${owner}/${projectsId}`} className="font-22">{project && project.name}</Link>
|
||||
<Link to={`/projects/${owner}/${projectsId}`} className="color-white font-22">{project && project.name}</Link>
|
||||
{
|
||||
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
||||
<Tooltip placement={'right'} title={text}>
|
||||
|
@ -438,15 +473,14 @@ class Detail extends Component {
|
|||
<span>{watched ? '取消关注' : '关注'}</span>
|
||||
</a>
|
||||
{
|
||||
watchers_count > 0 ?
|
||||
platform ?
|
||||
<Link className="detail_tag_btn_count" style={{color:`${watched?"#2878FF":"#666"}`}} to={platform?{ pathname: `/projects/${owner}/${projectsId}/watchers`, state }:""}>
|
||||
{watchers_count}
|
||||
</Link>
|
||||
:
|
||||
<span className="detail_tag_btn_count">{watchers_count}</span>
|
||||
:""
|
||||
}
|
||||
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={() => this.pariseFunc(praised)}>
|
||||
|
@ -454,13 +488,11 @@ class Detail extends Component {
|
|||
<span>{praised ? '取消点赞' : '点赞'}</span>
|
||||
</a>
|
||||
{
|
||||
praises_count > 0 ?
|
||||
platform ?
|
||||
<Link className="detail_tag_btn_count" style={{color:`${praised?"#2878FF":"#666"}`}} to={{ pathname: `/projects/${owner}/${projectsId}/stargazers`, state }}>
|
||||
{praises_count}
|
||||
</Link>:
|
||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||
:""
|
||||
}
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
|
@ -468,14 +500,12 @@ class Detail extends Component {
|
|||
<i className="iconfont icon-fork color-grey-9 mr3"></i>复刻 (Fork)
|
||||
</a>
|
||||
{
|
||||
forked_count > 0 ?
|
||||
platform ?
|
||||
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${owner}/${projectsId}/fork_users`, state }}>
|
||||
{forked_count}
|
||||
</Link>
|
||||
:
|
||||
<span className="detail_tag_btn_count">{forked_count}</span>
|
||||
:""
|
||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||
}
|
||||
</span>
|
||||
</span>
|
||||
|
@ -483,23 +513,23 @@ class Detail extends Component {
|
|||
</div>
|
||||
{
|
||||
firstSync ? "" :
|
||||
<div className="f-wrap-between mt15">
|
||||
<div className="f-wrap-between pb20">
|
||||
<ul className="headerMenu-wrapper">
|
||||
<li className={pathname==="about" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/about`, state }}>
|
||||
<i className={(pathname==="" || urlFlag) ? "iconfont icon-zhuye1 color-grey-3 mr5 font-14":"iconfont icon-zhuye1 color-grey-6 font-14 mr5"}></i>
|
||||
<i className={ pathname === "about" ? "iconfont icon-zhuye1 color-blue mr5 font-14":"iconfont icon-zhuye1 color-white font-14 mr5"}></i>
|
||||
<span>主页</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className={(pathname==="" || urlFlag) ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}`, state }}>
|
||||
<i className={(pathname==="" || urlFlag) ? "iconfont icon-daimaku color-grey-3 mr5 font-14":"iconfont icon-daimaku color-grey-6 font-14 mr5"}></i>
|
||||
<i className={(pathname==="" || urlFlag) ? "iconfont icon-daimaku color-blue mr5 font-14":"iconfont icon-daimaku color-white font-14 mr5"}></i>
|
||||
<span>代码库</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li className={pathname==="issues" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/issues`, state }}>
|
||||
<i className={pathname==="issues" ? "iconfont icon-renwu color-grey-3 mr5 font-14":"iconfont icon-renwu color-grey-6 font-14 mr5"}></i>
|
||||
<i className={pathname==="issues" ? "iconfont icon-renwu color-blue mr5 font-14":"iconfont icon-renwu color-white font-14 mr5"}></i>
|
||||
<span>易修 (Issue)</span>
|
||||
{projectDetail && projectDetail.issues_count ? <span className="num">{projectDetail.issues_count}</span> : ""}
|
||||
</Link>
|
||||
|
@ -508,32 +538,32 @@ class Detail extends Component {
|
|||
projectDetail && parseInt(projectDetail.type) !== 2 && platform &&
|
||||
<li className={pathname==="pulls" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/pulls`, state }}>
|
||||
<i className={pathname==="pulls" ? "iconfont icon-hebingqingqiu1 color-grey-3 mr5 font-14":"iconfont icon-hebingqingqiu1 color-grey-6 font-14 mr5"}></i>
|
||||
<i className={pathname==="pulls" ? "iconfont icon-hebingqingqiu1 color-blue mr5 font-14":"iconfont icon-hebingqingqiu1 color-white font-14 mr5"}></i>
|
||||
<span>合并请求</span>
|
||||
{projectDetail && projectDetail.pull_requests_count ? <span className="num">{projectDetail.pull_requests_count}</span> : ""}
|
||||
</Link>
|
||||
</li>
|
||||
}
|
||||
{
|
||||
{/* {
|
||||
platform &&
|
||||
<li className={pathname==="devops" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/devops${open_devops ? `/dispose`:""}`, state }}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/devops${open_devops ? `/list`:""}`, state }}>
|
||||
<i className="iconfont icon-gongzuoliu font-13 mr8"></i>工作流(beta版)
|
||||
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
|
||||
</Link>
|
||||
</li>
|
||||
}
|
||||
} */}
|
||||
|
||||
<li className={pathname==="milestones" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/milestones`, state }}>
|
||||
<i className={pathname==="milestones" ? "iconfont icon-lichengbei color-grey-3 mr5 font-14":"iconfont icon-lichengbei color-grey-6 font-14 mr5"}></i>
|
||||
<i className={pathname==="milestones" ? "iconfont icon-lichengbei color-blue mr5 font-14":"iconfont icon-lichengbei color-white font-14 mr5"}></i>
|
||||
<span>里程碑</span>
|
||||
{projectDetail && projectDetail.versions_count ? <span className="num">{projectDetail.versions_count}</span> :""}
|
||||
</Link>
|
||||
</li>
|
||||
<li className={pathname==="activity" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/activity`, state }}>
|
||||
<i className={pathname==="activity" ? "iconfont icon-tongzhi color-grey-3 mr5 font-14":"iconfont icon-tongzhi color-grey-6 font-14 mr5"}></i>
|
||||
<i className={pathname==="activity" ? "iconfont icon-tongzhi color-blue mr5 font-14":"iconfont icon-tongzhi color-white font-14 mr5"}></i>
|
||||
<span>动态</span>
|
||||
</Link>
|
||||
</li>
|
||||
|
@ -541,7 +571,7 @@ class Detail extends Component {
|
|||
isManager && platform &&
|
||||
<li className={url.indexOf("/setting") > 0 ? "active" : ""}>
|
||||
<Link to={`/projects/${owner}/${projectsId}/setting`}>
|
||||
<i className={url.indexOf("/setting") > 0 ? "iconfont icon-cangku color-grey-3 mr5 font-14":"iconfont icon-cangku color-grey-6 font-14 mr5"}></i>
|
||||
<i className={url.indexOf("/setting") > 0 ? "iconfont icon-cangku color-blue mr5 font-14":"iconfont icon-cangku color-white font-14 mr5"}></i>
|
||||
<span>仓库设置</span>
|
||||
</Link>
|
||||
</li>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Menu, Input , Spin, Pagination , Popover , Select } from 'antd';
|
||||
import { getUrl } from 'educoder';
|
||||
import { Menu, Input , Spin, Pagination , Popover, Affix, } from 'antd';
|
||||
import '../css/index.scss'
|
||||
import './list.css';
|
||||
import './Index.scss';
|
||||
|
@ -9,7 +8,7 @@ import ListItem from './IndexItem'
|
|||
import axios from 'axios';
|
||||
import img_new from '../Images/new.png';
|
||||
import img_array from '../Images/array.png';
|
||||
import banner from '../Images/banner_list.jpg';
|
||||
import banner from '../Images/banner_list.png';
|
||||
const Search = Input.Search;
|
||||
|
||||
class Index extends Component {
|
||||
|
@ -23,7 +22,6 @@ class Index extends Component {
|
|||
sort: undefined,
|
||||
total: 0,
|
||||
isSpin: true,
|
||||
project_type: undefined,
|
||||
category_id: undefined,
|
||||
|
||||
typeList: undefined,
|
||||
|
@ -37,8 +35,8 @@ class Index extends Component {
|
|||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
const { page, limit, search, sort, project_type, category_id , languageId } = this.state;
|
||||
this.getListData(page, limit, search, sort, project_type, category_id , languageId);
|
||||
const { page,search, sort,category_id , languageId } = this.state;
|
||||
this.getListData(page,search, sort,category_id , languageId);
|
||||
|
||||
this.getType();
|
||||
|
||||
|
@ -73,19 +71,24 @@ class Index extends Component {
|
|||
}
|
||||
|
||||
// 获取列表
|
||||
getListData = (page, limit, search, sort, project_type, category_id,languageId) => {
|
||||
getListData = (page,search, sort,category_id,language_id) => {
|
||||
const { current_user } = this.props;
|
||||
const url = `/projects.json`;
|
||||
if(category_id==0){
|
||||
category_id=undefined;
|
||||
}
|
||||
if(language_id==0){
|
||||
language_id=undefined;
|
||||
}
|
||||
axios.get(url, {
|
||||
params: {
|
||||
user_id: current_user && current_user.user_id,
|
||||
page,
|
||||
limit,
|
||||
limit:15,
|
||||
search,
|
||||
sort_by: sort,
|
||||
project_type,
|
||||
category_id,
|
||||
language_id:languageId
|
||||
language_id
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
|
@ -103,7 +106,11 @@ class Index extends Component {
|
|||
const url = `/projects/group_type_list.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
this.setTypeList(result.data, undefined)
|
||||
result.data.unshift({
|
||||
name:'全部语言',
|
||||
id:0,
|
||||
});
|
||||
this.setTypeList(result.data, 0)
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}
|
||||
|
@ -112,7 +119,7 @@ class Index extends Component {
|
|||
this.setState({
|
||||
typeList: list.map((item, key) => {
|
||||
return (
|
||||
<li key={key} className={active_type && active_type === item.project_type ? 'active' : ''} onClick={() => this.changeType(`${item.project_type}`, list)}>
|
||||
<li key={key} className={ parseInt(active_type) === item.id ? 'active' : ''} onClick={() => this.changeType(`${item.id}`, list)}>
|
||||
<p>
|
||||
<span className="font-16">{item.name}</span>
|
||||
<span className="color-blue">{item.projects_count}</span>
|
||||
|
@ -123,16 +130,16 @@ class Index extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
// 切换类型
|
||||
changeType = (type, list) => {
|
||||
// 切换语言类型
|
||||
changeType = (id, list) => {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
project_type: type,
|
||||
languageId: id,
|
||||
search: undefined
|
||||
})
|
||||
this.setTypeList(list, type)
|
||||
const { page, limit, sort, category_id , languageId } = this.state;
|
||||
this.getListData(page, limit, undefined, sort, type, category_id , languageId);
|
||||
this.setTypeList(list, id);
|
||||
const { page,sort, category_id} = this.state;
|
||||
this.getListData(page,undefined, sort,category_id , id);
|
||||
}
|
||||
|
||||
// 获取类型
|
||||
|
@ -141,7 +148,11 @@ class Index extends Component {
|
|||
|
||||
axios.get(url).then((result) => {
|
||||
if (result && result.data) {
|
||||
this.setCategoryList(result.data, undefined);
|
||||
result.data.unshift({
|
||||
name:'全部类别',
|
||||
id:0,
|
||||
});
|
||||
this.setCategoryList(result.data, 0);
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}
|
||||
|
@ -150,7 +161,7 @@ class Index extends Component {
|
|||
this.setState({
|
||||
categoryList: list.map((item, key) => {
|
||||
return (
|
||||
<li key={key} className={active_id && parseInt(active_id) === item.id ? 'active' : ''} onClick={() => this.changeCategory(`${item.id}`, list)}>
|
||||
<li key={key} className={ parseInt(active_id) === item.id ? 'active' : ''} onClick={() => this.changeCategory(`${item.id}`, list)}>
|
||||
<p>
|
||||
<span className="font-16">{item.name}</span>
|
||||
<span className="color-blue">{item.projects_count}</span>
|
||||
|
@ -167,8 +178,8 @@ class Index extends Component {
|
|||
page: 1
|
||||
});
|
||||
this.setCategoryList(list, id)
|
||||
const { limit, sort, project_type , languageId } = this.state;
|
||||
this.getListData(1, limit, undefined, sort, project_type, id , languageId);
|
||||
const { sort,languageId } = this.state;
|
||||
this.getListData(1,undefined, sort,id , languageId);
|
||||
}
|
||||
|
||||
// 排序
|
||||
|
@ -179,8 +190,8 @@ class Index extends Component {
|
|||
search: undefined,
|
||||
isSpin: true
|
||||
})
|
||||
const { limit, project_type, category_id , languageId } = this.state;
|
||||
this.getListData(1, limit, undefined, e.key, project_type, category_id , languageId);
|
||||
const {category_id , languageId } = this.state;
|
||||
this.getListData(1,undefined, e.key,category_id , languageId);
|
||||
}
|
||||
|
||||
// 搜索
|
||||
|
@ -192,8 +203,8 @@ class Index extends Component {
|
|||
project_type: undefined,
|
||||
sort: "updated_on"
|
||||
})
|
||||
const { limit, sort, category_id , languageId } = this.state;
|
||||
this.getListData(1, limit, value, sort, undefined, category_id , languageId);
|
||||
const {sort, category_id , languageId } = this.state;
|
||||
this.getListData(1,value, sort,category_id , languageId);
|
||||
}
|
||||
changeSearchValue = (e) => {
|
||||
this.setState({
|
||||
|
@ -205,23 +216,14 @@ class Index extends Component {
|
|||
this.setState({
|
||||
page
|
||||
})
|
||||
const { limit, search, sort, project_type, category_id , languageId } = this.state;
|
||||
this.getListData(page, limit, search, sort, project_type, category_id , languageId);
|
||||
const {search, sort,category_id , languageId } = this.state;
|
||||
this.getListData(page,search, sort, category_id , languageId);
|
||||
}
|
||||
|
||||
getoDetail=(login,identifier)=>{
|
||||
this.props.history.push(`/projects/${login}/${identifier}`);
|
||||
}
|
||||
|
||||
// 选择语言类别
|
||||
changeLanguage=(e)=>{
|
||||
this.setState({
|
||||
isSpin:true,
|
||||
languageId:e === 0 ?undefined:e
|
||||
})
|
||||
const { page, limit, sort , project_type , category_id } = this.state;
|
||||
this.getListData(page, limit, undefined, sort, project_type, category_id ,e === 0 ?undefined:e);
|
||||
}
|
||||
|
||||
menu =()=> {
|
||||
return(
|
||||
|
@ -255,15 +257,14 @@ class Index extends Component {
|
|||
render() {
|
||||
const { current_user } = this.props;
|
||||
|
||||
const { projectsList , recommendList , languageList , languageId ,
|
||||
isSpin, total, search, limit, page, typeList, categoryList } = this.state;
|
||||
const { projectsList , isSpin , total , search , limit , page , typeList , categoryList } = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p className="t_project_banner">
|
||||
<img src={banner} width="100%" alt=""/>
|
||||
</p>
|
||||
{
|
||||
{/* {
|
||||
recommendList && recommendList.length>0 &&
|
||||
<div className="recommandProjects">
|
||||
{
|
||||
|
@ -285,44 +286,29 @@ class Index extends Component {
|
|||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
*/}
|
||||
<div className="ProjectListIndex">
|
||||
<div className="list-left">
|
||||
|
||||
<Affix className="affix-list-left" offsetTop={90}>
|
||||
<div className="affix-list-content">
|
||||
<ul className="list-l-Menu">
|
||||
<li className="MenuTitle"><i className="iconfont icon-xiangmuleixing color-grey-9 font-15 mr5"></i>项目类型</li>
|
||||
{typeList}
|
||||
<li className="MenuTitle" onClick={() => {this.getType();this.changeType(undefined, this.state.typeList);}}>
|
||||
<span><i className="iconfont icon-bianchengyuyan color-grey-9 font-15 mr5"></i>
|
||||
语言</span></li>
|
||||
<div className="list-affix">{typeList}</div>
|
||||
</ul>
|
||||
<ul className="list-l-Menu">
|
||||
<li className="MenuTitle"><i className="iconfont icon-xiangmuleibie color-grey-9 font-15 mr5"></i>项目类别</li>
|
||||
{categoryList}
|
||||
<li className="MenuTitle" onClick={() => {this.getCategory();this.changeCategory(undefined, this.state.categoryList);}}>
|
||||
<span><i className="iconfont icon-xiangmuleibie color-grey-9 font-15 mr5"></i>项目类别</span></li>
|
||||
<div className="list-affix">{categoryList}</div>
|
||||
</ul>
|
||||
</div>
|
||||
</Affix>
|
||||
|
||||
<div className="list-right boxShandow radius-2" style={{padding:0}}>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="list-r-operation">
|
||||
<div>
|
||||
<Select
|
||||
showSearch
|
||||
placeholder="请选择语言"
|
||||
style={{width:"150px",marginRight:"20px"}}
|
||||
size={"large"}
|
||||
onChange={this.changeLanguage}
|
||||
value={languageId}
|
||||
allowClear={true}
|
||||
optionFilterProp="children"
|
||||
filterOption={(input,option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
|
||||
>
|
||||
<Select.Option key={0} value={0}>请选择语言</Select.Option>
|
||||
{
|
||||
languageList && languageList.length>0 && languageList.map((item,key)=>{
|
||||
return(
|
||||
<Select.Option key={item.id} value={item.id}>
|
||||
{item.name}
|
||||
</Select.Option>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Select>
|
||||
<Search
|
||||
placeholder="输入项目名称关键字进行搜索"
|
||||
enterButton="搜索"
|
||||
|
@ -350,7 +336,7 @@ class Index extends Component {
|
|||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
<ListItem {...this.props} {...this.state} projects={projectsList}></ListItem>
|
||||
<ListItem {...this.props} {...this.state} projects={projectsList} getListData={this.getListData}></ListItem>
|
||||
{this.pagination(total,limit,page)}
|
||||
</Spin>
|
||||
</div>
|
||||
|
|
|
@ -71,4 +71,16 @@
|
|||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
.singleBtn{
|
||||
display: inline-block;
|
||||
.ant-upload-list-item{
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
width: 100%;
|
||||
left: 0px;
|
||||
.ant-upload-list-item-name{
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,72 +6,123 @@ import '../css/index.scss';
|
|||
import Nodata from '../Nodata';
|
||||
import './list.css';
|
||||
import img_parise from '../Images/parise.png';
|
||||
import SpecialModal from './SpecialModal';
|
||||
|
||||
class IndexItem extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
visible:false,
|
||||
user_apply_signatures:[],
|
||||
project_id:undefined
|
||||
}
|
||||
}
|
||||
TurnToDetail = (login, url) => {
|
||||
this.props.history.push({
|
||||
pathname: url,
|
||||
state: login
|
||||
})
|
||||
}
|
||||
/**
|
||||
* link:跳转到详情的地址
|
||||
* user_apply_signatures:是否已经发送访问特殊开源项目的文件
|
||||
* project_id:项目id
|
||||
* is_secret:是否是特殊开源许可证项目
|
||||
* id:创建者login
|
||||
* is_member:是否是项目成员(如果是项目成员可以直接进入项目)
|
||||
* */
|
||||
projectHref=(link , user_apply_signatures,project_id,is_secret , id,is_member)=>{
|
||||
const { user , showLoginDialog } = this.props;
|
||||
if(is_secret && (!user || (user && !user.login))){
|
||||
showLoginDialog();
|
||||
return;
|
||||
}
|
||||
let signa = user_apply_signatures && user_apply_signatures[0];
|
||||
if((is_secret && !is_member && (!signa || (signa && signa.status !== "passed"))) && user.login !== id ){
|
||||
this.setState({
|
||||
visible:true,
|
||||
user_apply_signatures:user_apply_signatures.length>0 ? user_apply_signatures[0] : undefined,
|
||||
project_id
|
||||
})
|
||||
}else{
|
||||
this.props.history.push(link);
|
||||
}
|
||||
}
|
||||
hideModal=()=>{
|
||||
this.setState({
|
||||
visible:false
|
||||
})
|
||||
}
|
||||
|
||||
sureModal=()=>{
|
||||
this.hideModal();
|
||||
const { getListData } = this.props;
|
||||
getListData && getListData(1);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { projects } = this.props;
|
||||
return (
|
||||
<div className="project-list minH-670">
|
||||
{ projects && projects.length > 0 ? projects.map((item, key) => {
|
||||
return (
|
||||
<div className="p-r-Item" key={key}>
|
||||
{
|
||||
item.platform === "educoder" ?
|
||||
<a href="javascript:void(0)" style={{cursor:"default"}} className="show-user-link">
|
||||
<img className="p-r-photo" alt="" src={item.author && item.author.image_url} ></img>
|
||||
</a>
|
||||
:
|
||||
<Link to={`/users/${item.author.login}`} className="show-user-link">
|
||||
<img className="p-r-photo" alt="" src={getImageUrl(`${item.author && item.author.image_url}`)} ></img>
|
||||
</Link>
|
||||
}
|
||||
<div className="p-r-Infos">
|
||||
<div className="p-r-name">
|
||||
<Link to={`/projects/${item.author.login}/${item.identifier}`} className="hide-1 color-grey-3 font-18 task-hide " style={{ whiteSpace: "wrap", display: 'flex', width: 400 }}>
|
||||
{item.author.name}/{item.name}
|
||||
{
|
||||
item.forked_from_project_id ?
|
||||
<span className="ml5">
|
||||
<i className="iconfont icon-fork font-18 color-orange" />
|
||||
</span>
|
||||
: ""
|
||||
}
|
||||
{
|
||||
item.type && item.type !== 0 ?
|
||||
item.type === 2 ?
|
||||
<Tooltip title="该项目是一个镜像" className="ml5">
|
||||
<i className="iconfont icon-banbenku font-18 color-green" />
|
||||
</Tooltip>:
|
||||
const { visible , user_apply_signatures , project_id } = this.state;
|
||||
const renderList = (
|
||||
projects && projects.length > 0 ? projects.map((item, key) => {
|
||||
return (
|
||||
<div className="p-r-Item" key={key}>
|
||||
{
|
||||
item.platform === "educoder" ?
|
||||
<a style={{cursor:"default"}} className="show-user-link">
|
||||
<img className="p-r-photo" alt="" src={item.author && item.author.image_url} ></img>
|
||||
</a>
|
||||
:
|
||||
<Link to={`/users/${item.author.login}`} className="show-user-link">
|
||||
<img className="p-r-photo" alt="" src={getImageUrl(`${item.author && item.author.image_url}`)} ></img>
|
||||
</Link>
|
||||
}
|
||||
<div className="p-r-Infos">
|
||||
<div className="p-r-name">
|
||||
<a onClick={()=>this.projectHref(`/projects/${item.author.login}/${item.identifier}`,item.user_apply_signatures, item.id,item.is_secret,item.author.login,item.is_member)} className="hide-1 color-grey-3 font-18 task-hide fwt-500 " style={{ whiteSpace: "wrap", display: 'flex', width: 400 }}>
|
||||
{item.author.name}/{item.name}
|
||||
{
|
||||
item.forked_from_project_id ?
|
||||
<span className="ml5">
|
||||
<i className="iconfont icon-jingxiang font-18 color-green" />
|
||||
</span>:""
|
||||
}
|
||||
</Link>
|
||||
<span className="p-r-tags">
|
||||
<span className="pariseTag"><img src={img_parise} alt="" className="pariseImg" />赞 {item.praises_count}</span>
|
||||
<span><i className="iconfont icon-fork mr3 font-16" style={{ color: "#1B8FFF" }} />fork {item.forked_count}</span>
|
||||
</span>
|
||||
</div>
|
||||
<p className="break_word task-hide-2 mt10" style={{ maxHeight: "44px",lineHeight:"22px" }}>{item.description}</p>
|
||||
<i className="iconfont icon-fork font-18 color-orange" />
|
||||
</span>
|
||||
: ""
|
||||
}
|
||||
{
|
||||
item.type && item.type !== 0 ?
|
||||
item.type === 2 ?
|
||||
<Tooltip title="该项目是一个镜像" className="ml5">
|
||||
<i className="iconfont icon-banbenku font-18 color-green" />
|
||||
</Tooltip>:
|
||||
<span className="ml5">
|
||||
<i className="iconfont icon-jingxiang font-18 color-green" />
|
||||
</span>:""
|
||||
}
|
||||
</a>
|
||||
<span className="p-r-tags">
|
||||
<span className="pariseTag"><img src={img_parise} alt="" className="pariseImg" />赞 {item.praises_count}</span>
|
||||
<span><i className="iconfont icon-fork mr3 font-16" style={{ color: "#1B8FFF" }} />fork {item.forked_count}</span>
|
||||
</span>
|
||||
</div>
|
||||
<p className="break_word task-hide-2 mt8 color-grey-3 " style={{ maxHeight: "44px",lineHeight:"22px" }}>{item.description}</p>
|
||||
|
||||
<div className="p-r-about">
|
||||
<span className="p-r-detail">
|
||||
{/* <span><label>浏览量:</label>{item.visits}</span> */}
|
||||
{/* {item.category && item.category.id && <span>{item.category.name}</span>} */}
|
||||
{item.last_update_time ? <span><label>更新于</label>{item.time_ago}</span> : ""}
|
||||
{item.language && item.language.id ? <span className="color-grey-3">{item.language.name}</span> : ""}
|
||||
</span>
|
||||
</div>
|
||||
<div className="p-r-about">
|
||||
<span className="p-r-detail">
|
||||
{/* <span><label>浏览量:</label>{item.visits}</span> */}
|
||||
{/* {item.category && item.category.id && <span>{item.category.name}</span>} */}
|
||||
{item.last_update_time ? <span><label>更新于</label>{item.time_ago}</span> : ""}
|
||||
{item.language && item.language.id ? <span className="color-grey-3">{item.language.name}</span> : ""}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}) : <Nodata _html="暂无数据~"></Nodata>}
|
||||
</div>
|
||||
)
|
||||
}) : <Nodata _html="暂无数据~"></Nodata>
|
||||
)
|
||||
return (
|
||||
<div className="project-list minH-670">
|
||||
<SpecialModal {...this.props} visible={visible} hideModal={this.hideModal} user_apply_signatures={user_apply_signatures} project_id={project_id} sureModal={this.sureModal}></SpecialModal>
|
||||
{renderList}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import { Modal } from 'antd';
|
||||
import UploadSingle from '../Upload/single';
|
||||
import './Index.scss';
|
||||
import axios from 'axios';
|
||||
import { getUrl } from 'educoder';
|
||||
|
||||
function SpecialModal({ visible , hideModal , sureModal , showNotification , user_apply_signatures , project_id }){
|
||||
const [ id ,setId ] = useState(undefined);
|
||||
|
||||
|
||||
function loadFunc(id){
|
||||
setId(id);
|
||||
}
|
||||
|
||||
function sure(){
|
||||
if(!user_apply_signatures || (user_apply_signatures && user_apply_signatures.status !== "waiting")){
|
||||
if(!id || (id && id.length === 0)){
|
||||
showNotification("请先提交文件进行审核!");
|
||||
return;
|
||||
}
|
||||
const url = `/apply_signatures.json`;
|
||||
axios.post(url,{
|
||||
attachment_id:id,
|
||||
project_id:project_id
|
||||
}).then(result=>{
|
||||
if(result && result.data.id){
|
||||
showNotification("已提交文件,正在等待审核!");
|
||||
sureModal();
|
||||
}
|
||||
})
|
||||
}else{
|
||||
sureModal();
|
||||
}
|
||||
}
|
||||
return(
|
||||
<Modal title="提示" visible={visible} closable={false} onCancel={hideModal} onOk={sure}>
|
||||
{
|
||||
!user_apply_signatures || (user_apply_signatures && user_apply_signatures.status !== "waiting") ?
|
||||
<div style={{width:"420px",textAlign:'center',margin:"0 auto",paddingBottom:"30px",position:"relative"}}>
|
||||
<div>该项目为私有项目,请先<a href={getUrl(`/api/apply_signatures/template_file`)} className="color-blue">下载</a>开源协议,阅读并填写<br/>相关信息后,将协议<UploadSingle size={"5"} load={loadFunc} showNotification={showNotification} className={'singleBtn'}><span className="color-blue" style={{cursor:"pointer"}}>上传</span></UploadSingle>,平台审核通过后即可进入当前项目</div>
|
||||
</div>
|
||||
:
|
||||
<p style={{textAlign:'center'}}>您上传的文件正在审核中,通过后才能访问当前项目</p>
|
||||
}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default SpecialModal;
|
|
@ -18,6 +18,14 @@
|
|||
box-sizing: border-box;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.affix-list-left{
|
||||
width: 26%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.affix-list-content{
|
||||
padding-right:20px;
|
||||
}
|
||||
.list-right{
|
||||
width:74%;
|
||||
background: #fff;
|
||||
|
@ -208,9 +216,7 @@
|
|||
}
|
||||
/* -----------详情------------ */
|
||||
.detailHeader-wrapper{
|
||||
background-color:#FAFBFC;
|
||||
/* background: url(../Images/forgeBanner.jpg) no-repeat center; */
|
||||
/* background-size:cover; */
|
||||
background:linear-gradient(82deg,rgba(82,91,215,1) 0%,rgba(34,24,171,1) 100%);
|
||||
}
|
||||
.headerMenu-wrapper{
|
||||
font-size: 16px;
|
||||
|
@ -222,36 +228,42 @@
|
|||
text-align: center;
|
||||
height: 40px;
|
||||
line-height: 28px;
|
||||
margin-right: 40px;
|
||||
border:1px solid transparent;
|
||||
}
|
||||
.headerMenu-wrapper{
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.headerMenu-wrapper li{
|
||||
padding:0px 18px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.headerMenu-wrapper li a{
|
||||
color: #666;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.headerMenu-wrapper li a > img{
|
||||
margin-right: 8px;
|
||||
}
|
||||
.headerMenu-wrapper li a > span.num{
|
||||
height: 28px;
|
||||
line-height: 29px;
|
||||
margin-left: 8px;
|
||||
font-size: 12px;
|
||||
color: #2878FF;
|
||||
float: right;
|
||||
.headerMenu-wrapper li a > span{
|
||||
display: block;
|
||||
margin-left: 5px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.headerMenu-wrapper li.active::after{
|
||||
position: absolute;
|
||||
bottom:0px;
|
||||
height:2px;
|
||||
background-color: #5091FF;
|
||||
content:'';
|
||||
left: 0px;
|
||||
width:100%;
|
||||
.headerMenu-wrapper li.active{
|
||||
border-radius: 15px;
|
||||
border:1px solid #71A6FF;
|
||||
}
|
||||
.detail_tag_btn{
|
||||
height:26px;
|
||||
line-height: 26px;
|
||||
border-radius:5px;
|
||||
border:1px solid #f1f1f1;
|
||||
border:1px solid #71A6FF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 30px
|
||||
|
@ -259,19 +271,26 @@
|
|||
.ant-tooltip {
|
||||
max-width: fit-content!important;
|
||||
}
|
||||
|
||||
.detail_tag_btn_name{
|
||||
padding:0px 10px;
|
||||
color: #666!important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
}
|
||||
.detail_tag_btn_name img{
|
||||
margin-right: 10px;
|
||||
}
|
||||
.detail_tag_btn_count{
|
||||
padding:0px 10px;
|
||||
background: #fff;
|
||||
color: #fff !important;
|
||||
background: rgba(255,255,255,0.2);
|
||||
border-radius: 0px 4px 4px 0px;
|
||||
font-size: 12px;
|
||||
height:100%;
|
||||
}
|
||||
.detail_tag_btn_count:hover{
|
||||
/* color: #1C91FF !important; */
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
.files-md{
|
||||
border:1px solid #eee;
|
||||
|
|
|
@ -47,7 +47,7 @@ function Files({data,history,owner,projectsId}){
|
|||
<span>{item.name}</span>
|
||||
</AlignCenter>
|
||||
<span>
|
||||
<Button className="mr20" onClick={()=>{history.push(`/projects/${owner}/${projectsId}${item.sha ? `/branch/${truncateCommitId(item.sha)}/`:"/"}tree/${item.name}`)}}>查看文件</Button>
|
||||
<Button className="mr20" onClick={()=>{history.push(`/projects/${owner}/${projectsId}/tree/${truncateCommitId(item.sha)}/${item.name}`)}}>查看文件</Button>
|
||||
<span className="color-green">+{item.addition}</span>
|
||||
<span className="color-red ml20">-{item.deletion}</span>
|
||||
</span>
|
||||
|
|
|
@ -43,7 +43,9 @@ class Index extends Component {
|
|||
project_language_name: undefined,
|
||||
project_category_name: undefined,
|
||||
license_name: undefined,
|
||||
ignore_name: undefined
|
||||
ignore_name: undefined,
|
||||
|
||||
licenseForDisabled:undefined
|
||||
}
|
||||
}
|
||||
componentDidMount = () => {
|
||||
|
@ -145,7 +147,7 @@ class Index extends Component {
|
|||
_data = data.filter(item => item.name.toLowerCase().indexOf(name.toLowerCase()) > -1);
|
||||
}
|
||||
let list = _data && _data.map((item) => (
|
||||
<Option key={item.id} value={item.name}>
|
||||
<Option key={item.id} value={item.name} onClick={()=>this.selectSerect(item.is_secret)}>
|
||||
{item.name}
|
||||
</Option>
|
||||
));
|
||||
|
@ -155,6 +157,17 @@ class Index extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
selectSerect=(flag)=>{
|
||||
if(flag){
|
||||
this.props.form.setFieldsValue({
|
||||
private:true
|
||||
})
|
||||
}
|
||||
this.setState({
|
||||
licenseForDisabled:flag
|
||||
})
|
||||
}
|
||||
|
||||
subMitFrom = () => {
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
|
@ -198,7 +211,8 @@ class Index extends Component {
|
|||
}
|
||||
|
||||
ChangePlatform = (value, e, name, list) => {
|
||||
this.setOptionsList(list, name, value)
|
||||
this.setOptionsList(list, name, value);
|
||||
|
||||
this.setState({
|
||||
[name + "_id"]: e.key,
|
||||
[name + "_name"]: value,
|
||||
|
@ -272,6 +286,7 @@ class Index extends Component {
|
|||
project_category_list,
|
||||
license_list,
|
||||
ignore_list,
|
||||
licenseForDisabled,
|
||||
|
||||
mirrorCheck
|
||||
} = this.state;
|
||||
|
@ -477,8 +492,8 @@ class Index extends Component {
|
|||
style={{ margin: "0px" }}
|
||||
className="privatePart"
|
||||
>
|
||||
{getFieldDecorator('private')(
|
||||
<Checkbox value="limit">将项目设为私有<span className="ml15 font-13 color-grey-9">(只有项目所有人或拥有权限的项目成员才能看到)</span></Checkbox>
|
||||
{getFieldDecorator('private',{valuePropName:"checked"})(
|
||||
<Checkbox value="limit" disabled={licenseForDisabled}>将项目设为私有<span className="ml15 font-13 color-grey-9">(只有项目所有人或拥有权限的项目成员才能看到)</span></Checkbox>
|
||||
)}
|
||||
</Form.Item >
|
||||
{
|
||||
|
|
|
@ -15,8 +15,8 @@ const MENU_LIST = [
|
|||
function CollaboratorMember({projectsId,owner,project_id,author,showNotification,newId}){
|
||||
const [ roleName , setRoleName ] = useState(undefined);
|
||||
const [ search , setSearch ] = useState(undefined);
|
||||
const [ page , setPage ] = useState(undefined);
|
||||
const [ isSpin , setIsSpin ] = useState(false);
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ isSpin , setIsSpin ] = useState(true);
|
||||
const [ role , setRole ] = useState(undefined);
|
||||
const [ listData , setListData ] = useState(undefined);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
|
@ -166,7 +166,11 @@ function CollaboratorMember({projectsId,owner,project_id,author,showNotification
|
|||
<label className={get_color(item.role)}>
|
||||
{operation && operation[0].name}
|
||||
</label>
|
||||
) : (
|
||||
)
|
||||
:
|
||||
item.is_apply_signature ?
|
||||
<label className="text-grey">外围贡献者</label>
|
||||
:(
|
||||
<Dropdown overlay={setRoles(`${item.id}`)} placement={"bottomCenter"}>
|
||||
<span className={get_color(item.role)}>
|
||||
{operation && operation[0].name}
|
||||
|
@ -261,14 +265,8 @@ function CollaboratorMember({projectsId,owner,project_id,author,showNotification
|
|||
</div>
|
||||
</Spin>
|
||||
{total > LIMIT ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
<Pagination
|
||||
showQuickJumper
|
||||
pageSize={LIMIT}
|
||||
current={page}
|
||||
total={total}
|
||||
onChange={()=>setPage(page)}
|
||||
></Pagination>
|
||||
<div className="edu-txt-center mt20 pb20">
|
||||
<Pagination simple current={page} pageSize={LIMIT} total={total} onChange={(page)=>setPage(page)}/>
|
||||
</div>
|
||||
:""}
|
||||
</React.Fragment>
|
||||
|
|
|
@ -28,6 +28,10 @@ const Tags = Loadable({
|
|||
loader: () => import("./new_tags"),
|
||||
loading: Loading,
|
||||
});
|
||||
const Special = Loadable({
|
||||
loader: () => import("./SpecialProject"),
|
||||
loading: Loading,
|
||||
});
|
||||
const Manage = Loadable({
|
||||
loader: () => import("./ManageWeb"),
|
||||
loading: Loading,
|
||||
|
@ -40,6 +44,7 @@ class Index extends Component {
|
|||
render() {
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { pathname } = this.props.history.location;
|
||||
const { projectDetail } = this.props;
|
||||
|
||||
const flag = pathname === `/projects/${owner}/${projectsId}/setting`;
|
||||
return (
|
||||
|
@ -87,6 +92,20 @@ class Index extends Component {
|
|||
</Link>
|
||||
</p>
|
||||
</li>
|
||||
{
|
||||
projectDetail && projectDetail.permission && (projectDetail.permission === "Owner" || projectDetail.permission === "Admin") ?
|
||||
<li
|
||||
className={pathname.indexOf("setting/special") > -1 ? "active" : ""}
|
||||
>
|
||||
<p>
|
||||
<Link to={`/projects/${owner}/${projectsId}/setting/special`} className="w-100">
|
||||
<i className="iconfont icon-jingyan font-18 mr10"></i>
|
||||
特殊开源许可证项目管理
|
||||
</Link>
|
||||
</p>
|
||||
</li>
|
||||
:""
|
||||
}
|
||||
|
||||
{/* <li
|
||||
className={
|
||||
|
@ -112,7 +131,15 @@ class Index extends Component {
|
|||
<Collaborator {...this.props} {...props} {...this.state} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
<Route
|
||||
path="/projects/:owner/:projectsId/setting/special"
|
||||
render={(props) => (
|
||||
<Special {...this.props} {...props} {...this.state} />
|
||||
)}
|
||||
></Route>
|
||||
{/* 修改仓库信息 */}
|
||||
|
||||
<Route
|
||||
path="/projects/:owner/:projectsId/setting/tags"
|
||||
render={(props) => (
|
||||
|
|
|
@ -15,6 +15,7 @@ class Setting extends Component {
|
|||
CategoryList: undefined,
|
||||
LanguageList: undefined,
|
||||
private_check: undefined,
|
||||
is_secret:false
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -52,10 +53,11 @@ class Setting extends Component {
|
|||
.then((result) => {
|
||||
if (result) {
|
||||
this.props.form.setFieldsValue({
|
||||
...result.data,
|
||||
...result.data
|
||||
});
|
||||
this.setState({
|
||||
private_check: result.data.private,
|
||||
is_secret:result.data.is_secret
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -152,7 +154,7 @@ class Setting extends Component {
|
|||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
|
||||
const { CategoryList, LanguageList, private_check } = this.state;
|
||||
const { CategoryList, LanguageList, private_check , is_secret } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<WhiteBack style={{paddingBottom:"20px"}}>
|
||||
|
@ -177,6 +179,7 @@ class Setting extends Component {
|
|||
<Checkbox
|
||||
checked={private_check}
|
||||
onChange={this.changePrivate}
|
||||
disabled={is_secret}
|
||||
>
|
||||
将仓库设为私有
|
||||
</Checkbox>
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
import React , { useEffect , useState} from 'react';
|
||||
import { Input , Table , Pagination, Button , Dropdown , Menu } from 'antd';
|
||||
import { Banner , WhiteBack , AlignCenterBetween } from '../Component/layout';
|
||||
import axios from 'axios';
|
||||
|
||||
const { Search } = Input;
|
||||
|
||||
const LIMIT = 15;
|
||||
function SpecialProject(props){
|
||||
const [ page , setPage] = useState(1);
|
||||
const [ searchValue , SetSearchValue ] = useState(undefined);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
const [ list , setList ] = useState(undefined);
|
||||
const [ status , setStatus ] = useState(undefined);
|
||||
const [ loading ,setLoading ] = useState(true);
|
||||
|
||||
const { owner , projectsId} = props.match.params;
|
||||
const { project_id } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
if(project_id){
|
||||
setLoading(true);
|
||||
Init(searchValue, status);
|
||||
}
|
||||
},[page,project_id]);
|
||||
|
||||
function Init(search,status){
|
||||
const url = `/apply_signatures.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
project_id,
|
||||
page,limit:LIMIT,search,status
|
||||
}
|
||||
}).then(result=>{
|
||||
setLoading(false);
|
||||
if(result){
|
||||
setList(result.data.apply_signatures);
|
||||
setTotal(result.data.total_count);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function changePage(page){
|
||||
setLoading(true);
|
||||
setPage(page);
|
||||
}
|
||||
|
||||
const column = [
|
||||
{
|
||||
dataIndex:"column",
|
||||
key:1,
|
||||
width:"12%",
|
||||
title:"序号",
|
||||
render:(txt,item,index)=>{
|
||||
return `${index+1}`
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex:"name",
|
||||
key:2,
|
||||
title:"申请人",
|
||||
render:(text,item,m)=>{
|
||||
return item.user && <span className="task-hide" style={{maxWidth:"139px",display:"block"}}>{item.user.name}</span>
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex:"email",
|
||||
key:2,
|
||||
title:"邮箱",
|
||||
width:"22%",
|
||||
render:(text,item,m)=>{
|
||||
return item.user && <span>{item.user.email}</span>
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex:"attachment",
|
||||
key:3,
|
||||
title:"附件",
|
||||
width:"28%",
|
||||
render:(text,item,m)=>{
|
||||
return item.attachment && <a className="task-hide" style={{maxWidth:"173px",display:"block"}} href={`${item.attachment.path}`}>{item.attachment.filename}</a>
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex:"operation",
|
||||
key:4,
|
||||
width:"18%",
|
||||
title:"操作",
|
||||
render:(text, item) =>{
|
||||
return(
|
||||
<React.Fragment>
|
||||
{
|
||||
item.status === "waiting" &&
|
||||
<span>
|
||||
<Button size="small" onClick={()=>operation(item.id,"unpassed")}>拒绝</Button>
|
||||
<Button size="small" onClick={()=>operation(item.id,"passed")} type={"primary"} className="ml20">同意</Button>
|
||||
</span>
|
||||
}
|
||||
{
|
||||
item.status === "unpassed" &&
|
||||
<span style={{color:"#ff041c"}}>已拒绝</span>
|
||||
}
|
||||
{
|
||||
item.status === "passed" &&
|
||||
<span style={{color:"#13b4f1"}}>已同意</span>
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
// 拒绝&同意
|
||||
function operation(ids,s){
|
||||
setLoading(true);
|
||||
const url = `/apply_signatures/${ids}.json`;
|
||||
axios.put(url,{
|
||||
project_id:project_id,
|
||||
status:s
|
||||
}).then(result=>{
|
||||
setLoading(false);
|
||||
if(result){
|
||||
props.showNotification(`${s==="passed"?"同意":"拒绝"}此申请已操作成功!`);
|
||||
Init(searchValue,status);
|
||||
}
|
||||
}).catch(error=>{setLoading(false)})
|
||||
}
|
||||
|
||||
function searchList(){
|
||||
setLoading(true);
|
||||
Init(searchValue,status);
|
||||
}
|
||||
|
||||
const menu=(
|
||||
<Menu onClick={chooseStatus}>
|
||||
<Menu.Item key="all">全部</Menu.Item>
|
||||
<Menu.Item key="waiting">审核中</Menu.Item>
|
||||
<Menu.Item key="unpassed">已拒绝</Menu.Item>
|
||||
<Menu.Item key="passed">已同意</Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
|
||||
function chooseStatus(e){
|
||||
setStatus(e.key);
|
||||
Init(searchValue, e.key);
|
||||
}
|
||||
|
||||
|
||||
return(
|
||||
<WhiteBack style={{minHeight:"500px"}}>
|
||||
<Banner>项目管理</Banner>
|
||||
<AlignCenterBetween style={{padding:"10px 20px",textAlign:"right"}}>
|
||||
<Search
|
||||
placeholder="请输入用户姓名或者邮箱搜索"
|
||||
allowClear
|
||||
enterButton="搜索"
|
||||
style={{width:400}}
|
||||
size="middle"
|
||||
value={searchValue}
|
||||
onChange={(e)=>SetSearchValue(e.target.value)}
|
||||
onSearch={searchList}
|
||||
/>
|
||||
<Dropdown overlay={menu} placement="bottomRight">
|
||||
<span>
|
||||
<span style={{color:status ? "color-blue" : "color-grey-3"}}>{status ==="waiting"?"审核中":status==="unpassed"?"已拒绝":status==="passed"?"已同意":"全部"}</span>
|
||||
<i className="iconfont icon-xiajiantou color-grey-9 font-14 ml8"></i>
|
||||
</span>
|
||||
</Dropdown>
|
||||
</AlignCenterBetween>
|
||||
<Table
|
||||
columns={column}
|
||||
rowKey={(record) => record.id}
|
||||
pagination={false}
|
||||
dataSource={list}
|
||||
loading={loading}
|
||||
></Table>
|
||||
{
|
||||
total > LIMIT &&
|
||||
<div className="center mt20 mb20">
|
||||
<Pagination simple current={page} total={total} pageSize={LIMIT} onChange={changePage}></Pagination>
|
||||
</div>
|
||||
}
|
||||
|
||||
</WhiteBack>
|
||||
)
|
||||
}
|
||||
export default SpecialProject;
|
|
@ -139,6 +139,7 @@
|
|||
.padding15-10{
|
||||
padding:15px 10px;
|
||||
}
|
||||
.center{text-align: center;}
|
||||
.w-100{width: 100%;}
|
||||
.fwb{font-weight: 600;}
|
||||
.text-black{color: #333;}
|
||||
|
@ -151,6 +152,9 @@
|
|||
.text-yellow{color: #FF6E21 !important;}
|
||||
.text-delete{color: #BBBBBB; }
|
||||
.text-delete:hover{color: #db2828; }
|
||||
.text-grey{
|
||||
color: #999;
|
||||
}
|
||||
.new-tag-div{
|
||||
padding: 15px;
|
||||
height: 75px;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { Component } from "react";
|
||||
import { Upload, Button, Icon } from 'antd';
|
||||
import { Upload , Icon } from 'antd';
|
||||
import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder';
|
||||
|
||||
import axios from 'axios';
|
||||
|
@ -45,8 +45,7 @@ class Index extends Component {
|
|||
deleteAttachment = (file) => {
|
||||
|
||||
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
|
||||
axios.delete(url, {
|
||||
}).then((response) => {
|
||||
axios.delete(url).then((response) => {
|
||||
if (response.data) {
|
||||
if (response.data.status === 0) {
|
||||
this.setState((state) => {
|
||||
|
@ -71,11 +70,26 @@ class Index extends Component {
|
|||
handleChange = (info) => {
|
||||
const { changeIsComplete } = this.props;
|
||||
changeIsComplete && changeIsComplete(true);
|
||||
|
||||
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
|
||||
let fileList = info.fileList;
|
||||
|
||||
this.setState({ fileList: appendFileSizeToUploadFileAll(fileList) });
|
||||
this.fileIdList(fileList);
|
||||
|
||||
if ( info.file.status === 'done') {
|
||||
let filelist = info.fileList && info.fileList.length>0 && info.fileList[info.fileList.length-1];
|
||||
if(filelist && filelist.response && filelist.response.status === -1){
|
||||
this.props.showNotification(filelist.response.message)
|
||||
this.setState((state) => {
|
||||
state.fileList.pop()
|
||||
return {
|
||||
fileList: state.fileList,
|
||||
};
|
||||
});
|
||||
this.fileIdList(this.state.fileList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
import React, { useEffect , useState } from "react";
|
||||
import { Upload } from 'antd';
|
||||
import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
function Single({ children , showNotification , className , load , size }) {
|
||||
const [ fileList , setFileList ] = useState(undefined);
|
||||
// 移除
|
||||
function onAttachmentRemove(file){
|
||||
if (!file.percent || file.percent === 100) {
|
||||
deleteAttachment(file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function deleteAttachment(file){
|
||||
let uid = file.response ? file.response.id : file.uid;
|
||||
const url = `/attachments/${uid}.json`
|
||||
axios.delete(url).then((response) => {
|
||||
if (response.data && response.data.status === 0) {
|
||||
let list = fileList.filter(item=> item.response && item.response.id !== uid);
|
||||
setFileList(list);
|
||||
fileIdList(list);
|
||||
}
|
||||
}).catch(error=>{});
|
||||
}
|
||||
|
||||
|
||||
function handleChange(info){
|
||||
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
|
||||
let fileList = [info.file];
|
||||
|
||||
let list = appendFileSizeToUploadFileAll(fileList);
|
||||
setFileList(list);
|
||||
if ( info.file.status === 'done') {
|
||||
let f = info.fileList && info.fileList.length>0 && info.fileList[info.fileList.length-1];
|
||||
if(f && f.response && f.response.status === -1){
|
||||
showNotification(f.response.message)
|
||||
setFileList(f);
|
||||
}
|
||||
fileIdList(fileList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fileIdList(fileList){
|
||||
let l = fileList && fileList.length > 0 && fileList[0];
|
||||
let array = [l && l.response && l.response.id];
|
||||
load && load(array);
|
||||
}
|
||||
|
||||
function beforeUpload(file){
|
||||
if(!size) return;
|
||||
const isLt100M = file.size / 1024 / 1024 < size;
|
||||
if (!isLt100M) {
|
||||
showNotification(`文件大小必须小于${size}MB!`);
|
||||
}
|
||||
return isLt100M;
|
||||
}
|
||||
|
||||
//判断是否已经提交,如已提交评论则上一条评论数据清除
|
||||
const upload = {
|
||||
name: 'file',
|
||||
fileList: fileList,
|
||||
action: `${getUploadActionUrl()}`,
|
||||
onChange: handleChange,
|
||||
onRemove: onAttachmentRemove,
|
||||
beforeUpload: beforeUpload
|
||||
};
|
||||
|
||||
return (
|
||||
<Upload {...upload} className={className}>
|
||||
{children}
|
||||
</Upload>
|
||||
)
|
||||
}
|
||||
export default Single;
|
|
@ -1,21 +0,0 @@
|
|||
|
||||
1.请求URL: https://code.ihub.org.cn/api/v1/mirrors/create.json
|
||||
|
||||
2.请求方式: POST
|
||||
|
||||
3.参数:
|
||||
|
||||
{
|
||||
"image_url": "xxx.git", #必填,且后缀必为.git,
|
||||
"language": "Ruby", #必填,如数据库不存在,则会创建新的记录
|
||||
}
|
||||
|
||||
|
||||
4. 返回值: {
|
||||
"status": 1,
|
||||
"message": "同步成功,项目ID===1806"
|
||||
}
|
||||
|
||||
5. 返回值说明: 仅有当有返回值,且返回值的status 的值为1, 才是创建成功,其余均为创建失败
|
||||
|
||||
|
|
@ -62,6 +62,9 @@
|
|||
.text-yellow{
|
||||
color: #FFA802 !important
|
||||
}
|
||||
.text-grey{
|
||||
color: #999;
|
||||
}
|
||||
.text-gray {
|
||||
color: #888888;
|
||||
}
|
||||
|
|
|
@ -166,7 +166,12 @@ form{
|
|||
margin-bottom: 12px;
|
||||
border-radius:2px;
|
||||
background-color: #fff;
|
||||
&>li{
|
||||
.list-affix{
|
||||
min-height: 20px;
|
||||
max-height: 240px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
& li{
|
||||
font-size: 1rem;
|
||||
padding:0px 0px 0px 20px;
|
||||
box-sizing: border-box;
|
||||
|
@ -205,7 +210,7 @@ form{
|
|||
width: 6px;
|
||||
content: '';
|
||||
height: 33px;
|
||||
background: #4CACFF;
|
||||
background: #1484EF;
|
||||
}
|
||||
.MenuTitle{
|
||||
font-size: 16px;
|
||||
|
@ -215,6 +220,21 @@ form{
|
|||
line-height: 62px;
|
||||
border-bottom: 1px solid #E0E0E0;
|
||||
font-weight: 400;
|
||||
|
||||
span{
|
||||
display: block;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span:hover{
|
||||
color: #1484EF;
|
||||
|
||||
.iconfont{
|
||||
color: #1484EF !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ant-menu-inline{
|
||||
border:none;
|
||||
|
|
|
@ -6,7 +6,6 @@ import { withRouter } from "react-router";
|
|||
import { SnackbarHOC } from "educoder";
|
||||
import { CNotificationHOC } from "../../modules/courses/common/CNotificationHOC";
|
||||
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
|
||||
import Handbook from '../Component/Handbook';
|
||||
const Infos = Loadable({
|
||||
loader: () => import("./Infos"),
|
||||
loading: Loading,
|
||||
|
@ -15,7 +14,6 @@ export default withRouter(
|
|||
(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC((props)=>{
|
||||
return(
|
||||
<div>
|
||||
<Handbook />
|
||||
<Switch>
|
||||
<Route
|
||||
path="/users/:username"
|
||||
|
@ -27,4 +25,4 @@ export default withRouter(
|
|||
</div>
|
||||
)
|
||||
}))))
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import React, { Component } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Avatar, Tag, Button, Spin } from "antd";
|
||||
import FocusButton from "../UsersList/focus_button";
|
||||
|
||||
|
@ -52,7 +51,7 @@ class Infos extends Component {
|
|||
isSpin: false,
|
||||
user: undefined,
|
||||
project_type: undefined,
|
||||
route_type: undefined
|
||||
route_type: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -138,7 +137,7 @@ class Infos extends Component {
|
|||
|
||||
|
||||
render() {
|
||||
const { current_user, mygetHelmetapi } = this.props;
|
||||
const { current_user, main_web_site_url } = this.props;
|
||||
const { username } = this.props.match.params;
|
||||
|
||||
const { user, isSpin, project_type, route_type } = this.state;
|
||||
|
@ -147,7 +146,7 @@ class Infos extends Component {
|
|||
<Spin spinning={isSpin}>
|
||||
<div className="new-content-flex">
|
||||
<div className="list-left">
|
||||
<div className="bgcF">
|
||||
<div className="bgcF mb20">
|
||||
<div className="list-l-Menu text-center pd20 ">
|
||||
<Avatar
|
||||
size={110}
|
||||
|
@ -168,11 +167,7 @@ class Infos extends Component {
|
|||
<Button
|
||||
block
|
||||
className="text-button-grey"
|
||||
href={`${
|
||||
mygetHelmetapi &&mygetHelmetapi.new_course&&
|
||||
mygetHelmetapi.new_course.edit_account
|
||||
}`}
|
||||
target="_blank"
|
||||
href={`${main_web_site_url || "https://osredm.com/"}users/${user.login}/profiles`}
|
||||
>
|
||||
{" "}
|
||||
<i className="iconfont icon-shezhi4 font-15 mr5"></i>
|
||||
|
@ -193,22 +188,22 @@ class Infos extends Component {
|
|||
)}
|
||||
</div>
|
||||
<div className="width100 inline-block mt20">
|
||||
<Link
|
||||
to={`/users/${user && user.login}/watchers`}
|
||||
<a
|
||||
href={`/users/${user && user.login}/user_watchlist`}
|
||||
className={`with50 text-center pull-left ${route_type === "watchers" ? "text-primary" : ""}`}
|
||||
onClick={() =>this.route_link("watchers")}
|
||||
>
|
||||
<div>{current_user && user && user.login === current_user.login ? "我关注的" : "TA关注的"}</div>
|
||||
<span>{user && user.watching_count}</span>
|
||||
</Link>
|
||||
<Link
|
||||
to={`/users/${user && user.login}/fan_users`}
|
||||
</a>
|
||||
<a
|
||||
href={`/users/${user && user.login}/user_fanslist`}
|
||||
onClick={() =>this.route_link("fan_users")}
|
||||
className={`with50 text-center pull-left ${route_type === "fan_users" ? "text-primary" : ""}`}
|
||||
>
|
||||
<div>{current_user && user && user.login === current_user.login ? "关注我的" : "关注TA的"}</div>
|
||||
<span>{user && user.watched_count}</span>
|
||||
</Link>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -230,7 +225,7 @@ class Infos extends Component {
|
|||
|
||||
<div className="bgcF">
|
||||
<ul className="list-l-Menu">
|
||||
<li className="MenuTitle" onClick={() => this.change_project_type(undefined)}>
|
||||
<li className="MenuTitle" onClick={() => this.change_project_type()}>
|
||||
<i className="iconfont icon-xiangmuleixing font-15 mr5"></i>
|
||||
项目类型
|
||||
<i className="iconfont icon-youjiantou font-15 mr20 color-grey-9 pull-right"></i>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import { Modal } from 'antd';
|
||||
|
||||
export default (
|
||||
handleOk,
|
||||
title,
|
||||
content,
|
||||
handleCancel) => {
|
||||
return Modal.confirm({
|
||||
title: title || "警告",
|
||||
content: content || "确认删除?",
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk() {
|
||||
handleOk && handleOk();
|
||||
},
|
||||
onCancel() {
|
||||
handleCancel && handleCancel();
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { Upload, Button } from 'antd';
|
||||
import { appendFileSizeToUploadFileAll } from 'educoder';
|
||||
import { httpUrl } from '../fetch';
|
||||
|
||||
function Uploads({ className, size, actionUrl, fileList, showNotification, load }) {
|
||||
const [files, setFiles] = useState(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
if (fileList) {
|
||||
init();
|
||||
}
|
||||
}, [fileList]);
|
||||
|
||||
function init() {
|
||||
let f = appendFileSizeToUploadFileAll(fileList);
|
||||
setFiles(f);
|
||||
}
|
||||
function onAttachmentRemove(file) {
|
||||
if (!file.percent || file.percent === 100) {
|
||||
deleteAttachment(file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function deleteAttachment(file) {
|
||||
let id = (file.response && file.response.data && file.response.data.id) || file.id;
|
||||
|
||||
// 暂时不直接删除上传的文件,只在最后保存的时候进行修改
|
||||
let nf = files.filter(item => {
|
||||
let itemId = (item.response && item.response.data && item.response.data.id) || item.id;
|
||||
return itemId !== id;
|
||||
});
|
||||
setFiles(nf);
|
||||
backFiles(nf);
|
||||
}
|
||||
|
||||
function backFiles(fileList) {
|
||||
let filesId = [];
|
||||
for (const item of fileList) {
|
||||
if (item) {
|
||||
let itemId = (item.response && item.response.data && item.response.data.id) || item.id;
|
||||
itemId && filesId.push(itemId);
|
||||
}
|
||||
}
|
||||
load && load(fileList, filesId.join());
|
||||
}
|
||||
|
||||
|
||||
function handleChange(info) {
|
||||
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
|
||||
let fileList = info.fileList;
|
||||
setFiles(appendFileSizeToUploadFileAll(fileList));
|
||||
if (info.file.response) {
|
||||
for (let i = 0; i < fileList.length; i++) {
|
||||
if (fileList[i].response && !fileList[i].response.data) {
|
||||
fileList.splice(i, 1);
|
||||
}
|
||||
}
|
||||
backFiles(fileList);
|
||||
if (!info.file.response.data) {
|
||||
info.file.response && showNotification(info.file.response.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function beforeUpload(file) {
|
||||
const isLt100M = file.size / 1024 / 1024 < size;
|
||||
if (!isLt100M) {
|
||||
showNotification(`文件大小必须小于${size}MB!`);
|
||||
}
|
||||
return isLt100M;
|
||||
}
|
||||
|
||||
const upload = {
|
||||
name: 'file',
|
||||
fileList: files,
|
||||
action: (httpUrl || actionUrl) + `/busiAttachments/upload`,
|
||||
onChange: handleChange,
|
||||
onRemove: onAttachmentRemove,
|
||||
beforeUpload: beforeUpload,
|
||||
};
|
||||
return (
|
||||
<Upload {...upload} className={className}>
|
||||
<Button type="primary">点击上传</Button>
|
||||
<span className="ml10 color-grey-9">(你可以上传小于<span className="color-red">{size}MB</span>的文件)</span>
|
||||
</Upload>
|
||||
)
|
||||
}
|
||||
export default Uploads;
|
|
@ -0,0 +1,28 @@
|
|||
import React, { useEffect, useState,memo } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import './index.scss';
|
||||
|
||||
export default memo((props) => {
|
||||
const { title, options, changeOptionId, type ,size} = props;
|
||||
const [option, setOption] = useState({ code: "", dicItemName: "" ,dicItemCode:""});
|
||||
|
||||
useEffect(() => {
|
||||
changeOptionId(option, type);
|
||||
}, [option])
|
||||
|
||||
return (
|
||||
|
||||
<div className={classNames({"choose-box":true,"choose-box-big":size})}>
|
||||
<div className="choose-title">{title}</div>
|
||||
<div className="choose-list">
|
||||
<div className={classNames({ "choose-item-checked": option.dicItemCode === "", "choose-item": true })} key={"all"} onClick={() => { setOption({ dicItemCode: "", dicItemName: "" }) }}>全部</div>
|
||||
{
|
||||
options.map((item) => {
|
||||
return <div className={classNames({ "choose-item-checked": option.dicItemCode === item.dicItemCode, "choose-item": true })} key={item.dicItemCode} onClick={() => { setOption(item) }} >{item.dicItemName}</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
})
|
|
@ -0,0 +1,47 @@
|
|||
.nav-content {
|
||||
margin:20px 0;
|
||||
padding:1rem 0.2rem;
|
||||
background: #fff;
|
||||
box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 5px;
|
||||
}
|
||||
.choose-box {
|
||||
padding: .35em 0;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
font-size: .85rem;
|
||||
}
|
||||
.choose-title {
|
||||
width: 6.5em;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
flex:none;
|
||||
}
|
||||
|
||||
.choose-box-big{
|
||||
font-size: 1rem;
|
||||
.choose-title{
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
.choose-list {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.choose-item {
|
||||
color:#666;
|
||||
text-align: center;
|
||||
padding: 0 15px ;
|
||||
cursor: pointer;
|
||||
&:hover{
|
||||
color: #1B8FFF;
|
||||
}
|
||||
}
|
||||
|
||||
.choose-item-checked {
|
||||
background: #f7f7f7;
|
||||
color: #1B8FFF;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { httpUrl } from '../fetch';
|
||||
|
||||
export const editorConfig = {
|
||||
placeholder: '请输入',
|
||||
uploadImgServer: httpUrl + '/busiAttachments/upload',
|
||||
uploadFileName: 'file',
|
||||
uploadImgHeaders: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
excludeMenus: [
|
||||
'list',
|
||||
'todo',
|
||||
'emoticon',
|
||||
'video'
|
||||
],
|
||||
uploadImgHooks: {
|
||||
// 图片上传并返回了结果,想要自己把图片插入到编辑器中
|
||||
customInsert: function (insertImgFn, result) {
|
||||
// insertImgFn 可把图片插入到编辑器,传入图片 src ,执行函数即可
|
||||
if (result && result.data && result.data.id) {
|
||||
insertImgFn(`${httpUrl}/busiAttachments/view/${result.data.id}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
import React, { useEffect, useState, memo } from 'react';
|
||||
import { Icon, } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import './index.scss';
|
||||
|
||||
export default memo((props) => {
|
||||
const { options, changeOptionId, type } = props;
|
||||
|
||||
const [myOptions, setMyOptions] = useState(()=>{
|
||||
return JSON.parse(JSON.stringify(options));
|
||||
});
|
||||
const [option, setOption] = useState({
|
||||
name: '综合',
|
||||
type: 'default',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
changeOptionId(option, type);
|
||||
}, [option]);
|
||||
|
||||
function itemClick(activeItem) {
|
||||
const newOption = {
|
||||
...activeItem,
|
||||
desc: !activeItem.desc
|
||||
};
|
||||
for (const item of myOptions) {
|
||||
if (item.type === activeItem.type) {
|
||||
item.desc = newOption.desc;
|
||||
}
|
||||
}
|
||||
setOption(newOption);
|
||||
setMyOptions(myOptions);
|
||||
}
|
||||
|
||||
console.log('-----options----')
|
||||
return (
|
||||
|
||||
<div className="sort-box">
|
||||
{
|
||||
myOptions.map((item) => {
|
||||
return <div className={classNames({ "sort-item-checked": option.type === item.type, "sort-item": true })} key={item.type} onClick={() => { itemClick(item) }} >
|
||||
{item.name}
|
||||
{
|
||||
item.icon && <span className="caret-up-down">
|
||||
<Icon type="caret-up" className={classNames({ "caret-checked": !item.desc })} />
|
||||
<Icon type="caret-down" className={classNames({ "caret-checked": item.desc })} />
|
||||
</span>}
|
||||
</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
)
|
||||
})
|
|
@ -0,0 +1,40 @@
|
|||
.sort-box {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
margin-left: 10px;
|
||||
font-size: 1rem;
|
||||
.sort-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #333;
|
||||
padding: 0 20px;
|
||||
background-color: #fff;
|
||||
&:hover {
|
||||
background-color: #fff;
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.sort-item-checked {
|
||||
// background-color: #409eff;
|
||||
// color: #fff;
|
||||
color: #409eff;
|
||||
}
|
||||
.caret-up-down {
|
||||
display: inline-flex;
|
||||
flex-flow: column nowrap;
|
||||
margin-left:.25em;
|
||||
font-size: .75em;
|
||||
color:#ccc;
|
||||
}
|
||||
.caret-checked{
|
||||
color: #409eff;
|
||||
}
|
||||
.anticon-caret-up{
|
||||
margin-bottom: -.15em;
|
||||
}
|
||||
.anticon-caret-down{
|
||||
margin-top: -.15em;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import React, { useEffect, useState ,memo} from 'react';
|
||||
import classNames from 'classnames';
|
||||
import './index.scss';
|
||||
|
||||
export default memo((props) => {
|
||||
const { options, changeOptionId, type } = props;
|
||||
|
||||
const [option, setOption] = useState({ code: "", dicItemName: "" ,dicItemCode:""});
|
||||
|
||||
useEffect(() => {
|
||||
changeOptionId(option, type);
|
||||
}, [option])
|
||||
|
||||
return (
|
||||
|
||||
<div className="status-list">
|
||||
<div className={classNames({ "status-item-checked": option.dicItemCode === "", "status-item": true })} key={"all"} onClick={() => { setOption({ dicItemCode: "", dicItemName: "" }) }}>全部</div>
|
||||
{
|
||||
options.map((item) => {
|
||||
return <div className={classNames({ "status-item-checked": option.dicItemCode === item.dicItemCode, "status-item": true })} key={item.dicItemCode} onClick={() => { setOption(item) }} >{item.dicItemName}</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
)
|
||||
})
|
|
@ -0,0 +1,21 @@
|
|||
.status-list {
|
||||
padding: 1rem 0;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.status-item {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
padding: 3px 15px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: #4cacff;
|
||||
}
|
||||
}
|
||||
|
||||
.status-item-checked {
|
||||
background: #f7f7f7;
|
||||
color: #4cacff ;
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
import { notification,message } from 'antd';
|
||||
import axios from 'axios';
|
||||
import cookie from 'react-cookies';
|
||||
|
||||
|
||||
let actionUrl = '';
|
||||
if (window.location.href.indexOf('localhost') > -1) {
|
||||
actionUrl='https://taskapi.osredm.com';
|
||||
// actionUrl='http://192.168.31.47:8081';
|
||||
}else if(window.location.href.indexOf('192.168.31.48') > -1){
|
||||
actionUrl='https://taskapi.osredm.com';
|
||||
axios.defaults.withCredentials = true;
|
||||
}else if(window.location.href.indexOf('noticeweb.osredm') > -1){
|
||||
actionUrl="https://taskapi.osredm.com";
|
||||
axios.defaults.withCredentials = true;
|
||||
}else if(window.location.href.indexOf('forge.osredm.com')>-1){
|
||||
actionUrl="https://task.osredm.com";
|
||||
axios.defaults.withCredentials = true;
|
||||
}
|
||||
export const httpUrl = actionUrl;
|
||||
|
||||
const TokenKey = 'autologin_forge_military';
|
||||
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
baseURL: httpUrl,
|
||||
timeout: 10000, // 请求超时时间
|
||||
});
|
||||
|
||||
// request拦截器
|
||||
service.interceptors.request.use(config => {
|
||||
if (cookie.load(TokenKey)) {
|
||||
console.log(cookie.load(TokenKey));
|
||||
config.headers['Authorization'] = cookie.load(TokenKey); // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
if (window.location.port === "3007") {
|
||||
// 模拟token为登录用户
|
||||
const taskToken = sessionStorage.taskToken;
|
||||
if (config.url.indexOf('?') === -1) {
|
||||
config.url = `${config.url}?token=${taskToken}`;
|
||||
} else {
|
||||
config.url = `${config.url}&token=${taskToken}`;
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}, error => {
|
||||
// Do something with request error
|
||||
console.log(error); // for debug
|
||||
Promise.reject(error);
|
||||
});
|
||||
// respone拦截器
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
const res = response;
|
||||
if (res.status === 400) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.data.message || '验证失败',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 401) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.data.message || '未授权,请登录!',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 403) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.data.message || '无权限',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 40001) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: '账户或密码错误!',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (response.status !== 200 && res.status !== 200) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message,
|
||||
});
|
||||
} else {
|
||||
return response.data;
|
||||
}
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
let res = error.response||{};
|
||||
if (res.status === 400) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.data.message || '操作失败',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 401) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.data.message || '登录信息已过期',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 403) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.data.message || '无权限!',
|
||||
});
|
||||
window.location.href="/403";
|
||||
return Promise.reject('error');
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default service;
|
|
@ -0,0 +1,231 @@
|
|||
// 本模块公共样式
|
||||
.color-grey3 {
|
||||
color: #333;
|
||||
}
|
||||
.color-grey9 {
|
||||
color: #999;
|
||||
}
|
||||
.color-orange {
|
||||
color: #ff6800;
|
||||
}
|
||||
.color-deep-blue {
|
||||
color: #1b8fff;
|
||||
}
|
||||
.centerbox {
|
||||
width: 1200px;
|
||||
margin: 40px auto;
|
||||
position: relative;
|
||||
}
|
||||
.head-navigation {
|
||||
position: absolute;
|
||||
top: -2.3em;
|
||||
// width: 80vw;
|
||||
// max-width: 1280px;
|
||||
// margin: 40px auto;
|
||||
// position: relative;
|
||||
span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.center-content {
|
||||
background: #fff;
|
||||
border: 1px solid #dedede;
|
||||
box-shadow: #eee 0px 1px 1px 3px;
|
||||
}
|
||||
.centerScreen {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 46px;
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #dedede;
|
||||
}
|
||||
|
||||
// 内容标题左侧样式
|
||||
.center-left-but {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
margin-left: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.center-left-butD {
|
||||
height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
color: #333;
|
||||
padding: 0 10px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #dedede;
|
||||
}
|
||||
.center-left-butD:hover {
|
||||
background-color: #fff;
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.center-left-butDACT {
|
||||
background-color: #409eff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
// 内容标题左侧样式
|
||||
.center-left-but {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
margin-left: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
// 内容标题右侧样式
|
||||
.center-right-but {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.center-right-but > span {
|
||||
margin: 0 10px;
|
||||
font-size: 16px;
|
||||
color: #0089ff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// 文件预览modal样式
|
||||
.file-modal {
|
||||
width: 800px !important;
|
||||
.ant-modal-body {
|
||||
padding-top: 40px;
|
||||
.pdf-box {
|
||||
height: 70vh;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
.ant-modal-close {
|
||||
top: 0 !important;
|
||||
}
|
||||
.show-img {
|
||||
width: 100%;
|
||||
}
|
||||
.react-pdf__Page__canvas,
|
||||
.react-pdf__Page__textContent {
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.edit-input {
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: #0089ff;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: #509eff;
|
||||
}
|
||||
}
|
||||
|
||||
.color-grey-a {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.greater {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
.none_panels {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-flow: column nowrap;
|
||||
height: 40vh;
|
||||
}
|
||||
|
||||
.newFooter .footerInfos > ul {
|
||||
padding: 0 40px;
|
||||
box-sizing: border-box;
|
||||
max-width: 25%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.ant-modal-footer {
|
||||
text-align: center;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
// 头像
|
||||
.head-log-big {
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
margin-right: 0.5rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.head-log-middle {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
margin-right: 0.35rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.head-log-small {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
margin-right: 0.35rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
// 富文本样式
|
||||
.w-e-text table td,
|
||||
.w-e-text table th {
|
||||
height: 30px;
|
||||
}
|
||||
.editor-w-text {
|
||||
table td,
|
||||
table th {
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-right: 1px solid #ccc;
|
||||
padding: 3px 5px;
|
||||
height: 30px;
|
||||
min-height: 30px;
|
||||
}
|
||||
table th {
|
||||
border-bottom: 2px solid #ccc;
|
||||
text-align: center;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
table {
|
||||
border-top: 1px solid #ccc;
|
||||
border-left: 1px solid #ccc;
|
||||
}
|
||||
blockquote {
|
||||
display: block;
|
||||
border-left: 8px solid #d0e5f2;
|
||||
padding: 5px 10px;
|
||||
margin: 10px 0;
|
||||
line-height: 1.4;
|
||||
font-size: 100%;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
a {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.text-center{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
.centerbox {
|
||||
width: 98%;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
import React, { Component } from "react";
|
||||
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
import { withRouter } from "react-router";
|
||||
import { SnackbarHOC } from "educoder";
|
||||
import { CNotificationHOC } from "../modules/courses/common/CNotificationHOC";
|
||||
import { TPMIndexHOC } from "../modules/tpm/TPMIndexHOC";
|
||||
import Loadable from "react-loadable";
|
||||
import Loading from "../Loading";
|
||||
import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC";
|
||||
import './index.scss';
|
||||
|
||||
const NoticeList = Loadable({
|
||||
loader: () => import("./notice/noticeList"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const NoticeDetail = Loadable({
|
||||
loader: () => import("./notice/noticeDetail"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
|
||||
class Index extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="newMain clearfix">
|
||||
<Switch {...this.props}>
|
||||
|
||||
<Route
|
||||
path="/notice/noticeDetail/:noticeId"
|
||||
render={(props) => (
|
||||
<NoticeDetail {...this.props} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
<Route
|
||||
path="/notice"
|
||||
render={(props) => (
|
||||
<NoticeList {...this.props} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default withRouter(
|
||||
ImageLayerOfCommentHOC({
|
||||
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
|
||||
parentSelector: ".newMain",
|
||||
})(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Index))))
|
||||
);
|
|
@ -0,0 +1,49 @@
|
|||
import fetch from './fetch';
|
||||
import { notification } from 'antd';
|
||||
|
||||
|
||||
// 公告列表查询
|
||||
export async function getNoticeList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/announcements/',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.message === 'success') {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 公告详情查询
|
||||
export async function getNoticeDetail(id) {
|
||||
let res = await fetch({
|
||||
url: '/api/announcements/' + id,
|
||||
method: 'get',
|
||||
params:{flag:1}
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//新增加密公告申请人
|
||||
export function addReader(data) {
|
||||
return fetch({
|
||||
url: '/api/request_contact_reader_info/',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react';
|
||||
import { NewSvg } from '../../svg';
|
||||
import './index.scss';
|
||||
export default (props) => {
|
||||
const { list, itemClick, } = props;
|
||||
|
||||
return (
|
||||
list.map(item => {
|
||||
return (
|
||||
<div className="list-box" key={item.id}>
|
||||
<div className="list-title" onClick={() => { itemClick(item.id) }}>
|
||||
{item.achievementName || item.title} {item.new && <NewSvg color="#ffb300"/>}
|
||||
</div>
|
||||
<div className="list-other">
|
||||
{item.publisher && <p>发布单位:{item.publisher}</p>}
|
||||
<p>发布时间:{(item.publishDate && item.publishDate.split(' ')[0]) || (item.createTime && item.createTime.split(' ')[0])}</p>
|
||||
<p><i className="iconfont icon-dianjiliang mr5 font-12" />{item.visits || 0}</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
.list-box {
|
||||
position: relative;
|
||||
padding: 17px 20px;
|
||||
background: #fff;
|
||||
border-bottom: 1px dashed #dedede;
|
||||
}
|
||||
.list-title {
|
||||
font-size: 1rem;
|
||||
color: #000;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
svg {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
.list-title:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
.list-title span {
|
||||
padding: 3px 5px;
|
||||
margin-left: 0.5em;
|
||||
background: #f8c753;
|
||||
font-size: 13px;
|
||||
color: #fff;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.list-other {
|
||||
margin-top: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
& > p {
|
||||
display: inline-block;
|
||||
font-size: 0.875rem;
|
||||
color: #666;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
p:first-child{
|
||||
width: 50%;
|
||||
}
|
||||
p:nth-child(2){
|
||||
width: 40%;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
import { notification,message } from 'antd';
|
||||
import axios from 'axios';
|
||||
import cookie from 'react-cookies';
|
||||
|
||||
|
||||
let actionUrl = '';
|
||||
if (window.location.href.indexOf('localhost') > -1) {
|
||||
actionUrl='https://taskapi.osredm.com';
|
||||
// actionUrl='http://192.168.31.47:8081';
|
||||
}else if(window.location.href.indexOf('192.168.31.48') > -1){
|
||||
actionUrl='https://taskapi.osredm.com';
|
||||
axios.defaults.withCredentials = true;
|
||||
}else if(window.location.href.indexOf('noticeweb.osredm') > -1){
|
||||
actionUrl="https://taskapi.osredm.com";
|
||||
axios.defaults.withCredentials = true;
|
||||
}else if(window.location.href.indexOf('forge.osredm.com')>-1){
|
||||
actionUrl="https://info.osredm.com";
|
||||
axios.defaults.withCredentials = true;
|
||||
}
|
||||
export const httpUrl = actionUrl;
|
||||
|
||||
const TokenKey = 'autologin_forge_military';
|
||||
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
baseURL: httpUrl,
|
||||
timeout: 10000, // 请求超时时间
|
||||
});
|
||||
|
||||
// request拦截器
|
||||
service.interceptors.request.use(config => {
|
||||
if (cookie.load(TokenKey)) {
|
||||
console.log(cookie.load(TokenKey));
|
||||
config.headers['Authorization'] = cookie.load(TokenKey); // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
if (window.location.port === "3007") {
|
||||
// 模拟token为登录用户
|
||||
const taskToken = sessionStorage.taskToken;
|
||||
if (config.url.indexOf('?') === -1) {
|
||||
config.url = `${config.url}?token=${taskToken}`;
|
||||
} else {
|
||||
config.url = `${config.url}&token=${taskToken}`;
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}, error => {
|
||||
// Do something with request error
|
||||
console.log(error); // for debug
|
||||
Promise.reject(error);
|
||||
});
|
||||
// respone拦截器
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
const res = response;
|
||||
if (res.status === 400) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.data.message || '验证失败',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 401) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.data.message || '未授权,请登录!',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 403) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.data.message || '无权限',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 40001) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: '账户或密码错误!',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (response.status !== 200 && res.status !== 200) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message,
|
||||
});
|
||||
} else {
|
||||
return response.data;
|
||||
}
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
let res = error.response||{};
|
||||
if (res.status === 400) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.data.message || '操作失败',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 401) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.data.message || '登录信息已过期',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
if (res.status === 403) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.data.message || '无权限!',
|
||||
});
|
||||
window.location.href="/403";
|
||||
return Promise.reject('error');
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default service;
|
After Width: | Height: | Size: 168 KiB |
|
@ -0,0 +1,172 @@
|
|||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { Button, Icon, Form, Modal, Input } from 'antd';
|
||||
import { Link } from "react-router-dom";
|
||||
import { getNoticeDetail, addReader } from '../api';
|
||||
import { noticeType } from '../static';
|
||||
import './index.scss';
|
||||
|
||||
const noticeTypeArr = [];
|
||||
for (const item of noticeType) {
|
||||
noticeTypeArr[item.code] = item.name;
|
||||
}
|
||||
|
||||
export default Form.create()(({ match, history, showNotification, form }) => {
|
||||
const { getFieldDecorator, validateFields, setFieldsValue } = form;
|
||||
|
||||
const [reload, setReload] = useState(0);
|
||||
const [noticeData, setNoticeData] = useState({});
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
const [readerName,setReaderName]=useState('');
|
||||
|
||||
const id = match.params.noticeId;
|
||||
|
||||
useEffect(() => {
|
||||
id && getNoticeDetail(id).then(data => {
|
||||
if (data) {
|
||||
data.publishDate = data.publishDate.split(' ')[0];
|
||||
data.createdAt = data.createdAt.split(' ')[0];
|
||||
data.closingDate = data.closingDate.split(' ')[0];
|
||||
}
|
||||
setNoticeData(data || {});
|
||||
})
|
||||
}, [id, reload]);
|
||||
|
||||
// form表单公共处理函数
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget) => (
|
||||
<Form.Item label={label}>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true ,getValueFromEvent: e=>e.target.value.replace(/(^\s*)|(\s*$)/g, "") })(widget)}
|
||||
</Form.Item>
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
function pushInfo() {
|
||||
validateFields((err, values) => {
|
||||
if (!err) {
|
||||
addReader({
|
||||
...values,
|
||||
annId: noticeData.id,
|
||||
}).then(res => {
|
||||
if (res.message === "success") {
|
||||
setVisible(false);
|
||||
setReload(Math.random());
|
||||
} else {
|
||||
res && Modal.error({ content: res.message });
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="centerbox notice-detail">
|
||||
<div className="head-navigation">
|
||||
<Link to="/">首页<span className="greater"> > </span></Link>
|
||||
<Link to="/notice">公告<span className="greater"> > </span></Link>
|
||||
<span>公告详情</span>
|
||||
</div>
|
||||
<div className="center-content">
|
||||
{/* <div className="notice-center-content"> */}
|
||||
<div className="notice-title">
|
||||
{noticeData.title}
|
||||
</div>
|
||||
<div className="notice-detail-content">
|
||||
<div className="center-author">
|
||||
<p key={0}>公告类型:{noticeTypeArr[noticeData.type]}</p>
|
||||
{noticeData.publisher && <p key={1}>发布单位:{noticeData.publisher}</p>}
|
||||
<p key={2}>发布时间:{noticeData.publishDate || noticeData.createdAt}</p>
|
||||
<p key={3}>截止时间:{noticeData.closingDate}</p>
|
||||
<p key={4}>浏览:{noticeData.visits || 0}</p>
|
||||
</div>
|
||||
|
||||
<div className="content-text">
|
||||
<div className="notice-content-title"><Icon type="caret-right" />公告主要内容</div>
|
||||
<div className="editor-w-text" dangerouslySetInnerHTML={{ __html: noticeData.text }}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{
|
||||
noticeData.contactInfo ? <React.Fragment>
|
||||
<div className="notice-content-title"><Icon type="caret-right" />联系方式</div>
|
||||
<div className="content-secret" dangerouslySetInnerHTML={{ __html: noticeData.contactInfo && noticeData.contactInfo.replace(/\n/g, '</br>') }}>
|
||||
</div>
|
||||
{
|
||||
noticeData.blockedView && <Button type="primary" onClick={() => { setVisible(true) }}>申请查看加密内容</Button>
|
||||
}
|
||||
</React.Fragment> : ''
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
noticeData.fileDownloadPath &&
|
||||
<React.Fragment>
|
||||
<div className="notice-content-title"><Icon type="caret-right" />公告附件</div>
|
||||
<p className="notice-content-download" >
|
||||
<span onClick={() => { window.open(noticeData.fileDownloadPath) }}>
|
||||
<i className="iconfont icon-fujian color-green font-14 mr3"></i>{noticeData.fileName}
|
||||
</span>
|
||||
<span className="link" onClick={() => { window.open(noticeData.fileDownloadPath) }}>下载</span>
|
||||
</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Modal
|
||||
title="提交信息"
|
||||
visible={visible}
|
||||
onOk={pushInfo}
|
||||
onCancel={() => { setVisible(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
|
||||
{
|
||||
helper('用户姓名',
|
||||
'readerName',
|
||||
[{ required: true, message: "请输入用户姓名" }, { max: 50, message: '不能超过50字符' }],
|
||||
<Input
|
||||
placeholder="请输入用户姓名"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
helper('公司名称',
|
||||
'companyName',
|
||||
[{ required: true, message: "请输入公司名称" }, { max: 100, message: '不能超过100字符' }],
|
||||
<Input
|
||||
placeholder="请输入公司名称"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
helper('联系方式',
|
||||
'contactInfo',
|
||||
[{ required: true, message: "请输入联系方式" },
|
||||
{ max: 100, message: '不能超过100字符' },
|
||||
{ validator: (rule,val,callback) =>{
|
||||
const pattern = /^((\+)?86|((\+)?86)?)0?1[3458]\d{9}$/;
|
||||
if(pattern.test(val)){
|
||||
callback();
|
||||
}else {
|
||||
callback('请输入正确的手机号码!');
|
||||
}
|
||||
}}],
|
||||
<Input
|
||||
placeholder="请输入联系方式"
|
||||
/>
|
||||
)
|
||||
}
|
||||
</Modal>
|
||||
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
||||
)
|
|
@ -0,0 +1,102 @@
|
|||
.centerbox {
|
||||
position: relative;
|
||||
}
|
||||
.notice-detail {
|
||||
margin-top: 3.5rem;
|
||||
.head-navigation {
|
||||
top: -2.5rem;
|
||||
}
|
||||
.center-content {
|
||||
overflow: auto;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.notice-detail-content {
|
||||
padding: 2rem 2.5rem 3rem;
|
||||
|
||||
.anticon-caret-right {
|
||||
color: #1890ff;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.notice-title {
|
||||
margin: 3rem auto 0;
|
||||
text-align: center;
|
||||
font-size: 1.375rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.375rem;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
// 内容详情
|
||||
.item-content {
|
||||
padding: 10px 10px 0 30px;
|
||||
}
|
||||
.content-notice {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.center-author {
|
||||
display: flex;
|
||||
flex-flow:row wrap-reverse;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
padding: .5rem;
|
||||
background: #f9f9f9;
|
||||
color: #333;
|
||||
p {
|
||||
padding: 0 .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content-text {
|
||||
margin: 1.25rem 0;
|
||||
min-height: 30vh;
|
||||
}
|
||||
|
||||
.content-secret{
|
||||
min-height: 2em;
|
||||
}
|
||||
|
||||
.notice-content-title {
|
||||
margin: 0.5rem 0;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.notice-content-download {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem !important;
|
||||
padding: 0 1rem;
|
||||
background: #f9f9f9;
|
||||
span:hover{
|
||||
cursor: pointer;
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
|
||||
.form-edit-modal {
|
||||
.ant-form-item{
|
||||
display: flex;
|
||||
}
|
||||
.ant-form-item-label{
|
||||
min-width: 5rem;
|
||||
}
|
||||
.ant-form-item-control-wrapper{
|
||||
width: 75%;
|
||||
display: inline-block;
|
||||
}
|
||||
.ant-input-number{
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.ant-modal-footer{
|
||||
border-top: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Pagination, Icon, Input, Affix, } from 'antd';
|
||||
import ItemList from '../components/itemList';
|
||||
import Nodata from '../../../forge/Nodata';
|
||||
import Loading from "../../../Loading";
|
||||
import noticePng from '../image/banner.png';
|
||||
import { getNoticeList } from '../api';
|
||||
|
||||
import './index.scss';
|
||||
const Search = Input.Search;
|
||||
|
||||
export default (props) => {
|
||||
|
||||
const [tab, setTab] = useState('0');
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const [title, setTitle] = useState(undefined);
|
||||
const [orderBy, setOrderBy] = useState('publishDateDesc');
|
||||
|
||||
const [curPage, setCurPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [noticeList, setNoticeList] = useState([]);
|
||||
|
||||
const [callList, setCallList] = useState([]);
|
||||
const [changeList, setChangeList] = useState([]);
|
||||
const [checkList, setCheckList] = useState([]);
|
||||
const [abandonList, setAbandonList] = useState([]);
|
||||
const [technologyList, setTechnologyList] = useState([]);
|
||||
const [dealList, setDealList] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
if (tab === '0' || tab === '7') {
|
||||
const params = {
|
||||
orderBy,
|
||||
curPage: 1,
|
||||
isChecked: 1,
|
||||
pageSize: 5,
|
||||
status: 1,
|
||||
type: 1,
|
||||
title,
|
||||
flag: 1, //后台管理查询:2;前台展示:1
|
||||
};
|
||||
getNoticeList(params).then(data => {
|
||||
setChangeList(data.rows);
|
||||
});
|
||||
getNoticeList({ ...params, type: 4 }).then(data => {
|
||||
setCallList(data.rows);
|
||||
setLoading(false);
|
||||
});
|
||||
getNoticeList({ ...params, type: 2 }).then(data => {
|
||||
setCheckList(data.rows);
|
||||
});
|
||||
getNoticeList({ ...params, type: 3 }).then(data => {
|
||||
setAbandonList(data.rows);
|
||||
setLoading(false);
|
||||
});
|
||||
getNoticeList({ ...params, type: 5 }).then(data => {
|
||||
setTechnologyList(data.rows);
|
||||
});
|
||||
getNoticeList({ ...params, type: 6 }).then(data => {
|
||||
setDealList(data.rows);
|
||||
setLoading(false);
|
||||
});
|
||||
} else {
|
||||
const params = {
|
||||
orderBy,
|
||||
curPage,
|
||||
isChecked: 1,
|
||||
pageSize: 10,
|
||||
status: 1,
|
||||
title,
|
||||
type: tab,
|
||||
flag: 1, //后台管理查询:2;前台展示:1
|
||||
};
|
||||
getNoticeList(params).then(data => {
|
||||
setNoticeList(data.rows);
|
||||
setTotal(data.total);
|
||||
setLoading(false);
|
||||
})
|
||||
}
|
||||
}, [tab, title, orderBy, curPage]);
|
||||
|
||||
function changeSort(sortType) {
|
||||
setOrderBy(sortType);
|
||||
setCurPage(1);
|
||||
}
|
||||
|
||||
function noticeClick(id) {
|
||||
props.history.push(`/notice/noticeDetail/${id}`);
|
||||
}
|
||||
|
||||
function sortNav() {
|
||||
return <div className="notice-sort-nav">
|
||||
<Search
|
||||
size="large"
|
||||
maxLength={20}
|
||||
style={{ width: "56%" }}
|
||||
placeholder="输入标题关键字,不能超过20字符"
|
||||
enterButton={<span><Icon type="search" className="mr5" /> 搜索</span>}
|
||||
onSearch={(value) => setTitle(value)} />
|
||||
<div className="center-right-but">
|
||||
<div className={classNames({ sortLink: true, active: orderBy === 'publishDateDesc' })} onClick={() => { changeSort('publishDateDesc') }}>时间降序<Icon type="arrow-down" /></div>
|
||||
<span className="piece">|</span>
|
||||
<div className={classNames({ sortLink: true, active: orderBy === 'publishDateAsc' })} onClick={() => { changeSort('publishDateAsc') }}>时间升序<Icon type="arrow-up" /></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
function handleClick(e) {
|
||||
setTab(e.key);
|
||||
setCurPage(1);
|
||||
setTitle('');
|
||||
setOrderBy('publishDateDesc');
|
||||
}
|
||||
|
||||
function click(e){
|
||||
console.log("aa");
|
||||
console.log(e);
|
||||
setTab(e);
|
||||
setCurPage(1);
|
||||
setTitle('');
|
||||
setOrderBy('publishDateDesc');
|
||||
}
|
||||
|
||||
function cont(param, titleStr, key, svgStr) {
|
||||
return <React.Fragment>
|
||||
<div className="item-head-title">
|
||||
<div className="item-head-title-content">
|
||||
<i className={svgStr}></i>
|
||||
<span>{titleStr}</span>
|
||||
</div>
|
||||
{param.length === 5 && <span className="link" onClick={() => { handleClick({ key: key }) }}>查看更多 <Icon type="arrow-right" /></span>}
|
||||
</div>
|
||||
{param.length > 0 ? <ItemList
|
||||
list={param}
|
||||
itemClick={noticeClick}
|
||||
/> : <Nodata _html="暂无数据" />}
|
||||
{/* <ItemList
|
||||
list={param}
|
||||
itemClick={noticeClick}
|
||||
/> */}
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
function content() {
|
||||
if (tab === '0') {
|
||||
if(callList.length === 0 && changeList.length === 0 && checkList.length === 0 && abandonList.length === 0){
|
||||
return <React.Fragment><Nodata _html="暂无数据" /></React.Fragment>
|
||||
}else{
|
||||
return <React.Fragment>
|
||||
{cont(callList, "招标公告", '4', "iconfont icon-zhaobiaogonggao")}
|
||||
{cont(changeList, "更正公告", '1', "iconfont icon-gengzhenggonggao")}
|
||||
{cont(checkList, "中标公告", '2', "iconfont icon-zhongbiaogonggao")}
|
||||
{cont(abandonList, "废标公告", '3', "iconfont icon-feibiaogonggao")}
|
||||
</React.Fragment>
|
||||
}
|
||||
} else if (tab === '7') {
|
||||
{/* {technologyList.length <= 0 && dealList.length <= 0 ? <Nodata _html="暂无数据" /> : ""} */}
|
||||
{/* {technologyList.length > 0 && cont(technologyList, "技术资产", '5',"iconfont icon-jishuzichan")} */}
|
||||
if(technologyList.length === 0 && dealList.length === 0){
|
||||
return <React.Fragment><Nodata _html="暂无数据" /></React.Fragment>
|
||||
}else{
|
||||
return <React.Fragment>
|
||||
{cont(technologyList, "技术资产", '5', "iconfont icon-jishuzichan")}
|
||||
{cont(dealList, "成交公告", '6', "iconfont icon-chengjiaogonggao")}
|
||||
</React.Fragment>
|
||||
}
|
||||
} else if (tab === '8') {
|
||||
return <div></div>
|
||||
} else {
|
||||
let titleStr;
|
||||
let svgStr;
|
||||
switch (tab) {
|
||||
case '1':
|
||||
titleStr = "更正公告";
|
||||
svgStr = "iconfont icon-gengzhenggonggao"
|
||||
break;
|
||||
case '2':
|
||||
titleStr = "中标公告";
|
||||
svgStr = "iconfont icon-zhongbiaogonggao"
|
||||
break;
|
||||
case '3':
|
||||
titleStr = "废标公告";
|
||||
svgStr = "iconfont icon-feibiaogonggao"
|
||||
break;
|
||||
case '4':
|
||||
titleStr = "招标公告";
|
||||
svgStr = "iconfont icon-zhaobiaogonggao"
|
||||
break;
|
||||
case '5':
|
||||
titleStr = "技术资产";
|
||||
svgStr = "iconfont icon-jishuzichan"
|
||||
break;
|
||||
default:
|
||||
titleStr = "成交公告";
|
||||
svgStr = "iconfont icon-chengjiaogonggao"
|
||||
}
|
||||
return <React.Fragment>
|
||||
<div className="item-head-title">
|
||||
<div className="item-head-title-content">
|
||||
<i className={svgStr}></i>
|
||||
<span>{titleStr}</span>
|
||||
</div>
|
||||
</div>
|
||||
<ItemList
|
||||
list={noticeList}
|
||||
itemClick={noticeClick}
|
||||
/>
|
||||
{/* {noticeList.length === 10 && <div className="edu-txt-center mt30 mb30">
|
||||
<Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { setCurPage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>
|
||||
</div>} */}
|
||||
{noticeList.length > 0 ? noticeList.length === 10 && <div className="edu-txt-center mt30 mb30">
|
||||
<Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { setCurPage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>
|
||||
</div> : <Nodata _html="暂无数据" />}
|
||||
</React.Fragment>
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<img alt="图片加载失败" src={noticePng} width="100%"></img>
|
||||
<div className="centerbox notice-list clearfix">
|
||||
{/* <div className="head-navigation">
|
||||
<Link to="/">首页<span className="greater"> > </span></Link>
|
||||
<span>公告</span>
|
||||
</div> */}
|
||||
<div className="body">
|
||||
<Affix className="affix-list-left" offsetTop={90}>
|
||||
{/* <div className="affix-list-content"> */}
|
||||
<div className="navigationMenu">
|
||||
<ul className="menu-ul">
|
||||
<li className="MenuTitle" onClick={()=>click('0')}><span><i className="iconfont icon-xiangmugonggao"></i>项目公告</span></li>
|
||||
<li className={tab === '4' ? "active" : ""} onClick={()=>click('4')}><span>招标公告</span></li>
|
||||
<li className={tab === '1' ? "active" : ""} onClick={()=>click('1')}><span>更正公告</span></li>
|
||||
<li className={tab === '2' ? "active" : ""} onClick={()=>click('2')}><span>中标公告</span></li>
|
||||
<li className={tab === '3' ? "active" : ""} onClick={()=>click('3')}><span>废标公告</span></li>
|
||||
</ul>
|
||||
<ul className="menu-ul">
|
||||
<li className="MenuTitle" onClick={()=>click('7')}><span><i className="iconfont icon-chengguo"></i>成果转化</span></li>
|
||||
<li className={tab === '5' ? "active" : ""} onClick={()=>click('5')}><span>技术资产</span></li>
|
||||
<li className={tab === '6' ? "active" : ""} onClick={()=>click('6')}><span>成交公告</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</Affix>
|
||||
<div className="notice-center-content">
|
||||
{sortNav()}
|
||||
{loading ? <Loading /> : content()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
.notice-list{
|
||||
.ant-tabs {
|
||||
.ant-tabs-left-bar{
|
||||
border: 1px solid #E5E5E5;
|
||||
.ant-tabs-nav-container{
|
||||
margin-right: 0;
|
||||
}
|
||||
.ant-tabs-nav-wrap{
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
svg{
|
||||
margin-right:.75em;
|
||||
}
|
||||
}
|
||||
.ant-tabs-tab{
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
margin-bottom: 0.5rem;
|
||||
width: 13.5rem;
|
||||
height: 2.8125rem;
|
||||
background: #fff;
|
||||
font-size: 1.125rem;
|
||||
|
||||
}
|
||||
.ant-tabs-left-content{
|
||||
border: 0;
|
||||
}
|
||||
.ant-tabs-tab-active{
|
||||
background: #1890FF;
|
||||
color: #fff;
|
||||
}
|
||||
.ant-tabs-ink-bar{
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.notice-sort-nav{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: .3rem 2rem 1.5rem;
|
||||
margin: 0px -1.25rem;
|
||||
// border: 1px solid;
|
||||
border-bottom: 1px solid #E0E0E0;
|
||||
// background: #f5f5f5;
|
||||
}
|
||||
|
||||
.notice-center-content{
|
||||
padding:1.25rem;
|
||||
background: #fff;
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.item-head-title{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1.25rem 0 .6rem 0;
|
||||
.item-head-title-content{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1rem;
|
||||
span{
|
||||
font-weight: bold;
|
||||
}
|
||||
i{
|
||||
margin-right: .25em;
|
||||
color: #1890FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-input-group-addon{
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.item-head-title{
|
||||
border-bottom: 1px solid #E5E5E5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.center-right-but{
|
||||
caret-color: rgba(0, 0, 0, 0);
|
||||
.piece{
|
||||
margin:0 .8rem;
|
||||
color: #aaa;
|
||||
}
|
||||
.sortLink{
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
&:hover{
|
||||
color: #1890FF;
|
||||
}
|
||||
&.active{
|
||||
color: #1890FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.body{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: -20px;
|
||||
|
||||
.navigationMenu{
|
||||
margin-right: 20px;
|
||||
width: 20.8em;
|
||||
caret-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.none_p_title{
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-ul{
|
||||
background-color: white;
|
||||
margin-bottom: 12px;
|
||||
border-radius:2px;
|
||||
|
||||
.MenuTitle{
|
||||
border-bottom: 1px solid #E0E0E0;
|
||||
|
||||
span{
|
||||
display: block;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
border-bottom: 0px solid;
|
||||
i{
|
||||
color: #afaaae;
|
||||
}
|
||||
}
|
||||
|
||||
span:hover{
|
||||
color: #1484EF;
|
||||
.iconfont{
|
||||
color: #1484EF !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
li{
|
||||
padding:0px 0px 0px 20px;
|
||||
position: relative;
|
||||
height: 62px;
|
||||
line-height: 62px;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
span{
|
||||
display: block;
|
||||
height: 62px;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
&:last-child > span{
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
li:hover{
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.active{
|
||||
background-color: #fafafa;
|
||||
& ::before{
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 15px;
|
||||
width: 6px;
|
||||
content: '';
|
||||
height: 30px;
|
||||
background: #1484EF;
|
||||
}
|
||||
}
|
||||
|
||||
& i{
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-input-group-addon .ant-btn-lg {
|
||||
height: 40px;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// 公告开始
|
||||
export const noticeStatus = [
|
||||
{ code: 0, name: "关闭", dicItemName: '关闭' },
|
||||
{ code: 1, name: "正常", dicItemName: '正常' },
|
||||
{ code: 2, name: "草稿", dicItemName: '草稿' },
|
||||
];
|
||||
|
||||
export const noticeType = [
|
||||
{ code: 1, name: "更正公告", dicItemName: "更正" },
|
||||
{ code: 2, name: "中标公告", dicItemName: "中标" },
|
||||
{ code: 3, name: "废标公告", dicItemName: "废标" },
|
||||
{ code: 4, name: "招标公告", dicItemName: "招标" },
|
||||
{ code: 5, name: "技术资产", dicItemName: "技术" },
|
||||
{ code: 6, name: "成交公告", dicItemName: "成交" },
|
||||
];
|
||||
|
||||
export const noticeChecked = [
|
||||
{ code: 0, name: "未通过", dicItemName: "未通过" },
|
||||
{ code: 1, name: "通过", dicItemName: "通过" },
|
||||
{ code: 2, name: "未处理", dicItemName: "未处理" },
|
||||
];
|
||||
//公告结束
|
|
@ -0,0 +1,73 @@
|
|||
import React from 'react';
|
||||
|
||||
export function AbandonSvg({ color }) {
|
||||
return <svg width="16" height="15.198" viewBox="0 0 16 15.198">
|
||||
<g id="组_96" data-name="组 96" transform="translate(-54.703 -1778.755)">
|
||||
<g id="组_87" data-name="组 87" transform="translate(63.014 1786.264)">
|
||||
<path id="路径_334" data-name="路径 334" d="M365.033,2110.025H361.89a.591.591,0,1,1,0-1.183h3.143a.591.591,0,1,1,0,1.183Z" transform="translate(-359.618 -2105.589)" fill={color} />
|
||||
<path id="路径_335" data-name="路径 335" d="M316.429,2010.462a3.844,3.844,0,1,0,1.126,2.718A3.819,3.819,0,0,0,316.429,2010.462Zm-.739,4.7a2.8,2.8,0,1,1,0-3.959A2.79,2.79,0,0,1,315.69,2015.16Z" transform="translate(-309.866 -2009.336)" fill={color} />
|
||||
</g>
|
||||
<g id="组_88" data-name="组 88" transform="translate(54.703 1778.755)">
|
||||
<path id="路径_336" data-name="路径 336" d="M61.441,1790.478a5.6,5.6,0,0,1,5.545-5.651,5.476,5.476,0,0,1,1.02.1v-4.368a1.808,1.808,0,0,0-1.8-1.8H56.507a1.808,1.808,0,0,0-1.8,1.8v11.02a1.808,1.808,0,0,0,1.8,1.8h5.718A5.705,5.705,0,0,1,61.441,1790.478Zm-4.155-8.229a.7.7,0,0,1,.728-.666h6.692a.7.7,0,0,1,.728.666h0a.7.7,0,0,1-.728.666H58.014a.7.7,0,0,1-.728-.666Zm3.077,7.351h-2.5a.673.673,0,0,1,0-1.332h2.5a.673.673,0,0,1,0,1.332Zm-2.349-3.44a.7.7,0,0,1-.728-.666h0a.7.7,0,0,1,.728-.666h3.18a.7.7,0,0,1,.728.666h0a.7.7,0,0,1-.728.666Z" transform="translate(-54.703 -1778.755)" fill={color} />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
|
||||
export function AllSvg({ color }) {
|
||||
return <svg width="16" height="15.198" viewBox="0 0 16 15.198">
|
||||
<g id="组_93" data-name="组 93" transform="translate(696.223 -1778.755)">
|
||||
<path id="路径_337" data-name="路径 337" d="M-365.778,2071.537l-1.4.948h-.467a.313.313,0,0,0-.311.315v1.263a.314.314,0,0,0,.311.316h.467l1.4.947a.315.315,0,0,0,.221-.094.314.314,0,0,0,.09-.222v-3.157A.314.314,0,0,0-365.778,2071.537Z" transform="translate(-317.611 -283.396)" fill={color} />
|
||||
<g id="组_90" data-name="组 90" transform="translate(-688.125 1786.051)">
|
||||
<path id="路径_338" data-name="路径 338" d="M-434.315,2010.493a3.925,3.925,0,0,0-2.794-1.157,3.925,3.925,0,0,0-2.794,1.157,3.925,3.925,0,0,0-1.157,2.794,3.925,3.925,0,0,0,1.157,2.794,3.926,3.926,0,0,0,2.794,1.157,3.926,3.926,0,0,0,2.794-1.157,3.925,3.925,0,0,0,1.157-2.794A3.925,3.925,0,0,0-434.315,2010.493Zm-.76,4.828a2.867,2.867,0,0,1-2.034.841,2.868,2.868,0,0,1-2.034-.841,2.858,2.858,0,0,1-.843-2.034,2.858,2.858,0,0,1,.843-2.034,2.858,2.858,0,0,1,2.034-.843,2.858,2.858,0,0,1,2.034.843A2.88,2.88,0,0,1-435.075,2015.321Z" transform="translate(441.06 -2009.336)" fill={color} />
|
||||
</g>
|
||||
<g id="组_91" data-name="组 91" transform="translate(-696.223 1778.755)">
|
||||
<path id="路径_339" data-name="路径 339" d="M-689.3,1790.466a5.672,5.672,0,0,1,5.7-5.645,5.79,5.79,0,0,1,1.048.1v-4.363a1.832,1.832,0,0,0-1.854-1.8h-9.964a1.832,1.832,0,0,0-1.854,1.8v11.008a1.833,1.833,0,0,0,1.854,1.8h5.877A5.577,5.577,0,0,1-689.3,1790.466Zm-4.27-8.22a.712.712,0,0,1,.748-.665h6.878a.713.713,0,0,1,.748.665h0a.713.713,0,0,1-.748.665h-6.878a.713.713,0,0,1-.748-.665Zm3.163,7.343h-2.573a.633.633,0,0,1-.589-.665.633.633,0,0,1,.589-.665h2.573a.633.633,0,0,1,.589.665A.632.632,0,0,1-690.406,1789.588Zm-2.414-3.437a.713.713,0,0,1-.748-.665h0a.713.713,0,0,1,.748-.665h3.268a.713.713,0,0,1,.748.665h0a.713.713,0,0,1-.748.665Z" transform="translate(696.223 -1778.755)" fill={color} />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
|
||||
export function ChangeSvg({ color }) {
|
||||
return <svg width="16" height="15.176" viewBox="0 0 16 15.176">
|
||||
<g id="组_94" data-name="组 94" transform="translate(-703.372 -1778.755)">
|
||||
<path id="路径_331" data-name="路径 331" d="M1034.307,2069.547a1.2,1.2,0,0,0-1.2.934,1.17,1.17,0,0,0,.707,1.326c.044.219.063.475-.073.573a1.129,1.129,0,0,0-.885.486v.422h2.865v-.393a1.414,1.414,0,0,0-.949-.523.751.751,0,0,1-.032-.554,1.172,1.172,0,0,0,.739-1.309,1.2,1.2,0,0,0-1.175-.961Z" transform="translate(-318.75 -281.318)" fill={color} />
|
||||
<path id="路径_332" data-name="路径 332" d="M965.772,2010.458a3.832,3.832,0,1,0,1.122,2.709A3.807,3.807,0,0,0,965.772,2010.458Zm-.737,4.682a2.79,2.79,0,1,1,0-3.946A2.781,2.781,0,0,1,965.035,2015.141Z" transform="translate(-247.522 -223.068)" fill={color} />
|
||||
<g id="组_85" data-name="组 85" transform="translate(703.372 1778.755)">
|
||||
<path id="路径_333" data-name="路径 333" d="M710.088,1790.463a5.586,5.586,0,0,1,5.527-5.643,5.441,5.441,0,0,1,1.017.1v-4.362a1.8,1.8,0,0,0-1.8-1.8H705.17a1.8,1.8,0,0,0-1.8,1.8v11.005a1.8,1.8,0,0,0,1.8,1.8h5.7A5.705,5.705,0,0,1,710.088,1790.463Zm-4.141-8.218a.7.7,0,0,1,.726-.665h6.67a.7.7,0,0,1,.726.665h0a.7.7,0,0,1-.726.665h-6.67a.7.7,0,0,1-.726-.665Zm3.067,7.341h-2.5a.673.673,0,0,1,0-1.33h2.5a.673.673,0,0,1,0,1.33Zm-2.341-3.436a.7.7,0,0,1-.726-.665h0a.7.7,0,0,1,.726-.665h3.169a.7.7,0,0,1,.726.665h0a.7.7,0,0,1-.726.665Z" transform="translate(-703.372 -1778.755)" fill={color} />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
|
||||
export function CheckSvg({ color }) {
|
||||
return <svg width="16" height="14.548" viewBox="0 0 16 14.548">
|
||||
<g id="组_95" data-name="组 95" transform="translate(-1325.073 -1778.755)">
|
||||
<path id="路径_325" data-name="路径 325" d="M1655.311,1844.214" transform="translate(-319.943 -63.419)" fill={color} />
|
||||
<path id="路径_326" data-name="路径 326" d="M1680.948,2109.083a.659.659,0,1,0-.407.609.659.659,0,0,0,.407-.609Z" transform="translate(-343.504 -319.392)" fill={color} />
|
||||
<g id="组_82" data-name="组 82" transform="translate(1333.053 1785.974)">
|
||||
<path id="路径_327" data-name="路径 327" d="M1587.227,2013.456a2.664,2.664,0,1,1-1.177-1.812l.058-.378.585-.39a3.665,3.665,0,1,0,1.565,3,3.7,3.7,0,0,0-.064-.686l-.541.361Z" transform="translate(-1580.931 -2010.216)" fill={color} />
|
||||
<path id="路径_328" data-name="路径 328" d="M1645.528,2074.812a1.261,1.261,0,1,1-.58-2.115l.479-.319a1.734,1.734,0,1,0,.941,1.542c0-.008,0-.016,0-.023l-.514.349A1.254,1.254,0,0,1,1645.528,2074.812Z" transform="translate(-1640.971 -2070.255)" fill={color} />
|
||||
</g>
|
||||
<g id="组_83" data-name="组 83" transform="translate(1337.198 1786.341)">
|
||||
<path id="路径_329" data-name="路径 329" d="M1717.735,2023.462h-.009l-.741-.124h0a.373.373,0,0,1-.271-.406v0l.186-.693,0-.01a.092.092,0,0,0-.05-.125l-.01,0-.009-.006a.132.132,0,0,0-.074-.023.134.134,0,0,0-.075.023l-1.335.89-.133.628-1.246.831.005,0a1.024,1.024,0,0,1,.608.916l1.238-.84.628.121,1.34-.893.005,0c.04-.02.049-.053.05-.148C1717.805,2023.516,1717.773,2023.462,1717.735,2023.462Z" transform="translate(-1713.97 -2022.066)" fill={color} />
|
||||
</g>
|
||||
<path id="路径_330" data-name="路径 330" d="M1331.495,1789.957a5.343,5.343,0,0,1,5.285-5.4,5.206,5.206,0,0,1,.972.091v-4.174a1.725,1.725,0,0,0-1.719-1.72h-9.24a1.725,1.725,0,0,0-1.719,1.72v10.53a1.725,1.725,0,0,0,1.719,1.72h5.45A5.462,5.462,0,0,1,1331.495,1789.957Zm-3.96-7.863a.669.669,0,0,1,.694-.636h6.378a.669.669,0,0,1,.694.636h0a.669.669,0,0,1-.694.636h-6.378a.669.669,0,0,1-.694-.636Zm2.933,7.024h-2.386a.644.644,0,0,1,0-1.272h2.386a.644.644,0,0,1,0,1.272Zm-2.239-3.287a.669.669,0,0,1-.694-.636h0a.669.669,0,0,1,.694-.636h3.031a.669.669,0,0,1,.694.636h0a.669.669,0,0,1-.694.636Z" transform="translate(0 0)" fill={color} />
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
|
||||
export function NewSvg({ color }) {
|
||||
return <svg width="33.091" height="14" viewBox="0 0 33.091 14">
|
||||
<g id="组_137" data-name="组 137" transform="translate(-294 -259)">
|
||||
<path id="路径_346" data-name="路径 346" d="M324.546,259h-28A2.553,2.553,0,0,0,294,261.545v8.909A2.553,2.553,0,0,0,296.545,273h28a2.553,2.553,0,0,0,2.545-2.545v-8.909A2.553,2.553,0,0,0,324.546,259ZM302.9,269.818a.642.642,0,0,1-.445.611.983.983,0,0,1-.191.025.664.664,0,0,1-.535-.28l-3.907-5.893v5.524a.636.636,0,1,1-1.273.013v-7.636a.632.632,0,0,1,1.158-.356l3.92,5.88v-5.524a.636.636,0,1,1,1.273,0Zm8.285-4.455a.636.636,0,1,1,0,1.273h-4.455v2.546h4.455a.636.636,0,1,1,0,1.273h-5.091a.63.63,0,0,1-.636-.636v-7.636a.63.63,0,0,1,.636-.636h5.091a.636.636,0,0,1,0,1.273h-4.455v2.545Zm13.211-3.029-2.52,7.522a.63.63,0,0,1-1.2,0l-1.922-5.74-1.922,5.74a.659.659,0,0,1-1.2,0l-2.52-7.522a.636.636,0,0,1,1.209-.395l1.922,5.74,1.922-5.74a.659.659,0,0,1,1.2,0l1.922,5.74,1.922-5.74a.624.624,0,1,1,1.184.395Zm0,0" fill={color} />
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
|
||||
export function CallSvg({ color }) {
|
||||
return <svg width="13.925" height="16" viewBox="0 0 13.925 16">
|
||||
<path id="路径_350" data-name="路径 350" d="M1822.1,2425.528h-1.478a1.674,1.674,0,0,1-1.68,1.68h-5.371a1.674,1.674,0,0,1-1.68-1.68h-1.461a1.122,1.122,0,0,0-1.117,1.117v12.485a1.122,1.122,0,0,0,1.117,1.117h11.691a1.122,1.122,0,0,0,1.117-1.117v-12.481A1.155,1.155,0,0,0,1822.1,2425.528Zm-10.052,4.009h4.306a.77.77,0,1,1,0,1.539h-4.306a.77.77,0,1,1,0-1.539Zm0,3.463h4.306a.77.77,0,1,1,0,1.54h-4.306a.77.77,0,0,1,0-1.54Zm5.358,4.781h-5.382a.77.77,0,0,1,0-1.54h5.382a.77.77,0,0,1,0,1.54Zm2.92.052a.822.822,0,1,1,.822-.822A.822.822,0,0,1,1820.33,2437.833Zm.028-4.967-1.245.953v-3.9a.362.362,0,0,1,.331-.382h1.816a.362.362,0,0,1,.331.382l.01,3.9Zm-1.673-6.569h-4.871a1.034,1.034,0,0,1-1.025-1.025,1.045,1.045,0,0,1,1.025-1.025h4.871a1.025,1.025,0,0,1,0,2.049Zm0,0" transform="translate(-1809.317 -2424.247)" fill={color} />
|
||||
</svg>
|
||||
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
import React, { Component, useEffect, useState } from "react";
|
||||
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
import { withRouter } from "react-router";
|
||||
import { SnackbarHOC } from "educoder";
|
||||
import { CNotificationHOC } from "../modules/courses/common/CNotificationHOC";
|
||||
import { TPMIndexHOC } from "../modules/tpm/TPMIndexHOC";
|
||||
import Loadable from "react-loadable";
|
||||
import Loading from "../Loading";
|
||||
import { getUserInfo } from './task/api';
|
||||
import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC";
|
||||
import './index.scss';
|
||||
|
||||
const TaskList = Loadable({
|
||||
loader: () => import("./task/taskList"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const TaskDetail = Loadable({
|
||||
loader: () => import("./task/taskDetail"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const TaskEdit = Loadable({
|
||||
loader: () => import("./task/taskEdit"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const MyTask = Loadable({
|
||||
loader: () => import("./task/myTask"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
|
||||
const TaskAdminRouter = Loadable({
|
||||
loader: () => import("./task/taskAdminRouter"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
|
||||
|
||||
const Index = (propsTransmit) => {
|
||||
// 开发时,从代理的位置获取用户信息
|
||||
const [currentUser, setCurrentUser] = useState(propsTransmit.current_user);
|
||||
// const isDev = window.location.href.indexOf('3007') > -1 ? true : false;
|
||||
useEffect(() => {
|
||||
getUserInfo().then(res => {
|
||||
if (res && res.data) {
|
||||
setCurrentUser(res.data);
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
let propsF = { ...propsTransmit };
|
||||
propsF.current_user = currentUser;
|
||||
|
||||
return (
|
||||
<div className="newMain clearfix">
|
||||
<Switch {...propsF}>
|
||||
|
||||
{/* 任务详情 */}
|
||||
<Route
|
||||
path="/task/taskDetail/:taskId"
|
||||
render={(props) => (
|
||||
<TaskDetail {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 新增任务 */}
|
||||
<Route
|
||||
path="/task/taskAdd"
|
||||
render={(props) => (
|
||||
<TaskEdit {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 编辑任务 */}
|
||||
<Route
|
||||
path="/task/taskEdit/:taskId"
|
||||
render={(props) => (
|
||||
<TaskEdit {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 我的任务 */}
|
||||
<Route
|
||||
path="/task/myTask"
|
||||
render={(props) => (
|
||||
<MyTask {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 管理员管理 */}
|
||||
<Route
|
||||
path="/task/:admin"
|
||||
render={(props) => (
|
||||
<TaskAdminRouter {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 任务列表 */}
|
||||
<Route
|
||||
path="/task"
|
||||
render={(props) => (
|
||||
<TaskList {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
// }
|
||||
export default withRouter(
|
||||
ImageLayerOfCommentHOC({
|
||||
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
|
||||
parentSelector: ".newMain",
|
||||
})(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Index))))
|
||||
);
|
|
@ -0,0 +1,206 @@
|
|||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { Input, Button, Form, Select } from 'antd';
|
||||
|
||||
import ItemAgreementManage from '../components/itemAgreementManage';
|
||||
import StatusNav from '../../components/statusNav';
|
||||
import { agreementArr } from '../static';
|
||||
import { agreementList } from '../api';
|
||||
import '../index.scss';
|
||||
const Option = Select.Option;
|
||||
|
||||
const agreementOptionArr = agreementArr.slice(0, 2);
|
||||
export default Form.create()(({ form, showNotification, match, history }) => {
|
||||
|
||||
|
||||
const { getFieldDecorator, validateFields, setFieldsValue, } = form;
|
||||
|
||||
const [approve, setApprove] = useState(1);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [searchObj, setSearchObj] = useState({});
|
||||
const [status, setStatus] = useState('2');
|
||||
const [curPage, setCurPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [taskList, setTaskList] = useState([]);
|
||||
const [type, setType] = useState('1');
|
||||
|
||||
const [reload, setReload] = useState(0);
|
||||
|
||||
const [loadPaper, setLoadPaper] = useState(0);
|
||||
|
||||
// 加载审核协议列表
|
||||
useEffect(() => {
|
||||
const params = {
|
||||
...searchObj,
|
||||
status,
|
||||
type,
|
||||
currentPage: curPage,
|
||||
pageSize: 10,
|
||||
};
|
||||
setLoading(true);
|
||||
agreementList(params).then(data => {
|
||||
if (data) {
|
||||
if (loadPaper === 0 && data.rows.length === 0) {
|
||||
setLoadPaper(1);
|
||||
} else {
|
||||
setLoadPaper(2);
|
||||
}
|
||||
setTaskList(data.rows);
|
||||
setTotal(data.total);
|
||||
}
|
||||
setLoading(false);
|
||||
});
|
||||
}, [reload, status, curPage, searchObj, type]);
|
||||
|
||||
// 如果第一次加载任务协议审核发现没有数据,那么切换成审核成果协议列表
|
||||
useEffect(() => {
|
||||
if (loadPaper === 1) {
|
||||
const params = {
|
||||
status: '2',
|
||||
type: '2',
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
};
|
||||
setLoading(true);
|
||||
agreementList(params).then(data => {
|
||||
if (data && data.rows.length > 0) {
|
||||
setTaskList(data.rows);
|
||||
setTotal(data.total);
|
||||
setType('2');
|
||||
setLoadPaper(2);
|
||||
}
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
}, [loadPaper]);
|
||||
|
||||
// form表单公共处理函数
|
||||
const helper = useCallback(
|
||||
(name, rules, widget, initialValue) => (
|
||||
<Form.Item>
|
||||
{getFieldDecorator(name, { rules, initialValue, validateFirst: true, })(widget)}
|
||||
</Form.Item>
|
||||
), []);
|
||||
|
||||
|
||||
function onSearch() {
|
||||
validateFields((err, values) => {
|
||||
if (!err) {
|
||||
setSearchObj(values);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 修改选项
|
||||
const changeOptionId = useCallback((option) => {
|
||||
setStatus(option.dicItemCode.toString() || '0,1');
|
||||
setCurPage(1);
|
||||
}, []);
|
||||
|
||||
// 修改状态
|
||||
function changeApprove(approve) {
|
||||
setApprove(approve);
|
||||
setCurPage(1);
|
||||
if (approve === 1) {
|
||||
setStatus('2');
|
||||
} else {
|
||||
setStatus('0,1');
|
||||
}
|
||||
}
|
||||
|
||||
// 清除查询内容
|
||||
function clearSearch() {
|
||||
setFieldsValue({
|
||||
taskNumber: '',
|
||||
taskName: '',
|
||||
userName: ''
|
||||
});
|
||||
setSearchObj({});
|
||||
}
|
||||
|
||||
// 刷新数据
|
||||
const reloadList = useCallback(() => {
|
||||
setReload(Math.random());
|
||||
}, []);
|
||||
|
||||
|
||||
return (
|
||||
<div className="centerbox task-manage">
|
||||
|
||||
<div className="center-screen" >
|
||||
<div className="center-left-but">
|
||||
{helper(
|
||||
"type",
|
||||
[],
|
||||
<Select
|
||||
showArrow
|
||||
placeholder="请选择协议"
|
||||
onChange={(type) => { setType(type) }}
|
||||
>
|
||||
<Option key={'1'}>委托协议</Option>
|
||||
<Option key={'2'}>成果协议</Option>
|
||||
</Select>,
|
||||
type
|
||||
)}
|
||||
<Button className="circle-button" type={approve === 1 ? 'primary' : ''} onClick={() => { changeApprove(1) }}>待审批</Button>
|
||||
<Button className="circle-button" type={approve === 2 ? 'primary' : ''} onClick={() => { changeApprove(2) }}>已审批</Button>
|
||||
</div>
|
||||
|
||||
<div className="center-right-but">
|
||||
{helper(
|
||||
"taskNumber",
|
||||
[{ max: 20, message: '长度不能超过20个字符' }],
|
||||
<Input
|
||||
placeholder="输入任务编号进行检索"
|
||||
/>
|
||||
)}
|
||||
|
||||
{helper(
|
||||
"taskName",
|
||||
[{ max: 20, message: '长度不能超过20个字符' }],
|
||||
<Input
|
||||
placeholder="输入任务名称进行检索"
|
||||
/>
|
||||
)}
|
||||
|
||||
{helper(
|
||||
"userName",
|
||||
[{ max: 20, message: '长度不能超过20个字符' }],
|
||||
<Input
|
||||
placeholder="输入发布人名称进行检索"
|
||||
/>
|
||||
)}
|
||||
|
||||
<Button className="mr10" type="primary" onClick={onSearch}>搜索</Button>
|
||||
<Button className="mr10" type="" onClick={clearSearch}>清除</Button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="center-content">
|
||||
|
||||
{
|
||||
approve === 2 && <StatusNav
|
||||
key={'status'}
|
||||
type={'status'}
|
||||
options={agreementOptionArr}
|
||||
changeOptionId={changeOptionId}
|
||||
/>
|
||||
}
|
||||
<ItemAgreementManage
|
||||
list={taskList}
|
||||
curPage={curPage}
|
||||
total={total}
|
||||
changePage={(page) => { setCurPage(page) }}
|
||||
loading={loading}
|
||||
showNotification={showNotification}
|
||||
reloadList={reloadList}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)
|
|
@ -0,0 +1,571 @@
|
|||
import fetch, { } from '../fetch';
|
||||
import { notification } from 'antd';
|
||||
import { func } from 'prop-types';
|
||||
|
||||
// 获取字典分类列表
|
||||
export function getDictionary(id) {
|
||||
return fetch({
|
||||
url: '/dicItem/getData?dicTypeCode=' + id,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
export function getUserInfo() {
|
||||
return fetch({
|
||||
url: '/user/getUserInfo',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户企业信息
|
||||
export function getCompanyInfo() {
|
||||
return fetch({
|
||||
url: '/api/tasks/getEnterpriseUserInfo',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取任务领域
|
||||
export async function getTaskCategory() {
|
||||
let res = await fetch({
|
||||
url: '/api/taskCategory/getTaskCategory',
|
||||
method: 'get',
|
||||
});
|
||||
if (Array.isArray(res.data.rows)) {
|
||||
return res.data.rows;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 任务列表查询
|
||||
export async function getTaskList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/tasks/',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 管理员任务列表查询
|
||||
export async function getTaskAdminList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/tasks/backend/list',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 我的任务列表查询
|
||||
export async function getMyTaskList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/myTasks/',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 我参与的任务列表查询
|
||||
export async function getJoinTaskList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/myTasks/myPapers',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 详情查询
|
||||
export async function getTaskDetail(id) {
|
||||
let res = await fetch({
|
||||
url: '/api/tasks/getTask/' + id,
|
||||
method: 'get',
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//新增任务
|
||||
export function addTask(data) {
|
||||
return fetch({
|
||||
url: '/api/tasks/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
//更新任务
|
||||
export function updateTask(data) {
|
||||
return fetch({
|
||||
url: '/api/tasks/',
|
||||
method: 'PUT',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
//删除
|
||||
export function deleteTask(id) {
|
||||
return fetch({
|
||||
url: '/api/tasks/' + id,
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//新增成果
|
||||
export function addPaper(data) {
|
||||
return fetch({
|
||||
url: '/api/paper/',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 任务成果
|
||||
export async function getTaskPaper(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/paper/',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 审核任务成果
|
||||
export async function readyCheckPapers(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/paper/admin/readyCheckPapers',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 我的成果
|
||||
export async function myPapers(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/paper/my',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//更新成果
|
||||
export function updatePaper(data) {
|
||||
return fetch({
|
||||
url: '/api/paper/',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 删除
|
||||
export function deletePaper(id) {
|
||||
return fetch({
|
||||
url: `api/paper/${id}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//应征者名单公示
|
||||
export function makePublic(id) {
|
||||
return fetch({
|
||||
url: `/api/tasks/makeApplicantListPublic/${id}`,
|
||||
method: 'put',
|
||||
});
|
||||
}
|
||||
|
||||
//举报成果
|
||||
export function reportPaper(data) {
|
||||
return fetch({
|
||||
url: `/api/paper/${data.paperId}/paperReport`,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
//点赞成果
|
||||
export function thumbUpPaper(id) {
|
||||
return fetch({
|
||||
url: `/api/paper/${id}/thumbUp`,
|
||||
method: 'post',
|
||||
data: { paperId: id }
|
||||
});
|
||||
}
|
||||
|
||||
// 检查用户是否同意协议
|
||||
export function checkAgreement(taskId) {
|
||||
return fetch({
|
||||
url: `/api/paper/${taskId}/agreement`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 检查用户是否提交了成果
|
||||
export function checkHavePaper(taskId) {
|
||||
return fetch({
|
||||
url: `/api/paper/${taskId}/check`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 获取协议
|
||||
export function getAgreement() {
|
||||
return fetch({
|
||||
url: '/api/paper/agreementSettings/1',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 同意协议
|
||||
export function agreement(taskId) {
|
||||
return fetch({
|
||||
url: `/api/paper/${taskId}/agreement`,
|
||||
method: 'post',
|
||||
data: { taskId }
|
||||
});
|
||||
}
|
||||
|
||||
// 新增评论
|
||||
export function commentAdd(data) {
|
||||
return fetch({
|
||||
url: `/api/paper/${data.paperId}/comment`,
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//管理员审核任务
|
||||
export function checkTask(data) {
|
||||
return fetch({
|
||||
url: `/api/tasks/backend/adminCheck`,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 审核成果/评论
|
||||
export function checkPaper(data) {
|
||||
return fetch({
|
||||
url: `/api/paper/admin/complainPaper/${data.paperId}`,
|
||||
method: 'post',
|
||||
data: data.auditingVo
|
||||
});
|
||||
}
|
||||
|
||||
// 成果申诉
|
||||
export function complainPaper(data) {
|
||||
return fetch({
|
||||
url: `/api/paper/complainInfo/${data.paperId}`,
|
||||
method: 'post',
|
||||
data: data.params
|
||||
});
|
||||
}
|
||||
|
||||
// 审核申诉材料列表查询
|
||||
export async function complainPaperList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/paper/admin/readyComplaintPapers',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 审核申诉材料
|
||||
export function checkComplain(data) {
|
||||
return fetch({
|
||||
url: `/api/paper/admin/complainMaterial/${data.paperId}`,
|
||||
method: 'post',
|
||||
data: data.auditingVo
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 佐证上传
|
||||
export function proofAdd(data) {
|
||||
return fetch({
|
||||
url: `/api/taskResultProof/addTaskResultProof`,
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 审核佐证材料列表查询
|
||||
export async function proofList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/tasks/backend/proofList',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 审核佐证
|
||||
export function checkProof(data) {
|
||||
return fetch({
|
||||
url: `/api/taskResultProof/adminCheckResultAndProof`,
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 应征者公示期申诉
|
||||
export function publicityComplain(data) {
|
||||
return fetch({
|
||||
url: `/api/myTasks/applicantComplaintDuringPublicity`,
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 审核公示期申诉列表查询
|
||||
export async function publicityComplainList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/tasks/backend/complaintMaterialList',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 审核公示期申诉
|
||||
export function checkPublicity(data) {
|
||||
return fetch({
|
||||
url: `/api/tasks/backend/adminCheck/complaintMaterialDuringPublicity`,
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 选择签订协议的方式
|
||||
export function signMethod(data) {
|
||||
return fetch({
|
||||
url: `/api/sign/method/${data.taskId}/${data.method}`,
|
||||
method: 'post',
|
||||
});
|
||||
}
|
||||
|
||||
// 上传委托协议
|
||||
export function uploadAgreeRequire(data) {
|
||||
return fetch({
|
||||
url: `/api/sign/task/contract/${data.taskId}`,
|
||||
method: 'post',
|
||||
data: data.params
|
||||
});
|
||||
}
|
||||
|
||||
// 审核委托协议列表
|
||||
export async function agreementList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/sign/task/contract',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 审核协议
|
||||
export function adminCheckAgreement(data) {
|
||||
return fetch({
|
||||
url: `/api/sign/admin/${data.type === 1 ? 'task' : 'paper'}/contract/${data.agreementId}`,
|
||||
method: 'post',
|
||||
data: data.params
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 上传委托协议
|
||||
export function uploadAgreePaper(data) {
|
||||
return fetch({
|
||||
url: `/api/sign/paper/contract/${data.paperId}`,
|
||||
method: 'post',
|
||||
data: data.params
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 上传凭证列表查询
|
||||
export async function uploadPayProofList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/sign/admin/paper/payOrders',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 管理员上传支付凭证
|
||||
export function uploadPayProof(data){
|
||||
return fetch({
|
||||
url: `/api/sign/admin/paper/payment/${data.paperId}`,
|
||||
method: 'post',
|
||||
data: data.params
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 胜出者确认收款
|
||||
export function confirmReceipt(paperId) {
|
||||
return fetch({
|
||||
url: `/api/sign/paper/money/${paperId}`,
|
||||
method: 'post',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 下载协议签订凭证
|
||||
export function downAgreement(params) {
|
||||
return fetch({
|
||||
url: `/api/myTasks/getWinnersContractsByTaskId`,
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 管理员修改任务公示方式
|
||||
export function changeShowUserMode(data) {
|
||||
return fetch({
|
||||
url: `/api/tasks/backend/changeShowUserMode`,
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 延期列表查询
|
||||
export async function delayList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/tasks/backend/admin/delayList',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 延期
|
||||
export function delayTask(data) {
|
||||
return fetch({
|
||||
url: `/api/tasks/backend/admin/task/delay/${data.taskId}`,
|
||||
method: 'post',
|
||||
data:data.params,
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭
|
||||
export function closeTask(taskId) {
|
||||
return fetch({
|
||||
url: `/api/tasks/backend/admin/task/close/${taskId}`,
|
||||
method: 'post',
|
||||
});
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
import React, { useMemo } from 'react';
|
||||
import { Menu, Dropdown, } from 'antd';
|
||||
import { current_main_site_url,main_web_site_url} from '../../static';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const { SubMenu } = Menu;
|
||||
|
||||
export default props => {
|
||||
|
||||
const projectMenu = useMemo(() => {
|
||||
return <Menu>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${current_main_site_url}/admins`}>项目管理后台</a></Menu.Item>
|
||||
</Menu>
|
||||
});
|
||||
|
||||
const taskMenu = useMemo(() => {
|
||||
return <Menu>
|
||||
<SubMenu title="基础数据" >
|
||||
<Menu.Item><a href={`${main_web_site_url}/admin/categories/list`}>任务领域</a></Menu.Item>
|
||||
<Menu.Item><a href={`${main_web_site_url}/admin/industries/list`}>行业信息</a></Menu.Item>
|
||||
<Menu.Item><a href={`${main_web_site_url}/admin/placements/list`}>职位信息</a></Menu.Item>
|
||||
<Menu.Item><a href={`${main_web_site_url}/admin/task_templates/list`}>需求导入模板</a></Menu.Item>
|
||||
<Menu.Item><a href={`${main_web_site_url}/admin/agreement_setting`}>签订协议内容</a></Menu.Item>
|
||||
<Menu.Item><a href={`${main_web_site_url}/admin/sign_agreement_setting`}>应征投稿协议内容</a></Menu.Item>
|
||||
</SubMenu>
|
||||
<SubMenu title="代办事项" >
|
||||
<Menu.Item><a href={`/task/delayManage`}>延期任务处理</a></Menu.Item>
|
||||
{/* <Menu.Item><a href={`${main_web_site_url}/admin/audit_files`}>协议签订凭证上传</a></Menu.Item> */}
|
||||
<Menu.Item><a href="/task/payProof">支付报酬凭证上传</a></Menu.Item>
|
||||
</SubMenu>
|
||||
|
||||
<Menu.Item><a href="/task/taskAdmin">创客列表</a></Menu.Item>
|
||||
<Menu.Item><a href="/task/paperManage">创意征集评论</a></Menu.Item>
|
||||
</Menu>
|
||||
});
|
||||
|
||||
const competitionMenu = useMemo(() => {
|
||||
return <Menu>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/admin/competitions/list`}>竞赛列表</a></Menu.Item>
|
||||
</Menu>
|
||||
});
|
||||
|
||||
const userMenu = useMemo(() => {
|
||||
return <Menu>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/managements/users`}>用户列表</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/admin/entities`}>主体信息列表</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/managements/users_trial`}>试用授权列表</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/managements/auto_users_trial`}>自动授权列表</a></Menu.Item>
|
||||
</Menu>
|
||||
});
|
||||
|
||||
const forumMenu = useMemo(() => {
|
||||
return <Menu>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/managements/messages_list`}>帖子</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/managements/apply_destroy_memos`}>申请删帖</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/managements/memo_reply_list`}>回复</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/admin/forum_sections`}>版块配置</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/admin/banned_users`}>禁言列表</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/admin/forum_applies`}>版主审批</a></Menu.Item>
|
||||
</Menu>
|
||||
});
|
||||
|
||||
|
||||
const checkMenu = useMemo(() => {
|
||||
return <Menu>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/managements/enterprise_authentication`}>企业认证</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/admin/reviews/projects_list`}>开源项目</a></Menu.Item>
|
||||
<Menu.Item><a href="/task/taskManage">统筹任务发布审批</a></Menu.Item>
|
||||
<Menu.Item><a href="/task/paperComplain">成果上传申诉审批</a></Menu.Item>
|
||||
<Menu.Item><a href="/task/publicityComplain">公示期成果申诉审批</a></Menu.Item>
|
||||
<Menu.Item><a href="/task/agreementManage">协议审批</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/admin/tasks/report_result_tasks`}>成果举报申诉</a></Menu.Item>
|
||||
<Menu.Item><a href="/task/proofManage">评选佐证材料</a></Menu.Item>
|
||||
</Menu>
|
||||
});
|
||||
|
||||
|
||||
const limitsMenu = useMemo(() => {
|
||||
return <Menu>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/managements/user_admin_roles`}>权限组配置</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/managements/admin_role_permissions`}>权限操作配置</a></Menu.Item>
|
||||
</Menu>
|
||||
});
|
||||
|
||||
|
||||
const configMenu = useMemo(() => {
|
||||
return <Menu>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/admin/about_infos/new"`}>关于我们</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/admin/home_sections"`}>首页版块</a></Menu.Item>
|
||||
<Menu.Item><a target="_blank" rel="noopener noreferrer" href={`${main_web_site_url}/admin/partners`}>合作伙伴</a></Menu.Item>
|
||||
</Menu>
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
<div className="centerbox managements_menus clearfix">
|
||||
<Dropdown key={'projectMenu'} overlay={projectMenu} placement="bottomLeft">
|
||||
<div className="drop-div">
|
||||
项目
|
||||
</div>
|
||||
</Dropdown>
|
||||
|
||||
<Dropdown key={'taskMenu'} overlay={taskMenu} placement="bottomLeft">
|
||||
<div className="drop-div">
|
||||
创客
|
||||
</div>
|
||||
</Dropdown>
|
||||
|
||||
<Dropdown key={'competitionMenu'} overlay={competitionMenu} placement="bottomLeft">
|
||||
<div className="drop-div">竞赛</div>
|
||||
</Dropdown>
|
||||
|
||||
<Dropdown key={'userMenu'} overlay={userMenu} placement="bottomLeft">
|
||||
<div className="drop-div">用户</div>
|
||||
</Dropdown>
|
||||
|
||||
<Dropdown key={'forumMenu'} overlay={forumMenu} placement="bottomLeft">
|
||||
<div className="drop-div">论坛交流</div>
|
||||
</Dropdown>
|
||||
|
||||
<Dropdown key={'checkMenu'} overlay={checkMenu} placement="bottomLeft">
|
||||
<div className="drop-div">审批</div>
|
||||
</Dropdown>
|
||||
|
||||
<Dropdown key={'limitsMenu'} overlay={limitsMenu} placement="bottomLeft">
|
||||
<div className="drop-div">权限管理</div>
|
||||
</Dropdown>
|
||||
|
||||
<Dropdown key={'configMenu'} overlay={configMenu} placement="bottomLeft">
|
||||
<div className="drop-div">网站配置</div>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
.managements_menus {
|
||||
background: #fff;
|
||||
border: 1px solid #eee;
|
||||
|
||||
.drop-div {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 108px;
|
||||
text-align: center;
|
||||
padding: 15px 0px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 1px;
|
||||
top: 20px;
|
||||
width: 1px;
|
||||
height: 20px;
|
||||
background-color: #ddd;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
import React, { useState, } from 'react';
|
||||
import { Modal, Form, Input, } from 'antd';
|
||||
import Upload from 'military/components/Upload';
|
||||
import { uploadAgreePaper } from "../../api";
|
||||
import '../../index.scss';
|
||||
|
||||
|
||||
export default Form.create()(props => {
|
||||
const { visible, setVisible, checkedItem, form, showNotification ,reloadList } = props;
|
||||
const { getFieldDecorator, validateFields, setFieldsValue, } = form;
|
||||
|
||||
const [fileList, setFileList] = useState([]);
|
||||
|
||||
|
||||
// 上传附件后得到的文件数组
|
||||
function uploadFunc(fileList, files) {
|
||||
setFileList(fileList);
|
||||
setFieldsValue({
|
||||
files,
|
||||
});
|
||||
}
|
||||
|
||||
function uploadAgree() {
|
||||
validateFields((err, values) => {
|
||||
if (!err) {
|
||||
uploadAgreePaper({
|
||||
paperId: checkedItem.id,
|
||||
params: {
|
||||
files: values.files,
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.message === 'success') {
|
||||
setFieldsValue({
|
||||
files: '',
|
||||
});
|
||||
setVisible(false);
|
||||
showNotification("上传协议成功!");
|
||||
reloadList();
|
||||
} else {
|
||||
showNotification(res.message || "上传协议失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="签订协议"
|
||||
visible={visible}
|
||||
onOk={uploadAgree}
|
||||
onCancel={() => { setVisible(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
<div className="task-popup-content">
|
||||
{/* paperAuditing */}
|
||||
{checkedItem.paperAuditing && <p className=" mb10 color-orange task_tip">审核意见:{checkedItem.paperAuditing.message}</p>}
|
||||
<a href="http://117.50.100.12:8000/attachments/download/523/%E5%88%9B%E5%AE%A2%E4%BB%BB%E5%8A%A1%E5%88%97%E8%A1%A8_2019-07-26_20-53.xlsx" className="icon icon-attachment font-13 color-blue" length="32">协议样板.word</a>
|
||||
<Form.Item className="upload-form" label="附件上传" required={true}>
|
||||
<Upload
|
||||
load={uploadFunc}
|
||||
size={50}
|
||||
showNotification={showNotification}
|
||||
fileList={fileList}
|
||||
/>
|
||||
{getFieldDecorator('files', {
|
||||
rules: [{ required: visible, message: "请上传文件" }],
|
||||
validateFirst: true
|
||||
})(<Input style={{ display: 'none' }} />)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
)
|
|
@ -0,0 +1,109 @@
|
|||
import React, { useState, useCallback, useMemo} from 'react';
|
||||
import { Modal, Form, Input, } from 'antd';
|
||||
import Upload from 'military/components/Upload';
|
||||
import { complainPaper, publicityComplain, } from "../../api";
|
||||
import '../../index.scss';
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
export default Form.create()(props => {
|
||||
const { visible, setVisible, checkedItem, detailStatus, form, showNotification, reloadList } = props;
|
||||
const { getFieldDecorator, validateFields, setFieldsValue, } = form;
|
||||
|
||||
const [fileList, setFileList] = useState([]);
|
||||
|
||||
// 上传附件后得到的文件数组
|
||||
function uploadFunc(fileList, files) {
|
||||
setFileList(fileList);
|
||||
setFieldsValue({
|
||||
files,
|
||||
});
|
||||
}
|
||||
|
||||
const helper = useCallback(
|
||||
(name, rules, widget) => (
|
||||
<Form.Item>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
</Form.Item>
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
function complain() {
|
||||
validateFields((error, values) => {
|
||||
if (!error) {
|
||||
if (detailStatus === 5) {
|
||||
publicityComplain({
|
||||
content: values.complainValue,
|
||||
files: values.files,
|
||||
paperId: checkedItem.id,
|
||||
}).then(res => {
|
||||
complainDeal(res);
|
||||
});
|
||||
} else {
|
||||
complainPaper({
|
||||
paperId: checkedItem.id,
|
||||
params: {
|
||||
content: values.complainValue,
|
||||
files: values.files,
|
||||
}
|
||||
}).then(res => {
|
||||
complainDeal(res);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function complainDeal(res) {
|
||||
if (res && res.message === 'success') {
|
||||
showNotification('申诉提交成功');
|
||||
setVisible(false);
|
||||
setFileList(null);
|
||||
setFieldsValue({
|
||||
files: ''
|
||||
});
|
||||
reloadList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="申诉"
|
||||
visible={visible}
|
||||
onOk={complain}
|
||||
onCancel={() => { setVisible(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
{checkedItem.checkStatus == 2 && detailStatus === 3 && <p className=" mb10 color-orange task_tip">审核意见:{checkedItem.auditing.message}</p>}
|
||||
<p className="edu-txt-center lineh-20 mb10">你的申诉信息将发送给平台管理员</p>
|
||||
<p className="edu-txt-center lineh-20">请如实填写有效的申诉原由,我们将尽快完成审核</p>
|
||||
{
|
||||
helper('complainValue', [{ required: visible, message: "(必填)请在此输入发起申诉的原因,最大限制100个字符" },
|
||||
{ max: 100, message: '长度不能超过100个字符' }],
|
||||
<TextArea
|
||||
placeholder="(必填)请在此输入发起申诉的原因,最大限制100个字符"
|
||||
autoSize={{ minRows: 6 }}
|
||||
className="applyText"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
<Form.Item className="upload-form" label="附件上传" required={true}>
|
||||
<Upload
|
||||
className="commentStyle"
|
||||
load={uploadFunc}
|
||||
size={50}
|
||||
showNotification={showNotification}
|
||||
fileList={fileList}
|
||||
/>
|
||||
{getFieldDecorator('files', {
|
||||
rules: [{ required: visible, message: "请上传文件" }],
|
||||
validateFirst: true
|
||||
})(<Input style={{ display: 'none' }} />)}
|
||||
</Form.Item>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
)
|
|
@ -0,0 +1,204 @@
|
|||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { Pagination, Modal, Input, Form, } from 'antd';
|
||||
import { Link } from "react-router-dom";
|
||||
import Nodata from 'forge/Nodata';
|
||||
import Loading from "src/Loading";
|
||||
import { timeAgo, getImageUrl } from 'educoder';
|
||||
import { adminCheckAgreement } from '../../api';
|
||||
import { httpUrl } from 'military/fetch';
|
||||
import './index.scss';
|
||||
|
||||
const { TextArea } = Input;
|
||||
export default Form.create()((props) => {
|
||||
const { form, list, curPage, total, changePage, loading, showNotification, reloadList } = props;
|
||||
const { getFieldDecorator, validateFields, setFieldsValue } = form;
|
||||
const [checkedItem, setCheckedItem] = useState({});
|
||||
const [visible, setVisible] = useState(false);
|
||||
const pageSize = props.pageSize || 10;
|
||||
|
||||
|
||||
|
||||
function refuseClick(item) {
|
||||
setCheckedItem(item);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
function dealAction() {
|
||||
validateFields((error, values) => {
|
||||
if (!error) {
|
||||
adminCheckAgreement({
|
||||
agreementId: checkedItem.id,
|
||||
type: checkedItem.type,
|
||||
params: {
|
||||
pass: 0,
|
||||
message: values.message
|
||||
}
|
||||
}).then(res => {
|
||||
if (res && res.message === 'success') {
|
||||
showNotification('操作成功');
|
||||
reloadList();
|
||||
setFieldsValue({
|
||||
message: '',
|
||||
});
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function agreeClick(item) {
|
||||
Modal.confirm({
|
||||
title: '确认审批通过?',
|
||||
onOk() {
|
||||
adminCheckAgreement({
|
||||
agreementId: item.id,
|
||||
type: item.type,
|
||||
params: {
|
||||
pass: 1,
|
||||
}
|
||||
}).then(res => {
|
||||
if (res && res.message === 'success') {
|
||||
showNotification('操作成功');
|
||||
reloadList();
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function goUser(login) {
|
||||
window.location.href = `/users/${login}`;
|
||||
}
|
||||
|
||||
function goUserMes(login) {
|
||||
window.location.href = `/users/${login}/message_detail`;
|
||||
}
|
||||
|
||||
function downFile(item) {
|
||||
let url = httpUrl + '/busiAttachments/download/' + item.id;
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget) => (
|
||||
<Form.Item label={label}>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
</Form.Item>
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
loading ? <Loading /> :
|
||||
<React.Fragment>
|
||||
{
|
||||
list.map(item => {
|
||||
return (
|
||||
<div className="list-box" key={item.id}>
|
||||
|
||||
<img alt="" className="radius mr15" height="50px" src={item.user && getImageUrl(item.user.logo)} width="50px" />
|
||||
<div className="flex1">
|
||||
<li className="clearfix mb20">
|
||||
<a className="user-box fl mr15 color-grey-3 font-16" onClick={() => { goUser(item.user.login) }}>{item.user && (item.user.nickname || item.user.login)}</a>
|
||||
<span className="fl color-grey-9 mt3 mr15">{timeAgo(item.createdAt)}</span>
|
||||
<span className="fr">
|
||||
{item.status === 1 && <span className="spanTitle color-grey-6 fl ml20">已同意</span>}
|
||||
{item.status === 0 && <span className="spanTitle color-red fl ml20">已驳回</span>}
|
||||
|
||||
{
|
||||
item.status === 2 && <React.Fragment>
|
||||
<a className="edu-default-btn edu-orangeline-btn ml20 fl" onClick={() => { goUserMes(item.user.login) }}>私信</a>
|
||||
<a className="edu-default-btn edu-blueline-btn ml20 fl" onClick={() => { agreeClick(item) }}>同意</a>
|
||||
<a className="edu-default-btn edu-greyline-btn ml20 fl" onClick={() => { refuseClick(item) }}>驳回</a>
|
||||
</React.Fragment>
|
||||
}
|
||||
</span>
|
||||
</li>
|
||||
<div className="clearfix">
|
||||
<div className="width100 lineh-35">
|
||||
<span className="color-grey-9 fl">任务名称:</span>
|
||||
<span className="fl lineh-35 ml5">
|
||||
<Link className="primary-link" to={`/task/taskDetail/${item.containerId}`}>{item.taskName}</Link>
|
||||
</span>
|
||||
</div>
|
||||
<div className="clearfix"></div>
|
||||
<div className="width100 lineh-35">
|
||||
<span className="color-grey-9 fl">任务编号:</span>
|
||||
<span className="fl lineh-35 ml5">
|
||||
{item.taskNumber}
|
||||
</span>
|
||||
</div>
|
||||
<div className="clearfix"></div>
|
||||
|
||||
{
|
||||
item.paperNumber && <React.Fragment>
|
||||
<div className="width100 lineh-35">
|
||||
<span className="color-grey-9 fl">成果编号:</span>
|
||||
<span className="fl lineh-35 ml5">
|
||||
{item.paperNumber}
|
||||
</span>
|
||||
</div>
|
||||
<div className="clearfix"></div>
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
<div className="width100 lineh-35 clearfix">
|
||||
<span className="color-grey-9 fl">协议文件:</span>
|
||||
{
|
||||
item.busiAttachments && item.busiAttachments.map(fileItem => {
|
||||
return <span className="file-list-prof " key={fileItem.id}>
|
||||
<a onClick={() => { downFile(fileItem) }}><i className="iconfont icon-fujian color-green font-14 mr3"></i>
|
||||
{fileItem.fileName} </a>
|
||||
<span className="ml10 color-grey-9">({fileItem.fileSizeString})</span>
|
||||
</span>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
{/* <div className="width100 lineh-35">
|
||||
<span className="color-grey-9 fl">驳回原因:</span>
|
||||
<span className="infos_item">{item.content}</span>
|
||||
</div> */}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
{list.length > 0 ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
{total > pageSize && <Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { changePage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>}
|
||||
</div> :
|
||||
<Nodata _html="暂无数据" />}
|
||||
|
||||
<Modal
|
||||
title="驳回协议"
|
||||
visible={visible}
|
||||
onOk={dealAction}
|
||||
onCancel={() => { setVisible(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
{
|
||||
helper('驳回原因', 'message', [{ required: visible, message: "请输入驳回的原因" }, { max: 200, message: '不能超过200字符' }],
|
||||
<TextArea
|
||||
placeholder="(必填)我想说点什么呢,200字以内"
|
||||
autoSize={{ minRows: 6 }}
|
||||
className="applyText"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
</Modal>
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
||||
)
|
|
@ -0,0 +1,52 @@
|
|||
.list-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
margin: 0 1.5rem;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #dedede;
|
||||
a.edu-orangeline-btn {
|
||||
padding: 0px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
a.primary-link {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.infos_item {
|
||||
float: left;
|
||||
max-width: 273px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: #343434;
|
||||
margin-right: 6px;
|
||||
line-height: 35px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.file-list-prof{
|
||||
background: #fafafa;
|
||||
padding:.25rem .5rem;
|
||||
margin-right:.5rem;
|
||||
}
|
||||
|
||||
.form-edit-modal {
|
||||
.ant-form-item{
|
||||
display: flex;
|
||||
}
|
||||
.ant-form-item-label{
|
||||
min-width: 5rem;
|
||||
}
|
||||
.ant-form-item-control-wrapper{
|
||||
width: 75%;
|
||||
display: inline-block;
|
||||
}
|
||||
.ant-input-number{
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,269 @@
|
|||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { Pagination, Modal, Input, DatePicker, Form } from 'antd';
|
||||
import { Link } from "react-router-dom";
|
||||
import moment from 'moment';
|
||||
import Nodata from 'forge/Nodata';
|
||||
import Loading from "src/Loading";
|
||||
import { getImageUrl, formatDuring } from 'educoder';
|
||||
import { taskStatusAllArr } from '../../static';
|
||||
import { delayTask, closeTask } from '../../api';
|
||||
import './index.scss';
|
||||
|
||||
const format = "YYYY-MM-DD";
|
||||
|
||||
const statusArr = [];
|
||||
for (const item of taskStatusAllArr) {
|
||||
statusArr[item.dicItemCode] = item.dicItemName;
|
||||
}
|
||||
|
||||
const classArr = ['', 'list-done', 'list-error', 'list-red', 'list-yellow', 'list-pay', '', 'list-pay', 'list-gray',];
|
||||
|
||||
function getSomeDayAfter(time, nDay) {
|
||||
return moment(new Date(time).setDate(new Date(time).getDate() + nDay)).format('YYYY-MM-DD HH:mm');
|
||||
}
|
||||
|
||||
export default Form.create()((props) => {
|
||||
|
||||
const { list, curPage, total, changePage, loading, showNotification, reloadList, form } = props;
|
||||
const { getFieldDecorator, validateFields } = form;
|
||||
|
||||
const [checkedItem, setCheckedItem] = useState('');
|
||||
const [visible, setVisible] = useState(false);
|
||||
const pageSize = props.pageSize || 10;
|
||||
|
||||
function closeClick(item) {
|
||||
Modal.confirm({
|
||||
title: '是否关闭?',
|
||||
content: <p class="font-14 lineh-25 mb10 edu-txt-center">关闭后该任务立即结束,无法重新打开</p>,
|
||||
onOk() {
|
||||
closeTask(item.id).then(res => {
|
||||
if (res && res.message === 'success') {
|
||||
showNotification('操作成功');
|
||||
reloadList();
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function delayClick(item) {
|
||||
setCheckedItem(item);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
function delayTime() {
|
||||
validateFields((err, values) => {
|
||||
if (!err) {
|
||||
delayTask({
|
||||
taskId: checkedItem.id,
|
||||
params: {
|
||||
delayedTo: moment(values.delayedTo).format(format)
|
||||
},
|
||||
}).then(res => {
|
||||
if (res && res.message === 'success') {
|
||||
showNotification('操作成功');
|
||||
reloadList();
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function goUser(login) {
|
||||
window.location.href = `/users/${login}`;
|
||||
}
|
||||
|
||||
function goUserMes(login) {
|
||||
window.location.href = `/users/${login}/message_detail`;
|
||||
}
|
||||
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget, initialValue) => (
|
||||
<Form.Item label={label}>
|
||||
{getFieldDecorator(name, { rules, initialValue, validateFirst: true, })(widget)}
|
||||
</Form.Item>
|
||||
), []);
|
||||
|
||||
const surplusTime = useCallback((item) => {
|
||||
let surplus;
|
||||
switch (item.currentStatus) {
|
||||
case 3:
|
||||
surplus = item.collectingDays * 24 * 3600 - (new Date() - new Date(item.publishedAt || item.createdAt)) / 1000;
|
||||
break;
|
||||
case 4:
|
||||
surplus = item.choosingDays * 24 * 3600 - (new Date() - new Date(item.collectingCompleteAt)) / 1000;
|
||||
break;
|
||||
case 5:
|
||||
surplus = item.makePublicDays * 24 * 3600 - (new Date() - new Date(item.makePublicAt)) / 1000;
|
||||
break;
|
||||
case 6:
|
||||
surplus = item.signingDays * 24 * 3600 - (new Date() - new Date(item.publicityCompleteAt)) / 1000;
|
||||
break;
|
||||
case 7:
|
||||
surplus = item.payingDays * 24 * 3600 - (new Date() - new Date(item.signingCompleteAt)) / 1000;
|
||||
break;
|
||||
default:
|
||||
surplus = 0;
|
||||
}
|
||||
let surplusTimetext = formatDuring(surplus);
|
||||
return surplus > 0 ? '剩余' + surplusTimetext : <span>延期 <span className="color-red">{surplusTimetext}</span></span>;
|
||||
}, []);
|
||||
|
||||
const stopTime = useCallback((item) => {
|
||||
switch (item.currentStatus) {
|
||||
case 3:
|
||||
return getSomeDayAfter(item.publishedAt, item.collectingDays);
|
||||
case 4:
|
||||
return getSomeDayAfter(item.collectingCompleteAt, item.choosingDays);
|
||||
case 5:
|
||||
return getSomeDayAfter(item.makePublicAt, item.makePublicDays);
|
||||
case 6:
|
||||
return getSomeDayAfter(item.publicityCompleteAt, item.signingDays);
|
||||
case 7:
|
||||
return getSomeDayAfter(item.signingCompleteAt, item.payingDays);
|
||||
case 8:
|
||||
return item.payingCompleteAt;
|
||||
default:
|
||||
return item.expiredAt;
|
||||
}
|
||||
})
|
||||
|
||||
function disabledDate(current) {
|
||||
return current && current < moment().endOf('day');
|
||||
}
|
||||
|
||||
return (
|
||||
loading ? <Loading /> :
|
||||
<React.Fragment>
|
||||
{
|
||||
list.map(item => {
|
||||
return (
|
||||
<div className="list-box" key={item.id}>
|
||||
|
||||
<img alt="" className="radius mr15" height="50px" src={item.user && getImageUrl(item.user.logo)} width="50px" onClick={() => { goUser(item.user.login) }} />
|
||||
<div className="flex1">
|
||||
|
||||
<div className="clearfix">
|
||||
<span className="lineh-35" style={{ display: "inline-flex" }}>
|
||||
<span className="color-grey-9 fl">任务编号:</span>
|
||||
<span className="infos_item mr15">{item.number}</span>
|
||||
<span className="fl lineh-35 ml5">
|
||||
<Link className="primary-link" to={`/task/taskDetail/${item.id}`}>{item.name}</Link>
|
||||
</span>
|
||||
<span>{item.currentStatus > 0 && <span className={classArr[item.currentStatus] + ' status-tag'}>{statusArr[item.currentStatus]}</span>}</span>
|
||||
</span>
|
||||
|
||||
<span className="fr">
|
||||
{item.cancelStatus === 1 && <span className="spanTitle color-red fl ml20">延期</span>}
|
||||
{item.cancelStatus === 2 && <span className="spanTitle color-grey-6 fl ml20">关闭</span>}
|
||||
|
||||
{
|
||||
item.cancelStatus === 0 && <React.Fragment>
|
||||
<a className="edu-default-btn edu-orangeline-btn ml20 fl" onClick={() => { goUserMes(item.user.login) }}>私信</a>
|
||||
<a className="edu-default-btn edu-blueline-btn ml20 fl" onClick={() => { delayClick(item) }}>延期</a>
|
||||
<a className="edu-default-btn edu-greyline-btn ml20 fl" onClick={() => { closeClick(item) }}>关闭</a>
|
||||
</React.Fragment>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="clearfix">
|
||||
|
||||
<span className="with40 fl lineh-35">
|
||||
<span className="color-grey-9 fl">主体名称:</span>
|
||||
<span className="infos_item">{item.enterpriseName}</span>
|
||||
</span>
|
||||
|
||||
<span className="with30 fl lineh-35">
|
||||
<span className="color-grey-9 fl">发布方式:</span>
|
||||
<span className="infos_item mr15 fl">{item.publishMode === 1 ? '统筹任务' : '自主提交'}</span>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
<div className="clearfix">
|
||||
<span className="with40 fl lineh-35">
|
||||
<span className="color-grey-9 fl">联系手机:</span>
|
||||
<span className="infos_item">{item.user.phone}(位置分析:{item.belongTo})</span>
|
||||
</span>
|
||||
|
||||
<span className="with40 fl lineh-35 color-orange">
|
||||
{
|
||||
item.status === 4 && item.papersCount > 0 && (!item.isProofBoolean) && '未上传佐证材料'
|
||||
}
|
||||
|
||||
{item.status === 6 && item.agreementSigning === 0 && '未选择协议签订方式'}
|
||||
|
||||
{
|
||||
item.status === 6 && item.agreementSigning === 2 && (item.contractStatus === null || item.contractStatus === 0) && '未上传委托协议'
|
||||
}
|
||||
|
||||
{
|
||||
item.status === 6 && item.agreementSigning === 2 && item.contractStatus === 2 && '已上传委托协议'
|
||||
}
|
||||
|
||||
{
|
||||
item.status === 7 && item.agreementSigning === 2 && '未上传支付报酬凭证'
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="clearfix">
|
||||
<span className="with40 fl lineh-35">
|
||||
<span className="color-grey-9 fl">截止时间:</span>
|
||||
<span className="infos_item">{stopTime(item)}</span>
|
||||
|
||||
{[3, 4, 5, 6, 7].includes(item.currentStatus) && <span className="ml10">{surplusTime(item)}</span>}
|
||||
</span>
|
||||
|
||||
{/* <span className="with40 lineh-35" style={{ display: "inline-flex" }}>
|
||||
<span className="color-grey-9 fl">任务编号:</span>
|
||||
<span className="infos_item mr15">{item.number}</span>
|
||||
<span className="fl lineh-35 ml5">
|
||||
<Link className="primary-link" to={`/task/taskDetail/${item.id}`}>{item.name}</Link>
|
||||
</span>
|
||||
</span> */}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
{list.length > 0 ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
{total > pageSize && <Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { changePage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>}
|
||||
</div> :
|
||||
<Nodata _html="暂无数据" />}
|
||||
|
||||
<Modal
|
||||
title="请输入延期截止的具体时间"
|
||||
visible={visible}
|
||||
onOk={delayTime}
|
||||
onCancel={() => { setVisible(false) }}
|
||||
className="time-edit-modal"
|
||||
>
|
||||
{helper(
|
||||
"",
|
||||
"delayedTo",
|
||||
[{ required: true, message: "请选择日期" }],
|
||||
<DatePicker
|
||||
format={format}
|
||||
placeholder="请选择日期"
|
||||
disabledDate={disabledDate}
|
||||
/>,
|
||||
moment(new Date(), format)
|
||||
)}
|
||||
</Modal>
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
||||
)
|
|
@ -0,0 +1,50 @@
|
|||
.list-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
margin: 0 1.5rem;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #dedede;
|
||||
a.edu-orangeline-btn {
|
||||
padding: 0px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
a.primary-link {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.infos_item {
|
||||
float: left;
|
||||
max-width: 273px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: #343434;
|
||||
margin-right: 6px;
|
||||
line-height: 35px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.file-list-prof{
|
||||
background: #fafafa;
|
||||
padding:.25rem .5rem;
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
display: inline-block;
|
||||
padding: 0px 10px;
|
||||
margin-left: .625rem;
|
||||
background: #f8c753;
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
border-radius: 14px;
|
||||
line-height: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.time-edit-modal .ant-modal-body{
|
||||
width: 200px;
|
||||
margin:0 auto;
|
||||
}
|
|
@ -0,0 +1,356 @@
|
|||
import React, { useEffect, useState, useCallback, useMemo } from 'react';
|
||||
import { Form, Modal, Input, Pagination, Radio, Table } from 'antd';
|
||||
import { Link } from "react-router-dom";
|
||||
import Nodata from 'forge/Nodata';
|
||||
import Loading from "src/Loading";
|
||||
import Upload from 'military/components/Upload';
|
||||
import ProofModal from '../proofModal';
|
||||
import { publishModeArr, taskStatusAllArr, myPaperStatusArr } from '../../static';
|
||||
import { signMethod, uploadAgreeRequire, downAgreement } from "../../api";
|
||||
import { httpUrl } from 'military/fetch';
|
||||
import '../../index.scss';
|
||||
import './index.scss';
|
||||
|
||||
const statusArr = [];
|
||||
for (const item of taskStatusAllArr) {
|
||||
statusArr[item.dicItemCode] = item.dicItemName;
|
||||
}
|
||||
export default Form.create()((props) => {
|
||||
const { form, list, curPage, total, changePage, taskCategoryValueArr, loading, publish, showNotification, reloadList, joinTask } = props;
|
||||
const { getFieldDecorator, validateFields, setFieldsValue, } = form;
|
||||
|
||||
const [visibleProofs, setVisibleProofs] = useState(false);
|
||||
const [taskId, setTaskId] = useState();
|
||||
const [checkItem, setCheckItem] = useState({});
|
||||
const [taskModeId, setTaskModeId] = useState('');
|
||||
const pageSize = props.pageSize || 10;
|
||||
|
||||
const [visibleMethod, setVisibleMethod] = useState(false);
|
||||
const [visibleAgree, setVisibleAgree] = useState(false);
|
||||
const [fileList, setFileList] = useState(null);
|
||||
|
||||
const [dowloadTaskId, setDowloadTaskId] = useState('');
|
||||
const [visibleDownload, setVisibleDownload] = useState(false);
|
||||
const [uploadList, setUploadList] = useState([]);
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
visibleDownload && downAgreement({ taskId: dowloadTaskId }).then(res => {
|
||||
if (res && res.message === "success") {
|
||||
setUploadList(res.data);
|
||||
}
|
||||
})
|
||||
}, [visibleDownload])
|
||||
|
||||
function uploadProofs(item) {
|
||||
setVisibleProofs(true);
|
||||
setTaskId(item.id);
|
||||
setTaskModeId(item.taskModeId);
|
||||
}
|
||||
|
||||
function adviceModal(advice) {
|
||||
Modal.info({
|
||||
title: '审核意见',
|
||||
content: advice
|
||||
})
|
||||
}
|
||||
|
||||
function signMethodModal(item) {
|
||||
setVisibleMethod(true);
|
||||
setTaskId(item.id);
|
||||
}
|
||||
|
||||
function uploadAgree(item) {
|
||||
setVisibleAgree(true);
|
||||
setTaskId(item.id);
|
||||
setCheckItem(item);
|
||||
}
|
||||
|
||||
function chooseMethod() {
|
||||
validateFields((err, values) => {
|
||||
if (!err) {
|
||||
signMethod({
|
||||
taskId,
|
||||
method: values.method,
|
||||
}).then(res => {
|
||||
if (res && res.message === 'success') {
|
||||
showNotification('选择协议签订方式成功');
|
||||
setVisibleMethod(false);
|
||||
setFieldsValue({
|
||||
method: ''
|
||||
});
|
||||
reloadList();
|
||||
} else {
|
||||
showNotification((res && res.message) || '操作失败');
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const helper = useCallback(
|
||||
(name, rules, widget) => (
|
||||
<Form.Item>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true, })(widget)}
|
||||
</Form.Item>
|
||||
), []);
|
||||
|
||||
|
||||
function uploadAgreeList() {
|
||||
validateFields((err, values) => {
|
||||
if (!err) {
|
||||
uploadAgreeRequire({
|
||||
taskId,
|
||||
params: {
|
||||
files: values.files
|
||||
}
|
||||
}).then(res => {
|
||||
if (res && res.message === "success") {
|
||||
setFieldsValue({
|
||||
files: ''
|
||||
});
|
||||
reloadList();
|
||||
setVisibleAgree(false);
|
||||
showNotification('上传协议成功');
|
||||
} else {
|
||||
showNotification((res && res.message) || '上传协议失败');
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function uploadFunc(fileList, files) {
|
||||
setFileList(fileList);
|
||||
setFieldsValue({
|
||||
files,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const columns = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
title: '成果物编号',
|
||||
dataIndex: 'paperNumber',
|
||||
},
|
||||
{
|
||||
title: '凭证文件',
|
||||
dataIndex: 'fileName',
|
||||
render: (text, record) => {
|
||||
return <a className="line_1 color-grey3" onClick={() => { download(record.winnerContracts[0].id) }}> {record.winnerContracts && record.winnerContracts[0].fileName}</a >
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
render: (text, record) => {
|
||||
return <a className="line_1 color-grey3" onClick={(e) => { download(record.winnerContracts[0].id) }}> 下载凭证</a >
|
||||
}
|
||||
}
|
||||
];
|
||||
}, []);
|
||||
|
||||
function download(id) {
|
||||
window.open(httpUrl + '/busiAttachments/download/' + id);
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ul className="df mt10 needs_condition_content_nav">
|
||||
<li key={1} className="with35 edu-txt-left">任务</li>
|
||||
<li key={2} className="with15">类型</li>
|
||||
{publish && <li key={3} className="with10 draft_only">应征投稿</li>}
|
||||
<li key={4} className="with10">金额</li>
|
||||
<li key={5} className="flex1">任务状态</li>
|
||||
<li key={6} className="with15">操作</li>
|
||||
</ul>
|
||||
|
||||
{loading ? <Loading /> : <React.Fragment>
|
||||
{
|
||||
list.map(item => {
|
||||
return (
|
||||
<div key={item.id} className="needs_condition_content">
|
||||
<p className="needs_condition_content_t color-dark-grey">
|
||||
任务编号:{item.number}
|
||||
<i className="ml20 mr5 iconfont icon-shijian color-grey9 font-16"></i>
|
||||
{item.createdAt}
|
||||
</p>
|
||||
<ul className="df">
|
||||
<li key={1} className="mytask-title with35 edu-txt-left font-16 font-bd" >
|
||||
<Link className="color-grey3 font-16 font-bd" to={`/task/taskDetail/${item.id}`}>{item.name}</Link>
|
||||
{
|
||||
joinTask ? <React.Fragment>
|
||||
{item.myPaperStatus === 0 && <span className="list_status s_orange ml10">{myPaperStatusArr[item.myPaperStatus]}</span>}
|
||||
{item.myPaperStatus === 1 && <span className="list_status s_grey ml10">{myPaperStatusArr[item.myPaperStatus]}</span>}
|
||||
{item.myPaperStatus === 2 && <span className="list_status s_red ml10">{myPaperStatusArr[item.myPaperStatus]}</span>}
|
||||
|
||||
{item.status === 6 && (item.agreementSigning === 1 || (item.agreementSigning === 2 && item.contractStatus === 1)) && <span className="list_status s_orange ml10">待签订协议</span>}
|
||||
|
||||
{item.status !== 8 && item.delayTime < 0 &&<span className="list_status list-yellow">延期中</span>}
|
||||
{item.status !== 8 && item.cancelStatus === 1 && item.delayTime > 0 && <span className="list_status list-yellow">手动延期中</span>}
|
||||
{item.status !== 8 && item.delayed && item.cancelStatus === 0 && item.delayTime > 0 && item.delayCount>0 &&<span className="list_status list-yellow">系统自动延期中</span>}
|
||||
|
||||
</React.Fragment> : <React.Fragment>
|
||||
{item.status === 6 && (item.agreementSigning === 1 || (item.agreementSigning === 2 && item.auditing && item.auditing.pass === 1)) && <span className="list_status s_orange ml10">待签订协议</span>}
|
||||
|
||||
{item.status !== 8 && item.delayTime < 0 &&<span className="list_status list-yellow">延期中</span>}
|
||||
{item.status !== 8 && item.cancelStatus === 1 && item.delayTime > 0 &&<span className="list_status list-yellow">手动延期中</span>}
|
||||
{item.status !== 8 && item.delayed && item.cancelStatus === 0 && item.delayTime > 0 && item.delayCount>0 && <span className="list_status list-yellow">系统自动延期中</span>}
|
||||
</React.Fragment>
|
||||
}
|
||||
</li>
|
||||
<li key={2} className="with15 flex-column">
|
||||
<span className="line_1">{taskCategoryValueArr[item.categoryId]}</span>
|
||||
<span className="line_1">{publishModeArr[item.publishMode]}</span>
|
||||
</li>
|
||||
|
||||
{publish && <li key={3} className="with10 draft_only">{item.papersCount || 0}</li>}
|
||||
|
||||
<li key={4} className="with10 color-orange">¥{item.bounty}</li>
|
||||
<li className="flex1">
|
||||
<span>
|
||||
<span className="line_1">{item.exceptClosedBoolean ? '已关闭' : statusArr[item.status]}</span>
|
||||
</span>
|
||||
</li>
|
||||
<li key={5} className="with15 flex-column">
|
||||
{
|
||||
joinTask ? <Link className="line_1 color-grey3" to={`/task/taskDetail/${item.id}`}>查看详情</Link>
|
||||
:
|
||||
<React.Fragment>
|
||||
{
|
||||
item.status === 0 || item.status === 9 ?
|
||||
<Link className="line_1 color-grey3" to={`/task/taskEdit/${item.id}`}>编辑草稿</Link> :
|
||||
<Link className="line_1 color-grey3" to={`/task/taskDetail/${item.id}`}>查看详情</Link>
|
||||
}
|
||||
|
||||
{
|
||||
item.status === 4 && item.papersCount > 0 && (!item.isProofBoolean) && (!item.isProofBoolean) &&
|
||||
<a onClick={() => { uploadProofs(item) }} className="line_1 color-blue">上传佐证材料</a>
|
||||
}
|
||||
|
||||
{
|
||||
(!item.isProofBoolean) && (item.taskResultProof && item.taskResultProof.status === 0) &&
|
||||
<a onClick={() => { adviceModal(item.advice) }} className="line_1 color-blue">佐证被拒原因</a>
|
||||
}
|
||||
|
||||
{(item.status === 2 || item.status === 9) && <a onClick={() => { adviceModal(item.repairAdvice) }} className="line_1 color-blue">审核意见</a>}
|
||||
|
||||
{item.status === 6 && item.agreementSigning === 0 && <a className="line_1 color-blue" onClick={() => { signMethodModal(item) }}>选择协议签订方式</a>}
|
||||
|
||||
{item.status === 6 && item.agreementSigning === 2 && (item.contractStatus === null || item.contractStatus === 0) && <a className="line_1 color-blue" onClick={() => { uploadAgree(item) }}>上传委托协议</a>}
|
||||
|
||||
{item.status === 6 && item.agreementSigning === 2 && [1, 2].includes(item.contractStatus) && <a className="line_1 color-grey-9" >已上传委托协议</a>}
|
||||
|
||||
{item.status === 6 && item.agreementSigning === 1 && <span className="line_1 color-grey-9">已选择自主签订协议</span>}
|
||||
|
||||
{item.status === 7 && <span className="line_1 color-grey-9">{item.agreementSigning === 1 ? '待胜出者确认收款' : '待平台上传支付凭证'}</span>}
|
||||
|
||||
{item.status === 7 && <a className="line_1 color-blue" onClick={() => { setDowloadTaskId(item.id); setVisibleDownload(true); }}>下载协议签订凭证</a>}
|
||||
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
{list.length > 0 ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
{total > pageSize && <Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { changePage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>}
|
||||
</div> :
|
||||
<Nodata _html="暂无数据" />}
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
{visibleProofs && <ProofModal
|
||||
taskId={taskId}
|
||||
taskModeId={taskModeId}
|
||||
visible={visibleProofs}
|
||||
changeVisible={setVisibleProofs}
|
||||
showNotification={showNotification}
|
||||
reloadList={reloadList}
|
||||
/>}
|
||||
|
||||
|
||||
<Modal
|
||||
title="选择签订协议方式"
|
||||
visible={visibleMethod}
|
||||
onOk={chooseMethod}
|
||||
onCancel={() => { setVisibleMethod(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
{
|
||||
helper('method', [{ required: visibleMethod, message: '请选择签订协议的方式' }],
|
||||
<Radio.Group className="vertical-radio">
|
||||
<Radio value={2}>
|
||||
<p>委托平台签订</p>
|
||||
<p className="color-grey-9">以平台名义与评选胜出者签订协议,需要经平台管理员审批需要发布方将奖励经费划归平台,在审核通过后平台自动发送电子协议</p>
|
||||
</Radio>
|
||||
<Radio value={1}>
|
||||
<p>自主签订</p>
|
||||
<p className="color-grey-9">通过线下的方式,以发布方名义与评选胜出者签订协议</p>
|
||||
</Radio>
|
||||
</Radio.Group>)
|
||||
}
|
||||
</Modal>
|
||||
|
||||
|
||||
<Modal
|
||||
title="上传委托协议"
|
||||
visible={visibleAgree}
|
||||
onOk={uploadAgreeList}
|
||||
onCancel={() => { setVisibleAgree(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
{checkItem.auditing && <p className="color-orange mb10 task_tip">
|
||||
审核意见:{checkItem.auditing.message}
|
||||
</p>}
|
||||
<Form.Item className="upload-form" label="协议上传" required={true}>
|
||||
<Upload
|
||||
load={uploadFunc}
|
||||
size={50}
|
||||
showNotification={showNotification}
|
||||
fileList={fileList}
|
||||
/>
|
||||
{/* 用一个隐藏的input实现上传文件的必填校验 */}
|
||||
{getFieldDecorator('files', {
|
||||
rules: [{ required: visibleAgree, message: "请上传文件" }],
|
||||
validateFirst: true
|
||||
})(<Input style={{ display: 'none' }} />)}
|
||||
</Form.Item>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="下载协议签订凭证"
|
||||
visible={visibleDownload}
|
||||
onOk={() => { setVisibleDownload(false) }}
|
||||
onCancel={() => { setVisibleDownload(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
<Table
|
||||
loading={loading}
|
||||
rowKey={(row) => row.id}
|
||||
dataSource={uploadList}
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
/>
|
||||
|
||||
</Modal>
|
||||
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
||||
)
|
|
@ -0,0 +1,106 @@
|
|||
.needs_condition_content_nav {
|
||||
padding: 0px 20px;
|
||||
background: #f7f7f7;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
color: #656565;
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.needs_condition_content {
|
||||
border: 1px solid #eaeaea;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
|
||||
li {
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: -webkit-flex;
|
||||
}
|
||||
|
||||
.mytask-title {
|
||||
justify-content: left;
|
||||
a {
|
||||
word-break: break-all;
|
||||
}
|
||||
span {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list_status {
|
||||
border-radius: 10px;
|
||||
padding: 0px 10px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
display: inline-block;
|
||||
color: #fff;
|
||||
background: #fa6400;
|
||||
margin-left: 0.625rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.s_orange {
|
||||
background: #ffb121;
|
||||
}
|
||||
|
||||
.s_red {
|
||||
background: #fe0e36;
|
||||
}
|
||||
|
||||
.s_blue {
|
||||
background: #4cacff;
|
||||
}
|
||||
|
||||
.s_grey {
|
||||
background: #bababa;
|
||||
}
|
||||
|
||||
.needs_condition_content_t {
|
||||
height: 40px;
|
||||
padding: 0px 20px;
|
||||
background: #f7f7f7;
|
||||
color: #333;
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-list-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #dedede;
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.vertical-radio {
|
||||
.ant-radio-wrapper {
|
||||
display: flex;
|
||||
line-height: 2rem;
|
||||
align-items: flex-start;
|
||||
.ant-radio {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
p {
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,297 @@
|
|||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { Pagination, Modal, Form, Input, Button } from 'antd';
|
||||
import ReactWEditor from 'wangeditor-for-react';
|
||||
import { timeAgo, getImageUrl } from 'educoder';
|
||||
import Nodata from 'forge/Nodata';
|
||||
import Loading from "src/Loading";
|
||||
import { editorConfig } from 'military/components/config';
|
||||
import AgreementModal from '../agreementModal';
|
||||
import ComplainModal from '../complainModal';
|
||||
import { reportPaper, thumbUpPaper, commentAdd, confirmReceipt } from '../../api';
|
||||
import { paperCheckStatusArr } from '../../static';
|
||||
import { httpUrl } from '../../../fetch';
|
||||
import winpng from '../../image/winner.png';
|
||||
import './index.scss';
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
const paperCheckStatus = [];
|
||||
for (const item of paperCheckStatusArr) {
|
||||
paperCheckStatus[item.dicItemCode] = item.dicItemName;
|
||||
}
|
||||
|
||||
export default Form.create()((props) => {
|
||||
const { list, curPage, total, changePage, loading, applyStatusAllNameArr, reloadList, showNotification, current_user, form, detailStatus } = props;
|
||||
const { getFieldDecorator, validateFields, setFieldsValue } = form;
|
||||
const [page, setPage] = useState(1);
|
||||
const pageSize = props.pageSize || 10;
|
||||
const [checkedItem, setCheckedItem] = useState({});
|
||||
const [reportVisible, setReportVisible] = useState(false);
|
||||
const [commentHtml, setCommentHtml] = useState('');
|
||||
|
||||
const [commentId, setCommentId] = useState(undefined);
|
||||
|
||||
const [complainVisible, setComplainVisible] = useState(false);
|
||||
const [agreeVisible, setAgreeVisible] = useState(false);
|
||||
|
||||
|
||||
const [loadingChild, setLoadingChild] = useState(false);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
changePage(page);
|
||||
}, [page]);
|
||||
|
||||
function downFile(item) {
|
||||
let url = httpUrl + '/busiAttachments/download/' + item.id;
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
function report() {
|
||||
validateFields((error, values) => {
|
||||
if (!error) {
|
||||
setLoadingChild(true);
|
||||
reportPaper({
|
||||
paperId: checkedItem.id,
|
||||
content: values.reportValue
|
||||
}).then(res => {
|
||||
if (res && res.message === 'success') {
|
||||
showNotification('举报成功');
|
||||
setReportVisible(false);
|
||||
setFieldsValue({
|
||||
reportValue: '',
|
||||
complainValue: '',
|
||||
});
|
||||
}
|
||||
setLoadingChild(false);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function thumbUp(id) {
|
||||
setLoadingChild(true);
|
||||
thumbUpPaper(id).then(res => {
|
||||
reloadList();
|
||||
setLoadingChild(false);
|
||||
});
|
||||
}
|
||||
|
||||
function commentPush(item) {
|
||||
if (!commentHtml) {
|
||||
showNotification("请输入评价");
|
||||
return;
|
||||
}
|
||||
if (commentHtml.length > 10000) {
|
||||
showNotification("评论过长,请减少评论内容或者简化评论格式");
|
||||
return;
|
||||
}
|
||||
commentAdd({
|
||||
content: commentHtml,
|
||||
paperId: item.id,
|
||||
taskId: item.taskId
|
||||
}).then(res => {
|
||||
if (res.message === 'success') {
|
||||
closeComment();
|
||||
reloadList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function closeComment() {
|
||||
setCommentId(undefined);
|
||||
setCommentHtml('');
|
||||
}
|
||||
|
||||
function commentEdit(id) {
|
||||
setCommentId(id);
|
||||
setCommentHtml('');
|
||||
}
|
||||
|
||||
function goUser(login) {
|
||||
window.location.href = `/users/${login}`;
|
||||
}
|
||||
|
||||
|
||||
function confirmReceiptModal(paperId) {
|
||||
Modal.confirm({
|
||||
title: '确认收款',
|
||||
content: '确认已经收到任务报酬',
|
||||
onOk: () => {
|
||||
confirmReceipt(paperId).then(res => {
|
||||
if (res && res.message === "success") {
|
||||
showNotification("您已确认收款!");
|
||||
reloadList();
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const helper = useCallback(
|
||||
(name, rules, widget) => (
|
||||
<Form.Item>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
</Form.Item>
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{loading || loadingChild ? <Loading /> :
|
||||
<React.Fragment>
|
||||
{
|
||||
list.map(item => {
|
||||
return (
|
||||
|
||||
<div className="fileComments df" key={item.id}>
|
||||
<img alt="头像加载失败" src={item.user && getImageUrl(item.user.logo)} width="50" height="50" className="bor-radius-all mr20" />
|
||||
<div className="flex1">
|
||||
<ul>
|
||||
<li className="fl pr">
|
||||
<span className={item.user.nickname === "******" ? "font-16 mr20 color-grey3" : "user-box font-16 mr20 color-grey3 clickable"} onClick={() => { item.user.nickname === "******" ? "" : goUser(item.user.login) }}>
|
||||
{item.user.nickname || item.user.login}
|
||||
</span>
|
||||
<span className="color-grey9">{timeAgo(item.createdAt)}</span>
|
||||
{item.status === 2 ? <img alt="胜出" className="mr5" src={winpng} /> : <span className="color-blue ml10">{item.checkStatus !== 1 ? paperCheckStatus[item.checkStatus] : applyStatusAllNameArr[item.status]}</span>}
|
||||
</li>
|
||||
<li className="fr">
|
||||
{((item.needComplain && detailStatus === 3) || (detailStatus === 5 && item.publicTaskComplain && item.checkStatus === 1 && item.status !== 2)) && (current_user.login === item.user.login) &&
|
||||
<a className="base_smallBtn blue_line_btn fl" onClick={() => { setComplainVisible(true); setCheckedItem(item) }}>申诉</a>}
|
||||
|
||||
{item.status === 2 && detailStatus === 6 && (current_user.login === item.user.login) && (!item.sign) && (item.canApplicantSign || item.canApplicantSignByPlatform) &&
|
||||
<a className="base_smallBtn blue_line_btn fl" onClick={() => { setAgreeVisible(true); setCheckedItem(item) }}>签订协议</a>}
|
||||
|
||||
{item.status === 2 && detailStatus === 7 && (current_user.login === item.user.login) && (item.task && item.task.agreementSigning === 1) && (!item.isPay) &&
|
||||
<a className="base_smallBtn blue_line_btn fl" onClick={() => { confirmReceiptModal(item.id) }}>确认收款</a>}
|
||||
</li>
|
||||
</ul>
|
||||
<div className="paper-detail-content markdown-body editormd-html-preview editor-w-text" dangerouslySetInnerHTML={{ __html: item.paperDetail ? item.paperDetail.content : '' }}></div>
|
||||
|
||||
<div className="attachments" >
|
||||
{
|
||||
item.paperDetail && item.paperDetail.busiAttachments && item.paperDetail.busiAttachments.map(fileItem => {
|
||||
return <div className="file-list-box" key={fileItem.id}>
|
||||
<a onClick={() => { downFile(fileItem) }}><i className="iconfont icon-fujian color-green font-14 mr3"></i>
|
||||
{fileItem.fileName} </a>
|
||||
<span className="ml10 color-grey-9">({fileItem.fileSizeString})</span>
|
||||
</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
{item.comments && item.comments.length > 0 && <div className="padding20 fileCommentsList">
|
||||
{item.comments.map(commentsItem => {
|
||||
return <div className="comments-item" key={commentsItem.id}>
|
||||
<div className="comments-author">
|
||||
<span className="color-grey3 font-bd mr20">{commentsItem.user.nickname || commentsItem.user.login}</span>
|
||||
<span className="color-grey9">{timeAgo(commentsItem.createdAt)}</span>
|
||||
</div>
|
||||
<div className="editor-w-text comments-content" dangerouslySetInnerHTML={{ __html: commentsItem.details && commentsItem.details.content }}>
|
||||
</div>
|
||||
</div>
|
||||
})
|
||||
}
|
||||
</div>}
|
||||
|
||||
|
||||
<li className="clearfix color-grey-6 mt10 mb20">
|
||||
<span className="mr50 fl"><span className="color-grey9">成果编号:</span>#{item.number}</span>
|
||||
<span className="mr50 fl"><span className="color-grey9">提交时间:</span>{item.createdAt}</span>
|
||||
<span className="fl"><span className="color-grey9">稿件状态:</span>{item.read ? '雇主已浏览' : '雇主未浏览'}</span>
|
||||
{
|
||||
item.user.nickname !== "******" && <span className="fr">
|
||||
{[4, 5].includes(detailStatus) && <a className="mr20" onClick={() => { setReportVisible(true); setCheckedItem(item) }}><i className="iconfont icon-jinggao font-15 mr3"></i>举报</a>}
|
||||
<a className="mr20" onClick={() => { commentEdit(item.id) }}><i className="iconfont icon-huifu1 font-15 mr3"></i>{item.comments ? item.comments.length : 0}</a>
|
||||
<a onClick={() => { thumbUp(item.id) }}><i className="iconfont icon-dianzan11 font-16 mr3"></i>{item.thumbsUp}</a>
|
||||
</span>
|
||||
}
|
||||
|
||||
</li>
|
||||
|
||||
{commentId === item.id && <React.Fragment>
|
||||
<ReactWEditor
|
||||
config={{
|
||||
...editorConfig,
|
||||
placeholder: "请输入评论",
|
||||
}}
|
||||
onChange={(html) => { setCommentHtml(html) }}
|
||||
/>
|
||||
<Button className="mt20 mr20 mb20 fr" type={"primary"} onClick={() => { commentPush(item) }}>发表</Button>
|
||||
<Button className="mt20 mr20 mb20 fr" onClick={closeComment}>取消</Button>
|
||||
</React.Fragment>}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
{list.length > 0 ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
{total > pageSize && <Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { setPage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>}
|
||||
</div> :
|
||||
<Nodata _html="暂无数据" />}
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
|
||||
<Modal
|
||||
title="举报"
|
||||
visible={reportVisible}
|
||||
onOk={report}
|
||||
onCancel={() => { setReportVisible(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
<div className="task-popup-content">
|
||||
<p className="edu-txt-center lineh-20 mb10">你的举报信息将发送给平台管理员</p>
|
||||
<p className="edu-txt-center lineh-20">请如实填写有效的举报原由,我们将尽快完成审核</p>
|
||||
{
|
||||
helper('reportValue', [{ required: reportVisible, message: "(必填)请在此输入发起举报的原因,最大限制100个字符" },
|
||||
{ max: 100, message: '长度不能超过100个字符' }],
|
||||
<TextArea
|
||||
placeholder="(必填)请在此输入发起举报的原因,最大限制100个字符"
|
||||
autoSize={{ minRows: 6 }}
|
||||
className="applyText"
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<ComplainModal
|
||||
visible={complainVisible}
|
||||
setVisible={setComplainVisible}
|
||||
checkedItem={checkedItem}
|
||||
detailStatus={detailStatus}
|
||||
showNotification={showNotification}
|
||||
reloadList={reloadList}
|
||||
/>
|
||||
|
||||
{agreeVisible && <AgreementModal
|
||||
paperId={checkedItem.id}
|
||||
checkedItem={checkedItem}
|
||||
visible={agreeVisible}
|
||||
setVisible={setAgreeVisible}
|
||||
showNotification={showNotification}
|
||||
reloadList={reloadList}
|
||||
/>}
|
||||
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
.blue_line_btn {
|
||||
color: #4cacff !important;
|
||||
border: 1px solid #4cacff;
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
.base_smallBtn {
|
||||
color: #ccc;
|
||||
font-size: 14px;
|
||||
background: #ccc;
|
||||
border-radius: 4px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
display: block;
|
||||
width: 100px;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
margin-top: 1.25rem;
|
||||
}
|
||||
|
||||
.fileCommentsList {
|
||||
background: #fafafa;
|
||||
padding-top: .25rem;
|
||||
}
|
||||
|
||||
.comments-item{
|
||||
margin-top:1rem;
|
||||
}
|
||||
.comments-content {
|
||||
text-align: left;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
padding: 20px;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.small-head{
|
||||
max-width: 2rem;
|
||||
}
|
||||
|
||||
.clickable:hover{
|
||||
color: #4cacff;
|
||||
cursor: pointer;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Icon, Pagination } from 'antd';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import Nodata from 'forge/Nodata';
|
||||
import { taskStatusAllArr } from '../../static';
|
||||
import Loading from "src/Loading";
|
||||
import './index.scss';
|
||||
|
||||
const statusArr = [];
|
||||
for (const item of taskStatusAllArr) {
|
||||
statusArr[item.dicItemCode] = item.dicItemName;
|
||||
}
|
||||
|
||||
const classArr = ['', 'list-done', 'list-error', 'list-red', 'list-yellow', 'list-pay', '', 'list-pay', 'list-gray',];
|
||||
export default (props) => {
|
||||
const { list, itemClick, curPage, total, changePage, loading } = props;
|
||||
const pageSize = props.pageSize || 10;
|
||||
|
||||
|
||||
function goUser(login) {
|
||||
window.location.href = `/users/${login}`;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
loading ? <Loading /> :
|
||||
<React.Fragment>
|
||||
{
|
||||
list.map(item => {
|
||||
return (
|
||||
<div className="list-box" key={item.id}>
|
||||
<div className="list-content">
|
||||
<div className="list-title mb10" onClick={() => { itemClick(item.id) }}>
|
||||
<div className="title-content text-ellipsis">{item.name}</div>
|
||||
{item.status && <span className={classArr[item.status]}>{item.exceptClosedBoolean ? '已关闭' : statusArr[item.status]}</span>}
|
||||
{(item.status !== 8) && item.delayTime.indexOf('延期') > -1 ? <span className="list-yellow">延期中</span>
|
||||
: <React.Fragment>
|
||||
{(item.status !== 8) && item.cancelStatus === 1 && <span className="list-yellow">手动延期中</span>}
|
||||
{(item.status !== 8) && item.delayed && item.cancelStatus === 0 && item.delayCount>0 && <span className="list-yellow">系统自动延期中</span>}
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
</div>
|
||||
<div className="list-other">
|
||||
<span className="user-box mr30" onClick={() => { goUser(item.user.login) }}>
|
||||
<img alt="" className="head-log-small" src={getImageUrl(item.user.logo)} />
|
||||
<span>{item.user.nickname || item.user.login}</span>
|
||||
</span>
|
||||
<span className="font-14 mr30"><i className="iconfont icon-dianjiliang mr3 font-12" />{item.visits || 0}</span>
|
||||
<span className="font-14 mr30"><Icon type="user" /><span className="color-orange">{item.papersCount || 0}</span>人参与</span>
|
||||
{(item.status !== 8) && <span className="color-orange mr30 font-14"><i className="mr5 iconfont icon-shijian color-grey9 font-14"></i>{item.delayTime}</span>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span className="price color-deep-blue ">
|
||||
<span className="font-16">¥</span>
|
||||
<span className="font-24">{item.bounty}</span>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
{list.length > 0 ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
{total > pageSize && <Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { changePage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>}
|
||||
</div> :
|
||||
<Nodata _html="暂无数据" />}
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
.list-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
margin: 0 1.5rem;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #dedede;
|
||||
}
|
||||
.user-box{
|
||||
cursor: pointer;
|
||||
&:hover{
|
||||
color: #409eff;
|
||||
}
|
||||
.head-log-small{
|
||||
position: relative;
|
||||
top:-2px;
|
||||
}
|
||||
}
|
||||
.price {
|
||||
font-weight: 500;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.list-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1rem;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
.title-content{
|
||||
display: inline-block;
|
||||
max-width: 80%;
|
||||
}
|
||||
}
|
||||
.list-title:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
.list-title span {
|
||||
padding: 0px 10px;
|
||||
margin-left: .625rem;
|
||||
background: #f8c753;
|
||||
font-size: .8rem;
|
||||
line-height: 1.8;
|
||||
color: #fff;
|
||||
border-radius: 14px;
|
||||
}
|
||||
|
||||
|
||||
.list-other {
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
i {
|
||||
font-size: 14px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { Pagination, Modal, Input, Button, Form, InputNumber } from 'antd';
|
||||
import { Link } from "react-router-dom";
|
||||
import Nodata from 'forge/Nodata';
|
||||
import Loading from "src/Loading";
|
||||
import Upload from 'military/components/Upload';
|
||||
import { timeAgo, getImageUrl } from 'educoder';
|
||||
import { uploadPayProof } from '../../api';
|
||||
import './index.scss';
|
||||
|
||||
export default Form.create()((props) => {
|
||||
const { form, list, curPage, total, changePage, loading, showNotification, reloadList } = props;
|
||||
const { getFieldDecorator, validateFields, setFieldsValue } = form;
|
||||
const [checkedItem, setCheckedItem] = useState({});
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [fileList, setFileList] = useState(null);
|
||||
const pageSize = props.pageSize || 10;
|
||||
|
||||
|
||||
function goUser(login) {
|
||||
window.location.href = `/users/${login}`;
|
||||
}
|
||||
|
||||
function goUserMes(login) {
|
||||
window.location.href = `/users/${login}/message_detail`;
|
||||
}
|
||||
|
||||
|
||||
// 上传附件后得到的文件数组
|
||||
function uploadFunc(fileList, files) {
|
||||
setFileList(fileList);
|
||||
setFieldsValue({ files });
|
||||
}
|
||||
|
||||
function uploadPay() {
|
||||
validateFields((err, values) => {
|
||||
if (!err) {
|
||||
uploadPayProof({
|
||||
paperId: checkedItem.id,
|
||||
params: {
|
||||
files: values.files,
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.message === 'success') {
|
||||
setFieldsValue({
|
||||
files: '',
|
||||
});
|
||||
setFileList([]);
|
||||
reloadList();
|
||||
setVisible(false);
|
||||
showNotification("上传支付凭证成功!");
|
||||
} else {
|
||||
showNotification(res.message || "上传支付凭证失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
loading ? <Loading /> :
|
||||
<React.Fragment>
|
||||
{
|
||||
list.map(item => {
|
||||
return (
|
||||
<div className="list-box" key={item.id}>
|
||||
|
||||
<img alt="" className="radius mr15" height="50px" src={item.user && getImageUrl(item.user.logo)} width="50px" />
|
||||
<div className="flex1">
|
||||
<li className="clearfix mb20">
|
||||
<a className="user-box fl mr15 color-grey-3 font-16" onClick={() => { goUser(item.user.login) }}>{item.user && (item.user.nickname || item.user.login)}</a>
|
||||
<span className="fl color-grey-9 mt3 mr15">{timeAgo(item.createdAt)}</span>
|
||||
<span className="infos_item color-grey-9 fl">发布方式:</span>
|
||||
<span className="infos_item mr15 fl">{item.task && item.task.publishMode === 1 ? '统筹任务' : '自主提交'}</span>
|
||||
<span className="fr"><a className="edu-default-btn edu-orangeline-btn ml20 fl" onClick={() => { item.user && goUserMes(item.user.login) }}>私信</a></span>
|
||||
</li>
|
||||
<div className="clearfix">
|
||||
<div className="width100 lineh-35" >
|
||||
<span className="with40 fl lineh-35">
|
||||
<span className="color-grey-9 fl">任务编号:</span>
|
||||
<span className="fl lineh-35 ml5">
|
||||
<Link className="primary-link" to={`/task/taskDetail/${item.taskId}`}>{item.task.name}</Link>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span className="with40 fl lineh-35">
|
||||
<span className="color-grey-9 fl">任务编号:</span>
|
||||
<span className="infos_item">{item.task.number}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div className="clearfix">
|
||||
<span className="with40 fl lineh-35" style={{ display: "inline-flex" }}>
|
||||
<span className="color-grey-9 fl">联系手机:</span>
|
||||
<span className="infos_item">{item.user.phone}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="clearfix"></div>
|
||||
{!item.isPay && (item.status !== 8) && <div className="width100 lineh-35 clearfix">
|
||||
<Button type="primary" onClick={() => { setVisible(true); setCheckedItem(item) }}>上传支付报酬凭证</Button>
|
||||
</div>}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
{list.length > 0 ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
{total > pageSize && <Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { changePage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>}
|
||||
</div> :
|
||||
<Nodata _html="暂无数据" />}
|
||||
|
||||
<Modal
|
||||
title="上传支付报酬凭证"
|
||||
visible={visible}
|
||||
onOk={uploadPay}
|
||||
onCancel={() => { setVisible(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
<div className="task-popup-content">
|
||||
<Form.Item className="upload-form" label="附件上传" required={true}>
|
||||
<Upload
|
||||
className="commentStyle"
|
||||
load={uploadFunc}
|
||||
size={50}
|
||||
showNotification={showNotification}
|
||||
fileList={fileList}
|
||||
/>
|
||||
{getFieldDecorator('files', {
|
||||
rules: [{ required: visible, message: "请上传文件" }],
|
||||
validateFirst: true
|
||||
})(<Input style={{ display: 'none' }} />)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
||||
)
|
|
@ -0,0 +1,52 @@
|
|||
.list-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
margin: 0 1.5rem;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #dedede;
|
||||
a.edu-orangeline-btn {
|
||||
padding: 0px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
a.primary-link {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.infos_item {
|
||||
float: left;
|
||||
max-width: 273px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: #343434;
|
||||
margin-right: 6px;
|
||||
line-height: 35px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.file-list-prof{
|
||||
background: #fafafa;
|
||||
padding:.25rem .5rem;
|
||||
margin-right:.5rem;
|
||||
}
|
||||
|
||||
.form-edit-modal {
|
||||
.ant-form-item{
|
||||
display: flex;
|
||||
}
|
||||
.ant-form-item-label{
|
||||
min-width: 5rem;
|
||||
}
|
||||
.ant-form-item-control-wrapper{
|
||||
width: 75%;
|
||||
display: inline-block;
|
||||
}
|
||||
.ant-input-number{
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
import React, { useEffect, useState, } from 'react';
|
||||
import { Pagination, Modal, Input } from 'antd';
|
||||
import { Link } from "react-router-dom";
|
||||
import Nodata from 'forge/Nodata';
|
||||
import Loading from "src/Loading";
|
||||
import { timeAgo, getImageUrl } from 'educoder';
|
||||
import { checkProof } from '../../api';
|
||||
import { httpUrl } from 'military/fetch';
|
||||
import './index.scss';
|
||||
|
||||
const { TextArea } = Input;
|
||||
export default (props) => {
|
||||
const { list, curPage, total, changePage, loading, showNotification, reloadList } = props;
|
||||
const [checkedItem, setCheckedItem] = useState('');
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [advice, setRepairAdvice] = useState('');
|
||||
const pageSize = props.pageSize || 10;
|
||||
|
||||
function agreeClick(item) {
|
||||
Modal.confirm({
|
||||
title: '是否确认审批通过?',
|
||||
onOk() {
|
||||
checkProof({
|
||||
id: item.taskResultProof.id,
|
||||
isPassed: 1,
|
||||
taskId: item.id,
|
||||
advice: "",
|
||||
}).then(res => {
|
||||
if (res && res.message === 'success') {
|
||||
showNotification('操作成功');
|
||||
reloadList();
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function refuseClick(item) {
|
||||
setCheckedItem(item);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
function refuse() {
|
||||
if (!advice) {
|
||||
showNotification('请输入拒绝的理由');
|
||||
return;
|
||||
}
|
||||
checkProof({
|
||||
id: checkedItem.taskResultProof.id,
|
||||
taskId: checkedItem.id,
|
||||
isPassed: 0,
|
||||
advice: advice
|
||||
}).then(res => {
|
||||
if (res && res.message === 'success') {
|
||||
showNotification('操作成功');
|
||||
reloadList();
|
||||
setRepairAdvice('');
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function goUser(login) {
|
||||
window.location.href = `/users/${login}`;
|
||||
}
|
||||
|
||||
function goUserMes(login) {
|
||||
window.location.href = `/users/${login}/message_detail`;
|
||||
}
|
||||
|
||||
function downFile(item) {
|
||||
let url = httpUrl + '/busiAttachments/download/' + item.id;
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return (
|
||||
loading ? <Loading /> :
|
||||
<React.Fragment>
|
||||
{
|
||||
list.map(item => {
|
||||
return (
|
||||
<div className="list-box" key={item.id}>
|
||||
|
||||
<img alt="" className="radius mr15" height="50px" src={item.user && getImageUrl(item.user.logo)} width="50px" />
|
||||
<div className="flex1">
|
||||
<li className="clearfix mb20">
|
||||
<a className="user-box fl mr15 color-grey-3 font-16" onClick={() => { goUser(item.user.login) }}>{item.user.nickname || item.user.login}</a>
|
||||
<span className="fl color-grey-9 mt3 mr15">{timeAgo(item.createdAt)}</span>
|
||||
<span className="with40 fl lineh-35">
|
||||
<span className="color-grey-9 fl">主体名称:</span>
|
||||
<span className="infos_item">{item.enterpriseName}</span>
|
||||
</span>
|
||||
<span className="fr">
|
||||
{item.taskResultProof.status === 1 && <span className="spanTitle color-grey-6 fl ml20">已同意</span>}
|
||||
{item.taskResultProof.status === 0 && <span className="spanTitle color-red fl ml20">已拒绝</span>}
|
||||
|
||||
{
|
||||
item.taskResultProof.status === 2 && <React.Fragment>
|
||||
<a className="edu-default-btn edu-orangeline-btn ml20 fl" onClick={() => { goUserMes(item.user.login) }}>私信</a>
|
||||
<a className="edu-default-btn edu-blueline-btn ml20 fl" onClick={() => { agreeClick(item) }}>同意</a>
|
||||
<a className="edu-default-btn edu-greyline-btn ml20 fl" onClick={() => { refuseClick(item) }}>拒绝</a>
|
||||
</React.Fragment>
|
||||
}
|
||||
</span>
|
||||
</li>
|
||||
<ul className="clearfix">
|
||||
<div className="width100 lineh-35" style={{ display: "inline-flex" }}>
|
||||
<span className="color-grey-9 fl">任务编号:</span>
|
||||
<span className="infos_item mr15">{item.number}</span>
|
||||
<span className="fl lineh-35 ml5">
|
||||
<Link className="primary-link" to={`/task/taskDetail/${item.id}`}>{item.name}</Link>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="clearfix"></div>
|
||||
<div className="width100 lineh-35">
|
||||
<span className="color-grey-9 fl">评选胜出({item.taskResultProof.winnerName.split(',').length}):</span>
|
||||
<span className="infos_item">{item.taskResultProof.winnerName}</span>
|
||||
</div>
|
||||
<div className="clearfix"></div>
|
||||
<div className="width100 lineh-35 clearfix">
|
||||
<span className="color-grey-9 fl">佐证材料:</span>
|
||||
{
|
||||
item.taskProofAttachments && item.taskProofAttachments.map(fileItem => {
|
||||
return <span className="file-list-prof " key={fileItem.id}>
|
||||
<a onClick={() => { downFile(fileItem) }}><i className="iconfont icon-fujian color-green font-14 mr3"></i>
|
||||
{fileItem.fileName} </a>
|
||||
<span className="ml10 color-grey-9">({fileItem.fileSizeString})</span>
|
||||
</span>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
{item.taskResultProof.status === 0 && <p className="color-orange lineh-35 "><span className="fl color-orange mr5">拒绝原因:</span>{item.advice}</p>}
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
{list.length > 0 ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
{total > pageSize && <Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { changePage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>}
|
||||
</div> :
|
||||
<Nodata _html="暂无数据" />}
|
||||
|
||||
<Modal
|
||||
title="拒绝原因"
|
||||
visible={visible}
|
||||
onOk={refuse}
|
||||
onCancel={() => { setVisible(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
<TextArea
|
||||
value={advice}
|
||||
placeholder="(必填)我想说点什么呢,200字以内"
|
||||
autoSize={{ minRows: 6 }}
|
||||
className="applyText"
|
||||
onChange={(e) => { setRepairAdvice(e.target.value) }}
|
||||
maxLength={200}
|
||||
/>
|
||||
</Modal>
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
.list-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
margin: 0 1.5rem;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #dedede;
|
||||
a.edu-orangeline-btn {
|
||||
padding: 0px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
a.primary-link {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.infos_item {
|
||||
float: left;
|
||||
max-width: 273px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: #343434;
|
||||
margin-right: 6px;
|
||||
line-height: 35px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.file-list-prof{
|
||||
background: #fafafa;
|
||||
padding:.25rem .5rem;
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { Pagination, Modal, Input, Radio, Form, InputNumber } from 'antd';
|
||||
import { Link } from "react-router-dom";
|
||||
import Nodata from 'forge/Nodata';
|
||||
import Loading from "src/Loading";
|
||||
import { timeAgo, getImageUrl } from 'educoder';
|
||||
import { checkPublicity } from '../../api';
|
||||
import { httpUrl } from 'military/fetch';
|
||||
import './index.scss';
|
||||
|
||||
const { TextArea } = Input;
|
||||
export default Form.create()((props) => {
|
||||
const { form, list, curPage, total, changePage, loading, showNotification, reloadList } = props;
|
||||
const { getFieldDecorator, validateFields, setFieldsValue } = form;
|
||||
const [checkedItem, setCheckedItem] = useState('');
|
||||
const [visible, setVisible] = useState(false);
|
||||
const pageSize = props.pageSize || 10;
|
||||
|
||||
const [isAccepted, setIsAccepted] = useState('');
|
||||
const [isReconsidered, setIsReconsidered] = useState('');
|
||||
const [isChanged, setIsChanged] = useState('');
|
||||
|
||||
|
||||
|
||||
function deal(item) {
|
||||
setCheckedItem(item);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
function dealAction() {
|
||||
validateFields((error, values) => {
|
||||
if (!error) {
|
||||
checkPublicity({
|
||||
complaintMaterialId: checkedItem.id,
|
||||
...values,
|
||||
}).then(res => {
|
||||
if (res && res.message === 'success') {
|
||||
showNotification('操作成功');
|
||||
reloadList();
|
||||
setFieldsValue({
|
||||
isAccepted: '',
|
||||
reason: '',
|
||||
});
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function goUser(login) {
|
||||
window.location.href = `/users/${login}`;
|
||||
}
|
||||
|
||||
function goUserMes(login) {
|
||||
window.location.href = `/users/${login}/message_detail`;
|
||||
}
|
||||
|
||||
function downFile(item) {
|
||||
let url = httpUrl + '/busiAttachments/download/' + item.id;
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget, rightDom) => (
|
||||
<Form.Item label={label}>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
{rightDom}
|
||||
</Form.Item>
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
loading ? <Loading /> :
|
||||
<React.Fragment>
|
||||
{
|
||||
list.map(item => {
|
||||
return (
|
||||
<div className="list-box" key={item.id}>
|
||||
|
||||
<img alt="头像加载失败" className="radius mr15" height="50px" src={item.user && getImageUrl(item.user.logo)} width="50px" />
|
||||
<div className="flex1">
|
||||
<li className="clearfix mb20">
|
||||
<a className="user-box fl mr15 color-grey-3 font-16" onClick={() => { goUser(item.user.login) }}>{item.user && (item.user.nickname || item.user.login)}</a>
|
||||
<span className="fl color-grey-9 mt3 mr15">{timeAgo(item.createdAt)}</span>
|
||||
<span className="fr">
|
||||
<a className="edu-default-btn edu-orangeline-btn ml20 fl" onClick={() => { goUserMes(item.user.login) }}>私信</a>
|
||||
{item.status === 2 && <a className="edu-default-btn edu-blueline-btn ml20 fl" onClick={() => { deal(item) }}>处理</a>}
|
||||
</span>
|
||||
</li>
|
||||
<div className="clearfix">
|
||||
|
||||
{/* <div className="width100">
|
||||
<span className="with40 fl lineh-35">
|
||||
<span className="color-grey-9 fl">联系手机:</span>
|
||||
<span className="infos_item">{item.contactPhone}(位置分析:河北-唐山)</span>
|
||||
</span>
|
||||
<span className="inline-block lineh-35">
|
||||
<span className="color-grey-9 fl">IP地址:</span>
|
||||
<span className="infos_item">{item.ip}(位置分析:北京-北京)</span>
|
||||
</span>
|
||||
</div> */}
|
||||
|
||||
<div className="clearfix"></div>
|
||||
<div className="width100 lineh-35">
|
||||
<span className="color-grey-9 fl">成果编号:</span>
|
||||
<span className="fl lineh-35 ml5">
|
||||
<Link className="primary-link" to={`/task/taskDetail/${item.taskId}`}>{item.paperNumber}</Link>
|
||||
</span>
|
||||
</div>
|
||||
<div className="clearfix"></div>
|
||||
<div className="width100 lineh-35 clearfix">
|
||||
<span className="color-grey-9 fl">申诉材料:</span>
|
||||
{
|
||||
item.materials && item.materials.map(fileItem => {
|
||||
return <span className="file-list-prof " key={fileItem.id}>
|
||||
<a onClick={() => { downFile(fileItem) }}><i className="iconfont icon-fujian color-green font-14 mr3"></i>
|
||||
{fileItem.fileName} </a>
|
||||
<span className="ml10 color-grey-9">({fileItem.fileSizeString})</span>
|
||||
</span>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
<div className="width100 lineh-35">
|
||||
<span className="color-grey-9 fl">申诉原因:</span>
|
||||
<span className="infos_item">{item.content}</span>
|
||||
</div>
|
||||
{/* {item.taskResultProof.status === 0 && <p className="color-orange lineh-35 "><span className="fl color-orange mr5">拒绝原因:</span>{item.advice}</p>} */}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
{list.length > 0 ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
{total > pageSize && <Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { changePage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>}
|
||||
</div> :
|
||||
<Nodata _html="暂无数据" />}
|
||||
|
||||
<Modal
|
||||
title="处理申诉"
|
||||
visible={visible}
|
||||
onOk={dealAction}
|
||||
onCancel={() => { setVisible(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
|
||||
{
|
||||
helper('是否受理', 'isAccepted', [{ required: true, message: "请选择是否受理" }],
|
||||
<Radio.Group
|
||||
className="mb10"
|
||||
onChange={(e) => { setIsAccepted(e.target.value); setIsReconsidered(''); setIsChanged(''); }}
|
||||
>
|
||||
<Radio value={'1'}>受理</Radio>
|
||||
<Radio value={'0'}>不受理</Radio>
|
||||
</Radio.Group>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
isAccepted === '1' && helper('复议评审', 'isReconsidered', [{ required: true, message: "请选择是否启动复议评审" }],
|
||||
<Radio.Group
|
||||
className="mb10"
|
||||
onChange={(e) => { setIsReconsidered(e.target.value); setIsChanged(''); }}
|
||||
>
|
||||
<Radio value={'1'}>启动</Radio>
|
||||
<Radio value={'0'}>不启动</Radio>
|
||||
</Radio.Group>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
isAccepted === '1' && isReconsidered === '0' && helper('公示结果', 'isChanged', [{ required: true, message: "请选择是否更改公示结果" }],
|
||||
<Radio.Group
|
||||
className="mb10"
|
||||
onChange={(e) => { setIsChanged(e.target.value) }}
|
||||
>
|
||||
<Radio value={'1'}>更改</Radio>
|
||||
<Radio value={'0'}>不更改</Radio>
|
||||
</Radio.Group>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
isAccepted === '1' && isReconsidered === '0' && isChanged === '1' && helper('延长公示', 'delayDuration',
|
||||
[{ required: true, message: "请输入延长天数" }],
|
||||
<InputNumber
|
||||
placeholder="您打算延长多少天呢"
|
||||
max={150}
|
||||
min={0}
|
||||
/>,
|
||||
' 天'
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
helper('原因', 'reason', [{ required: true, message: "请输入原因" }, { max: 200, message: '不能超过200字符' }],
|
||||
<TextArea
|
||||
placeholder="(必填)我想说点什么呢,200字以内"
|
||||
autoSize={{ minRows: 6 }}
|
||||
className="applyText"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
</Modal>
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
||||
)
|
|
@ -0,0 +1,52 @@
|
|||
.list-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
margin: 0 1.5rem;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #dedede;
|
||||
a.edu-orangeline-btn {
|
||||
padding: 0px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
a.primary-link {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.infos_item {
|
||||
float: left;
|
||||
max-width: 90%;
|
||||
overflow: hidden;
|
||||
// white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: #343434;
|
||||
margin-right: 6px;
|
||||
line-height: 35px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.file-list-prof{
|
||||
background: #fafafa;
|
||||
padding:.25rem .5rem;
|
||||
margin-right:.5rem;
|
||||
}
|
||||
|
||||
.form-edit-modal {
|
||||
.ant-form-item{
|
||||
display: flex;
|
||||
}
|
||||
.ant-form-item-label{
|
||||
min-width: 5rem;
|
||||
}
|
||||
.ant-form-item-control-wrapper{
|
||||
width: 75%;
|
||||
display: inline-block;
|
||||
}
|
||||
.ant-input-number{
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Pagination, Modal, Input, Radio, Button } from 'antd';
|
||||
import { Link } from "react-router-dom";
|
||||
import Nodata from 'forge/Nodata';
|
||||
import Loading from "src/Loading";
|
||||
import { timeAgo, getImageUrl } from 'educoder';
|
||||
import { main_web_site_url } from '../../static';
|
||||
import { checkTask } from '../../api';
|
||||
import './index.scss';
|
||||
|
||||
const { TextArea } = Input;
|
||||
export default (props) => {
|
||||
const { list, categoryArr, curPage, total, changePage, loading, showNotification, reloadList } = props;
|
||||
const [checkedId, setCheckedId] = useState('');
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [isRepairDocument, setIsRepairDocument] = useState('0');
|
||||
const [repairAdvice, setRepairAdvice] = useState('');
|
||||
const pageSize = props.pageSize || 10;
|
||||
|
||||
|
||||
function agreeClick(id) {
|
||||
Modal.confirm({
|
||||
title: '是否确认审批通过?',
|
||||
onOk() {
|
||||
checkTask({
|
||||
id,
|
||||
isPassed: 1,
|
||||
}).then(res => {
|
||||
if (res && res.message === 'success') {
|
||||
showNotification('操作成功');
|
||||
reloadList();
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function refuseClick(id) {
|
||||
setCheckedId(id);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
function refuse() {
|
||||
if (!repairAdvice) {
|
||||
showNotification('请输入拒绝的理由');
|
||||
return;
|
||||
}
|
||||
checkTask({
|
||||
id: checkedId,
|
||||
isPassed: 0,
|
||||
isRepairDocument,
|
||||
repairAdvice: repairAdvice
|
||||
}).then(res => {
|
||||
if (res && res.message === 'success') {
|
||||
showNotification('操作成功');
|
||||
reloadList();
|
||||
setRepairAdvice('');
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function goUser(login) {
|
||||
window.location.href = `/users/${login}`;
|
||||
}
|
||||
|
||||
function goUserMes(login) {
|
||||
window.location.href = `/users/${login}/message_detail`;
|
||||
}
|
||||
|
||||
function scale(scale) {
|
||||
if (scale > 10000) {
|
||||
return '10000人以上';
|
||||
} else if (scale > 1000) {
|
||||
return '1001 - 10000人';
|
||||
} else if (scale > 100) {
|
||||
return '101 - 1000人';
|
||||
} else if (scale > 10) {
|
||||
return '11 - 99人';
|
||||
} else {
|
||||
return '0 - 10人';
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
loading ? <Loading /> :
|
||||
<React.Fragment>
|
||||
{
|
||||
list.map(item => {
|
||||
return (
|
||||
<div className="list-box" key={item.id}>
|
||||
|
||||
<img alt="头像加载失败" className="radius mr15" height="50px" src={item.user && getImageUrl(item.user.logo)} width="50px" />
|
||||
<div className="flex1">
|
||||
<li className="clearfix mb20">
|
||||
<a className="user-box fl mr15 color-grey-3 font-16" onClick={() => { goUser(item.user.login) }}>{item.user.nickname || item.user.login}</a>
|
||||
<span className="fl color-grey-9 mt3">{timeAgo(item.createdAt)}</span>
|
||||
<span className="fr">
|
||||
{item.status > 2 && item.status !== 9 && <span className="spanTitle color-grey-6 fl ml20">已同意</span>}
|
||||
{item.status === 9 && <span className="spanTitle color-yellow fl ml20">已处理</span>}
|
||||
{item.status === 2 && <span className="spanTitle color-red fl ml20">已拒绝</span>}
|
||||
|
||||
{
|
||||
item.status === 1 && <React.Fragment>
|
||||
<a className="edu-default-btn edu-orangeline-btn ml20 fl" onClick={() => { goUserMes(item.user.login) }}>私信</a>
|
||||
<a className="edu-default-btn edu-blueline-btn ml20 fl" onClick={() => { agreeClick(item.id) }}>同意</a>
|
||||
<a className="edu-default-btn edu-greyline-btn ml20 fl" onClick={() => { refuseClick(item.id) }}>拒绝</a>
|
||||
</React.Fragment>
|
||||
}
|
||||
</span>
|
||||
</li>
|
||||
<ul className="clearfix">
|
||||
<div className="width100">
|
||||
<span className="with40 fl inline-block lineh-35">
|
||||
<span className="color-grey-9 fl">任务名称:</span>
|
||||
<span className="fl lineh-35 ml5">
|
||||
<Link className="primary-link" to={`/task/taskDetail/${item.id}`}>{item.name}</Link>
|
||||
</span>
|
||||
</span>
|
||||
<span className=" lineh-35">
|
||||
<span className="color-grey-9 fl">任务编号:</span>
|
||||
<span className="infos_item">{item.number}</span>
|
||||
</span>
|
||||
|
||||
{item.status === 1 && <div className="fr text-center">
|
||||
<Button type="primary" onClick={() => { window.open(`${main_web_site_url}/admin/tasks/export_task_files.zip?task_id=${item.id}`) }} className="edu-default-btn edu-blueback-btn">导出任务需求材料</Button>
|
||||
</div>}
|
||||
</div>
|
||||
<div className="clearfix"></div>
|
||||
|
||||
<div className="width100">
|
||||
<div className="width100">
|
||||
<span className="with40 fl lineh-35">
|
||||
<span className="color-grey-9 fl">主体名称:</span>
|
||||
<span className="infos_item">{item.enterpriseName}</span>
|
||||
</span>
|
||||
<span className="inline-block lineh-35">
|
||||
<span className="color-grey-9 fl">信用代码:</span>
|
||||
<span className="infos_item">{item.enterpriseSimple ? item.enterpriseSimple.creditCode : ''}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="clearfix"></div>
|
||||
<div className="width100">
|
||||
<span className="with40 fl lineh-35">
|
||||
<span className="color-grey-9 fl">联系手机:</span>
|
||||
<span className="infos_item">{item.contactPhone}{item.belongTo && `(位置分析:${item.belongTo})`}</span>
|
||||
</span>
|
||||
<span className="inline-block lineh-35">
|
||||
<span className="color-grey-9 fl">IP地址:</span>
|
||||
<span className="infos_item">{item.ip}{item.belongTo && `(位置分析:${item.belongTo})`}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div className="clearfix"></div>
|
||||
<div className="width100">
|
||||
<span className="with40 fl lineh-35">
|
||||
<span className="color-grey-9 fl">所在行业:</span>
|
||||
<span className="infos_item" style={{ maxWidth: '100px' }}>{categoryArr[item.categoryId]}</span>
|
||||
</span>
|
||||
{
|
||||
item.enterpriseSimple && <span className="with25 fl lineh-35">
|
||||
<span className="color-grey-9 fl">企业规模:</span>
|
||||
<span className="infos_item" style={{ maxWidth: '100px' }}>{scale(item.enterpriseSimple.scale)}</span>
|
||||
</span>}
|
||||
{/* <span className="inline-block lineh-35">
|
||||
<span className="color-grey-9 fl">所在职位:</span>
|
||||
<span className="infos_item">普通员工</span>
|
||||
</span> */}
|
||||
</div>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
{list.length > 0 ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
{total > pageSize && <Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { changePage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>}
|
||||
</div> :
|
||||
<Nodata _html="暂无数据" />}
|
||||
|
||||
<Modal
|
||||
title="拒绝原因"
|
||||
visible={visible}
|
||||
onOk={refuse}
|
||||
onCancel={() => { setVisible(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
<Radio.Group
|
||||
className="mb10"
|
||||
value={isRepairDocument}
|
||||
onChange={(e) => { setIsRepairDocument(e.target.value) }}>
|
||||
<Radio value={'0'}>不允许重新发布</Radio>
|
||||
<Radio value={'1'}>允许修缮后重新发布</Radio>
|
||||
</Radio.Group>
|
||||
<TextArea
|
||||
value={repairAdvice}
|
||||
placeholder="(必填)我想说点什么呢,200字以内"
|
||||
autoSize={{ minRows: 6 }}
|
||||
className="applyText"
|
||||
onChange={(e) => { setRepairAdvice(e.target.value) }}
|
||||
maxLength={200}
|
||||
/>
|
||||
</Modal>
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
.list-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
margin: 0 1.5rem;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #dedede;
|
||||
a.edu-orangeline-btn {
|
||||
padding: 0px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
a.primary-link {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.infos_item {
|
||||
float: left;
|
||||
max-width: 273px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: #343434;
|
||||
margin-right: 6px;
|
||||
line-height: 35px;
|
||||
margin-left: 5px;
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
import React, { useEffect, useState, useCallback, useMemo } from 'react';
|
||||
import { Modal, Table, Form, Input, Button, Pagination } from 'antd';
|
||||
import Upload from 'military/components/Upload';
|
||||
import { readyCheckPapers, proofAdd } from "../../api";
|
||||
import { httpUrl } from 'military/fetch';
|
||||
import '../../index.scss';
|
||||
import './index.scss';
|
||||
|
||||
export default Form.create()(props => {
|
||||
const { changeVisible, taskId, taskModeId, visible, form, showNotification, reloadList } = props;
|
||||
const { getFieldDecorator, validateFields, setFieldsValue, getFieldsValue } = form;
|
||||
|
||||
const pageSize = props.pageSize || 10;
|
||||
const [searchObj, setSearchObj] = useState({});
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [curPage, setCurPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [dataList, setDataList] = useState([]);
|
||||
|
||||
const [fileList, setFileList] = useState([]);
|
||||
const [selectedRows, setSelectedRows] = useState([]);
|
||||
|
||||
// 获取成果列表
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
let params = {
|
||||
...searchObj,
|
||||
taskId,
|
||||
checkStatus: '1',
|
||||
pageSize,
|
||||
curPage,
|
||||
status: '',
|
||||
parentId:0,
|
||||
}
|
||||
taskId && readyCheckPapers(params).then(data => {
|
||||
if (data && Array.isArray(data.rows)) {
|
||||
for (const item of data.rows) {
|
||||
item.detail = item.paperDetail && item.paperDetail.content;
|
||||
}
|
||||
}
|
||||
setDataList(data.rows || []);
|
||||
setLoading(false);
|
||||
setTotal(data.total);
|
||||
});
|
||||
}, [taskId, curPage, searchObj]);
|
||||
|
||||
|
||||
const helper = useCallback(
|
||||
(name, rules, widget) => (
|
||||
<Form.Item>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true, })(widget)}
|
||||
</Form.Item>
|
||||
), []);
|
||||
|
||||
function onSearch() {
|
||||
let values = getFieldsValue(['number', 'userName']);
|
||||
setSearchObj(values);
|
||||
setCurPage(1);
|
||||
}
|
||||
|
||||
function clearSearch() {
|
||||
setFieldsValue({
|
||||
number: '',
|
||||
userName: '',
|
||||
});
|
||||
setSearchObj({});
|
||||
setCurPage(1);
|
||||
}
|
||||
|
||||
// 上传附件后得到的文件数组
|
||||
function UploadFunc(fileList, files) {
|
||||
setFileList(fileList);
|
||||
setFieldsValue({
|
||||
files
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const columns = useMemo(() => {
|
||||
return [{
|
||||
title: '作者',
|
||||
dataIndex: 'name',
|
||||
render: (text, record) => {
|
||||
return record.user ? record.user.nickname || record.user.login : ''
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '成果物编号',
|
||||
dataIndex: 'number',
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
dataIndex: 'updatedAt',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
render: (text, record) => {
|
||||
// return <Link className="line_1 color-grey3" to={`/task/taskDetail/${record.task.id}`}>查看详情</Link>
|
||||
return <a className="line_1 color-grey3" onClick={(e) => { goToDeatil(e, record.task.id) }}> 查看详情</a >
|
||||
}
|
||||
}];
|
||||
}, [taskId]);
|
||||
|
||||
const rowSelection = useMemo(() => {
|
||||
return {
|
||||
type: taskModeId === 1 ? 'radio' : 'checkbox',
|
||||
onChange: (selectedRowKeys, selectedRows) => {
|
||||
setSelectedRows(selectedRows);
|
||||
},
|
||||
}
|
||||
}, [taskModeId]);
|
||||
|
||||
function goToDeatil(e, taskId) {
|
||||
e.stopPropagation();
|
||||
window.location.href = `/task/taskDetail/${taskId}`;
|
||||
}
|
||||
|
||||
const handleRow = record => {
|
||||
return {
|
||||
onClick: event => {
|
||||
let chooseDom = event.currentTarget.getElementsByClassName("ant-checkbox-wrapper")[0] || event.currentTarget.getElementsByClassName("ant-radio-wrapper")[0];
|
||||
chooseDom && chooseDom.click();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
function proofItem() {
|
||||
if (!selectedRows.length) {
|
||||
showNotification("请至少选择一条数据!");
|
||||
return;
|
||||
}
|
||||
|
||||
validateFields((err, values) => {
|
||||
if (!err) {
|
||||
let paperNumber = [];
|
||||
let winnerIds = [];
|
||||
let winnerName = [];
|
||||
|
||||
for (const item of selectedRows) {
|
||||
paperNumber.push(item.number);
|
||||
winnerIds.push(item.user.id);
|
||||
winnerName.push(item.user.nickname || item.user.login);
|
||||
}
|
||||
|
||||
let params = {
|
||||
paperNumber: paperNumber.join(),
|
||||
winnerIds: winnerIds.join(),
|
||||
winnerName: winnerName.join(),
|
||||
proofFileNumbers: values.files,
|
||||
status: 2,
|
||||
taskId,
|
||||
};
|
||||
proofAdd(params).then(res => {
|
||||
if (res && res.message === 'success') {
|
||||
changeVisible(false);
|
||||
reloadList();
|
||||
} else {
|
||||
showNotification((res && res.message) || "评选提交失败");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="上传评选佐证材料"
|
||||
visible={visible}
|
||||
onOk={proofItem}
|
||||
onCancel={() => { changeVisible(false) }}
|
||||
className="proof-modal"
|
||||
draggable={true}
|
||||
>
|
||||
<h3 className="margin10">选出胜出者<span className="color-red">*</span></h3>
|
||||
<div className="center-right-but">
|
||||
{helper(
|
||||
"number",
|
||||
[{ max: 20, message: '长度不能超过20个字符' }],
|
||||
<Input
|
||||
placeholder="请输入成果编号进行检索"
|
||||
/>
|
||||
)}
|
||||
|
||||
{helper(
|
||||
"userName",
|
||||
[{ max: 20, message: '长度不能超过20个字符' }],
|
||||
<Input
|
||||
placeholder="请输入作者名称进行检索"
|
||||
/>
|
||||
)}
|
||||
<Button className="mr10" type="primary" onClick={onSearch}>搜索</Button>
|
||||
<Button className="mr10" type="" onClick={clearSearch}>清除</Button>
|
||||
</div>
|
||||
<Table
|
||||
loading={loading}
|
||||
rowKey={(row) => row.id}
|
||||
dataSource={dataList}
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
rowSelection={rowSelection}
|
||||
onRow={handleRow}
|
||||
/>
|
||||
{total > 10 &&
|
||||
<Pagination
|
||||
onChange={(page) => { setCurPage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
/>}
|
||||
|
||||
<Form.Item className="upload-form" label="上传附件" required={true} >
|
||||
<Upload
|
||||
className="commentStyle"
|
||||
load={UploadFunc}
|
||||
size={50}
|
||||
showNotification={showNotification}
|
||||
actionUrl={httpUrl}
|
||||
fileList={fileList}
|
||||
/>
|
||||
{getFieldDecorator('files', {
|
||||
rules: [{ required: visible, message: "请上传文件" }],
|
||||
validateFirst: true
|
||||
})(<Input style={{ display: 'none' }} />)}
|
||||
</Form.Item>
|
||||
</Modal>
|
||||
|
||||
)
|
||||
}
|
||||
)
|