Merge branch 'dev_aliyun' of http://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun

chromesetting
cxt 5 years ago
commit d2e76a263a

@ -61,7 +61,10 @@ class HackUserLastestCodesController < ApplicationController
# 提交记录
def submit_records
@records = @my_hack.hack_user_codes.created_order
records = @my_hack.hack_user_codes
@records_count = records.count
@records = paginate records.created_order
end
@ -163,12 +166,12 @@ class HackUserLastestCodesController < ApplicationController
# 通关
if submit_params[:status] == "0"
# 编程题已经发布,且之前未通关奖励积分
@hack.increment!(:pass_num)
if @hack.status == 1 && !@my_hack.passed?
reward_attrs = { container_id: game.id, container_type: 'Hack', score: @hack.score }
RewardGradeService.call(@my_hack.user, reward_attrs)
RewardExperienceService.call(@my_hack.user, reward_attrs)
# 评测完成更新通过数
@hack.increment!(:pass_num)
@my_hack.update_attributes(passed: true, passed_time: Time.now)
end
end

@ -100,6 +100,7 @@ class HacksController < ApplicationController
@hack.update_attribute(:status, 1)
base_attrs = {
trigger_user_id: current_user.id, viewed: 0, tiding_type: 'System', user_id: @hack.user_id,
parent_container_type: "HackPublish"
}
@hack.tidings.create!(base_attrs)
render_ok
@ -109,7 +110,8 @@ class HacksController < ApplicationController
def cancel_publish
@hack.update_attribute(:status, 0)
base_attrs = {
trigger_user_id: current_user.id, viewed: 0, tiding_type: 'System', user_id: @hack.user_id
trigger_user_id: current_user.id, viewed: 0, tiding_type: 'System', user_id: @hack.user_id,
parent_container_type: "HackUnPublish"
}
@hack.tidings.create!(base_attrs)
render_ok
@ -129,8 +131,19 @@ class HacksController < ApplicationController
def new;end
def destroy
@hack.destroy
render_ok
begin
base_attrs = {
user_id: @hack.user_id, viewed: 0, tiding_type: 'System', trigger_user_id: current_user.id,
parent_container_type: "HackDelete", extra: "#{@hack.name}"
}
@hack.tidings.create!(base_attrs)
@hack.destroy
render_ok
rescue => e
logger.error("####hack_delete_error: #{e.message}")
render_error("删除失败")
end
end
private

@ -80,4 +80,17 @@ class JupytersController < ApplicationController
render json: {status: 0}
end
def timeinfo_with_tpm
shixun = Shixun.find_by(identifier: params[:identifier])
info = jupyter_timeinfo_tpm(shixun)
render json: {status: 0}.merge(info)
end
def timeinfo_with_tpi
myshixun = Myshixun.find_by(identifier: params[:identifier])
info = jupyter_timeinfo_tpi(shixun)
render json: {status: 0}.merge(info)
end
end

@ -376,7 +376,7 @@ class MyshixunsController < ApplicationController
# todo: identifier 是以前的密码,用来验证的,新版如果不需要,和中间层协调更改.
params = {tpiID: "#{@myshixun.try(:id)}", tpiGitURL: "#{git_myshixun_url}", tpmGitURL: "#{git_shixun_url}",
identifier: "xinhu1ji2qu3"}
uri = "#{shixun_tomcat}/bridge/game/resetTpmRepository"
uri = "#{shixun_tomcat}/bridge/game/resetJupyterTpm"
res = uri_post uri, params
if (res && res['code'] != 0)
tip_exception("实训云平台繁忙繁忙等级95")

@ -216,7 +216,7 @@ class ShixunsController < ApplicationController
ShixunInfo.create!(shixun_id: @new_shixun.id,
description: @shixun.description,
evaluate_script: @shixun.evaluate_script,
shixun_reason: params[:reason].to_s.strip)
fork_reason: params[:reason].to_s.strip)
end
# 同步私密版本库
@ -363,7 +363,7 @@ class ShixunsController < ApplicationController
page = params[:page] || 1
limit = params[:limit] || 10
@member_count = @shixun.shixun_members.count
@members = @shixun.shixun_members.includes(:user).page(page).per(limit)
@members = @shixun.shixun_members.order("role = 1 desc, created_at asc").includes(:user).page(page).per(limit)
end
def fork_list

@ -31,6 +31,9 @@ module GradeDecorator
when 'check_ta_answer' then
game = Game.find_by(id: container_id)
game.present? ? "查看实训“#{game.challenge.shixun.name}”第#{game.challenge.position}关的TA人解答消耗的金币" : ''
when 'hack' then
hack = Hack.find_by(id: container_id)
game.present? ? "完成了题目解答“#{hack.name}”,获得金币奖励:#{hack.score}" : ''
end
end
end

@ -220,11 +220,13 @@ module TidingDecorator
when 'Journal' then
message = parent_container&.notes.present? ? '' + message_content_helper(parent_container.notes) : ''
I18n.t(locale_format(parent_container_type)) % message
when 'Hack' then
I18n.t(locale_format(parent_container_type)) % parent_container.name
end
end
def discuss_content
I18n.t(locale_format(container.parent_id.present?)) % message_content_helper(container.content)
I18n.t(locale_format(container_type, container.parent_id.present?)) % message_content_helper(container.content)
end
def grade_content
@ -250,6 +252,9 @@ module TidingDecorator
when 'shixunPublish' then
name = Shixun.find_by(id: parent_container_id)&.name || '---'
I18n.t(locale_format(parent_container_type)) % [name, container.score]
when 'Hack' then
name = Hack.find_by(id: container_id)&.name || '---'
I18n.t(locale_format(parent_container_type)) % [name, container.score]
else
I18n.t(locale_format(parent_container_type)) % container.score
end
@ -405,4 +410,8 @@ module TidingDecorator
def subject_start_course_content
I18n.t(locale_format) % belong_container&.name
end
def hack_content
I18n.t(locale_format(parent_container_type)) % (container&.name || extra)
end
end

