Merge branch 'ysm1' of https://bdgit.educoder.net/Hjqreturn/educoder into yslcompetition

dev_sync_trustie
杨树林 5 years ago
commit 582fc40632

@ -5,8 +5,7 @@ $(document).on('turbolinks:load', function(){
autoclose: true,
language: 'zh-CN',
format: 'yyyy-mm-dd',
startDate: '2017-04-01',
endDate: '-1d'
startDate: '2017-04-01'
};
var defineDateRangeSelect = function(element){
@ -19,5 +18,74 @@ $(document).on('turbolinks:load', function(){
};
defineDateRangeSelect('.teaching-mode-date');
defineDateRangeSelect('.competition-start-end-date');
var $basicForm = $('form.basic-setting-form');
$basicForm.validate({
errorElement: 'span',
errorClass: 'danger text-danger',
rules: {
name: "required",
subTitle: "required",
startTime: "required",
endTime: "required",
mode: "required",
identifier: "required"
}
});
// 保存按钮
$basicForm.on('click', ".submit-btn", function(){
$basicForm.find('.submit-btn').attr('disabled', 'disabled');
$basicForm.find('.error').html('');
var valid = $basicForm.valid();
if($("input[name='mode'[checked]]").val() == 2) {
var $courseId = $("input[name='course_id'");
if($courseId.val() === undefined || $course_id.val().length === 0){
$courseId.addClass('danger text-danger');
valid = false;
} else {
$courseId.removeClass('danger text-danger');
}
} else if ($("input[name='mode'[checked]]").val() == 4) {
var $techStartTime = $("input[name='teach_start_time'");
var $techEndTime = $("input[name='teach_end_time'");
if($techStartTime.val() === undefined || $techStartTime.val().length === 0){
$techStartTime.addClass('danger text-danger');
valid = false;
} else {
$techStartTime.removeClass('danger text-danger');
}
if($techEndTime.val() === undefined || $techEndTime.val().length === 0){
$techEndTime.addClass('danger text-danger');
valid = false;
} else {
$techEndTime.removeClass('danger text-danger');
}
}
if(!valid) return;
$.ajax({
method: 'POST',
dataType: 'json',
url: $basicForm.attr('action'),
data: new FormData($basicForm[0]),
processData: false,
contentType: false,
success: function(data){
$.notify({ message: '保存成功' });
window.location.reload();
},
error: function(res){
var data = res.responseJSON;
$form.find('.error').html(data.message);
},
complete: function(){
$form.find('.submit-btn').attr('disabled', false);
}
});
});
});

@ -60,7 +60,12 @@ class Competitions::CompetitionTeamsController < Competitions::BaseController
def index
@personal = current_competition.personal?
admin_or_business? ? all_competition_teams : user_competition_teams
if admin_or_business?
all_competition_teams
user_competition_teams
else
user_competition_teams
end
end
def create
@ -113,8 +118,8 @@ class Competitions::CompetitionTeamsController < Competitions::BaseController
teams = teams.joins(users: { user_extension: :school }).where('schools.name LIKE ?', "%#{keyword}%")
end
@count = teams.count
@teams = paginate(teams.includes(:user, users: { user_extension: :school }))
@all_count = teams.count
@all_teams = paginate(teams.includes(:user, users: { user_extension: :school }))
end
def user_competition_teams

@ -10,8 +10,36 @@
<span class="flex-1">基础设置</span>
</div>
<div class="card-body row">
<%= form_tag(admins_competition_competition_settings_path(unsafe_params), method: :post, class: 'basic-setting-form flex-1', remote: true) do %>
<%= simple_form_for(@competition, url: a_path(@laboratory), method: 'patch', html: { enctype: 'multipart/form-data' }) do |f| %>
<div class="container competition-mode-container">
<div class="row align-items-center mb-1">
<div class="col-1 text-right">
主标题
</div>
<div class="col-5 text-left">
<%= text_field_tag(:name, @competition.name, autocomplete: 'off', class: 'form-control', placeholder: '竞赛标题') %>
</div>
</div>
<div class="row align-items-center mb-1">
<div class="col-1 text-right">
副标题
</div>
<div class="col-5 text-left">
<%= text_field_tag(:sub_title, @competition.sub_title, autocomplete: 'off', class: 'form-control', placeholder: '竞赛副标题') %>
</div>
</div>
<div class="row align-items-center mb-1">
<div class="col-1 text-right">
起止时间
</div>
<div class="col-5 competition-start-end-date d-flex">
<%= text_field_tag :start_time, @competition.start_time&.strftime('%Y-%m-%d'), autocomplete: 'off', class: 'form-control start-date mx-0 mr-2', placeholder: '竞赛开始时间' %>
<%= text_field_tag :end_time, @competition.end_time&.strftime('%Y-%m-%d'), autocomplete: 'off', class: 'form-control end-date mx-0', placeholder: '竞赛截止时间' %>
</div>
</div>
<div class="row align-items-center mb-1">
<div class="col-1 text-right">
竞赛模式
@ -42,12 +70,12 @@
<label class="form-radio-label mb-0" for="mode_3">教学模式(参赛者报名参赛,统计战队课堂和实训数据)</label>
</div>
<div class="col-6 teaching-mode-date d-flex">
<%= text_field_tag :start_time, @competition.competition_mode_setting&.start_time, autocomplete: 'off', class: 'form-control start-date mx-0 mr-2', placeholder: '统计数据的开始时间' %>
<%= text_field_tag :end_time, @competition.competition_mode_setting&.end_time, autocomplete: 'off', class: 'form-control end-date mx-0', placeholder: '统计数据的结束时间' %>
<%= text_field_tag :teach_start_time, @competition.competition_mode_setting&.start_time, autocomplete: 'off', class: 'form-control start-date mx-0 mr-2', placeholder: '统计数据的开始时间' %>
<%= text_field_tag :teach_end_time, @competition.competition_mode_setting&.end_time, autocomplete: 'off', class: 'form-control end-date mx-0', placeholder: '统计数据的结束时间' %>
</div>
</div>
<div class="row align-items-center mb-1">
<div class="row align-items-center mb-2">
<div class="col-1 text-right">
</div>
<div class="col-5 text-left">
@ -56,7 +84,7 @@
</div>
</div>
<div class="row align-items-center mb-1">
<div class="row align-items-center mb-2">
<div class="col-1 text-right">
URL
</div>
@ -65,7 +93,7 @@
</div>
</div>
<div class="row align-items-center mb-1">
<div class="row align-items-center mb-2">
<div class="col-1 text-right">
主办方
</div>
@ -74,7 +102,7 @@
</div>
</div>
<div class="row align-items-center mb-1">
<div class="row align-items-center mb-2">
<div class="col-1 text-right">
奖金
</div>
@ -86,16 +114,16 @@
</div>
</div>
<div class="row align-items-center mb-1">
<div class="row align-items-center mb-2">
<div class="col-1 text-right">
获奖人
奖项
</div>
<div class="col-5 text-left">
<%= number_field_tag(:bonus, @competition.bonus, autocomplete: 'off', step: 1, min: 0, class: 'form-control', placeholder: '请输入总奖金额') %>
<%= number_field_tag(:awards_count, @competition.awards_count, autocomplete: 'off', step: 1, min: 0, class: 'form-control', placeholder: '请输入奖项数') %>
</div>
</div>
<div class="row des-row align-items-center mb-1">
<div class="row des-row align-items-center mb-2">
<div class="col-1 text-right">
描述
</div>
@ -104,7 +132,9 @@
</div>
</div>
<div class="row des-row align-items-center mb-1">
<div class="error my-2 danger text-danger"></div>
<div class="row des-row align-items-center mb-2">
<div class="col-1 text-right">
</div>
<div class="col-5 text-left">
@ -112,7 +142,6 @@
</div>
</div>
</div>
<% end %>
</div>
</div>

@ -1,7 +1,31 @@
json.count @count
json.count @all_count
json.personal @personal
json.competition_teams do
json.array! @teams.each do |team|
json.array! @all_teams&.each do |team|
json.extract! team, :id, :name, :invite_code
json.team_type team.en_team_type
json.school_name team.user.school_name
json.created_at team.created_at.strftime("%Y-%m-%d %H:%M")
json.creator do
json.partial! 'users/user_simple', user: team.user
json.role team.team_members.find(&:creator?).en_role
end
json.team_members do
json.array! team.team_members.each do |member|
json.partial! 'users/user_simple', user: member.user
json.user_id member.user_id
json.role member.en_role
json.identity member.user.identity
json.school_name member.user.school_name
json.student_id member.user.student_id
end
end
end
end
json.my_teams @teams.each do |team|
json.extract! team, :id, :name, :invite_code
json.team_type team.en_team_type
json.school_name team.user.school_name
@ -23,5 +47,6 @@ json.competition_teams do
json.student_id member.user.student_id
end
end
end
end

@ -62,7 +62,7 @@ module.exports = {
// We generate sourcemaps in production. This is slow but gives good results.
// You can exclude the *.map files from the build during deployment.
// devtool: shouldUseSourceMap ? 'nosources-source-map' : false, //正式版
devtool: shouldUseSourceMap ? 'source-map' : false,//测试版
devtool:false,//测试版
// In production, we only want to load the polyfills and the app code.
entry: [require.resolve('./polyfills'), paths.appIndexJs],
output: {
@ -319,7 +319,6 @@ module.exports = {
output: {
comments: false
},
warnings: false,
compress: {
drop_debugger: true,
drop_console: true

@ -161,6 +161,7 @@
"devDependencies": {
"@babel/runtime": "7.0.0-beta.51",
"babel-plugin-import": "^1.11.0",
"compression-webpack-plugin": "^1.1.12",
"concat": "^1.0.3",
"happypack": "^5.0.1",
"node-sass": "^4.12.0",

@ -76,10 +76,10 @@ const Otherloginstart=Loadable({
loading: Loading,
})
const TestIndex = Loadable({
loader: () => import('./modules/test'),
loading: Loading,
})
// const TestIndex = Loadable({
// loader: () => import('./modules/test'),
// loading: Loading,
// })
const IndexWrapperComponent = Loadable({
loader: () => import('./modules/page/IndexWrapper'),
@ -91,23 +91,23 @@ const CommentComponent = Loadable({
loading: Loading,
})
const TestMaterialDesignComponent = Loadable({
loader: () => import('./modules/test/md/TestMaterialDesign'),
loading: Loading,
})
const TestCodeMirrorComponent = Loadable({
loader: () => import('./modules/test/codemirror/TestCodeMirror'),
loading: Loading,
})
// const TestMaterialDesignComponent = Loadable({
// loader: () => import('./modules/test/md/TestMaterialDesign'),
// loading: Loading,
// })
// const TestCodeMirrorComponent = Loadable({
// loader: () => import('./modules/test/codemirror/TestCodeMirror'),
// loading: Loading,
// })
const TestComponent = Loadable({
loader: () => import('./modules/test/TestRC'),
loading: Loading,
})
const TestUrlQueryComponent = Loadable({
loader: () => import('./modules/test/urlquery/TestUrlQuery'),
loading: Loading,
})
// const TestComponent = Loadable({
// loader: () => import('./modules/test/TestRC'),
// loading: Loading,
// })
// const TestUrlQueryComponent = Loadable({
// loader: () => import('./modules/test/urlquery/TestUrlQuery'),
// loading: Loading,
// })
const TPMIndexComponent = Loadable({
loader: () => import('./modules/tpm/TPMIndex'),
@ -254,10 +254,10 @@ const Interestpage = Loadable({
})
//众包创新
const ProjectPackages=Loadable({
loader: () => import('./modules/projectPackages/ProjectPackageIndex'),
loading: Loading,
})
// const ProjectPackages=Loadable({
// loader: () => import('./modules/projectPackages/ProjectPackageIndex'),
// loading: Loading,
// })
//竞赛
const NewCompetitions=Loadable({
@ -283,7 +283,7 @@ const Help = Loadable({
const Ecs = Loadable({
loader: () => import('./modules/ecs/Ecs'),
loading: Loading,
});
})
//团队竞赛报名
const Registration = Loadable({
@ -487,8 +487,8 @@ class App extends Component {
return (<Topicbank {...this.props} {...props} {...this.state} />)
}
}></Route>
{/*众包创新*/}
<Route path={"/crowdsourcing"} component={ProjectPackages}/>
{/*/!*众包创新*!/*/}
{/*<Route path={"/crowdsourcing"} component={ProjectPackages}/>*/}
{/*竞赛*/}
<Route path={"/newcompetitions"} component={NewCompetitions}/>
{/*认证*/}
@ -598,11 +598,11 @@ class App extends Component {
>
</Route>
<Route path="/comment" component={CommentComponent}/>
<Route path="/testMaterial" component={TestMaterialDesignComponent}/>
<Route path="/test" component={TestIndex}/>
<Route path="/testCodeMirror" component={TestCodeMirrorComponent}/>
<Route path="/testRCComponent" component={TestComponent}/>
<Route path="/testUrlQuery" component={TestUrlQueryComponent}/>
{/*<Route path="/testMaterial" component={TestMaterialDesignComponent}/>*/}
{/*<Route path="/test" component={TestIndex}/>*/}
{/*<Route path="/testCodeMirror" component={TestCodeMirrorComponent}/>*/}
{/*<Route path="/testRCComponent" component={TestComponent}/>*/}
{/*<Route path="/testUrlQuery" component={TestUrlQueryComponent}/>*/}
<Route
path="/registration"
render={

@ -71,3 +71,18 @@ export function toPath(path) {
export function getTaskUrlById(id) {
return `/tasks/${id}`
}
export function htmlEncode(str) {
var s = "";
if (str.length === 0) {
return "";
}
s = str.replace(/&/g, "&amp;");
s = s.replace(/</g, "&lt;");
s = s.replace(/>/g, "&gt;");
s = s.replace(/ /g, "&nbsp;");
s = s.replace(/\'/g, "&#39;");//IE下不支持实体名称
s = s.replace(/\"/g, "&quot;");
return s;
}

@ -4,7 +4,7 @@ import { from } from '_array-flatten@2.1.2@array-flatten';
export { getImageUrl as getImageUrl, getUrl as getUrl, getUrl2 as getUrl2, setImagesUrl as setImagesUrl
, getUploadActionUrl as getUploadActionUrl, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth
, getTaskUrlById as getTaskUrlById, TEST_HOST } from './UrlTool';
, getTaskUrlById as getTaskUrlById, TEST_HOST ,htmlEncode as htmlEncode } from './UrlTool';
export { default as queryString } from './UrlTool2';
export { SnackbarHOC as SnackbarHOC } from './SnackbarHOC';

@ -0,0 +1,216 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { Menu, Icon, List, Avatar,Row, Col,Tag,Pagination} from 'antd';
import axios from 'axios';
import './Competitionsindex.css';
import NoneData from "../../courses/shixunHomework/shixunHomework";
import groups1 from './groups1.png';
import groups2 from './groups2.png';
import groups3 from './groups3.png';
const { SubMenu } = Menu;
const IconText = ({ type, text }) => (
<span>
<Icon type={type} style={{ marginRight: 8 }} />
{text}
</span>
);
class CompetitionsIndex extends Component{
constructor(props) {
super(props)
this.state={
current: 'all',
datas:undefined,
page:1,
category:undefined
}
}
componentDidMount(){
window.document.title = '竞赛';
let{category,page}=this.state;
this.getdata(category,page)
}
getdata=(category,page)=>{
const Url =`/competitions.json`;
axios.get(Url,{params:{
category:category,
page:page,
per_page:6,
}
}).then((response) => {
if(response.status===200){
this.setState({
datas:response.data.competitions,
count:response.data.count,
})
}
})
.catch(function (error) {
console.log(error);
});
}
handleClick = e => {
this.setState({
current: e.key,
});
let{category,page}=this.state;
this.getdata(e.key,page)
};
render() {
let {datas,page,count}=this.state;
return (
<div>
<div className="clearfix">
<div>
<div className="newMain clearfix">
<div className="courses-head pr">
<div className="edu-txt-center pathNavLine">
<div className="inline path-nav"></div>
</div>
</div>
<div className="competitionstitle mb20">
<div className="competitionstitle2">
<Menu onClick={this.handleClick} selectedKeys={[this.state.current]} mode="horizontal">
<Menu.Item key="all" className={"competitionmr50"}>
<span className={"competitionsvalue"}>全部</span>
</Menu.Item>
<Menu.Item key="nearly_published" className={"competitionmr50"}>
<span className={"competitionsvalue"}>即将发布</span>
</Menu.Item>
<Menu.Item key="progressing" className={"competitionmr50"}>
<span className={"competitionsvalue"}>进行中</span>
</Menu.Item>
<Menu.Item key="ended" className={"competitionmr50"}>
<span className={"competitionsvalue"}>往期比赛</span>
</Menu.Item>
</Menu>
</div>
</div>
<div className={"educontent clearfix mtf10 CompetitionsIndex "}>
<style>
{
`
.CompetitionsList{
position: relative;
max-height: 210px;
}
.competitonimg{
position: absolute;
right: -5px;
width: 80px;
top: 20px;
}
`
}
</style>
<List
itemLayout="vertical"
size="large"
dataSource={datas&&datas}
renderItem={(item,key) => (
<Link to={`/newcompetitions/${item.identifier}/common_header`}>
<div className={"CompetitionsList"} >
{item.description===null||item.description===undefined||item.description===""?<style>
{
`
.CompetitionsIndex .ant-list-vertical .ant-list-item-action{
margin-top:50px;
}
`
}
</style>:""}
<img className={"competitonimg"}
src={item.nearly_published===true?groups2:item.published===true?groups2:groups1} />
<List.Item
key={key}
actions={[
<span>竞赛时间: 2019-08-07 24: 002019-09-10 24: 00</span>,
<span>报名截止时间2019-08-07 08:10</span>,
]}
extra={
<div className={"pt50"} style={{"width":'305px'}}>
<Row gutter={16}>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexdadels">奖金</div>
</Col>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexdadels">浏览数</div>
</Col>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexdadels">报名数</div>
</Col>
</Row>
<Row gutter={16}>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexbottomvalue">¥{item.bonus}</div>
</Col>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexbottomvalue">{item.visits_count}</div>
</Col>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexbottomvalue">{item.member_count}</div>
</Col>
</Row>
</div>
}
>
<List.Item.Meta
title={<a><span className={"competitionstitles"}>{item.name}</span><span>{item.sub_title===null?"":<Tag className="competitionsrelative" color="#87d068">{
item.sub_title
}</Tag>}</span>
</a>}
/>
{item.description}
</List.Item>
</div>
</Link>
)
}
/>
{datas===undefined?'none':datas.task_count >6 ?<div className="mb40 edu-txt-center padding20-30"
>
<Pagination
showQuickJumper
defaultCurrent={1}
pageSize={6}
total={count===undefined?"":count}
current={page}
onChange={this.PaginationCourse}
/>
</div>:""}
{
datas===undefined?"":datas && datas.length===0? <NoneData></NoneData>:""
}
</div>
</div>
</div>
</div>
</div>
)
}
}
export default CompetitionsIndex;

@ -1,3 +1,4 @@
.teamsLayout{background: transparent !important;}
.courses-head{
width: 100%;
height: 300px;
@ -104,6 +105,12 @@
.competitionsrelative{
position: absolute;
/*top: 28px;*/
top: 28px;
}
.CompetitionsList:hover{
/*box-shadow: 0 2px 6px rgba(51,51,51,.09);*/
box-shadow:3px 4px 10px 2px rgba(229,229,229,0.5);
opacity: 1;
border-radius: 2px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

@ -0,0 +1,53 @@
.teamsLayout{background: transparent !important;}
.teamsLayout .teamsLayoutitle{
font-size:18px;
font-family:PingFangSC-Semibold,PingFang SC;
font-weight:600;
color:rgba(5,16,26,1);
line-height:25px;
margin-top: 10px;
margin-bottom: 10px;
}
.teamsLayoutTable .ant-table-bordered .ant-table-thead > tr > th, .ant-table-bordered .ant-table-tbody > tr > td {
border-right: 1px solid transparent !important;
}
.teamsLayoutTable .ant-table-body .ant-table-thead > tr> th:nth-last-child(1){
border-right: 1px solid #e8e8e8 !important;
}
.teamsLayoutTable .ant-table-body .ant-table-tbody > tr> td:nth-last-child(1){
border-right: 1px solid #e8e8e8 !important;
}
.teamsLayoutTable .ant-table-bordered .ant-table-thead > tr > th{
background:#EEEEEE;
font-size: 14px;
font-family: PingFangSC-Regular,PingFang SC;
font-weight: 400;
color: rgba(102,102,102,1);
line-height: 20px;
}
.teamsLayoutTable .ant-table-bordered .ant-table-tbody > tr > th{
background:#EEEEEE;
font-size:14px;
font-family:PingFangSC-Regular,PingFang SC;
font-weight:400;
color:rgba(5,16,26,1);
line-height:20px;
}
.teamsLayout .mt40{
margin-top: 40px !important;
}
.teamsLayoutheji{
color: #878787;
font-size: 16px;
}
.teamsLayoucolor-orange {
color: #ff6800!important;
font-size: 16px;
}

@ -0,0 +1,246 @@
import React, { Component } from 'react';
import { Breadcrumb,Layout,Table, Divider, Tag,Badge} from 'antd';
import axios from 'axios';
import NoneData from "../../courses/shixunHomework/shixunHomework";
import './Competitionteams.css';
const { Header, Footer, Sider, Content } = Layout;
class Competitionteams extends Component{
constructor(props) {
super(props)
this.state={
shixundata: undefined,
coursedata:undefined,
}
}
componentDidMount(){
window.document.title = '竞赛';
this.getshixundata();
this.getcoursedata();
}
getshixundata=()=>{
const Url =`/competitions/${this.props.match.params.identifier}/competition_teams/${this.props.match.params.competition_team_id}/shixun_detail.json`;
axios.get(Url).then((response) => {
if(response.status===200){
// let data={
// shixuns: [
// {
// creator: "黄井泉", // 创建者
// shixun_name: "单链表的学习与应用I", // 实训名称
// shixun_identifier: "mnf6b7z3",
// forked: false, // false:原创
// myshixuns_count: 179, // 学习人数
// forked_myshixun_count: 0, // 被fork发布的学习人数
// valid_count: 82, // 有效作品数
// score: 1320 // 应用值
// }
// ],
// shixun_count: 1, // 实训总计
// total_myshixun_count: 179, // 学习人数总计
// total_forked_myshixun_count: 0, // 被fork发布的学习人数总计
// total_valid_count: 82, // 有效作品数总计
// total_shixun_score: 1320 // 应用值总计
// }
let data=response.data;
let newarr=data.shixuns;
let newobj={
creator:"合计:",
shixun_name:data.shixun_count,
myshixuns_count:data.total_myshixun_count,
forked_myshixun_count:data.total_forked_myshixun_count,
valid_count:data.total_valid_count,
score:data.total_shixun_score
}
newarr.push(newobj)
this.setState({
shixundata:newarr
})
}
})
.catch(function (error) {
console.log(error);
});
}
getcoursedata=()=>{
const Url =`/competitions/${this.props.match.params.identifier}/competition_teams/${this.props.match.params.competition_team_id}/course_detail.json`;
axios.get(Url).then((response) => {
if(response.status===200){
// let data={
// courses: [
// {
// creator: "周海芳", // 创建者
// creator_login: "Nancy", // login
// course_name: "大学计算机基础2018年秋季",
// course_id: 1502,
// students_count: 122, // 学生数量
// shixun_homework_count: 8, // 发布的实训作业数量
// valid_count: 977, // 有效作品数
// score: 29810 // 应用值
// }
// ],
// total_course_count: 1, // 课堂总计
// total_students_count: 122, // 学生数总计
// total_shixun_homework_count: 8, // 实训作业数总计
// total_valid_count: 977, // 有效作品数总计
// total_course_score: 29810 // 应用值总计
// }
let data=response.data;
let newarr=data.courses;
let newobj={
creator:"合计:",
course_name:data.total_course_count,
students_count:data.total_students_count,
shixun_homework_count:data.total_shixun_homework_count,
valid_count:data.total_valid_count,
score:data.total_course_score
}
newarr.push(newobj)
this.setState({
coursedata:newarr
})
}
})
.catch(function (error) {
console.log(error);
});
}
render() {
const shixuncolumns = [
{
title: '创建者',
dataIndex: 'creator',
key: 'creator',
render: (text, record) => <div className={record.creator==="合计:"?"teamsLayoutheji":""}>{text}</div>,
},
{
title: '名称',
dataIndex: 'shixun_name',
key: 'shixun_name',
render: (text, record) =>
<div className={record.creator==="合计:"?"teamsLayoucolor-orange":""}>{text}{record.forked===true?<Badge count={"原创"} style={{ backgroundColor: '#459BE5' }} />:""}</div>,
},
{
title: '学习人数',
dataIndex: 'myshixuns_count',
key: 'myshixuns_count',
render: (text, record) => <div className={record.creator==="合计:"?"teamsLayoucolor-orange":""}>{text}</div>,
},
{
title: '被fork发布的学习人数',
dataIndex: 'forked_myshixun_count',
key: 'forked_myshixun_count',
render: (text, record) => <div className={record.creator==="合计:"?"teamsLayoucolor-orange":""}>{text}</div>,
},
{
title: '有效作品数',
dataIndex: 'valid_count',
key: 'valid_count',
render: (text, record) => <div className={record.creator==="合计:"?"teamsLayoucolor-orange":""}>{text}</div>,
},
{
title: '应用值',
dataIndex: 'score',
key: 'score',
render: (text, record) => <div className={record.creator==="合计:"?"teamsLayoucolor-orange":""}>{text}</div>,
},
];
const coursecolumns = [
{
title: '创建者',
dataIndex: 'creator',
key: 'creator',
render: (text, record) => <div className={record.creator==="合计:"?"teamsLayoutheji":""}>{text}</div>,
},
{
title: '名称',
dataIndex: 'course_name',
key: 'course_name',
render: (text, record) => <div className={record.creator==="合计:"?"teamsLayoucolor-orange":""}>{text}</div>,
},
{
title: '学习人数',
dataIndex: 'students_count',
key: 'students_count',
render: (text, record) => <div className={record.creator==="合计:"?"teamsLayoucolor-orange":""}>{text}</div>,
},
{
title: '被fork发布的学习人数',
dataIndex: 'shixun_homework_count',
key: 'shixun_homework_count',
render: (text, record) => <div className={record.creator==="合计:"?"teamsLayoucolor-orange":""}>{text}</div>,
},
{
title: '有效作品数',
dataIndex: 'valid_count',
key: 'valid_count',
render: (text, record) => <div className={record.creator==="合计:"?"teamsLayoucolor-orange":""}>{text}</div>,
},
{
title: '应用值',
dataIndex: 'score',
key: 'score',
render: (text, record) => <div className={record.creator==="合计:"?"teamsLayoucolor-orange":""}>{text}</div>,
},
];
console.log(this.state.shixundata)
return (
<div className={"educontent clearfix mt20 "}>
<Breadcrumb separator=">">
<Breadcrumb.Item>全国高校计算机大赛战</Breadcrumb.Item>
<Breadcrumb.Item href="">报名</Breadcrumb.Item>
<Breadcrumb.Item href="">战队详情</Breadcrumb.Item>
</Breadcrumb>
<Layout className={"teamsLayout"}>
<Content className={"teamsLayoutitle"}>实训项目</Content>
<Content className={"teamsLayoutContent"}>
<Table className="teamsLayoutTable" columns={shixuncolumns} dataSource={this.state.shixundata} bordered pagination={false}/>
</Content>
<Content className={"teamsLayoutitle mt40"}>翻转课堂</Content>
<Content className={"teamsLayoutContents"}>
<Table className="teamsLayoutTable" columns={coursecolumns} dataSource={this.state.coursedata} bordered pagination={false}/>
</Content>
</Layout>
</div>
)
}
}
export default Competitionteams;

@ -0,0 +1,172 @@
.teamsLayout{background: transparent !important;}
.teamsLayout .ant-layout-sider{
background: transparent !important;
flex: 0 0 180px !important;
max-width: 180px !important;
min-width: 180px !important;
width: 180px !important;
}
.teamsLayout .teamsLayoutitle{
font-size:18px;
font-family:PingFangSC-Semibold,PingFang SC;
font-weight:600;
color:rgba(5,16,26,1);
line-height:25px;
margin-top: 10px;
margin-bottom: 10px;
}
.teamsLayoutTable .ant-table-bordered .ant-table-thead > tr > th, .ant-table-bordered .ant-table-tbody > tr > td {
border-right: 1px solid transparent !important;
}
.teamsLayoutTable .ant-table-body .ant-table-thead > tr> th:nth-last-child(1){
border-right: 1px solid #e8e8e8 !important;
}
.teamsLayoutTable .ant-table-body .ant-table-tbody > tr> td:nth-last-child(1){
border-right: 1px solid #e8e8e8 !important;
}
.teamsLayoutTable .ant-table-bordered .ant-table-thead > tr > th{
background:#EEEEEE;
font-size: 14px;
font-family: PingFangSC-Regular,PingFang SC;
font-weight: 400;
color: rgba(102,102,102,1);
line-height: 20px;
}
.teamsLayoutTable .ant-table-bordered .ant-table-tbody > tr > th{
background:#EEEEEE;
font-size:14px;
font-family:PingFangSC-Regular,PingFang SC;
font-weight:400;
color:rgba(5,16,26,1);
line-height:20px;
}
.teamsLayout .mt40{
margin-top: 40px !important;
}
.teamsLayoutheji{
color: #878787;
font-size: 16px;
}
.teamsLayoucolor-orange {
color: #ff6800!important;
font-size: 16px;
}
.CompetitionCommonbanner{
padding: 20px;
background:rgba(255,255,255,1);
box-shadow:3px 2px 12px 2px rgba(0,0,0,0.05);
}
.CompetitionCommonbannerfont{
height:100%;
}
.CompetitionCommonbannerfont .competitionbannerdiv:nth-child(1){
max-height:100px;
font-size:25px;
font-weight:400;
color:rgba(5,16,26,1);
}
.CompetitionCommonbannerfont .competitionbannerdiv:nth-child(2){
max-height: 70px;
font-size:16px;
font-weight:400;
/*color:rgba(155,155,155,1);*/
color:#05101A;
}
.CompetitionCommonbannerfont .competitionbannerdiv:nth-child(3){
max-height: 70px;
font-size: 16px;
font-weight: 400;
/*color: rgba(155,155,155,1);*/
color:#05101A;
}
.CompetitionCommonbannerfont .competitionbannerdiv:nth-child(4),.CompetitionCommonbannerfont .competitionbannerdiv:nth-child(4) button{
height: 50px;
background: rgba(76,172,255,1);
border-radius: 4px;
}
.Competitioncolor9b{
color: #9B9B9B;
}
.Competitioncolor77{
color: #777777;
font-size: 14px;
}
.Competitioncolor516{
font-size:24px;
color:rgba(5,16,26,1);
}
.Competitionfontsize22{
font-size:22px;
font-weight:500;
color:rgba(255,255,255,1);
}
.Competitionfontsize16{
font-size: 16px;
font-weight: 400;
color: rgba(102,102,102,1);
}
.ant-layout-sider {
position: relative;
min-width: 0;
background: #001529;
-webkit-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
.CompetitionMenu .ant-menu-item::after {
left: 0px !important;
right: auto;
border-right: 5px solid #4CACFF;
}
.CompetitionMenu .ant-menu-item{
height: 30px;
line-height: 30px;
background:none;
}
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
background-color: transparent;
}
.CompetitionMenu .ant-menu-item:not(:last-child){
margin-bottom: 40px;
background: transparent;
color:#666;
}
.CompetitionMenu .ant-menu-item{
font-size: 18px;
}
.CompetitionMenu .ant-menu-item-selected {
color: rgba(76,172,255,1) !important;
}
.CompetitionMenu{
width: 145px;
background: transparent;
border: 1px solid rgba(239,239,239,1);
padding-top: 20px;
padding-bottom: 40px !important;
}

@ -0,0 +1,127 @@
import React, { Component } from 'react';
import { Breadcrumb,Layout,Table, Divider, Tag,Badge,Row, Col,Button, Menu, Icon} from 'antd';
import axios from 'axios';
import NoneData from "../../courses/shixunHomework/shixunHomework";
import './CompetitionCommon.css';
const { Header, Footer, Sider, Content } = Layout;
class CompetitionCommon extends Component{
constructor(props) {
super(props)
this.state={
}
}
componentDidMount(){
window.document.title = '竞赛';
this.getbannerdata()
}
getbannerdata=()=>{
let url=`/competitions/${this.props.match.params.identifier}/common_header.json`;
axios.get(url).then((response) => {
console.log(response)
}).catch((error) => {
console.log(error)
});
}
render() {
return (
<div className={"educontent clearfix mt20 "}>
<Breadcrumb separator=">">
<Breadcrumb.Item href="">在线竞赛</Breadcrumb.Item>
<Breadcrumb.Item href="">全国高校计算机大赛</Breadcrumb.Item>
</Breadcrumb>
<div className={"mt10"}>
<Row className={"CompetitionCommonbanner"}>
<Col span={15}>banner</Col>
<Col className={"CompetitionCommonbannerfont"} span={9}>
<Col className={"competitionbannerdiv"}>全国计算机系列大赛系列大赛系列大赛</Col>
<Col className={"competitionbannerdiv mt10"}>
<Col className={"Competitioncolor9b"}>竞赛时间</Col>
<Col>2019-08-07 24: 002019-09-10 24: 00</Col>
</Col>
<Col className={"competitionbannerdiv mt20"}>
<Row gutter={16}>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexdadels Competitioncolor77">奖金</div>
</Col>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexdadels Competitioncolor77">浏览数</div>
</Col>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexdadels Competitioncolor77">报名数</div>
</Col>
</Row>
<Row gutter={16}>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516">¥123</div>
</Col>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516">4124</div>
</Col>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexbottomvalue Competitioncolor516">51234</div>
</Col>
</Row>
</Col>
<Col className={"competitionbannerdiv mt20"}>
<Button type="primary" block className={"Competitionfontsize22"}>
立即报名
</Button>
</Col>
<Col className={"mt10 Competitionfontsize16"}>报名截止时间2019-08-07 08:10</Col>
</Col>
</Row>
</div>
<Layout className={'teamsLayout mt40'}>
<Sider>
<Menu mode="inline" className="CompetitionMenu" defaultSelectedKeys={['1']}>
<Menu.Item key="1">
<span>赛制介绍</span>
</Menu.Item>
<Menu.Item key="2">
<span>参赛手册</span>
</Menu.Item>
<Menu.Item key="3">
<span>排行榜</span>
</Menu.Item>
<Menu.Item key="4">
<span>通知公告</span>
</Menu.Item>
</Menu>
</Sider>
<Layout>
<Content>Content</Content>
</Layout>
</Layout>
</div>
)
}
}
export default CompetitionCommon;

@ -4,25 +4,39 @@ import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import Loading from '../../Loading'
import Loading from '../../Loading';
import Loadable from 'react-loadable';
import { TPMIndexHOC } from '../tpm/TPMIndexHOC'
import { SnackbarHOC } from 'educoder'
import { TPMIndexHOC } from '../tpm/TPMIndexHOC';
import { SnackbarHOC } from 'educoder';
//新版竞赛首页
const CompetitionsIndex = Loadable({
loader: () => import('./competitimain/CompetitionsIndex'),
loader: () => import('./Competitimain/CompetitionsIndex'),
loading: Loading,
})
//竞赛详情页
const CompetitionCommon=Loadable({
loader: () => import('./Competitioncommon/CompetitionCommon'),
loading: Loading,
})
//战队详情
const CompetitionTeams = Loadable({
loader: () => import('./Competition_teams/Competitionteams'),
loading: Loading,
})
class Competitions extends Component {
constructor(props) {
super(props)
}
componentDidMount(){
window.document.title = '竞赛'
window.document.title = '竞赛';
}
render() {
@ -31,14 +45,28 @@ class Competitions extends Component {
<div className="newMain clearfix">
<Switch>
{/*新版竞赛首页*/}
{/*新版竞赛战队详情*/}
<Route path="/newcompetitions/:identifier/competition_teams/:competition_team_id"
render={
(props) => (<CompetitionTeams {...this.props} {...props} {...this.state} />)
}
></Route>
{/*新版竞赛详情页面*/}
<Route path="/newcompetitions/:identifier/common_header"
render={
(props) => (<CompetitionCommon {...this.props} {...props} {...this.state} />)
}
></Route>
{/*新版竞赛首页*/}
<Route path="/newcompetitions"
render={
(props) => (<CompetitionsIndex {...this.props} {...props} {...this.state} />)
}
></Route>
</Switch>
</div>

@ -1,191 +0,0 @@
import React, { Component } from 'react';
import {BrowserRouter as Router,Route,Switch} from 'react-router-dom';
import { Menu, Icon, List, Avatar,Row, Col,Tag,Pagination} from 'antd';
import axios from 'axios';
import './Competitionsindex.css';
import NoneData from "../../courses/shixunHomework/shixunHomework";
const { SubMenu } = Menu;
const IconText = ({ type, text }) => (
<span>
<Icon type={type} style={{ marginRight: 8 }} />
{text}
</span>
);
class CompetitionsIndex extends Component{
constructor(props) {
super(props)
this.state={
current: 'all',
datas:undefined,
page:1
}
}
componentDidMount(){
window.document.title = '竞赛';
let{page}=this.state;
const Url =`/competitions.json`;
axios.get(Url,{params:{
page:page
}
}).then((response) => {
if(response.status===200){
this.setState({
datas:response.data.competitions,
count:response.data.count,
})
}
})
.catch(function (error) {
console.log(error);
});
}
handleClick = e => {
console.log('click ', e);
this.setState({
current: e.key,
});
};
render() {
let {datas,page,count}=this.state;
// bonus: 0
// current_stage: {name: "正赛 第一阶段", start_time: "2019-10-11 00:00:00", end_time: "2019-11-01 00:00:00"}
// description: null
// end_time: "2019-11-01 00:00:00"
// enroll_end_time: "2019-10-31 00:00:00"
// id: 7
// identifier: "gcc-annotation-2019"
// image: null
// member_count: 540
// name: "第二届全国绿色计算系列大赛"
// nearly_published: false
// published: true
// single_stage: false
// start_time: "2019-07-01 00:00:00"
// sub_title: "代码标注组"
// visits_count: 10181
return (
<div>
<div className="clearfix">
<div>
<div className="newMain clearfix">
<div className="courses-head pr">
<div className="edu-txt-center pathNavLine">
<div className="inline path-nav"></div>
</div>
</div>
<div className="competitionstitle mb20">
<div className="competitionstitle2">
<Menu onClick={this.handleClick} selectedKeys={[this.state.current]} mode="horizontal">
<Menu.Item key="all" className={"competitionmr50"}>
<span className={"competitionsvalue"}>全部</span>
</Menu.Item>
<Menu.Item key="nearly_published" className={"competitionmr50"}>
<span className={"competitionsvalue"}>即将发布</span>
</Menu.Item>
<Menu.Item key="progressing" className={"competitionmr50"}>
<span className={"competitionsvalue"}>进行中</span>
</Menu.Item>
<Menu.Item key="ended" className={"competitionmr50"}>
<span className={"competitionsvalue"}>往期比赛</span>
</Menu.Item>
</Menu>
</div>
</div>
<div className={"educontent clearfix mtf10 CompetitionsIndex "}>
<List
itemLayout="vertical"
size="large"
dataSource={datas&&datas}
renderItem={(item,key) => (
<List.Item
key={key}
actions={[
<span>竞赛时间: 2019-08-07 24: 002019-09-10 24: 00</span>,
<span>报名截止时间2019-08-07 08:10</span>,
]}
extra={
<div className={"pt50"} style={{"width":'305px'}}>
<Row gutter={16}>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexdadels">奖金</div>
</Col>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexdadels">浏览数</div>
</Col>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexdadels">报名数</div>
</Col>
</Row>
<Row gutter={16}>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexbottomvalue">¥4500</div>
</Col>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexbottomvalue">351</div>
</Col>
<Col className="gutter-row" span={6}>
<div className="gutter-box CompetitionsIndexbottomvalue">351</div>
</Col>
</Row>
</div>
}
>
<List.Item.Meta
title={<a><span className={"competitionstitles"}>{item.name}</span><span>{item.sub_title===null?"":<Tag className="competitionsrelative" color="#87d068">{
item.sub_title
}</Tag>}</span>
</a>}
/>
{item.description}
</List.Item>
)}
/>
<div className="mb40 edu-txt-center padding20-30"
// style={
// // {
// // display: datas===undefined?'none':datas.task_count >15 ? 'block':'none'
// // }
// }
>
<Pagination
showQuickJumper
defaultCurrent={1}
pageSize={8}
total={count===undefined?"":count}
current={page}
onChange={this.PaginationCourse}
/>
</div>
{
datas===undefined?"":datas && datas.length===0? <NoneData></NoneData>:""
}
</div>
</div>
</div>
</div>
</div>
)
}
}
export default CompetitionsIndex;

@ -22,7 +22,7 @@ import {ImageLayerOfCommentHOC} from '../page/layers/ImageLayerOfCommentHOC'
import MemoDetailKEEditor from './MemoDetailKEEditor'
import MemoDetailMDEditor from './MemoDetailMDEditor'
import { bytesToSize, CBreadcrumb } from 'educoder'
import { bytesToSize, CBreadcrumb ,htmlEncode} from 'educoder'
import { Tooltip } from 'antd'
// import CBreadcrumb from '../courses/common/CBreadcrumb'
@ -246,6 +246,8 @@ class MemoDetail extends Component {
if (commentContent) {
commentContent = commentContent.replace(/(\n<p>\n\t<br \/>\n<\/p>)*$/g,'');
}
commentContent=htmlEncode(commentContent)
axios.post(url, {
parent_id: id,
content: commentContent
@ -491,6 +493,7 @@ class MemoDetail extends Component {
const url = `/memos/reply.json`;
let { comments } = this.state;
const user = this._getUser();
content=htmlEncode(content)
axios.post(url, {
parent_id: memo.id,
content: content

@ -1,6 +1,6 @@
import React, { Component } from 'react';
import "../css/messagemy.css"
import {getImageUrl,markdownToHTML} from 'educoder';
import {getImageUrl,markdownToHTML,htmlEncode} from 'educoder';
import { Modal,Input,Icon,Tooltip,Spin} from 'antd';
import axios from 'axios';
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
@ -417,6 +417,7 @@ class MessagChat extends Component{
let contents=this.messageRef.current.getValue().trim();
const query = this.props.location.search;
let target_ids = query.split('?target_ids=');
contents=htmlEncode(contents)
let url = `/users/${this.props.match.params.userid}/private_messages.json`;
axios.post(url, {
target_id: target_ids[1],

@ -2,7 +2,7 @@ import React, { Component } from 'react';
import { Modal,Input,Icon,Tooltip,Spin} from 'antd';
import axios from 'axios';
// import '../../modules/user/common.css';
import {getImageUrl} from 'educoder';
import {getImageUrl,htmlEncode} from 'educoder';
//完善个人资料
class WriteaprivateletterModal extends Component {
@ -58,6 +58,7 @@ class WriteaprivateletterModal extends Component {
//发送私信
SendprivatemessageAPI=(idvalue,contentvalue)=>{
const url =`/users/${this.props.current_user.user_id}/private_messages.json`
contentvalue=htmlEncode(contentvalue)
let data={
target_id:idvalue,
content:contentvalue,

Loading…
Cancel
Save