new version
This commit is contained in:
parent
ed778853ca
commit
62be5c0388
|
@ -30,6 +30,72 @@
|
||||||
<div class="content unicode" style="display: block;">
|
<div class="content unicode" style="display: block;">
|
||||||
<ul class="icon_lists dib-box">
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">TAR</div>
|
||||||
|
<div class="code-name">&#xe75e;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">ZIP</div>
|
||||||
|
<div class="code-name">&#xe75d;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">文件夹</div>
|
||||||
|
<div class="code-name">&#xe75c;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">文件</div>
|
||||||
|
<div class="code-name">&#xe75b;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">下载</div>
|
||||||
|
<div class="code-name">&#xe75a;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">复制</div>
|
||||||
|
<div class="code-name">&#xe759;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">仓库</div>
|
||||||
|
<div class="code-name">&#xe758;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">贡献者</div>
|
||||||
|
<div class="code-name">&#xe757;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">发行版</div>
|
||||||
|
<div class="code-name">&#xe755;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">标签</div>
|
||||||
|
<div class="code-name">&#xe754;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">分支</div>
|
||||||
|
<div class="code-name">&#xe753;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dib">
|
<li class="dib">
|
||||||
<span class="icon iconfont"></span>
|
<span class="icon iconfont"></span>
|
||||||
<div class="name">项目类别</div>
|
<div class="name">项目类别</div>
|
||||||
|
@ -2228,6 +2294,105 @@
|
||||||
<div class="content font-class">
|
<div class="content font-class">
|
||||||
<ul class="icon_lists dib-box">
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-TAR"></span>
|
||||||
|
<div class="name">
|
||||||
|
TAR
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-TAR
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-ZIP"></span>
|
||||||
|
<div class="name">
|
||||||
|
ZIP
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-ZIP
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-wenjianjia1"></span>
|
||||||
|
<div class="name">
|
||||||
|
文件夹
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-wenjianjia1
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-wenjia"></span>
|
||||||
|
<div class="name">
|
||||||
|
文件
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-wenjia
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-xiazai2"></span>
|
||||||
|
<div class="name">
|
||||||
|
下载
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-xiazai2
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-fuzhi5"></span>
|
||||||
|
<div class="name">
|
||||||
|
复制
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-fuzhi5
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-cangku"></span>
|
||||||
|
<div class="name">
|
||||||
|
仓库
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-cangku
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-gongxianzhe"></span>
|
||||||
|
<div class="name">
|
||||||
|
贡献者
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-gongxianzhe
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-fahangban"></span>
|
||||||
|
<div class="name">
|
||||||
|
发行版
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-fahangban
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-biaoqian3"></span>
|
||||||
|
<div class="name">
|
||||||
|
标签
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-biaoqian3
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-fenzhi1"></span>
|
||||||
|
<div class="name">
|
||||||
|
分支
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-fenzhi1
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dib">
|
<li class="dib">
|
||||||
<span class="icon iconfont icon-xiangmuleibie"></span>
|
<span class="icon iconfont icon-xiangmuleibie"></span>
|
||||||
<div class="name">
|
<div class="name">
|
||||||
|
@ -5479,6 +5644,94 @@
|
||||||
<div class="content symbol">
|
<div class="content symbol">
|
||||||
<ul class="icon_lists dib-box">
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-TAR"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">TAR</div>
|
||||||
|
<div class="code-name">#icon-TAR</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-ZIP"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">ZIP</div>
|
||||||
|
<div class="code-name">#icon-ZIP</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-wenjianjia1"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">文件夹</div>
|
||||||
|
<div class="code-name">#icon-wenjianjia1</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-wenjia"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">文件</div>
|
||||||
|
<div class="code-name">#icon-wenjia</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-xiazai2"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">下载</div>
|
||||||
|
<div class="code-name">#icon-xiazai2</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-fuzhi5"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">复制</div>
|
||||||
|
<div class="code-name">#icon-fuzhi5</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-cangku"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">仓库</div>
|
||||||
|
<div class="code-name">#icon-cangku</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-gongxianzhe"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">贡献者</div>
|
||||||
|
<div class="code-name">#icon-gongxianzhe</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-fahangban"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">发行版</div>
|
||||||
|
<div class="code-name">#icon-fahangban</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-biaoqian3"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">标签</div>
|
||||||
|
<div class="code-name">#icon-biaoqian3</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-fenzhi1"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">分支</div>
|
||||||
|
<div class="code-name">#icon-fenzhi1</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dib">
|
<li class="dib">
|
||||||
<svg class="icon svg-icon" aria-hidden="true">
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
<use xlink:href="#icon-xiangmuleibie"></use>
|
<use xlink:href="#icon-xiangmuleibie"></use>
|
||||||
|
|
|
@ -2475,7 +2475,10 @@ a.color-grey-c:hover {
|
||||||
.color-blue {
|
.color-blue {
|
||||||
color: #4CACFF !important;
|
color: #4CACFF !important;
|
||||||
}
|
}
|
||||||
|
/* 绿色 */
|
||||||
|
.color-green-file{
|
||||||
|
color: #28BD6C;
|
||||||
|
}
|
||||||
/*主*/
|
/*主*/
|
||||||
.color-blue_4C {
|
.color-blue_4C {
|
||||||
color: #4CACFF !important;
|
color: #4CACFF !important;
|
||||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -5,6 +5,83 @@
|
||||||
"css_prefix_text": "icon-",
|
"css_prefix_text": "icon-",
|
||||||
"description": "",
|
"description": "",
|
||||||
"glyphs": [
|
"glyphs": [
|
||||||
|
{
|
||||||
|
"icon_id": "14776069",
|
||||||
|
"name": "TAR",
|
||||||
|
"font_class": "TAR",
|
||||||
|
"unicode": "e75e",
|
||||||
|
"unicode_decimal": 59230
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "14776044",
|
||||||
|
"name": "ZIP",
|
||||||
|
"font_class": "ZIP",
|
||||||
|
"unicode": "e75d",
|
||||||
|
"unicode_decimal": 59229
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "14706564",
|
||||||
|
"name": "文件夹",
|
||||||
|
"font_class": "wenjianjia1",
|
||||||
|
"unicode": "e75c",
|
||||||
|
"unicode_decimal": 59228
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "14706563",
|
||||||
|
"name": "文件",
|
||||||
|
"font_class": "wenjia",
|
||||||
|
"unicode": "e75b",
|
||||||
|
"unicode_decimal": 59227
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "14706484",
|
||||||
|
"name": "下载",
|
||||||
|
"font_class": "xiazai2",
|
||||||
|
"unicode": "e75a",
|
||||||
|
"unicode_decimal": 59226
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "14706480",
|
||||||
|
"name": "复制",
|
||||||
|
"font_class": "fuzhi5",
|
||||||
|
"unicode": "e759",
|
||||||
|
"unicode_decimal": 59225
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "14706430",
|
||||||
|
"name": "仓库",
|
||||||
|
"font_class": "cangku",
|
||||||
|
"unicode": "e758",
|
||||||
|
"unicode_decimal": 59224
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "14706421",
|
||||||
|
"name": "贡献者",
|
||||||
|
"font_class": "gongxianzhe",
|
||||||
|
"unicode": "e757",
|
||||||
|
"unicode_decimal": 59223
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "14706420",
|
||||||
|
"name": "发行版",
|
||||||
|
"font_class": "fahangban",
|
||||||
|
"unicode": "e755",
|
||||||
|
"unicode_decimal": 59221
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "14706416",
|
||||||
|
"name": "标签",
|
||||||
|
"font_class": "biaoqian3",
|
||||||
|
"unicode": "e754",
|
||||||
|
"unicode_decimal": 59220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "14706413",
|
||||||
|
"name": "分支",
|
||||||
|
"font_class": "fenzhi1",
|
||||||
|
"unicode": "e753",
|
||||||
|
"unicode_decimal": 59219
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"icon_id": "14599181",
|
"icon_id": "14599181",
|
||||||
"name": "项目类别",
|
"name": "项目类别",
|
||||||
|
|
|
@ -20,6 +20,39 @@ Created by iconfont
|
||||||
/>
|
/>
|
||||||
<missing-glyph />
|
<missing-glyph />
|
||||||
|
|
||||||
|
<glyph glyph-name="TAR" unicode="" d="M916.945455-109.381818H139.636364c-69.818182 0-130.327273 55.854545-130.327273 130.327273V756.363636C9.309091 826.181818 65.163636 886.690909 139.636364 886.690909h572.509091l330.472727-302.545454v-563.2c0-69.818182-55.854545-130.327273-125.672727-130.327273zM139.636364 812.218182c-32.581818 0-55.854545-23.272727-55.854546-55.854546v-735.418181c0-32.581818 27.927273-55.854545 55.854546-55.854546h777.309091c32.581818 0 55.854545 27.927273 55.854545 55.854546V551.563636l-288.581818 260.654546H139.636364zM1010.036364 556.218182h-344.436364V849.454545h69.818182v-223.418181h274.618182zM386.327273 356.072727h-93.090909v-293.236363h-37.236364v293.236363h-93.090909v37.236364h228.072727v-37.236364zM660.945455 67.490909h-41.89091l-32.581818 93.090909h-139.636363l-32.581819-93.090909H372.363636l125.672728 325.818182h37.236363l125.672728-325.818182z m-88.436364 125.672727l-51.2 139.636364c0 4.654545-4.654545 13.963636-4.654546 23.272727 0-9.309091-4.654545-18.618182-4.654545-23.272727l-51.2-139.636364h111.709091zM940.218182 67.490909h-46.545455l-55.854545 93.090909c-4.654545 9.309091-9.309091 13.963636-13.963637 23.272727l-13.963636 13.963637c-4.654545 4.654545-9.309091 4.654545-13.963636 9.309091-4.654545 0-13.963636 4.654545-18.618182 4.654545H744.727273v-139.636363h-37.236364v325.818181h97.745455c13.963636 0 27.927273 0 37.236363-4.654545 13.963636-4.654545 23.272727-9.309091 32.581818-13.963636 9.309091-9.309091 13.963636-18.618182 18.618182-27.927273 4.654545-9.309091 9.309091-23.272727 9.309091-37.236364 0-9.309091 0-23.272727-4.654545-32.581818-4.654545-9.309091-9.309091-18.618182-13.963637-23.272727-4.654545-9.309091-13.963636-13.963636-23.272727-18.618182l-27.927273-13.963636c4.654545-4.654545 9.309091-4.654545 13.963637-9.309091 4.654545-4.654545 9.309091-4.654545 9.309091-9.309091s9.309091-9.309091 9.309091-13.963637c4.654545-4.654545 9.309091-9.309091 13.963636-18.618181l60.509091-107.054546zM744.727273 356.072727v-116.363636h51.2c9.309091 0 18.618182 0 27.927272 4.654545 9.309091 4.654545 13.963636 9.309091 23.272728 13.963637 4.654545 4.654545 9.309091 13.963636 13.963636 18.618182 4.654545 9.309091 4.654545 18.618182 4.654546 27.927272 0 18.618182-4.654545 32.581818-18.618182 41.890909-9.309091 9.309091-27.927273 13.963636-51.2 13.963637H744.727273z" horiz-adv-x="1070" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="ZIP" unicode="" d="M916.945455-109.381818H139.636364c-69.818182 0-130.327273 55.854545-130.327273 130.327273V756.363636C9.309091 826.181818 65.163636 886.690909 139.636364 886.690909h572.509091l330.472727-302.545454v-563.2c0-69.818182-55.854545-130.327273-125.672727-130.327273zM139.636364 812.218182c-32.581818 0-55.854545-23.272727-55.854546-55.854546v-735.418181c0-32.581818 27.927273-55.854545 55.854546-55.854546h777.309091c32.581818 0 55.854545 27.927273 55.854545 55.854546V551.563636l-288.581818 260.654546H139.636364zM1010.036364 556.218182h-344.436364V849.454545h69.818182v-223.418181h274.618182zM456.145455 384l-190.836364-283.927273h186.181818v-32.581818H209.454545v9.309091l190.836364 279.272727H223.418182v37.236364h232.727273v-9.309091zM544.581818 67.490909h-37.236363v325.818182h37.236363v-325.818182zM670.254545 188.509091v-121.018182h-37.236363v325.818182h88.436363c32.581818 0 60.509091-9.309091 79.127273-23.272727 18.618182-18.618182 27.927273-41.890909 27.927273-69.818182s-9.309091-55.854545-32.581818-74.472727c-23.272727-18.618182-51.2-27.927273-88.436364-27.927273h-37.236364z m0 167.563636v-134.981818h41.89091c27.927273 0 46.545455 4.654545 60.50909 18.618182 13.963636 13.963636 18.618182 27.927273 18.618182 51.2 0 41.890909-23.272727 65.163636-74.472727 65.163636h-46.545455z" horiz-adv-x="1070" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="wenjianjia1" unicode="" d="M529.709176 896a12.047059 12.047059 0 0 0 7.228236-2.409412l129.204706-97.219764h280.877176a120.470588 120.470588 0 0 0 120.470588-120.470589v-605.665882a120.470588 120.470588 0 0 0-120.470588-120.470588H120.470588a120.470588 120.470588 0 0 0-120.470588 120.470588V835.764706a60.235294 60.235294 0 0 0 60.235294 60.235294h469.473882z m357.376-197.150118H98.605176v-591.390117h788.48V698.849882zM0 600.244706h1084.235294v-599.582118a90.352941 90.352941 0 0 0-90.352941-90.352941h-903.529412a90.352941 90.352941 0 0 0-90.352941 90.352941V600.304941z" horiz-adv-x="1084" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="wenjia" unicode="" d="M824.888889-128H199.111111c-62.577778 0-113.777778 51.2-113.777778 113.777778V782.222222C85.333333 844.8 136.533333 896 199.111111 896h506.311111L938.666667 651.377778V-14.222221999999988c0-62.577778-51.2-113.777778-113.777778-113.777778zM199.111111 810.666667c-17.066667 0-28.444444-11.377778-28.444444-28.444445v-796.444444c0-17.066667 11.377778-28.444444 28.444444-28.444445h625.777778c17.066667 0 28.444444 11.377778 28.444444 28.444445V617.2444439999999l-182.044444 193.422223H199.111111zM739.555556 99.55555600000002h-455.111112c-17.066667 0-28.444444 11.377778-28.444444 28.444444s11.377778 28.444444 28.444444 28.444444h455.111112c17.066667 0 28.444444-11.377778 28.444444-28.444444s-11.377778-28.444444-28.444444-28.444444zM625.777778 554.666667h-341.333334c-17.066667 0-28.444444 11.377778-28.444444 28.444444s11.377778 28.444444 28.444444 28.444445h341.333334c17.066667 0 28.444444-11.377778 28.444444-28.444445s-11.377778-28.444444-28.444444-28.444444zM739.555556 327.11111100000005h-455.111112c-17.066667 0-28.444444 11.377778-28.444444 28.444445s11.377778 28.444444 28.444444 28.444444h455.111112c17.066667 0 28.444444-11.377778 28.444444-28.444444s-11.377778-28.444444-28.444444-28.444445z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="xiazai2" unicode="" d="M602.352941 155.105882c-24.094118 0-48.188235 18.070588-48.188235 48.188236V835.764706c0 24.094118 18.070588 48.188235 48.188235 48.188235s48.188235-24.094118 48.188235-48.188235v-638.494118c0-24.094118-18.070588-42.164706-48.188235-42.164706zM602.352941 137.035294L222.870588 486.4c-18.070588 12.047059-18.070588 42.164706-6.023529 60.235294 18.070588 18.070588 48.188235 18.070588 66.258823 6.02353l319.247059-295.152942 325.270588 289.129412c18.070588 18.070588 48.188235 18.070588 66.258824-6.023529 18.070588-18.070588 18.070588-48.188235-6.023529-66.258824L602.352941 137.035294zM1017.976471-109.929412H180.705882c-90.352941 0-168.658824 72.282353-168.658823 168.658824v186.729412c0 24.094118 18.070588 48.188235 48.188235 48.188235s48.188235-18.070588 48.188235-48.188235v-186.729412c0-42.164706 36.141176-72.282353 72.282353-72.282353h837.270589c42.164706 0 72.282353 36.141176 72.282353 72.282353v186.729412c0 24.094118 18.070588 48.188235 48.188235 48.188235s48.188235-18.070588 48.188235-48.188235v-186.729412c0-90.352941-78.305882-168.658824-168.658823-168.658824z" horiz-adv-x="1204" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="fuzhi5" unicode="" d="M939.670588 149.082353H481.882353c-90.352941 0-168.658824 72.282353-168.658824 168.658823V727.341176C313.223529 823.717647 391.529412 896 481.882353 896h457.788235c90.352941 0 168.658824-72.282353 168.658824-168.658824v-415.623529c-6.023529-90.352941-78.305882-162.635294-168.658824-162.635294zM481.882353 805.647059c-42.164706 0-72.282353-36.141176-72.282353-72.282353v-415.62353c0-42.164706 36.141176-72.282353 72.282353-72.282352h457.788235c42.164706 0 72.282353 36.141176 72.282353 72.282352V727.341176c0 42.164706-36.141176 72.282353-72.282353 72.282353H481.882353zM728.847059-91.858824h-602.352941c-60.235294 0-108.423529 42.164706-108.42353 102.4V649.035294c0 54.211765 48.188235 102.4 108.42353 102.4h108.423529V655.058824H126.494118c-12.047059 0-18.070588-6.023529-18.070589-6.02353v-638.494118c0-6.023529 6.023529-12.047059 18.070589-12.047058h602.352941c12.047059 0 18.070588 6.023529 18.070588 12.047058v90.352942h90.352941v-90.352942c0-54.211765-48.188235-102.4-108.423529-102.4z" horiz-adv-x="1144" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="cangku" unicode="" d="M512-128C246.964706-128 36.141176-1.505882 36.141176 155.105882c0 42.164706 12.047059 78.305882 42.164706 120.470589l78.305883-60.235295c-12.047059-18.070588-24.094118-42.164706-24.094118-60.235294 0-90.352941 156.611765-186.729412 379.482353-186.729411 222.870588 0 379.482353 96.376471 379.482353 186.729411 0 18.070588-6.023529 36.141176-18.070588 54.211765l78.305882 54.211765c24.094118-36.141176 36.141176-66.258824 36.141177-108.42353 0-156.611765-210.823529-283.105882-475.858824-283.105882zM512 131.011765c-265.035294 0-475.858824 120.470588-475.858824 271.058823 0 48.188235 24.094118 96.376471 66.258824 138.541177L168.658824 474.352941c-24.094118-24.094118-36.141176-48.188235-36.141177-72.282353 0-84.329412 156.611765-174.682353 379.482353-174.682353 222.870588 0 379.482353 90.352941 379.482353 174.682353 0 36.141176-24.094118 60.235294-48.188235 78.305883l60.235294 72.282353c54.211765-42.164706 84.329412-96.376471 84.329412-156.611765 0-144.564706-210.823529-265.035294-475.858824-265.035294zM512 359.905882c-271.058824 0-481.882353 120.470588-481.882353 265.035294S240.941176 896 512 896s481.882353-120.470588 481.882353-265.035294-210.823529-271.058824-481.882353-271.058824z m0 439.717647c-228.894118 0-385.505882-90.352941-385.505882-168.658823S283.105882 456.282353 512 456.282353c228.894118 0 385.505882 90.352941 385.505882 168.658823S740.894118 799.623529 512 799.623529z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="gongxianzhe" unicode="" d="M498.346667 254.293333C341.333333 254.293333 211.626667 377.173333 211.626667 541.013333S341.333333 827.733333 498.346667 827.733333s286.72-129.706667 286.72-286.72-122.88-286.72-286.72-286.72z m0 464.213334c-95.573333 0-177.493333-81.92-177.493334-177.493334s81.92-177.493333 177.493334-177.493333S682.666667 438.613333 682.666667 541.013333 600.746667 718.506667 498.346667 718.506667zM885.282133 260.846933v109.226667c95.573333 0 177.493333 81.92 177.493334 177.493333s-81.92 177.493333-177.493334 177.493334v109.226666c157.013333 0 286.72-129.706667 286.72-286.72s-129.706667-286.72-286.72-286.72zM1212.962133 15.086933c-20.48 163.84-163.84 286.72-327.68 286.72v109.226667c218.453333 0 402.773333-163.84 436.906667-375.466667l-109.226667-20.48zM880.64-121.173333c-27.306667 211.626667-191.146667 368.64-375.466667 368.64s-348.16-157.013333-375.466666-368.64l-109.226667 13.653333c34.133333 259.413333 245.76 464.213333 484.693333 464.213333s450.56-197.973333 484.693334-464.213333l-109.226667-13.653333z" horiz-adv-x="1365" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="fahangban" unicode="" d="M881.777778-93.866667l-318.577778 170.666667 45.511111 79.644444 199.111111-108.088888 68.266667 665.6L204.8 435.2l142.222222-113.777778-56.888889-73.955555L22.755556 463.644444 984.177778 850.488889zM466.488889-25.6H375.466667v261.688889l517.688889 574.577778 68.266666-56.888889-494.933333-551.822222z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="biaoqian3" unicode="" d="M597.333333-76.8c-34.133333 0-68.266667 11.377778-91.022222 34.133333L5.688889 418.133333 79.644444 878.933333h438.044445l426.666667-455.111111c45.511111-51.2 51.2-130.844444 0-182.044444l-244.622223-278.755556c-22.755556-22.755556-56.888889-39.822222-102.4-39.822222 5.688889 0 5.688889 0 0 0zM108.088889 457.955556L568.888889 25.6c11.377778-5.688889 17.066667-11.377778 34.133333-11.377778 11.377778 0 22.755556 5.688889 34.133334 17.066667l244.622222 278.755555c17.066667 17.066667 17.066667 45.511111 0 62.577778L483.555556 799.288889H159.288889l-51.2-341.333333zM398.222222 543.288889m-113.777778 0a113.777778 113.777778 0 1 1 227.555556 0 113.777778 113.777778 0 1 1-227.555556 0Z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
|
<glyph glyph-name="fenzhi1" unicode="" d="M267.377778 531.911111C164.977778 531.911111 85.333333 611.555556 85.333333 713.955556S164.977778 896 267.377778 896s182.044444-79.644444 182.044444-182.044444S369.777778 531.911111 267.377778 531.911111z m0 273.066667c-51.2 0-91.022222-39.822222-91.022222-91.022222s39.822222-91.022222 91.022222-91.022223 91.022222 39.822222 91.022222 91.022223-39.822222 91.022222-91.022222 91.022222zM267.377778-105.244444c-102.4 0-182.044444 79.644444-182.044445 182.044444s79.644444 182.044444 182.044445 182.044444 182.044444-79.644444 182.044444-182.044444-79.644444-182.044444-182.044444-182.044444z m0 273.066666c-51.2 0-91.022222-39.822222-91.022222-91.022222 0-51.2 39.822222-91.022222 91.022222-91.022222s91.022222 39.822222 91.022222 91.022222c0 51.2-39.822222 91.022222-91.022222 91.022222zM750.933333 213.333333C665.6 213.333333 597.333333 281.6 597.333333 366.933333c0 85.333333 68.266667 153.6 153.6 153.6 85.333333 0 153.6-68.266667 153.6-153.6 0-85.333333-68.266667-153.6-153.6-153.6z m0 216.177778c-34.133333 0-62.577778-28.444444-62.577777-62.577778 0-34.133333 28.444444-62.577778 62.577777-62.577777s62.577778 28.444444 62.577778 62.577777c0 34.133333-28.444444 62.577778-62.577778 62.577778zM194.446222 160.995556l5.802667 432.298666 91.022222-1.251555-5.802667-432.355556zM330.524444 590.734222l50.801778 75.548445 287.971556-193.649778-50.801778-75.548445z" horiz-adv-x="1024" />
|
||||||
|
|
||||||
|
|
||||||
<glyph glyph-name="xiangmuleibie" unicode="" d="M542.117647 317.741176c-6.023529 0-12.047059 0-18.070588 6.02353l-481.882353 246.964706C24.094118 576.752941 12.047059 594.823529 12.047059 612.894118c0 18.070588 12.047059 30.117647 24.094117 42.164706L505.976471 877.929412c12.047059 6.023529 24.094118 6.023529 42.164705 0l493.929412-234.917647c18.070588-6.023529 24.094118-24.094118 24.094118-42.164706s-12.047059-30.117647-24.094118-42.164706L566.211765 323.764706c-6.023529-6.023529-18.070588-6.023529-24.094118-6.02353zM162.635294 612.894118L542.117647 414.117647l373.458824 186.729412-385.505883 186.729412-367.435294-174.682353zM542.117647 124.988235c-6.023529 0-12.047059 0-18.070588 6.02353L42.164706 353.882353C18.070588 365.929412 12.047059 390.023529 18.070588 414.117647s36.141176 30.117647 60.235294 24.094118l457.788236-216.847059 457.788235 240.941176c24.094118 12.047059 48.188235 6.023529 60.235294-18.070588 12.047059-24.094118 6.023529-48.188235-18.070588-60.235294l-481.882353-252.988235s-6.023529-6.023529-12.047059-6.02353zM542.117647-85.835294c-6.023529 0-12.047059 0-18.070588 6.023529l-481.882353 222.870589c-24.094118 12.047059-30.117647 36.141176-24.094118 60.235294 12.047059 24.094118 36.141176 30.117647 60.235294 24.094117l457.788236-216.847059 457.788235 240.941177c24.094118 12.047059 48.188235 6.023529 60.235294-18.070588 12.047059-24.094118 6.023529-48.188235-18.070588-60.235294l-481.882353-252.988236c0-6.023529-6.023529-6.023529-12.047059-6.023529z" horiz-adv-x="1084" />
|
<glyph glyph-name="xiangmuleibie" unicode="" d="M542.117647 317.741176c-6.023529 0-12.047059 0-18.070588 6.02353l-481.882353 246.964706C24.094118 576.752941 12.047059 594.823529 12.047059 612.894118c0 18.070588 12.047059 30.117647 24.094117 42.164706L505.976471 877.929412c12.047059 6.023529 24.094118 6.023529 42.164705 0l493.929412-234.917647c18.070588-6.023529 24.094118-24.094118 24.094118-42.164706s-12.047059-30.117647-24.094118-42.164706L566.211765 323.764706c-6.023529-6.023529-18.070588-6.023529-24.094118-6.02353zM162.635294 612.894118L542.117647 414.117647l373.458824 186.729412-385.505883 186.729412-367.435294-174.682353zM542.117647 124.988235c-6.023529 0-12.047059 0-18.070588 6.02353L42.164706 353.882353C18.070588 365.929412 12.047059 390.023529 18.070588 414.117647s36.141176 30.117647 60.235294 24.094118l457.788236-216.847059 457.788235 240.941176c24.094118 12.047059 48.188235 6.023529 60.235294-18.070588 12.047059-24.094118 6.023529-48.188235-18.070588-60.235294l-481.882353-252.988235s-6.023529-6.023529-12.047059-6.02353zM542.117647-85.835294c-6.023529 0-12.047059 0-18.070588 6.023529l-481.882353 222.870589c-24.094118 12.047059-30.117647 36.141176-24.094118 60.235294 12.047059 24.094118 36.141176 30.117647 60.235294 24.094117l457.788236-216.847059 457.788235 240.941177c24.094118 12.047059 48.188235 6.023529 60.235294-18.070588 12.047059-24.094118 6.023529-48.188235-18.070588-60.235294l-481.882353-252.988236c0-6.023529-6.023529-6.023529-12.047059-6.023529z" horiz-adv-x="1084" />
|
||||||
|
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 438 KiB After Width: | Height: | Size: 450 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -17573,7 +17573,7 @@ Copyright © 2018 Basecamp, LLC
|
||||||
|
|
||||||
var actualPadding = document.body.style.paddingRight;
|
var actualPadding = document.body.style.paddingRight;
|
||||||
var calculatedPadding = $(document.body).css('padding-right');
|
var calculatedPadding = $(document.body).css('padding-right');
|
||||||
$(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px");
|
// $(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px");
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document.body).addClass(ClassName.OPEN);
|
$(document.body).addClass(ClassName.OPEN);
|
||||||
|
@ -17597,9 +17597,9 @@ Copyright © 2018 Basecamp, LLC
|
||||||
}
|
}
|
||||||
}); // Restore body padding
|
}); // Restore body padding
|
||||||
|
|
||||||
var padding = $(document.body).data('padding-right');
|
// var padding = $(document.body).data('padding-right');
|
||||||
$(document.body).removeData('padding-right');
|
// $(document.body).removeData('padding-right');
|
||||||
document.body.style.paddingRight = padding ? padding : '';
|
// document.body.style.paddingRight = padding ? padding : '';
|
||||||
};
|
};
|
||||||
|
|
||||||
_proto._getScrollbarWidth = function _getScrollbarWidth() {
|
_proto._getScrollbarWidth = function _getScrollbarWidth() {
|
||||||
|
|
|
@ -19,14 +19,14 @@ class CloneAddress extends Component {
|
||||||
}
|
}
|
||||||
<input type="text" id="copy_rep_content" value={http_url} />
|
<input type="text" id="copy_rep_content" value={http_url} />
|
||||||
<Tooltip title="复制链接">
|
<Tooltip title="复制链接">
|
||||||
<span onClick={() => this.jsCopy()}><i className="iconfont icon-fuzhi"></i></span>
|
<span className="color-blue" onClick={() => this.jsCopy()}><i className="iconfont icon-fuzhi"></i></span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{
|
{
|
||||||
downloadUrl &&
|
downloadUrl &&
|
||||||
<span>
|
<span>
|
||||||
<Dropdown overlay={downloadUrl} trigger={['click']} placement="bottomRight">
|
<Dropdown overlay={downloadUrl} trigger={['click']} placement="bottomRight">
|
||||||
<a className="ant-dropdown-link">
|
<a className="ant-dropdown-link">
|
||||||
<Icon type="cloud-download" className="font-18 fl" />
|
<Icon type="cloud-download" className="font-18 fl color-blue" />
|
||||||
</a>
|
</a>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -63,7 +63,9 @@ class SelectBranch extends Component{
|
||||||
let branchsFilter = value ? (branchs && branchs.length>0 && branchs.filter(item=>item.name.indexOf(value)>-1)):branchs;
|
let branchsFilter = value ? (branchs && branchs.length>0 && branchs.filter(item=>item.name.indexOf(value)>-1)):branchs;
|
||||||
const menu = (
|
const menu = (
|
||||||
<div className="branchOptions" id="m-btn" onClick={this.stopPropagations}>
|
<div className="branchOptions" id="m-btn" onClick={this.stopPropagations}>
|
||||||
<Input placeholder="请输入分支名称进行搜索" autocomplete="off" id="input-btn" value={value} className="OptionsInput" onChange={this.changeValue} onClick={this.InputClick}/>
|
<div className="padding10 bor-bottom-greyE">
|
||||||
|
<Input placeholder="请输入分支名称进行搜索" autocomplete="off" id="input-btn" value={value} className="OptionsInput" onChange={this.changeValue} onClick={this.InputClick}/>
|
||||||
|
</div>
|
||||||
<ul className="OptionsUl" id="ul-btn">
|
<ul className="OptionsUl" id="ul-btn">
|
||||||
{
|
{
|
||||||
branchsFilter && branchsFilter.map((item,key)=>{
|
branchsFilter && branchsFilter.map((item,key)=>{
|
||||||
|
@ -79,10 +81,13 @@ class SelectBranch extends Component{
|
||||||
<div className="branchDropdown f-wrap-alignCenter" onClick={()=>this.ChangeVisible(visible)}>
|
<div className="branchDropdown f-wrap-alignCenter" onClick={()=>this.ChangeVisible(visible)}>
|
||||||
<Dropdown overlay={menu} trigger={['click']} placement="bottomLeft" visible={visible}>
|
<Dropdown overlay={menu} trigger={['click']} placement="bottomLeft" visible={visible}>
|
||||||
<span>
|
<span>
|
||||||
<span className="color-grey-9 mr3"><i className="iconfont icon-fenzhi font-20 color-grey-6 mr3"></i>分支:</span>
|
<span>
|
||||||
<a className="ant-dropdown-link">
|
<span className="color-grey-9 mr3">分支:</span>
|
||||||
{branch} <Icon type="down" />
|
<a className="ant-dropdown-link">
|
||||||
</a>
|
{branch}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
<Icon type="down" />
|
||||||
</span>
|
</span>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,37 +3,40 @@
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 35px;
|
height: 40px;
|
||||||
line-height: 35px;
|
line-height: 40px;
|
||||||
min-width: 150px;
|
min-width: 220px;
|
||||||
}
|
}
|
||||||
.branchDropdown .ant-dropdown-trigger{
|
.branchDropdown .ant-dropdown-trigger{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
|
||||||
padding:0px 15px;
|
padding:0px 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.branchOptions{
|
.branchOptions{
|
||||||
width: 200px;
|
width: 220px;
|
||||||
padding:10px;
|
|
||||||
box-shadow: 0px 0px 1px 1px rgba(134, 134, 134, 0.1);
|
box-shadow: 0px 0px 1px 1px rgba(134, 134, 134, 0.1);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
}
|
}
|
||||||
.OptionsUl{
|
.OptionsUl{
|
||||||
max-height: 200px;
|
max-height: 220px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
margin-top: 10px;
|
|
||||||
}
|
}
|
||||||
.OptionsUl li{
|
.OptionsUl li{
|
||||||
height: 30px;
|
height: 35px;
|
||||||
/*line-height: 22px;*/
|
line-height: 35px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
padding:0px 10px;
|
||||||
|
}
|
||||||
|
.OptionsUl li:hover{
|
||||||
|
background-color: #F0F0F0;
|
||||||
}
|
}
|
||||||
.OptionsUl li a{
|
.OptionsUl li a{
|
||||||
display: block;
|
display: block;
|
||||||
padding: 4px;
|
|
||||||
/*padding-left: 2px;*/
|
|
||||||
}
|
}
|
||||||
.OptionsInput{
|
.OptionsInput{
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
|
|
@ -28,15 +28,15 @@ class CoderRootBranch extends Component {
|
||||||
<li key={key}>
|
<li key={key}>
|
||||||
<div>
|
<div>
|
||||||
<Link to={`/projects/${projectsId}/coders?branch=${item.name}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
|
<Link to={`/projects/${projectsId}/coders?branch=${item.name}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
|
||||||
<p className="f-wrap-alignCenter">
|
<p className="f-wrap-alignCenter mt15">
|
||||||
<span className="mr5 color-blue">{item.last_commit && truncateCommitId(item.last_commit.id)}</span>
|
<span className="mr5 commitKey" style={{marginLeft:0}}>{item.last_commit && truncateCommitId(item.last_commit.id)}</span>
|
||||||
<span className="color-grey-9 hide-1 messages leftPoint">{item.last_commit && item.last_commit.message}</span>
|
<span className="color-grey-3 hide-1 messages leftPoint">{item.last_commit && item.last_commit.message}</span>
|
||||||
<span className="color-grey-6 leftPoint">最后更新于{item.last_commit && item.last_commit.time_from_now}</span>
|
<span className="color-grey-8 ml30">最后更新于{item.last_commit && item.last_commit.time_from_now}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<span>
|
<span>
|
||||||
<Link to={`/projects/${projectsId}/merge/new`} className="mr20 operationBtn">创建合并请求</Link>
|
<Link to={`/projects/${projectsId}/merge/new`} className="mr20 color-blue mr30">创建合并请求</Link>
|
||||||
<Dropdown overlay={menu(item.zip_url,item.tar_url)} trigger={['click']} placement="bottomRight" className="operationBtn">
|
<Dropdown overlay={menu(item.zip_url,item.tar_url)} trigger={['click']} placement="bottomRight" className="color-green-file">
|
||||||
<a className="ant-dropdown-link">
|
<a className="ant-dropdown-link">
|
||||||
<Tooltip title={`下载分支${item.name}`}><Icon type="cloud-download" className="font-18"/></Tooltip>
|
<Tooltip title={`下载分支${item.name}`}><Icon type="cloud-download" className="font-18"/></Tooltip>
|
||||||
</a>
|
</a>
|
||||||
|
@ -58,13 +58,14 @@ class CoderRootBranch extends Component {
|
||||||
</Menu>
|
</Menu>
|
||||||
)
|
)
|
||||||
return(
|
return(
|
||||||
<div>
|
<React.Fragment>
|
||||||
<Top { ...this.props } {...this.state} />
|
<div className="main">
|
||||||
<div className="branchTable">
|
<div className="branchTable">
|
||||||
<p className="branchTitle">分支列表</p>
|
<p className="branchTitle bor-bottom-greyE">分支列表</p>
|
||||||
{list()}
|
{list()}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,39 +81,7 @@ class CoderRootCommit extends Component{
|
||||||
render(){
|
render(){
|
||||||
const { branch , data , dataCount , limit , page , isSpin } = this.state;
|
const { branch , data , dataCount , limit , page , isSpin } = this.state;
|
||||||
const { branchs } = this.props;
|
const { branchs } = this.props;
|
||||||
const columns=[{
|
|
||||||
title:"作者",
|
|
||||||
dataIndex: 'name',
|
|
||||||
width:"10%",
|
|
||||||
render: (text,item) => (
|
|
||||||
<span className="f-wrap-alignCenter">
|
|
||||||
<Link to={`/users/${item.login}/projects`} className="show-user-link">
|
|
||||||
<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr3 radius"/>
|
|
||||||
<label className="hide-1" style={{maxWidth:"75px",'verticalAlign':'middle'}}>{text}</label>
|
|
||||||
</Link>
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
},{
|
|
||||||
title:"SHA",
|
|
||||||
dataIndex: 'sha',
|
|
||||||
render: (text) => (
|
|
||||||
<span className="commitKey">{truncateCommitId(text)}</span>
|
|
||||||
)
|
|
||||||
},{
|
|
||||||
title:"备注",
|
|
||||||
dataIndex: 'message',
|
|
||||||
render: (text) => (
|
|
||||||
<span>{text}</span>
|
|
||||||
)
|
|
||||||
},{
|
|
||||||
title:"提交时间",
|
|
||||||
className:"edu-txt-right",
|
|
||||||
dataIndex: 'time_from_now',
|
|
||||||
render: (text) => (
|
|
||||||
<span>{text}</span>
|
|
||||||
)
|
|
||||||
}]
|
|
||||||
|
|
||||||
const title =()=>{
|
const title =()=>{
|
||||||
return(
|
return(
|
||||||
<div className="f-wrap-between" style={{alignItems:"center"}}>
|
<div className="f-wrap-between" style={{alignItems:"center"}}>
|
||||||
|
@ -132,24 +100,42 @@ class CoderRootCommit extends Component{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(
|
return(
|
||||||
<div>
|
<React.Fragment>
|
||||||
<Top { ...this.props } {...this.state} />
|
<div className="main">
|
||||||
<div className="f-wrap-between mt20">
|
<div className="f-wrap-between">
|
||||||
<SelectBranch branch={branch} branchs={branchs} changeBranch={this.changeBranch}></SelectBranch>
|
<SelectBranch branch={branch} branchs={branchs} changeBranch={this.changeBranch}></SelectBranch>
|
||||||
|
</div>
|
||||||
|
<Spin spinning={isSpin}>
|
||||||
|
<div className="commonBox">
|
||||||
|
<div className="commonBox-title">
|
||||||
|
{title()}
|
||||||
|
</div>
|
||||||
|
<div className="commitList">
|
||||||
|
{
|
||||||
|
data && data.length > 0 && data.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<p className="df">
|
||||||
|
<span className="commitKey" style={{marginLeft:0}}>{truncateCommitId(`${item.sha}`)}</span>
|
||||||
|
<span className="flex1 ml20 font-16 color-grey-3">{item.message}</span>
|
||||||
|
{/* <Link to={''} className="color-blue">浏览代码</Link> */}
|
||||||
|
</p>
|
||||||
|
<p className="f-wrap-alignCenter mt15">
|
||||||
|
<Link to={`/users/${item.login}/projects`} className="show-user-link">
|
||||||
|
<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr15 radius"/>
|
||||||
|
<label className="font-14 color-grey-6" style={{'verticalAlign':'middle'}}>{item.name}:提交于 {item.time_from_now}</label>
|
||||||
|
</Link>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{ Pagination() }
|
||||||
|
</Spin>
|
||||||
</div>
|
</div>
|
||||||
<Spin spinning={isSpin}>
|
</React.Fragment>
|
||||||
<Table
|
|
||||||
className="mt20 wrap-commit-table"
|
|
||||||
columns={columns}
|
|
||||||
dataSource={data}
|
|
||||||
showHeader={false}
|
|
||||||
size="small"
|
|
||||||
pagination={false}
|
|
||||||
title={() => title()}
|
|
||||||
/>
|
|
||||||
{ Pagination() }
|
|
||||||
</Spin>
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,11 +230,11 @@ class CoderRootDirectory extends Component{
|
||||||
return(
|
return(
|
||||||
<div className="commonBox">
|
<div className="commonBox">
|
||||||
<div className="commonBox-title">
|
<div className="commonBox-title">
|
||||||
<span className="mr5"><img src={readme_img} alt="" width="16px"/></span>
|
<span className="mr10"><i className="iconfont icon-xinjianjianliwodejianli font-20 color-grey-9 fl mt3"></i></span>
|
||||||
<span className="commonBox-title-read">{readMeContent[0].name}</span>
|
<span className="commonBox-title-read">{readMeContent[0].name}</span>
|
||||||
{
|
{
|
||||||
permission ?
|
permission ?
|
||||||
<a onClick={()=>this.ChangeFile(readMeFile[0],false)} className="ml20 pull-right"><i className="iconfont icon-bianji font-15 color-grey-6"></i></a>
|
<a onClick={()=>this.ChangeFile(readMeFile[0],false)} className="ml20 pull-right"><i className="iconfont icon-bianji2 font-20 color-blue"></i></a>
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -286,7 +286,7 @@ class CoderRootDirectory extends Component{
|
||||||
width:"100%",
|
width:"100%",
|
||||||
render: (text,item) => (
|
render: (text,item) => (
|
||||||
<a onClick={()=>this.goToSubRoot(item.path)}>
|
<a onClick={()=>this.goToSubRoot(item.path)}>
|
||||||
<i className={ item.type === "file" ? "iconfont icon-zuoye font-15 color-blue mr5":"iconfont icon-wenjian font-15 color-blue mr5"}></i>{text}
|
<i className={ item.type === "file" ? "iconfont icon-wenjian1 font-15 color-green-file mr5":"iconfont color-green-file font-15 color-blue mr5"}></i>{text}
|
||||||
</a>
|
</a>
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -307,8 +307,8 @@ class CoderRootDirectory extends Component{
|
||||||
:""
|
:""
|
||||||
}
|
}
|
||||||
<span className="color-blue flex-1 hide-1">{branchLastCommit.last_commit.message}</span>
|
<span className="color-blue flex-1 hide-1">{branchLastCommit.last_commit.message}</span>
|
||||||
<span className="commitKey">{truncateCommitId(branchLastCommit.last_commit.id)}</span>
|
|
||||||
<span>{branchLastCommit.last_commit.time_from_now}</span>
|
<span>{branchLastCommit.last_commit.time_from_now}</span>
|
||||||
|
<span className="commitKey">{truncateCommitId(branchLastCommit.last_commit.id)}</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}else{
|
}else{
|
||||||
|
@ -332,9 +332,8 @@ class CoderRootDirectory extends Component{
|
||||||
let array = filePath && filePath.split("/");
|
let array = filePath && filePath.split("/");
|
||||||
return(
|
return(
|
||||||
<Spin spinning={isSpin}>
|
<Spin spinning={isSpin}>
|
||||||
<div>
|
<div className="main">
|
||||||
<Top { ...this.props } {...this.state} />
|
<div className="f-wrap-between">
|
||||||
<div className="f-wrap-between mt20">
|
|
||||||
<div className="f-wrap-alignCenter">
|
<div className="f-wrap-alignCenter">
|
||||||
<SelectBranch branch={branch} changeBranch={this.changeBranch} {...this.props} {...this.state}></SelectBranch>
|
<SelectBranch branch={branch} changeBranch={this.changeBranch} {...this.props} {...this.state}></SelectBranch>
|
||||||
|
|
||||||
|
@ -365,8 +364,8 @@ class CoderRootDirectory extends Component{
|
||||||
<div className="f-wrap-alignCenter">
|
<div className="f-wrap-alignCenter">
|
||||||
{
|
{
|
||||||
subFileType && (isManager || isDeveloper) &&
|
subFileType && (isManager || isDeveloper) &&
|
||||||
<p className="addFile mr30">
|
<p className="mr30">
|
||||||
<Link to={`/projects/${projectsId}/coders/${branch}/newfile${urlRoot}`} >新建文件</Link>
|
<Link className="color-blue" to={`/projects/${projectsId}/coders/${branch}/newfile${urlRoot}`} >新建文件</Link>
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -378,7 +377,6 @@ class CoderRootDirectory extends Component{
|
||||||
{
|
{
|
||||||
rootList &&
|
rootList &&
|
||||||
<RootTable columns = {columns} data={rootList} title={() => title()}></RootTable>
|
<RootTable columns = {columns} data={rootList} title={() => title()}></RootTable>
|
||||||
|
|
||||||
}
|
}
|
||||||
{/* 子目录列表、文件 */}
|
{/* 子目录列表、文件 */}
|
||||||
{
|
{
|
||||||
|
|
|
@ -105,8 +105,8 @@ class CoderRootFileDetail extends Component{
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
const { detail , current_user , isManager , isReporter , isDeveloper } = this.props;
|
const { detail , current_user , isManager , isDeveloper } = this.props;
|
||||||
const { readOnly ,value } = this.state;
|
const { readOnly } = this.state;
|
||||||
let flag = current_user && current_user.login && (isManager || isDeveloper);
|
let flag = current_user && current_user.login && (isManager || isDeveloper);
|
||||||
var options = {
|
var options = {
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import React , { Component } from 'react';
|
import React , { Component } from 'react';
|
||||||
import { Route , Switch , Link} from 'react-router-dom';
|
import { Route , Switch } from 'react-router-dom';
|
||||||
|
|
||||||
import Loadable from 'react-loadable';
|
import Loadable from 'react-loadable';
|
||||||
import Loading from '../../Loading';
|
import Loading from '../../Loading';
|
||||||
|
import Top from './DetailTop';
|
||||||
|
|
||||||
|
|
||||||
const CoderRootDirectory = Loadable({
|
const CoderRootDirectory = Loadable({
|
||||||
|
@ -13,27 +14,61 @@ const CoderRootCommit = Loadable({
|
||||||
loader: () => import('./CoderRootCommit'),
|
loader: () => import('./CoderRootCommit'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const CoderRootFileDetail = Loadable({
|
|
||||||
loader: () => import('./CoderRootFileDetail'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
const CoderRootBranch = Loadable({
|
const CoderRootBranch = Loadable({
|
||||||
loader: () => import('./CoderRootBranch'),
|
loader: () => import('./CoderRootBranch'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
const CoderRootTag = Loadable({
|
||||||
|
loader: () => import('./CoderRootTag'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
|
const CoderRootVersion = Loadable({
|
||||||
|
loader: () => import('../Version/version'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
|
const CoderRootVersionNew = Loadable({
|
||||||
|
loader: () => import('../Version/NewVersion'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
|
const CoderRootVersionUpdate = Loadable({
|
||||||
|
loader: () => import('../Version/UpdateVersion'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
|
|
||||||
class CoderRootIndex extends Component{
|
class CoderRootIndex extends Component{
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div className="main">
|
<div>
|
||||||
|
<Top {...this.props} {...this.state}/>
|
||||||
<Switch {...this.props}>
|
<Switch {...this.props}>
|
||||||
<Route path="/projects/:projectsId/coders/commit"
|
<Route path="/projects/:projectsId/coders/commit"
|
||||||
render={
|
render={
|
||||||
(props) => (<CoderRootCommit {...this.props} {...props} {...this.state} />)
|
(props) => (<CoderRootCommit {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
<Route path="/projects/:projectsId/coders/version/new"
|
||||||
|
render={
|
||||||
|
(props) => (<CoderRootVersionNew {...this.props} {...props} {...this.state} />)
|
||||||
|
}
|
||||||
|
></Route>
|
||||||
|
|
||||||
|
<Route path="/projects/:projectsId/coders/version/:versionId/update"
|
||||||
|
render={
|
||||||
|
(props) => (<CoderRootVersionUpdate {...this.props} {...props} {...this.state} />)
|
||||||
|
}
|
||||||
|
></Route>
|
||||||
|
|
||||||
|
<Route path="/projects/:projectsId/coders/version"
|
||||||
|
render={
|
||||||
|
(props) => (<CoderRootVersion {...this.props} {...props} {...this.state} />)
|
||||||
|
}
|
||||||
|
></Route>
|
||||||
|
<Route path="/projects/:projectsId/coders/tag"
|
||||||
|
render={
|
||||||
|
(props) => (<CoderRootTag {...this.props} {...props} {...this.state} />)
|
||||||
|
}
|
||||||
|
></Route>
|
||||||
<Route path="/projects/:projectsId/coders/branch"
|
<Route path="/projects/:projectsId/coders/branch"
|
||||||
render={
|
render={
|
||||||
(props) => (<CoderRootBranch {...this.props} {...props} {...this.state} />)
|
(props) => (<CoderRootBranch {...this.props} {...props} {...this.state} />)
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
import React , { useState, useEffect } from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { Spin } from 'antd';
|
||||||
|
import { truncateCommitId } from '../common/util';
|
||||||
|
|
||||||
|
|
||||||
|
export default ({
|
||||||
|
projectDetail
|
||||||
|
}) => {
|
||||||
|
const [ isSpin , setSpin ] = useState(true);
|
||||||
|
const [ data , setData ] = useState(undefined);
|
||||||
|
|
||||||
|
const repo_id = projectDetail && projectDetail.repo_id;
|
||||||
|
useEffect(()=>{
|
||||||
|
if(repo_id){
|
||||||
|
const url = `/repositories/${repo_id}/tags.json`;
|
||||||
|
axios.get(url).then((result)=>{
|
||||||
|
if(result){
|
||||||
|
setData(result.data);
|
||||||
|
setSpin(false);
|
||||||
|
}
|
||||||
|
}).catch(error=>{
|
||||||
|
console.log(error);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},[repo_id]);
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="main">
|
||||||
|
<Spin spinning={isSpin}>
|
||||||
|
<div className="div_table">
|
||||||
|
<ul className="ul_thead">
|
||||||
|
<li>
|
||||||
|
<span className="flex1">标签名</span>
|
||||||
|
{/* <span>描述</span> */}
|
||||||
|
<span>提交信息</span>
|
||||||
|
<span className="ul_tbody_forth">下载</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul className="ul_tbody">
|
||||||
|
{
|
||||||
|
data && data.length > 0 && data.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
<li>
|
||||||
|
<span className="flex1">
|
||||||
|
<i className="iconfont icon-biaoqian3 font-16 mr5 color-grey-8"></i>
|
||||||
|
<span className="font-16">{item.name}</span>
|
||||||
|
</span>
|
||||||
|
{/* <span className="font-16 task-hide">坎坎坷坷死二无一额坎坎坷坷死二无一额坎坎坷坷死二无一额</span> */}
|
||||||
|
<span className="ul_tbody_third">
|
||||||
|
<span className="commitKey" style={{"marginLeft":0}}>{truncateCommitId(`${item.id}`)}</span>
|
||||||
|
{/* <span>2020-05-18 16:30</span> */}
|
||||||
|
</span>
|
||||||
|
<span className="ul_tbody_forth">
|
||||||
|
<a href={item.tarball_url} style={{color:"#4CC1DA"}} className="mr30"><i className="iconfont icon-TAR font-18 mr5"></i>TAR</a>
|
||||||
|
<a href={item.zipball_url} style={{color:"#28BD6C"}}><i className="iconfont icon-ZIP font-18 mr5"></i>ZIP</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</Spin>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import React , { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Spin , Tooltip } from 'antd';
|
import { Spin, Tooltip } from 'antd';
|
||||||
import { Link , Route , Switch,withRouter } from 'react-router-dom';
|
import { Link, Route, Switch, withRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import '../css/index.css'
|
import '../css/index.css'
|
||||||
import './list.css';
|
import './list.css';
|
||||||
|
@ -23,362 +23,385 @@ import img_focused from '../Images/focused.png';
|
||||||
import img_fork from '../Images/fork.png';
|
import img_fork from '../Images/fork.png';
|
||||||
import img_milepost from '../Images/milepost.png';
|
import img_milepost from '../Images/milepost.png';
|
||||||
const FileNew = Loadable({
|
const FileNew = Loadable({
|
||||||
loader: () => import('../Newfile/Index'),
|
loader: () => import('../Newfile/Index'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const Setting = Loadable({
|
const Setting = Loadable({
|
||||||
loader: () => import('../Settings/Index'),
|
loader: () => import('../Settings/Index'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const TagList = Loadable({
|
const TagList = Loadable({
|
||||||
loader: () => import('../Order/Tags'),
|
loader: () => import('../Order/Tags'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const OrderNew = Loadable({
|
const OrderNew = Loadable({
|
||||||
loader: () => import('../Order/New'),
|
loader: () => import('../Order/New'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const OrderDetail = Loadable({
|
const OrderDetail = Loadable({
|
||||||
loader: () => import('../Order/Detail'),
|
loader: () => import('../Order/Detail'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const OrderIndex = Loadable({
|
const OrderIndex = Loadable({
|
||||||
loader: () => import('../Order/order'),
|
loader: () => import('../Order/order'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const CoderRootIndex = Loadable({
|
const CoderRootIndex = Loadable({
|
||||||
loader: () => import('./CoderRootIndex'),
|
loader: () => import('./CoderRootIndex'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const OrderMilepost = Loadable({
|
const OrderMilepost = Loadable({
|
||||||
loader: () => import('../Order/Milepost'),
|
loader: () => import('../Order/Milepost'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
|
||||||
const OrdernewMilepost = Loadable({
|
const OrdernewMilepost = Loadable({
|
||||||
loader: () => import('../Order/newMilepost'),
|
loader: () => import('../Order/newMilepost'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
|
||||||
const OrderupdateMilepost = Loadable({
|
const OrderupdateMilepost = Loadable({
|
||||||
loader: () => import('../Order/UpdateMilepost'),
|
loader: () => import('../Order/UpdateMilepost'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
|
||||||
const OrderupdateDetail = Loadable({
|
const OrderupdateDetail = Loadable({
|
||||||
loader: () => import('../Order/UpdateDetail'),
|
loader: () => import('../Order/UpdateDetail'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
|
||||||
const OrdercopyDetail = Loadable({
|
const OrdercopyDetail = Loadable({
|
||||||
loader: () => import('../Order/CopyDetail'),
|
loader: () => import('../Order/CopyDetail'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
|
||||||
//合并请求
|
//合并请求
|
||||||
const MergeIndexDetail = Loadable({
|
const MergeIndexDetail = Loadable({
|
||||||
loader: () => import('../Merge/merge'),
|
loader: () => import('../Merge/merge'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
|
||||||
const CreateMerge = Loadable({
|
const CreateMerge = Loadable({
|
||||||
loader: () => import('../Merge/NewMerge'),
|
loader: () => import('../Merge/NewMerge'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
|
||||||
const MessageCount = Loadable({
|
const MessageCount = Loadable({
|
||||||
loader: () => import('../Merge/MessageCount'),
|
loader: () => import('../Merge/MessageCount'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
|
||||||
const MergeSubmit = Loadable({
|
const MergeSubmit = Loadable({
|
||||||
loader: () => import('../Merge/MergeSubmit'),
|
loader: () => import('../Merge/MergeSubmit'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
|
||||||
const UpdateMerge = Loadable({
|
const UpdateMerge = Loadable({
|
||||||
loader: () => import('../Merge/UpdateMerge'),
|
loader: () => import('../Merge/UpdateMerge'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
//版本发布
|
//版本发布
|
||||||
const VersionIndex = Loadable({
|
const VersionIndex = Loadable({
|
||||||
loader: () => import('../Version/version'),
|
loader: () => import('../Version/version'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const NewVersionIndex = Loadable({
|
const NewVersionIndex = Loadable({
|
||||||
loader: () => import('../Version/NewVersion'),
|
loader: () => import('../Version/NewVersion'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const UpVersionIndex = Loadable({
|
const UpVersionIndex = Loadable({
|
||||||
loader: () => import('../Version/UpdateVersion'),
|
loader: () => import('../Version/UpdateVersion'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const MilepostDetail = Loadable({
|
const MilepostDetail = Loadable({
|
||||||
loader: () => import('../Order/MilepostDetail'),
|
loader: () => import('../Order/MilepostDetail'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const TrendsIndex = Loadable({
|
const TrendsIndex = Loadable({
|
||||||
loader: () => import('../Activity/Activity'),
|
loader: () => import('../Activity/Activity'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
/**
|
/**
|
||||||
* permission:Manager:管理员,Reporter:报告人员(只有读取权限),Developer:开发人员(除不能设置仓库信息外)
|
* permission:Manager:管理员,Reporter:报告人员(只有读取权限),Developer:开发人员(除不能设置仓库信息外)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Detail extends Component{
|
class Detail extends Component {
|
||||||
constructor(props){
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state={
|
this.state = {
|
||||||
isSpin:false,
|
isSpin: false,
|
||||||
projectDetail:undefined,
|
projectDetail: undefined,
|
||||||
isManager:false,
|
isManager: false,
|
||||||
isReporter:false,
|
isReporter: false,
|
||||||
isDeveloper:false,
|
isDeveloper: false,
|
||||||
project_id:undefined,
|
project_id: undefined,
|
||||||
watchers_count:undefined ,
|
watchers_count: undefined,
|
||||||
praises_count:undefined ,
|
praises_count: undefined,
|
||||||
forked_count:undefined,
|
forked_count: undefined,
|
||||||
watched: false,
|
watched: false,
|
||||||
praised: false,
|
praised: false,
|
||||||
http_url: undefined,
|
http_url: undefined,
|
||||||
author:undefined,
|
author: undefined,
|
||||||
branchs:undefined,
|
branchs: undefined,
|
||||||
branchList:undefined,
|
branchList: undefined,
|
||||||
branchLastCommit:undefined,
|
branchLastCommit: undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount=()=>{
|
componentDidMount = () => {
|
||||||
this.getDetail();
|
this.getDetail();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate=(prevState)=>{
|
componentDidUpdate = (prevState) => {
|
||||||
if((prevState.match.params.projectsId !== this.props.match.params.projectsId)){
|
if ((prevState.match.params.projectsId !== this.props.match.params.projectsId)) {
|
||||||
this.getDetail();
|
this.getDetail();
|
||||||
}
|
}
|
||||||
|
|
||||||
const { search } = this.props.location;
|
const { search } = this.props.location;
|
||||||
const search_c = prevState.location && prevState.location.search;
|
const search_c = prevState.location && prevState.location.search;
|
||||||
if( search && search!== search_c){
|
if (search && search !== search_c) {
|
||||||
// console.log("branches",this.props.location);
|
|
||||||
// console.log("branches_p",prevState.location);
|
|
||||||
// console.log("111",this.props.dataquerys);
|
|
||||||
const { projectsId } = this.props.match.params;
|
const { projectsId } = this.props.match.params;
|
||||||
this.getBranch(projectsId);
|
this.getBranch(projectsId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getDetail=()=>{
|
getDetail = () => {
|
||||||
const { projectsId } = this.props.match.params;
|
const { projectsId } = this.props.match.params;
|
||||||
const url = `/repositories/${projectsId}.json`;
|
const url = `/repositories/${projectsId}.json`;
|
||||||
axios.get(url).then((result)=>{
|
axios.get(url).then((result) => {
|
||||||
if(result){
|
if (result) {
|
||||||
this.setState({
|
this.setState({
|
||||||
projectDetail:result.data,
|
projectDetail: result.data,
|
||||||
project_id:result.data.project_id,
|
project_id: result.data.project_id,
|
||||||
isManager:result.data.permission && result.data.permission === "Manager",
|
isManager: result.data.permission && result.data.permission === "Manager",
|
||||||
isReporter:result.data.permission && result.data.permission === "Reporter",
|
isReporter: result.data.permission && result.data.permission === "Reporter",
|
||||||
isDeveloper:result.data.permission && result.data.permission === "Developer",
|
isDeveloper: result.data.permission && result.data.permission === "Developer",
|
||||||
http_url: result.data.clone_url,
|
http_url: result.data.clone_url,
|
||||||
author:result.data.author,
|
author: result.data.author,
|
||||||
praised: result.data.praised,
|
praised: result.data.praised,
|
||||||
watched: result.data.watched,
|
watched: result.data.watched,
|
||||||
watchers_count:result.data.watchers_count,
|
watchers_count: result.data.watchers_count,
|
||||||
praises_count:result.data.praises_count,
|
praises_count: result.data.praises_count,
|
||||||
forked_count:result.data.forked_count,
|
forked_count: result.data.forked_count,
|
||||||
})
|
})
|
||||||
if(result.data.project_id){
|
if (result.data.project_id) {
|
||||||
this.getBranch(result.data.project_id);
|
this.getBranch(result.data.project_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).catch((error)=>{})
|
}).catch((error) => { })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关注和取消关注
|
// 关注和取消关注
|
||||||
focusFunc =(flag)=>{
|
focusFunc = (flag) => {
|
||||||
const { project_id } = this.state;
|
const { project_id } = this.state;
|
||||||
axios({
|
axios({
|
||||||
method: flag? 'delete' : 'post',
|
method: flag ? 'delete' : 'post',
|
||||||
url: `/projects/${project_id}/watchers/${flag? 'unfollow' : 'follow'}.json`
|
url: `/projects/${project_id}/watchers/${flag ? 'unfollow' : 'follow'}.json`
|
||||||
})
|
})
|
||||||
.then(result => {
|
.then(result => {
|
||||||
if(result && result.data.status === 0){
|
if (result && result.data.status === 0) {
|
||||||
this.setWatchersCount(result.data.watchers_count, result.data.watched);
|
this.setWatchersCount(result.data.watchers_count, result.data.watched);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 点赞和取消点赞
|
// 点赞和取消点赞
|
||||||
pariseFunc=(flag)=>{
|
pariseFunc = (flag) => {
|
||||||
const { project_id } = this.state;
|
const { project_id } = this.state;
|
||||||
axios({
|
axios({
|
||||||
method: flag? 'delete' : 'post',
|
method: flag ? 'delete' : 'post',
|
||||||
url: `/projects/${project_id}/praise_tread/${flag? 'unlike' : 'like'}.json`
|
url: `/projects/${project_id}/praise_tread/${flag ? 'unlike' : 'like'}.json`
|
||||||
})
|
})
|
||||||
.then(result => {
|
.then(result => {
|
||||||
if(result && result.data.status === 0){
|
if (result && result.data.status === 0) {
|
||||||
this.setPraisesCount(result.data.praises_count, result.data.praised)
|
this.setPraisesCount(result.data.praises_count, result.data.praised)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setWatchersCount = (count, is_watched) => {
|
setWatchersCount = (count, is_watched) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
watched: is_watched,
|
watched: is_watched,
|
||||||
watchers_count: count
|
watchers_count: count
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setPraisesCount = (count, is_praised) => {
|
setPraisesCount = (count, is_praised) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
praised: is_praised,
|
praised: is_praised,
|
||||||
praises_count: count
|
praises_count: count
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// fork项目
|
// fork项目
|
||||||
forkFunc=()=>{
|
forkFunc = () => {
|
||||||
const { checkIfLogin } = this.props;
|
const { checkIfLogin } = this.props;
|
||||||
if(!checkIfLogin){
|
if (!checkIfLogin) {
|
||||||
this.props.showLoginDialog();
|
this.props.showLoginDialog();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
isSpin:true
|
isSpin: true
|
||||||
})
|
})
|
||||||
const { project_id } = this.state;
|
const { project_id } = this.state;
|
||||||
const url = `/projects/${project_id}/forks.json`;
|
const url = `/projects/${project_id}/forks.json`;
|
||||||
axios.post(url).then(result=>{
|
axios.post(url).then(result => {
|
||||||
if (result && result.data.status === 0) {
|
if (result && result.data.status === 0) {
|
||||||
this.props.history.push(`/projects/${result.data.id}/coders`);
|
this.props.history.push(`/projects/${result.data.id}/coders`);
|
||||||
this.props.showNotification(result.data.message);
|
this.props.showNotification(result.data.message);
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
isSpin:false
|
isSpin: false
|
||||||
})
|
})
|
||||||
}).catch(error=>{
|
}).catch(error => {
|
||||||
this.setState({
|
this.setState({
|
||||||
isSpin:false
|
isSpin: false
|
||||||
})
|
})
|
||||||
console.log(error);
|
console.log(error);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 获取分支列表
|
// 获取分支列表
|
||||||
getBranch=(id)=>{
|
getBranch = (id) => {
|
||||||
const url =`/projects/${id}/branches.json`;
|
const url = `/projects/${id}/branches.json`;
|
||||||
axios.get(url).then((result)=>{
|
axios.get(url).then((result) => {
|
||||||
if(result && result.data.length>0){
|
if (result && result.data.length > 0) {
|
||||||
const branchs = [];
|
const branchs = [];
|
||||||
result.data.map((item,key)=>{
|
result.data.map((item, key) => {
|
||||||
branchs.push({
|
branchs.push({
|
||||||
index:key,
|
index: key,
|
||||||
name:item.name
|
name: item.name
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
this.setState({
|
this.setState({
|
||||||
branchList:result.data,
|
branchList: result.data,
|
||||||
branchs,
|
branchs,
|
||||||
branchLastCommit:result.data[0],
|
branchLastCommit: result.data[0],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}).catch((error)=>{})
|
}).catch((error) => { })
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render() {
|
||||||
const { projectDetail , watchers_count , praises_count , forked_count , isSpin , isManager, watched, praised } = this.state;
|
const { projectDetail, watchers_count, praises_count, forked_count, isSpin, isManager, watched, praised } = this.state;
|
||||||
const url = this.props.history.location.pathname;
|
const url = this.props.history.location.pathname;
|
||||||
const urlArr= url.split("/");
|
const urlArr = url.split("/");
|
||||||
const urlFlag = (urlArr.length === 3);
|
const urlFlag = (urlArr.length === 3);
|
||||||
|
|
||||||
const { projectsId } = this.props.match.params;
|
const { projectsId } = this.props.match.params;
|
||||||
|
|
||||||
const { state } = this.props.history.location;
|
const { state } = this.props.history.location;
|
||||||
|
|
||||||
const text = (
|
const text = (
|
||||||
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<span>forked from </span>
|
<span>forked from </span>
|
||||||
<Link to={`/users/${projectDetail.fork_info.fork_project_user_login}/projects`} className="show-user-link color-grey-ccc">{projectDetail.fork_info.fork_project_user_name}</Link>
|
<Link to={`/users/${projectDetail.fork_info.fork_project_user_login}/projects`} className="show-user-link color-grey-ccc">{projectDetail.fork_info.fork_project_user_name}</Link>
|
||||||
<span> / </span>
|
<span> / </span>
|
||||||
<Link to={`/projects/${projectDetail.forked_from_project_id}/coders`} className="color-grey-ccc">{ projectDetail.fork_info.fork_form_name }</Link>
|
<Link to={`/projects/${projectDetail.forked_from_project_id}/coders`} className="color-grey-ccc">{projectDetail.fork_info.fork_form_name}</Link>
|
||||||
</React.Fragment>:""
|
</React.Fragment> : ""
|
||||||
);
|
);
|
||||||
return(
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Spin spinning={isSpin}>
|
<Spin spinning={isSpin}>
|
||||||
<div className="detailHeader-wrapper">
|
<div className="detailHeader-wrapper">
|
||||||
<div className="normal">
|
<div className="normal">
|
||||||
<div className="f-wrap-between mb15" style={{position:"relative"}}>
|
<div className="f-wrap-between mb15" style={{ position: "relative" }}>
|
||||||
<p className="font-18 color-white df flex-1 lineH2 mt15" style={{alignItems:"center"}}>
|
<p className="font-18 color-white df flex-1 lineH2 mt15" style={{ alignItems: "center" }}>
|
||||||
|
|
||||||
{projectDetail && projectDetail.author &&
|
{projectDetail && projectDetail.author &&
|
||||||
<Link to={`/users/${projectDetail.author.login}/projects`} className="show-user-link color-white">
|
<Link to={`/users/${projectDetail.author.login}/projects`} className="show-user-link color-white">
|
||||||
{projectDetail.author.name}
|
{projectDetail.author.name}
|
||||||
</Link>
|
</Link>
|
||||||
}
|
}
|
||||||
<span className="ml5 mr5">/</span>
|
<span className="ml5 mr5">/</span>
|
||||||
<span className="hide-1 flex-1 df">
|
<span className="hide-1 flex-1 df">
|
||||||
<Link to={`/projects/${projectsId}/coders`} className="color-white">{ projectDetail && projectDetail.name }</Link>
|
<Link to={`/projects/${projectsId}/coders`} className="color-white font-22">{projectDetail && projectDetail.name}</Link>
|
||||||
{
|
{
|
||||||
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
||||||
<Tooltip placement={'right'} title={text}>
|
<Tooltip placement={'right'} title={text}>
|
||||||
<Link to={`/projects/${projectDetail.forked_from_project_id}/coders`}
|
<Link to={`/projects/${projectDetail.forked_from_project_id}/coders`}
|
||||||
className="ml20" >
|
className="ml10" >
|
||||||
<i className="iconfont icon-fork color-grey-74 font-20 fl"></i>
|
<i className="iconfont icon-fork font-18 fl mt6" style={{ color: "#8D90E3" }}></i>
|
||||||
</Link>
|
</Link>
|
||||||
</Tooltip>:""
|
</Tooltip> : ""
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
<span className="df mt25">
|
||||||
<div className="f-wrap-between">
|
|
||||||
<ul className="headerMenu-wrapper">
|
|
||||||
<li className={(url.indexOf("coders")>-1 || urlFlag) ? "active" : ""}>
|
|
||||||
<Link to={{pathname:`/projects/${projectsId}/coders`,state}}><img alt="" src={img_1} width="18" />代码库</Link>
|
|
||||||
</li>
|
|
||||||
<li className={(url.indexOf("orders")>-1 && !(url.indexOf("Milepost")>0 || url.indexOf("meilpost")>0 || url.indexOf("tags")>0))? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/orders`,state}}><img alt="" src={img_2} width="12" />任务{projectDetail&&projectDetail.issues_count===0?"":projectDetail&&projectDetail.issues_count===0?projectDetail.issues_count:""}</Link></li>
|
|
||||||
<li className={url.indexOf("merge")>-1 ? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/merge`,state}}><img alt="" src={img_3} width="13" />合并请求{projectDetail&&projectDetail.pull_requests_count===0?"":projectDetail&&projectDetail.pull_requests_count===0?projectDetail.pull_requests_count:""}</Link></li>
|
|
||||||
<li className={url.indexOf("version")>-1 ? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/version`,state}}><img alt="" src={img_4} width="16" />版本发布</Link></li>
|
|
||||||
|
|
||||||
<li className={(url.indexOf("Milepost")>-1 || url.indexOf("meilpost")>-1) ? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/orders/Milepost`,state}}><img alt="" src={img_milepost} width="16" />里程碑</Link></li>
|
|
||||||
<li className={url.indexOf("trends")>-1 ? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/trends`,state}}><img alt="" src={img_6} width="16" />动态</Link></li>
|
|
||||||
{
|
|
||||||
isManager &&
|
|
||||||
<li className={url.indexOf("setting")>0 ? "active" : ""}><Link to={`/projects/${projectsId}/setting`}><img alt="" src={img_7} width="19" />仓库设置</Link></li>
|
|
||||||
}
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
<span className="df">
|
|
||||||
<span className="detail_tag_btn">
|
<span className="detail_tag_btn">
|
||||||
<a className="detail_tag_btn_name" onClick={()=>this.focusFunc(watched)}>
|
<a className="detail_tag_btn_name" onClick={() => this.focusFunc(watched)}>
|
||||||
<img src={watched ? img_focused : img_focus} alt="" width="14px"/>
|
<img src={watched ? img_focused : img_focus} alt="" width="14px" />
|
||||||
{watched ? '取消关注':'关注'}
|
{watched ? '取消关注' : '关注'}
|
||||||
</a>
|
</a>
|
||||||
<span className="detail_tag_btn_count">{watchers_count}</span>
|
<span className="detail_tag_btn_count">{watchers_count}</span>
|
||||||
</span>
|
</span>
|
||||||
<span className="detail_tag_btn">
|
<span className="detail_tag_btn">
|
||||||
<a className="detail_tag_btn_name" onClick={()=>this.pariseFunc(praised)}>
|
<a className="detail_tag_btn_name" onClick={() => this.pariseFunc(praised)}>
|
||||||
<img src={praised ? img_parised : img_parise} width="13px" alt=""/>
|
<img src={praised ? img_parised : img_parise} width="13px" alt="" />
|
||||||
{praised ? '取消点赞':'点赞'}
|
{praised ? '取消点赞' : '点赞'}
|
||||||
</a>
|
</a>
|
||||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||||
</span>
|
</span>
|
||||||
<span className="detail_tag_btn">
|
<span className="detail_tag_btn">
|
||||||
<a className="detail_tag_btn_name" onClick={this.forkFunc}>
|
<a className="detail_tag_btn_name" onClick={this.forkFunc}>
|
||||||
<img src={img_fork} alt="" width="10px"/>Fork</a>
|
<img src={img_fork} alt="" width="10px" />Fork</a>
|
||||||
<span className="detail_tag_btn_count">{forked_count}</span>
|
<span className="detail_tag_btn_count">{forked_count}</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="f-wrap-between">
|
||||||
|
<ul className="headerMenu-wrapper">
|
||||||
|
<li className={(url.indexOf("coders") > -1 || urlFlag) ? "active" : ""}>
|
||||||
|
<Link to={{ pathname: `/projects/${projectsId}/coders`, state }}>
|
||||||
|
<img alt="" src={img_1} width="18" />代码库
|
||||||
|
{projectDetail && projectDetail.commits_count && <span>{projectDetail.commits_count}</span>}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li className={(url.indexOf("orders") > -1 && !(url.indexOf("Milepost") > 0 || url.indexOf("meilpost") > 0 || url.indexOf("tags") > 0)) ? "active" : ""}>
|
||||||
|
<Link to={{ pathname: `/projects/${projectsId}/orders`, state }}>
|
||||||
|
<img alt="" src={img_2} width="12" />任务
|
||||||
|
{projectDetail && projectDetail.issues_count && <span>{projectDetail.issues_count}</span>}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li className={url.indexOf("merge") > -1 ? "active" : ""}>
|
||||||
|
<Link to={{ pathname: `/projects/${projectsId}/merge`, state }}>
|
||||||
|
<img alt="" src={img_3} width="13" />合并请求
|
||||||
|
{projectDetail && projectDetail.pull_requests_count && <span>{projectDetail.issues_count}</span>}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
{/* <li className={url.indexOf("version") > -1 ? "active" : ""}>
|
||||||
|
<Link to={{ pathname: `/projects/${projectsId}/version`, state }}>
|
||||||
|
<img alt="" src={img_4} width="16" />版本发布
|
||||||
|
{projectDetail && projectDetail.version_releases_count && <span>{projectDetail.version_releases_count}</span>}
|
||||||
|
</Link>
|
||||||
|
</li> */}
|
||||||
|
|
||||||
|
<li className={(url.indexOf("Milepost") > -1 || url.indexOf("meilpost") > -1) ? "active" : ""}>
|
||||||
|
<Link to={{ pathname: `/projects/${projectsId}/orders/Milepost`, state }}>
|
||||||
|
<img alt="" src={img_milepost} width="16" />里程碑
|
||||||
|
{projectDetail && projectDetail.version_count && <span>{projectDetail.version_count}</span>}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li className={url.indexOf("trends") > -1 ? "active" : ""}>
|
||||||
|
<Link to={{ pathname: `/projects/${projectsId}/trends`, state }}>
|
||||||
|
<img alt="" src={img_6} width="16" />动态
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
{
|
||||||
|
isManager &&
|
||||||
|
<li className={url.indexOf("setting") > 0 ? "active" : ""}><Link to={`/projects/${projectsId}/setting`}><img alt="" src={img_7} width="19" />仓库设置</Link></li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -386,55 +409,55 @@ class Detail extends Component{
|
||||||
{/* 新建文件 */}
|
{/* 新建文件 */}
|
||||||
<Route path="/projects/:projectsId/coders/:branch/newfile/:path"
|
<Route path="/projects/:projectsId/coders/:branch/newfile/:path"
|
||||||
render={
|
render={
|
||||||
(props) => (<FileNew {...this.props} {...props} {...this.state}/>)
|
(props) => (<FileNew {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/projects/:projectsId/coders/:branch/newfile"
|
<Route path="/projects/:projectsId/coders/:branch/newfile"
|
||||||
render={
|
render={
|
||||||
(props) => (<FileNew {...this.props} {...props} {...this.state}/>)
|
(props) => (<FileNew {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
{/* 标签列表 */}
|
{/* 标签列表 */}
|
||||||
<Route path="/projects/:projectsId/orders/tags"
|
<Route path="/projects/:projectsId/orders/tags"
|
||||||
render={
|
render={
|
||||||
(props) => (<TagList {...this.props} {...props} {...this.state}/>)
|
(props) => (<TagList {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 仓库设置 */}
|
{/* 仓库设置 */}
|
||||||
<Route path="/projects/:projectsId/setting"
|
<Route path="/projects/:projectsId/setting"
|
||||||
render={
|
render={
|
||||||
(props) => (<Setting {...this.props} {...props} {...this.state} getDetail={this.getDetail}/>)
|
(props) => (<Setting {...this.props} {...props} {...this.state} getDetail={this.getDetail} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 任务详情 */}
|
{/* 任务详情 */}
|
||||||
<Route path="/projects/:projectsId/orders/:orderId/detail"
|
<Route path="/projects/:projectsId/orders/:orderId/detail"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderDetail {...this.props} {...props} {...this.state}/>)
|
(props) => (<OrderDetail {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 里程碑 */}
|
{/* 里程碑 */}
|
||||||
<Route path="/projects/:projectsId/orders/Milepost"
|
<Route path="/projects/:projectsId/orders/Milepost"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderMilepost {...this.props} {...props} {...this.state}/>)
|
(props) => (<OrderMilepost {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 新建里程碑 */}
|
{/* 新建里程碑 */}
|
||||||
<Route path="/projects/:projectsId/orders/meilpost"
|
<Route path="/projects/:projectsId/orders/meilpost"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrdernewMilepost {...this.props} {...props} {...this.state}/>)
|
(props) => (<OrdernewMilepost {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/*里程碑详情*/ }
|
{/*里程碑详情*/}
|
||||||
<Route path="/projects/:projectsId/orders/:meilid/MilepostDetail"
|
<Route path="/projects/:projectsId/orders/:meilid/MilepostDetail"
|
||||||
render={
|
render={
|
||||||
(props) => (<MilepostDetail {...this.props} {...props} {...this.state}/>)
|
(props) => (<MilepostDetail {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/*修改里程碑*/}
|
{/*修改里程碑*/}
|
||||||
<Route path="/projects/:projectsId/orders/:meilid/meilpost"
|
<Route path="/projects/:projectsId/orders/:meilid/meilpost"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderupdateMilepost {...this.props} {...props} {...this.state}/>)
|
(props) => (<OrderupdateMilepost {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
|
@ -442,34 +465,34 @@ class Detail extends Component{
|
||||||
{/* 里程碑页面新建任务 */}
|
{/* 里程碑页面新建任务 */}
|
||||||
<Route path="/projects/:projectsId/orders/:milepostId/new"
|
<Route path="/projects/:projectsId/orders/:milepostId/new"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderNew {...this.props} {...props} {...this.state}/>)
|
(props) => (<OrderNew {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 新建任务 */}
|
{/* 新建任务 */}
|
||||||
<Route path="/projects/:projectsId/orders/new"
|
<Route path="/projects/:projectsId/orders/new"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderNew {...this.props} {...props} {...this.state}/>)
|
(props) => (<OrderNew {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
{/* 修改详情 */}
|
{/* 修改详情 */}
|
||||||
<Route path="/projects/:projectsId/orders/:orderId/updatedetail"
|
<Route path="/projects/:projectsId/orders/:orderId/updatedetail"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state}/>)
|
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
{/* 复制详情 */}
|
{/* 复制详情 */}
|
||||||
<Route path="/projects/:projectsId/orders/:orderId/copyetail"
|
<Route path="/projects/:projectsId/orders/:orderId/copyetail"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrdercopyDetail {...this.props} {...props} {...this.state}/>)
|
(props) => (<OrdercopyDetail {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
{/* 动态 */}
|
{/* 动态 */}
|
||||||
<Route path="/projects/:projectsId/trends"
|
<Route path="/projects/:projectsId/trends"
|
||||||
render={
|
render={
|
||||||
(props) => (<TrendsIndex {...this.props} {...props} {...this.state}/>)
|
(props) => (<TrendsIndex {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
|
@ -477,71 +500,53 @@ class Detail extends Component{
|
||||||
{/* 代码Index */}
|
{/* 代码Index */}
|
||||||
<Route path="/projects/:projectsId/orders"
|
<Route path="/projects/:projectsId/orders"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderIndex {...this.props} {...props} {...this.state}/>)
|
(props) => (<OrderIndex {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
<Route path="/projects/:projectsId/merge/new"
|
<Route path="/projects/:projectsId/merge/new"
|
||||||
render={
|
render={
|
||||||
(props) => (<CreateMerge {...this.props} {...props} {...this.state}/>)
|
(props) => (<CreateMerge {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
<Route path="/projects/:projectsId/merge/:mergeId/UpdateMerge"
|
<Route path="/projects/:projectsId/merge/:mergeId/UpdateMerge"
|
||||||
render={
|
render={
|
||||||
(props) => (<MessageCount {...this.props} {...props} {...this.state}/>)
|
(props) => (<MessageCount {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
<Route path="/projects/:projectsId/merge/:mergeId/Messagecount"
|
<Route path="/projects/:projectsId/merge/:mergeId/Messagecount"
|
||||||
render={
|
render={
|
||||||
(props) => (<MessageCount {...this.props} {...props} {...this.state}/>)
|
(props) => (<MessageCount {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
<Route path="/projects/:projectsId/merge/:mergeId/MergeSubmit"
|
<Route path="/projects/:projectsId/merge/:mergeId/MergeSubmit"
|
||||||
render={
|
render={
|
||||||
(props) => (<MessageCount {...this.props} {...props} {...this.state}/>)
|
(props) => (<MessageCount {...this.props} {...props} {...this.state} />)
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
<Route path="/projects/:projectsId/version/new"
|
|
||||||
render={
|
|
||||||
(props) => (<NewVersionIndex {...this.props} {...props} {...this.state}/>)
|
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
|
|
||||||
<Route path="/projects/:projectsId/version/:versionId/upversion"
|
<Route path="/projects/:projectsId/merge"
|
||||||
render={
|
render={
|
||||||
(props) => (<UpVersionIndex {...this.props} {...props} {...this.state}/>)
|
(props) => (<MergeIndexDetail {...this.props} {...props} {...this.state} />)
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
|
|
||||||
|
|
||||||
<Route path="/projects/:projectsId/version"
|
|
||||||
render={
|
|
||||||
(props) => (<VersionIndex {...this.props} {...props} {...this.state}/>)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
|
|
||||||
<Route path="/projects/:projectsId/merge"
|
|
||||||
render={
|
|
||||||
(props) => (<MergeIndexDetail {...this.props} {...props} {...this.state}/>)
|
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/projects/:projectsId/coders/filesurl"
|
<Route path="/projects/:projectsId/coders/filesurl"
|
||||||
render={
|
render={
|
||||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state}/>)
|
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/projects/:projectsId/coders"
|
<Route path="/projects/:projectsId/coders"
|
||||||
render={
|
render={
|
||||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state}/>)
|
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/projects/:projectsId"
|
<Route path="/projects/:projectsId"
|
||||||
render={
|
render={
|
||||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state}/>)
|
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
|
@ -9,12 +9,28 @@ class DetailTop extends Component {
|
||||||
return (
|
return (
|
||||||
<p className="branch-wrapper">
|
<p className="branch-wrapper">
|
||||||
<Link to={`/projects/${projectsId}/coders/commit`} className={pathname.indexOf("/coders/commit") > 0 ? "active" : ""}>
|
<Link to={`/projects/${projectsId}/coders/commit`} className={pathname.indexOf("/coders/commit") > 0 ? "active" : ""}>
|
||||||
<i className="iconfont icon-tijiaojilu font-18 mr3"></i>
|
<i className="iconfont icon-tijiaojilu font-20 mr3 font-bd"></i>
|
||||||
<span className="mr3">{projectDetail && projectDetail.commits_count}</span>提交
|
<span>{projectDetail && projectDetail.commits_count}</span>个提交
|
||||||
</Link>
|
</Link>
|
||||||
<Link to={`/projects/${projectsId}/coders/branch`} className={pathname.indexOf("/coders/branch") > 0 ? "active" : ""}>
|
<Link to={`/projects/${projectsId}/coders/branch`} className={pathname.indexOf("/coders/branch") > 0 ? "active" : ""}>
|
||||||
<i className="iconfont icon-fenzhi font-18 mr3"></i>
|
<i className="iconfont icon-fenzhi1 font-18 mr3"></i>
|
||||||
<span className="mr3">{projectDetail && projectDetail.branches_count}</span>分支
|
<span>{projectDetail && projectDetail.branches_count}</span>个分支
|
||||||
|
</Link>
|
||||||
|
<Link to={`/projects/${projectsId}/coders/tag`} className={pathname.indexOf("/coders/tag") > 0 ? "active" : ""}>
|
||||||
|
<i className="iconfont icon-biaoqian3 font-18 mr3"></i>
|
||||||
|
<span>{projectDetail && projectDetail.issue_tags_count}</span>个标签
|
||||||
|
</Link>
|
||||||
|
<Link to={`/projects/${projectsId}/coders/version`} className={pathname.indexOf("/coders/version") > 0 ? "active" : ""}>
|
||||||
|
<i className="iconfont icon-fahangban font-18 mr3"></i>
|
||||||
|
<span>{projectDetail && projectDetail.version_releasesed_count}</span>个发行版
|
||||||
|
</Link>
|
||||||
|
<Link to={`/projects/${projectsId}/coders/contributor`} className={pathname.indexOf("/coders/contributor") > 0 ? "active" : ""}>
|
||||||
|
<i className="iconfont icon-gongxianzhe font-18 mr3"></i>
|
||||||
|
<span>{projectDetail && projectDetail.contributor_users_count}</span>位贡献者
|
||||||
|
</Link>
|
||||||
|
<Link to={`/projects/${projectsId}/coders/warehouse`} className={pathname.indexOf("/coders/warehouse") > 0 ? "active" : ""}>
|
||||||
|
<i className="iconfont icon-cangku font-18 mr3"></i>
|
||||||
|
仓库 <span>{projectDetail && projectDetail.size}</span>kb
|
||||||
</Link>
|
</Link>
|
||||||
</p>
|
</p>
|
||||||
)
|
)
|
||||||
|
|
|
@ -201,9 +201,9 @@ class Index extends Component {
|
||||||
</div> : ""
|
</div> : ""
|
||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
<div style={{ background: "#EAEBEC" }}>
|
<div>
|
||||||
<p className="t_project_banner"></p>
|
<p className="t_project_banner"></p>
|
||||||
<div className="main ProjectListIndex">
|
<div className="ProjectListIndex">
|
||||||
<div className="list-left">
|
<div className="list-left">
|
||||||
<ul className="list-l-Menu">
|
<ul className="list-l-Menu">
|
||||||
<li className="MenuTitle"><i className="iconfont icon-xiangmuleixing color-grey-9 font-15 mr5"></i>项目类型</li>
|
<li className="MenuTitle"><i className="iconfont icon-xiangmuleixing color-grey-9 font-15 mr5"></i>项目类型</li>
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
background-color: #050d34;
|
background-color: #050d34;
|
||||||
}
|
}
|
||||||
.ProjectListIndex{
|
.ProjectListIndex{
|
||||||
|
width: 1200px;
|
||||||
|
margin:20px auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
flex-wrap:wrap;
|
flex-wrap:wrap;
|
||||||
|
@ -278,21 +280,27 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.headerMenu-wrapper li a > img{
|
.headerMenu-wrapper li a > img{
|
||||||
margin-right: 5px;
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.headerMenu-wrapper li a > span{
|
||||||
|
background-color: #676AF1;
|
||||||
|
height: 18px;
|
||||||
|
line-height: 18px;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: block;
|
||||||
|
padding:0px 6px;
|
||||||
|
margin-left: 5px;
|
||||||
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
.headerMenu-wrapper li.active{
|
.headerMenu-wrapper li.active{
|
||||||
background:linear-gradient(180deg,rgba(58,194,255,1) 0%,rgba(27,143,255,1) 100%);
|
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
|
border:1px solid #71A6FF;
|
||||||
}
|
|
||||||
.headerMenu-wrapper li.active a {
|
|
||||||
color: #fff !important;
|
|
||||||
}
|
}
|
||||||
.detail_tag_btn{
|
.detail_tag_btn{
|
||||||
height:30px;
|
height:26px;
|
||||||
line-height: 30px;
|
line-height: 26px;
|
||||||
border-radius:4px;
|
border-radius:5px;
|
||||||
border:1px solid rgba(28,145,255,1);
|
border:1px solid #71A6FF;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-left: 30px
|
margin-left: 30px
|
||||||
|
@ -304,43 +312,61 @@
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
.detail_tag_btn_name img{
|
.detail_tag_btn_name img{
|
||||||
margin-right: 3px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
.detail_tag_btn_count{
|
.detail_tag_btn_count{
|
||||||
padding:0px 10px;
|
padding:0px 10px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: #1C91FF;
|
background: #71A6FF;
|
||||||
border-radius: 0px 4px 4px 0px;
|
border-radius: 0px 4px 4px 0px;
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
/* 详情-代码 */
|
/* 详情-代码 */
|
||||||
.branch-wrapper{
|
.branch-wrapper{
|
||||||
border:1px solid #eee;
|
border:1px solid #eee;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding:5px;
|
align-items: center;
|
||||||
|
height: 60px;
|
||||||
|
padding:0px 30px;
|
||||||
|
width: 1200px;
|
||||||
|
margin:0px auto;
|
||||||
|
background-color: #fff;
|
||||||
|
margin-top: 20px;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.branch-wrapper > a >i{
|
||||||
|
color: #5091FF;
|
||||||
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
.branch-wrapper a{
|
.branch-wrapper a{
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex: 1;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
color: #333333;
|
||||||
}
|
}
|
||||||
.branch-wrapper a.active{
|
.branch-wrapper a > span{
|
||||||
background: #eee;
|
position: relative;
|
||||||
}
|
}
|
||||||
.branch-wrapper a:hover{
|
.branch-wrapper a.active > span::after{
|
||||||
color: #4CACFF;
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
bottom: -5px;
|
||||||
|
width: 30px;
|
||||||
|
height: 3px;
|
||||||
|
left: 0px;
|
||||||
|
background-color:#5091FF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.gitAddressClone{
|
.gitAddressClone{
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 32px;
|
height: 40px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border:1px solid #eee;
|
border:1px solid #eee;
|
||||||
|
@ -349,14 +375,13 @@
|
||||||
}
|
}
|
||||||
.gitAddressClone > span{
|
.gitAddressClone > span{
|
||||||
display: flex;
|
display: flex;
|
||||||
line-height: 30px;
|
line-height: 40px;
|
||||||
height: 30px;
|
height: 40px;
|
||||||
padding:0px 12px;
|
padding:0px 12px;
|
||||||
border-right: 1px solid #eee;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.gitAddressClone > span.addressType.active{
|
.gitAddressClone > span.addressType{
|
||||||
color: #4CACFF;
|
color: #4CACFF;
|
||||||
}
|
}
|
||||||
.gitAddressClone > span:last-child{
|
.gitAddressClone > span:last-child{
|
||||||
|
@ -366,47 +391,54 @@
|
||||||
border:none;
|
border:none;
|
||||||
outline: none;
|
outline: none;
|
||||||
padding:0px 8px;
|
padding:0px 8px;
|
||||||
height: 30px;
|
height: 40px;
|
||||||
line-height: 30px;
|
line-height: 40px;
|
||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
border-right: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
flex:1;
|
flex:1;
|
||||||
}
|
}
|
||||||
.wrap-commit-table .ant-table-small > .ant-table-content > .ant-table-body{
|
.wrap-commit-table .ant-table-small > .ant-table-content > .ant-table-body{
|
||||||
margin:0px;
|
margin:0px;
|
||||||
}
|
}
|
||||||
|
.wrap-commit-table .ant-table-title{
|
||||||
|
background-color: rgba(241,248,255,1);
|
||||||
|
padding: 13px 8px!important;
|
||||||
|
}
|
||||||
.commitKey{
|
.commitKey{
|
||||||
border:1px solid #dcdcdc;
|
border:1px solid #FD7700;
|
||||||
background-color:#f4f4f4;
|
background-color:#FFF3DC;
|
||||||
color: #666!important;
|
color: #FD7700!important;
|
||||||
padding:0px 5px;
|
padding:0px 12px;
|
||||||
height: 28px;
|
height: 20px;
|
||||||
line-height: 28px;
|
line-height: 20px;
|
||||||
margin-right:15px;
|
margin-left:15px;
|
||||||
border-radius: 4px;
|
border-radius: 18px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
/* 分支 */
|
/* 分支 */
|
||||||
.branchTable{
|
.branchTable{
|
||||||
border:1px solid #f7f7f7;
|
border:1px solid #f7f7f7;
|
||||||
background-color: #f7f7f7;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
margin-top:20px;
|
|
||||||
}
|
}
|
||||||
.branchTitle{
|
.branchTitle{
|
||||||
padding:12px 10px;
|
padding:12px 10px;
|
||||||
color: #333;
|
color: #333;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
background: #EEEEEE;
|
||||||
|
}
|
||||||
|
.branchUl{
|
||||||
|
padding:0px 30px;
|
||||||
}
|
}
|
||||||
.branchUl li{
|
.branchUl li{
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding:8px 10px 10px 10px;
|
padding:20px 0px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
}
|
}
|
||||||
.branchUl li:nth-child(2n+1){
|
.branchUl li:last-child{
|
||||||
background-color: #fff;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
.operationBtn{
|
.operationBtn{
|
||||||
border:1px solid #f4f4f4;
|
border:1px solid #f4f4f4;
|
||||||
|
@ -507,16 +539,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.commonBox{
|
.commonBox{
|
||||||
border:1px solid #f4f4f4;
|
border:1px solid #ddd;
|
||||||
border-radius: 4px;
|
|
||||||
margin-top: 25px;
|
margin-top: 25px;
|
||||||
}
|
}
|
||||||
.commonBox .commonBox-title{
|
.commonBox .commonBox-title{
|
||||||
padding:3px 15px;
|
padding:0px 15px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-size: 15px;
|
font-size: 16px;
|
||||||
background: #f0f0f0;
|
background: #F1F8FF;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
.commonBox .commonBox-info{
|
.commonBox .commonBox-info{
|
||||||
padding:20px 15px;
|
padding:20px 15px;
|
||||||
|
@ -607,4 +641,63 @@ border: 1px solid #2185d0;
|
||||||
a.color-grey-ccc:hover{
|
a.color-grey-ccc:hover{
|
||||||
color: #4cacff !important;
|
color: #4cacff !important;
|
||||||
}
|
}
|
||||||
.pull-right{float: right;}
|
.pull-right{float: right;}
|
||||||
|
|
||||||
|
.commitList{
|
||||||
|
padding:0px 30px;
|
||||||
|
}
|
||||||
|
.commitList > div{
|
||||||
|
border-bottom: 1px solid #EEEEEE;
|
||||||
|
padding:16px 0px;
|
||||||
|
}
|
||||||
|
.commitList > div:last-child{
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 标签列表 */
|
||||||
|
.div_table{
|
||||||
|
border:1px solid #eee;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.ul_thead{
|
||||||
|
padding:0px 30px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: #FAFAFA;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
}
|
||||||
|
.ul_tbody{
|
||||||
|
padding:0px 30px;
|
||||||
|
}
|
||||||
|
.ul_thead li, .ul_tbody li{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
.ul_tbody li{
|
||||||
|
padding:18px 0px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
.ul_tbody li:last-child{
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.ul_thead li > span , .ul_tbody li > span{
|
||||||
|
width: 20%;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
.ul_thead li > span:nth-child(2), .ul_tbody li > span:nth-child(2){
|
||||||
|
flex:1;
|
||||||
|
}
|
||||||
|
.ul_tbody_third{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: left;
|
||||||
|
}
|
||||||
|
.ul_tbody_forth{
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
|
@ -193,6 +193,9 @@ class Index extends Component {
|
||||||
|
|
||||||
checkId = (rule, value, callback, list, title) => {
|
checkId = (rule, value, callback, list, title) => {
|
||||||
let filter = list.filter(item => item.name === value);
|
let filter = list.filter(item => item.name === value);
|
||||||
|
if(!value){
|
||||||
|
callback();
|
||||||
|
}
|
||||||
if (filter && filter.length > 0) {
|
if (filter && filter.length > 0) {
|
||||||
callback();
|
callback();
|
||||||
} else {
|
} else {
|
||||||
|
@ -248,7 +251,7 @@ class Index extends Component {
|
||||||
<Input placeholder="输入需要同步到本项目的镜像版本库地址" />
|
<Input placeholder="输入需要同步到本项目的镜像版本库地址" />
|
||||||
)}
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<p className="formTip">示例:https://github.com/facebook/reack.git</p>
|
<p className="formTip color-orange">示例:https://github.com/facebook/reack.git</p>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
<Form.Item
|
<Form.Item
|
||||||
|
@ -301,7 +304,6 @@ class Index extends Component {
|
||||||
className="plateAutoComplete"
|
className="plateAutoComplete"
|
||||||
onBlur={(value) => this.blurCategory(value, CategoryList, "project_category")}
|
onBlur={(value) => this.blurCategory(value, CategoryList, "project_category")}
|
||||||
>
|
>
|
||||||
{/* {this.setOptionsList(CategoryList,project_category_name)} */}
|
|
||||||
{project_category_list}
|
{project_category_list}
|
||||||
</AutoComplete>
|
</AutoComplete>
|
||||||
)}
|
)}
|
||||||
|
@ -322,14 +324,10 @@ class Index extends Component {
|
||||||
className="plateAutoComplete"
|
className="plateAutoComplete"
|
||||||
onBlur={(value) => this.blurCategory(value, LanguageList, "project_language")}
|
onBlur={(value) => this.blurCategory(value, LanguageList, "project_language")}
|
||||||
>
|
>
|
||||||
{/* {this.setOptionsList(LanguageList,project_language_name)} */}
|
|
||||||
{project_language_list}
|
{project_language_list}
|
||||||
</AutoComplete>
|
</AutoComplete>
|
||||||
)}
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
|
||||||
<Divider />
|
|
||||||
<div className="newPanel_content">
|
|
||||||
{
|
{
|
||||||
projectsType === "deposit" &&
|
projectsType === "deposit" &&
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
@ -379,23 +377,17 @@ class Index extends Component {
|
||||||
}
|
}
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="可见性"
|
label="可见性"
|
||||||
style={{ marginBottom: "0px" }}
|
style={{ margin: "0px" }}
|
||||||
|
className="privatePart"
|
||||||
>
|
>
|
||||||
{getFieldDecorator('private')(
|
{getFieldDecorator('private')(
|
||||||
<Checkbox value="limit">将项目设为私有<span className="ml15 font-13 color-grey-9">(只有项目所有人或拥有权限的项目成员才能看到)</span></Checkbox>
|
<Checkbox value="limit">将项目设为私有<span className="ml15 font-13 color-grey-9">(只有项目所有人或拥有权限的项目成员才能看到)</span></Checkbox>
|
||||||
)}
|
)}
|
||||||
</Form.Item >
|
</Form.Item >
|
||||||
<div className="ant-row ant-form-item">
|
<div>
|
||||||
<div className="ant-col ant-form-item-label">
|
注:<span className="ant-form-item-required"></span> 为必填项,否则为选填
|
||||||
注:
|
|
||||||
</div>
|
|
||||||
<div className="ant-col ant-form-item-control-wrapper color-grey-9">
|
|
||||||
<div className="ant-form-item-control">
|
|
||||||
<span className="ant-form-item-required"></span> 为必填项,否则为选填
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<Form.Item className="formTip">
|
<Form.Item className="formTip mt20">
|
||||||
<Button type="primary" onClick={this.subMitFrom} className="mr20">创建项目</Button>
|
<Button type="primary" onClick={this.subMitFrom} className="mr20">创建项目</Button>
|
||||||
<Link to={'/projects'} className="btn_32">取消</Link>
|
<Link to={'/projects'} className="btn_32">取消</Link>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
|
@ -5,28 +5,14 @@
|
||||||
.newPanel_title{
|
.newPanel_title{
|
||||||
height: 3rem;
|
height: 3rem;
|
||||||
line-height: 3rem;
|
line-height: 3rem;
|
||||||
background: #f0f0f0;
|
background: #F1F8FF;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: 4px 4px 0px 0px;
|
border-radius: 4px 4px 0px 0px;
|
||||||
font-size: 1.6em;
|
font-size: 1.6em;
|
||||||
border-bottom: 1px solid #f0f0f0
|
border-bottom: 1px solid #f0f0f0
|
||||||
}
|
}
|
||||||
.newPanel_content{
|
.newPanel_content{
|
||||||
width: 600px;
|
padding:1rem 2rem;
|
||||||
margin:1rem auto;
|
|
||||||
}
|
|
||||||
.newPanel_content .ant-row.ant-form-item{
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newPanel_content .ant-form-item-label{
|
|
||||||
width: 135px;
|
|
||||||
display: block;
|
|
||||||
text-align: right;
|
|
||||||
margin-right: 10px;
|
|
||||||
height: 37px;
|
|
||||||
line-height: 40px;
|
|
||||||
}
|
}
|
||||||
.newPanel_content .ant-form-item-control-wrapper{
|
.newPanel_content .ant-form-item-control-wrapper{
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
@ -50,8 +36,13 @@
|
||||||
.newContent_inline > .ant-form-item:nth-child(2){
|
.newContent_inline > .ant-form-item:nth-child(2){
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
.formTip{
|
.newPanel_content .privatePart .ant-form-item-label{
|
||||||
margin:0px 0px 20px 146px;
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
.newPanel_content .ant-form-item-label{
|
||||||
|
line-height: 25px;
|
||||||
|
height: 25px;
|
||||||
|
margin-left: -0.8rem;
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 750px){
|
@media screen and (max-width: 750px){
|
||||||
.newPanel_content{
|
.newPanel_content{
|
||||||
|
@ -60,13 +51,7 @@
|
||||||
.newPanel_content .ant-row.ant-form-item{
|
.newPanel_content .ant-row.ant-form-item{
|
||||||
display: grid
|
display: grid
|
||||||
}
|
}
|
||||||
.newPanel_content .ant-form-item-label{
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.newContent_inline > .ant-form-item:nth-child(2){
|
.newContent_inline > .ant-form-item:nth-child(2){
|
||||||
margin-left:0px
|
margin-left:0px
|
||||||
}
|
}
|
||||||
.formTip{
|
|
||||||
margin:0px 0px 20px 0px;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@ import React , { Component } from "react";
|
||||||
import Editor from "react-monaco-editor";
|
import Editor from "react-monaco-editor";
|
||||||
|
|
||||||
import UserSubmitComponent from './UserSubmitComponent';
|
import UserSubmitComponent from './UserSubmitComponent';
|
||||||
|
import Top from '../Main/DetailTop';
|
||||||
import { Input } from 'antd';
|
import { Input } from 'antd';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
|
@ -38,29 +39,32 @@ class Index extends Component{
|
||||||
const { pathname } = this.props.location;
|
const { pathname } = this.props.location;
|
||||||
const urlroot = pathname.split("newfile")[1];
|
const urlroot = pathname.split("newfile")[1];
|
||||||
return(
|
return(
|
||||||
<div className="main">
|
<React.Fragment>
|
||||||
<div className="f-wrap-alignCenter">
|
<Top {...this.props} {...this.state}/>
|
||||||
<div className="setInputAddon">
|
<div className="main">
|
||||||
<Input addonBefore={`/${projectDetail && projectDetail.identifier}${urlroot}/`} value={filename} onChange={this.changeFileName} placeholder="命名文件..."/>
|
<p className="pb15 bor-bottom-greyE font-16 color-grey-3 mb20">新建文件</p>
|
||||||
|
<div className="f-wrap-alignCenter mb20">
|
||||||
|
<div className="setInputAddon">
|
||||||
|
<Input addonBefore={`/${projectDetail && projectDetail.identifier}${urlroot}/`} value={filename} onChange={this.changeFileName} placeholder="命名文件..."/>
|
||||||
|
</div>
|
||||||
|
<a onClick={this.CancelAddFile} className="color-blue">取消</a>
|
||||||
</div>
|
</div>
|
||||||
<a onClick={this.CancelAddFile} className="color-blue">取消</a>
|
<div className="branchTable">
|
||||||
|
<Editor
|
||||||
|
height="320px"
|
||||||
|
theme={"vs-grey"}
|
||||||
|
value={editorValue}
|
||||||
|
onChange={this.changeEditor}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<UserSubmitComponent
|
||||||
|
{...this.props}
|
||||||
|
{...this.state}
|
||||||
|
filepath={`${urlroot}/${filename}`}
|
||||||
|
content={editorValue}
|
||||||
|
></UserSubmitComponent>
|
||||||
</div>
|
</div>
|
||||||
<div className="branchTable">
|
</React.Fragment>
|
||||||
<p className="branchTitle">新建文件</p>
|
|
||||||
<Editor
|
|
||||||
height="320px"
|
|
||||||
theme={"vs-dark"}
|
|
||||||
value={editorValue}
|
|
||||||
onChange={this.changeEditor}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<UserSubmitComponent
|
|
||||||
{...this.props}
|
|
||||||
{...this.state}
|
|
||||||
filepath={`${urlroot}/${filename}`}
|
|
||||||
content={editorValue}
|
|
||||||
></UserSubmitComponent>
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,61 +50,63 @@ class UserSubmitComponent extends Component{
|
||||||
const { submitType } = this.state;
|
const { submitType } = this.state;
|
||||||
const { getFieldDecorator } = this.props.form;
|
const { getFieldDecorator } = this.props.form;
|
||||||
|
|
||||||
const { branch } = this.props.match.params;
|
const { branch , projectsId } = this.props.match.params;
|
||||||
|
|
||||||
const { current_user , filepath , projectDetail } = this.props;
|
const { current_user , filepath , projectDetail } = this.props;
|
||||||
|
|
||||||
const changeSubmitBranch = ()=>{
|
const changeSubmitBranch = ()=>{
|
||||||
if(submitType==="1"){
|
if(submitType==="1"){
|
||||||
return(
|
return(
|
||||||
<div className="mt24">
|
<div className="mt15">
|
||||||
<Form.Item style={{paddingLeft:"24px"}}>
|
|
||||||
{getFieldDecorator('desc', {
|
|
||||||
rules: [{
|
|
||||||
required:true,message:'请输入合并请求的描述内容'
|
|
||||||
}],
|
|
||||||
})(
|
|
||||||
<TextArea placeholder={`请输入合并请求的描述,(必填)`} authSize={{minRows:3,maxRows:5}}/>
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item style={{paddingLeft:"24px"}}>
|
<Form.Item style={{paddingLeft:"24px"}}>
|
||||||
{getFieldDecorator('branchname', {
|
{getFieldDecorator('branchname', {
|
||||||
rules: [{
|
rules: [{
|
||||||
required: true, message: '请输入分支名称'
|
required: true, message: '请输入分支名称'
|
||||||
}],
|
}],
|
||||||
})(
|
})(
|
||||||
<Input placeholder={`请输入分支名称`}/>
|
<Input placeholder={`请输入分支名称`} style={{width:"220px"}}/>
|
||||||
)}
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(
|
return(
|
||||||
<div className="userScrew">
|
<div>
|
||||||
<img src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt="" className="screwImg"/>
|
<span className="df mt20" style={{alignItems:"center"}}>
|
||||||
<div className="screwPanel">
|
<img src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt="" className="screwImg"/>
|
||||||
<Form>
|
<span className="color-grey-3">用户名:<span className="color-grey-8">{current_user && current_user.username}</span></span>
|
||||||
<Form.Item>
|
</span>
|
||||||
{getFieldDecorator('path', {
|
<div className="userScrew">
|
||||||
rules: [],
|
<div className="screwPanel">
|
||||||
})(
|
<Form>
|
||||||
<Input placeholder={`/${projectDetail && projectDetail.identifier}${filepath}`} readOnly/>
|
<Form.Item>
|
||||||
)}
|
{getFieldDecorator('path', {
|
||||||
</Form.Item>
|
rules: [],
|
||||||
|
})(
|
||||||
|
<Input placeholder={`/${projectDetail && projectDetail.identifier}${filepath}`} readOnly/>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item>
|
||||||
|
{getFieldDecorator('desc', {
|
||||||
|
rules: [{
|
||||||
|
required:true,message:'请输入合并请求的描述内容'
|
||||||
|
}],
|
||||||
|
})(
|
||||||
|
<TextArea placeholder={`请输入合并请求的描述,(必填)`} authSize={{minRows:3,maxRows:5}}/>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
<Radio.Group value={submitType} onChange={this.changeSubmittype}>
|
||||||
|
<Radio value="0" className="mb10"><i className="iconfont icon-banbenku font-16 mr5"></i>直接提交至<span className="color-orange">{branch}</span>分支</Radio>
|
||||||
|
<Radio value="1"><Icon type="pull-request" className="mr5" />为此提交创建一个<span className="font-bd">新的分支</span>并发起合并请求</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
{changeSubmitBranch()}
|
||||||
|
|
||||||
<Radio.Group value={submitType} onChange={this.changeSubmittype}>
|
</Form>
|
||||||
<Radio value="0"><i className="iconfont icon-banbenku font-16 mr5"></i>直接提交至<span>{branch}</span>分支</Radio>
|
</div>
|
||||||
<Radio value="1"><Icon type="pull-request" className="mr5" />为此提交创建一个<span className="font-bd">新的分支</span>并发起合并请求</Radio>
|
|
||||||
</Radio.Group>
|
|
||||||
{changeSubmitBranch()}
|
|
||||||
|
|
||||||
<Form.Item className="mt10" style={{marginBottom:"0px"}}>
|
|
||||||
<Button type="primary" onClick={this.subMitFrom} className="mr20">提交变更</Button>
|
|
||||||
</Form.Item>
|
|
||||||
</Form>
|
|
||||||
</div>
|
</div>
|
||||||
|
<Button type="primary" onClick={this.subMitFrom} className="mr20">提交变更</Button>
|
||||||
|
<Button type="primary grey" onClick={()=>{this.props.history.push(`/projects/${projectsId}/coders`)}} className="mr20">取消</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,39 @@
|
||||||
border:1px solid #f4f4f4;
|
border:1px solid #f4f4f4;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding:10px;
|
padding:20px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.userScrew::before{
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 110px;
|
||||||
|
top: -20px;
|
||||||
|
border-bottom:10px solid #f4f4f4;
|
||||||
|
border-top:10px solid transparent;
|
||||||
|
border-left:10px solid transparent;
|
||||||
|
border-right:10px solid transparent;
|
||||||
|
}
|
||||||
|
.userScrew::after{
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left:111px;
|
||||||
|
top: -18px;
|
||||||
|
border-bottom:9px solid #fff;
|
||||||
|
border-top:9px solid transparent;
|
||||||
|
border-left:9px solid transparent;
|
||||||
|
border-right:9px solid transparent;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.ant-input-group .ant-input:focus{
|
||||||
|
border-right: 1px solid #d9d9d9!important;
|
||||||
|
}
|
||||||
|
.ant-btn-primary.grey{
|
||||||
|
border:1px solid #BBBBBB;
|
||||||
|
background-color: #BBBBBB;
|
||||||
|
}
|
||||||
|
.userScrew .ant-row{
|
||||||
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
.screwImg{
|
.screwImg{
|
||||||
width: 34px;
|
width: 34px;
|
||||||
|
@ -29,6 +61,14 @@
|
||||||
.screwPanel .ant-radio-wrapper{
|
.screwPanel .ant-radio-wrapper{
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
.branchTable{
|
||||||
|
border:1px solid #eaeaea;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.branchTable .margin-view-overlays{
|
||||||
|
border-right: 1px solid #eaeaea;
|
||||||
|
background-color: #fbfbfb;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 400px){
|
@media screen and (max-width: 400px){
|
||||||
.setInputAddon{
|
.setInputAddon{
|
||||||
|
|
|
@ -1,56 +1,56 @@
|
||||||
import React , { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { Upload, Button, Icon } from 'antd';
|
import { Upload, Button, Icon } from 'antd';
|
||||||
import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder';
|
import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
const { Dragger } = Upload;
|
const { Dragger } = Upload;
|
||||||
class Index extends Component{
|
class Index extends Component {
|
||||||
constructor(props){
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state={
|
this.state = {
|
||||||
fileList:undefined,
|
fileList: undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onAttachmentRemove = (file) => {
|
onAttachmentRemove = (file) => {
|
||||||
if(!file.percent || file.percent === 100){
|
if (!file.percent || file.percent === 100) {
|
||||||
// this.props.confirm({
|
// this.props.confirm({
|
||||||
// content: '是否确认删除?',
|
// content: '是否确认删除?',
|
||||||
// onOk: () => {
|
// onOk: () => {
|
||||||
// this.deleteAttachment(file)
|
// this.deleteAttachment(file)
|
||||||
// },
|
// },
|
||||||
// onCancel() {
|
// onCancel() {
|
||||||
// console.log('Cancel');
|
// console.log('Cancel');
|
||||||
// },
|
// },
|
||||||
// });
|
// });
|
||||||
this.deleteAttachment(file)
|
this.deleteAttachment(file)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAttachment = (file) => {
|
deleteAttachment = (file) => {
|
||||||
|
|
||||||
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
|
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
|
||||||
axios.delete(url, {
|
axios.delete(url, {
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
if (response.data.status === 0) {
|
if (response.data.status === 0) {
|
||||||
this.setState((state) => {
|
this.setState((state) => {
|
||||||
const index = state.fileList.indexOf(file);
|
const index = state.fileList.indexOf(file);
|
||||||
const newFileList = state.fileList.slice();
|
const newFileList = state.fileList.slice();
|
||||||
newFileList.splice(index, 1);
|
newFileList.splice(index, 1);
|
||||||
return {
|
return {
|
||||||
fileList: newFileList,
|
fileList: newFileList,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
this.fileIdList(this.state.fileList);
|
this.fileIdList(this.state.fileList);
|
||||||
}else{
|
} else {
|
||||||
this.props.showNotification(response.data.message)
|
this.props.showNotification(response.data.message)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}).catch(function (error) {
|
}
|
||||||
console.log(error);
|
}).catch(function (error) {
|
||||||
});
|
console.log(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,36 +65,36 @@ class Index extends Component{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fileIdList=(fileList)=>{
|
fileIdList = (fileList) => {
|
||||||
let array = [];
|
let array = [];
|
||||||
fileList && fileList.length>0 && fileList.map((item)=>{
|
fileList && fileList.length > 0 && fileList.map((item) => {
|
||||||
return array.push(item.response && item.response.id);
|
return array.push(item.response && item.response.id);
|
||||||
})
|
})
|
||||||
array && this.props.load && this.props.load(array);
|
array && this.props.load && this.props.load(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render() {
|
||||||
//判断是否已经提交,如已提交评论则上一条评论数据清除
|
//判断是否已经提交,如已提交评论则上一条评论数据清除
|
||||||
const { isComplete } = this.props;
|
const { isComplete } = this.props;
|
||||||
const { fileList } = this.state;
|
const { fileList } = this.state;
|
||||||
|
|
||||||
let list = isComplete === true ? fileList : undefined;
|
let list = isComplete === true ? fileList : undefined;
|
||||||
const upload = {
|
const upload = {
|
||||||
name: 'file',
|
name: 'file',
|
||||||
fileList:list,
|
fileList: list,
|
||||||
action: `${getUploadActionUrl()}`,
|
action: `${getUploadActionUrl()}`,
|
||||||
onChange:this.handleChange,
|
onChange: this.handleChange,
|
||||||
onRemove: this.onAttachmentRemove,
|
onRemove: this.onAttachmentRemove,
|
||||||
};
|
};
|
||||||
|
|
||||||
return(
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Dragger {...upload} >
|
<Dragger {...upload} >
|
||||||
<Icon type="inbox" />
|
<Icon type="inbox" />
|
||||||
<p className="ant-upload-text">拖动文件或者点击此处上传</p>
|
<p className="ant-upload-text">拖动文件或者点击此处上传</p>
|
||||||
</Dragger>
|
</Dragger>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default Index;
|
export default Index;
|
|
@ -1,6 +1,5 @@
|
||||||
import React , { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { Form , Input , Select,Divider,Button,Checkbox,Dropdown,Menu, Spin} from 'antd';
|
import { Form, Input, Select, Divider, Button, Checkbox, Dropdown, Menu, Spin } from 'antd';
|
||||||
import {Link} from 'react-router-dom';
|
|
||||||
|
|
||||||
import '../Order/order.css';
|
import '../Order/order.css';
|
||||||
import './version.css';
|
import './version.css';
|
||||||
|
@ -9,56 +8,56 @@ import axios from 'axios';
|
||||||
|
|
||||||
const Option = Select.Option;
|
const Option = Select.Option;
|
||||||
const TextArea = Input.TextArea;
|
const TextArea = Input.TextArea;
|
||||||
class NewVersion extends Component{
|
class NewVersion extends Component {
|
||||||
constructor(props){
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state={
|
this.state = {
|
||||||
branch_name:"",
|
branch_name: "",
|
||||||
issue_tag_ids:"",
|
issue_tag_ids: "",
|
||||||
fixed_version_id:"",
|
fixed_version_id: "",
|
||||||
issue_chosen:undefined,
|
issue_chosen: undefined,
|
||||||
fileList:undefined,
|
fileList: undefined,
|
||||||
ischeck:undefined,
|
ischeck: undefined,
|
||||||
branches:undefined,
|
branches: undefined,
|
||||||
pull:undefined,
|
pull: undefined,
|
||||||
tag_name:'',
|
tag_name: '',
|
||||||
isSpin: false
|
isSpin: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount=()=>{
|
componentDidMount = () => {
|
||||||
this.InitData();
|
this.InitData();
|
||||||
this.getSelectList();
|
this.getSelectList();
|
||||||
}
|
}
|
||||||
|
|
||||||
InitData=()=>{
|
InitData = () => {
|
||||||
this.props.form.setFieldsValue({
|
this.props.form.setFieldsValue({
|
||||||
...this.state
|
...this.state
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getSelectList=()=>{
|
getSelectList = () => {
|
||||||
const { projectsId } = this.props.match.params;
|
const { projectsId } = this.props.match.params;
|
||||||
const url = `/projects/${projectsId}/version_releases/new.json`;
|
const url = `/projects/${projectsId}/version_releases/new.json`;
|
||||||
axios.get(url).then((result)=>{
|
axios.get(url).then((result) => {
|
||||||
if(result){
|
if (result) {
|
||||||
this.setState({
|
this.setState({
|
||||||
branches:result.data.branches,
|
branches: result.data.branches,
|
||||||
pull:result.data.branches[0]
|
pull: result.data.branches[0]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}).catch((error)=>{
|
}).catch((error) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
renderSelect=(list)=>{
|
renderSelect = (list) => {
|
||||||
if(list && list.length >0){
|
if (list && list.length > 0) {
|
||||||
return(
|
return (
|
||||||
list.map((item,key)=>{
|
list.map((item, key) => {
|
||||||
return(
|
return (
|
||||||
<Option key={key+1} value={item.id+""}>{item.name}</Option>
|
<Option key={key + 1} value={item.id + ""}>{item.name}</Option>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -66,36 +65,36 @@ class NewVersion extends Component{
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建
|
// 创建
|
||||||
handleSubmit=(draft)=>{
|
handleSubmit = (draft) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
isSpin: true
|
isSpin: true
|
||||||
})
|
})
|
||||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||||
if(!err){
|
if (!err) {
|
||||||
const { projectsId } = this.props.match.params;
|
const { projectsId } = this.props.match.params;
|
||||||
const { pull,tag_name,ischeck} = this.state;
|
const { pull, tag_name, ischeck } = this.state;
|
||||||
const url = `/projects/${projectsId}/version_releases.json`;
|
const url = `/projects/${projectsId}/version_releases.json`;
|
||||||
// if(values.issue_type==="普通"){
|
// if(values.issue_type==="普通"){
|
||||||
// values.issue_type="1"
|
// values.issue_type="1"
|
||||||
// }
|
// }
|
||||||
axios.post(url,{
|
axios.post(url, {
|
||||||
...values,
|
...values,
|
||||||
tag_name:tag_name,
|
tag_name: tag_name,
|
||||||
draft:draft,
|
draft: draft,
|
||||||
prerelease:ischeck,
|
prerelease: ischeck,
|
||||||
target_commitish:pull,
|
target_commitish: pull,
|
||||||
}).then(result=>{
|
}).then(result => {
|
||||||
if(result){
|
if (result) {
|
||||||
this.setState({
|
this.setState({
|
||||||
isSpin: false
|
isSpin: false
|
||||||
})
|
})
|
||||||
this.props.history.push(`/projects/${projectsId}/version`);
|
this.props.history.push(`/projects/${projectsId}/version`);
|
||||||
}
|
}
|
||||||
}).catch(error=>{
|
}).catch(error => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
})
|
})
|
||||||
|
|
||||||
}else{
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
isSpin: false
|
isSpin: false
|
||||||
})
|
})
|
||||||
|
@ -104,27 +103,27 @@ class NewVersion extends Component{
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取上传后的文件id数组
|
// 获取上传后的文件id数组
|
||||||
UploadFunc=(fileList)=>{
|
UploadFunc = (fileList) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
fileList
|
fileList
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
RedieonChange=(e)=>{
|
RedieonChange = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
ischeck:e.target.checked
|
ischeck: e.target.checked
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Preservation=()=>{
|
Preservation = () => {
|
||||||
alert(this.state.ischeck)
|
alert(this.state.ischeck)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMenu =(array,id)=>{
|
renderMenu = (array, id) => {
|
||||||
return(
|
return (
|
||||||
<Menu>
|
<Menu>
|
||||||
{
|
{
|
||||||
array && array.length > 0 && array.map((item,key)=>{
|
array && array.length > 0 && array.map((item, key) => {
|
||||||
return(
|
return (
|
||||||
<Menu.Item key={item} onClick={()=>this.getOption(item)}>{item}</Menu.Item>
|
<Menu.Item key={item} onClick={() => this.getOption(item)}>{item}</Menu.Item>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -132,78 +131,77 @@ class NewVersion extends Component{
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
getOption=(name)=>{
|
getOption = (name) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
pull:name
|
pull: name
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
changmodelname=(e)=>{
|
changmodelname = (e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
tag_name:e.target.value
|
tag_name: e.target.value
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render() {
|
||||||
const { getFieldDecorator } = this.props.form;
|
const { getFieldDecorator } = this.props.form;
|
||||||
const {branches,pull,tag_name, isSpin} = this.state;
|
const { branches, pull, tag_name, isSpin } = this.state;
|
||||||
|
|
||||||
return(
|
return (
|
||||||
<div className="main">
|
<div className="main">
|
||||||
<Form>
|
<Form>
|
||||||
<h1 style={{marginLeft:15,marginTop:20}}>发布新版</h1>
|
<h1 style={{ marginLeft: 15, marginTop: 20 }}>发布新版</h1>
|
||||||
<h5 style={{marginLeft:15}}>发布一个特定的打包好的项目版本</h5>
|
<h5 style={{ marginLeft: 15 }}>发布一个特定的打包好的项目版本</h5>
|
||||||
<Divider/>
|
<Divider />
|
||||||
<div style={{display:'flex'}}>
|
<div style={{ display: 'flex' }}>
|
||||||
<Input placeholder="标签名称" style={{width:180,marginLeft:15}} value={tag_name} onChange={this.changmodelname} />
|
<Input placeholder="标签名称" style={{ width: 180, marginLeft: 15 }} value={tag_name} onChange={this.changmodelname} />
|
||||||
<div style={{marginLeft:20,marginRight:20,lineHeight: '32px'}}>@ </div>
|
<div style={{ marginLeft: 20, marginRight: 20, lineHeight: '32px' }}>@ </div>
|
||||||
<Dropdown overlay={this.renderMenu(branches &&branches,'pull')} trigger={['click']} placement="bottomCenter">
|
<Dropdown overlay={this.renderMenu(branches && branches, 'pull')} trigger={['click']} placement="bottomCenter">
|
||||||
<Button style={{width:180}}>{pull}</Button>
|
<Button style={{ width: 180 }}>{pull}</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
<div style={{display:'flex'}}>
|
<div style={{ display: 'flex' }}>
|
||||||
<div className="versionmilepostleft">
|
<div className="versionmilepostleft">
|
||||||
<h1>标题</h1>
|
<h1>标题</h1>
|
||||||
<div>
|
<div>
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
{getFieldDecorator('name', {
|
{getFieldDecorator('name', {
|
||||||
rules: [{
|
rules: [{
|
||||||
required: true, message: '请输入标题'
|
required: true, message: '请输入标题'
|
||||||
}],
|
}],
|
||||||
})(
|
})(
|
||||||
<Input placeholder="标题" maxLength="32"/>
|
<Input placeholder="标题" maxLength="32" />
|
||||||
)}
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
<h1>内容</h1>
|
<h1>内容</h1>
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
{getFieldDecorator('body', {
|
{getFieldDecorator('body', {
|
||||||
rules: [{
|
rules: [{
|
||||||
required: true, message: '请输入描述内容'
|
required: true, message: '请输入描述内容'
|
||||||
}],
|
}],
|
||||||
})(
|
})(
|
||||||
<TextArea placeholder="添加描述内容..." style={{'min-height':"150px"}}/>
|
<TextArea placeholder="添加描述内容..." style={{ 'min-height': "150px" }} />
|
||||||
|
)}
|
||||||
)}
|
</Form.Item>
|
||||||
</Form.Item>
|
{/* <UploadComponent load={this.UploadFunc} style={{width:80,marginLeft:15}}></UploadComponent> */}
|
||||||
{/* <UploadComponent load={this.UploadFunc} style={{width:80,marginLeft:15}}></UploadComponent> */}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
<div className="fr mb15">
|
||||||
|
<Checkbox onChange={this.RedieonChange}>标记为预行版<span className="ml15 color-grey-9 font-13">(此版本不适合生产使用)</span></Checkbox>
|
||||||
|
</div>
|
||||||
|
<div className="clearfix mt15" style={{ marginTop: 5 }} >
|
||||||
|
<Spin spinning={isSpin}>
|
||||||
|
<a className='topWrapper_btn_close fr' onClick={() => this.handleSubmit(true)} style={{ marginLeft: 15 }} >保存草稿</a>
|
||||||
|
<a className='topWrapper_btn fr' onClick={() => this.handleSubmit(false)} style={{ marginRight: 15 }}>发布版本</a>
|
||||||
|
</Spin>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Divider/>
|
|
||||||
<div className="fr mb15">
|
|
||||||
<Checkbox onChange={this.RedieonChange}>标记为预行版<span className="ml15 color-grey-9 font-13">(此版本不适合生产使用)</span></Checkbox>
|
|
||||||
</div>
|
|
||||||
<div className="clearfix mt15" style={{marginTop:5}} >
|
|
||||||
<Spin spinning={isSpin}>
|
|
||||||
<a className='topWrapper_btn_close fr' onClick={()=>this.handleSubmit(true)} style={{marginLeft:15}} >保存草稿</a>
|
|
||||||
<a className='topWrapper_btn fr' onClick={()=>this.handleSubmit(false)} style={{marginRight:15}}>发布版本</a>
|
|
||||||
</Spin>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,71 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
border-bottom: 1px solid #EEEEEE;
|
border-bottom: 1px solid #EEEEEE;
|
||||||
flex-wrap: wrap;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.topWrapper_btn {
|
.topWrapper_btn_new {
|
||||||
background: #21ba45;
|
background: #fff;
|
||||||
color: #FFFFFF!important;
|
color: #5091FF!important;
|
||||||
padding:0px 12px;
|
padding:0px 12px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
border:1px solid #5091FF;
|
||||||
|
}
|
||||||
|
.versionInfo{
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.versionInfo_left{
|
||||||
|
display: flex;
|
||||||
|
width: 30%;
|
||||||
|
padding-top: 20px;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
.versionInfo_right{
|
||||||
|
flex: 1;
|
||||||
|
padding: 20px 0px 20px 15px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
border-left: 1px solid #eee;
|
||||||
|
}
|
||||||
|
.versionTag{
|
||||||
|
display: inline;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding:2px 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.versionTag.yellow{
|
||||||
|
background-color: #FBBC06;
|
||||||
|
}
|
||||||
|
.versionTag.green{
|
||||||
|
background-color: #20BA45;
|
||||||
|
}
|
||||||
|
.versionTag.orange{
|
||||||
|
background-color: #F2711D;
|
||||||
|
}
|
||||||
|
.versionName{
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.versionName::before{
|
||||||
|
position: absolute;
|
||||||
|
left: -19px;
|
||||||
|
top:8px;
|
||||||
|
content: '';
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
background-color: #5091FF;
|
||||||
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import React , { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import {Link} from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { Input } from 'antd';
|
|
||||||
import NoneData from '../Nodata';
|
import NoneData from '../Nodata';
|
||||||
import './version.css';
|
import './version.css';
|
||||||
import { getImageUrl } from 'educoder';
|
import { getImageUrl } from 'educoder';
|
||||||
|
@ -11,160 +10,112 @@ import axios from 'axios';
|
||||||
* data:列表接口返回的所有数据,
|
* data:列表接口返回的所有数据,
|
||||||
* issues:列表数组,
|
* issues:列表数组,
|
||||||
* isSpin:加载中,
|
* isSpin:加载中,
|
||||||
* search:搜索关键字,
|
|
||||||
* author_id:发布者id,
|
|
||||||
* assigned_to_id:指派给。。。的id,
|
|
||||||
* limit:每页条数,
|
|
||||||
* page:当前页,
|
|
||||||
* search_count:列表总条数
|
|
||||||
* issue_type:搜索条件
|
|
||||||
*/
|
*/
|
||||||
class version extends Component{
|
class version extends Component {
|
||||||
constructor(props){
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state={
|
this.state = {
|
||||||
issue_chosen:undefined,
|
issue_chosen: undefined,
|
||||||
data:undefined,
|
data: undefined,
|
||||||
issues:undefined,
|
releases:undefined,
|
||||||
isSpin:false,
|
issues: undefined,
|
||||||
search:undefined,
|
isSpin: false,
|
||||||
author_id:undefined,
|
search: undefined,
|
||||||
assigned_to_id:undefined,
|
search_count: undefined,
|
||||||
limit:15,
|
|
||||||
page:1,
|
|
||||||
search_count:undefined,
|
|
||||||
issue_type:undefined
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount=()=>{
|
componentDidMount = () => {
|
||||||
this.getIssueList();
|
this.getIssueList();
|
||||||
}
|
}
|
||||||
// 获取列表数据
|
// 获取列表数据
|
||||||
getIssueList=(page,limit,search,author_id,assigned_to_id,id,value)=>{
|
getIssueList = () => {
|
||||||
const { projectsId } = this.props.match.params;
|
const { projectsId } = this.props.match.params;
|
||||||
const url = `/projects/${projectsId}/version_releases.json`;
|
const url = `/projects/${projectsId}/version_releases.json`;
|
||||||
axios.get(url).then((result)=>{
|
axios.get(url).then((result) => {
|
||||||
if(result){
|
if (result) {
|
||||||
this.setState({
|
this.setState({
|
||||||
data:result.data,
|
data: result.data,
|
||||||
issues:result.data.issues,
|
releases:result.data.releases,
|
||||||
search_count:result.data.search_count,
|
issues: result.data.issues,
|
||||||
isSpin:false
|
isSpin: false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}).catch((error)=>{
|
}).catch((error) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 显示版本描述
|
||||||
|
showBody=(key,flag)=>{
|
||||||
|
let { releases } = this.state;
|
||||||
|
releases[key].bodyshow = !flag;
|
||||||
|
this.setState({
|
||||||
|
releases
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
render(){
|
|
||||||
const { projectsId } = this.props.match.params;
|
const { projectsId } = this.props.match.params;
|
||||||
const{data}=this.state
|
const { data , releases } = this.state
|
||||||
const renderList =()=>{
|
const renderList = () => {
|
||||||
if(data && data.releases && data.releases.length>0 ){
|
if (releases && releases.length > 0) {
|
||||||
return(
|
return (
|
||||||
<div>{
|
<div>
|
||||||
data.releases.map((item,key)=>{
|
{
|
||||||
return(
|
releases.map((item, key) => {
|
||||||
<div key={key}>
|
return (
|
||||||
{
|
<div className="versionInfo" key={key}>
|
||||||
item && item.id ?
|
<span className="versionInfo_left">
|
||||||
<div>
|
<span className={`${item.draft === "稳定" ?"versionTag green":"versionTag yellow"}`}>{item.draft}</span>
|
||||||
<div style={{display:'flex'}}>
|
<span className="mt10">{item.created_at}</span>
|
||||||
<div className="versionleft">
|
<span className="color-grey-8">
|
||||||
<div className="versionrighe"></div><span className={item&&item.draft==="稳定"?"opendversionetail":"closedversionetail"} style={{marginTop:5,margin:'auto',marginRight:15}}>{item.draft} </span>
|
<i className="iconfont icon-biaoqian3 mr3 font-14"></i>
|
||||||
</div>
|
{item.tag_name}
|
||||||
<div className="version_line_one">
|
</span>
|
||||||
<p className="versionrectangle"> </p>
|
</span>
|
||||||
</div>
|
<div className="versionInfo_right">
|
||||||
<div className="versionrighe">
|
<span className="versionName">
|
||||||
<h1 style={{marginLeft:15,marginTop:5}}>{item.name}
|
<span className="task-hide">{item.name}</span>
|
||||||
{
|
<Link to={`/projects/${projectsId}/coders/version/${item.version_id}/update`} className="color-blue ml3 font-12">(编辑)</Link>
|
||||||
data && data.user_permission ?
|
</span>
|
||||||
<Link to={`/projects/${projectsId}/version/${item.version_id}/upversion`} style={{color:'blue',fontSize:10,marginLeft:5}}>(编辑)</Link>
|
<span className="color-grey-3">
|
||||||
: ''
|
<i className={`${item.bodyshow ? "iconfont icon-sanjiaoxing-down color-grey-8 mr3 font-14":"iconfont icon-triangle color-grey-8 mr3 font-14"}`} onClick={()=>this.showBody(key,item.bodyshow)}></i>
|
||||||
}
|
{item.user_name}:<span className="color-grey-8">发布了这个版本,并在发布后提交给{item.target_commitish}</span>
|
||||||
</h1>
|
</span>
|
||||||
</div>
|
{
|
||||||
|
item.bodyshow && <p className="mt10">{item.body}</p>
|
||||||
|
}
|
||||||
</div>
|
<p className="mt10 pl3">
|
||||||
<div style={{display:'flex'}}>
|
{/* <span className="commitKey mr20">{item.commit_id}</span> */}
|
||||||
<div className="versionleft">
|
<a href={item.tarball_url} style={{color:"#4CC1DA"}} className="mr30"><i className="iconfont icon-TAR font-18 mr5"></i>TAR</a>
|
||||||
<span style={{marginTop:5,margin:'auto',marginRight:15}}>{item.tag_name} </span>
|
<a href={item.zipball_url} style={{color:"#28BD6C"}}><i className="iconfont icon-ZIP font-18 mr5"></i>ZIP</a>
|
||||||
</div>
|
</p>
|
||||||
<div className="version_line_one">
|
</div>
|
||||||
<p style={{width:4}}> </p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div className="versionrighe">
|
|
||||||
<h5 style={{marginLeft:15,marginTop:10}}>{item.body} </h5>
|
|
||||||
<div className="ml15">
|
|
||||||
<Link to={`/users/${item && item.login}/projects`} className="show-user-link">
|
|
||||||
<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr5 radius"/>
|
|
||||||
<span className="mr10 ver-middle">{item.user_name}</span>
|
|
||||||
</Link>
|
|
||||||
<span className="color-grey-9 ver-middle">发布于{item.created_at}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{display:'flex'}}>
|
|
||||||
<div className="versionleft">
|
|
||||||
<span style={{marginTop:5,marginRight:15}}></span>
|
|
||||||
</div>
|
|
||||||
<div className="version_line_tpw">
|
|
||||||
<p style={{width:4}}> </p>
|
|
||||||
</div>
|
|
||||||
<div className="versionrighe">
|
|
||||||
<h1 style={{marginLeft:15,marginTop:10}}>下载附件
|
|
||||||
</h1>
|
|
||||||
<a href={item.zipball_url} download="源代码(ZIP)" style={{color:'blue',marginLeft:15}}>源代码(ZIP)</a>
|
|
||||||
<a href={item.tarball_url} download="源文件(TAR.GZ)" style={{color:'blue',marginLeft:15}}>源文件(TAR.GZ)</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{display:'flex'}}>
|
|
||||||
<div className="versionleft">
|
|
||||||
<span style={{marginTop:5,marginRight:15}}></span>
|
|
||||||
</div>
|
|
||||||
<div className="version_line_tpw">
|
|
||||||
<p style={{width:4}}> </p>
|
|
||||||
</div>
|
|
||||||
<div className="versionrighe">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}else{
|
} else {
|
||||||
return(
|
return (
|
||||||
<NoneData _html="暂时还没有相关数据哦!" />
|
<NoneData _html="暂时还没有相关数据哦!" />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(
|
return (
|
||||||
<div className="main">
|
<div className="main">
|
||||||
<div className="topWrapper">
|
<div className="topWrapper">
|
||||||
<h1>版本发布</h1>
|
<span className="font-18 color-grey-3">版本发布</span>
|
||||||
{
|
{
|
||||||
data && data.user_permission ?
|
data && data.user_permission ?
|
||||||
<Link to={`/projects/${projectsId}/version/new`} className="topWrapper_btn">发布新版</Link>
|
<Link to={`/projects/${projectsId}/coders/version/new`} className="topWrapper_btn_new">+ 发布新版</Link>
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="releasesVersion">
|
||||||
{renderList()}
|
{renderList()}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
ul,ol,dl{
|
ul,ol,dl{
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
/* #EAEBEC */
|
||||||
.newMain{
|
.newMain{
|
||||||
background-color: #fff;
|
background-color: #EAEBEC;
|
||||||
}
|
}
|
||||||
.main{
|
.main{
|
||||||
width: 1200px;
|
width: 1200px;
|
||||||
padding:20px 0px;
|
padding:20px;
|
||||||
margin:0px auto;
|
margin:20px auto;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
.radius-2{
|
.radius-2{
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
|
|
@ -136,10 +136,6 @@ pre.prettyprint {
|
||||||
color: #FF6545
|
color: #FF6545
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-orange {
|
|
||||||
color: #ee4a1f !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.color-orange02 {
|
.color-orange02 {
|
||||||
color: #f79f88 !important;
|
color: #f79f88 !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,43 +12,11 @@ const CommonWork = Loadable({
|
||||||
loader: () => import('./busyWork/commonWork'),
|
loader: () => import('./busyWork/commonWork'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
// 讨论
|
|
||||||
const Boards = Loadable({
|
|
||||||
loader: () => import('./boards'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
//教师列表
|
|
||||||
const TeacherList = Loadable({
|
|
||||||
loader: () => import('./members/teacherList'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
//主签到目录
|
//主签到目录
|
||||||
const Signinmain = Loadable({
|
const Signinmain = Loadable({
|
||||||
loader: () => import('./signin/mymain/Signinmain'),
|
loader: () => import('./signin/mymain/Signinmain'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
});
|
});
|
||||||
//学生列表
|
|
||||||
const StudentsList = Loadable({
|
|
||||||
loader: () => import('./members/studentsList'),
|
|
||||||
loading: Loading,
|
|
||||||
});
|
|
||||||
//分班列表
|
|
||||||
const CourseGroupList = Loadable({
|
|
||||||
loader: () => import('./members/CourseGroupList'),
|
|
||||||
loading: Loading,
|
|
||||||
});
|
|
||||||
|
|
||||||
const Eduinforms = Loadable({
|
|
||||||
loader: () => import('./gradinforms/Eduinforms'),
|
|
||||||
loading: Loading,
|
|
||||||
});
|
|
||||||
|
|
||||||
//2019.10.29 统计
|
|
||||||
const Statistics = Loadable({
|
|
||||||
loader: () => import('./statistics/Statistics'),
|
|
||||||
loading: Loading,
|
|
||||||
});
|
|
||||||
|
|
||||||
const Elearning = Loadable({
|
const Elearning = Loadable({
|
||||||
loader: () => import('./elearning/Elearning'),
|
loader: () => import('./elearning/Elearning'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
|
@ -58,38 +26,13 @@ const Exercise = Loadable({
|
||||||
loader: () => import('./exercise/Exercise'),
|
loader: () => import('./exercise/Exercise'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
//
|
|
||||||
const Poll = Loadable({
|
|
||||||
loader: () => import('./poll/Poll'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
// 资源
|
|
||||||
const Resourcelist = Loadable({
|
|
||||||
loader: () => import('./Resource/index'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
// 视频
|
|
||||||
const CourseVideo = Loadable({
|
|
||||||
loader: () => import('./Video/VideoIndex'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
//实训作业
|
//实训作业
|
||||||
const ShixunHomework = Loadable({
|
const ShixunHomework = Loadable({
|
||||||
loader: () => import('./shixunHomework/shixunHomework'),
|
loader: () => import('./shixunHomework/shixunHomework'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
|
||||||
const GraduationTopics = Loadable({
|
|
||||||
loader: () => import('./graduation/topics'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
const GraduationTasks = Loadable({
|
|
||||||
loader: () => import('./graduation/tasks'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
class ListPageIndex extends Component {
|
class ListPageIndex extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -226,35 +169,6 @@ class ListPageIndex extends Component {
|
||||||
(props) => (<CommonWork {...this.props} {...props} {...this.state} />)
|
(props) => (<CommonWork {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
<Route exact path="/classrooms/:coursesId/boards/:boardId"
|
|
||||||
render={
|
|
||||||
(props) => (<Boards {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
{/*视频列表*/}
|
|
||||||
<Route path="/classrooms/:coursesId/course_video/:videoId"
|
|
||||||
render={
|
|
||||||
(props) => (<CourseVideo {...this.props} {...props} {...this.state} homedirectory={this.state.homedirectory} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
<Route path="/classrooms/:coursesId/course_videos"
|
|
||||||
render={
|
|
||||||
(props) => (<CourseVideo {...this.props} {...props} {...this.state} homedirectory={this.state.homedirectory} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
{/* 教师列表*/}
|
|
||||||
<Route path="/classrooms/:coursesId/teachers"
|
|
||||||
render={
|
|
||||||
(props) => (<TeacherList updatabanners={() => this.updatabanners()} {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
{/* 学生列表*/}
|
|
||||||
<Route path="/classrooms/:coursesId/students"
|
|
||||||
render={
|
|
||||||
(props) => (<StudentsList {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
{/* 主签到 */}
|
{/* 主签到 */}
|
||||||
<Route path="/classrooms/:coursesId/attendances"
|
<Route path="/classrooms/:coursesId/attendances"
|
||||||
render={
|
render={
|
||||||
|
@ -262,28 +176,12 @@ class ListPageIndex extends Component {
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
<Route path="/classrooms/:coursesId/course_groups/:course_group_id"
|
|
||||||
render={
|
|
||||||
(props) => (<StudentsList {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
<Route path="/classrooms/:coursesId/course_groups"
|
|
||||||
render={
|
|
||||||
(props) => (<CourseGroupList {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
|
|
||||||
<Route path="/classrooms/:coursesId/exercises/:Id"
|
<Route path="/classrooms/:coursesId/exercises/:Id"
|
||||||
render={
|
render={
|
||||||
(props) => (<Exercise {...this.props} {...props} {...this.state} />)
|
(props) => (<Exercise {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
<Route path="/classrooms/:coursesId/polls/:Id"
|
|
||||||
render={
|
|
||||||
(props) => (<Poll {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
{/* 实训作业子页面*/}
|
{/* 实训作业子页面*/}
|
||||||
<Route path="/classrooms/:coursesId/shixun_homework/:category_id"
|
<Route path="/classrooms/:coursesId/shixun_homework/:category_id"
|
||||||
render={
|
render={
|
||||||
|
@ -291,22 +189,6 @@ class ListPageIndex extends Component {
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
{/*课堂统计列表2019.10.29 */}
|
|
||||||
|
|
||||||
<Route path="/classrooms/:coursesId/statistics"
|
|
||||||
render={
|
|
||||||
(props) => (<Statistics {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
|
|
||||||
|
|
||||||
{/*公告栏列表*/}
|
|
||||||
|
|
||||||
<Route path="/classrooms/:coursesId/informs"
|
|
||||||
render={
|
|
||||||
(props) => (<Eduinforms {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
{/*在线学习*/}
|
{/*在线学习*/}
|
||||||
<Route
|
<Route
|
||||||
path="/classrooms/:coursesId/online_learning"
|
path="/classrooms/:coursesId/online_learning"
|
||||||
|
@ -321,35 +203,6 @@ class ListPageIndex extends Component {
|
||||||
(props) => (<ShixunHomework {...this.props} {...props} {...this.state} />)
|
(props) => (<ShixunHomework {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
|
|
||||||
<Route path="/classrooms/:coursesId/files/:main_id"
|
|
||||||
render={
|
|
||||||
(props) => (<Resourcelist {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
<Route path="/classrooms/:coursesId/file/:Id"
|
|
||||||
render={
|
|
||||||
(props) => (<Resourcelist {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
|
|
||||||
<Route path="/classrooms/:coursesId/graduation_topics/:Id"
|
|
||||||
render={
|
|
||||||
(props) => (<GraduationTopics {...this.props} {...props} {...this.state} />)
|
|
||||||
}></Route>
|
|
||||||
<Route path="/classrooms/:coursesId/graduation_tasks/:Id"
|
|
||||||
render={
|
|
||||||
(props) => (<GraduationTasks {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
{/* 默认 */}
|
|
||||||
<Route path="/classrooms/:coursesId"
|
|
||||||
render={
|
|
||||||
(props) => (<StudentsList {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
|
|
||||||
</Switch>
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,470 +0,0 @@
|
||||||
import React, {Component} from "react";
|
|
||||||
import {WordsBtn} from 'educoder';
|
|
||||||
import {Tooltip, message} from 'antd';
|
|
||||||
import {Link} from 'react-router-dom';
|
|
||||||
import {getImageUrl} from 'educoder';
|
|
||||||
import axios from 'axios'
|
|
||||||
import {getUrl} from 'educoder';
|
|
||||||
import moment from 'moment'
|
|
||||||
import CoursesListType from '../coursesPublic/CoursesListType';
|
|
||||||
import Showoldfiles from "../coursesPublic/Showoldfiles";
|
|
||||||
import Modals from '../../modals/Modals';
|
|
||||||
|
|
||||||
class Fileslistitem extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
settingList = (bools) => {
|
|
||||||
let {discussMessage} = this.props
|
|
||||||
console.log(discussMessage);
|
|
||||||
this.setState({
|
|
||||||
discussMessageid: discussMessage.id
|
|
||||||
})
|
|
||||||
if (bools === true) {
|
|
||||||
this.props.Settingtypes(discussMessage.id)
|
|
||||||
} else {
|
|
||||||
this.props.Settingtypess(discussMessage.id,discussMessage.title,discussMessage.link)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
//外链
|
|
||||||
showfiless = (url,id) => {
|
|
||||||
window.open(url)
|
|
||||||
let urls=`/files/${id}/update_visits.json`;
|
|
||||||
axios.post(urls,{
|
|
||||||
}).then((result)=>{
|
|
||||||
if(result.data.status===0){
|
|
||||||
this.props.Updateresourcepage()
|
|
||||||
}else{
|
|
||||||
this.props.showNotification(result.data.message);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
showfiles = (list) => {
|
|
||||||
if (this.props.checkIfLogin() === false) {
|
|
||||||
this.props.showLoginDialog()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// if(this.props.checkIfProfileCompleted()===false){
|
|
||||||
// this.setState({
|
|
||||||
// AccountProfiletype:true
|
|
||||||
// })
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// if(this.props.checkIfProfessionalCertification()===false){
|
|
||||||
// this.props.showProfileCompleteDialog()
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (list.is_history_file === false) {
|
|
||||||
// this.props.DownloadFileA(list.title,list.url)
|
|
||||||
//window.location.href=list.url;
|
|
||||||
window.open(list.url, '_blank');
|
|
||||||
} else {
|
|
||||||
let {discussMessage, coursesId} = this.props
|
|
||||||
let file_id = discussMessage.id
|
|
||||||
let url = "/files/" + file_id + "/histories.json"
|
|
||||||
axios.get(url, {
|
|
||||||
params: {
|
|
||||||
course_id: coursesId
|
|
||||||
},
|
|
||||||
}).then((result) => {
|
|
||||||
|
|
||||||
if (result.data.attachment_histories.length === 0) {
|
|
||||||
// if(result.data.is_pdf===true){
|
|
||||||
// this.props.ShowOnlinePdf(result.data.url)
|
|
||||||
// //预览pdf
|
|
||||||
// }else{
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// this.props.DownloadFileA(result.data.title,result.data.url)
|
|
||||||
window.open(list.url, '_blank');
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
Showoldfiles: true,
|
|
||||||
allfiles: result.data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
closaoldfilesprops = () => {
|
|
||||||
this.setState({
|
|
||||||
Showoldfiles: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onDelete = (id) => {
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
Modalstype: true,
|
|
||||||
Modalstopval: "是否确认删除?",
|
|
||||||
ModalCancel: this.cancelmodel,
|
|
||||||
ModalSave: () => this.savedelete(id),
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelmodel = () => {
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
Modalstype: false,
|
|
||||||
Loadtype: false,
|
|
||||||
Modalstopval: "",
|
|
||||||
ModalCancel: "",
|
|
||||||
ModalSave: "",
|
|
||||||
checkBoxValues: [],
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
savedelete = (id) => {
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
Modalstype: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
const cid = this.props.match.params.coursesId
|
|
||||||
const url = `/files/bulk_delete.json`;
|
|
||||||
axios.delete(url, {
|
|
||||||
data: {
|
|
||||||
course_id: cid,
|
|
||||||
ids: [id],
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.status == 0) {
|
|
||||||
//Modalstopval:response.data.message,
|
|
||||||
|
|
||||||
this.props.updatafiledfun()
|
|
||||||
this.setState({
|
|
||||||
// Modalstype:true,
|
|
||||||
// Modalstopval:"删除成功",
|
|
||||||
ModalsBottomval: "",
|
|
||||||
// ModalSave:this.cancelmodel,
|
|
||||||
// Loadtype:true,
|
|
||||||
checkBoxValues: [],
|
|
||||||
checkAllValue: false
|
|
||||||
})
|
|
||||||
|
|
||||||
this.props.showNotification("删除成功");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
eventStop = (event) => {
|
|
||||||
event.stopPropagation()
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
|
|
||||||
const {
|
|
||||||
checkBox,
|
|
||||||
discussMessage, index
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
let bools = discussMessage.link && discussMessage.link ? false : true;
|
|
||||||
return (
|
|
||||||
<div className="graduateTopicList boardsList">
|
|
||||||
|
|
||||||
{/*提示*/}
|
|
||||||
{this.state.Modalstype && this.state.Modalstype === true ? <Modals
|
|
||||||
modalsType={this.state.Modalstype}
|
|
||||||
modalsTopval={this.state.Modalstopval}
|
|
||||||
modalCancel={this.state.ModalCancel}
|
|
||||||
modalSave={this.state.ModalSave}
|
|
||||||
modalsBottomval={this.state.ModalsBottomval}
|
|
||||||
loadtype={this.state.Loadtype}
|
|
||||||
/> : ""}
|
|
||||||
<Showoldfiles
|
|
||||||
{...this.props}
|
|
||||||
visible={this.state.Showoldfiles}
|
|
||||||
allfiles={this.state.allfiles}
|
|
||||||
closaoldfilesprops={this.closaoldfilesprops}
|
|
||||||
/>
|
|
||||||
<style>{`
|
|
||||||
.graduateTopicList .ant-checkbox-input {
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
.graduateTopicList .ant-checkbox-wrapper {
|
|
||||||
margin-top: 0px;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
|
|
||||||
|
|
||||||
<style>{`
|
|
||||||
.boardsList .panel-list-img {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
{/*<a href={"/users/"+this.props.user.login} alt="用户"*/}
|
|
||||||
{/*style={{"width": "50px", "height": "50px", "display": "block", margin: "0 10px"}}>*/}
|
|
||||||
{/*<img*/}
|
|
||||||
{/*alt="1?1529221779" className="panel-list-img mr15" height="50"*/}
|
|
||||||
{/*src={getImageUrl("images/"+discussMessage.author.image_url)} width="50"*/}
|
|
||||||
{/*></img>*/}
|
|
||||||
{/*</a>*/}
|
|
||||||
|
|
||||||
<style>{`
|
|
||||||
.boardsList .contentSection{
|
|
||||||
margin-left:0px;
|
|
||||||
}
|
|
||||||
.maxwidth580{
|
|
||||||
max-width: 580px;
|
|
||||||
overflow:hidden;
|
|
||||||
text-overflow:ellipsis;
|
|
||||||
white-space:nowrap
|
|
||||||
}
|
|
||||||
.mt2{
|
|
||||||
margin-top:2px;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
<div className="clearfix ds pr contentSection" style={{cursor: this.props.isAdmin ? "pointer" : "default"}}
|
|
||||||
onClick={() => window.$(`.sourceitem${index} input`).click()}>
|
|
||||||
<h6 onClick={(event) => this.eventStop(event)}>
|
|
||||||
<span className={`sourceitem${index} fl mr12 mt3`}>
|
|
||||||
{checkBox}
|
|
||||||
</span>
|
|
||||||
{
|
|
||||||
this.props.isAdmin ?
|
|
||||||
(bools === true ?
|
|
||||||
<a
|
|
||||||
// href={"/classrooms/" + coursesId + "/graduation/graduation_tasks/" + categoryid + "/" + taskid + "/list"}
|
|
||||||
onClick={() => this.showfiles(discussMessage)}
|
|
||||||
title={discussMessage.title}
|
|
||||||
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a>
|
|
||||||
:
|
|
||||||
<a
|
|
||||||
// href={"/classrooms/" + coursesId + "/graduation/graduation_tasks/" + categoryid + "/" + taskid + "/list"}
|
|
||||||
onClick={() => this.showfiless(discussMessage.link,discussMessage.id)}
|
|
||||||
title={discussMessage.title}
|
|
||||||
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a>
|
|
||||||
)
|
|
||||||
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
{
|
|
||||||
this.props.isStudent ?
|
|
||||||
(bools === true ?
|
|
||||||
<a
|
|
||||||
onClick={() => this.showfiles(discussMessage)}
|
|
||||||
title={discussMessage.title}
|
|
||||||
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a>
|
|
||||||
|
|
||||||
:
|
|
||||||
<a
|
|
||||||
onClick={() => this.showfiless(discussMessage.link,discussMessage.id)}
|
|
||||||
title={discussMessage.title}
|
|
||||||
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a>
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
this.props.isNotMember === true ?
|
|
||||||
discussMessage.is_lock === true ?
|
|
||||||
<span className="fl mt3 font-16 font-bd color-dark maxwidth580 pointer"
|
|
||||||
title={"私有属性,非课堂成员不能访问"}>{discussMessage.title}</span>
|
|
||||||
:
|
|
||||||
(bools === true ?
|
|
||||||
|
|
||||||
<a
|
|
||||||
onClick={() => this.showfiles(discussMessage)}
|
|
||||||
title={discussMessage.title}
|
|
||||||
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a> :
|
|
||||||
|
|
||||||
<a
|
|
||||||
onClick={() =>this.showfiless(discussMessage.link,discussMessage.id)}
|
|
||||||
title={discussMessage.title}
|
|
||||||
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.title}</a>
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
discussMessage.is_lock === true ?
|
|
||||||
<Tooltip title={"私有属性,非课堂成员不能访问"} placement="bottom">
|
|
||||||
<i className="iconfont icon-guansuo color-grey-c ml10 font-16 fl mt4"></i>
|
|
||||||
</Tooltip>
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
.fwlz{
|
|
||||||
width:40px;
|
|
||||||
height:20px;
|
|
||||||
border-radius:2px;
|
|
||||||
border:1px solid rgba(250,100,0,1);
|
|
||||||
font-size:12px;
|
|
||||||
font-family:MicrosoftYaHei;
|
|
||||||
color:rgba(250,100,0,1);
|
|
||||||
text-align: center;
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{
|
|
||||||
discussMessage.link && discussMessage.link ?
|
|
||||||
<p className="fl mt3 fwlz " style={{
|
|
||||||
cursor:"auto"
|
|
||||||
}}>外链</p>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
}
|
|
||||||
|
|
||||||
{discussMessage.is_publish === false ? <CoursesListType typelist={["未发布"]} typesylename={""}/> : ""}
|
|
||||||
|
|
||||||
{this.props.isAdmin ?
|
|
||||||
<span className={"fr mt2"} onClick={(event) => this.eventStop(event)}>
|
|
||||||
<WordsBtn style="blue" className="colorblue font-16 ml20 fr">
|
|
||||||
<a className="btn colorblue fontweight400"
|
|
||||||
onClick={() => this.settingList(bools)}>设置</a>
|
|
||||||
</WordsBtn>
|
|
||||||
</span> : ""}
|
|
||||||
|
|
||||||
{this.props.isStudent === true && this.props.current_user.login === discussMessage.author.login ?
|
|
||||||
<span className={"fr mt2"} onClick={(event) => this.eventStop(event)}>
|
|
||||||
|
|
||||||
<WordsBtn style="blue" className="colorblue font-16 ml20 fr">
|
|
||||||
<a className="btn colorblue fontweight400"
|
|
||||||
onClick={() => this.settingList(bools)}>设置</a>
|
|
||||||
</WordsBtn>
|
|
||||||
|
|
||||||
<WordsBtn style="blue" className="colorblue font-16 ml20 fr">
|
|
||||||
<a className="btn colorblue fontweight400"
|
|
||||||
onClick={() => this.onDelete(discussMessage.id)}>删除</a>
|
|
||||||
</WordsBtn>
|
|
||||||
|
|
||||||
</span> : ""}
|
|
||||||
</h6>
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
.sttingbox{
|
|
||||||
position: absolute;
|
|
||||||
right: 0px;
|
|
||||||
top: 20px;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
.lightgreybox{
|
|
||||||
min-width: 260px;
|
|
||||||
}
|
|
||||||
.mrf2{
|
|
||||||
margin-top: -2px;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{/*资源分班*/}
|
|
||||||
{/*{discussMessage.course_groups.length===0?"":*/}
|
|
||||||
{/*<p className="color-grey panel-lightgrey mt8 fl lightgreybox ml30" style={{width:'100%'}}>*/}
|
|
||||||
{/*{discussMessage.course_groups.map((item,key)=>{*/}
|
|
||||||
{/*return(*/}
|
|
||||||
{/*<div className="mr50">*/}
|
|
||||||
{/*<span className="mr15 color-dark">{item.course_group_name}</span>*/}
|
|
||||||
{/*<span className="mr15 color-grey9 ">将发布于 { moment(item.course_group_publish_time).format('YYYY-MM-DD HH:mm')}</span>*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
{/*)*/}
|
|
||||||
{/*})}*/}
|
|
||||||
|
|
||||||
{/*</p>}*/}
|
|
||||||
|
|
||||||
<p
|
|
||||||
className={this.props.isAdmin === true ? "color-grey panel-lightgrey mt8 fl ml30" : "color-grey panel-lightgrey mt8 fl ml13"}
|
|
||||||
style={{width: '100%'}}>
|
|
||||||
<span className="mr50">
|
|
||||||
<span className="mr15 color-dark">{discussMessage.author.name}</span>
|
|
||||||
{
|
|
||||||
bools ?
|
|
||||||
<span className="mr15 color-grey9">大小 {discussMessage.filesize}</span>
|
|
||||||
|
|
||||||
:
|
|
||||||
""
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
bools ?
|
|
||||||
<span className="mr15 color-grey9">下载 {discussMessage.downloads_count}</span>
|
|
||||||
:
|
|
||||||
<span className="mr15 color-grey9">点击次数:{discussMessage.downloads_count}</span>
|
|
||||||
|
|
||||||
}
|
|
||||||
{/*<span className="mr15 color-grey9">引用 {discussMessage.quotes}</span>*/}
|
|
||||||
<span className="mr15 color-grey-c">
|
|
||||||
{/*{moment(discussMessage.publish_time).format('YYYY-MM-DD HH:mm:ss')}*/}
|
|
||||||
{/*{moment(discussMessage.publish_time).fromNow()}*/}
|
|
||||||
{discussMessage.publish_time === null ? "" :
|
|
||||||
discussMessage.is_publish === true ? "" : "发布于"}
|
|
||||||
{discussMessage.publish_time === null ? "" : discussMessage.is_publish === true ? moment(discussMessage.publish_time).fromNow() : moment(discussMessage.publish_time).format('YYYY-MM-DD HH:mm')}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
{discussMessage && discussMessage.category_name === undefined||discussMessage && discussMessage.category_name === null ? "" :
|
|
||||||
<div className="color-grey9 task-hide fr mr30" title={discussMessage && discussMessage.category_name}
|
|
||||||
style={{display:'flex',"max-width": "300px"}}>所属目录:<div style={{display:discussMessage && discussMessage.parent_category_name === null ? "none":'block',"max-width": "150px",overflow: 'hidden',textOverflow:'ellipsis',whiteSpace: 'nowrap'}}>{discussMessage && discussMessage. parent_category_name}</div><div style={{display:discussMessage && discussMessage.parent_category_name === null ? "none":'block'}}>/</div><div style={{"max-width": "150px",overflow: 'hidden',textOverflow:'ellipsis',whiteSpace: 'nowrap'}}>{discussMessage && discussMessage.category_name}</div>
|
|
||||||
</div>}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<p
|
|
||||||
className={this.props.isAdmin === true ? "color-grey panel-lightgrey mt8 fl ml30" : "color-grey panel-lightgrey mt8 fl ml13"}
|
|
||||||
style={{width: '94%'}}>
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
.isspans{
|
|
||||||
text-align: left;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-break: break-all;
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<span
|
|
||||||
className="color-dark isspans">资源描述 :{discussMessage.description === null ? "暂无描述" : discussMessage.description}</span>
|
|
||||||
{/*<span className="mr50">*/}
|
|
||||||
{/*/!*<span className="mr15 color-dark"></span>*!/*/}
|
|
||||||
{/*<span className="mr15 color-dark">*/}
|
|
||||||
|
|
||||||
{/*</span>*/}
|
|
||||||
{/*/!*{this.props.isAdmin ?<span><i className="iconfont icon-bianjidaibeijing font-22 color-green" onClick={()=>this.settingList()}></i></span>:""}*!/*/}
|
|
||||||
{/*</span>*/}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Fileslistitem;
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
.indexdiv {
|
|
||||||
background:#ffffff;
|
|
||||||
}
|
|
||||||
.indexdiv:hover {
|
|
||||||
background:#ccc;
|
|
||||||
}
|
|
|
@ -582,8 +582,8 @@ span.CodeMirror-selectedtext {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#root {
|
body #root {
|
||||||
background: rgb(250, 250, 250);
|
background: #EAEBEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
.newedu-class-leftnav {
|
.newedu-class-leftnav {
|
||||||
|
|
|
@ -1,549 +0,0 @@
|
||||||
import React,{ Component } from "react";
|
|
||||||
import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form,Row, Col } from "antd";
|
|
||||||
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
|
|
||||||
import './myysleduinforms.css'
|
|
||||||
import axios from 'axios';
|
|
||||||
import TPMMDEditor from "../../tpm/challengesnew/TPMMDEditor";
|
|
||||||
import moment from "../new/CoursesNew";
|
|
||||||
import Fileslistitem from "../Resource/Fileslistitem";
|
|
||||||
import Modals from "../../modals/Modals";
|
|
||||||
// 公告栏
|
|
||||||
class Bullsubdirectory extends Component{
|
|
||||||
constructor(props){
|
|
||||||
super(props);
|
|
||||||
this.messageRef = React.createRef();
|
|
||||||
|
|
||||||
this.state={
|
|
||||||
description:null,
|
|
||||||
isSpinysl:false,
|
|
||||||
whethertoeditysl:false,
|
|
||||||
addonAfter:0,
|
|
||||||
eduintits:"",
|
|
||||||
informs:[],
|
|
||||||
Modalstype:false,
|
|
||||||
Modalstopval:"是否确认删除?",
|
|
||||||
ModalCancel:"",
|
|
||||||
ModalSave:"",
|
|
||||||
index:0,
|
|
||||||
|
|
||||||
}
|
|
||||||
//不能显示数据编辑的时候没有赋值
|
|
||||||
//没加initialValue 输入不能赋值到from 上
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
// console.log("获取到数据");
|
|
||||||
// console.log(this.props);
|
|
||||||
let{id,myname,mydescription,index,item} =this.props
|
|
||||||
this.props.form.setFieldsValue({
|
|
||||||
id:id,
|
|
||||||
eduintits:item.name,
|
|
||||||
description:item.description,
|
|
||||||
});
|
|
||||||
// this.contentMdRef.current.setValue(mydescription);
|
|
||||||
this.setState({
|
|
||||||
id:id,
|
|
||||||
eduintits:item.name,
|
|
||||||
description:item.description,
|
|
||||||
index:index
|
|
||||||
})
|
|
||||||
if(myname!=undefined){
|
|
||||||
this.setState({
|
|
||||||
addonAfter:myname.length
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
setModeltrue=()=>{
|
|
||||||
this.setState({
|
|
||||||
Modalstype:true,
|
|
||||||
Modalstopval:"是否确认删除?",
|
|
||||||
ModalCancel:this.cancelmodel,
|
|
||||||
ModalSave:this.saveonOpen,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelmodel=()=>{
|
|
||||||
//取消
|
|
||||||
this.setState({
|
|
||||||
Modalstype:false,
|
|
||||||
Modalstopval:"是否确认删除?",
|
|
||||||
ModalCancel:"",
|
|
||||||
ModalSave:"",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
saveonOpen=()=>{
|
|
||||||
//确认
|
|
||||||
// /
|
|
||||||
// 删除公告
|
|
||||||
var id=this.props.match.params.coursesId
|
|
||||||
const url =`/courses/${id}/delete_informs.json`;
|
|
||||||
axios.delete(url, { data: {
|
|
||||||
inform_id: this.props.id
|
|
||||||
}})
|
|
||||||
.then((response) => {
|
|
||||||
if(response){
|
|
||||||
if(response.data){
|
|
||||||
if(response.data.status===0){
|
|
||||||
this.setState({
|
|
||||||
Modalstype:false,
|
|
||||||
Modalstopval:"是否确认删除?",
|
|
||||||
ModalCancel:"",
|
|
||||||
ModalSave:"",
|
|
||||||
})
|
|
||||||
this.props.showNotification(`删除成功`);
|
|
||||||
this.props.getinputdata();
|
|
||||||
}else{
|
|
||||||
this.props.showNotification(`删除失败`);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
this.props.showNotification(`删除失败`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
this.props.showNotification(`删除失败`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bianji = (bians,i)=>{
|
|
||||||
console.log("bianji");
|
|
||||||
console.log(this.props.myname);
|
|
||||||
console.log(this.props.mydescription);
|
|
||||||
this.setState({
|
|
||||||
whethertoeditysl:bians,
|
|
||||||
eduintits:this.props.myname,
|
|
||||||
description:this.props.mydescription,
|
|
||||||
index:i
|
|
||||||
});
|
|
||||||
this.props.form.setFieldsValue({
|
|
||||||
eduintits:this.props.myname,
|
|
||||||
description:this.props.mydescription,
|
|
||||||
});
|
|
||||||
if(bians===true){
|
|
||||||
this.props.getyslbooltrue();
|
|
||||||
}else {
|
|
||||||
this.props.getyslboolfalse();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
changeTopicName = (e) => {
|
|
||||||
// console.log("调用了changeTopicName");
|
|
||||||
let num = e.target.value.length;
|
|
||||||
|
|
||||||
if(num>60){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
addonAfter: num < 0 ? 0 : num
|
|
||||||
});
|
|
||||||
if(num<=60){
|
|
||||||
this.setState({
|
|
||||||
eduintits: e.target.value
|
|
||||||
})
|
|
||||||
|
|
||||||
this.props.form.setFieldsValue({
|
|
||||||
eduintits: e.target.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
handleSubmit=(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
this.props.form.validateFields((err, values) => {
|
|
||||||
|
|
||||||
if (!err) {
|
|
||||||
console.log(values.description);
|
|
||||||
if(values.eduintits === undefined|| values.eduintits === "" || values.eduintits ===null){
|
|
||||||
this.props.showNotification(`请输入标题`);
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
if(values.description === undefined|| values.description === "" || values.description ===null){
|
|
||||||
this.props.showNotification(`请输入内容`);
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
var id=this.props.match.params.coursesId
|
|
||||||
var titname="";
|
|
||||||
try {
|
|
||||||
if(values.eduintits.length>0){
|
|
||||||
if( values.eduintits.length>60){
|
|
||||||
var str=values.eduintits;
|
|
||||||
titname=str.substring(0,60);
|
|
||||||
}else {
|
|
||||||
titname=values.eduintits;
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
titname=values.eduintits;
|
|
||||||
}
|
|
||||||
}catch (e) {
|
|
||||||
titname=values.eduintits;
|
|
||||||
}
|
|
||||||
var url = `/courses/${id}/update_informs.json`;
|
|
||||||
axios.post(url,{
|
|
||||||
inform_id:this.props.id,
|
|
||||||
name:titname,
|
|
||||||
description:values.description,
|
|
||||||
}).then((result) => {
|
|
||||||
if(result){
|
|
||||||
if(result.data){
|
|
||||||
if(result.data.status === 0){
|
|
||||||
// this.props.form.setFieldsValue({
|
|
||||||
// id:this.state.id,
|
|
||||||
// eduintits:titname,
|
|
||||||
// description:values.description,
|
|
||||||
// });
|
|
||||||
this.setState({
|
|
||||||
whethertoeditysl:false,
|
|
||||||
id:this.state.id,
|
|
||||||
eduintits:titname,
|
|
||||||
description:values.description,
|
|
||||||
});
|
|
||||||
this.props.getinputdata();
|
|
||||||
this.props.getyslboolfalse();
|
|
||||||
this.props.showNotification(result.data.message);
|
|
||||||
}else {
|
|
||||||
this.props.showNotification(result.data.message);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//上移
|
|
||||||
Moveupward = (id) => {
|
|
||||||
let url = `/courses/${this.props.match.params.coursesId}/inform_up.json`;
|
|
||||||
axios.post(url, {
|
|
||||||
inform_id: id
|
|
||||||
}).then((response) => {
|
|
||||||
if (response) {
|
|
||||||
if (response.data) {
|
|
||||||
if (response.data.status === 0) {
|
|
||||||
this.props.showNotification(`上移成功`);
|
|
||||||
this.props.getinputdata();
|
|
||||||
} else {
|
|
||||||
this.props.showNotification(`上移失败`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.props.showNotification(`上移失败`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.props.showNotification(`上移失败`);
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//下移
|
|
||||||
Movedown = (id) => {
|
|
||||||
let url = `/courses/${this.props.match.params.coursesId}/inform_down.json`;
|
|
||||||
axios.post(url, {
|
|
||||||
inform_id: id
|
|
||||||
}).then((response) => {
|
|
||||||
if (response) {
|
|
||||||
if (response.data) {
|
|
||||||
if (response.data.status === 0) {
|
|
||||||
this.props.showNotification(`下移成功`);
|
|
||||||
this.props.getinputdata();
|
|
||||||
} else {
|
|
||||||
this.props.showNotification(`下移失败`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.props.showNotification(`下移失败`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.props.showNotification(`下移失败`);
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render(){
|
|
||||||
let{description,whethertoeditysl,addonAfter,eduintits,informs,isSpinysl,index} =this.state;
|
|
||||||
let{myname,mydescription,id}=this.props;
|
|
||||||
const {getFieldDecorator} = this.props.form;
|
|
||||||
// console.log("Bullsubdirectory");
|
|
||||||
// console.log(this.props.isAdmin());
|
|
||||||
// console.log(this.props);
|
|
||||||
// console.log(whethertoeditysl);
|
|
||||||
// console.log(this.state.eduintits);
|
|
||||||
// console.log(this.state.description);
|
|
||||||
|
|
||||||
return(
|
|
||||||
<React.Fragment key={this.props.index} id={this.props.id}>
|
|
||||||
<div key={this.props.index} id={this.props.id}>
|
|
||||||
{this.state.Modalstype&&this.state.Modalstype===true?<Modals
|
|
||||||
modalsType={this.state.Modalstype}
|
|
||||||
modalsTopval={this.state.Modalstopval}
|
|
||||||
modalCancel={this.state.ModalCancel}
|
|
||||||
modalSave={this.state.ModalSave}
|
|
||||||
/>:""}
|
|
||||||
<Spin size="large" spinning={isSpinysl} >
|
|
||||||
<div className="edu-back-white " id={
|
|
||||||
index
|
|
||||||
}>
|
|
||||||
{
|
|
||||||
whethertoeditysl === false?
|
|
||||||
<div id={this.props.index}>
|
|
||||||
<div className="fudonyingxiangysls">
|
|
||||||
<div className="fudonyingxiangysl">
|
|
||||||
<div style={{marginRight:"60px"}}>
|
|
||||||
<span className="ysltitbt">{myname}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<span className="fr yslbianji" style={{marginRight:"17px"}}>
|
|
||||||
{
|
|
||||||
this.props.isAdmin() === true ?
|
|
||||||
(this.props.yslbool===false?
|
|
||||||
<Tooltip placement="bottom" title={<div>
|
|
||||||
编辑
|
|
||||||
</div>}>
|
|
||||||
<i className="iconfont icon-bianji1 newbianji1" onClick={()=>this.bianji(true,this.props.index)}></i>
|
|
||||||
</Tooltip>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
</span>
|
|
||||||
<span className="fr yslbianji" style={{marginRight:"22px"}}>
|
|
||||||
{
|
|
||||||
this.props.isAdmin() === true ?
|
|
||||||
(this.props.yslbool===false?
|
|
||||||
<Tooltip placement="bottom" title={<div>
|
|
||||||
删除
|
|
||||||
</div>}>
|
|
||||||
<i className="iconfont icon-shanchu newbianji1" style={{ color: "#4CACFF"}} onClick={()=>this.setModeltrue(true)}></i>
|
|
||||||
</Tooltip>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
</span>
|
|
||||||
{
|
|
||||||
this.props.length - 1 === this.props.index ? "" :
|
|
||||||
this.props.isAdmin() === true ?
|
|
||||||
(this.props.yslbool === false ?
|
|
||||||
<a className="fr yslbianji mr30"
|
|
||||||
style={{
|
|
||||||
lineHeight: "31px",
|
|
||||||
}}
|
|
||||||
onClick={() => this.Movedown(this.props.id)}
|
|
||||||
><Tooltip
|
|
||||||
title="下移"><i
|
|
||||||
style={{color: "#4CACFF"}}
|
|
||||||
className=" font-18 iconfont icon-xiangxiayi"></i></Tooltip></a>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
{
|
|
||||||
this.props.index === 0 ? "" :
|
|
||||||
this.props.isAdmin() === true ?
|
|
||||||
(this.props.yslbool === false ?
|
|
||||||
<a className="fr yslbianji mr30"
|
|
||||||
style={{
|
|
||||||
lineHeight: "31px",
|
|
||||||
}}
|
|
||||||
onClick={() => this.Moveupward(this.props.id)}
|
|
||||||
><Tooltip
|
|
||||||
title="上移"><i
|
|
||||||
style={{color: "#4CACFF"}}
|
|
||||||
className=" font-18 iconfont icon-xiangshangyi"></i></Tooltip></a>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div className="yslclear"></div>
|
|
||||||
</div>
|
|
||||||
<div id="MakedownHTML"className="markdown-body fonttext yslmtopcg yslminHeigth markdownysltext" dangerouslySetInnerHTML={{__html: markdownToHTML(mydescription).replace(/▁/g, "▁▁▁")}}/>
|
|
||||||
</div>
|
|
||||||
{parseInt(this.props&&this.props.informs.length)===parseInt(this.props&&this.props.index+1)?"":<div className="bor-bottom-greyE mr25 ml25"></div>}
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
whethertoeditysl === true?
|
|
||||||
<div className="edu-back-white " key={this.props.index} id={this.props.id}>
|
|
||||||
<Form layout='vertical' onSubmit={this.handleSubmit} key={this.props.index}>
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`.ant-form-item{
|
|
||||||
margin-bottom:0px !important;
|
|
||||||
}
|
|
||||||
.chooseDestwo .ant-form-item{
|
|
||||||
margin-bottom:0px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chooseDestwo .ant-form-item-control-wrapper .ant-form-item-control .ant-form-explain{
|
|
||||||
padding-left: 25px !important;
|
|
||||||
}
|
|
||||||
.ant-form-vertical .ant-form-item {
|
|
||||||
margin-bottom:0px !important;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<Form.Item
|
|
||||||
style={{"borderBottom":'none'}}
|
|
||||||
className="chooseDestwo "
|
|
||||||
key={this.props.index}
|
|
||||||
>
|
|
||||||
{getFieldDecorator('eduintits', { initialValue: eduintits}, {
|
|
||||||
rules: [{
|
|
||||||
required: true, message: '请在此输入标题,最多60个字符',
|
|
||||||
}],
|
|
||||||
})(
|
|
||||||
<div className="ysleduinwh">
|
|
||||||
<div className="yslduinlefts">
|
|
||||||
<span className="yslduincolorred">*</span>
|
|
||||||
</div>
|
|
||||||
<div className="yslduinleft">
|
|
||||||
<style>{
|
|
||||||
`
|
|
||||||
.ant-input{
|
|
||||||
border-right: none !important;
|
|
||||||
height: 40px !important;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}</style>
|
|
||||||
<Input placeholder="请在此输入标题,最多60个字符" key={this.props.index} maxLength="60"
|
|
||||||
style={{ textAlign: "left",width:"100%",}}
|
|
||||||
onInput={this.changeTopicName}
|
|
||||||
autoComplete="off"
|
|
||||||
addonAfter={String(addonAfter)+"/60"}
|
|
||||||
value={eduintits}
|
|
||||||
className="searchViewAfter"></Input>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
|
|
||||||
<div className="edu-back-white " key={this.props.index}>
|
|
||||||
<div className={"yslmt16px"}>
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
.ant-form-item-children {
|
|
||||||
position: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chooseDes .ant-form-item{
|
|
||||||
margin-bottom:0px !important;
|
|
||||||
}
|
|
||||||
.rememberTip{
|
|
||||||
position:absolute;
|
|
||||||
right:0px;
|
|
||||||
bottom:-10px;
|
|
||||||
}
|
|
||||||
.chooseDes .ant-form-explain{
|
|
||||||
position:absolute;
|
|
||||||
bottom:-10px;
|
|
||||||
left:0px;
|
|
||||||
}
|
|
||||||
.ant-form-vertical .ant-form-explain {
|
|
||||||
margin-top: 0px !important;
|
|
||||||
margin-bottom: 0px !important;
|
|
||||||
padding-left: 0px !important;
|
|
||||||
}
|
|
||||||
.chooseDes .ant-form-item-with-help {
|
|
||||||
margin-bottom: 24px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.courseMessageMD .ant-form-item-with-help {
|
|
||||||
margin-bottom: 24px !important;
|
|
||||||
}
|
|
||||||
.chooseDes .editormd-toolbar {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 37px;
|
|
||||||
background: #fff;
|
|
||||||
display: none;
|
|
||||||
position: absolute !important;
|
|
||||||
left: 0;
|
|
||||||
z-index: 10;
|
|
||||||
border-bottom: 1px solid #ddd;
|
|
||||||
|
|
||||||
}
|
|
||||||
.yslmt16px .ant-form-item-with-help
|
|
||||||
{
|
|
||||||
margin-bottom: 24px !important;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<Form.Item
|
|
||||||
style={{"borderBottom":'none'}}
|
|
||||||
className="chooseDes "
|
|
||||||
key={this.props.index}
|
|
||||||
>
|
|
||||||
{getFieldDecorator('description', { initialValue: description},{
|
|
||||||
rules: [{
|
|
||||||
required: true, message: '请在此输入内容,最多5000个字符',
|
|
||||||
}, {
|
|
||||||
len: 5000, message: '最大限制为5000个字符',
|
|
||||||
}],
|
|
||||||
})(
|
|
||||||
<TPMMDEditor ref={this.messageRef}
|
|
||||||
key={this.props.index}
|
|
||||||
placeholder={'请在此输入内容,最多5000个字符'}
|
|
||||||
initValue={description}
|
|
||||||
mdID={'courseMessageMD'}
|
|
||||||
className="courseMessageMD "
|
|
||||||
height={518}
|
|
||||||
></TPMMDEditor>
|
|
||||||
|
|
||||||
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Form.Item>
|
|
||||||
<div className="clearfix mt28 fr pb50 mr25">
|
|
||||||
<a className="defalutCancelbtn fl mr20 " onClick={()=>this.bianji(false,this.props.index)}>取消</a>
|
|
||||||
<Button htmlType="submit" className="ant-btn defalutSubmitbtn fl ant-btn-primary">
|
|
||||||
<span>提 交</span></Button>
|
|
||||||
</div>
|
|
||||||
</Form.Item>
|
|
||||||
</Form>
|
|
||||||
<div className="bor-bottom-greyE mr25 ml25"></div>
|
|
||||||
</div>
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</Spin>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const Bullsubdirectorys = Form.create({ name: 'bullsubdirectorys' })(Bullsubdirectory);
|
|
||||||
export default Bullsubdirectorys;
|
|
|
@ -1,531 +0,0 @@
|
||||||
import React,{ Component } from "react";
|
|
||||||
import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form } from "antd";
|
|
||||||
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
|
|
||||||
import './myysleduinforms.css'
|
|
||||||
import axios from 'axios';
|
|
||||||
import TPMMDEditor from "../../tpm/challengesnew/TPMMDEditor";
|
|
||||||
import Bullsubdirectory from "./Bullsubdirectory";
|
|
||||||
import NoneData from '../../../modules/courses/coursesPublic/NoneData'
|
|
||||||
|
|
||||||
import moment from "../new/CoursesNew";
|
|
||||||
import Fileslistitem from "../Resource/Fileslistitem";
|
|
||||||
// 公告栏
|
|
||||||
// var isOnComposition = false;
|
|
||||||
// const isChrome = !!window.chrome && !!window.chrome.webstore
|
|
||||||
class Eduinforms extends Component{
|
|
||||||
constructor(props){
|
|
||||||
super(props);
|
|
||||||
this.messageRef = React.createRef();
|
|
||||||
|
|
||||||
this.state={
|
|
||||||
description:null,
|
|
||||||
isSpin:true,
|
|
||||||
whethertoedit:false,
|
|
||||||
addonAfter:0,
|
|
||||||
eduintits:"",
|
|
||||||
informs:[],
|
|
||||||
yslbool:false,
|
|
||||||
dataquerys:{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
// console.log("Eduinformss");
|
|
||||||
// console.log("获取到数据");
|
|
||||||
// console.log(this.props);
|
|
||||||
const query = this.props.location.search;
|
|
||||||
// const type = query.split('?chinaoocTimestamp=');
|
|
||||||
// console.log("Eduinforms12345");
|
|
||||||
// console.log(this.foo(query));
|
|
||||||
// console.log(JSON.stringify(this.foo(query)));
|
|
||||||
var dataqueryss={}
|
|
||||||
try {
|
|
||||||
var foqus=this.foo(query);
|
|
||||||
if(JSON.stringify(foqus) ==="{}"){
|
|
||||||
this.setState({
|
|
||||||
dataquerys:{},
|
|
||||||
});
|
|
||||||
}else {
|
|
||||||
this.setState({
|
|
||||||
dataquerys:foqus,
|
|
||||||
});
|
|
||||||
dataqueryss=foqus;
|
|
||||||
}
|
|
||||||
}catch (e) {
|
|
||||||
this.setState({
|
|
||||||
dataquerys:{},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.getinputdatas(dataqueryss);
|
|
||||||
}
|
|
||||||
//截取数据
|
|
||||||
foo=(url)=> {
|
|
||||||
var json = {};
|
|
||||||
var regExp = /[\?\&](\w+)(=?)(\w*)/g;
|
|
||||||
var arr;
|
|
||||||
do {
|
|
||||||
arr = regExp.exec(url);
|
|
||||||
// console.log(arr); // arr = [完整的字符串, key, 等号或'', value或'']
|
|
||||||
|
|
||||||
if (arr) {
|
|
||||||
var key = arr[1];
|
|
||||||
var value = arr[3];
|
|
||||||
// arr[2] === ''时, value = undefined
|
|
||||||
if (!arr[2])
|
|
||||||
value = undefined;
|
|
||||||
|
|
||||||
json[key] = value;
|
|
||||||
}
|
|
||||||
} while (arr);
|
|
||||||
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
getyslbooltrue(){
|
|
||||||
console.log("调用了getyslbooltrue");
|
|
||||||
this.setState({
|
|
||||||
yslbool:true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getyslboolfalse(){
|
|
||||||
console.log("调用了getyslboolfalse");
|
|
||||||
this.setState({
|
|
||||||
yslbool:false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getinputdata=()=>{
|
|
||||||
this.setState({
|
|
||||||
isSpin:true,
|
|
||||||
})
|
|
||||||
let url = `/courses/${this.props.match.params.coursesId}/informs.json`;
|
|
||||||
//
|
|
||||||
axios.get(url,
|
|
||||||
{params:this.state.dataquerys}
|
|
||||||
).then((response) => {
|
|
||||||
if(response){
|
|
||||||
if(response.data){
|
|
||||||
this.setState({
|
|
||||||
informs:response.data.informs,
|
|
||||||
isSpin:false,
|
|
||||||
})
|
|
||||||
}else {
|
|
||||||
this.setState({
|
|
||||||
informs:[],
|
|
||||||
isSpin:false,
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
this.setState({
|
|
||||||
informs:[],
|
|
||||||
isSpin:false,
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
this.setState({
|
|
||||||
informs:[],
|
|
||||||
isSpin:false,
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getinputdatas=(yslwebobject)=>{
|
|
||||||
this.setState({
|
|
||||||
isSpin:true,
|
|
||||||
})
|
|
||||||
let url = `/courses/${this.props.match.params.coursesId}/informs.json`;
|
|
||||||
//
|
|
||||||
axios.get(url,
|
|
||||||
{params:yslwebobject}
|
|
||||||
).then((response) => {
|
|
||||||
if(response){
|
|
||||||
if(response.data){
|
|
||||||
this.setState({
|
|
||||||
informs:response.data.informs,
|
|
||||||
isSpin:false,
|
|
||||||
})
|
|
||||||
}else {
|
|
||||||
this.setState({
|
|
||||||
informs:[],
|
|
||||||
isSpin:false,
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
this.setState({
|
|
||||||
informs:[],
|
|
||||||
isSpin:false,
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
this.setState({
|
|
||||||
informs:[],
|
|
||||||
isSpin:false,
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate = (prevProps) => {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
bianji = (bians)=>{
|
|
||||||
this.setState({
|
|
||||||
whethertoedit:bians,
|
|
||||||
description:"",
|
|
||||||
eduintits:"",
|
|
||||||
addonAfter:0,
|
|
||||||
});
|
|
||||||
this.props.form.setFieldsValue({
|
|
||||||
description:"",
|
|
||||||
eduintits:"",
|
|
||||||
});
|
|
||||||
if(bians===true){
|
|
||||||
this.getyslbooltrue();
|
|
||||||
|
|
||||||
}else {
|
|
||||||
this.getyslboolfalse();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
changeTopicName = (e) => {
|
|
||||||
// console.log("调用了changeTopicName");
|
|
||||||
let num = e.target.value.length;
|
|
||||||
if(num>60){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
addonAfter: num < 0 ? 0 : num
|
|
||||||
});
|
|
||||||
if(num<=60){
|
|
||||||
this.setState({
|
|
||||||
eduintits: e.target.value
|
|
||||||
})
|
|
||||||
|
|
||||||
this.props.form.setFieldsValue({
|
|
||||||
eduintits: e.target.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// handleComposition=(e)=>{
|
|
||||||
// if (e.type === 'compositionend') {
|
|
||||||
// // composition is end
|
|
||||||
// isOnComposition = false
|
|
||||||
//
|
|
||||||
// if (!isOnComposition && isChrome) {
|
|
||||||
// // fire onChange
|
|
||||||
// console.log(!isOnComposition);
|
|
||||||
// this.changeTopicName(e);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// // in composition
|
|
||||||
// isOnComposition = true
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// handleComposition = (e) => {
|
|
||||||
// console.log(e.type + ": " + e.target.value);
|
|
||||||
// if (e.type === 'compositionend') {
|
|
||||||
// // composition is end
|
|
||||||
// const value = e.target.value;
|
|
||||||
// this.setState({ isOnComposition: false },()=>{
|
|
||||||
// // this.handleFixedChange(value);
|
|
||||||
// });
|
|
||||||
// } else {
|
|
||||||
// // in composition
|
|
||||||
// this.setState({ isOnComposition: true });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
handleSubmit=(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
this.props.form.validateFields((err, values) => {
|
|
||||||
if (!err) {
|
|
||||||
console.log(values.description);
|
|
||||||
if(values.eduintits === undefined|| values.eduintits === "" || values.eduintits ===null){
|
|
||||||
this.props.showNotification(`请输入标题`);
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
if(values.description === undefined|| values.description === "" || values.description ===null){
|
|
||||||
this.props.showNotification(`请输入内容`);
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
var id=this.props.match.params.coursesId
|
|
||||||
var titname="";
|
|
||||||
try {
|
|
||||||
if(values.eduintits.length>0){
|
|
||||||
if( values.eduintits.length>60){
|
|
||||||
var str=values.eduintits;
|
|
||||||
titname=str.substring(0,60);
|
|
||||||
}else {
|
|
||||||
titname=values.eduintits;
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
titname=values.eduintits;
|
|
||||||
}
|
|
||||||
}catch (e) {
|
|
||||||
titname=values.eduintits;
|
|
||||||
}
|
|
||||||
var url = `/courses/${id}/new_informs.json`;
|
|
||||||
axios.post(url,{
|
|
||||||
name:titname,
|
|
||||||
description:values.description,
|
|
||||||
}).then((result) => {
|
|
||||||
if(result){
|
|
||||||
if(result.data){
|
|
||||||
if(result.data.status === 0){
|
|
||||||
this.setState({
|
|
||||||
whethertoedit:false,
|
|
||||||
|
|
||||||
});
|
|
||||||
this.getinputdata();
|
|
||||||
this.getyslboolfalse();
|
|
||||||
this.props.showNotification(result.data.message);
|
|
||||||
}else {
|
|
||||||
this.props.showNotification(result.data.message);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render(){
|
|
||||||
let{description,whethertoedit,addonAfter,eduintits,informs,yslbool} =this.state;
|
|
||||||
const {getFieldDecorator} = this.props.form;
|
|
||||||
|
|
||||||
return(
|
|
||||||
<React.Fragment >
|
|
||||||
<div id={"zhudiv"}>
|
|
||||||
<div className="edu-back-white">
|
|
||||||
<p className="clearfix padding30 bor-bottom-greyE yslmaxheigth80" >
|
|
||||||
<p style={{height: '20px'}}>
|
|
||||||
<span className="font-18 fl color-dark-21">公告栏</span>
|
|
||||||
{
|
|
||||||
this.props.isAdmin()===true?
|
|
||||||
(this.state.yslbool===false?
|
|
||||||
<li className="btn colorblue font-16 fr bluebkbk pointer"
|
|
||||||
onClick={() => this.bianji(true)}>
|
|
||||||
发布公告
|
|
||||||
</li>
|
|
||||||
:"")
|
|
||||||
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Spin size="large" spinning={this.state.isSpin} id={"cdiv"}>
|
|
||||||
|
|
||||||
<div id={"cdiv1"}>
|
|
||||||
{
|
|
||||||
whethertoedit === false?""
|
|
||||||
:
|
|
||||||
<div className="edu-back-white ">
|
|
||||||
|
|
||||||
|
|
||||||
<Form layout='vertical' onSubmit={this.handleSubmit} >
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`.ant-form-item{
|
|
||||||
margin-bottom:0px !important;
|
|
||||||
}
|
|
||||||
.chooseDestwo .ant-form-item{
|
|
||||||
margin-bottom:0px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chooseDestwo .ant-form-item-control-wrapper .ant-form-item-control .ant-form-explain{
|
|
||||||
padding-left: 25px !important;
|
|
||||||
}
|
|
||||||
.ant-form-vertical .ant-form-item {
|
|
||||||
margin-bottom:0px !important;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<Form.Item
|
|
||||||
style={{"borderBottom":'none'}}
|
|
||||||
className="chooseDestwo "
|
|
||||||
>
|
|
||||||
{getFieldDecorator('eduintits', {
|
|
||||||
rules: [{
|
|
||||||
required: true, message: '请在此输入标题,最多60个字符',
|
|
||||||
}],
|
|
||||||
})(
|
|
||||||
<div className="ysleduinwh">
|
|
||||||
<div className="yslduinlefts">
|
|
||||||
<span className="yslduincolorred">*</span>
|
|
||||||
</div>
|
|
||||||
<div className="yslduinleft">
|
|
||||||
<style>{
|
|
||||||
`
|
|
||||||
.ant-input{
|
|
||||||
border-right: none !important;
|
|
||||||
height: 40px !important;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}</style>
|
|
||||||
<Input placeholder="请在此输入标题,最多60个字符" maxLength={60}
|
|
||||||
style={{ textAlign: "left",width:"100%",}}
|
|
||||||
onInput={this.changeTopicName}
|
|
||||||
autoComplete="off"
|
|
||||||
addonAfter={String(addonAfter)+"/60"}
|
|
||||||
value={eduintits}
|
|
||||||
className="searchViewAfter"></Input>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
|
|
||||||
<div className="edu-back-white ">
|
|
||||||
<div className={"yslmt16px"}>
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
.ant-form-item-children {
|
|
||||||
position: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chooseDes .ant-form-item{
|
|
||||||
margin-bottom:0px !important;
|
|
||||||
}
|
|
||||||
.rememberTip{
|
|
||||||
position:absolute;
|
|
||||||
right:0px;
|
|
||||||
bottom:-10px;
|
|
||||||
}
|
|
||||||
.chooseDes .ant-form-explain{
|
|
||||||
position:absolute;
|
|
||||||
bottom:-10px;
|
|
||||||
left:0px;
|
|
||||||
}
|
|
||||||
.ant-form-vertical .ant-form-explain {
|
|
||||||
margin-top: 0px !important;
|
|
||||||
margin-bottom: 0px !important;
|
|
||||||
padding-left: 0px !important;
|
|
||||||
}
|
|
||||||
.chooseDes .ant-form-item-with-help {
|
|
||||||
margin-bottom: 24px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.courseMessageMD .ant-form-item-with-help {
|
|
||||||
margin-bottom: 24px !important;
|
|
||||||
}
|
|
||||||
.chooseDes .editormd-toolbar {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 37px;
|
|
||||||
background: #fff;
|
|
||||||
display: none;
|
|
||||||
position: absolute !important;
|
|
||||||
left: 0;
|
|
||||||
z-index: 10;
|
|
||||||
border-bottom: 1px solid #ddd;
|
|
||||||
|
|
||||||
}
|
|
||||||
.yslmt16px .ant-form-item-with-help
|
|
||||||
{
|
|
||||||
margin-bottom: 24px !important;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<Form.Item
|
|
||||||
style={{"borderBottom":'none'}}
|
|
||||||
className="chooseDes "
|
|
||||||
>
|
|
||||||
{getFieldDecorator('description', {
|
|
||||||
rules: [{
|
|
||||||
required: true, message: '请在此输入内容,最多5000个字符',
|
|
||||||
}, {
|
|
||||||
max: 5000, message: '最大限制为5000个字符',
|
|
||||||
}],
|
|
||||||
})(
|
|
||||||
<TPMMDEditor ref={this.messageRef}
|
|
||||||
placeholder={'请在此输入内容,最多5000个字符'}
|
|
||||||
initValue={description}
|
|
||||||
mdID={'courseMessageMD'}
|
|
||||||
className="courseMessageMD "
|
|
||||||
height={518}
|
|
||||||
></TPMMDEditor>
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Form.Item>
|
|
||||||
<div className="clearfix mt28 fr pb50 mr25" >
|
|
||||||
<a className="defalutCancelbtn fl mr20 " onClick={()=>this.bianji(false)}>取消</a>
|
|
||||||
<Button htmlType="submit" className="ant-btn defalutSubmitbtn fl ant-btn-primary">
|
|
||||||
<span>提 交</span></Button>
|
|
||||||
</div>
|
|
||||||
</Form.Item>
|
|
||||||
</Form>
|
|
||||||
<div className="bor-bottom-greyE mr25 ml25"></div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
<div>
|
|
||||||
{
|
|
||||||
informs === null || informs=== undefined ||informs.length === 0 ?
|
|
||||||
this.state.yslbool===false?
|
|
||||||
<NoneData></NoneData>
|
|
||||||
:""
|
|
||||||
:
|
|
||||||
|
|
||||||
<div className="edu-back-white ">
|
|
||||||
{/*公告栏底部*/}
|
|
||||||
{ informs&&informs.map((item, index) => {
|
|
||||||
return (
|
|
||||||
<Bullsubdirectory {...this.state} {...this.props} key={index} index={index}
|
|
||||||
length={informs.length} yslbool={yslbool} id={item.id}
|
|
||||||
myname={item.name} mydescription={item.description}
|
|
||||||
item={item}
|
|
||||||
getyslbooltrue={()=>this.getyslbooltrue()}
|
|
||||||
getyslboolfalse={()=>this.getyslboolfalse()}
|
|
||||||
getinputdata={()=>this.getinputdata()} ></Bullsubdirectory>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Spin>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const Eduinformss = Form.create({ name: 'eduinforms' })(Eduinforms);
|
|
||||||
export default Eduinformss;
|
|
||||||
{/*<div key={index} className="bor-bottom-greyE" >*/}
|
|
||||||
{/* {item.name===""?"":item.name===undefined?"":item.name===null?"":<div className="ysltitbt"><span >{item.name}</span></div>}*/}
|
|
||||||
{/* <div id="MakedownHTML" key={index} className={"markdown-body fonttext yslmtopcg yslminHeigth markdownysltext"} dangerouslySetInnerHTML={{__html: markdownToHTML(item.description).replace(/▁/g, "▁▁▁")}}/>*/}
|
|
||||||
{/*</div>*/}
|
|
|
@ -1,93 +0,0 @@
|
||||||
.yslmt16px{
|
|
||||||
padding-top: 12px !important;
|
|
||||||
padding-left: 25px !important;
|
|
||||||
padding-right: 25px !important;
|
|
||||||
padding-bottom: 1px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.yslmtopcg
|
|
||||||
{
|
|
||||||
padding: 25px !important;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.bluebkbk{
|
|
||||||
border: 1px solid #4CADFF;
|
|
||||||
width: 79px;
|
|
||||||
height: 30px;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 30px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
.ysleduinwh{
|
|
||||||
|
|
||||||
padding-right: 25px;
|
|
||||||
margin-top: 26px;
|
|
||||||
display: flex;
|
|
||||||
justify-content:flex-start;
|
|
||||||
}
|
|
||||||
.yslduincolorred{
|
|
||||||
color: red;
|
|
||||||
line-height: 40px;
|
|
||||||
height: 40px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.yslduinleft{
|
|
||||||
width: 100% ;
|
|
||||||
}
|
|
||||||
.yslduinlefts{
|
|
||||||
width: 25px;
|
|
||||||
line-height: 40px;
|
|
||||||
height: 40px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.mtyslduin25{
|
|
||||||
margin-top: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newbianji1{
|
|
||||||
font-size: 16px !important;
|
|
||||||
margin-right: 10px;
|
|
||||||
color: #4CACFF;
|
|
||||||
margin-bottom: 3px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ysltitbt{
|
|
||||||
float: left;
|
|
||||||
padding-top: 28px;
|
|
||||||
padding-left: 25px;
|
|
||||||
font-size: 21px;
|
|
||||||
color: #05101a;
|
|
||||||
text-align: left;
|
|
||||||
font-weight: bold;
|
|
||||||
max-width: 805px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
.markdownysltext{
|
|
||||||
font-size: 14px;
|
|
||||||
color: #333333;
|
|
||||||
}
|
|
||||||
.fudonyingxiangysl{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.fudonyingxiangysls{
|
|
||||||
display: flex;
|
|
||||||
flex-direction:column;
|
|
||||||
}
|
|
||||||
.yslbianji{
|
|
||||||
padding-top: 31px;
|
|
||||||
|
|
||||||
}
|
|
||||||
.yslmaxheigth80{
|
|
||||||
max-height: 80px;
|
|
||||||
}
|
|
||||||
.ysldashed{
|
|
||||||
border:1px dashed #EEE;
|
|
||||||
}
|
|
||||||
.yslclear{ clear: both;
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
import React, { useState, useEffect, memo } from 'react'
|
|
||||||
import { trigger, WordsBtn } from 'educoder'
|
|
||||||
import { Input, Checkbox, Popconfirm } from "antd";
|
|
||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
/**
|
|
||||||
角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生
|
|
||||||
*/
|
|
||||||
function ChangeRolePop({ member_roles = [], record, courseId, onChangeRoleSuccess, showNotification, getUserId, fetchUser, style }) {
|
|
||||||
const [checkBoxRoles, setCheckBoxRoles] = useState(member_roles)
|
|
||||||
// useEffect(() => {
|
|
||||||
// if (checkBoxRoles.length != member_roles.length) { // 死循环
|
|
||||||
// setCheckBoxRoles(member_roles)
|
|
||||||
// }
|
|
||||||
// }, [member_roles])
|
|
||||||
function onCheckBoxChange(val) {
|
|
||||||
console.log(val)
|
|
||||||
|
|
||||||
const isTeacher = checkBoxRoles.indexOf('PROFESSOR')
|
|
||||||
const isAssitant = checkBoxRoles.indexOf('ASSISTANT_PROFESSOR')
|
|
||||||
const isTeacherNew = val.indexOf('PROFESSOR')
|
|
||||||
const isAssitantNew = val.indexOf('ASSISTANT_PROFESSOR')
|
|
||||||
if (isTeacherNew > -1 && isTeacher == -1 && isAssitantNew > -1) {
|
|
||||||
val.splice(isAssitantNew, 1)
|
|
||||||
}
|
|
||||||
if (isAssitantNew > -1 && isAssitant == -1 && isTeacherNew > -1) {
|
|
||||||
val.splice(isTeacherNew, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
setCheckBoxRoles(val)
|
|
||||||
}
|
|
||||||
function onCancel() {
|
|
||||||
setCheckBoxRoles(member_roles)
|
|
||||||
}
|
|
||||||
const onConfirm = async () => {
|
|
||||||
if (checkBoxRoles && checkBoxRoles.length == 0) {
|
|
||||||
showNotification('请至少选择一个角色');
|
|
||||||
setCheckBoxRoles(member_roles);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const url = `/courses/${courseId}/change_member_role.json`
|
|
||||||
const response = await axios.post(url, {
|
|
||||||
roles: checkBoxRoles,
|
|
||||||
user_id: record.user_id
|
|
||||||
})
|
|
||||||
if (response.data.status == 0) {
|
|
||||||
showNotification('保存成功')
|
|
||||||
onChangeRoleSuccess()
|
|
||||||
|
|
||||||
trigger('updatabanner')
|
|
||||||
if (fetchUser && record.user_id == getUserId) {
|
|
||||||
fetchUser()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
const isAdmin = checkBoxRoles.indexOf('CREATOR') != -1
|
|
||||||
const isTeacher = checkBoxRoles.indexOf('PROFESSOR') != -1
|
|
||||||
const isAssitant = checkBoxRoles.indexOf('ASSISTANT_PROFESSOR') != -1
|
|
||||||
const isStudent = checkBoxRoles.indexOf('STUDENT') != -1
|
|
||||||
return (
|
|
||||||
<Popconfirm
|
|
||||||
overlayClassName="changeRolePop"
|
|
||||||
placement="bottom"
|
|
||||||
icon={null}
|
|
||||||
onConfirm={onConfirm}
|
|
||||||
onCancel={onCancel}
|
|
||||||
title={
|
|
||||||
<Checkbox.Group style={{ width: '100%' }} onChange={onCheckBoxChange} value={checkBoxRoles}>
|
|
||||||
{isAdmin && <Checkbox disabled={isAdmin} value="CREATOR">管理员</Checkbox>}
|
|
||||||
{!isAdmin && <Checkbox value="PROFESSOR">教师</Checkbox>}
|
|
||||||
<Checkbox disabled={isAdmin} value="ASSISTANT_PROFESSOR">助教</Checkbox>
|
|
||||||
<Checkbox value="STUDENT">学生</Checkbox>
|
|
||||||
</Checkbox.Group>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<WordsBtn style={'blue'} style2={style}>修改角色</WordsBtn>
|
|
||||||
</Popconfirm>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default memo(ChangeRolePop)
|
|
|
@ -1,98 +0,0 @@
|
||||||
import React, { useState, useEffect } from 'react'
|
|
||||||
import { trigger } from 'educoder'
|
|
||||||
import { Input, Checkbox } from "antd";
|
|
||||||
|
|
||||||
/**
|
|
||||||
arg_course_groups 选中的id数组
|
|
||||||
joinCourseGroup 选中时触发 joinCourseGroup(checkedValues, item, index) 传入item:数据对象,index: 数据对象index
|
|
||||||
checkAllValue 是否全选
|
|
||||||
onCheckAllChange 全选 onCheckAllChange(e, item, index)
|
|
||||||
course_groups 所有的group
|
|
||||||
|
|
||||||
*/
|
|
||||||
function CourseGroupChooser({ course_groups, isAdminOrCreator = true, item, index, arg_course_groups, checkAllValue, alwaysShow
|
|
||||||
, onCheckAllChange, joinCourseGroup }) {
|
|
||||||
const [state, setState] = useState({ counter: 0 })
|
|
||||||
const [search, setSearch] = useState('')
|
|
||||||
// useEffect(() => {
|
|
||||||
// console.log(' cdm')
|
|
||||||
// return () => {
|
|
||||||
// console.log(' cwum')
|
|
||||||
// };
|
|
||||||
// // , [state.counter] 加了这个后,onClick就消失了 加错位置了?
|
|
||||||
// }, [state.counter] )
|
|
||||||
// TODO 为什么每次onClick都会执行 cwum
|
|
||||||
|
|
||||||
// const add1ToCounter = () => {
|
|
||||||
// const newCounterValue = state.counter + 1
|
|
||||||
// setState({ counter: newCounterValue })
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
that.state.groupSearchValue
|
|
||||||
that.setState({groupSearchValue: e.target.value})
|
|
||||||
|
|
||||||
that.onCheckAllChange(e, item, index) - onCheckAllChange(e, item, index)
|
|
||||||
that.joinCourseGroup(checkedValues, item, index) - joinCourseGroup(checkedValues, item, index)
|
|
||||||
|
|
||||||
that.state.checkAllArray[index] - checkAllValue
|
|
||||||
*/
|
|
||||||
|
|
||||||
// console.log('arg_course_groups', arg_course_groups)
|
|
||||||
|
|
||||||
|
|
||||||
const urlStyle = { "left": "unset", minWidth: '262px' };
|
|
||||||
if (alwaysShow == true) {
|
|
||||||
urlStyle.display = 'block'
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<ul className="drop_down_menu" style={urlStyle}>
|
|
||||||
{
|
|
||||||
course_groups && course_groups.length > 10 ?
|
|
||||||
(<p className="drop_down_search">
|
|
||||||
<Input placeholder="搜索" value={search} onChange={(e) => { setSearch(e.target.value) }} allowClear />
|
|
||||||
</p>) :
|
|
||||||
''
|
|
||||||
}
|
|
||||||
|
|
||||||
<Checkbox.Group onChange={(checkedValues) => joinCourseGroup(checkedValues, item, index)}
|
|
||||||
value={arg_course_groups.length && arg_course_groups[0].id ? arg_course_groups.map(item => item.id) : arg_course_groups}
|
|
||||||
disabled={!isAdminOrCreator} className="mainGroup"
|
|
||||||
>
|
|
||||||
{course_groups && course_groups.length > 1 && <li key={'_all' + index} >
|
|
||||||
{/* 防止被外面group包裹 */}
|
|
||||||
<Checkbox.Group onChange={(e) => onCheckAllChange(e, item, index)} value={[checkAllValue]}>
|
|
||||||
<Checkbox
|
|
||||||
value={true}
|
|
||||||
disabled={!isAdminOrCreator}
|
|
||||||
style={{ marginRight: '6px' }} onClick={() => { }}
|
|
||||||
>全选</Checkbox>
|
|
||||||
</Checkbox.Group>
|
|
||||||
</li>}
|
|
||||||
{
|
|
||||||
course_groups && course_groups.filter((item) => {
|
|
||||||
return (!search || item.name.indexOf(search) != -1)
|
|
||||||
}).map((item, key) => {
|
|
||||||
return (
|
|
||||||
<li key={item.id} value={item.id} >
|
|
||||||
<Checkbox value={item.id}
|
|
||||||
key={item.id}
|
|
||||||
id={`check${item.id}`}
|
|
||||||
style={{ marginRight: '6px' }}
|
|
||||||
></Checkbox>
|
|
||||||
<label for={`check${item.id}`}>{item.name}</label>
|
|
||||||
</li>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
</Checkbox.Group>
|
|
||||||
<p className="drop_down_btn">
|
|
||||||
<a className="color-grey-6"
|
|
||||||
onClick={() => trigger('groupAdd')}
|
|
||||||
>新建分班</a>
|
|
||||||
</p>
|
|
||||||
</ul>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default CourseGroupChooser
|
|
|
@ -1,246 +0,0 @@
|
||||||
// 分班列表 加入分班
|
|
||||||
|
|
||||||
import React, { useState, useEffect, useRef } from 'react'
|
|
||||||
|
|
||||||
import { Input,Checkbox,Table, Pagination, Modal,Menu ,Spin, Tooltip , Divider, Popconfirm } from "antd";
|
|
||||||
import ClipboardJS from 'clipboard'
|
|
||||||
import axios from 'axios'
|
|
||||||
import _ from 'lodash'
|
|
||||||
|
|
||||||
import '../css/Courses.css'
|
|
||||||
import '../css/members.css'
|
|
||||||
|
|
||||||
import CourseLayoutcomponent from '../common/CourseLayoutComponent'
|
|
||||||
import Titlesearchsection from '../common/titleSearch/TitleSearchSection'
|
|
||||||
import ColorCountText from '../common/titleSearch/ColorCountText'
|
|
||||||
|
|
||||||
import { WordsBtn, trigger, on, off, getUrl, downloadFile , getRandomcode, NoneData } from 'educoder'
|
|
||||||
import Modals from "../../modals/Modals";
|
|
||||||
|
|
||||||
import DownloadMessageysl from "../../modals/DownloadMessageysl";
|
|
||||||
import CreateGroupByImportModal from './modal/CreateGroupByImportModal'
|
|
||||||
import ChangeRolePop from './ChangeRolePop'
|
|
||||||
import CourseGroupListTable from './CourseGroupListTable'
|
|
||||||
|
|
||||||
import './studentsList.css'
|
|
||||||
/**
|
|
||||||
角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生
|
|
||||||
*/
|
|
||||||
function CourseGroupList(props) {
|
|
||||||
const [searchValue, setSearchValue] = useState('');
|
|
||||||
const [valueFlag,setValueFlag] = useState(false);
|
|
||||||
const [isSpin, setIsSpin] = useState(true)
|
|
||||||
|
|
||||||
const [DownloadType, setDownloadType] = useState()
|
|
||||||
const [DownloadMessageval, setDownloadMessageval] = useState()
|
|
||||||
|
|
||||||
const [listRes, setListRes] = useState({})
|
|
||||||
const createGroupModalEl = useRef(null);
|
|
||||||
|
|
||||||
const courseId = props.match.params.coursesId
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetchAll()
|
|
||||||
on('updateNavSuccess', onOperationSuccess)
|
|
||||||
return () => {
|
|
||||||
off('updateNavSuccess', onOperationSuccess)
|
|
||||||
}
|
|
||||||
}, [valueFlag])
|
|
||||||
function onOperationSuccess() {
|
|
||||||
fetchAll()
|
|
||||||
props.updataleftNavfun()
|
|
||||||
}
|
|
||||||
async function fetchAll() {
|
|
||||||
const url = `/courses/${courseId}/course_groups.json`;
|
|
||||||
setIsSpin(true);
|
|
||||||
const response = await axios.get(url, { params: {
|
|
||||||
search: searchValue
|
|
||||||
}});
|
|
||||||
|
|
||||||
setIsSpin(false)
|
|
||||||
if (response) {
|
|
||||||
setListRes(response.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const onConfirm = async () => {
|
|
||||||
}
|
|
||||||
|
|
||||||
function createGroupImportSuccess() {
|
|
||||||
|
|
||||||
}
|
|
||||||
function addDir() {
|
|
||||||
trigger('groupAdd', props.coursesids)
|
|
||||||
}
|
|
||||||
function deleteDir() {
|
|
||||||
|
|
||||||
}
|
|
||||||
function onPressEnter(value) {
|
|
||||||
setSearchValue(value);
|
|
||||||
setValueFlag(!valueFlag);
|
|
||||||
// fetchAll();
|
|
||||||
}
|
|
||||||
function onInputSearchChange(e) {
|
|
||||||
setSearchValue(e.target.value)
|
|
||||||
}
|
|
||||||
function Downloadcal() {
|
|
||||||
|
|
||||||
}
|
|
||||||
const confirmysl = (url) => {
|
|
||||||
axios.get(url + '&export=true').then((response) => {
|
|
||||||
if(response === undefined){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if(response.data.status&&response.data.status===-1){
|
|
||||||
|
|
||||||
}else if(response.data.status&&response.data.status===-2){
|
|
||||||
if(response.data.message === "100"){
|
|
||||||
// 已超出文件导出的上限数量(100 ),建议:
|
|
||||||
setDownloadType(true)
|
|
||||||
setDownloadMessageval(100)
|
|
||||||
}else {
|
|
||||||
//因附件资料超过500M
|
|
||||||
setDownloadType(true)
|
|
||||||
setDownloadMessageval(500)
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
props.slowDownload(getRandomcode(url))
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const isAdmin = props.isAdmin();
|
|
||||||
const isSuperAdmin = props.isSuperAdmin();
|
|
||||||
const isParent = true;
|
|
||||||
// const searchValue = '';
|
|
||||||
const isCourseEnd= props.isCourseEnd();
|
|
||||||
|
|
||||||
const course_group_id= '';
|
|
||||||
|
|
||||||
|
|
||||||
const total_count = listRes.group_count;
|
|
||||||
const none_group_member_count = listRes.none_group_member_count;
|
|
||||||
const course_groups = listRes.course_groups
|
|
||||||
const current_group_id = listRes.current_group_id
|
|
||||||
|
|
||||||
let exportUrl = `/courses/${courseId}/export_member_scores_excel.xlsx`; //总成绩
|
|
||||||
let exportUrltwo = `/courses/${courseId}/export_couser_info.xlsx`; //课堂信息
|
|
||||||
let exportUrlthree = `/courses/${courseId}/export_member_act_score.xlsx`; //活跃度
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<DownloadMessageysl
|
|
||||||
{...props}
|
|
||||||
value={DownloadMessageval}
|
|
||||||
modalCancel={Downloadcal}
|
|
||||||
modalsType={DownloadType}
|
|
||||||
/>
|
|
||||||
<Titlesearchsection
|
|
||||||
title={
|
|
||||||
<ul className="course_publicNav">
|
|
||||||
<li className="active">分班列表</li>
|
|
||||||
<li onClick={() => {props.history.push(`/classrooms/${courseId}/course_groups/0`)}}>未分班</li>
|
|
||||||
</ul>
|
|
||||||
}
|
|
||||||
searchValue={ searchValue }
|
|
||||||
onInputSearchChange={onInputSearchChange}
|
|
||||||
allowClearonChange={onInputSearchChange}
|
|
||||||
showSearchInput={total_count >= 10}
|
|
||||||
searchPlaceholder={ '请输入分班名称进行搜索' }
|
|
||||||
firstRowRight={
|
|
||||||
<React.Fragment>
|
|
||||||
{ // pageType !== TYPE_STUDENTS &&
|
|
||||||
isSuperAdmin && <React.Fragment>
|
|
||||||
{/* ref="createGroupByImportModal" */}
|
|
||||||
<CreateGroupByImportModal {...props}
|
|
||||||
ref={createGroupModalEl}
|
|
||||||
createGroupImportSuccess={createGroupImportSuccess}
|
|
||||||
></CreateGroupByImportModal>
|
|
||||||
{/* this.refs['createGroupByImportModal'].setVisible(true) */}
|
|
||||||
<WordsBtn style="blue" className="mr30" onClick={()=> {createGroupModalEl.current.setVisible(true)}}>导入创建分班</WordsBtn>
|
|
||||||
</React.Fragment> }
|
|
||||||
{
|
|
||||||
// pageType !== TYPE_STUDENTS &&
|
|
||||||
!isCourseEnd && isAdmin && <WordsBtn style="blue" className="mr30" onClick={()=>addDir()}>新建分班</WordsBtn> }
|
|
||||||
{/* {
|
|
||||||
isAdmin && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="mr30" onClick={()=>deleteDir()}>删除分班</WordsBtn> } */}
|
|
||||||
{/* {
|
|
||||||
isAdmin && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="mr30" onClick={()=>this.renameDir()}>分班重命名</WordsBtn> } */}
|
|
||||||
<style>{`
|
|
||||||
.drop_down_menu li a {
|
|
||||||
padding: 0px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.drop_down_menu {
|
|
||||||
/*width: 93px;*/
|
|
||||||
}
|
|
||||||
.drop_down_menu li {
|
|
||||||
width:100%;
|
|
||||||
box-sizing:boder-box;
|
|
||||||
float:unset;
|
|
||||||
line-height:30px!important;
|
|
||||||
flex: 0 0 30px;
|
|
||||||
}
|
|
||||||
.drop_down_menu, .drop_down_normal {
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
}
|
|
||||||
.drop_down_menu .drop_down_btn{
|
|
||||||
border-top:none;
|
|
||||||
}
|
|
||||||
.dividerStyle.ant-divider-horizontal{
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
.courseGroupList .ant-table-tbody tr:last-child td {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
{ isAdmin &&
|
|
||||||
<li className="li_line drop_down fr color-blue font-16">
|
|
||||||
导出<i className="iconfont icon-xiajiantou font-12 ml2"></i>
|
|
||||||
<ul className="drop_down_menu" style={{"right": "-20px", "left": "unset", "height": "auto"}}>
|
|
||||||
<li><a
|
|
||||||
onClick={(i) => confirmysl(exportUrltwo)}>课堂信息</a>
|
|
||||||
</li>
|
|
||||||
<li><a
|
|
||||||
onClick={(i) => confirmysl(exportUrlthree)}>活跃度</a>
|
|
||||||
</li>
|
|
||||||
<li><a
|
|
||||||
onClick={(i) => confirmysl(exportUrl)}>总成绩</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
secondRowLeft={
|
|
||||||
total_count ? <ColorCountText count={total_count} name="个分班"></ColorCountText> : ''
|
|
||||||
}
|
|
||||||
onPressEnter={onPressEnter}
|
|
||||||
></Titlesearchsection>
|
|
||||||
|
|
||||||
{/* {!!none_group_member_count && <div className="mt20 E9F8FF padding20-30 pointer" onClick={() => {props.history.push(`/classrooms/${courseId}/course_groups/0`)}}>
|
|
||||||
<span>未分班:</span>
|
|
||||||
<span style={{color: '#999999'}}>{none_group_member_count}个学生</span>
|
|
||||||
|
|
||||||
<WordsBtn style="blue" className="fr">查看</WordsBtn>
|
|
||||||
</div>} */}
|
|
||||||
|
|
||||||
<Spin size="large" spinning={isSpin}>
|
|
||||||
{course_groups && !!course_groups.length ?
|
|
||||||
<div className="mt20 edu-back-white padding20 courseGroupList">
|
|
||||||
|
|
||||||
<CourseGroupListTable
|
|
||||||
course_groups={course_groups}
|
|
||||||
onOperationSuccess={onOperationSuccess}
|
|
||||||
current_group_id={current_group_id}
|
|
||||||
{...props}
|
|
||||||
></CourseGroupListTable>
|
|
||||||
|
|
||||||
</div>:
|
|
||||||
<NoneData></NoneData>}
|
|
||||||
</Spin>
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default CourseGroupList
|
|
|
@ -1,280 +0,0 @@
|
||||||
import React, { useState, useEffect } from 'react'
|
|
||||||
|
|
||||||
import { Input,Checkbox,Table, Pagination, Modal,Menu ,Spin, Tooltip , Badge, Popconfirm, Result } from "antd";
|
|
||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
import { WordsBtn, trigger, on, off, getUrl, downloadFile , sortDirections } from 'educoder'
|
|
||||||
import ClipboardJS from 'clipboard'
|
|
||||||
import './studentsList.css';
|
|
||||||
/**
|
|
||||||
角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生
|
|
||||||
course_members_count: 0
|
|
||||||
id: 2441
|
|
||||||
invite_code: "WUNX9K"
|
|
||||||
member_manager: "全部教师"
|
|
||||||
name: "e'e'e"
|
|
||||||
*/
|
|
||||||
|
|
||||||
const clipboardMap = {}
|
|
||||||
function CourseGroupListTable(props) {
|
|
||||||
const [serachValue, setSerachValue] = useState('')
|
|
||||||
|
|
||||||
const courseId = props.match.params.coursesId
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const course_groups = props.course_groups
|
|
||||||
if (!course_groups) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
course_groups.forEach((record) => {
|
|
||||||
const id = record.id
|
|
||||||
let _clipboard = new ClipboardJS(`.copyBtn_${id}`);
|
|
||||||
_clipboard.on('success', (e) => {
|
|
||||||
props.showNotification('复制成功')
|
|
||||||
});
|
|
||||||
clipboardMap[id] = _clipboard
|
|
||||||
})
|
|
||||||
return () => {
|
|
||||||
course_groups.forEach((record) => {
|
|
||||||
const id = record.id
|
|
||||||
|
|
||||||
if (clipboardMap[id]) {
|
|
||||||
clipboardMap[id].destroy();
|
|
||||||
clipboardMap[id] = null;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, [props.course_groups])
|
|
||||||
function buildColumns() {
|
|
||||||
const columns=[{
|
|
||||||
title: '序号',
|
|
||||||
dataIndex: 'id',
|
|
||||||
key: 'id',
|
|
||||||
align:'center',
|
|
||||||
width:"5%",
|
|
||||||
className:"color-grey-6",
|
|
||||||
render: (id, record, index) => {
|
|
||||||
return index + 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '分班名称',
|
|
||||||
dataIndex: 'name',
|
|
||||||
key: 'name',
|
|
||||||
align:'center',
|
|
||||||
width:"25%",
|
|
||||||
className:"color-grey-6",
|
|
||||||
render: (name, record, index) => {
|
|
||||||
return <WordsBtn title={name.length > 11 ? name : ''} onClick={() => onGoDetail(record)} style={''}
|
|
||||||
className="overflowHidden1 color-dark" style2={{maxWidth: '180px', verticalAlign: 'bottom'}}>
|
|
||||||
{name}</WordsBtn>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: '学生成员',
|
|
||||||
dataIndex: 'course_members_count',
|
|
||||||
key: 'course_members_count',
|
|
||||||
align:'center',
|
|
||||||
width:"8%",
|
|
||||||
className:"color-grey-6",
|
|
||||||
render: (course_members_count, record, index) => {
|
|
||||||
return course_members_count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
if (!isNotMember) {
|
|
||||||
columns.push({
|
|
||||||
title: '管理教师',
|
|
||||||
dataIndex: 'member_manager',
|
|
||||||
key: 'member_manager',
|
|
||||||
align:'center',
|
|
||||||
width:"27%",
|
|
||||||
className:"color-grey-6",
|
|
||||||
render: (member_manager, record, index) => {
|
|
||||||
// 加title 文本太长会出现卡死 https://www.trustie.net/issues/24950
|
|
||||||
// title={record.subStringOfMember_manager ? member_manager : ''}
|
|
||||||
return <span className=""
|
|
||||||
>{record.subStringOfMember_manager || member_manager}</span>
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const aCol = (isAdmin ? {
|
|
||||||
title: '邀请码',
|
|
||||||
dataIndex: 'invite_code',
|
|
||||||
key: 'invite_code',
|
|
||||||
align:'center',
|
|
||||||
width:"21%",
|
|
||||||
className:"color-grey-6",
|
|
||||||
render: (invite_code, record, index) => {
|
|
||||||
return <React.Fragment>
|
|
||||||
<span>{invite_code}</span>
|
|
||||||
{
|
|
||||||
record.edit_auth ?
|
|
||||||
<span onClick={()=>changeInviteCode(record.id,record.invite_code_halt)} className={record.invite_code_halt ?"codeBtnStyle codeBtn_green ml10":"codeBtnStyle codeBtn_blue ml10"}>
|
|
||||||
{record.invite_code_halt ?"启用":"停用"}
|
|
||||||
</span>
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
{isAdmin && !record.invite_code_halt &&
|
|
||||||
<Tooltip title={
|
|
||||||
<div>
|
|
||||||
<div>成员可以通过邀请码主动加入分班</div>
|
|
||||||
<div>点击复制邀请码</div>
|
|
||||||
</div>
|
|
||||||
}>
|
|
||||||
<WordsBtn data-clipboard-text={record.invite_code}
|
|
||||||
className={`copyBtn_${record.id} codeBtnStyle codeBtn_yellow ml10`} style={''}>复制</WordsBtn>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
} : {
|
|
||||||
title: '你当前所在分班',
|
|
||||||
dataIndex: 'group',
|
|
||||||
key: 'group',
|
|
||||||
align:'center',
|
|
||||||
width:"20%",
|
|
||||||
className:"color-grey-6",
|
|
||||||
render: (invite_code, record, index) => {
|
|
||||||
return props.current_group_id == record.id && <Badge status="processing" text="" />
|
|
||||||
}
|
|
||||||
})
|
|
||||||
columns.push( aCol );
|
|
||||||
}
|
|
||||||
|
|
||||||
columns.push({
|
|
||||||
title: '操作',
|
|
||||||
dataIndex: 'setting',
|
|
||||||
key: 'setting',
|
|
||||||
align:'center',
|
|
||||||
width:"14%",
|
|
||||||
className:"color-grey-6",
|
|
||||||
render: (none, record, index) => {
|
|
||||||
return <React.Fragment>
|
|
||||||
{!isCourseEnd && isAdmin && <WordsBtn style2={{ marginRight: '12px' }} onClick={() => onDelete(record)} style={'grey'}>删除分班</WordsBtn>}
|
|
||||||
|
|
||||||
{isStudent && <WordsBtn style2={{ marginRight: '12px' }} onClick={() => addToDir(record)} style={''}>加入分班</WordsBtn>}
|
|
||||||
<WordsBtn onClick={() => onGoDetail(record)} style={''} className="color-dark">查看</WordsBtn>
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return columns
|
|
||||||
}
|
|
||||||
const doAddToDir = async (record) => {
|
|
||||||
const courseId = props.match.params.coursesId
|
|
||||||
const url = `/courses/${courseId}/join_course_group.json`
|
|
||||||
const course_group_id = record.id
|
|
||||||
|
|
||||||
const response = await axios.post(url, {
|
|
||||||
course_group_id
|
|
||||||
})
|
|
||||||
if (response && response.data.status == 0) {
|
|
||||||
props.showNotification(`已加入分班:${record.name}`)
|
|
||||||
props.updataleftNavfun()
|
|
||||||
props.onOperationSuccess && props.onOperationSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const addToDir = (record) => {
|
|
||||||
props.confirm({
|
|
||||||
|
|
||||||
content: `是否确认加入分班: ${record.name}?`,
|
|
||||||
|
|
||||||
okText: '确认',
|
|
||||||
cancelText: '取消',
|
|
||||||
|
|
||||||
onOk: () => {
|
|
||||||
doAddToDir(record)
|
|
||||||
},
|
|
||||||
onCancel() {
|
|
||||||
console.log('Cancel');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDelete(record) {
|
|
||||||
props.confirm({
|
|
||||||
content: <div>
|
|
||||||
<div>该分班的学生将被移动到“未分班”</div>
|
|
||||||
<div>是否确认删除?</div>
|
|
||||||
</div>,
|
|
||||||
onOk: () => {
|
|
||||||
// const cid = this.props.match.params.coursesId
|
|
||||||
|
|
||||||
const url = `/course_groups/${record.id}.json`
|
|
||||||
axios.delete(url)
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.status == 0) {
|
|
||||||
props.showNotification('删除成功')
|
|
||||||
props.onOperationSuccess && props.onOperationSuccess()
|
|
||||||
// props.history.push(response.data.right_url)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
function onGoDetail(record) {
|
|
||||||
props.history.push(`/classrooms/${courseId}/course_groups/${record.id}`)
|
|
||||||
}
|
|
||||||
// 停用和启用邀请码
|
|
||||||
function changeInviteCode(id,flag){
|
|
||||||
if(flag){
|
|
||||||
changeInviteCodeFunc(id,flag);
|
|
||||||
}else{
|
|
||||||
props.confirm({
|
|
||||||
content:"分班邀请码停用后,用户不能主动加入该分班了",
|
|
||||||
subContent:'您是否确认停用?',
|
|
||||||
onOk:() => {
|
|
||||||
changeInviteCodeFunc(id,flag)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeInviteCodeFunc(id,flag){
|
|
||||||
const url= `/course_groups/${id}/set_invite_code_halt.json`;
|
|
||||||
axios.post(url).then(result=>{
|
|
||||||
if(result){
|
|
||||||
props.showNotification(`邀请码${flag?"启用":"停用"}成功!`);
|
|
||||||
props.onOperationSuccess && props.onOperationSuccess();
|
|
||||||
}
|
|
||||||
}).catch(error=>{
|
|
||||||
console.log(error);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const isAdmin = props.isAdmin();
|
|
||||||
const isSuperAdmin = props.isSuperAdmin();
|
|
||||||
const isStudent = props.isStudent()
|
|
||||||
const isNotMember = props.isNotMember()
|
|
||||||
|
|
||||||
|
|
||||||
const isParent = true;
|
|
||||||
const isCourseEnd= props.isCourseEnd();
|
|
||||||
|
|
||||||
const course_groups = props.course_groups
|
|
||||||
const columns = buildColumns()
|
|
||||||
const dataSource = course_groups.map(item => {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
subStringOfMember_manager : (item.member_manager && item.member_manager.length > 92)
|
|
||||||
? item.member_manager.substring(0, 92) + '...' : null
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<style>{`
|
|
||||||
.groupListTable .ant-badge-status-processing {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
{/* onChange={onTableChange} */}
|
|
||||||
<Table columns={columns} dataSource={dataSource} pagination={false} className="groupListTable"></Table>
|
|
||||||
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default CourseGroupListTable
|
|
|
@ -1,2 +0,0 @@
|
||||||
export const ROLE_TEACHER_NUM = 2;
|
|
||||||
export const ROLE_ASSISTANT_NUM = 3;
|
|
|
@ -1,234 +0,0 @@
|
||||||
import React, { Component } from "react";
|
|
||||||
import { Modal, Checkbox, Input, Spin, Select, Divider, Radio } from "antd";
|
|
||||||
import axios from 'axios'
|
|
||||||
import ModalWrapper from "../../common/ModalWrapper"
|
|
||||||
import InfiniteScroll from 'react-infinite-scroller';
|
|
||||||
import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from '../common'
|
|
||||||
import NoneData from '../../coursesPublic/NoneData'
|
|
||||||
import { ConditionToolTip } from 'educoder'
|
|
||||||
import SchoolSelect from '../../coursesPublic/form/SchoolSelect'
|
|
||||||
|
|
||||||
const RadioGroup = Radio.Group;
|
|
||||||
|
|
||||||
const Option = Select.Option;
|
|
||||||
const pageCount = 15;
|
|
||||||
class AddAdminModal extends Component{
|
|
||||||
constructor(props){
|
|
||||||
super(props);
|
|
||||||
this.state={
|
|
||||||
radioBoxValue: [],
|
|
||||||
users: [],
|
|
||||||
hasMore: true,
|
|
||||||
loading: false,
|
|
||||||
courseGroup: '',
|
|
||||||
page: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fetchTeacherList = (arg_page) => {
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
const page = arg_page || this.state.page;
|
|
||||||
const { name, school_name } = this.state
|
|
||||||
|
|
||||||
let url = `/courses/${courseId}/teachers.json`
|
|
||||||
this.setState({ loading: true })
|
|
||||||
axios.get(url, {
|
|
||||||
params: {
|
|
||||||
page: page,
|
|
||||||
limit: pageCount
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (!response.data.teacher_list || response.data.teacher_list.length == 0) {
|
|
||||||
this.setState({
|
|
||||||
teacher_list: page == 1 ? response.data.teacher_list : this.state.teacher_list,
|
|
||||||
page,
|
|
||||||
loading: false,
|
|
||||||
hasMore: false,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
teacher_list: page == 1 ? response.data.teacher_list : this.state.teacher_list.concat(response.data.teacher_list),
|
|
||||||
page,
|
|
||||||
loading: false,
|
|
||||||
hasMore: response.data.teacher_list.length == pageCount
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
componentDidMount() {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
setVisible = (visible) => {
|
|
||||||
if (visible) {
|
|
||||||
this.fetchTeacherList()
|
|
||||||
}
|
|
||||||
this.refs.modalWrapper.setVisible(visible)
|
|
||||||
if (visible == false) {
|
|
||||||
this.setState({
|
|
||||||
radioBoxValue: ''
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onSendOk = () => {
|
|
||||||
if(!this.state.radioBoxValue || this.state.radioBoxValue.length == 0) {
|
|
||||||
this.props.showNotification('请从列表中先选择用户。')
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
const params = {
|
|
||||||
"user_ids": this.state.radioBoxValue
|
|
||||||
}
|
|
||||||
const { courseGroup } = this.state
|
|
||||||
|
|
||||||
if (courseGroup) {
|
|
||||||
params.course_group_id = courseGroup
|
|
||||||
}
|
|
||||||
const url = `/courses/${courseId}/change_course_admin.json`
|
|
||||||
axios.post(url, {
|
|
||||||
course_member_id: this.state.radioBoxValue.course_member_id,
|
|
||||||
user_id: this.state.radioBoxValue.user_id
|
|
||||||
}).then((result)=>{
|
|
||||||
if(result.data.status==0){
|
|
||||||
this.props.showNotification('操作成功。')
|
|
||||||
if (this.props.isCourseAdmin()) {
|
|
||||||
window.location.reload()
|
|
||||||
}
|
|
||||||
// this.fetchAll()
|
|
||||||
this.setVisible(false)
|
|
||||||
this.props.changeAdminSuccess && this.props.changeAdminSuccess()
|
|
||||||
}
|
|
||||||
}).catch((error)=>{
|
|
||||||
console.log(error);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onOk = () => {
|
|
||||||
this.onSendOk()
|
|
||||||
}
|
|
||||||
|
|
||||||
onCheckBoxChange = (e) => {
|
|
||||||
this.setState({
|
|
||||||
radioBoxValue: e.target.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
handleInfiniteOnLoad = () => {
|
|
||||||
this.fetchTeacherList(this.state.page + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
onSearch = () => {
|
|
||||||
this.fetchTeacherList(1)
|
|
||||||
}
|
|
||||||
handleCourseGroupChange = (value) => {
|
|
||||||
this.setState({
|
|
||||||
courseGroup: value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
render(){
|
|
||||||
const { teacher_list, radioBoxValue, loading, hasMore, name, school_name
|
|
||||||
, courseGroup, course_groups, } = this.state
|
|
||||||
const { moduleName } = this.props
|
|
||||||
return(
|
|
||||||
<ModalWrapper
|
|
||||||
ref="modalWrapper"
|
|
||||||
width="600px"
|
|
||||||
title={`更换管理员`}
|
|
||||||
{...this.props }
|
|
||||||
onOk={this.onOk}
|
|
||||||
className="addStudentModal"
|
|
||||||
>
|
|
||||||
<style>
|
|
||||||
{`
|
|
||||||
.demo-loading-container {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 93px;
|
|
||||||
width: 82%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.df {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
margin: 12px 0;
|
|
||||||
}
|
|
||||||
.firstLabel {
|
|
||||||
flex: 0 0 60px;
|
|
||||||
}
|
|
||||||
.df span.label {
|
|
||||||
margin-right: 8px;
|
|
||||||
text-align: right;
|
|
||||||
margin-left: 12px;
|
|
||||||
}
|
|
||||||
.df .ant-input-affix-wrapper {
|
|
||||||
width: 32%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.addTeacherModal label.task-hide {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div className="df" style={{ alignItems: 'center', flexDirection: 'column'}}>
|
|
||||||
<p>选择的成员将会成为新的管理员</p>
|
|
||||||
<p>您将不再拥有管理员的权限,但您仍是教师团队的一员</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{/* <p className="clearfix mb2" style={{ margin: '0px 15px 6px' }}>
|
|
||||||
<Checkbox className="fl" style={{ visibility: 'hidden' }} ></Checkbox>
|
|
||||||
<span className="fl with25"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'姓名'}</label></span>
|
|
||||||
<span className="fl with25"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'学号'}</label></span>
|
|
||||||
<span className="fl with45"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{'单位'}</label></span>
|
|
||||||
</p> */}
|
|
||||||
{ teacher_list && teacher_list.length ? <div>
|
|
||||||
{/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */}
|
|
||||||
<div className="edu-back-skyblue padding10-15" style={{"height":"300px", overflowY: "scroll", overflowAnchor: 'none' }}>
|
|
||||||
<InfiniteScroll
|
|
||||||
threshold={10}
|
|
||||||
initialLoad={false}
|
|
||||||
pageStart={0}
|
|
||||||
loadMore={this.handleInfiniteOnLoad}
|
|
||||||
hasMore={!loading && hasMore}
|
|
||||||
useWindow={false}
|
|
||||||
>
|
|
||||||
<RadioGroup style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={radioBoxValue}>
|
|
||||||
|
|
||||||
{ teacher_list.map( candidate => {
|
|
||||||
return (
|
|
||||||
<p className="clearfix mb7" key={candidate.user_id}>
|
|
||||||
<Radio className="fl" value={candidate} disabled={candidate.role == "管理员"}></Radio>
|
|
||||||
<span className="fl with25">
|
|
||||||
<label className="task-hide fl" style={{"maxWidth":"208px"}}>{candidate.name || ' '}{candidate.role == "管理员" ? '(当前管理员)' : '' }</label>
|
|
||||||
</span>
|
|
||||||
{/* <span className="fl with25">
|
|
||||||
<ConditionToolTip title={candidate.student_id} condition={candidate.student_id && candidate.student_id.length > 12 }>
|
|
||||||
<label className="task-hide fl" style={{"maxWidth":"208px;"}}>{candidate.student_id || ' '}</label>
|
|
||||||
</ConditionToolTip>
|
|
||||||
</span>
|
|
||||||
<span className="fl with45"><label className="task-hide fl" style={{"maxWidth":"208px;"}}>{candidate.school_name}</label></span> */}
|
|
||||||
|
|
||||||
</p>
|
|
||||||
)
|
|
||||||
}) }
|
|
||||||
</RadioGroup>
|
|
||||||
{loading && hasMore && (
|
|
||||||
<div className="demo-loading-container">
|
|
||||||
<Spin />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
</InfiniteScroll>
|
|
||||||
</div>
|
|
||||||
</div> : <NoneData></NoneData> }
|
|
||||||
</ModalWrapper>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default AddAdminModal;
|
|
|
@ -1,75 +0,0 @@
|
||||||
import React, { Component } from "react";
|
|
||||||
import { Input} from "antd";
|
|
||||||
import axios from 'axios'
|
|
||||||
import ModalWrapper from "../../common/ModalWrapper"
|
|
||||||
class AddStudentModal extends Component{
|
|
||||||
constructor(props){
|
|
||||||
super(props);
|
|
||||||
this.state={
|
|
||||||
name: ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
componentDidMount() {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
setVisible = (visible) => {
|
|
||||||
this.refs.modalWrapper.setVisible(visible)
|
|
||||||
if (visible == false) {
|
|
||||||
this.setState({
|
|
||||||
name: ''
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onSendOk = () => {
|
|
||||||
if(!this.state.name || !this.state.name.trim()) {
|
|
||||||
this.props.showNotification('请先输入答辩组名称。')
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
const url = `/courses/${courseId}/create_graduation_group.json`
|
|
||||||
const params = {
|
|
||||||
"name": this.state.name
|
|
||||||
}
|
|
||||||
axios.post(url, params)
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.status == 0) {
|
|
||||||
this.setVisible(false)
|
|
||||||
this.props.onOk && this.props.onOk();
|
|
||||||
this.props.showNotification('添加成功')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onOk = () => {
|
|
||||||
this.onSendOk()
|
|
||||||
}
|
|
||||||
|
|
||||||
render(){
|
|
||||||
const { name } = this.state
|
|
||||||
const { moduleName } = this.props
|
|
||||||
|
|
||||||
return(
|
|
||||||
<ModalWrapper
|
|
||||||
ref="modalWrapper"
|
|
||||||
width="600px"
|
|
||||||
title={`添加答辩组`}
|
|
||||||
{...this.props }
|
|
||||||
onOk={this.onOk}
|
|
||||||
className="addGraduationGroupModal"
|
|
||||||
>
|
|
||||||
<div style={{width: '100%', textAlign: 'center'}}>
|
|
||||||
<span>名称:</span>
|
|
||||||
<Input style={{width: '210px'}} value={name} onChange={(e)=> this.setState({name: e.target.value})}
|
|
||||||
placeholder={'示例:李老师答辩组'}
|
|
||||||
></Input>
|
|
||||||
</div>
|
|
||||||
</ModalWrapper>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default AddStudentModal;
|
|
|
@ -1,394 +0,0 @@
|
||||||
import React, { Component } from "react";
|
|
||||||
import { Modal, Checkbox, Input, Spin, Select, Divider } from "antd";
|
|
||||||
import axios from "axios";
|
|
||||||
import ModalWrapper from "../../common/ModalWrapper";
|
|
||||||
import InfiniteScroll from "react-infinite-scroller";
|
|
||||||
import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from "../common";
|
|
||||||
import NoneData from "../../coursesPublic/NoneData";
|
|
||||||
import { ConditionToolTip, ThemeContext } from "educoder";
|
|
||||||
import SchoolSelect from "../../coursesPublic/form/SchoolSelect";
|
|
||||||
import moment from "moment";
|
|
||||||
|
|
||||||
const formatTime = (time) => {
|
|
||||||
if (time) {
|
|
||||||
return moment(time).format("YYYY-MM-DD HH:mm");
|
|
||||||
} else {
|
|
||||||
return "-";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const Option = Select.Option;
|
|
||||||
const pageCount = 15;
|
|
||||||
class AddStudentModal extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
checkBoxValues: [],
|
|
||||||
users: [],
|
|
||||||
hasMore: true,
|
|
||||||
loading: false,
|
|
||||||
courseGroup: "",
|
|
||||||
page: 1,
|
|
||||||
isSpin: false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
fetchMemberList = (arg_page) => {
|
|
||||||
const courseId = this.props.match.params.coursesId;
|
|
||||||
const page = arg_page || this.state.page;
|
|
||||||
const { name, school_name } = this.state;
|
|
||||||
let url = `/courses/${courseId}/search_users.json?page=${page}&limit=${pageCount}&school_name=${
|
|
||||||
school_name || ""
|
|
||||||
}&name=${name || ""}`;
|
|
||||||
this.setState({ loading: true });
|
|
||||||
axios
|
|
||||||
.get(encodeURI(url))
|
|
||||||
.then((response) => {
|
|
||||||
if (!response.data.users || response.data.users.length == 0) {
|
|
||||||
this.setState({
|
|
||||||
users: page == 1 ? response.data.users : this.state.users,
|
|
||||||
page,
|
|
||||||
loading: false,
|
|
||||||
hasMore: false,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
users:
|
|
||||||
page == 1
|
|
||||||
? response.data.users
|
|
||||||
: this.state.users.concat(response.data.users),
|
|
||||||
page,
|
|
||||||
loading: false,
|
|
||||||
hasMore: response.data.users.length == pageCount,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
componentDidMount() {}
|
|
||||||
fetchOptions = () => {
|
|
||||||
// add_teacher_popup
|
|
||||||
const courseId = this.props.match.params.coursesId;
|
|
||||||
|
|
||||||
let url = `/courses/${courseId}/all_course_groups.json`;
|
|
||||||
|
|
||||||
axios
|
|
||||||
.get(url, {})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.course_groups && response.data.course_groups.length) {
|
|
||||||
this.setState({
|
|
||||||
course_groups: response.data.course_groups,
|
|
||||||
courseGroup: "0", // response.data.course_groups[0].id
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// showNotification('')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
setVisible = (visible) => {
|
|
||||||
if (visible) {
|
|
||||||
this.setState(
|
|
||||||
{
|
|
||||||
school_name: this.props.user.user_school,
|
|
||||||
name: undefined,
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
this.fetchMemberList();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.fetchOptions();
|
|
||||||
}
|
|
||||||
this.refs.modalWrapper.setVisible(visible);
|
|
||||||
if (visible == false) {
|
|
||||||
this.setState({
|
|
||||||
checkBoxValues: [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onSendOk = () => {
|
|
||||||
if (!this.state.checkBoxValues || this.state.checkBoxValues.length == 0) {
|
|
||||||
this.props.showNotification("请从列表中先选择用户。");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
isSpin: true,
|
|
||||||
});
|
|
||||||
const courseId = this.props.match.params.coursesId;
|
|
||||||
const url = `/courses/${courseId}/add_students_by_search.json`;
|
|
||||||
const params = {
|
|
||||||
user_ids: this.state.checkBoxValues,
|
|
||||||
};
|
|
||||||
const { courseGroup } = this.state;
|
|
||||||
if (courseGroup) {
|
|
||||||
params.course_group_id = courseGroup;
|
|
||||||
}
|
|
||||||
axios
|
|
||||||
.post(url, params)
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.status == 0) {
|
|
||||||
this.setVisible(false);
|
|
||||||
this.props.showNotification("添加成功");
|
|
||||||
this.props.addStudentSuccess && this.props.addStudentSuccess(params);
|
|
||||||
this.setState({
|
|
||||||
isSpin: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onOk = () => {
|
|
||||||
this.onSendOk();
|
|
||||||
};
|
|
||||||
|
|
||||||
onCheckBoxChange = (checkBoxValues) => {
|
|
||||||
this.setState({
|
|
||||||
checkBoxValues: checkBoxValues,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleInfiniteOnLoad = () => {
|
|
||||||
this.fetchMemberList(this.state.page + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
onSearch = () => {
|
|
||||||
this.fetchMemberList(1);
|
|
||||||
};
|
|
||||||
handleCourseGroupChange = (value) => {
|
|
||||||
this.setState({
|
|
||||||
courseGroup: value,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
users,
|
|
||||||
checkBoxValues,
|
|
||||||
loading,
|
|
||||||
hasMore,
|
|
||||||
name,
|
|
||||||
school_name,
|
|
||||||
courseGroup,
|
|
||||||
course_groups,
|
|
||||||
isSpin,
|
|
||||||
} = this.state;
|
|
||||||
const { moduleName } = this.props;
|
|
||||||
let theme = this.context;
|
|
||||||
return (
|
|
||||||
<ModalWrapper
|
|
||||||
ref="modalWrapper"
|
|
||||||
width="700px"
|
|
||||||
title={`添加${moduleName}`}
|
|
||||||
{...this.props}
|
|
||||||
onOk={this.onOk}
|
|
||||||
className="addStudentModal courseForm"
|
|
||||||
>
|
|
||||||
<style>
|
|
||||||
{`
|
|
||||||
.demo-loading-container {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 93px;
|
|
||||||
width: 82%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.df {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
margin: 12px 0;
|
|
||||||
}
|
|
||||||
.firstLabel {
|
|
||||||
flex: 0 0 60px;
|
|
||||||
}
|
|
||||||
.df span.label {
|
|
||||||
margin-right: 8px;
|
|
||||||
text-align: right;
|
|
||||||
margin-left: 12px;
|
|
||||||
}
|
|
||||||
.df .ant-input-affix-wrapper {
|
|
||||||
width: 32%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.addTeacherModal label.task-hide {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
</style>
|
|
||||||
<div className="df">
|
|
||||||
<span className="mr10">姓名:</span>
|
|
||||||
<Input
|
|
||||||
allowClear
|
|
||||||
placeholder="请输入真实姓名"
|
|
||||||
value={name}
|
|
||||||
onChange={(e) => {
|
|
||||||
this.setState({ name: e.target.value });
|
|
||||||
}}
|
|
||||||
style={{ width: "221px" }}
|
|
||||||
></Input>
|
|
||||||
<span className="label" style={{ minWidth: "36px" }}>
|
|
||||||
单位:
|
|
||||||
</span>
|
|
||||||
{/* <Input allowClear placeholder="请输入单位名称" value={school_name} onChange={(e) => {this.setState({school_name: e.target.value})}}
|
|
||||||
style={{ width: '200px'}}>
|
|
||||||
</Input> */}
|
|
||||||
<SchoolSelect
|
|
||||||
value={school_name}
|
|
||||||
onChange={(value) => {
|
|
||||||
this.setState({ school_name: value });
|
|
||||||
}}
|
|
||||||
></SchoolSelect>
|
|
||||||
<a
|
|
||||||
className="task-btn task-btn-orange"
|
|
||||||
onClick={() => this.fetchMemberList(1)}
|
|
||||||
style={{
|
|
||||||
height: "30px",
|
|
||||||
lineHeight: "30px",
|
|
||||||
marginLeft: "10px",
|
|
||||||
width: "70px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
搜索
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{/* <Divider /> */}
|
|
||||||
|
|
||||||
<p className="clearfix mb2" style={{ margin: "0px 20px 6px" }}>
|
|
||||||
<Checkbox className="fl" style={{ visibility: "hidden" }}></Checkbox>
|
|
||||||
<span className="fl task-hide with20" style={{ maxWidth: "208px;" }}>
|
|
||||||
{"姓名"}
|
|
||||||
</span>
|
|
||||||
<span className="fl task-hide with23" style={{ maxWidth: "208px;" }}>
|
|
||||||
{"学号"}
|
|
||||||
</span>
|
|
||||||
<span className="fl task-hide with23" style={{ maxWidth: "208px;" }}>
|
|
||||||
{"最后登录时间"}
|
|
||||||
</span>
|
|
||||||
<span className="fl task-hide with20" style={{ maxWidth: "208px;" }}>
|
|
||||||
{"单位"}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="fl task-hide with5"
|
|
||||||
style={{ maxWidth: "48px;" }}
|
|
||||||
></span>
|
|
||||||
</p>
|
|
||||||
<Spin size="large" spinning={isSpin}>
|
|
||||||
{loading || users.length ? (
|
|
||||||
<div>
|
|
||||||
{/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */}
|
|
||||||
<div
|
|
||||||
className="edu-back-skyblue padding10-15"
|
|
||||||
style={{
|
|
||||||
height: "300px",
|
|
||||||
overflowY: "scroll",
|
|
||||||
overflowAnchor: "none",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<InfiniteScroll
|
|
||||||
threshold={10}
|
|
||||||
initialLoad={false}
|
|
||||||
pageStart={0}
|
|
||||||
loadMore={this.handleInfiniteOnLoad}
|
|
||||||
hasMore={!loading && hasMore}
|
|
||||||
useWindow={false}
|
|
||||||
>
|
|
||||||
<Checkbox.Group
|
|
||||||
style={{ width: "100%" }}
|
|
||||||
onChange={this.onCheckBoxChange}
|
|
||||||
value={checkBoxValues}
|
|
||||||
>
|
|
||||||
{users.map((candidate) => {
|
|
||||||
return (
|
|
||||||
<p className="clearfix mb7" key={candidate.id}>
|
|
||||||
<Checkbox
|
|
||||||
className="fl"
|
|
||||||
value={candidate.id}
|
|
||||||
key={candidate.id}
|
|
||||||
disabled={candidate.added}
|
|
||||||
></Checkbox>
|
|
||||||
<span className="fl task-hide with20 ml5">
|
|
||||||
{candidate.name ? (
|
|
||||||
<a
|
|
||||||
href={`/users/${candidate.login}`}
|
|
||||||
title={candidate.name}
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
{candidate.name}
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
<span> </span>
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="fl task-hide with23"
|
|
||||||
title={candidate.student_id}
|
|
||||||
style={{ height: "20px" }}
|
|
||||||
>
|
|
||||||
{candidate.student_id || "-"}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="fl task-hide with23"
|
|
||||||
title={formatTime(candidate.last_login_on)}
|
|
||||||
style={{ height: "20px" }}
|
|
||||||
>
|
|
||||||
{formatTime(candidate.last_login_on)}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="fl task-hide with20"
|
|
||||||
title={candidate.school_name}
|
|
||||||
style={{ height: "20px" }}
|
|
||||||
>
|
|
||||||
{candidate.school_name||'-'}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="fl task-hide with5"
|
|
||||||
style={{
|
|
||||||
maxWidth: "48px",
|
|
||||||
color: theme.foreground_select,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{candidate.added ? "已加入" : ""}
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Checkbox.Group>
|
|
||||||
{loading && hasMore && (
|
|
||||||
<div className="demo-loading-container">
|
|
||||||
<Spin />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</InfiniteScroll>
|
|
||||||
</div>
|
|
||||||
{course_groups && course_groups.length && (
|
|
||||||
<div className="df" style={{ marginTop: "12px",width:'100%' }}>
|
|
||||||
<span className="mr10" style={{ width: "180PX" }}>
|
|
||||||
所选学生分班至(选填):
|
|
||||||
</span>
|
|
||||||
<Select
|
|
||||||
style={{ width: "100%" }}
|
|
||||||
onChange={this.handleCourseGroupChange}
|
|
||||||
value={courseGroup}
|
|
||||||
>
|
|
||||||
<Option value={"0"}>{"未分班"}</Option>
|
|
||||||
{course_groups.map((item) => {
|
|
||||||
return <Option value={item.id}>{item.name}</Option>;
|
|
||||||
})}
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<NoneData></NoneData>
|
|
||||||
)}
|
|
||||||
</Spin>
|
|
||||||
</ModalWrapper>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AddStudentModal.contextType = ThemeContext;
|
|
||||||
export default AddStudentModal;
|
|
|
@ -1,474 +0,0 @@
|
||||||
import React, { Component } from "react";
|
|
||||||
import { Modal, Checkbox, Input, Spin, Select, Divider, Icon } from "antd";
|
|
||||||
import axios from "axios";
|
|
||||||
import ModalWrapper from "../../common/ModalWrapper";
|
|
||||||
import InfiniteScroll from "react-infinite-scroller";
|
|
||||||
import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from "../common";
|
|
||||||
import { ConditionToolTip, ActionBtn } from "educoder";
|
|
||||||
import NoneData from "../../coursesPublic/NoneData";
|
|
||||||
import AddGraduationGroupModal from "./AddGraduationGroupModal";
|
|
||||||
import SchoolSelect from "../../coursesPublic/form/SchoolSelect";
|
|
||||||
import moment from "moment";
|
|
||||||
|
|
||||||
const formatTime = (time) => {
|
|
||||||
if (time) {
|
|
||||||
return moment(time).format("YYYY-MM-DD HH:mm");
|
|
||||||
} else {
|
|
||||||
return "-";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const formatePhone = (phone) => {
|
|
||||||
if (phone && typeof phone === "string") {
|
|
||||||
return phone.substring(0, 3) + "****" + phone.substring(7);
|
|
||||||
} else {
|
|
||||||
return "-";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const Option = Select.Option;
|
|
||||||
const pageCount = 15;
|
|
||||||
let timeout, currentValue;
|
|
||||||
class AddTeacherModal extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
school_names: [],
|
|
||||||
checkBoxValues: [],
|
|
||||||
candidates: [],
|
|
||||||
hasMore: true,
|
|
||||||
loading: false,
|
|
||||||
page: 1,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
fetchMemberList = (arg_page) => {
|
|
||||||
const courseId = this.props.match.params.coursesId;
|
|
||||||
const page = arg_page || this.state.page;
|
|
||||||
const { name, school_name } = this.state;
|
|
||||||
let url = `/courses/${courseId}/search_teacher_candidate.json`;
|
|
||||||
this.setState({ loading: true });
|
|
||||||
axios
|
|
||||||
.post(url, {
|
|
||||||
page: page,
|
|
||||||
limit: pageCount,
|
|
||||||
school_name: school_name || "",
|
|
||||||
name: name || "",
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (!response.data.candidates || response.data.candidates.length == 0) {
|
|
||||||
this.setState({
|
|
||||||
candidates:
|
|
||||||
page == 1 ? response.data.candidates : this.state.candidates,
|
|
||||||
page,
|
|
||||||
loading: false,
|
|
||||||
hasMore: false,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
candidates:
|
|
||||||
page == 1
|
|
||||||
? response.data.candidates
|
|
||||||
: this.state.candidates.concat(response.data.candidates),
|
|
||||||
page,
|
|
||||||
loading: false,
|
|
||||||
hasMore: response.data.candidates.length == pageCount,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
componentDidMount() {}
|
|
||||||
onAddGraduationGroupOk = () => {
|
|
||||||
this.fetchOptions();
|
|
||||||
};
|
|
||||||
fetchOptions = () => {
|
|
||||||
// add_teacher_popup
|
|
||||||
const courseId = this.props.match.params.coursesId;
|
|
||||||
|
|
||||||
let url = `/courses/${courseId}/add_teacher_popup.json`;
|
|
||||||
|
|
||||||
axios
|
|
||||||
.get(url, {})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.school_name) {
|
|
||||||
this.setState(
|
|
||||||
{
|
|
||||||
school_name: response.data.school_name,
|
|
||||||
},
|
|
||||||
() => this.fetchMemberList()
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.fetchMemberList();
|
|
||||||
}
|
|
||||||
if (response.data.graduation_groups) {
|
|
||||||
this.setState({
|
|
||||||
graduation_groups: response.data.graduation_groups,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (response.data.course_groups) {
|
|
||||||
this.setState({
|
|
||||||
course_groups: response.data.course_groups,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
setVisible = (visible) => {
|
|
||||||
if (visible) {
|
|
||||||
this.fetchOptions();
|
|
||||||
}
|
|
||||||
this.refs.modalWrapper.setVisible(visible);
|
|
||||||
if (visible == false) {
|
|
||||||
this.setState({
|
|
||||||
checkBoxValues: [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
name: undefined,
|
|
||||||
graduationGroup: undefined,
|
|
||||||
courseGroup: undefined,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onSendOk = () => {
|
|
||||||
const courseId = this.props.match.params.coursesId;
|
|
||||||
const url = `/courses/${courseId}/add_teacher.json`;
|
|
||||||
if (this.state.checkBoxValues.length == 0) {
|
|
||||||
this.props.showNotification("请先在下面列表中选择要添加教师的成员");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const params = {
|
|
||||||
user_list: this.state.checkBoxValues.map((item) => {
|
|
||||||
return { user_id: item };
|
|
||||||
}),
|
|
||||||
// "graduation_group_id": "2",
|
|
||||||
// "course_group_id": "820",
|
|
||||||
role: this.props.isTeacher ? ROLE_TEACHER_NUM : ROLE_ASSISTANT_NUM,
|
|
||||||
};
|
|
||||||
const { graduationGroup, courseGroup } = this.state;
|
|
||||||
if (graduationGroup) {
|
|
||||||
params.graduation_group_id = graduationGroup;
|
|
||||||
}
|
|
||||||
if (courseGroup) {
|
|
||||||
params.course_group_id = courseGroup;
|
|
||||||
}
|
|
||||||
axios
|
|
||||||
.post(url, params)
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.status == 0) {
|
|
||||||
this.setVisible(false);
|
|
||||||
this.props.showNotification("添加成功");
|
|
||||||
this.props.addTeacherSuccess && this.props.addTeacherSuccess(params);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onOk = () => {
|
|
||||||
this.onSendOk();
|
|
||||||
};
|
|
||||||
|
|
||||||
onCheckBoxChange = (checkBoxValues) => {
|
|
||||||
this.setState({
|
|
||||||
checkBoxValues: checkBoxValues,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleInfiniteOnLoad = () => {
|
|
||||||
this.fetchMemberList(this.state.page + 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
onSearch = () => {
|
|
||||||
this.fetchMemberList(1);
|
|
||||||
};
|
|
||||||
handleGradationGroupChange = (value) => {
|
|
||||||
this.setState({
|
|
||||||
graduationGroup: value,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
handleCourseGroupChange = (value) => {
|
|
||||||
this.setState({
|
|
||||||
courseGroup: value,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
onOrgNameChange = (value) => {
|
|
||||||
// console.log('school_name: ', value)
|
|
||||||
this.setState({ school_name: value });
|
|
||||||
};
|
|
||||||
|
|
||||||
hasGraduationModule = () => {
|
|
||||||
const { course_modules } = this.props;
|
|
||||||
const result =
|
|
||||||
course_modules &&
|
|
||||||
course_modules.filter((item) => {
|
|
||||||
return item.type == "graduation";
|
|
||||||
});
|
|
||||||
return result && result.length > 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
candidates,
|
|
||||||
checkBoxValues,
|
|
||||||
loading,
|
|
||||||
hasMore,
|
|
||||||
name,
|
|
||||||
school_name,
|
|
||||||
school_names,
|
|
||||||
graduationGroup,
|
|
||||||
graduation_groups,
|
|
||||||
courseGroup,
|
|
||||||
course_groups,
|
|
||||||
} = this.state;
|
|
||||||
const { moduleName } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ModalWrapper
|
|
||||||
ref="modalWrapper"
|
|
||||||
width="700px"
|
|
||||||
title={`添加${moduleName}`}
|
|
||||||
{...this.props}
|
|
||||||
onOk={this.onOk}
|
|
||||||
className="addTeacherModal courseForm"
|
|
||||||
>
|
|
||||||
<AddGraduationGroupModal
|
|
||||||
ref="addGraduationGroupModal"
|
|
||||||
{...this.props}
|
|
||||||
onOk={this.onAddGraduationGroupOk}
|
|
||||||
></AddGraduationGroupModal>
|
|
||||||
<style>
|
|
||||||
{`
|
|
||||||
.demo-loading-container {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 210px;
|
|
||||||
width: 82%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.df {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
margin: 12px 0;
|
|
||||||
}
|
|
||||||
.firstLabel {
|
|
||||||
flex: 0 0 60px;
|
|
||||||
}
|
|
||||||
.df span.label {
|
|
||||||
margin-right: 8px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.df .ant-input-affix-wrapper {
|
|
||||||
width: 32%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.addTeacherModal label.task-hide {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
</style>
|
|
||||||
<div className="df">
|
|
||||||
<span className="firstLabel label" style={{ flex: "0 0 40px" }}>
|
|
||||||
姓名:
|
|
||||||
</span>
|
|
||||||
<Input
|
|
||||||
allowClear
|
|
||||||
placeholder="请输入真实姓名"
|
|
||||||
value={name}
|
|
||||||
onChange={(e) => {
|
|
||||||
this.setState({ name: e.target.value });
|
|
||||||
}}
|
|
||||||
style={{ width: "200px", marginRight: "18px" }}
|
|
||||||
></Input>
|
|
||||||
<span
|
|
||||||
className="label"
|
|
||||||
style={{ minWidth: "36px", flex: "0 0 40px" }}
|
|
||||||
>
|
|
||||||
单位:
|
|
||||||
</span>
|
|
||||||
<SchoolSelect
|
|
||||||
value={school_name}
|
|
||||||
onChange={this.onOrgNameChange}
|
|
||||||
></SchoolSelect>
|
|
||||||
{/* <Select allowClear placeholder="请输入单位名称" value={school_name}
|
|
||||||
style={{ width: '200px'}} showArrow={false}
|
|
||||||
filterOption={false} onSearch={this.onOrgNameSearch}
|
|
||||||
onChange={this.onOrgNameChange} notFoundContent={null}
|
|
||||||
showSearch defaultActiveFirstOption={false}
|
|
||||||
>
|
|
||||||
{ school_names && school_names.map((item, index) => {
|
|
||||||
return <Option value={item} key={index}>{item}</Option>
|
|
||||||
})}
|
|
||||||
</Select> */}
|
|
||||||
<a
|
|
||||||
className="task-btn task-btn-orange"
|
|
||||||
onClick={() => this.fetchMemberList(1)}
|
|
||||||
style={{
|
|
||||||
height: "30px",
|
|
||||||
lineHeight: "30px",
|
|
||||||
marginLeft: "10px",
|
|
||||||
width: "70px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
搜索
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{/* graduation_groups && !!graduation_groups.length */}
|
|
||||||
|
|
||||||
<p className="clearfix mb2" style={{ margin: "0px 20px 6px" }}>
|
|
||||||
<Checkbox className="fl" style={{ visibility: "hidden" }}></Checkbox>
|
|
||||||
<span className="fl task-hide with20" style={{ maxWidth: "208px;" }}>
|
|
||||||
{"姓名"}
|
|
||||||
</span>
|
|
||||||
<span className="fl task-hide with23" style={{ maxWidth: "208px;" }}>
|
|
||||||
{"手机号/邮箱"}
|
|
||||||
</span>
|
|
||||||
<span className="fl task-hide with23" style={{ maxWidth: "208px;" }}>
|
|
||||||
{"最后登录时间"}
|
|
||||||
</span>
|
|
||||||
<span className="fl task-hide with20" style={{ maxWidth: "208px;" }}>
|
|
||||||
{"单位"}
|
|
||||||
</span>
|
|
||||||
<span className="fl task-hide with5" style={{ maxWidth: "48px" }}>
|
|
||||||
{""}
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
{loading || candidates.length ? (
|
|
||||||
<div>
|
|
||||||
{/* https://github.com/CassetteRocks/react-infinite-scroller/issues/70 */}
|
|
||||||
<div
|
|
||||||
className="edu-back-skyblue padding10-15"
|
|
||||||
style={{
|
|
||||||
height: "300px",
|
|
||||||
overflowY: "scroll",
|
|
||||||
overflowAnchor: "none",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<InfiniteScroll
|
|
||||||
threshold={10}
|
|
||||||
initialLoad={false}
|
|
||||||
pageStart={0}
|
|
||||||
loadMore={this.handleInfiniteOnLoad}
|
|
||||||
hasMore={!loading && hasMore}
|
|
||||||
useWindow={false}
|
|
||||||
>
|
|
||||||
<Checkbox.Group
|
|
||||||
style={{ width: "100%" }}
|
|
||||||
onChange={this.onCheckBoxChange}
|
|
||||||
value={checkBoxValues}
|
|
||||||
>
|
|
||||||
{candidates &&
|
|
||||||
candidates.map((candidate) => {
|
|
||||||
return (
|
|
||||||
<p className="clearfix mb7" key={candidate.id}>
|
|
||||||
<Checkbox
|
|
||||||
className="fl"
|
|
||||||
value={candidate.id}
|
|
||||||
key={candidate.id}
|
|
||||||
disabled={candidate.added}
|
|
||||||
></Checkbox>
|
|
||||||
<span
|
|
||||||
className="fl task-hide with20 ml5"
|
|
||||||
style={{ height: "20px" }}
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href={`/users/${candidate.login}`}
|
|
||||||
target="_blank"
|
|
||||||
title={candidate.name}
|
|
||||||
>
|
|
||||||
{candidate.name}
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="fl task-hide with23"
|
|
||||||
title={
|
|
||||||
candidate.phone
|
|
||||||
? formatePhone(candidate.phone)
|
|
||||||
: formatePhone(candidate.email)
|
|
||||||
}
|
|
||||||
style={{ height: "20px" }}
|
|
||||||
>
|
|
||||||
{candidate.phone
|
|
||||||
? formatePhone(candidate.phone)
|
|
||||||
: formatePhone(candidate.email)}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="fl task-hide with23"
|
|
||||||
title={formatTime(candidate.last_login_on)}
|
|
||||||
style={{ height: "20px" }}
|
|
||||||
>
|
|
||||||
{formatTime(candidate.last_login_on)}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="fl task-hide with20"
|
|
||||||
title={candidate.school_name}
|
|
||||||
style={{ height: "20px" }}
|
|
||||||
>
|
|
||||||
{candidate.school_name||'-'}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="fl task-hide with5 color-blue"
|
|
||||||
style={{ maxWidth: "48px;" }}
|
|
||||||
>
|
|
||||||
{candidate.added ? "已加入" : ""}
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Checkbox.Group>
|
|
||||||
{loading && hasMore && (
|
|
||||||
<div className="demo-loading-container">
|
|
||||||
<Spin />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</InfiniteScroll>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<NoneData></NoneData>
|
|
||||||
)}
|
|
||||||
<div className="df">
|
|
||||||
{/* { this.hasGraduationModule() && <div className="df" style={{ marginTop: '24px' }} >
|
|
||||||
<span className="firstLabel label" style={{ flex: '0 0 96px' }}>添加至答辩组:</span>
|
|
||||||
<Select style={{ width: 218, marginRight: '18px' }} onChange={this.handleGradationGroupChange} value={graduationGroup}
|
|
||||||
dropdownRender={menu => (
|
|
||||||
<div>
|
|
||||||
{menu}
|
|
||||||
<Divider style={{ margin: '4px 0' }} />
|
|
||||||
<div style={{ padding: '8px', cursor: 'pointer' }}
|
|
||||||
onMouseDown={() => { ; this.refs['addGraduationGroupModal'].setVisible(true) }}
|
|
||||||
>
|
|
||||||
<Icon type="plus" /> 添加答辩组
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{ graduation_groups && graduation_groups.map((item) => {
|
|
||||||
return <Option value={item.id}>{item.name}</Option>
|
|
||||||
})}
|
|
||||||
</Select>
|
|
||||||
</div>} */}
|
|
||||||
|
|
||||||
{course_groups && !!course_groups.length && (
|
|
||||||
<div className="df" style={{ width: "100%" }}>
|
|
||||||
<span className="firstLabel label">管理权限:</span>
|
|
||||||
<Select
|
|
||||||
style={{ width: "100%" }}
|
|
||||||
onChange={this.handleCourseGroupChange}
|
|
||||||
value={courseGroup}
|
|
||||||
>
|
|
||||||
{course_groups &&
|
|
||||||
course_groups.map((item) => {
|
|
||||||
return <Option value={item.id}>{item.name}</Option>;
|
|
||||||
})}
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</ModalWrapper>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default AddTeacherModal;
|
|
|
@ -1,127 +0,0 @@
|
||||||
import React, { useState, useEffect, useRef, useMemo } from 'react'
|
|
||||||
import { trigger } from 'educoder'
|
|
||||||
import { Input, Checkbox } from "antd";
|
|
||||||
import CourseGroupChooser from '../CourseGroupChooser'
|
|
||||||
import ModalWrapper from "../../common/ModalWrapper"
|
|
||||||
import axios from 'axios'
|
|
||||||
/**
|
|
||||||
arg_course_groups 选中的id数组
|
|
||||||
joinCourseGroup 选中时触发 joinCourseGroup(checkedValues, item, index) 传入item:数据对象,index: 数据对象index
|
|
||||||
checkAllValue 是否全选
|
|
||||||
onCheckAllChange 全选 onCheckAllChange(e, item, index)
|
|
||||||
course_groups 所有的group
|
|
||||||
*/
|
|
||||||
function CourseGroupChooserModal({ course_groups = [], isAdminOrCreator, item, index,
|
|
||||||
setVisible, visible, record = {}, props = {}, fetchAll
|
|
||||||
}) {
|
|
||||||
// , arg_course_groups, checkAllValue , onCheckAllChange, joinCourseGroup
|
|
||||||
const [checkAllValue, setCheckAllValue] = useState(true)
|
|
||||||
const [arg_course_groups, setArg_course_groups] = useState(course_groups.map(item => item.id))
|
|
||||||
const modalEl = useRef(null);
|
|
||||||
useEffect(() => {
|
|
||||||
setCheckAllValue(true)
|
|
||||||
setArg_course_groups(course_groups.map(item => item.id))
|
|
||||||
}, [course_groups, visible])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (visible != undefined) {
|
|
||||||
modalEl.current.setVisible(true)
|
|
||||||
}
|
|
||||||
}, [visible])
|
|
||||||
|
|
||||||
const joinCourseGroup = (checks) => {
|
|
||||||
setArg_course_groups(checks)
|
|
||||||
}
|
|
||||||
const onCheckAllChange = (e) => {
|
|
||||||
if (checkAllValue) {
|
|
||||||
setArg_course_groups([])
|
|
||||||
} else {
|
|
||||||
setArg_course_groups(course_groups.map(item => item.id))
|
|
||||||
}
|
|
||||||
setCheckAllValue(!checkAllValue)
|
|
||||||
}
|
|
||||||
const onOk = async () => {
|
|
||||||
let approval = 1
|
|
||||||
const courseId = props.match.params.coursesId
|
|
||||||
let url = `/courses/${courseId}/teacher_application_review.json`
|
|
||||||
const response = await axios.post(url, {
|
|
||||||
user_id: record.user_id,
|
|
||||||
application_id: record.application_id,
|
|
||||||
approval: approval,
|
|
||||||
group_id: arg_course_groups
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.data.status === 0) {
|
|
||||||
props.showNotification(`已${approval == 1? '同意' : '拒绝'}`)
|
|
||||||
fetchAll(1)
|
|
||||||
modalEl.current.setVisible(false)
|
|
||||||
}})
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<ModalWrapper
|
|
||||||
ref={modalEl}
|
|
||||||
width="600px"
|
|
||||||
title={`同意`}
|
|
||||||
visible={visible}
|
|
||||||
onOk={onOk}
|
|
||||||
className="courseGroupChooserModal"
|
|
||||||
>
|
|
||||||
<style>{`
|
|
||||||
.courseGroupChooserModal .ant-modal-body{
|
|
||||||
padding:20px 30px;
|
|
||||||
}
|
|
||||||
.courseGroupChooserModal .description {
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
.courseGroupChooserModal .marginauto{
|
|
||||||
margin-top:10px!important;
|
|
||||||
}
|
|
||||||
.courseGroupChooserModal .drop_down_menu {
|
|
||||||
position: relative;
|
|
||||||
top: auto;
|
|
||||||
box-shadow: none;
|
|
||||||
padding:0px;
|
|
||||||
}
|
|
||||||
.courseGroupChooserModal .drop_down_menu .mainGroup{
|
|
||||||
background: #f2f9ff;
|
|
||||||
padding: 0 20px;
|
|
||||||
}
|
|
||||||
.courseGroupChooserModal .drop_down_menu li:hover,.courseGroupChooserModal .drop_down_normal li:hover{
|
|
||||||
background: #f2f9ff;
|
|
||||||
}
|
|
||||||
.courseGroupChooserModal .drop_down_menu .mainGroup.ant-checkbox-group {
|
|
||||||
width: 100%;
|
|
||||||
max-height: 300px!important;
|
|
||||||
height: 300px;
|
|
||||||
}
|
|
||||||
.courseGroupChooserModal .drop_down_search {
|
|
||||||
margin: 0;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.courseGroupChooserModal .drop_down_menu li {
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
.courseGroupChooserModal .drop_down_menu .drop_down_btn {
|
|
||||||
height: 26px;
|
|
||||||
line-height: 26px;
|
|
||||||
padding: 0px 20px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.mainGroup .drop_down_menu .drop_down_btn{
|
|
||||||
height: 26px;
|
|
||||||
line-height: 26px;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
{/* <React.Fragment>
|
|
||||||
<React.Fragment> */}
|
|
||||||
<div className="description">确认同意TA的加入,并设置TA的分班管理权限</div>
|
|
||||||
<CourseGroupChooser
|
|
||||||
{...{ checkAllValue, isAdminOrCreator, course_groups, arg_course_groups, item, index,
|
|
||||||
joinCourseGroup, onCheckAllChange, alwaysShow: true }}
|
|
||||||
></CourseGroupChooser>
|
|
||||||
|
|
||||||
</ModalWrapper>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default (CourseGroupChooserModal)
|
|
|
@ -1,153 +0,0 @@
|
||||||
import React, { Component } from "react";
|
|
||||||
import { Modal, Checkbox, Input, Spin, Upload, Divider, Icon } from "antd";
|
|
||||||
import axios from 'axios'
|
|
||||||
import ModalWrapper from "../../common/ModalWrapper"
|
|
||||||
|
|
||||||
import { ConditionToolTip, getUploadActionUrl } from 'educoder'
|
|
||||||
|
|
||||||
const { Dragger } = Upload;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CreateGroupByImportModal extends Component{
|
|
||||||
constructor(props){
|
|
||||||
super(props);
|
|
||||||
this.state={
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fetchMemberList = (arg_page) => {
|
|
||||||
}
|
|
||||||
componentDidMount() {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
onSendOk = () => {
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
|
|
||||||
let url = `/courses/${courseId}/create_group_by_importing_file.json`
|
|
||||||
let { fileList } =this.state;
|
|
||||||
|
|
||||||
if (!fileList || fileList.length == 0) {
|
|
||||||
// this.props.showNotification('请先上传附件')
|
|
||||||
this.setState({
|
|
||||||
errorTip :'请先上传附件',
|
|
||||||
})
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let newfileList=[];
|
|
||||||
if(fileList!=undefined&&fileList.length>0) {
|
|
||||||
for (var list of fileList) {
|
|
||||||
newfileList.push(list.response.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
axios.post(url, {
|
|
||||||
attachment_ids: newfileList
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.status == 0) {
|
|
||||||
this.props.showNotification(response.data.message)
|
|
||||||
this.props.createGroupImportSuccess && this.props.createGroupImportSuccess()
|
|
||||||
this.setVisible(false)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
setVisible = (visible) => {
|
|
||||||
if (visible) {
|
|
||||||
this.setState({ fileList: [] });
|
|
||||||
}
|
|
||||||
this.refs.modalWrapper.setVisible(visible)
|
|
||||||
|
|
||||||
}
|
|
||||||
handleChange = (info) => {
|
|
||||||
let fileList = info.fileList;
|
|
||||||
console.log(fileList)
|
|
||||||
this.setState({ fileList });
|
|
||||||
}
|
|
||||||
|
|
||||||
onOk = () => {
|
|
||||||
this.onSendOk()
|
|
||||||
}
|
|
||||||
|
|
||||||
onAttachmentRemove = (file) => {
|
|
||||||
if(!file.percent || file.percent == 100){
|
|
||||||
this.props.confirm({
|
|
||||||
content: '是否确认删除?',
|
|
||||||
|
|
||||||
onOk: () => {
|
|
||||||
this.deleteAttachment(file)
|
|
||||||
},
|
|
||||||
onCancel() {
|
|
||||||
console.log('Cancel');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
deleteAttachment = (file) => {
|
|
||||||
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
|
|
||||||
axios.delete(url, {
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data) {
|
|
||||||
// const { status } = response.data;
|
|
||||||
if (response.data.status === 0) {
|
|
||||||
|
|
||||||
this.setState((state) => {
|
|
||||||
const index = state.fileList.indexOf(file);
|
|
||||||
const newFileList = state.fileList.slice();
|
|
||||||
newFileList.splice(index, 1);
|
|
||||||
return {
|
|
||||||
fileList: newFileList,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render(){
|
|
||||||
const { candidates, checkBoxValues, loading, hasMore, name, school_name, school_names
|
|
||||||
, graduationGroup, graduation_groups, courseGroup, course_groups , fileList } = this.state
|
|
||||||
const { moduleName } = this.props
|
|
||||||
|
|
||||||
const props = {
|
|
||||||
name: 'file',
|
|
||||||
multiple: true,
|
|
||||||
fileList:fileList,
|
|
||||||
action: getUploadActionUrl(),
|
|
||||||
onRemove: this.onAttachmentRemove,
|
|
||||||
onChange: this.handleChange
|
|
||||||
};
|
|
||||||
return(
|
|
||||||
<ModalWrapper
|
|
||||||
ref="modalWrapper"
|
|
||||||
width="700px"
|
|
||||||
title={`导入创建分班`}
|
|
||||||
{...this.props }
|
|
||||||
onOk={this.onOk}
|
|
||||||
className="createGroupByImport"
|
|
||||||
>
|
|
||||||
<Dragger {...props}>
|
|
||||||
<p className="ant-upload-drag-icon">
|
|
||||||
<Icon type="inbox" />
|
|
||||||
</p>
|
|
||||||
<p className="ant-upload-text">点击或拖拽文件到这里上传</p>
|
|
||||||
<p className="ant-upload-hint">
|
|
||||||
单个文件最大150MB
|
|
||||||
</p>
|
|
||||||
</Dragger>
|
|
||||||
</ModalWrapper>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default CreateGroupByImportModal;
|
|
|
@ -1,51 +0,0 @@
|
||||||
.stu_table .ant-table-thead > tr > th, .stu_table .ant-table-tbody > tr > td,
|
|
||||||
.courseGroupList .ant-table-thead > tr > th, .courseGroupList .ant-table-tbody > tr > td {
|
|
||||||
padding: 14px 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.E9F8FF{
|
|
||||||
background-color: #E9F8FF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codeBtnStyle{
|
|
||||||
height: 18px;
|
|
||||||
line-height: 18px;
|
|
||||||
padding:0px 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 12px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
.codeBtn_yellow{
|
|
||||||
border:1px solid #FF6B06;
|
|
||||||
color: #FF6B06!important;
|
|
||||||
}
|
|
||||||
.codeBtn_green{
|
|
||||||
border:1px solid #00BA38;
|
|
||||||
color: #00BA38!important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codeBtn_blue{
|
|
||||||
border:1px solid #4CACFF;
|
|
||||||
color: #4CACFF!important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.course_publicNav{
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.course_publicNav li{
|
|
||||||
position: relative;
|
|
||||||
margin-right: 30px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.course_publicNav li.active{
|
|
||||||
color: #4CACFF
|
|
||||||
}
|
|
||||||
.course_publicNav li.active::after{
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 2px;
|
|
||||||
content: '';
|
|
||||||
left: 0px;
|
|
||||||
bottom: -33px;
|
|
||||||
background: #4CACFF;
|
|
||||||
}
|
|
|
@ -1,937 +0,0 @@
|
||||||
import React, { Component } from "react";
|
|
||||||
import { Input, Checkbox, Table, Pagination, Modal, Menu, Spin, Tooltip, Divider, Popconfirm } from "antd";
|
|
||||||
import ClipboardJS from 'clipboard'
|
|
||||||
import '../css/Courses.css'
|
|
||||||
import '../css/members.css'
|
|
||||||
import CourseLayoutcomponent from '../common/CourseLayoutComponent'
|
|
||||||
|
|
||||||
import Titlesearchsection from '../common/titleSearch/TitleSearchSection'
|
|
||||||
import ColorCountText from '../common/titleSearch/ColorCountText'
|
|
||||||
import { WordsBtn, trigger, on, off, getRandomcode, getRandomNumber, sortDirections } from 'educoder'
|
|
||||||
import Modals from "../../modals/Modals";
|
|
||||||
import axios from 'axios'
|
|
||||||
import _ from 'lodash'
|
|
||||||
import NoneData from "../coursesPublic/NoneData"
|
|
||||||
import DownloadMessageysl from "../../modals/DownloadMessageysl";
|
|
||||||
import CreateGroupByImportModal from './modal/CreateGroupByImportModal'
|
|
||||||
import ChangeRolePop from './ChangeRolePop'
|
|
||||||
import "./studentsList.css"
|
|
||||||
|
|
||||||
const Search = Input.Search;
|
|
||||||
const TYPE_STUDENTS = 1
|
|
||||||
const TYPE_COURSE_GOURP_PARENT = 2
|
|
||||||
const TYPE_COURSE_GOURP_CHILD = 3
|
|
||||||
const buildColumns = (that, isParent) => {
|
|
||||||
const { course_groups, sortedInfo } = that.state
|
|
||||||
let showSorter = isParent == true
|
|
||||||
const courseId = that.props.match.params.coursesId
|
|
||||||
const columns = [{
|
|
||||||
title: '序号',
|
|
||||||
dataIndex: 'id',
|
|
||||||
key: 'id',
|
|
||||||
align: 'center',
|
|
||||||
width: "8%",
|
|
||||||
className: "color-grey-6",
|
|
||||||
render: (id, student, index) => {
|
|
||||||
return (that.state.page - 1) * 20 + index + 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// title: '用户id',
|
|
||||||
// dataIndex: 'login',
|
|
||||||
// key: 'login',
|
|
||||||
// align:'center',
|
|
||||||
// width:"10%",
|
|
||||||
// className:"color-grey-6",
|
|
||||||
// render: (login, record) => {
|
|
||||||
// return <span className="color-dark overflowHidden1" style={{maxWidth: '160px'}}
|
|
||||||
// title={login && login.length > 10 ? login : ''}
|
|
||||||
// >{login}</span>
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
title: '姓名',
|
|
||||||
dataIndex: 'name',
|
|
||||||
key: 'name',
|
|
||||||
align: 'center',
|
|
||||||
width: "10%",
|
|
||||||
className: "color-grey-6",
|
|
||||||
render: (name, record) => {
|
|
||||||
return <a className="color-dark overflowHidden1" target="_blank"
|
|
||||||
style={{ maxWidth: '120px' }} href={`/users/${record.login}`}>{name}</a>
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
title: '学号',
|
|
||||||
dataIndex: 'student_id',
|
|
||||||
key: 'student_id',
|
|
||||||
align: 'center',
|
|
||||||
width: "10%",
|
|
||||||
className: "color-grey-6",
|
|
||||||
sorter: true,
|
|
||||||
sortDirections: sortDirections,
|
|
||||||
sortOrder: sortedInfo.columnKey === 'student_id' && sortedInfo.order,
|
|
||||||
render: (student_id, record) => {
|
|
||||||
return <span className="color-dark overflowHidden1 " title={student_id && student_id.length > 10 ? student_id : ''}
|
|
||||||
style={{ maxWidth: '160px' }} >{student_id}</span>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
title: '手机号',
|
|
||||||
dataIndex: 'user_phone',
|
|
||||||
key: 'user_phone',
|
|
||||||
align: 'center',
|
|
||||||
width: "10%",
|
|
||||||
className: "color-grey-6",
|
|
||||||
// sorter: true,
|
|
||||||
// sortDirections: sortDirections,
|
|
||||||
// sortOrder: sortedInfo.columnKey === 'user_phone' && sortedInfo.order,
|
|
||||||
render: (user_phone, record) => {
|
|
||||||
return <span className="color-dark overflowHidden1 " title={user_phone && user_phone.length > 10 ? user_phone : ''}
|
|
||||||
style={{ maxWidth: '160px' }} >{user_phone}</span>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
title: '邮箱',
|
|
||||||
dataIndex: 'user_mail',
|
|
||||||
key: 'user_mail',
|
|
||||||
align: 'center',
|
|
||||||
width: "10%",
|
|
||||||
className: "color-grey-6",
|
|
||||||
// sorter: true,
|
|
||||||
// sortDirections: sortDirections,
|
|
||||||
// sortOrder: sortedInfo.columnKey === 'user_mail' && sortedInfo.order,
|
|
||||||
render: (user_mail, record) => {
|
|
||||||
return <span className="color-dark overflowHidden1 " title={user_mail && user_mail.length > 10 ? user_mail : ''}
|
|
||||||
style={{ maxWidth: '160px' }} >{user_mail}</span>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
if (that.hasGroupModule()) {
|
|
||||||
that.isStudentPage && columns.push({
|
|
||||||
title: '分班',
|
|
||||||
dataIndex: 'course_group_name',
|
|
||||||
key: 'course_group_name',
|
|
||||||
align: 'center',
|
|
||||||
width: "25%",
|
|
||||||
className: "color-grey-6",
|
|
||||||
sorter: showSorter,
|
|
||||||
sortDirections: sortDirections,
|
|
||||||
sortOrder: sortedInfo.columnKey === 'course_group_name' && sortedInfo.order,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const isAdminOrStudent = that.props.isAdminOrStudent()
|
|
||||||
if (!isAdminOrStudent) {
|
|
||||||
columns.some((item, key) => {
|
|
||||||
if (item.title === "学号") {
|
|
||||||
columns.splice(key, 1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const isAdmin = that.props.isAdmin()
|
|
||||||
if (isAdmin) {
|
|
||||||
!that.isStudentPage && columns.unshift({
|
|
||||||
title: '',
|
|
||||||
dataIndex: 'check',
|
|
||||||
key: 'check',
|
|
||||||
render: (text, item) => {
|
|
||||||
return <Checkbox value={item.course_member_id} key={item.course_member_id} ></Checkbox>
|
|
||||||
},
|
|
||||||
width: "5%"
|
|
||||||
})
|
|
||||||
|
|
||||||
columns.push({
|
|
||||||
title: '操作',
|
|
||||||
key: 'action',
|
|
||||||
width: '22%',
|
|
||||||
align: 'center',
|
|
||||||
render: (text, record) => {
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<WordsBtn onClick={() => that.onDelete(record)} style={'grey'}>删除学生</WordsBtn>
|
|
||||||
{record.member_roles && record.member_roles.length && <ChangeRolePop
|
|
||||||
style={{ marginLeft: '12px' }}
|
|
||||||
courseId={courseId}
|
|
||||||
record={record}
|
|
||||||
member_roles={record.member_roles}
|
|
||||||
onChangeRoleSuccess={that.onChangeRoleSuccess}
|
|
||||||
showNotification={that.props.showNotification}
|
|
||||||
getUserId={that.props.isUserid}
|
|
||||||
fetchUser={that.props.fetchUser}
|
|
||||||
></ChangeRolePop>}
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1-按照学生学号 2-按照分班名称,
|
|
||||||
const ORDER_BY_NUM = 1;
|
|
||||||
const ORDER_BY_GROUP = 2;
|
|
||||||
|
|
||||||
class studentsList extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
page: 1,
|
|
||||||
order: ORDER_BY_NUM,
|
|
||||||
searchValue: '',
|
|
||||||
course_groups: [],
|
|
||||||
students: [],
|
|
||||||
checkBoxValues: [],
|
|
||||||
|
|
||||||
stu_new_flag: false,
|
|
||||||
StudentList_value: "",
|
|
||||||
modalsType: "",
|
|
||||||
modalsTopval: "",
|
|
||||||
modalsBottomval: "",
|
|
||||||
modalCancel: "",
|
|
||||||
n_And_e: 1,
|
|
||||||
isSpin: false,
|
|
||||||
DownloadType: false,
|
|
||||||
DownloadMessageval: undefined,
|
|
||||||
sortedInfo: { order: 'ascend', columnKey: 'student_id' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// 确认是否下载
|
|
||||||
confirmysl(url, urls) {
|
|
||||||
// this.props.showGlobalLoading('正在生成文件,请稍后...')
|
|
||||||
axios.get(url + 'export=true').then((response) => {
|
|
||||||
if (response === undefined) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (response.data.status && response.data.status === -1) {
|
|
||||||
|
|
||||||
} else if (response.data.status && response.data.status === -2) {
|
|
||||||
if (response.data.message === "100") {
|
|
||||||
// 已超出文件导出的上限数量(100 ),建议:
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
DownloadType: true,
|
|
||||||
DownloadMessageval: 100
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
//因附件资料超过500M
|
|
||||||
this.setState({
|
|
||||||
DownloadType: true,
|
|
||||||
DownloadMessageval: 500
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// this.props.showNotification(`正在下载中`);
|
|
||||||
// window.open("/api"+url, '_blank');
|
|
||||||
this.props.slowDownload(getRandomcode(url))
|
|
||||||
|
|
||||||
// getUrl() + "/api"+
|
|
||||||
// const fileUrl = url;
|
|
||||||
|
|
||||||
// this.props.slowDownload(fileUrl)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// downloadFile({
|
|
||||||
// url: fileUrl,
|
|
||||||
// successCallback: (url) => {
|
|
||||||
// console.log('successCallback')
|
|
||||||
// },
|
|
||||||
// failCallback: (responseHtml, url) => {
|
|
||||||
// console.log('failCallback')
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// window.open(fileUrl, "_self");// , '_blank'
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
hasGroupModule = () => {
|
|
||||||
const { course_modules } = this.props;
|
|
||||||
const result = course_modules && course_modules.filter(item => {
|
|
||||||
return item.type == 'course_group'
|
|
||||||
})
|
|
||||||
return result && result.length > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Downloadcal = () => {
|
|
||||||
this.setState({
|
|
||||||
DownloadType: false,
|
|
||||||
DownloadMessageval: undefined
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
inputStudent = (e) => {
|
|
||||||
this.setState({
|
|
||||||
StudentList_value: e.target.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 有关新建分班和分班重命名
|
|
||||||
showStuNewBox = (index) => {
|
|
||||||
this.setState({
|
|
||||||
stu_new_flag: true,
|
|
||||||
n_And_e: index
|
|
||||||
})
|
|
||||||
}
|
|
||||||
hideStuNewBox = () => {
|
|
||||||
this.setState({
|
|
||||||
stu_new_flag: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 有关删除分班
|
|
||||||
delClasses = () => {
|
|
||||||
this.setState({
|
|
||||||
modalsType: true,
|
|
||||||
modalsTopval: "该分班的学生将被移动到“XX班”",
|
|
||||||
modalsBottomval: "是否确认删除?",
|
|
||||||
modalCancel: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
cancelDelClasses = () => {
|
|
||||||
this.setState({
|
|
||||||
modalsType: false,
|
|
||||||
modalsTopval: "",
|
|
||||||
modalsBottomval: "",
|
|
||||||
modalCancel: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 确认删除
|
|
||||||
sureDelClasses = () => {
|
|
||||||
this.setState({
|
|
||||||
modalsType: false,
|
|
||||||
modalsTopval: "",
|
|
||||||
modalsBottomval: "",
|
|
||||||
modalCancel: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onChange = () => {
|
|
||||||
|
|
||||||
}
|
|
||||||
onChangeRoleSuccess = () => {
|
|
||||||
const { page, searchValue } = this.state;
|
|
||||||
this.fetchAll(page, searchValue);
|
|
||||||
}
|
|
||||||
componentDidMount() {
|
|
||||||
this.setState({
|
|
||||||
isSpin: true
|
|
||||||
})
|
|
||||||
const { page, searchValue } = this.state;
|
|
||||||
this.fetchAll(page, searchValue);
|
|
||||||
const isAdmin = this.props.isAdmin()
|
|
||||||
// if (isAdmin) {
|
|
||||||
this.fetchCourseGroups();
|
|
||||||
// }
|
|
||||||
|
|
||||||
isAdmin && on('addStudentSuccess', this.addStudentSuccessListener)
|
|
||||||
isAdmin && on('updateNavSuccess', this.updateNavSuccess)
|
|
||||||
}
|
|
||||||
componentWillUnmount() {
|
|
||||||
if (this.clipboard) {
|
|
||||||
this.clipboard.destroy()
|
|
||||||
}
|
|
||||||
const isAdmin = this.props.isAdmin()
|
|
||||||
if (isAdmin) {
|
|
||||||
off('addStudentSuccess', this.addStudentSuccessListener)
|
|
||||||
off('updateNavSuccess', this.updateNavSuccess)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
createGroupImportSuccess = () => {
|
|
||||||
this.props.updataleftNavfun()
|
|
||||||
}
|
|
||||||
updateNavSuccess = () => {
|
|
||||||
this.fetchCourseGroups();
|
|
||||||
const { page, searchValue } = this.state;
|
|
||||||
|
|
||||||
this.fetchAll(page, searchValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
addStudentSuccessListener = (e, data) => {
|
|
||||||
const params = JSON.parse(data)
|
|
||||||
this.props.updataleftNavfun()
|
|
||||||
const course_group_id = this.props.match.params.course_group_id;
|
|
||||||
const coursesId = this.props.match.params.coursesId;
|
|
||||||
const { searchValue } = this.state;
|
|
||||||
if (params.course_group_id === course_group_id) {
|
|
||||||
this.fetchAll(1, searchValue);
|
|
||||||
} else {
|
|
||||||
this.props.history.push(`/classrooms/${coursesId}/course_groups/${params.course_group_id || '0'}`)
|
|
||||||
}
|
|
||||||
// console.log('addStudentSuccessListener', data)
|
|
||||||
}
|
|
||||||
fetchCourseGroups = () => {
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
|
|
||||||
let url = `/courses/${courseId}/all_course_groups.json`
|
|
||||||
|
|
||||||
axios.get(url, {
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.course_groups && response.data.course_groups.length) {
|
|
||||||
this.setState({
|
|
||||||
course_groups: response.data.course_groups
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// showNotification('')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
componentDidUpdate(prevProps) {
|
|
||||||
if (prevProps.match.params.course_group_id != this.props.match.params.course_group_id) {
|
|
||||||
this.setState({ checkBoxValues: [], checkAllValue: false })
|
|
||||||
|
|
||||||
this.fetchAll(1, this.state.searchValue)
|
|
||||||
}
|
|
||||||
// 加载了2次
|
|
||||||
// else if (prevProps.coursesids != this.props.coursesids) {
|
|
||||||
// this.fetchAll(1)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
fetchAll = (argPage, searchValue) => {
|
|
||||||
this.setState({
|
|
||||||
isSpin: true
|
|
||||||
})
|
|
||||||
let id = this.props.match.params.coursesId
|
|
||||||
let course_group_id = this.props.match.params.course_group_id
|
|
||||||
|
|
||||||
const { coursesids } = this.props
|
|
||||||
// if (!coursesids) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
if (!course_group_id || course_group_id == coursesids) {
|
|
||||||
course_group_id = ''
|
|
||||||
}
|
|
||||||
if (argPage) {
|
|
||||||
this.setState({ page: argPage })
|
|
||||||
}
|
|
||||||
let page = argPage || this.state.page
|
|
||||||
let { sortedInfo } = this.state
|
|
||||||
let order = 1;
|
|
||||||
if (sortedInfo.columnKey == 'student_id') {
|
|
||||||
order = 1;
|
|
||||||
} else if (sortedInfo.columnKey == 'course_group_name') {
|
|
||||||
order = 2;
|
|
||||||
}
|
|
||||||
let sort = 'desc';
|
|
||||||
if (sortedInfo.order == 'ascend') {
|
|
||||||
sort = 'asc'
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = `/courses/${id}/students.json?order=${order}&sort=${sort}&page=${page}&limit=20&course_group_id=${course_group_id}`;
|
|
||||||
if (!!searchValue) {
|
|
||||||
url += '&search=' + searchValue;
|
|
||||||
}
|
|
||||||
axios.get(encodeURI(url)).then((result) => {
|
|
||||||
if (result.data.students) {
|
|
||||||
this.setState({
|
|
||||||
students: result.data.students,
|
|
||||||
total_count: result.data.students_count,
|
|
||||||
course_group_name: result.data.course_group_name,
|
|
||||||
invite_code: result.data.invite_code,
|
|
||||||
isSpin: false
|
|
||||||
}, () => {
|
|
||||||
if (course_group_id) {
|
|
||||||
if (!this.clipboard) {
|
|
||||||
const clipboard = new ClipboardJS('.copybtn');
|
|
||||||
clipboard.on('success', (e) => {
|
|
||||||
this.props.showNotification('复制成功')
|
|
||||||
});
|
|
||||||
this.clipboard = clipboard
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
this.setState({
|
|
||||||
isSpin: false
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onInputSearchChange = (e) => {
|
|
||||||
this.setState({
|
|
||||||
searchValue: e.target.value
|
|
||||||
})
|
|
||||||
|
|
||||||
// if (this.timeoutHandler) {
|
|
||||||
// clearTimeout(this.timeoutHandler)
|
|
||||||
// }
|
|
||||||
// this.timeoutHandler = setTimeout(() => {
|
|
||||||
// this.fetchAll(1)
|
|
||||||
// }, 1200)
|
|
||||||
}
|
|
||||||
onSortTypeChange = (order) => {
|
|
||||||
const { page, searchValue } = this.state;
|
|
||||||
this.setState({ order: order }, () => {
|
|
||||||
this.fetchAll(page, searchValue)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onPageChange = (page) => {
|
|
||||||
const { searchValue } = this.state;
|
|
||||||
this.fetchAll(page, searchValue)
|
|
||||||
this.setState({ checkAllValue: false })
|
|
||||||
}
|
|
||||||
|
|
||||||
onPressEnter = (e) => {
|
|
||||||
this.setState({
|
|
||||||
page: 1,
|
|
||||||
searchValue: e
|
|
||||||
})
|
|
||||||
this.fetchAll(1, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
onCheckBoxChange = (checkedValues) => {
|
|
||||||
this.setState({
|
|
||||||
checkBoxValues: checkedValues,
|
|
||||||
checkAllValue: checkedValues.length == this.state.students.length
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 多选
|
|
||||||
moveToGroup = (group) => {
|
|
||||||
const len = this.state.checkBoxValues.length
|
|
||||||
if (len == 0) {
|
|
||||||
this.props.showNotification('请从列表先选择要移动的学生')
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let id = this.props.match.params.coursesId
|
|
||||||
let { order, searchValue, page } = this.state
|
|
||||||
let url = `/courses/${id}/transfer_to_course_group.json`;
|
|
||||||
axios.post((url), {
|
|
||||||
students: this.state.checkBoxValues.map(item => { return { course_member_id: item } }),
|
|
||||||
course_group_id: group.id
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.data.status == 0) {
|
|
||||||
this.props.showNotification('移动成功')
|
|
||||||
this.setState({ checkBoxValues: [] })
|
|
||||||
this.fetchAll(page, searchValue);
|
|
||||||
this.props.updataleftNavfun()
|
|
||||||
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onCheckAll = (e) => {
|
|
||||||
this.setState({
|
|
||||||
checkAllValue: e.target.checked
|
|
||||||
})
|
|
||||||
const values = this.state.students.map(item => {
|
|
||||||
return item.course_member_id
|
|
||||||
})
|
|
||||||
if (e.target.checked) {
|
|
||||||
const concated = this.state.checkBoxValues.concat(values);
|
|
||||||
const sortedUniqed = _.uniq(concated)
|
|
||||||
this.setState({
|
|
||||||
checkBoxValues: sortedUniqed
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
checkBoxValues: _.difference(this.state.checkBoxValues, values)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 多选
|
|
||||||
onDelete = (record) => {
|
|
||||||
if (!record) {
|
|
||||||
const len = this.state.checkBoxValues.length
|
|
||||||
if (len == 0) {
|
|
||||||
this.props.showNotification('请先从列表选择要删除的学生')
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const { page, searchValue } = this.state;
|
|
||||||
|
|
||||||
this.props.confirm({
|
|
||||||
// content: `确认要删除所选的${len}个学生吗?`,
|
|
||||||
content: `是否确认删除?`,
|
|
||||||
onOk: () => {
|
|
||||||
let id = this.props.match.params.coursesId
|
|
||||||
let url = `/courses/${id}/delete_from_course.json`;
|
|
||||||
axios.post((url), {
|
|
||||||
students: [{ course_member_id: record.course_member_id }] // this.state.checkBoxValues.map(item => {return {course_member_id: item} }),
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.data.status == 0) {
|
|
||||||
this.props.showNotification('删除成功')
|
|
||||||
this.props.updataleftNavfun()
|
|
||||||
this.fetchAll(page, searchValue);
|
|
||||||
this.setState({ checkBoxValues: [] })
|
|
||||||
trigger('updatabanner')
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
addDir = () => {
|
|
||||||
trigger('groupAdd', this.props.coursesids)
|
|
||||||
}
|
|
||||||
doAddToDir = async () => {
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
const url = `/courses/${courseId}/join_course_group.json`
|
|
||||||
const course_group_id = this.props.match.params.course_group_id
|
|
||||||
|
|
||||||
const response = await axios.post(url, {
|
|
||||||
course_group_id
|
|
||||||
})
|
|
||||||
const { page, searchValue } = this.state;
|
|
||||||
|
|
||||||
if (response && response.data.status == 0) {
|
|
||||||
this.props.showNotification(`已加入分班:${this.state.course_group_name}`)
|
|
||||||
this.props.updataleftNavfun()
|
|
||||||
this.fetchAll(page, searchValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addToDir = (record) => {
|
|
||||||
this.props.confirm({
|
|
||||||
|
|
||||||
content: `是否确认加入分班: ${this.state.course_group_name}?`,
|
|
||||||
|
|
||||||
okText: '确认',
|
|
||||||
cancelText: '取消',
|
|
||||||
|
|
||||||
onOk: () => {
|
|
||||||
this.doAddToDir()
|
|
||||||
},
|
|
||||||
onCancel() {
|
|
||||||
console.log('Cancel');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
renameDir = () => {
|
|
||||||
const course_group_id = this.props.match.params.course_group_id
|
|
||||||
trigger('groupRename', { id: parseInt(course_group_id), name: this.state.course_group_name })
|
|
||||||
}
|
|
||||||
deleteDir = () => {
|
|
||||||
this.props.confirm({
|
|
||||||
content: <div>
|
|
||||||
<div>该分班的学生将被移动到“未分班”</div>
|
|
||||||
<div>是否确认删除?</div>
|
|
||||||
</div>,
|
|
||||||
onOk: () => {
|
|
||||||
const course_group_id = this.props.match.params.course_group_id
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
|
|
||||||
const url = `/course_groups/${course_group_id}.json`
|
|
||||||
axios.delete(url)
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.status == 0) {
|
|
||||||
this.props.showNotification('删除成功')
|
|
||||||
this.props.history.push(`/classrooms/${courseId}/course_groups`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
jsCopy = () => {
|
|
||||||
var e = document.getElementById("copy_invite_code");
|
|
||||||
e.select();
|
|
||||||
document.execCommand("Copy");
|
|
||||||
this.props.showNotification('复制成功')
|
|
||||||
}
|
|
||||||
|
|
||||||
onTableChange = (pagination, filters, sorter) => {
|
|
||||||
const { page, searchValue } = this.state;
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
sortedInfo: sorter,
|
|
||||||
}, () => {
|
|
||||||
this.fetchAll(page, searchValue);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const isAdmin = this.props.isAdmin()
|
|
||||||
const isStudent = this.props.isStudent()
|
|
||||||
const isSuperAdmin = this.props.isSuperAdmin()
|
|
||||||
const isCourseEnd = this.props.isCourseEnd()
|
|
||||||
let {
|
|
||||||
page,
|
|
||||||
|
|
||||||
order,
|
|
||||||
StudentList_value,
|
|
||||||
stu_new_flag,
|
|
||||||
modalsType,
|
|
||||||
modalsTopval,
|
|
||||||
modalsBottomval,
|
|
||||||
n_And_e,
|
|
||||||
|
|
||||||
students,
|
|
||||||
searchValue,
|
|
||||||
total_count,
|
|
||||||
course_groups,
|
|
||||||
checkBoxValues,
|
|
||||||
checkAllValue
|
|
||||||
} = this.state;
|
|
||||||
let currentOrderName = '学生学号排序'
|
|
||||||
if (order == ORDER_BY_GROUP) {
|
|
||||||
currentOrderName = '分班名称排序'
|
|
||||||
}
|
|
||||||
const { coursesids } = this.props
|
|
||||||
const course_group_id = this.props.match.params.course_group_id
|
|
||||||
const isParent = !course_group_id || course_group_id == coursesids
|
|
||||||
const { course_group_name, invite_code } = this.state;
|
|
||||||
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
let exportUrl = `/courses/${courseId}/export_member_scores_excel.xlsx?`; //总成绩
|
|
||||||
let exportUrltwo = `/courses/${courseId}/export_couser_info.xlsx?`; //课堂信息
|
|
||||||
let exportUrlthree = `/courses/${courseId}/export_member_act_score.xlsx?`; //活跃度
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const params = {}
|
|
||||||
if (course_group_id) {
|
|
||||||
params.group_id = course_group_id
|
|
||||||
}
|
|
||||||
if (searchValue) {
|
|
||||||
searchValue = searchValue.trim()
|
|
||||||
if (searchValue) {
|
|
||||||
params.search = searchValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let paramsString = ''
|
|
||||||
for (let key in params) {
|
|
||||||
paramsString += `&${key}=${params[key]}&`
|
|
||||||
}
|
|
||||||
exportUrl += paramsString;
|
|
||||||
exportUrltwo += paramsString;
|
|
||||||
exportUrlthree += paramsString;
|
|
||||||
|
|
||||||
|
|
||||||
// console.log(paramsString);
|
|
||||||
// console.log(checkBoxValues);
|
|
||||||
// console.log(searchValue);
|
|
||||||
let pageType = TYPE_STUDENTS
|
|
||||||
if (this.props.match.path.endsWith('students')) {
|
|
||||||
|
|
||||||
} else if (course_group_id) {
|
|
||||||
pageType = TYPE_COURSE_GOURP_CHILD
|
|
||||||
} else {
|
|
||||||
pageType = TYPE_COURSE_GOURP_PARENT
|
|
||||||
}
|
|
||||||
// 本页面有2个状态,学生列表、具体分班
|
|
||||||
const isStudentPage = pageType == TYPE_STUDENTS
|
|
||||||
this.isStudentPage = isStudentPage
|
|
||||||
const isGroupChildPage = pageType == TYPE_COURSE_GOURP_CHILD
|
|
||||||
let studentlist = buildColumns(this, isParent);
|
|
||||||
if (this.props.isexcellent === true) {
|
|
||||||
studentlist.some((item, key) => {
|
|
||||||
if (item.title === "手机号") {
|
|
||||||
studentlist.splice(key, 1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.isexcellent === true) {
|
|
||||||
studentlist.some((item, key) => {
|
|
||||||
if (item.title === "邮箱") {
|
|
||||||
studentlist.splice(key, 1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment >
|
|
||||||
<DownloadMessageysl
|
|
||||||
{...this.props}
|
|
||||||
value={this.state.DownloadMessageval}
|
|
||||||
modalCancel={this.Downloadcal}
|
|
||||||
modalsType={this.state.DownloadType}
|
|
||||||
/>
|
|
||||||
<Titlesearchsection
|
|
||||||
title={isParent ? (pageType == TYPE_STUDENTS ? "全部学生" : "学生列表") :
|
|
||||||
<React.Fragment>
|
|
||||||
{
|
|
||||||
course_group_name ?
|
|
||||||
<span>
|
|
||||||
<Tooltip title="返回至分班列表">
|
|
||||||
<i className="icon-zuojiantou iconfont font-14" onClick={() => { this.props.history.push(`/classrooms/${courseId}/course_groups`) }}
|
|
||||||
style={{ color: '#212121', verticalAlign: 'initial', marginRight: '14px' }}
|
|
||||||
></i>
|
|
||||||
</Tooltip>{course_group_name}
|
|
||||||
</span>
|
|
||||||
:
|
|
||||||
<ul className="course_publicNav">
|
|
||||||
<li onClick={() => { this.props.history.push(`/classrooms/${courseId}/course_groups`) }}>分班列表</li>
|
|
||||||
<li className="active">未分班</li>
|
|
||||||
</ul>
|
|
||||||
}
|
|
||||||
|
|
||||||
{isAdmin && invite_code && <React.Fragment>
|
|
||||||
<span className="color-grey-9 font-16 ml10">邀请码:</span>
|
|
||||||
<span className="color-orange font-16">
|
|
||||||
{invite_code}
|
|
||||||
</span>
|
|
||||||
<Tooltip title={<div>
|
|
||||||
<div>成员可以通过邀请码主动加入分班</div>
|
|
||||||
<div>点击立刻复制邀请码</div>
|
|
||||||
</div>}>
|
|
||||||
<span>
|
|
||||||
<i className="iconfont icon-fuzhi font-14 ml10 copybtn" style={{ color: '#FF6800', cursor: 'pointer', verticalAlign: 'baseline' }} data-clipboard-text={invite_code} ></i>
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
searchValue={searchValue}
|
|
||||||
onInputSearchChange={this.onInputSearchChange}
|
|
||||||
allowClearonChange={this.onInputSearchChange}
|
|
||||||
showSearchInput={total_count >= 10}
|
|
||||||
onPressEnter={this.onPressEnter}
|
|
||||||
searchPlaceholder={'请输入姓名、学号进行搜索'}
|
|
||||||
firstRowRight={
|
|
||||||
<React.Fragment>
|
|
||||||
{
|
|
||||||
!isStudentPage && isAdmin && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="mr30" onClick={() => this.deleteDir()}>删除分班</WordsBtn>}
|
|
||||||
{
|
|
||||||
!isStudentPage && isAdmin && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="mr30" onClick={() => this.renameDir()}>分班重命名</WordsBtn>}
|
|
||||||
{
|
|
||||||
!isStudentPage && !isCourseEnd && isAdmin && <WordsBtn style="blue" className="mr30" onClick={() => this.addDir()}>新建分班</WordsBtn>}
|
|
||||||
|
|
||||||
{
|
|
||||||
!isStudentPage && isStudent && !isParent && course_group_id != 0 && <WordsBtn style="blue" className="" onClick={() => this.addToDir()}>加入分班</WordsBtn>}
|
|
||||||
<style>{`
|
|
||||||
.drop_down_menu li a {
|
|
||||||
padding: 0px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.drop_down_menu {
|
|
||||||
/*width: 93px;*/
|
|
||||||
}
|
|
||||||
.drop_down_menu li {
|
|
||||||
width:100%;
|
|
||||||
box-sizing:boder-box;
|
|
||||||
float:unset;
|
|
||||||
line-height:30px!important;
|
|
||||||
flex: 0 0 30px;
|
|
||||||
}
|
|
||||||
.drop_down_menu, .drop_down_normal {
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
}
|
|
||||||
.drop_down_menu .drop_down_btn{
|
|
||||||
border-top:none;
|
|
||||||
}
|
|
||||||
.dividerStyle.ant-divider-horizontal{
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
{isAdmin &&
|
|
||||||
<li className="li_line drop_down fr color-blue font-16">
|
|
||||||
导出<i className="iconfont icon-xiajiantou font-12 ml2"></i>
|
|
||||||
<ul className="drop_down_menu" style={{ "right": "-20px", "left": "unset", "height": "auto" }}>
|
|
||||||
|
|
||||||
<li><a
|
|
||||||
onClick={(i) => this.confirmysl(exportUrltwo)}>课堂信息</a>
|
|
||||||
</li>
|
|
||||||
<li><a
|
|
||||||
onClick={(i) => this.confirmysl(exportUrlthree)}>活跃度</a>
|
|
||||||
</li>
|
|
||||||
<li><a
|
|
||||||
onClick={(i) => this.confirmysl(exportUrl)}>总成绩</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
{/*<WordsBtn style="blue" className="" onClick={(url)=>this.confirmysl(exportUrl)} >导出成绩</WordsBtn>*/}
|
|
||||||
{/* */}
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
secondRowLeft={
|
|
||||||
total_count ? <ColorCountText count={total_count} name="个学生"></ColorCountText> : ''
|
|
||||||
}
|
|
||||||
></Titlesearchsection>
|
|
||||||
{
|
|
||||||
total_count > 0 || this.state.isSpin == true ?
|
|
||||||
<div className="mt20 edu-back-white padding20">
|
|
||||||
<div className="clearfix stu_head" style={{ paddingLeft: '5px' }}>
|
|
||||||
{isAdmin && !isStudentPage && <Checkbox className="fl" onChange={this.onCheckAll} checked={checkAllValue} >已选 {checkBoxValues.length} 个</Checkbox>}
|
|
||||||
<div className="studentList_operation_ul">
|
|
||||||
{/* {isAdmin && <li className="li_line"><a className="color-grey-9" onClick={this.onDelete}>删除</a></li>} */}
|
|
||||||
{isAdmin && !isStudentPage && <li className="drop_down">
|
|
||||||
移动到<i className="iconfont icon-xiajiantou font-12 ml2"></i>
|
|
||||||
<ul className="drop_down_menu" style={{ "right": "0px", "left": "unset", width: '200px', maxHeight: '324px', overflowY: 'auto' }}>
|
|
||||||
{
|
|
||||||
course_groups && course_groups.length > 9 ?
|
|
||||||
(<p className="drop_down_search">
|
|
||||||
<Input placeholder="搜索" value={this.state.groupSearchValue} onChange={(e) => { this.setState({ groupSearchValue: e.target.value }) }} />
|
|
||||||
</p>) :
|
|
||||||
''
|
|
||||||
}
|
|
||||||
{
|
|
||||||
course_group_id != 0 && course_groups && course_groups.length > 0 &&
|
|
||||||
<li key={0} onClick={() => this.moveToGroup({ id: 0 })}>未分班</li>
|
|
||||||
}
|
|
||||||
{course_groups.filter((item) => {
|
|
||||||
return item.id != course_group_id && (!this.state.groupSearchValue || item.name.indexOf(this.state.groupSearchValue) != -1)
|
|
||||||
}).map(item => {
|
|
||||||
return (
|
|
||||||
<li key={item.id} onClick={() => this.moveToGroup(item)} title={item.name}>{item.name}</li>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
{course_groups && course_groups.length > 0 && <Divider className="dividerStyle"></Divider>}
|
|
||||||
{isAdmin && !isCourseEnd &&
|
|
||||||
|
|
||||||
<p className="drop_down_btn">
|
|
||||||
<a className="color-grey-6"
|
|
||||||
onClick={() => this.addDir()}
|
|
||||||
>新建分班...</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</li>}
|
|
||||||
|
|
||||||
{/* <li className="drop_down">
|
|
||||||
{currentOrderName}
|
|
||||||
{ course_groups && !!course_groups.length &&
|
|
||||||
<React.Fragment>
|
|
||||||
<i className="iconfont icon-xiajiantou font-12 ml2"></i>
|
|
||||||
<ul className="drop_down_normal" style={{width: '124px'}}>
|
|
||||||
<li onClick={() => this.onSortTypeChange(ORDER_BY_NUM)} >学生学号排序</li>
|
|
||||||
<li onClick={() => this.onSortTypeChange(ORDER_BY_GROUP)} >分班名称排序</li>
|
|
||||||
</ul>
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
</li> */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Spin size="large" spinning={this.state.isSpin}>
|
|
||||||
<div className="clearfix stu_table">
|
|
||||||
{students && !!students.length && <Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}>
|
|
||||||
<Table columns={studentlist} dataSource={students} onChange={this.onTableChange} pagination={false}></Table>
|
|
||||||
</Checkbox.Group>}
|
|
||||||
</div>
|
|
||||||
</Spin>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<NoneData></NoneData>
|
|
||||||
}
|
|
||||||
{/* showQuickJumper */}
|
|
||||||
{total_count > 20 && <div className="clearfix mt30 mb50 edu-txt-center">
|
|
||||||
<Pagination showQuickJumper defaultCurrent={page} current={page} pageSize={20} total={total_count} onChange={this.onPageChange} />
|
|
||||||
</div>}
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default studentsList;
|
|
|
@ -1,840 +0,0 @@
|
||||||
import React, { Component } from "react";
|
|
||||||
import { Input, Checkbox, Table, Divider, Tooltip, Spin, Menu, Popconfirm } from "antd";
|
|
||||||
|
|
||||||
import CourseLayoutcomponent from '../common/CourseLayoutComponent'
|
|
||||||
import NoneData from "../coursesPublic/NoneData"
|
|
||||||
|
|
||||||
import Titlesearchsection from '../common/titleSearch/TitleSearchSection'
|
|
||||||
import ColorCountText from '../common/titleSearch/ColorCountText'
|
|
||||||
import update from 'immutability-helper'
|
|
||||||
|
|
||||||
import { WordsBtn, ConditionToolTip, on, off, trigger, sortDirections } from 'educoder'
|
|
||||||
|
|
||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
import _ from 'lodash'
|
|
||||||
// import { RouteHOC } from './common.js'
|
|
||||||
|
|
||||||
import '../css/members.css'
|
|
||||||
import { from } from "array-flatten";
|
|
||||||
// import AddTeacherModal from './modal/AddTeacherModal'
|
|
||||||
// import AddStudentModal from './modal/AddStudentModal'
|
|
||||||
import AddGraduationGroupModal from './modal/AddGraduationGroupModal'
|
|
||||||
import AddAdminModal from './modal/AddAdminModal'
|
|
||||||
import CourseGroupChooserModal from './modal/CourseGroupChooserModal'
|
|
||||||
import { ROLE_TEACHER_NUM, ROLE_ASSISTANT_NUM } from './common'
|
|
||||||
import CourseGroupChooser from './CourseGroupChooser'
|
|
||||||
import ChangeRolePop from './ChangeRolePop'
|
|
||||||
|
|
||||||
const Search = Input.Search;
|
|
||||||
const ROLE_ADMIN = "管理员"
|
|
||||||
const ROLE_TEACHER = "教师"
|
|
||||||
const ROLE_TEACHER_ASSISTANT = "助教"
|
|
||||||
const pageSize = 20;
|
|
||||||
|
|
||||||
function buildColumns(that) {
|
|
||||||
let sortedInfo = that.state.sortedInfo || {}
|
|
||||||
const isAdmin = that.props.isAdmin()
|
|
||||||
const isAdminOrCreator = that.props.isAdminOrCreator();
|
|
||||||
const isAdminOrTeacher = that.props.isAdminOrTeacher()
|
|
||||||
const { course_groups, filterKey } = that.state
|
|
||||||
const showSorter = filterKey == '1'
|
|
||||||
const courseId = that.props.match.params.coursesId
|
|
||||||
|
|
||||||
const columns = [{
|
|
||||||
title: '序号',
|
|
||||||
dataIndex: 'name',
|
|
||||||
key: 'index',
|
|
||||||
width: 78,
|
|
||||||
render: (content, item, index) => {
|
|
||||||
return index + 1
|
|
||||||
// return item.isApply == true ? '' : <a href="javascript:;">{(that.state.page - 1) * 20 + index + 1
|
|
||||||
// - (that.state.application_list ? that.state.application_list.length : 0)} </a>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ,{
|
|
||||||
// title: '用户ID',
|
|
||||||
// width: 120,
|
|
||||||
// dataIndex: 'login',
|
|
||||||
// key: 'login',
|
|
||||||
// render: (login, record) => {
|
|
||||||
// return <span className="overflowHidden1" style={{ maxWidth: '110px'}} title={`${login.length > 8 ? login : ''}`}>{login}</span>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
, {
|
|
||||||
title: '姓名',
|
|
||||||
dataIndex: 'name',
|
|
||||||
width: 120,
|
|
||||||
key: 'name',
|
|
||||||
sorter: showSorter,
|
|
||||||
sortDirections: sortDirections,
|
|
||||||
sortOrder: sortedInfo.columnKey === 'name' && sortedInfo.order,
|
|
||||||
render: (name, record) => {
|
|
||||||
return <a href={`/users/${record.login}`} target="_blank" className="overflowHidden1" style={{ maxWidth: '110px' }}
|
|
||||||
title={`${name.length > 4 ? name : ''}`}>{name}</a>
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
title: '角色',
|
|
||||||
dataIndex: 'role',
|
|
||||||
key: 'role',
|
|
||||||
sorter: showSorter,
|
|
||||||
width: 86,
|
|
||||||
// 'ascend' | 'descend'
|
|
||||||
defaultSortOrder: 'ascend',
|
|
||||||
sortDirections: sortDirections,
|
|
||||||
sortOrder: sortedInfo.columnKey === 'role' && sortedInfo.order,
|
|
||||||
|
|
||||||
}]
|
|
||||||
that.state.course_groups && that.state.course_groups.length && showSorter && columns.push({
|
|
||||||
title: <Tooltip title="仅能批阅指定分班的作品">管理权限</Tooltip>,
|
|
||||||
width: 260,
|
|
||||||
key: 'course_groups',
|
|
||||||
dataIndex: 'course_groups',
|
|
||||||
// onClick={() => that.joinCourseGroup(item.id)}
|
|
||||||
// "right":"0px",
|
|
||||||
render: (arg_course_groups, item, index) => {
|
|
||||||
if (!arg_course_groups) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
// ((!course_groups || course_groups.length == 0) && <p>暂未有分班信息,不能操作</p>)
|
|
||||||
const noGroups = (!course_groups || course_groups.length == 0);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ConditionToolTip title={`暂未有分班信息,不能操作`} condition={noGroups}>
|
|
||||||
<span className="drop_down" style={{ color: '#29BD8B', display: 'inline-block' }}>
|
|
||||||
{(arg_course_groups.length === 0 || arg_course_groups.length === course_groups.length) ? '全部分班' : arg_course_groups.map(item => item.name).join(', ')}
|
|
||||||
{isAdmin &&
|
|
||||||
<React.Fragment>
|
|
||||||
<i className="iconfont icon-xiajiantou font-12 ml2"></i>
|
|
||||||
{!noGroups && <CourseGroupChooser
|
|
||||||
{...{
|
|
||||||
course_groups, isAdminOrCreator, item, index, arg_course_groups,
|
|
||||||
checkAllValue: arg_course_groups.length === course_groups.length,
|
|
||||||
joinCourseGroup: that.joinCourseGroup,
|
|
||||||
onCheckAllChange: that.onCheckAllChange
|
|
||||||
}}
|
|
||||||
></CourseGroupChooser>}
|
|
||||||
</React.Fragment>}
|
|
||||||
</span>
|
|
||||||
</ConditionToolTip>)
|
|
||||||
}
|
|
||||||
,
|
|
||||||
});
|
|
||||||
const hasGraduationModule = that.hasGraduationModule()
|
|
||||||
if (hasGraduationModule && showSorter) {
|
|
||||||
columns.push({
|
|
||||||
title: '所在答辩组',
|
|
||||||
// width: 90,
|
|
||||||
sorter: showSorter,
|
|
||||||
sortDirections: sortDirections,
|
|
||||||
key: 'graduation_group',
|
|
||||||
dataIndex: 'graduation_group',
|
|
||||||
sortOrder: sortedInfo.columnKey === 'graduation_group' && sortedInfo.order,
|
|
||||||
|
|
||||||
render: text => (
|
|
||||||
<span className="overflowHidden1" style={{ maxWidth: '160px' }}
|
|
||||||
title={`${text && text.length > 10 ? text : ''}`}
|
|
||||||
>
|
|
||||||
{text}
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (isAdminOrTeacher) {
|
|
||||||
columns.push({
|
|
||||||
title: '操作',
|
|
||||||
key: 'action',
|
|
||||||
width: 150,
|
|
||||||
align: 'center',
|
|
||||||
render: (text, record) => {
|
|
||||||
const isAdmin = record.role == ROLE_ADMIN
|
|
||||||
const isTeacher = record.role == ROLE_TEACHER
|
|
||||||
const isAssitant = record.role == ROLE_TEACHER_ASSISTANT
|
|
||||||
if (record.application_id) {
|
|
||||||
return (
|
|
||||||
<span>
|
|
||||||
<WordsBtn onClick={() => that.onRefuse(record)} style={'grey'}>拒绝</WordsBtn>
|
|
||||||
<Divider type="vertical" />
|
|
||||||
<a onClick={() => that.onAgree(record)} style={{ color: '#4CACFF' }}>同意</a>
|
|
||||||
</span>)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<WordsBtn style2={{ marginRight: '12px' }} onClick={() => that.onDelete(record)} style={'grey'}>删除</WordsBtn>
|
|
||||||
<ChangeRolePop
|
|
||||||
courseId={courseId}
|
|
||||||
record={record}
|
|
||||||
member_roles={record.member_roles}
|
|
||||||
onChangeRoleSuccess={that.onChangeRoleSuccess}
|
|
||||||
showNotification={that.props.showNotification}
|
|
||||||
getUserId={that.props.isUserid}
|
|
||||||
fetchUser={that.props.fetchUser}
|
|
||||||
|
|
||||||
></ChangeRolePop>
|
|
||||||
{/* <Popconfirm
|
|
||||||
placement="bottom"
|
|
||||||
icon={null}
|
|
||||||
title={
|
|
||||||
<React.Fragment>
|
|
||||||
<Checkbox disable={isAdmin}>管理员</Checkbox>
|
|
||||||
<Checkbox disable={isAdmin}>助教</Checkbox>
|
|
||||||
<Checkbox >学生</Checkbox>
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<WordsBtn style={'blue'}>修改角色</WordsBtn>
|
|
||||||
</Popconfirm> */}
|
|
||||||
</React.Fragment>
|
|
||||||
|
|
||||||
|
|
||||||
// <span>
|
|
||||||
// {record.role != ROLE_ADMIN && <WordsBtn onClick={() => that.onDelete(record)} style={'grey'}>删除</WordsBtn>}
|
|
||||||
// {(record.role == ROLE_TEACHER || record.role == ROLE_TEACHER_ASSISTANT || isAdminOrCreator) && record.role != ROLE_ADMIN
|
|
||||||
// && <Divider type="vertical" />}
|
|
||||||
// { record.role == ROLE_TEACHER ? <a style={{color: '#4CACFF'}} onClick={() => that.changeToAssistant(record)}>变更为助教</a> : '' }
|
|
||||||
// { record.role == ROLE_TEACHER_ASSISTANT ? <a style={{color: '#4CACFF'}} onClick={() => that.changeToTeacher(record)}>变更为教师</a> : '' }
|
|
||||||
// { record.role == ROLE_ADMIN && isAdminOrCreator ? <a style={{color: '#4CACFF', marginLeft: '44px'}} onClick={() => that.showChangeAdminModal(record)}>更换管理员</a> : '' }
|
|
||||||
|
|
||||||
// </span>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 待审批不需要
|
|
||||||
if (filterKey == '1' && isAdminOrTeacher && hasGraduationModule) {
|
|
||||||
columns.unshift({
|
|
||||||
title: '',
|
|
||||||
dataIndex: 'course_member_id',
|
|
||||||
key: 'course_member_id',
|
|
||||||
render: (content, item, key) => {
|
|
||||||
return content ? <Checkbox value={content} key={content}></Checkbox> : ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return columns
|
|
||||||
}
|
|
||||||
|
|
||||||
const ORDER_BY_NAME = 1;
|
|
||||||
const ORDER_BY_DATE = 2;
|
|
||||||
const ORDER_BY_GRADUATION_GROUP = 3;
|
|
||||||
|
|
||||||
class studentsList extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
headIndex: "1",
|
|
||||||
page: 1,
|
|
||||||
sortedInfo: { columnKey: 'role', order: 'ascend' },
|
|
||||||
totalPage: undefined,
|
|
||||||
searchValue: "",
|
|
||||||
order: ORDER_BY_DATE,
|
|
||||||
search: "",
|
|
||||||
groupList: undefined,
|
|
||||||
teachers: [],
|
|
||||||
checkBoxValues: [],
|
|
||||||
isSpin: false,
|
|
||||||
application_list: [],
|
|
||||||
course_groups: [],
|
|
||||||
checkAllArray: [],
|
|
||||||
filterKey: 1, // 1 已审批 2 待审批
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onCheckAllChange = (e, item, index) => {
|
|
||||||
const that = this;
|
|
||||||
const checkAllArray = that.state.checkAllArray.slice(0)
|
|
||||||
checkAllArray[index] = !checkAllArray[index]
|
|
||||||
that.setState({ checkAllArray })
|
|
||||||
if (checkAllArray[index]) {
|
|
||||||
that.joinCourseGroup(that.state.course_groups.map((item) => item.id), item, index)
|
|
||||||
} else {
|
|
||||||
that.joinCourseGroup([], item, index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inputSearch = (e) => {
|
|
||||||
this.setState({
|
|
||||||
searchValue: e.target.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// approval 2 - 拒绝
|
|
||||||
onAgree = (record, approval = 1) => {
|
|
||||||
const isAdminOrCreator = this.props.isAdminOrCreator()
|
|
||||||
const { course_groups, filterKey, searchValue } = this.state
|
|
||||||
if (approval == 1 && isAdminOrCreator && course_groups && course_groups.length) {
|
|
||||||
this.setState({ clickRecord: record }, () => {
|
|
||||||
this.setGroupChooserModalVisible(true)
|
|
||||||
})
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
|
|
||||||
let url = `/courses/${courseId}/teacher_application_review.json`
|
|
||||||
|
|
||||||
this.props.confirm({
|
|
||||||
content: `是否确认${approval == 1 ? '同意' : '拒绝'}TA的加入?`,
|
|
||||||
onOk: () => {
|
|
||||||
axios.post(url, {
|
|
||||||
user_id: record.user_id,
|
|
||||||
application_id: record.application_id,
|
|
||||||
approval: approval
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.status == 0) {
|
|
||||||
this.props.showNotification(`已${approval == 1 ? '同意' : '拒绝'}`)
|
|
||||||
this.fetchAll(1, filterKey, searchValue)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
onRefuse = (record) => {
|
|
||||||
this.onAgree(record, 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.setState({
|
|
||||||
isSpin: true
|
|
||||||
})
|
|
||||||
let newmenuid = this.props.location.search.replace('?tab=', '');
|
|
||||||
if (newmenuid === undefined || newmenuid === "" || newmenuid === "1" || newmenuid === 1) {
|
|
||||||
this.setState({
|
|
||||||
filterKey: '1'
|
|
||||||
})
|
|
||||||
this.fetchAll(1, '1');
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
filterKey: '2'
|
|
||||||
})
|
|
||||||
this.fetchAll(1, '2');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const isAdminOrTeacher = this.props.isAdminOrTeacher()
|
|
||||||
const isAdmin = this.props.isAdmin()
|
|
||||||
|
|
||||||
isAdminOrTeacher && this.getGroupList();
|
|
||||||
this.getCourseGroups();
|
|
||||||
|
|
||||||
on('addTeacherSuccess', this.addTeacherSuccessListener)
|
|
||||||
isAdmin && on('updateNavSuccess', this.updateNavSuccess)
|
|
||||||
|
|
||||||
}
|
|
||||||
componentWillUnmount() {
|
|
||||||
off('addTeacherSuccess', this.addTeacherSuccessListener)
|
|
||||||
const isAdmin = this.props.isAdmin()
|
|
||||||
isAdmin && off('updateNavSuccess', this.updateNavSuccess)
|
|
||||||
}
|
|
||||||
updateNavSuccess = () => {
|
|
||||||
this.getCourseGroups()
|
|
||||||
}
|
|
||||||
addTeacherSuccessListener = (e, data) => {
|
|
||||||
const { searchValue } = this.state;
|
|
||||||
// const params = JSON.parse(data)
|
|
||||||
// const coursesId = this.props.match.params.coursesId
|
|
||||||
if (window.location.pathname.endsWith('teachers')) {
|
|
||||||
this.fetchAll(1, this.state.filterKey, searchValue)
|
|
||||||
} else {
|
|
||||||
// this.props.history.push(`/courses/${coursesId}/teachers`)
|
|
||||||
}
|
|
||||||
// console.log('addTeacherSuccessListener', data)
|
|
||||||
}
|
|
||||||
getCourseGroups = () => {
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
|
|
||||||
let url = `/courses/${courseId}/all_course_groups.json`
|
|
||||||
|
|
||||||
axios.get(url, {
|
|
||||||
params: { all: true }
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.course_groups && response.data.course_groups.length) {
|
|
||||||
let course_groups_map = {}
|
|
||||||
response.data.course_groups.forEach(item => {
|
|
||||||
course_groups_map[item.id] = item.name
|
|
||||||
})
|
|
||||||
this.setState({
|
|
||||||
course_groups: response.data.course_groups,
|
|
||||||
course_groups_map
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
joinCourseGroup = (ids, item, index) => {
|
|
||||||
// console.log('join ', ids, item)
|
|
||||||
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
|
|
||||||
let url = `/courses/${courseId}/set_course_group.json`
|
|
||||||
|
|
||||||
axios.post(url, {
|
|
||||||
course_group_ids: ids,
|
|
||||||
user_id: item.user_id,
|
|
||||||
course_member_id: item.course_member_id
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.status == 0) {
|
|
||||||
this.props.showNotification('修改成功')
|
|
||||||
this.props.updatabanners()
|
|
||||||
const newArray = ids.map((item) => { return { id: item, name: this.state.course_groups_map[item] } });
|
|
||||||
this.setState(
|
|
||||||
(prevState) => ({
|
|
||||||
teachers: update(prevState.teachers, { [this.state.page == 1 ? index - this.state.application_list.length : index]: { course_groups: { $set: newArray } } })
|
|
||||||
}))
|
|
||||||
// this.fetchAll()
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
onChangeRoleSuccess = () => {
|
|
||||||
this.fetchAll(undefined, this.state.filterKey, this.state.searchValue)
|
|
||||||
}
|
|
||||||
fetchAll = async (argPage, filterKey, searchValue) => {
|
|
||||||
this.setState({
|
|
||||||
isSpin: true
|
|
||||||
})
|
|
||||||
let id = this.props.match.params.coursesId
|
|
||||||
if (argPage) {
|
|
||||||
this.setState({ page: argPage })
|
|
||||||
}
|
|
||||||
|
|
||||||
const sortedInfo = this.state.sortedInfo;
|
|
||||||
let page = argPage || this.state.page
|
|
||||||
|
|
||||||
let order = 1;
|
|
||||||
if (sortedInfo.columnKey == 'role') {
|
|
||||||
order = 1;
|
|
||||||
} else if (sortedInfo.columnKey == 'name') {
|
|
||||||
order = 2;
|
|
||||||
} else if (sortedInfo.columnKey == 'graduation_group') {
|
|
||||||
order = 3;
|
|
||||||
}
|
|
||||||
let sort = 'desc'
|
|
||||||
if (sortedInfo.order == 'ascend') {
|
|
||||||
sort = 'asc'
|
|
||||||
}
|
|
||||||
let url = `/courses/${id}/teachers.json?order=${order}&page=${page}&sort=${sort}`;
|
|
||||||
if (filterKey == '1') {
|
|
||||||
|
|
||||||
} else if (filterKey == '2') {
|
|
||||||
url = `/courses/${id}/apply_teachers.json?_a=1`
|
|
||||||
}
|
|
||||||
if (searchValue) {
|
|
||||||
url += '&search=' + searchValue;
|
|
||||||
}
|
|
||||||
const { updatabanners } = this.props;
|
|
||||||
updatabanners && updatabanners();
|
|
||||||
const result = await axios.get(encodeURI(url))
|
|
||||||
if (result.data.teacher_list) {
|
|
||||||
this.setState({
|
|
||||||
teachers: result.data.teacher_list,
|
|
||||||
total_count: result.data.teacher_list_size,
|
|
||||||
application_list: result.data.application_list || [],
|
|
||||||
is_admin: result.data.is_admin,
|
|
||||||
apply_size: result.data.apply_size,
|
|
||||||
isSpin: false
|
|
||||||
})
|
|
||||||
|
|
||||||
} else if (result.data.application_list) {
|
|
||||||
this.setState({
|
|
||||||
total_count: result.data.teacher_list_size,
|
|
||||||
application_list: result.data.application_list || [],
|
|
||||||
is_admin: result.data.is_admin,
|
|
||||||
apply_size: result.data.apply_size,
|
|
||||||
isSpin: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getGroupList() {
|
|
||||||
let id = this.props.match.params.coursesId
|
|
||||||
let url = '/courses/' + id + '/graduation_group_list.json';
|
|
||||||
axios.get((url)).then((result) => {
|
|
||||||
if (result.status == 200) {
|
|
||||||
this.setState({
|
|
||||||
groupList: result.data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onAddGraduationGroupOk = () => {
|
|
||||||
this.getGroupList()
|
|
||||||
}
|
|
||||||
|
|
||||||
// join_graduation_group
|
|
||||||
joinGraduationGroup = (graduation_group_id) => {
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
let { filterKey, searchValue } = this.state
|
|
||||||
let url = `/courses/${courseId}/join_graduation_group.json`;
|
|
||||||
axios.post(url, {
|
|
||||||
course_member_list: this.state.checkBoxValues.map(item => { return { course_member_id: item } }),
|
|
||||||
graduation_group_id: graduation_group_id
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.data.status == 0) {
|
|
||||||
this.props.showNotification('操作成功。')
|
|
||||||
this.fetchAll(undefined, filterKey, searchValue);
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onInputSearchChange = (e) => {
|
|
||||||
// let {filterKey}=this.state;
|
|
||||||
this.setState({
|
|
||||||
searchValue: e.target.value
|
|
||||||
})
|
|
||||||
|
|
||||||
// if (this.timeoutHandler) {
|
|
||||||
// clearTimeout(this.timeoutHandler)
|
|
||||||
// }
|
|
||||||
// this.timeoutHandler = setTimeout(() => {
|
|
||||||
// this.fetchAll(1,filterKey,e.target.value)
|
|
||||||
// }, 1200)
|
|
||||||
}
|
|
||||||
|
|
||||||
onPressEnter = (value) => {
|
|
||||||
this.setState({
|
|
||||||
searchValue: value
|
|
||||||
})
|
|
||||||
this.fetchAll(1, this.state.filterKey, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onCheckBoxChange = (checkedValues) => {
|
|
||||||
this.setState({
|
|
||||||
checkBoxValues: checkedValues,
|
|
||||||
checkAllValue: checkedValues.length == this.state.teachers.length
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onCheckAll = (e) => {
|
|
||||||
this.setState({
|
|
||||||
checkAllValue: e.target.checked
|
|
||||||
})
|
|
||||||
const values = this.state.teachers.map(item => {
|
|
||||||
return item.course_member_id
|
|
||||||
})
|
|
||||||
if (e.target.checked) {
|
|
||||||
const concated = this.state.checkBoxValues.concat(values);
|
|
||||||
const sortedUniqed = _.uniq(concated)
|
|
||||||
this.setState({
|
|
||||||
checkBoxValues: sortedUniqed
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
checkBoxValues: _.difference(this.state.checkBoxValues, values),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onSortTypeChange = (order) => {
|
|
||||||
const { page, searchValue } = this.state;
|
|
||||||
this.setState({ order: order }, () => {
|
|
||||||
this.fetchAll(page, undefined, searchValue);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
changeRole = (member, role) => {
|
|
||||||
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
let { filterKey } = this.state;
|
|
||||||
let url = `/courses/${courseId}/change_course_teacher.json`;
|
|
||||||
axios.post(url, {
|
|
||||||
course_member_id: member.course_member_id
|
|
||||||
// "user_list": [
|
|
||||||
// { "user_id": member.user_id }
|
|
||||||
// ],
|
|
||||||
// "graduation_group_id": member.graduation_group_id,
|
|
||||||
// "course_group_id": "820",
|
|
||||||
// "role": role
|
|
||||||
}).then((result) => {
|
|
||||||
if (result.data.status == 0) {
|
|
||||||
this.props.showNotification('操作成功。')
|
|
||||||
this.fetchAll(undefined, filterKey)
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
changeToAssistant = (member) => {
|
|
||||||
this.changeRole(member, ROLE_ASSISTANT_NUM)
|
|
||||||
}
|
|
||||||
changeToTeacher = (member) => {
|
|
||||||
this.changeRole(member, ROLE_TEACHER_NUM)
|
|
||||||
}
|
|
||||||
showChangeAdminModal = () => {
|
|
||||||
this.refs.addAdminModal.setVisible(true)
|
|
||||||
}
|
|
||||||
changeAdminSuccess = () => {
|
|
||||||
let { filterKey } = this.state;
|
|
||||||
this.fetchAll(undefined, filterKey)
|
|
||||||
}
|
|
||||||
onDelete = (member) => {
|
|
||||||
let { filterKey } = this.state;
|
|
||||||
this.props.confirm({
|
|
||||||
content: `确认要将“${member.name}”从教师列表中移除吗?`,
|
|
||||||
onOk: () => {
|
|
||||||
// const cid = this.props.match.params.coursesId
|
|
||||||
const courseId = this.props.match.params.coursesId
|
|
||||||
|
|
||||||
const url = `/courses/${courseId}/delete_course_teacher.json`
|
|
||||||
axios.post(url, {
|
|
||||||
course_member_id: member.course_member_id
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.data.status == 0) {
|
|
||||||
// {"status":1,"message":"删除成功"}
|
|
||||||
this.props.showNotification('删除成功')
|
|
||||||
trigger('updatabanner')
|
|
||||||
this.fetchAll(undefined, filterKey)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
addTeacher = () => {
|
|
||||||
this.refs.addTeacherModal.setVisible(true)
|
|
||||||
}
|
|
||||||
addStudent = () => {
|
|
||||||
this.refs.addStudentModal.setVisible(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
hasGraduationModule = () => {
|
|
||||||
const { course_modules } = this.props;
|
|
||||||
const result = course_modules && course_modules.filter(item => {
|
|
||||||
return item.type == 'graduation'
|
|
||||||
})
|
|
||||||
return result && result.length > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
onTableChange = (pagination, filters, sorter) => {
|
|
||||||
let { filterKey } = this.state;
|
|
||||||
console.log('Various parameters', pagination, filters, sorter);
|
|
||||||
this.setState({
|
|
||||||
page: pagination.current,
|
|
||||||
sortedInfo: sorter,
|
|
||||||
}, () => {
|
|
||||||
this.fetchAll(undefined, filterKey)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
clearSelection = () => {
|
|
||||||
this.setState({ checkBoxValues: [] })
|
|
||||||
}
|
|
||||||
selectedStatus = (e) => {
|
|
||||||
this.clearSelection()
|
|
||||||
this.setState({
|
|
||||||
filterKey: e.key,
|
|
||||||
page: 1,
|
|
||||||
isSpin: true
|
|
||||||
}, () => {
|
|
||||||
this.fetchAll(undefined, e.key);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
setGroupChooserModalVisible = (visible) => {
|
|
||||||
// 这里只会调用open
|
|
||||||
this.setState({ groupChooserModalVisible: !this.state.groupChooserModalVisible })
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
const isAdmin = this.props.isAdmin()
|
|
||||||
const columns = buildColumns(this)
|
|
||||||
let {
|
|
||||||
searchValue, checkBoxValues, checkAllValue, course_groups,
|
|
||||||
groupList, total_count, teachers, order, page, apply_size, filterKey
|
|
||||||
} = this.state
|
|
||||||
let currentOrderName = '加入时间排序'
|
|
||||||
if (order == ORDER_BY_NAME) {
|
|
||||||
currentOrderName = '姓名排序'
|
|
||||||
} else if (order == ORDER_BY_GRADUATION_GROUP) {
|
|
||||||
currentOrderName = '答辩组排序'
|
|
||||||
}
|
|
||||||
let combineArray = teachers.slice(0)
|
|
||||||
if (page == 1 && filterKey == '2') {
|
|
||||||
// this.state.application_list && this.state.application_list.slice(0).reverse().forEach(item => {
|
|
||||||
// item.isApply = true
|
|
||||||
// combineArray.unshift(item)
|
|
||||||
// })
|
|
||||||
combineArray = this.state.application_list
|
|
||||||
}
|
|
||||||
const isAdminOrTeacher = this.props.isAdminOrTeacher()
|
|
||||||
const isAdminOrCreator = this.props.isAdminOrCreator()
|
|
||||||
const isSuperAdmin = this.props.isSuperAdmin()
|
|
||||||
const hasGraduationModule = this.hasGraduationModule()
|
|
||||||
const coursesId = this.props.match.params.coursesId
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
{/* <AddTeacherModal ref="addTeacherModal"
|
|
||||||
{...this.props}
|
|
||||||
moduleName="教师"
|
|
||||||
></AddTeacherModal>
|
|
||||||
<AddStudentModal ref="addStudentModal"
|
|
||||||
{...this.props}
|
|
||||||
moduleName="学生"
|
|
||||||
></AddStudentModal> */}
|
|
||||||
{isAdminOrTeacher && <AddGraduationGroupModal ref="addGraduationGroupModal"
|
|
||||||
{...this.props} onOk={this.onAddGraduationGroupOk}
|
|
||||||
></AddGraduationGroupModal>}
|
|
||||||
<AddAdminModal ref="addAdminModal"
|
|
||||||
{...this.props} onOk={this.showChangeAdminModal}
|
|
||||||
changeAdminSuccess={this.changeAdminSuccess}
|
|
||||||
></AddAdminModal>
|
|
||||||
|
|
||||||
<Titlesearchsection
|
|
||||||
title={<React.Fragment>
|
|
||||||
<span>教师列表</span>
|
|
||||||
{!isSuperAdmin && coursesId == '1309' && <span style={{ color: '#848484', fontSize: '14px', marginLeft: '10px' }}>(示例课堂,部分成员不可见)</span>}
|
|
||||||
</React.Fragment>}
|
|
||||||
searchValue={searchValue}
|
|
||||||
onInputSearchChange={this.onInputSearchChange}
|
|
||||||
showSearchInput={total_count >= 10}
|
|
||||||
searchPlaceholder={'请输入姓名进行搜索'}
|
|
||||||
firstRowRight={
|
|
||||||
<React.Fragment>
|
|
||||||
{/* { isAdmin && <WordsBtn style="blue" className="mr30" onClick={()=>this.addTeacher()}>添加教师</WordsBtn> }
|
|
||||||
{ isAdmin && <WordsBtn style="blue" className="mr30" onClick={()=>this.addStudent()}>添加学生</WordsBtn> } */}
|
|
||||||
|
|
||||||
{isAdminOrCreator && <WordsBtn style="blue" className="fr" onClick={() => this.showChangeAdminModal()}>更换管理员</WordsBtn>}
|
|
||||||
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
secondRowLeft={
|
|
||||||
isAdminOrTeacher ? <div className="fl mt6 task_menu_ul " style={{ width: '600px' }}>
|
|
||||||
<Menu mode="horizontal" selectedKeys={[`${this.state.filterKey}`]} onClick={this.selectedStatus}>
|
|
||||||
<Menu.Item key="1">已审批({total_count})</Menu.Item>
|
|
||||||
<Menu.Item key="2">待审批({apply_size})</Menu.Item>
|
|
||||||
</Menu>
|
|
||||||
{/* */}
|
|
||||||
</div> :
|
|
||||||
(!!total_count ? <ColorCountText count={total_count} name="个教师"></ColorCountText> : '')
|
|
||||||
}
|
|
||||||
onPressEnter={this.onPressEnter}
|
|
||||||
></Titlesearchsection>
|
|
||||||
|
|
||||||
<style>{`
|
|
||||||
/* CourseGroupChooser */
|
|
||||||
.drop_down_menu .mainGroup.ant-checkbox-group {
|
|
||||||
max-height: 170px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
.task_menu_ul .ant-menu-item, .task_menu_ul .ant-menu-submenu-title{
|
|
||||||
padding:0px;
|
|
||||||
margin-right: 30px;
|
|
||||||
line-height: 68px;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.teacherList .ant-table-pagination.ant-pagination {
|
|
||||||
float: none;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.drop_down_menu .drop_down_btn{
|
|
||||||
border-top:none;
|
|
||||||
}
|
|
||||||
.dividerStyle.ant-divider-horizontal{
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drop_down_menu li {
|
|
||||||
line-height:30px!important;
|
|
||||||
flex: 0 0 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.teacher_table .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
|
|
||||||
padding: 16px 10px;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
<div className="mt20 edu-back-white padding20 teacherList">
|
|
||||||
|
|
||||||
{course_groups && !!course_groups.length && <CourseGroupChooserModal
|
|
||||||
{...this.state}
|
|
||||||
{...this.props}
|
|
||||||
props={{ match: this.props.match, showNotification: this.props.showNotification }}
|
|
||||||
record={this.state.clickRecord}
|
|
||||||
fetchAll={(e) => this.fetchAll(e, this.state.filterKey)}
|
|
||||||
course_groups={course_groups}
|
|
||||||
visible={this.state.groupChooserModalVisible}
|
|
||||||
setVisible={this.setGroupChooserModalVisible}
|
|
||||||
></CourseGroupChooserModal>}
|
|
||||||
{filterKey == '1' && <div className="clearfix stu_head" style={{ paddingLeft: '15px' }}>
|
|
||||||
{isAdminOrTeacher && hasGraduationModule && <Checkbox className="fl" onChange={this.onCheckAll} checked={checkAllValue} >已选 {checkBoxValues.length} 个</Checkbox>}
|
|
||||||
{filterKey == '1' && <div className="studentList_operation_ul">
|
|
||||||
{hasGraduationModule && isAdminOrTeacher && <li className="li_line drop_down">
|
|
||||||
加入答辩组<i className="iconfont icon-xiajiantou font-12 ml2"></i>
|
|
||||||
<ul className="drop_down_menu" style={{ "right": "0px", "left": "unset", minWidth: '222px' }}>
|
|
||||||
|
|
||||||
{
|
|
||||||
groupList && groupList.graduation_groups_count > 10 ?
|
|
||||||
(<p className="drop_down_search">
|
|
||||||
<Input placeholder="搜索" value={this.state.graduationGroupSearchValue} onChange={(e) => { this.setState({ graduationGroupSearchValue: e.target.value }) }} allowClear />
|
|
||||||
</p>) :
|
|
||||||
(groupList && groupList.graduation_groups_count == 0 && <p style={{ textAlign: 'left', margin: '0px 20px' }}>暂无数据</p>)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
groupList && groupList.graduation_group_list && groupList.graduation_group_list.filter((item) => {
|
|
||||||
return (!this.state.graduationGroupSearchValue || item.name.indexOf(this.state.graduationGroupSearchValue) != -1)
|
|
||||||
}).map((item, key) => {
|
|
||||||
return (
|
|
||||||
<li key={key} value={item.id} onClick={() => this.joinGraduationGroup(item.id)}>{item.name}</li>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
{groupList && groupList.graduation_groups_count > 0 && <Divider className="dividerStyle"></Divider>}
|
|
||||||
<p className="drop_down_btn">
|
|
||||||
<a className="color-grey-6"
|
|
||||||
onClick={() => this.refs['addGraduationGroupModal'].setVisible(true)}
|
|
||||||
>添加答辩组...</a>
|
|
||||||
</p>
|
|
||||||
</ul>
|
|
||||||
</li>}
|
|
||||||
{/* <li className="drop_down">
|
|
||||||
{currentOrderName} <i className="iconfont icon-xiajiantou font-12 ml2"></i>
|
|
||||||
<ul className="drop_down_normal">
|
|
||||||
<li onClick={() => this.onSortTypeChange(ORDER_BY_NAME)} >姓名排序</li>
|
|
||||||
<li onClick={() => this.onSortTypeChange(ORDER_BY_DATE)} style={{width: '125px'}}>加入时间排序</li>
|
|
||||||
{this.hasGraduationModule() && <li onClick={() => this.onSortTypeChange(ORDER_BY_GRADUATION_GROUP)} >答辩组排序</li>}
|
|
||||||
</ul>
|
|
||||||
</li> */}
|
|
||||||
</div>}
|
|
||||||
</div>}
|
|
||||||
<Spin size="large" spinning={this.state.isSpin}>
|
|
||||||
<div className="clearfix stu_table teacher_table">
|
|
||||||
{combineArray.length ?
|
|
||||||
<Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}>
|
|
||||||
{/* pagination={{ current: page, total: total_count, pageSize:20, onChange: this.onPageChange }} */}
|
|
||||||
<Table columns={columns} dataSource={combineArray}
|
|
||||||
onChange={this.onTableChange}
|
|
||||||
pagination={total_count > 20 && filterKey == '1' ? { //分页
|
|
||||||
total: page == 1 && this.state.application_list.length ? total_count + total_count / Math.floor(this.state.application_list.length + 20) : total_count, //数据总数量
|
|
||||||
pageSize: page == 1 && this.state.application_list.length ? this.state.application_list.length + 20 : 20, //显示几条一页
|
|
||||||
current: page,
|
|
||||||
// onChange: this.onPageChange
|
|
||||||
} : false}
|
|
||||||
></Table>
|
|
||||||
</Checkbox.Group>
|
|
||||||
:
|
|
||||||
<NoneData></NoneData>}
|
|
||||||
</div>
|
|
||||||
</Spin>
|
|
||||||
</div>
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default studentsList;
|
|
|
@ -1,140 +0,0 @@
|
||||||
import React, {Component} from "react";
|
|
||||||
import { WordsBtn,on, off, trigger,MarkdownToHtml,getImageUrl} from 'educoder';
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Checkbox,
|
|
||||||
message,
|
|
||||||
InputNumber,
|
|
||||||
DatePicker,
|
|
||||||
Radio,
|
|
||||||
Tooltip,
|
|
||||||
notification,
|
|
||||||
} from "antd";
|
|
||||||
import GroupPackage from '../groupjobbank/GroupPackage'
|
|
||||||
import './questionbank.css';
|
|
||||||
import AttachmentsList from '../../../common/components/attachment/AttachmentList';
|
|
||||||
import NoneData from '../../courses/coursesPublic/NoneData'
|
|
||||||
|
|
||||||
class Generaljobanswer extends Component {
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
console.log("Generaljobanswer");
|
|
||||||
console.log("componentDidMount");
|
|
||||||
// let query = this.props.location.pathname;
|
|
||||||
// const type = query.split('/');
|
|
||||||
// this.setState({n
|
|
||||||
// shixuntypes:type[3]
|
|
||||||
// })
|
|
||||||
// this.props.triggerRef(this);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
// 获取数据地方
|
|
||||||
getTrainingjobsetting = () => {
|
|
||||||
var homeworkid = this.props.match.params.homeworkid;
|
|
||||||
}
|
|
||||||
|
|
||||||
//跳转道描点的地方
|
|
||||||
scrollToAnchor = (anchorName) => {
|
|
||||||
if (anchorName) {
|
|
||||||
// 找到锚点
|
|
||||||
let anchorElement = document.getElementById(anchorName);
|
|
||||||
// 如果对应id的锚点存在,就跳转到锚点
|
|
||||||
if(anchorElement) { anchorElement.scrollIntoView(); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let{datas}=this.props;
|
|
||||||
console.log("Generaljobanswer");
|
|
||||||
console.log(datas.reference_attachments);
|
|
||||||
console.log(datas.reference_answer);
|
|
||||||
return (
|
|
||||||
<div className=" clearfix edu-back-white " ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
|
|
||||||
<div className="yslquestionbank1">
|
|
||||||
{/*{*/}
|
|
||||||
{/* datas&&(datas.reference_answer===null?*/}
|
|
||||||
{/* <NoneData></NoneData>*/}
|
|
||||||
{/* :datas.reference_answer==="null"?*/}
|
|
||||||
{/* <NoneData></NoneData>*/}
|
|
||||||
{/* :*/}
|
|
||||||
{/* datas.reference_answer===""?*/}
|
|
||||||
{/* <NoneData></NoneData>*/}
|
|
||||||
{/* :*/}
|
|
||||||
{/* <MarkdownToHtml content={datas.reference_answer} selector="work_content" className="mb10 yslquesHeigth "></MarkdownToHtml>*/}
|
|
||||||
|
|
||||||
{/* // <div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML(datas.reference_answer).replace(/▁/g, "▁▁▁")}}/>*/}
|
|
||||||
{/* )*/}
|
|
||||||
{/*}*/}
|
|
||||||
{/*/!*<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML(datas&&(datas.reference_answer===null?"无":datas.reference_answer==="null"?"无":datas.reference_answer)).replace(/▁/g, "▁▁▁")}}/>*!/*/}
|
|
||||||
{/*<div className="mt16px">*/}
|
|
||||||
{/*{datas.reference_attachments === undefined ? "" :*/}
|
|
||||||
{/* <AttachmentsList {...this.state} {...this.props} attachments={datas.reference_attachments} ></AttachmentsList>}*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
|
|
||||||
{
|
|
||||||
datas.reference_answer===null?
|
|
||||||
""
|
|
||||||
:datas.reference_answer==="null"?
|
|
||||||
"" :
|
|
||||||
datas.reference_answer===""?
|
|
||||||
""
|
|
||||||
:
|
|
||||||
<MarkdownToHtml content={datas.reference_answer} selector="work_content" className="mb10 yslquesHeigth "></MarkdownToHtml>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
{datas.reference_attachments === undefined ?
|
|
||||||
(datas.reference_answer===undefined || datas.reference_answer===null|| datas.reference_answer===""?
|
|
||||||
<NoneData></NoneData>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
:
|
|
||||||
datas.reference_attachments === "" ?
|
|
||||||
(datas.reference_answer===undefined || datas.reference_answer===null|| datas.reference_answer===""?
|
|
||||||
<NoneData></NoneData>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
:
|
|
||||||
datas.reference_attachments === null ?
|
|
||||||
(datas.reference_answer===undefined || datas.reference_answer===null|| datas.reference_answer===""?
|
|
||||||
<NoneData></NoneData>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
:
|
|
||||||
datas.reference_attachments.length === 0 ?
|
|
||||||
(datas.reference_answer===undefined || datas.reference_answer===null|| datas.reference_answer===""?
|
|
||||||
<NoneData></NoneData>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
:
|
|
||||||
<div className="mt24">
|
|
||||||
<AttachmentsList {...this.state} {...this.props} attachments={datas.reference_attachments} ></AttachmentsList>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Generaljobanswer;
|
|
|
@ -1,170 +0,0 @@
|
||||||
import React, {Component} from "react";
|
|
||||||
import {BrowserRouter as Router,Route,Switch,Link, NavLin} from 'react-router-dom';
|
|
||||||
import {WordsBtn, ActionBtn,getImageUrl} from 'educoder';
|
|
||||||
import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form } from "antd";
|
|
||||||
import axios from 'axios';
|
|
||||||
import BanksMenu from '../../user/usersInfo/banks/banksMenu'
|
|
||||||
import Loadable from 'react-loadable';
|
|
||||||
import Loading from '../../../Loading';
|
|
||||||
import '../css/members.css';
|
|
||||||
import "../common/formCommon.css";
|
|
||||||
import '../css/Courses.css';
|
|
||||||
import '../css/busyWork.css';
|
|
||||||
import '../poll/pollStyle.css';
|
|
||||||
// 问卷内容
|
|
||||||
const Generaljobdetails = Loadable({
|
|
||||||
loader: () => import('./Generaljobdetails'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
// 试卷详情
|
|
||||||
const Generaljobanswer = Loadable({
|
|
||||||
loader: () => import('./Generaljobanswer'),
|
|
||||||
loading: Loading,
|
|
||||||
});
|
|
||||||
class Generaljobbankdetails extends Component {
|
|
||||||
//普通作业内容详情
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
// this.answerMdRef = React.createRef();
|
|
||||||
this.state = {
|
|
||||||
tab: ["0"],
|
|
||||||
workid:1,
|
|
||||||
isSpin:false,
|
|
||||||
datas:[],
|
|
||||||
visible:false,
|
|
||||||
banksMenu:undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.getonedata();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
getonedata=()=>{
|
|
||||||
if( this.props.match.params.workid){
|
|
||||||
this.setState({
|
|
||||||
workid: this.props.match.params.workid,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.getdata(this.props.match.params.workid);
|
|
||||||
};
|
|
||||||
//获取数据的地方
|
|
||||||
getdata=(workid)=>{
|
|
||||||
var workids= workid;
|
|
||||||
if(workids){
|
|
||||||
|
|
||||||
}else{
|
|
||||||
workids=this.state.workid;
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
isSpin:true,
|
|
||||||
})
|
|
||||||
let url = `/homework_banks/${workids}.json`;
|
|
||||||
//
|
|
||||||
axios.get(url).then((response) => {
|
|
||||||
if(response){
|
|
||||||
if(response.data){
|
|
||||||
this.setState({
|
|
||||||
datas:response.data,
|
|
||||||
})
|
|
||||||
try {
|
|
||||||
const crumbData={
|
|
||||||
title:response && response.data && response.data.name,
|
|
||||||
is_public:response && response.data && response.data.is_public,
|
|
||||||
crumbArray:[
|
|
||||||
{content:'详情'}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
const menuData={
|
|
||||||
tab:'0',//tab选中的index
|
|
||||||
menuArray:[//tab以及tab路由
|
|
||||||
{to:`/banks/normal/${workids}/${this.props.match.params.type}?tab=0`,content:'内容详情'},
|
|
||||||
{to:`/banks/normal/${workids}/${this.props.match.params.type}/answer?tab=1`,content:'参考答案'}
|
|
||||||
],
|
|
||||||
category:'normal',//毕设选题
|
|
||||||
tos:`/banks/normal/${workids}/edit/${this.props.match.params.type}?tab=0`,
|
|
||||||
id:workids,
|
|
||||||
is_public:response && response.data && response.data.is_public,
|
|
||||||
type:this.props.match.params.type,
|
|
||||||
authorize:response && response.data && response.data.authorize,
|
|
||||||
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
banksMenu:menuData
|
|
||||||
})
|
|
||||||
this.props.initPublic(crumbData,response.data);
|
|
||||||
}catch (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
this.setState({
|
|
||||||
datas:[],
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
this.setState({
|
|
||||||
datas:[],
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
isSpin:false,
|
|
||||||
})
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
this.setState({
|
|
||||||
datas:[],
|
|
||||||
isSpin:false,
|
|
||||||
})
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// initPublic = (crumbData,menuData) =>{
|
|
||||||
// this.setState({
|
|
||||||
// banksMenu:menuData
|
|
||||||
// })
|
|
||||||
// this.props.initPublic(crumbData);
|
|
||||||
// }
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let {tab,datas,visible} = this.state;
|
|
||||||
|
|
||||||
let{
|
|
||||||
banksMenu
|
|
||||||
}=this.state
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<div className="pd30">
|
|
||||||
{
|
|
||||||
banksMenu &&
|
|
||||||
<BanksMenu
|
|
||||||
banksMenu={banksMenu}
|
|
||||||
{...this.props}
|
|
||||||
{...this.state}
|
|
||||||
></BanksMenu>
|
|
||||||
}
|
|
||||||
<Switch {...this.props}>
|
|
||||||
<Route path={`/banks/normal/:workid/${this.props.match.params.type}/answer`}
|
|
||||||
render={
|
|
||||||
(props) => {
|
|
||||||
return (<Generaljobanswer {...this.props} {...props} {...this.state} datas={datas} />)
|
|
||||||
}
|
|
||||||
}></Route>
|
|
||||||
<Route path={`/banks/normal/:workid/${this.props.match.params.type}`}
|
|
||||||
render={
|
|
||||||
(props) => {
|
|
||||||
return (<Generaljobdetails {...this.props} {...props} {...this.state} datas={datas} />)
|
|
||||||
}
|
|
||||||
}></Route>
|
|
||||||
|
|
||||||
</Switch>
|
|
||||||
</div>
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Generaljobbankdetails;
|
|
|
@ -1,117 +0,0 @@
|
||||||
|
|
||||||
import React, {Component} from "react";
|
|
||||||
import { WordsBtn,on, off, trigger,markdownToHTML, MarkdownToHtml ,getImageUrl} from 'educoder';
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Checkbox,
|
|
||||||
message,
|
|
||||||
InputNumber,
|
|
||||||
DatePicker,
|
|
||||||
Radio,
|
|
||||||
Tooltip,
|
|
||||||
notification,
|
|
||||||
} from "antd";
|
|
||||||
import GroupPackage from '../groupjobbank/GroupPackage'
|
|
||||||
import './questionbank.css';
|
|
||||||
import AttachmentsList from "../../../common/components/attachment/AttachmentList";
|
|
||||||
import NoneData from '../../courses/coursesPublic/NoneData'
|
|
||||||
//内容详情
|
|
||||||
class Generaljobdetails extends Component {
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
console.log("Generaljobdetails");
|
|
||||||
console.log("componentDidMount");
|
|
||||||
// let query = this.props.location.pathname;
|
|
||||||
// const type = query.split('/');
|
|
||||||
// this.setState({
|
|
||||||
// shixuntypes:type[3]
|
|
||||||
// })
|
|
||||||
// this.props.triggerRef(this);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
// 获取数据地方
|
|
||||||
getTrainingjobsetting = () => {
|
|
||||||
var homeworkid = this.props.match.params.homeworkid;
|
|
||||||
}
|
|
||||||
|
|
||||||
//跳转道描点的地方
|
|
||||||
scrollToAnchor = (anchorName) => {
|
|
||||||
if (anchorName) {
|
|
||||||
// 找到锚点
|
|
||||||
let anchorElement = document.getElementById(anchorName);
|
|
||||||
// 如果对应id的锚点存在,就跳转到锚点
|
|
||||||
if(anchorElement) { anchorElement.scrollIntoView(); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let{datas}=this.props;
|
|
||||||
return (
|
|
||||||
<div className=" clearfix edu-back-white " ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
|
|
||||||
<div className="yslquestionbank1">
|
|
||||||
{
|
|
||||||
datas.description===null?
|
|
||||||
""
|
|
||||||
:datas.description==="null"?
|
|
||||||
""
|
|
||||||
:datas&&datas.description===""?
|
|
||||||
""
|
|
||||||
:
|
|
||||||
<MarkdownToHtml content={datas.description} selector="work_content" className="mb10 yslquesHeigth"></MarkdownToHtml>
|
|
||||||
// <div id="MakedownHTML "className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML(datas.description).replace(/▁/g, "▁▁▁")}}/>
|
|
||||||
}
|
|
||||||
{datas.attachments === undefined ?
|
|
||||||
(datas.description === undefined || datas.description === null || datas.description === "" ?
|
|
||||||
<NoneData></NoneData>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
:
|
|
||||||
datas.attachments=== "" ?
|
|
||||||
(datas.description === undefined || datas.description === null || datas.description === "" ?
|
|
||||||
<NoneData></NoneData>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
:
|
|
||||||
datas.attachments=== null ?
|
|
||||||
(datas.description === undefined || datas.description === null || datas.description === "" ?
|
|
||||||
<NoneData></NoneData>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
:
|
|
||||||
datas.attachments.length === 0 ?
|
|
||||||
(datas.description === undefined || datas.description === null || datas.description === "" ?
|
|
||||||
<NoneData></NoneData>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
:
|
|
||||||
<div className="mt16px">
|
|
||||||
<AttachmentsList {...this.state} {...this.props}
|
|
||||||
attachments={datas.attachments}></AttachmentsList>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Generaljobdetails;
|
|
|
@ -1,33 +0,0 @@
|
||||||
.yslquestionbank1{
|
|
||||||
padding-top: 30px !important;
|
|
||||||
padding-right: 30px !important;
|
|
||||||
padding-left: 30px !important;
|
|
||||||
min-height: 500px !important;
|
|
||||||
}
|
|
||||||
.yslquesHeigth{
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
|
||||||
.yslquesmarkdowntext{
|
|
||||||
font-size: 16px;
|
|
||||||
color: #707070;
|
|
||||||
|
|
||||||
}
|
|
||||||
.yslquesmat26{
|
|
||||||
margin-top: 26px;
|
|
||||||
padding-bottom: 44px !important;
|
|
||||||
}
|
|
||||||
.ysltextcolor9999{
|
|
||||||
color: #999999;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.ysltextcolor99999{
|
|
||||||
color: #999999;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
.mt16px{
|
|
||||||
margin-top: 16px;
|
|
||||||
padding-bottom: 30px;
|
|
||||||
}
|
|
||||||
.pd30{
|
|
||||||
padding-bottom: 30px;
|
|
||||||
}
|
|
|
@ -1,128 +0,0 @@
|
||||||
import React, {Component} from "react";
|
|
||||||
import {Menu, Dropdown, Icon, Input, Checkbox} from "antd";
|
|
||||||
import {getImageUrl} from 'educoder';
|
|
||||||
|
|
||||||
const {Search} = Input;
|
|
||||||
|
|
||||||
class Dropdownbox extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
activeKey: '1',
|
|
||||||
visible: false,
|
|
||||||
onSearchvalue: undefined,
|
|
||||||
checkedValues: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
let {group_ids} = this.props;
|
|
||||||
if (group_ids) {
|
|
||||||
this.setState({
|
|
||||||
checkedValues: group_ids
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate = (prevProps) => {
|
|
||||||
if (prevProps != this.props) {
|
|
||||||
let {group_ids} = this.props;
|
|
||||||
if (group_ids) {
|
|
||||||
this.setState({
|
|
||||||
checkedValues: group_ids
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SaveChange = () => {
|
|
||||||
this.props.postwork_scoredata(this.state.checkedValues)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
handleVisibleChange = flag => {
|
|
||||||
this.setState({visible: flag});
|
|
||||||
};
|
|
||||||
|
|
||||||
CheckboxonChange = (checkedValues) => {
|
|
||||||
this.setState({
|
|
||||||
checkedValues: checkedValues
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
unCheckboxonChange = () => {
|
|
||||||
this.setState({
|
|
||||||
checkedValues: [],
|
|
||||||
onSearchvalue: undefined
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onSearch = (value) => {
|
|
||||||
this.setState({
|
|
||||||
onSearchvalue: value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onSearchonChange = (e) => {
|
|
||||||
this.setState({
|
|
||||||
onSearchvalue: e.target.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let {course_groups} = this.props;
|
|
||||||
|
|
||||||
const menu = (
|
|
||||||
<Checkbox.Group style={{width: 220}} className={"StatisticsMenubox"} value={this.state.checkedValues}
|
|
||||||
onChange={(checkedValues) => this.CheckboxonChange(checkedValues)}>
|
|
||||||
<Menu className="Statisticslibox">
|
|
||||||
<li className={"Statisticsli"}>
|
|
||||||
{course_groups && course_groups.length > 10 ? <Search
|
|
||||||
placeholder="请输入名称搜索"
|
|
||||||
onSearch={(value) => this.onSearch(value)}
|
|
||||||
onChange={(e) => this.onSearchonChange(e)}
|
|
||||||
value={this.state.onSearchvalue}
|
|
||||||
style={{width: 200}}
|
|
||||||
/> : ""}
|
|
||||||
</li>
|
|
||||||
{course_groups && course_groups.map((item, key) => {
|
|
||||||
if (this.state.onSearchvalue) {
|
|
||||||
if (item.name.indexOf(this.state.onSearchvalue) != -1) {
|
|
||||||
return (
|
|
||||||
<Menu.Item key={key}>
|
|
||||||
<Checkbox value={item.id} key={item.id}> {item.name}</Checkbox>
|
|
||||||
</Menu.Item>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<Menu.Item key={key}>
|
|
||||||
<Checkbox value={item.id} key={item.id}> {item.name}</Checkbox>
|
|
||||||
</Menu.Item>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
<Menu.Divider/>
|
|
||||||
<li className={"Statisticsli"}>
|
|
||||||
<span onClick={() => this.SaveChange()} className={"ant-btn-link"}>确定</span>
|
|
||||||
<span className={"ml20 ant-btn-link"} onClick={() => this.unCheckboxonChange()}>重置</span>
|
|
||||||
</li>
|
|
||||||
</Menu>
|
|
||||||
</Checkbox.Group>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<Dropdown overlay={menu}
|
|
||||||
onVisibleChange={this.handleVisibleChange}
|
|
||||||
visible={this.state.visible}
|
|
||||||
>
|
|
||||||
<a className="ant-dropdown-link">
|
|
||||||
分班 <Icon type="down"/>
|
|
||||||
</a>
|
|
||||||
</Dropdown>
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Dropdownbox;
|
|
|
@ -1,90 +0,0 @@
|
||||||
import React,{ Component } from "react";
|
|
||||||
import {Row, Col,Popover,Button,Icon} from "antd";
|
|
||||||
import {
|
|
||||||
G2,
|
|
||||||
Chart,
|
|
||||||
Geom,
|
|
||||||
Axis,
|
|
||||||
Tooltip,
|
|
||||||
Coord,
|
|
||||||
Label,
|
|
||||||
Legend,
|
|
||||||
View,
|
|
||||||
Guide,
|
|
||||||
Shape,
|
|
||||||
Facet,
|
|
||||||
Util
|
|
||||||
} from "bizcharts";
|
|
||||||
|
|
||||||
class Dynamiclist extends Component{
|
|
||||||
constructor(props){
|
|
||||||
super(props);
|
|
||||||
this.state={
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render(){
|
|
||||||
const data = []
|
|
||||||
let {course_members}=this.props;
|
|
||||||
if(course_members){
|
|
||||||
if(course_members.length>0){
|
|
||||||
course_members.map((item,key)=>{
|
|
||||||
data.push({'name':item.user_name,'活跃度':item.total_score})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = (
|
|
||||||
<div className={"Statisticscircle"}>
|
|
||||||
<p>
|
|
||||||
作业完成数(*10)
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
试卷完成数(*10)
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
问卷完成数(*7)
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
资源发布数(*5)
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
帖子发布数(*2)
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
帖子回复数(*1)
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
作业回复数(*1)
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
return(
|
|
||||||
<React.Fragment>
|
|
||||||
<Row>
|
|
||||||
<Col span={12} className={"top10s"}>Top 10</Col>
|
|
||||||
<Col span={12} className={"Statisticsliboxjsgz"}>
|
|
||||||
<span className={"mr10"}>计算规则</span>
|
|
||||||
<Popover placement="bottom" title={"活动规则计算说明"} content={content} trigger="hover">
|
|
||||||
<Icon type="info-circle" />
|
|
||||||
</Popover>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
{/*scale={cols}*/}
|
|
||||||
<Chart height={400} data={data} forceFit>
|
|
||||||
<Axis name="name" />
|
|
||||||
<Axis name="活跃度" />
|
|
||||||
<Tooltip
|
|
||||||
crosshairs={{
|
|
||||||
type: "y"
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Geom type="interval" position="name*活跃度" />
|
|
||||||
</Chart>
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default Dynamiclist;
|
|
|
@ -1,148 +0,0 @@
|
||||||
.height-60{
|
|
||||||
line-height: 60px;
|
|
||||||
height:60px;
|
|
||||||
background:rgba(255,208,88,1);
|
|
||||||
border-radius:4px 4px 0px 0px;
|
|
||||||
}
|
|
||||||
.height-40{
|
|
||||||
line-height: 40px;
|
|
||||||
height:40px;
|
|
||||||
background:rgba(224,229,234,1);
|
|
||||||
border-radius:4px 0px 0px 0px;
|
|
||||||
}
|
|
||||||
.height-20{
|
|
||||||
line-height: 20px;
|
|
||||||
height:20px;
|
|
||||||
background:rgba(229,168,102,1);
|
|
||||||
border-radius:0px 4px 0px 0px;
|
|
||||||
}
|
|
||||||
.Statisticscenter{
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.Statisticscenter div:nth-child(1){
|
|
||||||
margin-top: 5px;
|
|
||||||
font-size:12px;
|
|
||||||
color:rgba(51,51,51,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.Statisticscenter div:nth-child(2){
|
|
||||||
margin-top: 5px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: rgba(153,153,153,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rankingss {
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rankingss a img {
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border:1px solid #F4F4F4;
|
|
||||||
/*box-shadow: 0px 0px 12px rgba(0,0,0,0.2);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.huangguans{
|
|
||||||
width: 36px;
|
|
||||||
height: 17px;
|
|
||||||
position: absolute;
|
|
||||||
top: -6px;
|
|
||||||
left: 71px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.relatives{
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.statisticsTabs{
|
|
||||||
padding: 30px;
|
|
||||||
padding-top: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.statisticsTabs .ant-tabs-tab{
|
|
||||||
height: 80px;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 61px;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Statisticsli{
|
|
||||||
clear: both;
|
|
||||||
margin: 0;
|
|
||||||
padding: 5px 12px;
|
|
||||||
color: rgba(0, 0, 0, 0.65);
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 22px;
|
|
||||||
white-space: nowrap;
|
|
||||||
cursor: pointer;
|
|
||||||
-webkit-transition: all 0.3s;
|
|
||||||
-o-transition: all 0.3s;
|
|
||||||
transition: all 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.StatisticsMenubox{
|
|
||||||
position: relative;
|
|
||||||
margin: 0;
|
|
||||||
padding: 4px 0;
|
|
||||||
text-align: left;
|
|
||||||
list-style-type: none;
|
|
||||||
background-color: #fff;
|
|
||||||
background-clip: padding-box;
|
|
||||||
border-radius: 4px;
|
|
||||||
outline: none;
|
|
||||||
-webkit-box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
|
||||||
-webkit-transform: translate3d(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.Statisticslibox li label{
|
|
||||||
width: 200px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.Statisticslibox .ant-menu-item{
|
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
|
||||||
text-overflow: clip;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top10s{
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: rgba(51,51,51,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.Statisticsliboxjsgz{
|
|
||||||
font-size:12px;
|
|
||||||
color:rgba(51,51,51,1);
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Statisticscircle p{
|
|
||||||
height: 30px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: rgba(153,153,153,1);
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
.Statisticsmxxy{
|
|
||||||
font-size: 16px;
|
|
||||||
margin-left:15px;
|
|
||||||
}
|
|
||||||
.maxnamewidth200 {
|
|
||||||
max-width: 200px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
.maxnamewidth180 {
|
|
||||||
max-width: 180px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
|
@ -1,665 +0,0 @@
|
||||||
import React,{ Component } from "react";
|
|
||||||
import {Table, Pagination,Popover,Spin, Row, Col ,Tabs, Icon} from "antd";
|
|
||||||
import { WordsBtn,on, off, getRandomcode ,getImageUrl,sortDirections} from 'educoder';
|
|
||||||
import axios from'axios';
|
|
||||||
import Dropdownbox from './Dropdownbox';
|
|
||||||
import Dynamiclist from './Dynamiclist';
|
|
||||||
import NoneData from "../../courses/coursesPublic/NoneData";
|
|
||||||
import './Statistics.css';
|
|
||||||
const qs = require('qs');
|
|
||||||
const { TabPane } = Tabs;
|
|
||||||
|
|
||||||
class Statistics extends Component{
|
|
||||||
constructor(props){
|
|
||||||
super(props);
|
|
||||||
this.state={
|
|
||||||
nd1:60,
|
|
||||||
nd2:40,
|
|
||||||
nd3:20,
|
|
||||||
data:undefined,
|
|
||||||
bomdata:undefined,
|
|
||||||
topisSpin:true,
|
|
||||||
bomisSpin:true,
|
|
||||||
sort:'desc',
|
|
||||||
course_groups:[],
|
|
||||||
page:1,
|
|
||||||
all_count:null,
|
|
||||||
activeKey:'1',
|
|
||||||
visible: false,
|
|
||||||
group_ids:[],
|
|
||||||
course_members:undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.getdatas()
|
|
||||||
}
|
|
||||||
|
|
||||||
getdatas=()=>{
|
|
||||||
let {page,group_ids,sort}=this.state;
|
|
||||||
let courseId=this.props.match.params.coursesId;
|
|
||||||
let url=`/courses/${courseId}/statistics.json`;
|
|
||||||
axios.get(url).then((result) => {
|
|
||||||
if (result) {
|
|
||||||
this.setState({
|
|
||||||
data:result.data.top_scores,
|
|
||||||
topisSpin:false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
this.setState({
|
|
||||||
topisSpin:false,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
let courseurl=`/courses/${courseId}/all_course_groups.json`;
|
|
||||||
axios.get(courseurl).then((result) => {
|
|
||||||
if (result) {
|
|
||||||
this.setState({
|
|
||||||
course_groups:result.data.course_groups
|
|
||||||
})
|
|
||||||
let list=result.data.course_groups;
|
|
||||||
// if(list.length>0){
|
|
||||||
// this.setState({
|
|
||||||
// group_ids:[list[0].id],
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
this.getwork_scoredata(page,undefined,sort);
|
|
||||||
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
getDynamiclistdatas=(group_ids,key)=>{
|
|
||||||
if(key==='2') {
|
|
||||||
let courseId = this.props.match.params.coursesId;
|
|
||||||
let url = `/courses/${courseId}/act_score.json`;
|
|
||||||
let data = {
|
|
||||||
group_ids: group_ids,
|
|
||||||
}
|
|
||||||
axios.get(url, {
|
|
||||||
params:
|
|
||||||
data
|
|
||||||
}).then((result) => {
|
|
||||||
if (result) {
|
|
||||||
this.setState({
|
|
||||||
course_members: result.data.course_members,
|
|
||||||
bomisSpin: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
this.setState({
|
|
||||||
bomisSpin: false,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getwork_scoredata=(page,group_ids,sort,key)=>{
|
|
||||||
this.setState({
|
|
||||||
page:page,
|
|
||||||
sort:sort,
|
|
||||||
group_ids:this.props.isStudent()===true?undefined:group_ids,
|
|
||||||
bomisSpin:true,
|
|
||||||
})
|
|
||||||
|
|
||||||
if(key==='1'||key===undefined){
|
|
||||||
let courseId=this.props.match.params.coursesId;
|
|
||||||
let url=`/courses/${courseId}/work_score.json`;
|
|
||||||
let data={
|
|
||||||
limit:20,
|
|
||||||
page:page,
|
|
||||||
group_ids:this.props.isStudent()===true?undefined:group_ids,
|
|
||||||
sort:sort
|
|
||||||
}
|
|
||||||
axios.get(url,{params:
|
|
||||||
data
|
|
||||||
}).then((result) => {
|
|
||||||
if (result) {
|
|
||||||
this.setState({
|
|
||||||
bomdata:result.data.course_members,
|
|
||||||
all_count:result.data.all_count,
|
|
||||||
bomisSpin:false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
this.setState({
|
|
||||||
bomisSpin:false,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
this.getDynamiclistdatas(group_ids)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
activeKey=(key)=>{
|
|
||||||
if(key==="1"){
|
|
||||||
let {page,group_ids,sort}=this.state;
|
|
||||||
// this.getdatas()
|
|
||||||
this.getwork_scoredata(page,group_ids,sort,key)
|
|
||||||
}else if(key==="2"){
|
|
||||||
let{group_ids}=this.state;
|
|
||||||
this.getDynamiclistdatas(group_ids,key)
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
activeKey:key
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PaginationCourse=(pageNumber)=>{
|
|
||||||
let {group_ids,sort}=this.state;
|
|
||||||
|
|
||||||
this.getwork_scoredata(pageNumber,group_ids,sort);
|
|
||||||
}
|
|
||||||
|
|
||||||
derivefun=(url)=>{
|
|
||||||
let{group_ids}=this.state;
|
|
||||||
let list=group_ids;
|
|
||||||
let urllist="";
|
|
||||||
if(list!=undefined&&list.length!=0)
|
|
||||||
list.map((item,key)=>{
|
|
||||||
if(key===0){
|
|
||||||
urllist=`group_id[]=${item}`
|
|
||||||
}else{
|
|
||||||
urllist=urllist+`&group_id[]=${item}`
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
// console.log(getRandomcode(`${url}?${urllist}`))
|
|
||||||
this.props.slowDownload(getRandomcode(`${url}?${urllist}`));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 筛选
|
|
||||||
handleTableChange =(pagination, filters, data)=>{
|
|
||||||
let order=data.order;
|
|
||||||
let {page,group_ids}=this.state;
|
|
||||||
if(order==="descend"){
|
|
||||||
this.getwork_scoredata(page,group_ids,'desc')
|
|
||||||
}else{
|
|
||||||
this.getwork_scoredata(page,group_ids,'asc')
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//计算成绩
|
|
||||||
setComputeTimet = (homeworkid) => {
|
|
||||||
let url = `/courses/${homeworkid}/calculate_all_shixun_scores.json`;
|
|
||||||
try {
|
|
||||||
this.props.yslslowCheckresults();
|
|
||||||
} catch (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
axios.get(url).then((response) => {
|
|
||||||
if (response) {
|
|
||||||
if (response.data.status === 0) {
|
|
||||||
let{page,group_ids,sort}=this.state;
|
|
||||||
setTimeout(() => {
|
|
||||||
try {
|
|
||||||
this.props.showNotification(`${response.data.message}`);
|
|
||||||
} catch (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
this.props.yslslowCheckresultsNo();
|
|
||||||
} catch (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
this.getwork_scoredata(page,group_ids,sort);
|
|
||||||
}, 2500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
try {
|
|
||||||
this.props.yslslowCheckresultsNo();
|
|
||||||
} catch (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
console.log(error)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
render(){
|
|
||||||
let {nd1,nd2,nd3,data,bomdata,course_members,activeKey}=this.state;
|
|
||||||
|
|
||||||
const columns = [
|
|
||||||
{
|
|
||||||
title: this.props.isAdmin()===true?'序号':'排名',
|
|
||||||
dataIndex: 'index',
|
|
||||||
render: (text, record,index) => {
|
|
||||||
return this.props.isAdmin()===true?(this.state.page - 1) * 20 + index + 1:record.rank
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '姓名',
|
|
||||||
dataIndex:'user_name',
|
|
||||||
className: 'maxnamewidth180',
|
|
||||||
render: (text, record) => (
|
|
||||||
<a title={record.user_name} className="maxnamewidth180">{record.user_name}</a>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '分班',
|
|
||||||
dataIndex: 'course_group',
|
|
||||||
className: 'maxnamewidth200',
|
|
||||||
render: (text, record) => (
|
|
||||||
<a title={record.course_group} className="maxnamewidth200">{record.course_group}</a>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '实训作业',
|
|
||||||
dataIndex: 'practice_score',
|
|
||||||
render: (text, record) => (
|
|
||||||
<span >{record.practice_score.toFixed(2)}</span>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '普通作业',
|
|
||||||
dataIndex: 'common_score',
|
|
||||||
render: (text, record) => (
|
|
||||||
<span >{record.common_score.toFixed(2)}</span>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '分组作业',
|
|
||||||
dataIndex: 'group_score',
|
|
||||||
render: (text, record) => (
|
|
||||||
<span >{record.group_score.toFixed(2)}</span>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '毕设任务',
|
|
||||||
dataIndex: 'graduation_score',
|
|
||||||
render: (text, record) => (
|
|
||||||
<span >{record.graduation_score.toFixed(2)}</span>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '试卷',
|
|
||||||
dataIndex: 'exercise_score',
|
|
||||||
render: (text, record) => (
|
|
||||||
<span >{record.exercise_score}</span>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '总成绩',
|
|
||||||
dataIndex: 'total_score',
|
|
||||||
sorter: this.props.isAdmin()===true?true:false,
|
|
||||||
defaultSortOrder: 'descend',
|
|
||||||
sortDirections: sortDirections,
|
|
||||||
render: (text, record) => (
|
|
||||||
<span >{record.total_score.toFixed(2)}</span>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
let shixun_homeworktype=false;
|
|
||||||
let common_homeworktype=false;
|
|
||||||
let group_homeworktype=false;
|
|
||||||
let graduationtype=false;
|
|
||||||
let exercisetype=false;
|
|
||||||
let course_grouptype=false;
|
|
||||||
if(this.props&&this.props.course_modules!=undefined){
|
|
||||||
{this.props&&this.props.course_modules.map((item,key)=>{
|
|
||||||
if(item.type==="course_group"){
|
|
||||||
course_grouptype=true
|
|
||||||
}
|
|
||||||
|
|
||||||
if(item.type==="shixun_homework"){
|
|
||||||
shixun_homeworktype=true
|
|
||||||
}
|
|
||||||
if(item.type==="common_homework"){
|
|
||||||
common_homeworktype=true
|
|
||||||
}
|
|
||||||
if(item.type==="group_homework"){
|
|
||||||
group_homeworktype=true
|
|
||||||
} if(item.type==="graduation"){
|
|
||||||
graduationtype=true
|
|
||||||
}
|
|
||||||
|
|
||||||
if(item.type==="exercise"){
|
|
||||||
exercisetype=true
|
|
||||||
}
|
|
||||||
|
|
||||||
})}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(course_grouptype===false){
|
|
||||||
columns.some((item,key)=> {
|
|
||||||
if (item.title === "分班") {
|
|
||||||
columns.splice(key, 1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(shixun_homeworktype===false){
|
|
||||||
columns.some((item,key)=> {
|
|
||||||
if (item.title === "实训作业") {
|
|
||||||
columns.splice(key, 1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(common_homeworktype===false){
|
|
||||||
columns.some((item,key)=> {
|
|
||||||
if (item.title === "普通作业") {
|
|
||||||
columns.splice(key, 1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(group_homeworktype===false){
|
|
||||||
columns.some((item,key)=> {
|
|
||||||
if (item.title === "分组作业") {
|
|
||||||
columns.splice(key, 1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(graduationtype===false){
|
|
||||||
columns.some((item,key)=> {
|
|
||||||
if (item.title === "毕设任务") {
|
|
||||||
columns.splice(key, 1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(exercisetype===false){
|
|
||||||
columns.some((item,key)=> {
|
|
||||||
if (item.title === "试卷") {
|
|
||||||
columns.splice(key, 1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log("Statistics");
|
|
||||||
// console.log(this.props.user.course_is_end)
|
|
||||||
|
|
||||||
const course_is_endismy=this.props&&this.props.user&&this.props.user.course_is_end;
|
|
||||||
const operations = <React.Fragment>
|
|
||||||
{course_grouptype===false||this.state.course_groups.length===0?"":
|
|
||||||
this.props.isAdmin()===true?
|
|
||||||
<Dropdownbox
|
|
||||||
{...this.props}
|
|
||||||
{...this.state}
|
|
||||||
postwork_scoredata={(group_idss)=>this.getwork_scoredata(1,group_idss,'desc')
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
{
|
|
||||||
this.state.activeKey==="1"?
|
|
||||||
(
|
|
||||||
course_is_endismy===false?
|
|
||||||
<a className={"ml20 ant-btn-link"} onClick={()=>this.setComputeTimet(this.props.match.params.coursesId)}>获取最新成绩</a>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
)
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
{
|
|
||||||
this.props.isAdmin()===true?
|
|
||||||
// 这里是文件下载 不能替换路由
|
|
||||||
<a className={"ml20 ant-btn-link"} onClick={()=>this.derivefun(this.state.activeKey==="1"?`/courses/${this.props.match.params.coursesId}/export_member_scores_excel.xlsx`:`/courses/${this.props.match.params.coursesId}/export_member_act_score.xlsx`)}>导出</a>
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
</React.Fragment>;
|
|
||||||
|
|
||||||
const content = (
|
|
||||||
<div className={"Statisticscircle"}>
|
|
||||||
<p>
|
|
||||||
课堂总成绩 * 70 %
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
课堂活跃度 * 10%
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
课外学习成绩 * 20%
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
其中,课外学习成绩= 当前学生经验值 / 课堂学生经验值 最大值*100
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
return(
|
|
||||||
<React.Fragment>
|
|
||||||
<div className="edu-back-white">
|
|
||||||
<Spin size="large" spinning={this.state.topisSpin}>
|
|
||||||
<p className="clearfix padding30">
|
|
||||||
<Row>
|
|
||||||
<Col span={12}>
|
|
||||||
明星学员
|
|
||||||
</Col>
|
|
||||||
<Col span={12} className={"Statisticsliboxjsgz"}>
|
|
||||||
<span className={"mr10"}>计算规则</span>
|
|
||||||
<Popover placement="bottom" title={"明星学员计算说明"} content={content} trigger="hover">
|
|
||||||
<Icon type="info-circle" />
|
|
||||||
</Popover>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row type="flex" justify="center" align="bottom">
|
|
||||||
{data&&data.map((item,key)=>{
|
|
||||||
if(key===3){
|
|
||||||
return(
|
|
||||||
<Col span={3}>
|
|
||||||
<li className="pr rankingss">
|
|
||||||
<a href={`/users/${item.user_login}`} className="color-dark">
|
|
||||||
<img src={getImageUrl(`images/${item.avatar_url}`)}/>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</Col>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
})}
|
|
||||||
{data&&data.map((item,key)=>{
|
|
||||||
if(key===1){
|
|
||||||
return(
|
|
||||||
<Col span={5}>
|
|
||||||
<li className="pr rankingss">
|
|
||||||
<a href={`/users/${item.user_login}`} className="color-dark">
|
|
||||||
<img src={getImageUrl(`images/${item.avatar_url}`)} className={"mb10"}/>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<Col className={`height-${nd2}`}>
|
|
||||||
|
|
||||||
</Col>
|
|
||||||
</Col>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
})}
|
|
||||||
|
|
||||||
{data&&data.map((item,key)=>{
|
|
||||||
if(key===0){
|
|
||||||
return(
|
|
||||||
<Col span={5} className={"relatives"}>
|
|
||||||
<li className="pr rankingss">
|
|
||||||
<img src={getImageUrl("images/educoder/imperialcrown.png")} className="huangguans mb5" />
|
|
||||||
<a href={`/users/${item.user_login}`} className="color-dark">
|
|
||||||
<img src={getImageUrl(`images/${item.avatar_url}`)} className={"mb10 mt5"}/>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<Col className={`height-${nd1}`}>
|
|
||||||
|
|
||||||
</Col>
|
|
||||||
</Col>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
})}
|
|
||||||
|
|
||||||
{data&&data.map((item,key)=>{
|
|
||||||
if(key===2){
|
|
||||||
return(
|
|
||||||
<Col span={5}>
|
|
||||||
<li className="pr rankingss">
|
|
||||||
<a href={`/users/${item.user_login}`} className="color-dark">
|
|
||||||
<img src={getImageUrl(`images/${item.avatar_url}`)} className={"mb10"}/>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<Col className={`height-${nd3}`}>
|
|
||||||
|
|
||||||
</Col>
|
|
||||||
</Col>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
})}
|
|
||||||
|
|
||||||
|
|
||||||
{data&&data.map((item,key)=>{
|
|
||||||
if(key===4){
|
|
||||||
return(
|
|
||||||
<Col span={3}>
|
|
||||||
<li className="pr rankingss">
|
|
||||||
<a href={`/users/${item.user_login}`} className="color-dark">
|
|
||||||
<img src={getImageUrl(`images/${item.avatar_url}`)}/>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</Col>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
})}
|
|
||||||
|
|
||||||
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
|
|
||||||
<Row className="mt10" type="flex" justify="center" align="bottom">
|
|
||||||
|
|
||||||
{data&&data.map((item,key)=>{
|
|
||||||
if(key===3){
|
|
||||||
return(
|
|
||||||
<Col span={3} className={"Statisticscenter"}>
|
|
||||||
<Col>{item.user_name}</Col>
|
|
||||||
<Col>4th</Col>
|
|
||||||
</Col>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
{data&&data.map((item,key)=>{
|
|
||||||
if(key===1){
|
|
||||||
return(
|
|
||||||
<Col span={5} className={"Statisticscenter"}>
|
|
||||||
<Col>{item.user_name}</Col>
|
|
||||||
<Col>2nd</Col>
|
|
||||||
</Col>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
{data&&data.map((item,key)=>{
|
|
||||||
if(key===0){
|
|
||||||
return(
|
|
||||||
<Col span={5} className={"Statisticscenter"}>
|
|
||||||
<Col>{item.user_name}</Col>
|
|
||||||
<Col>1st</Col>
|
|
||||||
</Col>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
{data&&data.map((item,key)=>{
|
|
||||||
if(key===2){
|
|
||||||
return(
|
|
||||||
<Col span={5} className={"Statisticscenter"}>
|
|
||||||
<Col>{item.user_name}</Col>
|
|
||||||
<Col>3rd</Col>
|
|
||||||
</Col>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
{data&&data.map((item,key)=>{
|
|
||||||
if(key===4){
|
|
||||||
return(
|
|
||||||
<Col span={3} className={"Statisticscenter"}>
|
|
||||||
<Col>{item.user_name}</Col>
|
|
||||||
<Col>5th</Col>
|
|
||||||
</Col>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
|
|
||||||
</Row>
|
|
||||||
</p>
|
|
||||||
</Spin>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mt20 edu-back-white">
|
|
||||||
<Spin size="large" spinning={this.state.bomisSpin}>
|
|
||||||
<style>{
|
|
||||||
`
|
|
||||||
.ant-select-dropdown-menu {
|
|
||||||
max-height: 320px;
|
|
||||||
}
|
|
||||||
.ant-tabs-extra-content{
|
|
||||||
margin-top:20px;
|
|
||||||
}
|
|
||||||
.ant-table-thead > tr > th, .ant-table-tbody > tr > td {
|
|
||||||
padding: 16px 0px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}</style>
|
|
||||||
<Tabs className="statisticsTabs" activeKey={this.state.activeKey} onChange={this.activeKey} tabBarExtraContent={operations}>
|
|
||||||
<TabPane tab="学习成绩" key="1" className={"statisticsTabs1"} >
|
|
||||||
{bomdata===undefined||bomdata===null?"":bomdata.length===0?<NoneData/>:<Table
|
|
||||||
columns={columns}
|
|
||||||
dataSource={bomdata}
|
|
||||||
pagination={false}
|
|
||||||
onChange={this.handleTableChange}
|
|
||||||
/>}
|
|
||||||
</TabPane>
|
|
||||||
<TabPane tab="课堂活跃度" key="2">
|
|
||||||
{course_members===undefined||course_members===null?"":course_members.length===0?<NoneData/>:<Dynamiclist
|
|
||||||
{...this.state}
|
|
||||||
{...this.props}
|
|
||||||
/>}
|
|
||||||
</TabPane>
|
|
||||||
</Tabs>
|
|
||||||
</Spin>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{this.state.all_count===undefined||this.state.all_count===null||this.state.activeKey==="2"?'':this.state.all_count >20&&this.props.isAdmin()===true?<div className="mb40 edu-txt-center padding20-30"
|
|
||||||
|
|
||||||
>
|
|
||||||
|
|
||||||
<Pagination
|
|
||||||
showQuickJumper
|
|
||||||
defaultCurrent={1}
|
|
||||||
pageSize={20}
|
|
||||||
total={this.state.all_count===undefined?0:this.state.all_count===null?0:this.state.all_count}
|
|
||||||
current={this.state.page}
|
|
||||||
onChange={this.PaginationCourse}
|
|
||||||
/>
|
|
||||||
|
|
||||||
</div>:""}
|
|
||||||
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default Statistics;
|
|
|
@ -1,134 +0,0 @@
|
||||||
import React,{ Component } from "react";
|
|
||||||
import axios from 'axios';
|
|
||||||
import '../signin/css/signincdi.css';
|
|
||||||
import Videostatisticscom from './component/Videostatisticscom';
|
|
||||||
import Videostatisticslist from './component/Videostatisticslist';
|
|
||||||
import Videostatisticscomtwo from './component/Videostatisticscomtwo';
|
|
||||||
import Studenticscom from './component/Studenticscom';
|
|
||||||
import Studentstatistics from './component/Studentstatistics';
|
|
||||||
|
|
||||||
|
|
||||||
//在线学习
|
|
||||||
class Videostatistics extends Component{
|
|
||||||
constructor(props){
|
|
||||||
super(props);
|
|
||||||
this.state={
|
|
||||||
watch_staticsdata:[],
|
|
||||||
tisticsbool:false,
|
|
||||||
tisid:null,
|
|
||||||
mytitle:""
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
const myisAdmin= this.props&& this.props.isAdmin();
|
|
||||||
if(myisAdmin===true){
|
|
||||||
this.togetdatas();
|
|
||||||
}else{
|
|
||||||
this.togetdataStudent();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
details=()=>{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
togetdatas(){
|
|
||||||
console.log("视频统计老师");
|
|
||||||
const CourseId=this.props.match.params.coursesId;
|
|
||||||
let url=`/courses/${CourseId}/watch_statics.json`;
|
|
||||||
axios.get(url,{params: {all:true}}).then((response) => {
|
|
||||||
if(response){
|
|
||||||
this.setState({
|
|
||||||
watch_staticsdata:response.data,
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}).catch((error) => {
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
togetdataStudent(){
|
|
||||||
console.log("视频统计学生数据");
|
|
||||||
const CourseId=this.props.match.params.coursesId;
|
|
||||||
let url=`/courses/${CourseId}/watch_statics.json`;
|
|
||||||
axios.get(url).then((response) => {
|
|
||||||
if(response){
|
|
||||||
this.setState({
|
|
||||||
watch_staticsdata:response.data,
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}).catch((error) => {
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
tisticsbools=(bool,id,mytitle)=>{
|
|
||||||
this.setState({
|
|
||||||
tisticsbool:bool,
|
|
||||||
tisid:id,
|
|
||||||
mytitle:mytitle
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render(){
|
|
||||||
let {watch_staticsdata,tisticsbool,tisid,mytitle}= this.state;
|
|
||||||
const isAdmin = this.props&& this.props.isAdmin();
|
|
||||||
|
|
||||||
return(
|
|
||||||
<React.Fragment>
|
|
||||||
<div className="ws100s">
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{
|
|
||||||
tisticsbool===false?
|
|
||||||
<div className="ws100s" style={{
|
|
||||||
position: "relative",
|
|
||||||
}}>
|
|
||||||
{
|
|
||||||
isAdmin?
|
|
||||||
<Videostatisticscom {...this.state} {...this.props} watch_staticsdata={watch_staticsdata} statisticsy={(b)=>this.props.statisticsy(b)}></Videostatisticscom>
|
|
||||||
:
|
|
||||||
<Studenticscom {...this.state} {...this.props} watch_staticsdata={watch_staticsdata} statisticsy={(b)=>this.props.statisticsy(b)}></Studenticscom>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div>
|
|
||||||
{ isAdmin?
|
|
||||||
<Videostatisticslist {...this.state} {...this.props} tisticsbools={(b,id,t)=>this.tisticsbools(b,id,t)}></Videostatisticslist>
|
|
||||||
:
|
|
||||||
<Studentstatistics {...this.state} {...this.props} tisticsbools={(b,id,t)=>this.tisticsbools(b,id,t)}></Studentstatistics>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<Videostatisticscomtwo {...this.state} {...this.props} tisid={tisid} mytitle={mytitle} tisticsbools={(b,id,t)=>this.tisticsbools(b,id,t)}></Videostatisticscomtwo>
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default Videostatistics;
|
|
|
@ -1,119 +0,0 @@
|
||||||
import React, {Component} from "react";
|
|
||||||
import '../../signin/css/signincdi.css';
|
|
||||||
import {Progress, message,Tooltip} from 'antd';
|
|
||||||
import {getImageUrl,formatSeconds} from 'educoder';
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//条目
|
|
||||||
class Studenticscom extends Component {
|
|
||||||
//条目组件
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate = (prevProps) => {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<div className="ws100s edu-back-white sortinxdirection" style={{
|
|
||||||
position: "relative"
|
|
||||||
}}>
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<div className="ws100s teacherentrydivss ">
|
|
||||||
<div className="ws100s sortinxdirection">
|
|
||||||
<p className="sortinxdirection h40s" onClick={()=>this.props.statisticsy(false)} >
|
|
||||||
<i className="iconfont icon-zuojiantou1 font-14 posiivsiconmyss mr5 colorbluesigin xiaoshou h36s" style={{color:'#BBBBBB'}} onClick={()=>this.props.statisticsy(false)} ></i>
|
|
||||||
</p>
|
|
||||||
<div className="ws47s sptits font-18" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}}><span className="ml10">视频统计总览</span></div>
|
|
||||||
<div className="ws50s sptitss xaxisreverseorder">播放数据从{this.props.watch_staticsdata&&this.props.watch_staticsdata.begin_at?this.props.watch_staticsdata.begin_at:0}开始统计</div>
|
|
||||||
</div>
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
.yslsprenshu{
|
|
||||||
background-image: url(${getImageUrl(`images/qiandao/studentbz1.png`)});
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
-moz-background-size:100% 100%;
|
|
||||||
background-size:100% 100%;
|
|
||||||
}
|
|
||||||
.yslspcishu{
|
|
||||||
background-image: url(${getImageUrl(`images/qiandao/studentbz2.png`)});
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
-moz-background-size:100% 100%;
|
|
||||||
background-size:100% 100%;
|
|
||||||
}
|
|
||||||
.yslshipingshi{
|
|
||||||
background-image: url(${getImageUrl(`images/qiandao/studentbz3.png`)});
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
-moz-background-size:100% 100%;
|
|
||||||
background-size:100% 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div className="ws100s spacearound mt10">
|
|
||||||
<div className="yslsprenshu mr30" style={{width:260,height:100}}>
|
|
||||||
<div className="ws100s verticallayout tbrt">
|
|
||||||
<div className="ws100s ts">观看总次数(次)</div>
|
|
||||||
<div className="ws100s tss">{this.props.watch_staticsdata&&this.props.watch_staticsdata.freq?this.props.watch_staticsdata.freq:0}</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="yslspcishu mr30" style={{width:260,height:100}}>
|
|
||||||
<div className="ws100s verticallayout tbrt">
|
|
||||||
<div className="ws100s ts">观看总个数(个)</div>
|
|
||||||
<div className="ws100s tss">{this.props.watch_staticsdata&&this.props.watch_staticsdata.num?this.props.watch_staticsdata.num:0}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="yslshipingshi" style={{width:260,height:100}}>
|
|
||||||
<div className="ws100s verticallayout tbrt">
|
|
||||||
<div className="ws100 ts">总观看时长(时)</div>
|
|
||||||
<Tooltip placement="bottom" title={this.props.watch_staticsdata&&this.props.watch_staticsdata.total_duration?formatSeconds(this.props.watch_staticsdata.total_duration):0}>
|
|
||||||
<div className="maxnamewidth166ss tss">{this.props.watch_staticsdata&&this.props.watch_staticsdata.total_duration?formatSeconds(this.props.watch_staticsdata.total_duration):0}</div>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Studenticscom;
|
|
|
@ -1,350 +0,0 @@
|
||||||
import React, {Component} from "react";
|
|
||||||
import '../../signin/css/signincdi.css';
|
|
||||||
import {Pagination,Table,Spin} from 'antd';
|
|
||||||
import {getImageUrl,sortDirections,formatSeconds} from 'educoder';
|
|
||||||
import axios from 'axios';
|
|
||||||
import LoadingSpin from "../../../../common/LoadingSpin";
|
|
||||||
import NoneDatas from "../../signin/component/NoneDatas";
|
|
||||||
|
|
||||||
|
|
||||||
//条目
|
|
||||||
class Studentstatistics extends Component {
|
|
||||||
//条目组件
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
columnsstu: [
|
|
||||||
{
|
|
||||||
title: '序号',
|
|
||||||
dataIndex: 'number',
|
|
||||||
key: 'number',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14',
|
|
||||||
width: '90px',
|
|
||||||
render: (text, record) => (
|
|
||||||
<span style={{width: '90px'}}>{record.number}</span>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '视频名称',
|
|
||||||
dataIndex: 'title',
|
|
||||||
key: 'title',
|
|
||||||
align: "left",
|
|
||||||
className: 'font-14 maxnamewidth150s',
|
|
||||||
width: '150px',
|
|
||||||
render: (text, record) => (
|
|
||||||
<div style={{width: '150px'}} className="maxnamewidth150s textalignlefts">
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<a className="maxnamewidth150s textalignlefts xiaoshout" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}} title={record.title}>{record.title}</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '观看次数(次)',
|
|
||||||
dataIndex: 'feq',
|
|
||||||
key: 'feq',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14',
|
|
||||||
width: '98px',
|
|
||||||
sorter: true,
|
|
||||||
sortDirections: sortDirections,
|
|
||||||
render: (text, record) => (
|
|
||||||
<span style={{width: '98px'}}>{record.feq}</span>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '观看时长',
|
|
||||||
dataIndex: 'total_duration',
|
|
||||||
key: 'total_duration',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14 maxnamewidth100s',
|
|
||||||
width: '100px',
|
|
||||||
sorter: true,
|
|
||||||
sortDirections: sortDirections,
|
|
||||||
render: (text, record) => (
|
|
||||||
<div style={{width: '100px'}} className="maxnamewidth100s ">
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<a className="maxnamewidth100s xiaoshout" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}} title={record.total_duration}>{record.total_duration}</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '发布人',
|
|
||||||
dataIndex: 'user_name',
|
|
||||||
key: 'user_name',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14 maxnamewidth100s',
|
|
||||||
width: '100px',
|
|
||||||
render: (text, record) => (
|
|
||||||
<span style={{width: '100px'}} className="maxnamewidth100s">
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<a className="maxnamewidth100s xiaoshout" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}} title={record.user_name}>{record.user_name}</a>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '是否看完',
|
|
||||||
dataIndex: 'is_finished',
|
|
||||||
key: 'is_finished',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14',
|
|
||||||
width: '90px',
|
|
||||||
render: (text, record) => (
|
|
||||||
<span style={{width: '90px'}}>{record.is_finished === true ?
|
|
||||||
<span style={{color: "#333333"}}>是</span> : <span style={{color: "#E02020"}}>否</span>}</span>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
loading:false,
|
|
||||||
data:[],
|
|
||||||
page:1,
|
|
||||||
limit:20,
|
|
||||||
members_count:0,
|
|
||||||
order:undefined,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
let data={
|
|
||||||
page:1,
|
|
||||||
order:this.state.order
|
|
||||||
}
|
|
||||||
this.togetdatas(data);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate = (prevProps) => {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
paginationonChange = (pageNumber) => {
|
|
||||||
this.setState({
|
|
||||||
page: pageNumber,
|
|
||||||
})
|
|
||||||
let data={
|
|
||||||
page:pageNumber,
|
|
||||||
order:this.state.order
|
|
||||||
}
|
|
||||||
this.togetdatas(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
togetdatas(data){
|
|
||||||
this.setState({
|
|
||||||
loading:true
|
|
||||||
})
|
|
||||||
const CourseId=this.props.match.params.coursesId;
|
|
||||||
let url=`/courses/${CourseId}/own_watch_histories.json`;
|
|
||||||
axios.get(url,{params:data
|
|
||||||
}).then((response) => {
|
|
||||||
if (response) {
|
|
||||||
if (response.data) {
|
|
||||||
if (response.data.data.length > 0) {
|
|
||||||
let datalists = [];
|
|
||||||
for (var i = 0; i < response.data.data.length; i++) {
|
|
||||||
datalists.push({
|
|
||||||
number: (parseInt(this.state.page) - 1) * parseInt(this.state.limit) + (i + 1),
|
|
||||||
title: response.data.data[i].title,
|
|
||||||
user_name: response.data.data[i].user_name,
|
|
||||||
is_finished: response.data.data[i].is_finished,
|
|
||||||
total_duration:response.data.data[i].total_duration?formatSeconds(response.data.data[i].total_duration):0,
|
|
||||||
feq:response.data.data[i].freq,
|
|
||||||
start_at:response.data.data[i].start_at,
|
|
||||||
end_at:response.data.data[i].end_at,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
data: datalists,
|
|
||||||
members_count: response.data.count,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
data: [],
|
|
||||||
members_count: response.data.count,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
data: [],
|
|
||||||
members_count: response.data.count,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
loading:false
|
|
||||||
})
|
|
||||||
}).catch((error) => {
|
|
||||||
this.setState({
|
|
||||||
loading:false
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//实训作业tbale 列表塞选数据
|
|
||||||
table1handleChange = (pagination, filters, sorter) => {
|
|
||||||
if (JSON.stringify(sorter) === "{}") {
|
|
||||||
//没有选择
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
//学生学号排序
|
|
||||||
if (sorter.columnKey === "feq"||sorter.columnKey === "total_duration") {
|
|
||||||
let mysorder="";
|
|
||||||
if (sorter.order === "ascend") {
|
|
||||||
if(sorter.columnKey === "feq"){
|
|
||||||
mysorder="freq-asc";
|
|
||||||
}else{
|
|
||||||
mysorder="total_duration-asc";
|
|
||||||
|
|
||||||
}
|
|
||||||
//升序
|
|
||||||
let data={
|
|
||||||
page:this.state.page,
|
|
||||||
order:mysorder
|
|
||||||
}
|
|
||||||
this.togetdatas(data);
|
|
||||||
this.setState({
|
|
||||||
order: mysorder,
|
|
||||||
})
|
|
||||||
} else if (sorter.order === "descend") {
|
|
||||||
if(sorter.columnKey === "feq"){
|
|
||||||
mysorder="freq-desc";
|
|
||||||
}else{
|
|
||||||
mysorder="total_duration-desc";
|
|
||||||
|
|
||||||
}
|
|
||||||
//降序
|
|
||||||
let data={
|
|
||||||
page:this.state.page,
|
|
||||||
order:mysorder
|
|
||||||
}
|
|
||||||
this.togetdatas(data);
|
|
||||||
this.setState({
|
|
||||||
order: mysorder,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let {loading,data,columnsstu,page,members_count,limit}=this.state;
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<div className="ws100s mt20">
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<div className="ws100s edu-back-white">
|
|
||||||
<div className="ws100s teacherentrydivss pd15s">
|
|
||||||
<div className="ws100s sortinxdirection">
|
|
||||||
<div className="ws100s sptits font-18">统计列表</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
.ysltableo .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
|
|
||||||
padding: 10px 5px;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div className="ws100s ysltableo teacherentrydivs pdinstop0" style={{ minHeight: "400px"}}>
|
|
||||||
{
|
|
||||||
data&&data.length===0?
|
|
||||||
<div style={{
|
|
||||||
minHeight: "400px",
|
|
||||||
}} className="ws100s">
|
|
||||||
<NoneDatas></NoneDatas>
|
|
||||||
</div>
|
|
||||||
: data&&data.length>0?
|
|
||||||
<Spin spinning={loading}>
|
|
||||||
<Table
|
|
||||||
columns={columnsstu}
|
|
||||||
dataSource={data}
|
|
||||||
pagination={false}
|
|
||||||
onChange={this.table1handleChange}
|
|
||||||
/>
|
|
||||||
</Spin>:
|
|
||||||
""
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb30 clearfix educontent mt40 intermediatecenter">
|
|
||||||
{
|
|
||||||
data&&data.length>0?
|
|
||||||
<Pagination showQuickJumper current={this.state.page} onChange={this.paginationonChange}
|
|
||||||
pageSize={this.state.limit}
|
|
||||||
total={this.state.members_count}></Pagination>
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Studentstatistics;
|
|
|
@ -1,119 +0,0 @@
|
||||||
import React, {Component} from "react";
|
|
||||||
import '../../signin/css/signincdi.css';
|
|
||||||
import {Progress, message,Tooltip} from 'antd';
|
|
||||||
import {getImageUrl,formatSeconds} from 'educoder';
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//条目
|
|
||||||
class Videostatisticscom extends Component {
|
|
||||||
//条目组件
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate = (prevProps) => {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<div className="ws100s edu-back-white sortinxdirection" style={{
|
|
||||||
position: "relative"
|
|
||||||
}}>
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<div className="ws100s teacherentrydivss ">
|
|
||||||
<div className="ws100s sortinxdirection">
|
|
||||||
<p className="sortinxdirection h40s" onClick={()=>this.props.statisticsy(false)} >
|
|
||||||
<i className="iconfont icon-zuojiantou1 font-14 posiivsiconmyss mr5 colorbluesigin xiaoshou h36s" style={{color:'#BBBBBB'}} onClick={()=>this.props.statisticsy(false)} ></i>
|
|
||||||
</p>
|
|
||||||
<div className="ws47s sptits font-18" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}}><span className="ml10">视频统计总览</span></div>
|
|
||||||
<div className="ws50s sptitss xaxisreverseorder">播放数据从{this.props.watch_staticsdata&&this.props.watch_staticsdata.begin_at?this.props.watch_staticsdata.begin_at:0}开始统计</div>
|
|
||||||
</div>
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
.yslsprenshu{
|
|
||||||
background-image: url(${getImageUrl(`images/qiandao/sprenshu.png`)});
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
-moz-background-size:100% 100%;
|
|
||||||
background-size:100% 100%;
|
|
||||||
}
|
|
||||||
.yslspcishu{
|
|
||||||
background-image: url(${getImageUrl(`images/qiandao/spcishu.png`)});
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
-moz-background-size:100% 100%;
|
|
||||||
background-size:100% 100%;
|
|
||||||
}
|
|
||||||
.yslshipingshi{
|
|
||||||
background-image: url(${getImageUrl(`images/qiandao/shipingshi.png`)});
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
-moz-background-size:100% 100%;
|
|
||||||
background-size:100% 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div className="ws100s spacearound mt10">
|
|
||||||
<div className="yslsprenshu mr30" style={{width:260,height:100}}>
|
|
||||||
<div className="ws100s verticallayout tbrt">
|
|
||||||
<div className="ws100s ts">观看总人数(人)</div>
|
|
||||||
<div className="ws100s tss">{this.props.watch_staticsdata&&this.props.watch_staticsdata.num?this.props.watch_staticsdata.num:0}</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="yslspcishu mr30" style={{width:260,height:100}}>
|
|
||||||
<div className="ws100s verticallayout tbrt">
|
|
||||||
<div className="ws100s ts">观看总人次(次)</div>
|
|
||||||
<div className="ws100s tss">{this.props.watch_staticsdata&&this.props.watch_staticsdata.freq?this.props.watch_staticsdata.freq:0}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="yslshipingshi" style={{width:260,height:100}}>
|
|
||||||
<div className="ws100s verticallayout tbrt">
|
|
||||||
<div className="ws100 ts">总观看时长(时)</div>
|
|
||||||
<Tooltip placement="bottom" title={this.props.watch_staticsdata&&this.props.watch_staticsdata.total_duration?formatSeconds(this.props.watch_staticsdata.total_duration):0}>
|
|
||||||
<div className="maxnamewidth166ss tss">{this.props.watch_staticsdata&&this.props.watch_staticsdata.total_duration?formatSeconds(this.props.watch_staticsdata.total_duration):0}</div>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Videostatisticscom;
|
|
|
@ -1,641 +0,0 @@
|
||||||
import React, {Component} from "react";
|
|
||||||
import '../../signin/css/signincdi.css';
|
|
||||||
import {Pagination, Table, Menu, Dropdown,Spin} from 'antd';
|
|
||||||
import {getImageUrl, sortDirections,formatSeconds} from 'educoder';
|
|
||||||
import axios from 'axios';
|
|
||||||
import LoadingSpin from "../../../../common/LoadingSpin";
|
|
||||||
import NoneDatas from "../../signin/component/NoneDatas";
|
|
||||||
import moment from 'moment';
|
|
||||||
|
|
||||||
|
|
||||||
//条目
|
|
||||||
class Videostatisticscomtwo extends Component {
|
|
||||||
//条目组件
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
data: [],
|
|
||||||
page: 1,
|
|
||||||
limit: 20,
|
|
||||||
members_count: 0,
|
|
||||||
columnsstu: [
|
|
||||||
{
|
|
||||||
title: '序号',
|
|
||||||
dataIndex: 'number',
|
|
||||||
key: 'number',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14',
|
|
||||||
width: '50px',
|
|
||||||
render: (text, record) => (
|
|
||||||
<div style={{width: '50px'}}>{record.number}</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '用户',
|
|
||||||
dataIndex: 'user_name',
|
|
||||||
key: 'user_name',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14 maxnamewidth100s',
|
|
||||||
width: '100px',
|
|
||||||
render: (text, record) => (
|
|
||||||
<div style={{width: "100px",wordWrap: 'break-word', wordBreak: 'break-word'}} className="maxnamewidth100s">
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<a className="maxnamewidth100s xiaoshout" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}} title={record.user_name}>{record.user_name}</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '是否看完',
|
|
||||||
dataIndex: 'is_finished',
|
|
||||||
key: 'is_finished',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14 maxnamewidth90s',
|
|
||||||
width: '90px',
|
|
||||||
render: (text, record) => (
|
|
||||||
<div style={{width: '90px'}} className="maxnamewidth90s">{record.is_finished === true ?
|
|
||||||
<span style={{color: "#333333"}}>是</span> : <span style={{color: "#E02020"}}>否</span>}</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '观看时长',
|
|
||||||
dataIndex: 'total_duration',
|
|
||||||
key: 'total_duration',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14 maxnamewidth100s',
|
|
||||||
width: '100px',
|
|
||||||
sorter: true,
|
|
||||||
sortDirections: sortDirections,
|
|
||||||
render: (text, record) => (
|
|
||||||
<div style={{width: '100px'}} className="maxnamewidth100s">
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<a className="maxnamewidth100s xiaoshout" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}} title={record.total_duration}>{record.total_duration}</a></div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '观看次数',
|
|
||||||
dataIndex: 'feq',
|
|
||||||
key: 'feq',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14 maxnamewidth100s',
|
|
||||||
width: '100px',
|
|
||||||
sorter: true,
|
|
||||||
sortDirections: sortDirections,
|
|
||||||
render: (text, record) => (
|
|
||||||
<div style={{width: '100px'}} className="maxnamewidth100s">
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<a className="maxnamewidth100s xiaoshout" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}} title={record.feq}>{record.feq}</a>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '最早观看时间',
|
|
||||||
dataIndex: 'start_at',
|
|
||||||
key: 'start_at',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14 ',
|
|
||||||
render: (text, record) => (
|
|
||||||
<div>
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{
|
|
||||||
record.start_at?
|
|
||||||
<a className="xiaoshout" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}} title={moment(record.start_at).format('YYYY-MM-DD HH:mm:ss')}>{moment(record.start_at).format('YYYY-MM-DD HH:mm:ss')}</a>
|
|
||||||
:
|
|
||||||
<span style={{color:"#333333"}}>--</span>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '最后观看时间',
|
|
||||||
dataIndex: 'end_at',
|
|
||||||
key: 'end_at',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14 ',
|
|
||||||
render: (text, record) => (
|
|
||||||
<div>
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{
|
|
||||||
record.end_at?
|
|
||||||
<a className="xiaoshout" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}} title={moment(record.end_at).format('YYYY-MM-DD HH:mm:ss')}>{moment(record.end_at).format('YYYY-MM-DD HH:mm:ss')}</a>
|
|
||||||
:
|
|
||||||
<span style={{color:"#333333"}}>--</span>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
}
|
|
||||||
],
|
|
||||||
loading: false,
|
|
||||||
order: undefined,
|
|
||||||
course_groups: [],
|
|
||||||
fbbool: false,
|
|
||||||
groupsid: null,
|
|
||||||
none_group_member_count:0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.setState({
|
|
||||||
order: undefined
|
|
||||||
})
|
|
||||||
if (this.props.isAdmin()) {
|
|
||||||
//老师
|
|
||||||
const CourseId = this.props.match.params.coursesId;
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
id: CourseId,
|
|
||||||
page: this.state.page,
|
|
||||||
}
|
|
||||||
this.getdatas(data);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//学生
|
|
||||||
var data = {
|
|
||||||
page: this.state.page,
|
|
||||||
}
|
|
||||||
this.getdatas(data);
|
|
||||||
}
|
|
||||||
this.fenbans();
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate = (prevProps) => {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//分班
|
|
||||||
fenbans = () => {
|
|
||||||
const CourseId = this.props.match.params.coursesId;
|
|
||||||
let url = `/courses/${CourseId}/course_groups.json`;
|
|
||||||
axios.get(url).then((response) => {
|
|
||||||
if (response) {
|
|
||||||
// console.log("分班");
|
|
||||||
// console.log("response");
|
|
||||||
// console.log(response);
|
|
||||||
this.setState({
|
|
||||||
course_groups: response.data.course_groups,
|
|
||||||
current_group_id: response.data.current_group_id,
|
|
||||||
none_group_member_count: response.data.none_group_member_count,
|
|
||||||
group_count: response.data.group_count,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}).catch((error) => {
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//学生
|
|
||||||
getdatas = (data) => {
|
|
||||||
this.setState({
|
|
||||||
loading: true
|
|
||||||
})
|
|
||||||
const CourseId = this.props.match.params.coursesId;
|
|
||||||
let url = "";
|
|
||||||
if (this.props.isAdmin()) {
|
|
||||||
url = `/course_videos/${this.props.tisid}/watch_histories.json`;
|
|
||||||
} else {
|
|
||||||
url = `/courses/${CourseId}/own_watch_histories.json`;
|
|
||||||
}
|
|
||||||
axios.get(url, {params: data}).then((response) => {
|
|
||||||
if (response) {
|
|
||||||
if (response.data) {
|
|
||||||
if (response.data.data.length > 0) {
|
|
||||||
let datalists = [];
|
|
||||||
for (var i = 0; i < response.data.data.length; i++) {
|
|
||||||
datalists.push({
|
|
||||||
number: (parseInt(this.state.page) - 1) * parseInt(this.state.limit) + (i + 1),
|
|
||||||
user_name: response.data.data[i].user_name,
|
|
||||||
is_finished: response.data.data[i].is_finished,
|
|
||||||
total_duration: response.data.data[i].total_duration?formatSeconds(response.data.data[i].total_duration):0,
|
|
||||||
feq: response.data.data[i].feq,
|
|
||||||
start_at: response.data.data[i].start_at?response.data.data[i].start_at:null,
|
|
||||||
end_at: response.data.data[i].end_at?response.data.data[i].end_at:null,
|
|
||||||
title: response.data.data[i].title,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
data: datalists,
|
|
||||||
members_count: response.data.count,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
data: [],
|
|
||||||
members_count: response.data.count,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
data: [],
|
|
||||||
members_count: response.data.count,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
loading: false
|
|
||||||
})
|
|
||||||
}).catch((error) => {
|
|
||||||
this.setState({
|
|
||||||
loading: false
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
paginationonChange = (pageNumber) => {
|
|
||||||
this.setState({
|
|
||||||
page: pageNumber,
|
|
||||||
})
|
|
||||||
let data = {}
|
|
||||||
if (this.props.isAdmin()) {
|
|
||||||
//老师
|
|
||||||
const CourseId = this.props.match.params.coursesId;
|
|
||||||
data = {
|
|
||||||
id: CourseId,
|
|
||||||
page: pageNumber,
|
|
||||||
group_id: this.state.groupsid,
|
|
||||||
order: this.state.order,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//学生
|
|
||||||
data = {
|
|
||||||
page: pageNumber,
|
|
||||||
order: this.state.order,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.getdatas(data);
|
|
||||||
}
|
|
||||||
fenbanone = () => {
|
|
||||||
if (this.state.fbbool === false) {
|
|
||||||
this.setState({
|
|
||||||
fbbool: true
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
fbbool: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setcourse_groups = (id) => {
|
|
||||||
this.setState({
|
|
||||||
groupsid: id
|
|
||||||
})
|
|
||||||
//老师
|
|
||||||
const CourseId = this.props.match.params.coursesId;
|
|
||||||
|
|
||||||
var data = {};
|
|
||||||
if (id) {
|
|
||||||
data = {
|
|
||||||
id: CourseId,
|
|
||||||
page: this.state.page,
|
|
||||||
group_id: id
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
if(id!==null&&id===0){
|
|
||||||
data = {
|
|
||||||
id: CourseId,
|
|
||||||
page: this.state.page,
|
|
||||||
group_id: id
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
data = {
|
|
||||||
id: CourseId,
|
|
||||||
page: this.state.page
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}catch (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
this.getdatas(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//实训作业tbale 列表塞选数据
|
|
||||||
table1handleChange = (pagination, filters, sorter) => {
|
|
||||||
if (JSON.stringify(sorter) === "{}") {
|
|
||||||
//没有选择
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
//学生学号排序
|
|
||||||
if (sorter.columnKey === "total_duration" || sorter.columnKey === "feq") {
|
|
||||||
let mysorder = "";
|
|
||||||
if (sorter.order === "ascend") {
|
|
||||||
if (sorter.columnKey === "total_duration") {
|
|
||||||
mysorder = "total_duration-asc";
|
|
||||||
} else {
|
|
||||||
mysorder = "freq-asc";
|
|
||||||
|
|
||||||
}
|
|
||||||
//升序
|
|
||||||
let data = {}
|
|
||||||
if (this.props.isAdmin()) {
|
|
||||||
//老师
|
|
||||||
const CourseId = this.props.match.params.coursesId;
|
|
||||||
if (this.state.groupsid) {
|
|
||||||
data = {
|
|
||||||
id: CourseId,
|
|
||||||
page: this.state.page,
|
|
||||||
group_id: this.state.groupsid,
|
|
||||||
order: mysorder,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data = {
|
|
||||||
id: CourseId,
|
|
||||||
page: this.state.page,
|
|
||||||
order: mysorder,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//学生
|
|
||||||
data = {
|
|
||||||
page: this.state.page,
|
|
||||||
order: mysorder,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getdatas(data);
|
|
||||||
this.setState({
|
|
||||||
order: mysorder,
|
|
||||||
})
|
|
||||||
} else if (sorter.order === "descend") {
|
|
||||||
if (sorter.columnKey === "total_duration") {
|
|
||||||
mysorder = "total_duration-desc";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
mysorder = "freq-desc";
|
|
||||||
|
|
||||||
}
|
|
||||||
//降序
|
|
||||||
let data = {}
|
|
||||||
if (this.props.isAdmin()) {
|
|
||||||
//老师
|
|
||||||
const CourseId = this.props.match.params.coursesId;
|
|
||||||
if (this.state.groupsid) {
|
|
||||||
data = {
|
|
||||||
id: CourseId,
|
|
||||||
page: this.state.page,
|
|
||||||
group_id: this.state.groupsid,
|
|
||||||
order: mysorder,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data = {
|
|
||||||
id: CourseId,
|
|
||||||
page: this.state.page,
|
|
||||||
order: mysorder,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//学生
|
|
||||||
data = {
|
|
||||||
page: this.state.page,
|
|
||||||
order: mysorder,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getdatas(data);
|
|
||||||
this.setState({
|
|
||||||
order: mysorder,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let {loading, data, page, limit, members_count, columnsstu, fbbool, course_groups} = this.state;
|
|
||||||
const isAdmin = this.props&& this.props.isAdmin();
|
|
||||||
|
|
||||||
const menu = (
|
|
||||||
<Menu>
|
|
||||||
<Menu.Item>
|
|
||||||
<a onClick={() => this.setcourse_groups(null)}>
|
|
||||||
<p className="maxnamewidth200yss">全部</p>
|
|
||||||
</a>
|
|
||||||
</Menu.Item>
|
|
||||||
{
|
|
||||||
course_groups && course_groups.length > 0 ?
|
|
||||||
(
|
|
||||||
course_groups.map((item, key) => {
|
|
||||||
return (
|
|
||||||
<Menu.Item>
|
|
||||||
<a onClick={() => this.setcourse_groups(item.id)} key={key}>
|
|
||||||
<p className="maxnamewidth200yss">{item.name}</p>
|
|
||||||
</a>
|
|
||||||
</Menu.Item>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
:
|
|
||||||
""
|
|
||||||
}
|
|
||||||
{
|
|
||||||
this.state.none_group_member_count&&this.state.none_group_member_count>0?
|
|
||||||
<Menu.Item>
|
|
||||||
<a onClick={() => this.setcourse_groups(0)}>
|
|
||||||
<p className="maxnamewidth200yss">未分班</p>
|
|
||||||
</a>
|
|
||||||
</Menu.Item>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
}
|
|
||||||
</Menu>
|
|
||||||
);
|
|
||||||
|
|
||||||
let mytitle="";
|
|
||||||
if(isAdmin){
|
|
||||||
mytitle=this.props&&this.props.mytitle;
|
|
||||||
|
|
||||||
}else{
|
|
||||||
if(this.state.data){
|
|
||||||
if(this.state.data.length>0){
|
|
||||||
try {
|
|
||||||
if(this.state.data[0].title){
|
|
||||||
mytitle=this.state.data[0].title;
|
|
||||||
}
|
|
||||||
}catch (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<div className="ws100s">
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{
|
|
||||||
text-decoration:none !important;
|
|
||||||
}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<div className="ws100s teacherentrydivss edu-back-white ">
|
|
||||||
<div className="ws100s sortinxdirection">
|
|
||||||
<p className="sortinxdirection h40s" onClick={() => this.props.tisticsbools(false, null)} >
|
|
||||||
<i className="iconfont icon-zuojiantou1 font-14 posiivsiconmyss mr5 colorbluesigin xiaoshou h36s" style={{color:'#BBBBBB'}} ></i>
|
|
||||||
</p>
|
|
||||||
<div className="ws50s sptits font-18">
|
|
||||||
<div className="ml10">{mytitle}</div>
|
|
||||||
</div>
|
|
||||||
<div className="ws50s sptitss xaxisreverseorder font-14" style={{
|
|
||||||
color: "#5091FF",
|
|
||||||
lineHeight: "42px",
|
|
||||||
}}>
|
|
||||||
{/*{*/}
|
|
||||||
{/* isAdmin === true ?*/}
|
|
||||||
{/* <div className="xiaoshou ml32" onClick={() => this.props.tisticsbools(false, null)}>*/}
|
|
||||||
{/* <span className="mr5 xiaoshou">视频统计总览</span><i className="iconfont icon-fanhui font-13 xiaoshou"></i>*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/* :""*/}
|
|
||||||
{/*}*/}
|
|
||||||
|
|
||||||
{
|
|
||||||
isAdmin === true ?
|
|
||||||
<div className="xiaoshou" onClick={() => this.fenbanone()}>
|
|
||||||
<Dropdown getPopupContainer={trigger => trigger.parentNode} overlay={menu}
|
|
||||||
placement="bottomLeft">
|
|
||||||
<span>
|
|
||||||
<span className="mr5 xiaoshou">分班</span>
|
|
||||||
{
|
|
||||||
fbbool === true ?
|
|
||||||
<i className="iconfont icon-sanjiaoxing-up font-13 xiaoshou"></i>
|
|
||||||
:
|
|
||||||
<i className="iconfont icon-sanjiaoxing-down font-13 xiaoshou"></i>
|
|
||||||
}
|
|
||||||
</span>
|
|
||||||
</Dropdown>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
.ysltableo .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
|
|
||||||
padding: 10px 5px;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div className="ws100s ysltableo mt10" style={{ minHeight: "400px"}}>
|
|
||||||
{
|
|
||||||
data.length === 0 ?
|
|
||||||
<div style={{
|
|
||||||
minHeight: "400px",
|
|
||||||
}} className="ws100s">
|
|
||||||
<NoneDatas></NoneDatas>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<Spin spinning={loading}>
|
|
||||||
<Table
|
|
||||||
columns={columnsstu}
|
|
||||||
dataSource={data}
|
|
||||||
pagination={false}
|
|
||||||
onChange={this.table1handleChange}
|
|
||||||
/>
|
|
||||||
</Spin>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb30 clearfix educontent mt40 intermediatecenter">
|
|
||||||
{
|
|
||||||
data && data.length > 0 ?
|
|
||||||
<Pagination showQuickJumper current={this.state.page} onChange={this.paginationonChange}
|
|
||||||
pageSize={this.state.limit}
|
|
||||||
total={this.state.members_count}></Pagination>
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Videostatisticscomtwo;
|
|
|
@ -1,350 +0,0 @@
|
||||||
import React, {Component} from "react";
|
|
||||||
import '../../signin/css/signincdi.css';
|
|
||||||
import {Pagination,Table,Spin} from 'antd';
|
|
||||||
import {getImageUrl,sortDirections,formatSeconds} from 'educoder';
|
|
||||||
import axios from 'axios';
|
|
||||||
import LoadingSpin from "../../../../common/LoadingSpin";
|
|
||||||
import NoneDatas from "../../signin/component/NoneDatas";
|
|
||||||
|
|
||||||
|
|
||||||
//条目
|
|
||||||
class Videostatisticslist extends Component {
|
|
||||||
//条目组件
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
columnsstu: [
|
|
||||||
{
|
|
||||||
title: '序号',
|
|
||||||
dataIndex: 'number',
|
|
||||||
key: 'number',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14',
|
|
||||||
width: '100px',
|
|
||||||
render: (text, record) => (
|
|
||||||
<span style={{width: '100px'}}>{record.number}</span>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '视频名称',
|
|
||||||
dataIndex: 'title',
|
|
||||||
key: 'title',
|
|
||||||
align: "left",
|
|
||||||
className: 'font-14 width200s widh150wpos',
|
|
||||||
width:200,
|
|
||||||
render: (text, record) => (
|
|
||||||
<div className="maxnamewidth200ss textalignlefts" style={{ wordWrap: 'break-word', wordBreak: 'break-word' }}>
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<a className="maxnamewidth200ss textalignlefts xiaoshout" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}} title={record.title}>{record.title}</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '观看人数',
|
|
||||||
dataIndex: 'people_num',
|
|
||||||
key: 'people_num',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14 width150s',
|
|
||||||
sorter: true,
|
|
||||||
sortDirections: sortDirections,
|
|
||||||
width:150,
|
|
||||||
render: (text, record) => (
|
|
||||||
<span>{record.people_num}</span>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '观看时长',
|
|
||||||
dataIndex: 'total_time',
|
|
||||||
key: 'total_time',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14 width100s ',
|
|
||||||
sorter: true,
|
|
||||||
sortDirections: sortDirections,
|
|
||||||
width:100,
|
|
||||||
render: (text, record) => (
|
|
||||||
<div className="maxnamewidth100s ">
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<a className="maxnamewidth100s xiaoshout" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}} title={record.total_time}>{record.total_time}</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '发布人',
|
|
||||||
dataIndex: 'user_name',
|
|
||||||
key: 'user_name',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14 width150s',
|
|
||||||
width:150,
|
|
||||||
render: (text, record) => (
|
|
||||||
<span className="maxnamewidth150ss">
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{text-decoration:none !important;}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<a className="maxnamewidth150ss xiaoshout" style={{
|
|
||||||
color:"#333333"
|
|
||||||
}} title={record.user_name}>{record.user_name}</a>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '详情',
|
|
||||||
dataIndex: 'id',
|
|
||||||
key: 'id',
|
|
||||||
align: "center",
|
|
||||||
className: 'font-14',
|
|
||||||
render: (text, record) => (
|
|
||||||
<span style={{color:'#5091FF'}} className="xiaoshou" onClick={()=>this.props.tisticsbools(true,record.id,record.title)}>详情</span>
|
|
||||||
),
|
|
||||||
}
|
|
||||||
],
|
|
||||||
loading:false,
|
|
||||||
data:[],
|
|
||||||
page:1,
|
|
||||||
limit:20,
|
|
||||||
members_count:0,
|
|
||||||
order:undefined,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
let data={
|
|
||||||
page:1,
|
|
||||||
order:this.state.order
|
|
||||||
}
|
|
||||||
this.togetdatas(data);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate = (prevProps) => {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
paginationonChange = (pageNumber) => {
|
|
||||||
this.setState({
|
|
||||||
page: pageNumber,
|
|
||||||
})
|
|
||||||
let data={
|
|
||||||
page:pageNumber,
|
|
||||||
order:this.state.order
|
|
||||||
}
|
|
||||||
this.togetdatas(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
togetdatas(data){
|
|
||||||
this.setState({
|
|
||||||
loading:true
|
|
||||||
})
|
|
||||||
const CourseId=this.props.match.params.coursesId;
|
|
||||||
let url=`/courses/${CourseId}/watch_video_histories.json`;
|
|
||||||
axios.get(url,{params:data
|
|
||||||
}).then((response) => {
|
|
||||||
if (response) {
|
|
||||||
if (response.data) {
|
|
||||||
if (response.data.videos.length > 0) {
|
|
||||||
let datalists = [];
|
|
||||||
for (var i = 0; i < response.data.videos.length; i++) {
|
|
||||||
datalists.push({
|
|
||||||
number: (parseInt(this.state.page) - 1) * parseInt(this.state.limit) + (i + 1),
|
|
||||||
title: response.data.videos[i].title,
|
|
||||||
people_num: response.data.videos[i].people_num,
|
|
||||||
total_time: response.data.videos[i].total_time?formatSeconds(response.data.videos[i].total_time):0,
|
|
||||||
user_name: response.data.videos[i].user_name,
|
|
||||||
id: response.data.videos[i].id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
data: datalists,
|
|
||||||
members_count: response.data.count,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
data: [],
|
|
||||||
members_count: response.data.count,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
data: [],
|
|
||||||
members_count: response.data.count,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
loading:false
|
|
||||||
})
|
|
||||||
}).catch((error) => {
|
|
||||||
this.setState({
|
|
||||||
loading:false
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//实训作业tbale 列表塞选数据
|
|
||||||
table1handleChange = (pagination, filters, sorter) => {
|
|
||||||
if (JSON.stringify(sorter) === "{}") {
|
|
||||||
//没有选择
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
//学生学号排序
|
|
||||||
if (sorter.columnKey === "people_num"||sorter.columnKey === "total_time") {
|
|
||||||
let mysorder="";
|
|
||||||
if (sorter.order === "ascend") {
|
|
||||||
if(sorter.columnKey === "people_num"){
|
|
||||||
mysorder="people_num-asc";
|
|
||||||
}else{
|
|
||||||
mysorder="total_time-asc";
|
|
||||||
|
|
||||||
}
|
|
||||||
//升序
|
|
||||||
let data={
|
|
||||||
page:this.state.page,
|
|
||||||
order:mysorder
|
|
||||||
}
|
|
||||||
this.togetdatas(data);
|
|
||||||
this.setState({
|
|
||||||
order: mysorder,
|
|
||||||
})
|
|
||||||
} else if (sorter.order === "descend") {
|
|
||||||
if(sorter.columnKey === "people_num"){
|
|
||||||
mysorder="people_num-desc";
|
|
||||||
}else{
|
|
||||||
mysorder="total_time-desc";
|
|
||||||
|
|
||||||
}
|
|
||||||
//降序
|
|
||||||
let data={
|
|
||||||
page:this.state.page,
|
|
||||||
order:mysorder
|
|
||||||
}
|
|
||||||
this.togetdatas(data);
|
|
||||||
this.setState({
|
|
||||||
order: mysorder,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let {loading,data,columnsstu,page,members_count,limit}=this.state;
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<div className="ws100s mt20">
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
a{
|
|
||||||
text-decoration:none !important;
|
|
||||||
}
|
|
||||||
a:hover {text-decoration: none !important;}
|
|
||||||
a:active{text-decoration:none !important;}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<div className="ws100s edu-back-white">
|
|
||||||
<div className="ws100s teacherentrydivss pd15s">
|
|
||||||
<div className="ws100s sortinxdirection">
|
|
||||||
<div className="ws100s sptits font-18">统计列表</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
.ysltableo .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
|
|
||||||
padding: 10px 10px;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div className="ws100s ysltableo teacherentrydivs pdinstop0" style={{ minHeight: "400px"}}>
|
|
||||||
{
|
|
||||||
data&&data.length===0?
|
|
||||||
<div style={{
|
|
||||||
minHeight: "400px",
|
|
||||||
}} className="ws100s">
|
|
||||||
<NoneDatas></NoneDatas>
|
|
||||||
</div>
|
|
||||||
: data&&data.length>0?
|
|
||||||
<Spin spinning={loading}>
|
|
||||||
<Table
|
|
||||||
columns={columnsstu}
|
|
||||||
dataSource={data}
|
|
||||||
pagination={false}
|
|
||||||
onChange={this.table1handleChange}
|
|
||||||
|
|
||||||
/>
|
|
||||||
</Spin>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb30 clearfix educontent mt40 intermediatecenter">
|
|
||||||
{
|
|
||||||
data&&data.length>0?
|
|
||||||
<Pagination showQuickJumper current={this.state.page} onChange={this.paginationonChange}
|
|
||||||
pageSize={this.state.limit}
|
|
||||||
total={this.state.members_count}></Pagination>
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Videostatisticslist;
|
|
|
@ -156,16 +156,7 @@ class Loginqq extends Component {
|
||||||
return (
|
return (
|
||||||
<div style={newContainer} className=" clearfix" >
|
<div style={newContainer} className=" clearfix" >
|
||||||
<Spin size="large" spinning={spinnings} >
|
<Spin size="large" spinning={spinnings} >
|
||||||
<style>
|
|
||||||
{
|
|
||||||
`
|
|
||||||
#root{
|
|
||||||
background:#fff !important;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div style={{
|
<div style={{
|
||||||
"width": "100%"
|
"width": "100%"
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
import React, { Component } from 'react';
|
|
||||||
|
|
||||||
import { Redirect } from 'react-router';
|
|
||||||
|
|
||||||
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
|
|
||||||
|
|
||||||
import Loading from '../../Loading'
|
|
||||||
|
|
||||||
import Loadable from 'react-loadable';
|
|
||||||
import { TPMIndexHOC } from '../tpm/TPMIndexHOC'
|
|
||||||
import { SnackbarHOC } from 'educoder'
|
|
||||||
|
|
||||||
|
|
||||||
const PackageIndex = Loadable({
|
|
||||||
loader: () => import('../user/usersInfo/InfosTopics'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
class Topic_bank extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props)
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount(){
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className="newMain clearfix">
|
|
||||||
|
|
||||||
<Switch>
|
|
||||||
<Route path="/topicbank/:username/:topicstype"
|
|
||||||
render={
|
|
||||||
(props) => (<PackageIndex {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
|
|
||||||
<Route path="/topicbank/:topicstype"
|
|
||||||
render={
|
|
||||||
(props) => (<PackageIndex {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
</Switch>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SnackbarHOC() (TPMIndexHOC (Topic_bank)) ;
|
|
Loading…
Reference in New Issue