@ -59,7 +59,7 @@ class Discuss < ApplicationRecord
elsif dis_type == 'Hack'
user_id = has_parent? ? parent.user_id : Hack.find(dis_id).user_id
parent_container_type = 'Hack'
challenge_id = nil
challenge_id = dis_id
end
base_attrs = {
trigger_user_id: user_id, parent_container_id: challenge_id, parent_container_type: parent_container_type,

@ -14,7 +14,7 @@ class Hack < ApplicationRecord
# 点赞
has_many :praise_treads, as: :praise_tread_object, dependent: :destroy
# 消息
has_many :tidings, as: :container, dependent: :destroy
has_many :tidings, as: :container
belongs_to :user
@ -23,8 +23,6 @@ class Hack < ApplicationRecord
scope :opening, -> {where(open_or_not: 1)}
scope :mine, -> (author_id){ where(user_id: author_id) }
after_destroy :send_delete_tiding
def language
if hack_codes.count == 1
hack_codes.first.language
@ -53,12 +51,4 @@ class Hack < ApplicationRecord
user_id == user.id || user.admin_or_business?
end
private
def send_delete_tiding
base_attrs = {
user_id: user_id, viewed: 0, tiding_type: 'Delete', trigger_user_id: current_user.id, content: "你删除了题目:#{name}"
}
tidings.create!(base_attrs)
end
end

@ -1,6 +1,7 @@
class ShixunInfo < ApplicationRecord
belongs_to :shixun
validates_uniqueness_of :shixun_id
validates_length_of :fork_reason, maximum: 60
after_commit :create_diff_record
private

@ -213,4 +213,27 @@ module JupyterService
_jupyter_active(tpiID)
end
def _jupyter_timeinfo(tpiID)
shixun_tomcat = edu_setting('cloud_bridge')
uri = "#{shixun_tomcat}/bridge/jupyter/getTimeInfo"
params = {:tpiID => tpiID}
res = uri_post uri, params
if res && res['code'].to_i != 0
raise("实训云平台繁忙繁忙等级130")
end
res['data']
end
# 获取时间参数
def jupyter_timeinfo_tpm(shixun)
tpiID = "tpm#{shixun.id}"
_jupyter_timeinfo(tpiID)
end
# 获取时间参数
def jupyter_timeinfo_tpi(myshixun)
tpiID = myshixun.id
_jupyter_timeinfo(tpiID)
end
end

@ -12,4 +12,5 @@ if discuss.parent_id
else
json.praise_count discuss.praises_count
json.user_praise discuss.praise_treads.select{|pt| pt.user_id == current_user.id}.length > 0
json.can_delete discuss.can_deleted?(current_user) && child.count == 0
end

@ -1,6 +1,6 @@
json.disscuss_count @discusses_count
json.comments @discusses do |discuss|
json.partial! 'comments/discuss', locals: { discuss: discuss}
json.partial! 'comments/discuss', locals: { discuss: discuss, child: discuss.child_discuss(current_user)}
json.children discuss.child_discuss(current_user) do |c_d|
json.partial! 'comments/discuss', locals: { discuss: c_d }
end

@ -1,4 +1,8 @@
json.array! @records do |hack_user|
json.(hack_user, :id, :created_at, :status, :execute_time, :execute_memory)
json.language hack_user.hack.language
end
json.records do
json.array! @records do |hack_user|
json.(hack_user, :id, :created_at, :status, :execute_time, :execute_memory)
json.language hack_user.hack.language
end
end
json.records_count @records_count

@ -10,4 +10,5 @@ json.data_sets do
json.file_path "#{@absolute_folder}/#{set.relative_path_filename}".gsub("/#{@shixun.identifier}", "")
end
end
json.data_sets_count @data_count
json.data_sets_count @data_count
json.folder_name @absolute_folder

@ -93,6 +93,7 @@
Challenge:
"1_end": "赞了你发布的实训任务:%s第%s关"
"2_end": "踩了你发布的实训任务:%s第%s关"
Hack_end: "赞了你发布的题目:%s"
Memo:
true_end: "赞了你的评论:%s"
false_end: "赞了发布的帖子:%s"
@ -107,8 +108,16 @@
Issue_end: "赞了你发布的项目Issue%s"
Journal_end: "赞了你的回复%s"
Discuss:
true_end: "评论了你的回复:%s"
false_end: "评论了你发布的实训:%s"
Shixun:
true_end: "评论了你的回复:%s"
false_end: "评论了你发布的实训:%s"
Hack:
true_end: "评论了你的回复:%s"
false_end: "评论了你发布的题目:%s"
Hack:
HackPublish_end: "你发布了题目:%s"
HackUnPublish_end: "你撤销发布了题目:%s"
HackDelete_end: "你删除了题目:%s"
Grade:
Avatar_end: "首次上传头像获得金币奖励:%s金币"
Phone_end: "首次绑定手机号码获得金币奖励:%s金币"
@ -118,6 +127,7 @@
Answer:
true_end: "查看实训%s第%s关的参考答案消耗金币%s金币"
false_end: "查看实训的参考答案消耗金币:%s金币"
Hack_end: "完成题目解答:%s获得金币奖励%s金币"
Game_end: "通过实训%s的第%s关获得金币奖励%s金币"
Memo_end: "发布的评论或者帖子获得平台奖励:%s金币"
Discusses_end: "发布的评论获得金币奖励:%s金币"

@ -35,6 +35,8 @@ Rails.application.routes.draw do
get :reset_with_tpm
get :active_with_tpm
get :active_with_tpi
get :timeinfo_with_tpm
get :timeinfo_with_tpi
post :import_with_tpm
end

@ -0,0 +1,5 @@
class ModifyOpenOrNotForHacks < ActiveRecord::Migration[5.2]
def change
change_column :hacks, :open_or_not, :boolean, :default => false
end
end

@ -37,9 +37,9 @@ document.addEventListener('keydown', (e) => {
if(e.data==="stopParent"){
//重置停止
timebool=false;
console.log("父窗口调用停止");
// console.log("父窗口调用停止");
}else if(e.data==="clonsParent"){
console.log("父窗口调用启动");
// console.log("父窗口调用启动");
//取消启动
timebool=true;
// runEvery10Sec();

@ -30,7 +30,7 @@ const env = getClientEnvironment(publicUrl);
module.exports = {
// You may want 'eval' instead if you prefer to see the compiled output in DevTools.
// See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s
// devtool: "cheap-module-eval-source-map",
devtool: "cheap-module-eval-source-map",
// 开启调试
//devtool: "source-map", // 开启调试
// These are the "entry points" to our application.

@ -4,11 +4,11 @@
* @Github:
* @Date: 2019-12-18 10:49:46
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-24 18:04:52
* @LastEditTime : 2019-12-25 10:03:21
*/
import './index.scss';
import React from 'react';
import { Icon } from 'antd';
// import { Icon } from 'antd';
// import MyIcon from '../MyIcon';
function CommentIcon ({
type, // 图标类型
@ -25,13 +25,15 @@ function CommentIcon ({
}
const _className = [undefined, null, ''].includes(count) ? 'comment_count_none' : 'comment_count';
const _classIcon = `iconfont icon-${type} icon_font_size_14 comment_icon `;
return (
<span
style={props.style}
className={`comment_icon_count ${props.className}`}
onClick={ handleSpanClick }
>
<Icon className="comment_icon" type={type} style={{ color: iconColor }} theme={theme}/>
{/* <Icon className="comment_icon" type={type} style={{ color: iconColor }} theme={theme}/> */}
<span className={_classIcon} style={{ color: iconColor }}></span>
<span className={_className}>{ count }</span>
</span>
)

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-17 17:35:17
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-24 18:05:18
* @LastEditTime : 2019-12-25 14:53:41
*/
import './index.scss';
import React, { useState } from 'react';
@ -28,7 +28,7 @@ function CommentItem ({
// 加载更多评论内容
// const [showMore, setShowMore] = useState(false);
// 显示子列数
const [showItemCount, setShowItemCount] = useState(1);
const [showItemCount, setShowItemCount] = useState(5);
// 箭头方向
const [arrow, setArrow] = useState(false);
@ -74,7 +74,7 @@ function CommentItem ({
<span className="item-name">{author.name || ''}</span>
<span className="item-time">{time || ''}</span>
<span className={_classNames}>
<Icon type="close" onClick={() => deleteComment(id)}/>
<span className="iconfont icon-shanchu icon_font_size_14" onClick={() => deleteComment(id)}></span>
</span>
</div>
);
@ -95,7 +95,7 @@ function CommentItem ({
const commentAppend = (children = []) => {
const len = children.length;
const _moreClass = len > 1 ? 'comment_item_loadmore show' : 'comment_item_loadmore'
const _moreClass = len > showItemCount ? 'comment_item_loadmore show' : 'comment_item_loadmore'
const lastTxt = len - showItemCount;
const renderChild = (children) => {
return children.map((child, i) => {
@ -112,7 +112,7 @@ function CommentItem ({
key={`child_${i}`}
className={showOrHide}
>
<div className="comment_item_area">
<div className="comment_item_area comment_child_item_area">
{commentAvatar(author)}
<div className="item-flex item-desc">
{commentInfo(id, author, time, can_delete)}
@ -179,13 +179,14 @@ function CommentItem ({
<CommentIcon
style={{ display: isAdmin ? 'inline-block' : 'none'}}
className='comment-icon-margin'
type={!hidden ? "eye" : 'eye-invisible'}
type={!hidden ? "xianshi" : 'yincang1'}
iconClick={() => handleShowOrHide(id, !hidden ? 1 : 0)}
/>
{/* 回复 */}
<CommentIcon
className='comment-icon-margin'
type="message" count="100"
type="huifu1"
count={children.length}
iconClick={handleClickMessage}
/>
{/* 点赞 */}
@ -193,7 +194,7 @@ function CommentItem ({
iconColor={ user_praise ? '#5091FF' : '' }
className='comment-icon-margin'
theme={user_praise ? 'filled' : ''}
type="like"
type="dianzan"
count={praise_count}
iconClick={() => handleClickLick(id)}
/>

@ -27,6 +27,13 @@ $ml: 20px;
padding: 20px 0;
box-sizing: border-box;
border-bottom: 1px solid $bdColor;
.comment_child_item_area:hover{
.item-close{
display: inline-block;
}
}
.flex-image{
width: 48px;
height: 48px;
@ -46,7 +53,7 @@ $ml: 20px;
margin-left: $ml;
}
.item-close{
display: inline-block;
display: none;
cursor: pointer;
float: right;
}
@ -54,6 +61,7 @@ $ml: 20px;
.item-close.hide{
display: none;
}
}
.item-ctx{
line-height: $lh22;
@ -140,6 +148,10 @@ $ml: 20px;
}
}
}
.icon_font_size_14{
font-size: 14px !important;
}
}
.comment_form_area,

@ -25,23 +25,22 @@ class NewShixunModel extends Component{
}
componentDidMount() {
let{page,type,keyword,order,diff,limit,status,sort}=this.state;
let newsort=sort
if(this.props&&this.props.user.course_name===undefined){
newsort="created_at";
}else{
newsort="publish_time";
}
if(this.props.type==='shixuns'){
this.getdatalist(page,type,status,keyword,order,diff,limit,undefined,newsort);
this.getdatalist(page,type,status,keyword,order,diff,limit,undefined,sort);
}else{
this.getdatalist(page,type,undefined,keyword,order,undefined,limit,undefined,sort);
}
}
getdatalist=(page,type,newstatus,keyword,order,diff,limit,pagetype,sort)=>{
getdatalist=(page,type,newstatus,keyword,order,diff,limit,pagetype,sorts)=>{
let newsort=sorts;
if(this.props.type==="shixuns"&&type==="mine"){
if(this.props&&this.props.user.course_name===undefined){
newsort="created_at";
}else{
newsort="publish_time";
}
}
this.setState({
isspinning:true
})
@ -53,14 +52,14 @@ class NewShixunModel extends Component{
url="/subject_lists.json";
}
axios.get(url,{params:{
page,
type,
status,
keyword,
order,
diff,
limit,
sort
page:page,
type:type,
status:status,
keyword:keyword,
order:order,
diff:diff,
limit:limit,
sort:newsort
}}).then((response) => {
if(response.data){
if(pagetype===undefined){

@ -3,8 +3,8 @@
* @Author: tangjiang
* @Github:
* @Date: 2019-12-03 15:20:55
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-03 20:36:24
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-25 11:41:42
*/
import './index.scss';
import React from 'react';
@ -46,6 +46,7 @@ function ErrorResult (props) {
case 3: // 创建pod失败
result = (
<div className={'error_result_wrap'}>
<p>系统繁忙请稍后重试</p>
</div>
);
break;

@ -3,8 +3,8 @@
* @Author: tangjiang
* @Github:
* @Date: 2019-11-28 08:44:54
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-19 10:44:16
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-25 11:42:10
*/
import './index.scss';
import React, { useState, useEffect } from 'react';
@ -82,7 +82,7 @@ function ExecResult (props) {
} else if (state === 4){
return (
<p className={'result_info_style'}>
{error_msg}
系统繁忙请稍后重试
</p>
)
} else if (state === -1) {

@ -4,11 +4,11 @@
* @Github:
* @Date: 2019-11-27 10:58:37
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-24 16:48:56
* @LastEditTime : 2019-12-25 10:02:03
*/
import './index.scss';
import React from 'react';
import { Icon } from 'antd';
// import { Icon } from 'antd';
const numberal = require('numeral');
const TextNumber = (props) => {
@ -47,14 +47,18 @@ const TextNumber = (props) => {
const renderCtx = (className, theme) => {
if (type === 'icon') { // 图标加文字时
const _className = `text_number_area text_icon_numb flex_${position} ${className}`;
const _classIcon = `iconfont icon-${text} numb_icon`;
return (
<div className={_className}>
<Icon
{/* <Icon
theme={theme}
onClick={handleIconClick}
type={text}
className={'numb_icon'}
></Icon>
></Icon> */}
<span
className={_classIcon}
onClick={handleIconClick}>
</span>
{renderNumb()}
</div>
)

@ -77,7 +77,12 @@
}
}
.oj_item_name{
flex-wrap: wrap;
color: #459be5;
cursor: pointer;
max-width: 510px;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
}

@ -117,7 +117,7 @@
}
.comp_ctx{
height: calc(100vh - 178px);
// height: calc(100vh - 178px);
overflow-y: hidden;
}

@ -4,17 +4,21 @@
* @Github:
* @Date: 2019-11-27 09:49:35
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-24 17:58:26
* @LastEditTime : 2019-12-25 10:55:44
*/
import './index.scss';
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import Comment from '../../../../../common/components/comment';
import { connect } from 'react-redux';
import actions from '../../../../../redux/actions';
import { Pagination } from 'antd';
const CommentTask = (props) => {
// 当前页
const [current, setCurrent] = useState(1);
const {
pages,
isAdmin,
identifier,
commentLists,
@ -23,7 +27,8 @@ const CommentTask = (props) => {
deleteComment,
getCommentLists,
showOrHideComment,
replayChildComment
replayChildComment,
changePagination
} = props;
useEffect(() => {
@ -35,7 +40,6 @@ const CommentTask = (props) => {
// 添加评论
const handleAddComment = (ctx) => {
console.log('添加的评论内容: ', ctx);
addComment(identifier, {
comments: {
content: ctx
@ -53,7 +57,7 @@ const CommentTask = (props) => {
}
// 删除评论
const handleSubmitDeleteComment = (id) => {
console.log('删除评论:', identifier, id);
// console.log('删除评论:', identifier, id);
deleteComment(identifier, id);
}
@ -72,6 +76,20 @@ const CommentTask = (props) => {
});
}
// 点击分页
const handlePageChange = (page, pageSize) => {
setCurrent(page);
changePagination(page);
// setTimeout(() => {
// 调用查询接口
getCommentLists(identifier);
// }, 300);
}
const _style = {
display: pages.total > pages.limit ? 'block' : 'none'
}
return (
<div className="task_comment_task">
<Comment
@ -83,13 +101,24 @@ const CommentTask = (props) => {
showOrHideComment={handleShowOrHideComment}
submitDeleteComment={handleSubmitDeleteComment}
/>
<div className="task_comment_page" style={ _style }>
<Pagination
showQuickJumper
current={current}
pageSize={pages.limit}
total={pages.total}
onChange={handlePageChange}
/>
</div>
</div>
)
}
const mapStateToProps = (state) => {
const {
commentLists // 评论列表
commentLists, // 评论列表
pages
} = state.commentReducer;
const {
comment_identifier
@ -98,7 +127,8 @@ const mapStateToProps = (state) => {
return {
commentLists,
isAdmin: userInfo.admin,
identifier: comment_identifier
identifier: comment_identifier,
pages
}
}
@ -110,6 +140,7 @@ const mapDispatchToProps = (dispatch) => ({
deleteComment: (identifier, id) => dispatch(actions.deleteComment(identifier, id)),
likeComment: (identifier, id, params) => dispatch(actions.likeComment(identifier, id, params)),
showOrHideComment: (identifier, id, params) => dispatch(actions.showOrHideComment(identifier, id, params)),
changePagination: (page) => dispatch(actions.changePagination(page))
})
export default connect(

@ -1,8 +1,16 @@
.task_comment_task{
display: flex;
flex-direction: column;
justify-content: space-between;
background: #fff;
padding: 20px 30px 0;
height: calc(100vh - 177px);
box-sizing: border-box;
overflow-y: auto;
border-bottom: 1px solid rgba(244,244,244,1);
.task_comment_page{
padding: 10px 0;
text-align: center;
}
}

@ -3,12 +3,12 @@
* @Author: tangjiang
* @Github:
* @Date: 2019-11-27 09:49:33
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-20 19:35:01
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-25 14:45:20
*/
import './index.scss';
import React, { useState, useEffect } from 'react';
import { Table, Icon, message } from 'antd';
import { Table, Icon, message, Pagination } from 'antd';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import actions from '../../../../../redux/actions';
@ -20,6 +20,7 @@ import ErrorResult from '../../../components/errorResult';
const numberal = require('numeral');
const {reviewResult} = CONST;
// 表格列
const columns = [
{
title: '提交时间',
@ -60,29 +61,30 @@ const columns = [
}
]
const paginationConfig = {
total: 1, // 总条数
pageSize: 10, // 每页显示条数
current: 1, // 当前页数
showQuickJumper: true
}
// const paginationConfig = {
// total: 1, // 总条数
// pageSize: 5, // 每页显示条数
// current: 1, // 当前页数
// showQuickJumper: true
// }
const CommitRecord = (props) => {
const {
identifier,
pages,
commitRecord,
// excuteState,
language,
operateType,
commitRecordDetail,
getUserCommitRecord
getUserCommitRecord,
changeRecordPagination
} = props;
const [pagination, setPagination] = useState(paginationConfig);
const [tableData, setTableData] = useState([]);
const [current, setCurrent] = useState(1);
// const [pagination, setPagination] = useState(paginationConfig);
// const [tableData, setTableData] = useState([]);
// 复制面板
let clipboard;
// const [recordDetail, setRecordDetail] = useState({});
const [renderCtx, setRenderCtx] = useState(() => {
return function () {
@ -140,12 +142,12 @@ const CommitRecord = (props) => {
getUserCommitRecord(identifier);
}, []);
// 提交记录变化时,同步到表单数据
useEffect(() => {
const len = commitRecord.length;
const pageConfig = Object.assign({}, paginationConfig, {total: len});
setTableData(commitRecord);
setPagination(pageConfig);
}, [commitRecord]);
// useEffect(() => {
// // const len = commitRecord.length;
// // const pageConfig = Object.assign({}, paginationConfig, {total: len});
// setTableData(commitRecord);
// // setPagination(pageConfig);
// }, [commitRecord]);
// 提交详情变化时,显示当前提交信息
useEffect(() => {
// setRecordDetail(commitRecordDetail);
@ -179,20 +181,46 @@ const CommitRecord = (props) => {
// });
// }
//
const handleTableChange = (pagination) => {
setPagination(Object.assign({}, pagination));
// const handleTableChange = (pagination) => {
// setPagination(Object.assign({}, pagination));
// }
const handlePaginationChange = (page) => {
setCurrent(page);
changeRecordPagination(page);
// 调用查询接口
getUserCommitRecord(identifier);
// setPagination(Object.assign({}, pagination, { current: page}));
// console.log('======>>>>>>', pagination)
}
// console.log(commitRecord);
const _style = {
display: pages.total > pages.limit ? 'block' : 'none'
};
return (
<div className={'commit_record_area'}>
{renderCtx()}
<Table
columns={columns}
rowKey={function (record) { return `key_${record.id}`}}
dataSource={tableData}
pagination={pagination}
onChange={handleTableChange}
/>
<div className="commit_record_table_pagination">
<Table
columns={columns}
rowKey={function (record) { return `key_${record.id}`}}
dataSource={commitRecord}
// pagination={pagination}
// onChange={handleTableChange}
pagination={false}
/>
<div className="commit_record_pagination" style={_style}>
<Pagination
showQuickJumper
pageSize={pages.limit}
current={current}
total={pages.total}
onChange={handlePaginationChange}
/>
</div>
</div>
</div>
)
}
@ -207,7 +235,8 @@ const mapStateToProps = (state) => {
commitRecordDetail,
commitRecord,
hack,
operateType
operateType,
pages
} = ojForUserReducer;
const { excuteState } = commonReducer;
return {
@ -216,11 +245,13 @@ const mapStateToProps = (state) => {
commitRecord, // 提交记录
excuteState, // 代码执行状态
language: hack.language,
operateType
operateType,
pages
}
}
const mapDispatchToProps = (dispatch) => ({
getUserCommitRecord: (identifier) => dispatch(actions.getUserCommitRecord(identifier))
getUserCommitRecord: (identifier) => dispatch(actions.getUserCommitRecord(identifier)),
changeRecordPagination: (page) => dispatch(actions.changeRecordPagination(page))
});
export default connect(

@ -2,7 +2,20 @@
// padding: 20px 30px;
padding: 0 20px;
overflow-y: auto;
height: calc(100vh - 177px);
// height: calc(100vh - 177px);
height: calc(100vh - 122px);
.commit_record_table_pagination{
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
.commit_record_pagination{
padding: 10px 0;
text-align: center;
}
}
.record_header{
display: flex;
// justify-content: space-between;

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-23 11:33:41
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-24 17:16:54
* @LastEditTime : 2019-12-25 11:07:42
// */
import './index.scss';
import React, { useState, useEffect, useMemo } from 'react';
@ -96,7 +96,7 @@ const LeftPane = (props) => {
// 添加评论
const handleAddComment = (ctx) => {
console.log('添加的评论内容: ', ctx, props.identifier);
// console.log('添加的评论内容: ', ctx, props.identifier);
props.identifier && props.addComment(props.identifier, {
comments: {
content: ctx
@ -104,6 +104,10 @@ const LeftPane = (props) => {
});
};
const _style = {
display: defaultActiveKey === 'record' ? 'none' : 'flex'
};
return (
<React.Fragment>
<ul className={'add_editor_list_area'}>
@ -112,7 +116,7 @@ const LeftPane = (props) => {
<div className="comp_ctx">
{ renderComp }
</div>
<div className={'number_area'}>
<div className={'number_area'} style={_style}>
<div className="number_flex flex_count" style={{ display: defaultActiveKey !== 'comment' ? 'flex' : 'none'}}>
<TextNumber text="通过次数" number={pass_count} position="vertical"/>
<Divider type="vertical" style={{ height: '20px', margin: '10px 20px' }}/>
@ -125,10 +129,10 @@ const LeftPane = (props) => {
/>
</div>
<div className="number_flex flex_info">
<TextNumber text="message" number={comments_count} type="icon" onIconClick={handleClickMessage}/>
<TextNumber text="huifu1" number={comments_count} type="icon" onIconClick={handleClickMessage}/>
<TextNumber
className={user_praise ? 'like active' : 'like'}
text="like"
text="dianzan"
number={praises_count}
theme={user_praise ? 'filled' : ''}
type="icon"

@ -54,10 +54,10 @@
.commit_record_area{
padding: 0 20px;
// height: calc(100vh - 178px);
// overflow-y: auto;
}
.task_description_area{
height: calc(100vh - 177px);
.task_desc_area{
height: calc(100vh - 242px);
overflow-y: auto;

@ -3,8 +3,8 @@
* @Author: tangjiang
* @Github:
* @Date: 2019-11-27 09:49:30
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-20 09:39:35
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-25 14:50:37
*/
import '../index.scss';
import React from 'react';
@ -37,7 +37,7 @@ const TaskDescription = (props) => {
</p>
<p className={'header_flex'}>
<span className={'flex_label'}>出题者:</span>
<Link to="/messages/innov/message_detail" target="_blank" style={{ color: '#5091FF'}}>{username}</Link>
<Link to="/users/innov/courses" target="_blank" style={{ color: '#5091FF'}}>{username}</Link>
</p>
</div>
<div className="task_desc_area">

@ -502,6 +502,7 @@ class DetailCardsEditAndAdd extends Component{
<a className={ "paragraph_name paragraph_nameid"}
href={/shixuns/+item.shixun_identifier}
target="_blank"
>
<span className="subject_stage_shixun_index">

@ -504,6 +504,7 @@ class DetailCardsEditAndEdit extends Component{
<a className={ "paragraph_name paragraph_nameid"}
href={/shixuns/+item.shixun_identifier}
target="_blank"
>
<span className="subject_stage_shixun_index">

@ -353,9 +353,15 @@ class NewHeader extends Component {
// this.setState({
// isRender:true
// })
// let newTPMsettings=this.props.user&&this.props.user.user_id+'newTPMsettings'
// let shixunopenprocess=this.props.user&&this.props.user.user_id+'shixunopenprocess'
// let openopenpublictype=this.props.user&&this.props.user.user_id+'openopenpublictype'
var url = `/accounts/logout.json`;
// let storage=window.localStorage;
axios.get((url)).then((result) => {
// storage.removeItem(newTPMsettings);
// storage.removeItem(shixunopenprocess);
// storage.removeItem( openopenpublictype);
if(result!==undefined){
// this.setState({
// isRender:true

@ -99,7 +99,8 @@ class TPMBanner extends Component {
this.setState({
openknow:false
})
storage.setItem("shixunopenprocess",true);
let shixunopenprocess=this.props.user&&this.props.user.user_id+'shixunopenprocess';
storage.setItem(shixunopenprocess,true);
}
openshowpublic=()=>{
@ -107,7 +108,8 @@ class TPMBanner extends Component {
this.setState({
openshowpublictype:false
})
storage.setItem("openopenpublictype",true);
let openopenpublictype=this.props.user&&this.props.user.user_id+'openopenpublictype';
storage.setItem(openopenpublictype,true);
}
@ -121,13 +123,14 @@ class TPMBanner extends Component {
})
}
}
let shixunopenprocess=window.localStorage.shixunopenprocess;
let openopenpublictype=window.localStorage.openopenpublictype;
let getshixunopenprocess=this.props.user&&this.props.user.user_id+'shixunopenprocess';
let getopenopenpublictype=this.props.user&&this.props.user.user_id+'openopenpublictype';
let shixunopenprocess=window.localStorage.getItem(getshixunopenprocess)
let openopenpublictype=window.localStorage.getItem(getopenopenpublictype)
if(this.props.status===0&&this.props.openknows===false){
if(this.props.shixunsDetails&&this.props.shixunsDetails.shixun_status === 0 && this.props.identity < 5){
if(shixunopenprocess===undefined||shixunopenprocess===false){
if(shixunopenprocess===undefined||shixunopenprocess===false||shixunopenprocess===null){
this.setState({
openknow:true
})
@ -147,7 +150,7 @@ class TPMBanner extends Component {
if(this.props.public===0&&this.props.status>1&&this.props.openknows===false){
if(this.props.shixunsDetails&&this.props.shixunsDetails.shixun_status === 2 && this.props.shixunsDetails&&this.props.shixunsDetails.public===0 && this.props.identity < 5){
if(openopenpublictype===undefined||openopenpublictype===false){
if(openopenpublictype===undefined||openopenpublictype===false||openopenpublictype===null){
this.setState({
openshowpublictype:true
})
@ -857,7 +860,7 @@ class TPMBanner extends Component {
`
.shixunDetail_top{
height: 180px !important;
padding-top:35px !important;
padding-top:50px !important;
}
.ant-popover{
z-index:1000 !important;
@ -900,9 +903,9 @@ class TPMBanner extends Component {
}
</p>
<div className="clearfix mt30">
<div className="clearfix mt10">
<ul className="fl color-grey-c pathInfo">
<ul className="fl color-grey-c pathInfo mt20">
{shixunsDetails&&shixunsDetails.stu_num===0?"":<li>
<span>学习人数</span>
<span className="mt3">{shixunsDetails.stu_num}</span>
@ -973,7 +976,7 @@ class TPMBanner extends Component {
</div>
</div>
}>
<div className="pr fl" id="commentsStar">
<div className="pr fl mt15" id="commentsStar">
<div className={"color-grey-c ml15"} style={{color: "#fff", textAlign: "center"}}>学员评分</div>
<div className="rateYo">
<MyRate allowHalf defaultValue={star_info[0]} disabled/>
@ -1307,7 +1310,7 @@ class TPMBanner extends Component {
}
</style>:""
}
<Modal
{Forkvisible===true?<Modal
keyboard={false}
title="Fork原因"
visible={Forkvisible}
@ -1338,8 +1341,11 @@ class TPMBanner extends Component {
</Radio>
{this.state.Radiovalue === 4 ?
<TextArea className={this.state.TextAreaintshow===true?"bor-red mt10":"mt10"}
placeholder="请填写fork原因60字以内)"
value={this.state.TextArea}
rows={4} style={{ width: '85%', marginLeft: '30px' }} onInput={this.changeTextArea}/>: null}
rows={4} style={{ width: '85%', marginLeft: '30px' }} onInput={this.changeTextArea}
maxlength={60}
/>: null}
{this.state.TextAreaintshow===true?<div className={"color-red ml30"}>不能为空</div>:""}
</Radio.Group>
</div>
@ -1351,7 +1357,7 @@ class TPMBanner extends Component {
}
</Modal>
</Modal>:""}
<Modal
keyboard={false}

@ -157,11 +157,13 @@ class TPMIndex extends Component {
this.setState({
openknows:false
})
storage.setItem("newTPMsettings",true);
let newTPMsettings=this.props.user&&this.props.user.user_id+'newTPMsettings'
storage.setItem(newTPMsettings,true);
}
componentDidMount = () => {
let newTPMsettings=window.localStorage.newTPMsettings;
let getnewTPMsettings=this.props.user&&this.props.user.user_id+'newTPMsettings'
let newTPMsettings=window.localStorage.getItem(getnewTPMsettings)
let id = this.props.match.params.shixunId;
// console.log('props', this.props);
// let collaborators = `/shixuns/` + id + `/propaedeutics.json`;
@ -214,7 +216,7 @@ class TPMIndex extends Component {
if(response.data.identity <4){
if(newTPMsettings===undefined||newTPMsettings===false){
if(newTPMsettings===undefined||newTPMsettings===false||newTPMsettings===null){
this.setState({
openknows:true
})
@ -423,22 +425,24 @@ class TPMIndex extends Component {
{ this.state.is_jupyter===false? <Menu.Item key="8" className={"competitionmr50"}>
<span className={"tpmbannernavstyler"}>排行榜</span>
</Menu.Item>:""}
{this.state.identity >4||this.state.identity===undefined ? "":
<Menu.Item key="9" className={"competitionmr50"}>
<Popover
<span>
<Popover
content={
<pre className={"bannerpd201"}>
<div>更多设置在这里点击配置看一看~</div>
<div className={"wechatcenter mt15"}><Button type="primary" onClick={this.openknow} >我知道了</Button></div>
</pre>
<div>更多设置在这里点击配置看一看~</div>
<div className={"wechatcenter mt15"}><Button type="primary" onClick={this.openknow} >我知道了</Button></div>
</pre>
}
trigger="click"
placement="top"
visible={this.state.openknows}
>
</Popover>
</span>
{this.state.identity >4||this.state.identity===undefined ? "":
<Menu.Item key="9" className={"competitionmr50"}>
<span className={"tpmbannernavstyler"}>配置</span>
</Popover>
</Menu.Item>
}

@ -35,14 +35,14 @@ if (!window['indexHOCLoaded']) {
// $('head').append($('<link rel="stylesheet" type="text/css" />')
// .attr('href', `${_url_origin}/stylesheets/educoder/antd.min.css?1525440977`));
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/css/edu-common.css?66`));
.attr('href', `${_url_origin}/stylesheets/css/edu-common.css?8`));
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?66`));
.attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?8`));
// index.html有加载
$('head').append($('<link rel="stylesheet" type="text/css" />')
.attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?66`));
.attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?8`));
// $('head').append($('<link rel="stylesheet" type="text/css" />')

@ -65,7 +65,8 @@ export default class Shixuninformation extends Component {
oldscope_partment: [],
scope_partment: [],
loading: false,
opening_timetype:false
opening_timetype:false,
use_scope_type:false
}
}
@ -80,6 +81,7 @@ export default class Shixuninformation extends Component {
timetype=true;
}
this.setState({
use_scope_type:this.props&&this.props.status>1&& this.props.data && this.props.data.shixun.use_scope===0&&this.props&&this.props.identity>2||this.props&&this.props.public===2&& this.props.data && this.props.data.shixun.use_scope===0&&this.props&&this.props.identity>2?true:false,
can_copy: this.props.data && this.props.data.shixun.can_copy === undefined ? false : this.props.data && this.props.data.shixun.can_copy,
use_scope: this.props.data && this.props.data.shixun.use_scope,
opening_time: this.props.data && this.props.data.shixun.opening_time,
@ -115,6 +117,7 @@ export default class Shixuninformation extends Component {
timetype=true;
}
this.setState({
use_scope_type:this.props&&this.props.status>1&& this.props.data && this.props.data.shixun.use_scope===0&&this.props&&this.props.identity>2||this.props&&this.props.public===2&& this.props.data && this.props.data.shixun.use_scope===0&&this.props&&this.props.identity>2?true:false,
can_copy: this.props.data && this.props.data.shixun.can_copy === undefined ? false : this.props.data && this.props.data.shixun.can_copy,
use_scope: this.props.data && this.props.data.shixun.use_scope,
opening_time: this.props.data && this.props.data.shixun.opening_time,
@ -194,7 +197,7 @@ export default class Shixuninformation extends Component {
SelectOpenpublic = (e) => {
this.setState({
use_scope: e.target.value
use_scope: e.target.value,
});
}
@ -295,6 +298,8 @@ export default class Shixuninformation extends Component {
const dateFormat = 'YYYY-MM-DD HH:mm';
// console.log()
console.log(this.props&&this.props.identity<8)
return (
<div>
<div className="educontent mb200 edu-back-white padding10-20 pdb30 mb50">
@ -308,8 +313,8 @@ export default class Shixuninformation extends Component {
</span>
</div>}
<div className="edu-back-white mb10 ml30 mt20">
<div>
<div className="edu-back-white mb10 ml30 mt20">
{this.props&&this.props.status>1&&this.state.use_scope===0&&this.props&&this.props.identity>2&&this.state.use_scope_type===true||this.props&&this.props.public===2&&this.state.use_scope===0&&this.props&&this.props.identity>2&&this.state.use_scope_type===true?"":<div>
<span className="color-grey-6 mt5 fl font-16" style={{minWidth: '45px'}}>公开程度:</span>
<span className="fl mt8 ml20">
<RadioGroup onChange={this.SelectOpenpublic} value={this.state.use_scope}>
@ -387,7 +392,7 @@ export default class Shixuninformation extends Component {
</span>
</div>
</div>}
<div className="clearfix mt20">
<span className="color-grey-6 mt5 fl font-16" style={{minWidth: '45px'}}>开启时间:</span>

@ -953,10 +953,10 @@ class Shixuninformation extends Component {
<div>
{this.state.mainvalues === undefined && this.state.subvalues === undefined || this.state.mainvalues === "" && this.state.subvalues === "" ? "" :
<div className={"font-12"} style={{'max-width': '600px'}}>
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : `已安装软件:` + this.state.mainvalues}`}
{`${this.state.subvalues === undefined || this.state.subvalues === "" ? "" : this.state.mainvalues === undefined || this.state.mainvalues === "" ? `已安装软件:` + this.state.subvalues : this.state.subvalues}`}
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : `说明:添加了` + this.state.mainvalues}${this.state.subvalues === undefined || this.state.subvalues === "" ? "" :
this.state.mainvalues === undefined || this.state.mainvalues === "" ? `说明:添加了` + this.state.subvalues : this.state.subvalues}`}
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : this.state.mainvalues}`}
{`${this.state.subvalues === undefined || this.state.subvalues === "" ? "" : this.state.mainvalues === undefined || this.state.mainvalues === "" ? this.state.subvalues : this.state.subvalues}`}
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : this.state.mainvalues}${this.state.subvalues === undefined || this.state.subvalues === "" ? "" :
this.state.mainvalues === undefined || this.state.mainvalues === "" ? this.state.subvalues : this.state.subvalues}`}
</div>}
</div>
</span>
@ -1185,7 +1185,11 @@ class Shixuninformation extends Component {
closable={false}
footer={null}
>
<div className="task-popup-content"><p className="task-popup-text-center font-16">评测脚本生成成功</p></div>
<div className="task-popup-content">
{/*<p className="task-popup-text-center font-16">已根据您的选择,生成新的评测脚本!</p>*/}
{/*<p className="task-popup-text-center font-16 mt10">您之前使用的脚本已复制到剪贴板可通过Ctrl+C贴贴</p>*/}
<p className="task-popup-text-center font-16">评测脚本生成成功</p>
</div>
<div className="task-popup-sure clearfix">
<a className="task-btn task-btn-orange" onClick={() => this.hidestandard_scriptsModal()}>确定</a>
</div>

@ -82,18 +82,18 @@ class TPMRightSection extends Component {
<div className="flex1">
<div className="creatorname sortinxdirection space-between">
<div className={"creatornamelist"}>
<div className={"creatornamelist color-grey-3"}>
{TPMRightSectionData === undefined ? "" : TPMRightSectionData.creator === undefined ? "" : TPMRightSectionData.creator.name}
</div>
<div className={"creatornamelist width80center"}>
{TPMRightSectionData.user_shixuns_count}
<span className={"color888hezuo"}>共发布实训</span> <span className={"color-grey-3"}>{TPMRightSectionData.user_shixuns_count}</span> <span className={"color888hezuo"}></span>
</div>
</div>
<div className="clearfix">
<span className={"fr color888hezuo"}>发布实训项目</span>
{/*<span className="ml20">粉丝 <span id="user_h_fan_count">{TPMRightSectionData.fans_count}</span></span>*/}
{/* <a href="/watchers/unwatch?className=fr+user_watch_btn+edu-default-btn+edu-focus-btn&amp;object_id=3039&amp;object_type=user&amp;shixun_id=61&amp;target_id=3039" className="fr edu-default-btn user_watch_btn edu-focus-btn" data-method="post" data-remote="true" id="cancel_watch" rel="nofollow">取消关注</a> */}
</div>
{/*<div className="clearfix">*/}
{/* <span className={"fr color888hezuo"}>发布实训项目</span>*/}
{/* /!*<span className="ml20">粉丝 <span id="user_h_fan_count">{TPMRightSectionData.fans_count}</span></span>*!/*/}
{/* /!* <a href="/watchers/unwatch?className=fr+user_watch_btn+edu-default-btn+edu-focus-btn&amp;object_id=3039&amp;object_type=user&amp;shixun_id=61&amp;target_id=3039" className="fr edu-default-btn user_watch_btn edu-focus-btn" data-method="post" data-remote="true" id="cancel_watch" rel="nofollow">取消关注</a> *!/*/}
{/*</div>*/}
</div>
</div>

@ -98,14 +98,15 @@
}
.creatornamelist {
-o-text-overflow: ellipsis;
cursor: default;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
width: 139px;
}
.width80center {
width: 80px;
font-size:12px;
text-align: center;
}

@ -19,13 +19,18 @@ import actions from '../../../redux/actions';
import RightPane from './rightPane';
import MyIcon from "../../../common/components/MyIcon";
function clearSlct() {
if("getSelection" in window){
window.getSelection().removeAllRanges();
}else{
document.selection.empty();
};
}
function jsCopy(s) {
var copyEle = document.getElementById(s);
const range = document.createRange(); // 创造range
window.getSelection().removeAllRanges(); //清除页面中已有的selection
range.selectNode(copyEle); // 选中需要复制的节点
window.getSelection().addRange(range); // 执行选中元素
const copyStatus = document.execCommand("Copy"); // 执行copy操作
clearSlct();
const copyEle = document.getElementById(s);
copyEle.select();
const copyStatus=document.execCommand("Copy");
// 对成功与否定进行提示
copyStatuss(copyStatus)
}
@ -66,7 +71,8 @@ function JupyterTPI (props) {
jupytertime,
active_with_tpi,
spinning,
updataspinning
updataspinning,
jupyter_folder_name
} = props;
const emptyCtx = (
@ -85,7 +91,7 @@ function JupyterTPI (props) {
// 保存代码
const addEventListeners = () => {
window.addEventListener('message', (e) => {
console.log("触发了jupytermessage");
// console.log("触发了jupytermessage");
if(e){
if(e.data){
if(e.data==="jupytermessage"){
@ -274,8 +280,8 @@ function JupyterTPI (props) {
mouseLeaveDelay={0.3}
>
<div className="sortinxdirection">
<Icon type="file-text" className="jupyter_icon fl lineheighttaj" />
<a className="jupyter_name ml10 maxnamewidth150 lineheighttaj colorlineheighttaj" title={item.title}>{item.title}</a>
<Icon type="file-text" className="jupyter_icon fl lineheighttaj filestyles" />
<a className="jupyter_name ml10 maxnamewidth181 lineheighttaj colorlineheighttaj" title={item.title}>{item.title}</a>
<a className={"fr color-blue lineheighttaj"}
onClick={() => {
jsCopy("file_path"+i)
@ -382,11 +388,22 @@ function JupyterTPI (props) {
>
{/*<p className={"RightPaneDrawertop"}></p>*/}
<div className="jupyter_data_sets_area newjupyter_data_sets_area">
<h2 className="jupyter_h2_title">
<h2 className="jupyter_h2_title bortop17212F">
{/*<MyIcon type="iconwenti" className="jupyter_data_icon"/>*/}
<i className={"iconfont icon-base"}></i>
{/* <span className="iconfont icon-java jupyter_data_icon"></span>数据集 */}
</h2>
<h2 className="borbottom17212F jupyterfilepaths">
<span className={"ml50"}>文件路径</span>
<div className="sortinxdirection">
<a className="jupyter_name ml50 maxnamewidth200 lineheighttaj colorlineheighttaj">{jupyter_folder_name}</a>
<a className={"fr color-blue lineheighttaj font-14"}
onClick={() => {
jsCopy("jupyter_folder_name")
}}>复制地址</a>
</div>
<input id="jupyter_folder_name" className={"file_path_input"} value={jupyter_folder_name}/>
</h2>
{ renderCtx }
<div className='jupyter_pagination'>
{total<20?"":<Pagination
@ -413,6 +430,7 @@ const mapStateToProps = (state) => {
jupyter_data_set,
jupyter_tpi_url_state,
jupyter_data_set_count,
jupyter_folder_name,
jupyter_pagination,
jupyter_identifier
} = state.jupyterReducer;
@ -425,6 +443,7 @@ const mapStateToProps = (state) => {
jupyter_tpi_url_state,
total: jupyter_data_set_count,
pagination: jupyter_pagination,
jupyter_folder_name:jupyter_folder_name,
jupyter_identifier,
drawervisible,
jupytertime,

@ -23,7 +23,11 @@
cursor: row-resize;
width: 100%;
}
.filestyles{
color: #28b887 !important;
font-size: 25px !important;
margin-left:20px;
}
.Resizer.horizontal:hover {
border-top: 5px solid rgba(0, 0, 0, 0.5);
border-bottom: 5px solid rgba(0, 0, 0, 0.5);
@ -138,9 +142,9 @@
height:49px;
line-height: 49px;
background: #070F1A !important;
border-bottom: 1px solid #17212F !important;
//border-bottom: 1px solid #17212F !important;
color:#FFFFFF !important;
border-top: 1px solid #17212F !important;
//border-top: 1px solid #17212F !important;
}
.iconfont{
color:#28b887!important;
@ -193,4 +197,38 @@ line-height: 50px !important;
.jupyter_data_list{
padding-left: 20px;
}
.bortop17212F{
border-top: 1px solid #17212F !important;
}
.borbottom17212F{
border-bottom: 1px solid #17212F !important;
}
.jupyterfilepaths{
color: #888 !important;
font-size: 16px !important;
padding-left: 20px;
background: #070F1A !important;
}
.maxnamewidth200{
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
width: 200px;
}
.maxnamewidth181{
max-width:181px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
width: 181px;
}

@ -620,10 +620,10 @@ class Newshixuns extends Component {
<div>
{this.state.mainvalues === undefined && this.state.subvalues === undefined || this.state.mainvalues === "" && this.state.subvalues === "" ? "" :
<div className={"font-12"} style={{'max-width': '600px'}}>
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : `已安装软件:` + this.state.mainvalues}`}
{`${this.state.subvalues === undefined || this.state.subvalues === "" ? "" : this.state.mainvalues === undefined || this.state.mainvalues === "" ? `已安装软件:` + this.state.subvalues : this.state.subvalues}`}
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : `说明:添加了` + this.state.mainvalues}${this.state.subvalues === undefined || this.state.subvalues === "" ? "" :
this.state.mainvalues === undefined || this.state.mainvalues === "" ? `说明:添加了` + this.state.subvalues : this.state.subvalues}`}
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : this.state.mainvalues}`}
{`${this.state.subvalues === undefined || this.state.subvalues === "" ? "" : this.state.mainvalues === undefined || this.state.mainvalues === "" ? this.state.subvalues : this.state.subvalues}`}
{`${this.state.mainvalues === undefined || this.state.mainvalues === "" ? "" : this.state.mainvalues}${this.state.subvalues === undefined || this.state.subvalues === "" ? "" :
this.state.mainvalues === undefined || this.state.mainvalues === "" ? this.state.subvalues : this.state.subvalues}`}
</div>}
</div>

@ -1,14 +1,13 @@
import React, { Component } from 'react';
import { Link } from "react-router-dom";
import { markdownToHTML, configShareForCustom,getImageUrl,getUploadActionUrlthree,appendFileSizeToUploadFileAll} from 'educoder'
import { Divider, Tooltip,Upload,Spin} from 'antd';
import { Divider, Tooltip,Upload,Modal,Spin} from 'antd';
import LoadingSpin from '../../../../common/LoadingSpin';
import 'antd/lib/pagination/style/index.css';
import '../shixunchildCss/Challenges.css';
import axios from 'axios';
const $ = window.$;
class Challengesjupyter extends Component {
constructor(props) {
super(props)
@ -29,6 +28,7 @@ class Challengesjupyter extends Component {
enlarge:false,
fileList:[],
shuaxin:false,
showtime:false
}
}
@ -150,12 +150,15 @@ class Challengesjupyter extends Component {
window.addEventListener('message', (e) => {
console.log(e);
if(e){
if(e.data){
if(e.data==="jupytermessage"){
that.modifyjupyter();
if(this.state.showtime===false){
that.modifyjupyter();
this.setState({
showtime:true
})
}
}
}
@ -215,7 +218,7 @@ class Challengesjupyter extends Component {
modifyjupyter=()=>{
this.props.showNotification('实训正在保存中...!');
// this.props.showNotification('实训正在保存中...!');
let id=this.props.match.params.shixunId;
var jupyter_port="";
@ -235,11 +238,23 @@ class Challengesjupyter extends Component {
if (result.data.status === 0) {
// this.props.showNotification(`应用成功`);
console.log("应用成功了");
this.props.showNotification('实训保存成功!');
this.props.showNotification('保存成功!');
setTimeout(() => {
this.setState({
showtime:false
})
}, 500)
}else{
this.setState({
showtime:false
})
this.props.showNotification(result.data.message);
}
}).catch((error) => {
this.setState({
showtime:false
})
this.props.showNotification('实训保存失败!');
})
@ -316,6 +331,50 @@ class Challengesjupyter extends Component {
}
}
handleClickResetTpisync_code=(id)=>{
this.setState({
jupyter_url : null,
booljupyterurls:false,
})
const url = `/jupyters/reset_with_tpm.json`;
axios.get(url,{params:{
identifier:id
}}).then((response) => {
if(response.data.status===0){
setTimeout(()=>{
this.setState({
jupyter_url :response.data.url,
booljupyterurls:true,
})
},1000);
this.props.showNotification('重置实训成功!');
}
});
}
// 重置实训
handleClickResetTpi = () => {
let id=this.props.match.params.shixunId;
let that=this;
Modal.confirm({
title: '重置实训',
content: (
<p style={{ lineHeight: '24px' }}>
你在本文件中修改的内容将丢失,<br />
是否确定重新加载初始代码
</p>
),
okText: '确定',
cancelText: '取消',
onOk () {
that.handleClickResetTpisync_code(id)
},
onCancel() {
},
})
}
render() {
let{ChallengesDataList,booljupyterurls,enlarge,fileList}=this.state;
let id = this.props.match.params.shixunId;
@ -514,11 +573,12 @@ class Challengesjupyter extends Component {
}
</style>
<Upload {...uploadProps}>
<div className="challenbaocun" type="upload">
<p
className="challenbaocuntest" type="upload" >导入</p>
</div>
<div className="challenbaocun" type="upload">
<p className="challenbaocuntest" type="upload" >导入</p>
</div>
</Upload>
{/*<button type="button" className="ant-btn deletebuttom chongzhistyles" onClick={this.handleClickResetTpi}><span>重置实训</span></button>*/}
</div>
</div>

@ -122,7 +122,7 @@
}
.fabushixunwidth{
color: #000000;
font-size: 16px;
font-size: 12px;
}
.fabushixunwidthcolor{
color: #4CACFF;
@ -143,11 +143,11 @@
height:34px;
line-height: 34px;
}
.hezuozhe630{
width: 630px;
.hezuozhe655{
width: 655px;
}
.hezuozhe634{
width: 634px;
.hezuozhe655{
width: 655px;
}
.color333hezuo{
color:#333333;
@ -193,4 +193,8 @@
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
}
.centertop20{
text-align: center;
padding-top: 20%;
}

@ -118,6 +118,7 @@ class Collaborators extends Component {
if (type === "cooperation") {
this.setState({
Collaboratorsvisibleadmin: true,
Collaboratorsvisible: false,
});
} else if ("admin") {
let id = this.props.match.params.shixunId;
@ -132,6 +133,7 @@ class Collaborators extends Component {
} else {
this.setState({
Collaboratorsvisible: true,
Collaboratorsvisibleadmin: false,
Collaboratorslist: response.data
})
}
@ -517,17 +519,16 @@ class Collaborators extends Component {
closable={false}
footer={null}
>
<div className="mb15 font-14 edu-txt-center color-orange-tip">
选择的成员将会成为新的管理员<br/> 您将不再拥有管理员的权限但您仍是合作团队的一员
</div>
<div className="clearfix mb15 edu-bg-light-blue edu-max-h200">
<ul className="">
<li className="clearfix">
<RadioGroup onChange={this.onChange} value={this.state.value}>
<li className={Collaboratorslist&&Collaboratorslist.length===0?"centertop20 clearfix":"clearfix"}>
{Collaboratorslist&&Collaboratorslist.length===0?<span>
请先将新的管理员通过 <a className={"color-blue"} onClick={() => this.showCollaboratorsvisible("cooperation")}>"添加合作者"</a>
</span>:""}
<RadioGroup onChange={this.onChange}>
{
Collaboratorslist.length === 0 ? "" : Collaboratorslist.map((item, key) => {
return (
@ -536,7 +537,6 @@ class Collaborators extends Component {
)
})
}
</RadioGroup>
</li>
</ul>
@ -642,7 +642,7 @@ class Collaborators extends Component {
<style>
{
`
.collaborators-item-middles{width: 100% !important; margin-left: 20px;}
.collaborators-item-middles{width: 100% !important;}
.ysltithead{
padding-bottom: 20px;
}
@ -665,7 +665,7 @@ class Collaborators extends Component {
<div className="fl collaborators-item-middles">
<p className="mb10 sortinxdirection space-between hezuozhe634">
<p className="mb10 sortinxdirection space-between hezuozhe655">
<a href={item.user.user_url} target="_blank" className="yslusername">{item.user.name}</a>
{item.user.shixun_manager === true ? "" : <span>
<i className={this.state.hovertype===true&&key===this.state.hoverkey?"fontnewreds iconfont icon-shanchu_Hover":"fontneweees iconfont icon-shanchu_moren"}
@ -681,10 +681,10 @@ class Collaborators extends Component {
</p>
<p className="color-grey-B2 font-12 mb10 sortinxdirection mt14">
<p className="hezuozhe630 sortinxdirection space-between">
<p className="hezuozhe655 sortinxdirection space-between">
{/*<p className={item.user.identity===null||item.user.identity===undefined||item.user.identity===""?" font-16 ":"mr20 font-16 w70"}>{item.user.identity}</p>*/}
<p
className={item.user.school_name === null || item.user.school_name === "" ? "" : " font-16 color888hezuo maxfont450"}>{item.user.school_name}</p>
className={item.user.school_name === null || item.user.school_name === "" ? "" : " font-12 color888hezuo maxfont450"}>{item.user.school_name}</p>
<p className="fabushixunwidth color888hezuo">发布实训项目&nbsp;&nbsp;<span
className="ml2">{item.user.user_shixuns_count}</span></p>
</p>

@ -129,7 +129,7 @@ class Ranking_list extends Component {
{/*<li className="fl with13 edu-txt-center color-grey-74">*/}
{/*/!*{item.accuracy} %准确率*!/*/}
{/*</li>*/}
<li className="fl with25 edu-txt-center">{this.formatSeconds(item.use_time)}</li>
<li className="fl with25 edu-txt-center">{item.use_time===null?"":this.formatSeconds(item.use_time)}</li>
<li className="fl with14 edu-txt-center color-yellow">+{item.gold}金币 </li>
</div>
)

@ -217,3 +217,21 @@
.jupyterswidth{
width: 1140px;
}
.chongzhistyles{
color: #fff;
width: 85px !important;
height: 32px !important;
margin-right: 20px;
}
.chongzhistyles:hover, .chongzhistyles:focus{
color: #fff !important;
background-color: #29BD8B !important;
border-color: transparent;
}
.chongzhistyles:active, .chongzhistyles:active{
color: #fff !important;
background-color: #29BD8B !important;
border-color: transparent ;
}

@ -155,7 +155,7 @@ class ShixunCard extends Component {
<p className="font-14 color-white">非试用内容需要授权</p>
</div>
<a href={"/shixuns/"+item.identifier+"/challenges"} className="square-img">
<a href={"/shixuns/"+item.identifier+"/challenges"} className="square-img" target="_blank">
{/*<img src={getImageUrl("images/"+item.pic+"?1540534846")}/>*/}
<img src={setImagesUrl(`${item.pic}`)}/>
</a>
@ -163,7 +163,7 @@ class ShixunCard extends Component {
<div className="square-main">
<p className="task-hide">
<a href={"/shixuns/"+item.identifier+"/challenges"} className="justify color-grey-name" title={item.name}>
<a href={"/shixuns/"+item.identifier+"/challenges"} className="justify color-grey-name" title={item.name} target="_blank">
{item.name}
</a>
</p>

@ -55,6 +55,7 @@ const types = {
CLICK_OPERATE_TYPE: 'CLICK_OPERATE_TYPE', // 点击类型
CLEAR_OJ_FOR_USER_REDUCER: 'CLEAR_OJ_FOR_USER_REDUCER', // 退出时清空 ojForUserReducer保存内容
ADD_OJ_LIKE_COUNT: 'ADD_OJ_LIKE_COUNT', // 增加点赞数
CHANGE_RECORD_PAGINATION_PAGE: 'CHANGE_RECORD_PAGINATION_PAGE', // 改变提交分页
/*** jupyter */
GET_JUPYTER_DATA_SETS: 'GET_JUPYTER_DATA_SETS', // jupyter 数据集
GET_JUPYTER_TPI_URL: 'GET_JUPYTER_TPI_URL', // 获取 jupyter url
@ -74,7 +75,8 @@ const types = {
GET_COMMENT_LISTS: 'GET_COMMENT_LISTS', // 获取评论列表
REPLAY_CHILD_COMMENTS: 'REPLAY_CHILD_COMMENTS', // 子回复
DELETE_COMMENTS: 'DELETE_COMMENTS', // 删除评论
SAVE_COMMENT_IDENTIFIER: 'SAVE_COMMENT_IDENTIFIER' // 评论时的identifier
SAVE_COMMENT_IDENTIFIER: 'SAVE_COMMENT_IDENTIFIER', // 评论时的identifier
CHANGE_COMMENT_PAGINATION_PARAMS: 'CHANGE_COMMENT_PAGINATION_PARAMS', // 改变分页
}
export default types;

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-23 10:53:25
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-24 16:17:00
* @LastEditTime : 2019-12-25 10:55:27
*/
import types from "./actionTypes";
@ -31,8 +31,12 @@ export const addComment = (identifier, comments) => {
// 获取评论列表
export const getCommentLists = (identifier) => {
return (dispatch) => {
fetchCommentLists(identifier).then(res => {
return (dispatch, getState) => {
const {pages: {limit, page}} = getState().commentReducer;
fetchCommentLists(identifier, {
limit,
page
}).then(res => {
console.log('获取评论列表: ====>>>>', res);
if (res.status === 200) {
const {data} = res;
@ -112,3 +116,10 @@ export const showOrHideComment = (identifier, id, params) => {
}
}
// 改变分页条件
export const changePagination = (page) => {
return {
type: types.CHANGE_COMMENT_PAGINATION_PARAMS,
payload: page
};
}

@ -49,7 +49,8 @@ import {
saveUserCodeForInterval,
saveEditorCodeForDetail,
saveOpacityType,
clearOjForUserReducer
clearOjForUserReducer,
changeRecordPagination
// isUpdateCodeCtx
} from './ojForUser';
@ -71,7 +72,8 @@ import {
replayChildComment,
deleteComment,
likeComment,
showOrHideComment
showOrHideComment,
changePagination
} from './comment';
import {
@ -134,6 +136,7 @@ export default {
saveEditorCodeForDetail,
saveOpacityType,
clearOjForUserReducer,
changeRecordPagination,
// jupyter
getJupyterTpiDataSet,
getJupyterTpiUrl,
@ -155,4 +158,5 @@ export default {
deleteComment,
likeComment,
showOrHideComment,
changePagination
}

@ -52,12 +52,13 @@ export const getJupyterTpiDataSet = (identifier, params) => {
fetchJupyterTpiDataSet(identifier, params).then(res => {
if (res.data.status === 401) return; // 用户未登录
if (res.status === 200) {
const {data_sets, data_sets_count} = res.data;
const {data_sets, data_sets_count,folder_name} = res.data;
dispatch({
type: types.GET_JUPYTER_DATA_SETS,
payload: {
data_sets,
data_sets_count
data_sets_count,
folder_name,
}
});
}

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 13:42:11
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-23 11:55:48
* @LastEditTime : 2019-12-25 14:27:58
*/
import types from "./actionTypes";
import { Base64 } from 'js-base64';
@ -315,8 +315,12 @@ export const debuggerCode = (identifier,value, type) => {
// 获取提交记录
export const getUserCommitRecord = (identifier) => {
return (dispatch) => {
fetchUserCommitRecord(identifier).then(res => {
return (dispatch, getState) => {
const { pages: { limit, page } } = getState().ojForUserReducer;
fetchUserCommitRecord(identifier, {
limit,
page
}).then(res => {
const {status, data} = res;
if (status === 200) {
dispatch({
@ -477,5 +481,10 @@ export const clearOjForUserReducer = () => {
};
}
export const changeRecordPagination = (page) => {
return {
type: types.CHANGE_RECORD_PAGINATION_PAGE,
payload: page
}
}
// 更新通知状态

@ -6,7 +6,7 @@ import types from "../actions/actionTypes";
* @Github:
* @Date: 2019-12-23 10:35:31
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-23 14:51:42
* @LastEditTime : 2019-12-25 10:56:10
*/
const initialState = {
comments: {
@ -14,8 +14,9 @@ const initialState = {
},
commentLists: {}, // 评论列表
pages: {
limit: 20,
page: 1
limit: 15,
page: 1,
total: 1
}
};
@ -28,9 +29,17 @@ const commentReducer = (state = initialState, action) => {
...state
}
case types.GET_COMMENT_LISTS:
const {disscuss_count} = payload;
return {
...state,
commentLists: Object.assign({}, payload)
commentLists: Object.assign({}, payload),
pages: Object.assign({}, state.pages, { total: disscuss_count })
}
case types.CHANGE_COMMENT_PAGINATION_PARAMS:
const _pages = Object.assign({}, state.pages, { page: payload });
return {
...state,
pages: _pages
}
default:
return {

@ -25,11 +25,12 @@ const initState = {
const JupyterReducer = (state = initState, action) => {
switch (action.type) {
case types.GET_JUPYTER_DATA_SETS:
const { data_sets, data_sets_count } = action.payload;
const { data_sets, data_sets_count,folder_name} = action.payload;
return {
...state,
jupyter_data_set: data_sets,
jupyter_data_set_count: data_sets_count
jupyter_data_set_count: data_sets_count,
jupyter_folder_name:folder_name,
}
case types.GET_JUPYTER_TPI_URL:
const {url, status, port} = action.payload;

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 13:41:48
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-24 16:35:09
* @LastEditTime : 2019-12-25 14:45:47
*/
import types from "../actions/actionTypes";
import { Base64 } from 'js-base64';
@ -27,7 +27,12 @@ const initialState = {
notice: false, // 通知
hadCodeUpdate: false, // 更新代码
operateType: '', // 点击类型: 调度或提交
comment_identifier: '' // 用户评论时使用的 identifier
comment_identifier: '', // 用户评论时使用的 identifier
pages: {
limit: 15,
page: 1,
total: 1
}
};
const ojForUserReducer = (state = initialState, action) => {
@ -81,9 +86,11 @@ const ojForUserReducer = (state = initialState, action) => {
}
case types.COMMIT_RECORD:
const {records, records_count} = action.payload;
return {
...state,
commitRecord: [...action.payload]
commitRecord: records,
pages: Object.assign({}, state.pages, { total: records_count })
}
case types.SAVE_USER_CODE:
let curCode = Base64.encode(action.payload);
@ -199,6 +206,11 @@ const ojForUserReducer = (state = initialState, action) => {
...state,
hack: _hack
}
case types.CHANGE_RECORD_PAGINATION_PAGE:
return {
...state,
pages: Object.assign({}, state.pages, { page: action.payload})
}
default:
return state;
}

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-12-23 10:43:27
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-24 17:10:49
* @LastEditTime : 2019-12-25 10:50:24
*/
import axios from 'axios';
@ -15,9 +15,9 @@ export async function fetchAddComment (identifier, params) {
}
// 获取评论列表
export async function fetchCommentLists (identifier) {
export async function fetchCommentLists (identifier, params) {
const url = `/problems/${identifier}/comments.json`;
return axios.get(url);
return axios.get(url, {params});
}
// 添加子评论

@ -3,8 +3,8 @@
* @Author: tangjiang
* @Github:
* @Date: 2019-11-20 10:55:38
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-20 10:10:53
* @LastEditors : tangjiang
* @LastEditTime : 2019-12-25 14:27:30
*/
import axios from 'axios';
@ -70,10 +70,10 @@ export async function fetchUserProgramDetail (identifier) {
}
// 获取提交记录
export async function fetchUserCommitRecord (identifier) {
export async function fetchUserCommitRecord (identifier, params) {
console.log('identifier=====', identifier);
const url = `/myproblems/${identifier}/submit_records.json`;
return axios.get(url);
return axios.get(url, { params });
}
// 获取提交记录详情

Loading…
Cancel
Save