sso
daiao 5 years ago
commit c59bef3d14

@ -1,7 +1,7 @@
class SyncSubjectdsMobile < ActiveRecord::Migration[5.2]
def change
SubDisciplineContainer.find_each do |sc|
subject.find(sc.container_id).update_column(:show_mobile => true)
SubDisciplineContainer.where(container_type: "Subject").find_each do |sc|
Subject.find(sc.container_id).update_column("show_mobile", true)
end
end
end

@ -93,6 +93,8 @@
"rsuite": "^4.0.1",
"sass-loader": "7.3.1",
"scroll-into-view": "^1.12.3",
"showdown": "^1.9.1",
"showdown-katex": "^0.6.0",
"store": "^2.0.12",
"style-loader": "0.19.0",
"styled-components": "^4.1.3",

@ -1,29 +1,16 @@
import '../katex.css';
import '../css/Courses.css';
import React,{Component} from "react";
import { Form, Select, Input, Button,Checkbox,Upload,Icon,message,Modal, Table, Divider, Tag,DatePicker,Radio,Tooltip} from "antd";
import {Link} from 'react-router-dom';
import locale from 'antd/lib/date-picker/locale/zh_CN';
import { WordsBtn, MarkdownToHtml, markdownToHTML, ImageLayer2 } from 'educoder';
import {markdownToHTML, ImageLayer2 } from 'educoder';
import axios from 'axios';
import Modals from '../../modals/Modals';
import CoursesListType from '../coursesPublic/CoursesListType';
import HomeworkModal from "../coursesPublic/HomeworkModal";
import CheckAllGroup from '../common/button/CheckAllGroup'
import moment from 'moment';
import CheckCodeModal from '../coursesPublic/modal/CheckCodeModal'
import '../css/Courses.css'
import WorkDetailPageHeader from './common/WorkDetailPageHeader'
import CommonWorkAppraiseReply from './reply/CommonWorkAppraiseReply'
import Example from './TestHooks'
import CommonWorkAppraiseReviseAttachments from './CommonWorkAppraiseReviseAttachments'
import LeaderIcon from './common/LeaderIcon'
const { Option} = Select;
const CheckboxGroup = Checkbox.Group;
const confirm = Modal.confirm;
const $ = window.$;
const Search = Input.Search;
const RadioGroup = Radio.Group;
import LeaderIcon from './common/LeaderIcon';
import showdown from 'showdown'
import showdownKatex from 'showdown-katex'
class CommonWorkAppraise extends Component{
constructor(props){
@ -56,22 +43,28 @@ class CommonWorkAppraise extends Component{
console.log(error)
})
}
getSupplyAttachments = () => {
let workId =this.props.match.params.workId;
let studentWorkId =this.props.match.params.studentWorkId;
const url = `/student_works/${studentWorkId}/supply_attachments.json`
axios.get(url).then((result)=> {
if (result.data.course_id) {
this.setState({
...result.data
})
}
}).catch((error)=>{
console.log(error)
})
exportMdtoHtml=(md)=> {
let newmd=md;
newmd=newmd.replace(/TOC/g, '');
newmd=newmd.replace(/\[|]/g,'');
newmd=newmd.replace(/`/g, '');
newmd=newmd.replace(/`/g, '');
newmd=newmd.replace(/"/g, '');
newmd=newmd.replace(/"/g, '');
newmd=newmd.replace(/"/g, '');
const converter = new showdown.Converter({
extensions: [
showdownKatex({
// maybe you want katex to throwOnError
throwOnError: true,
// disable displayMode
displayMode: false,
// change errorColor to blue
errorColor: '#1500ff',
}),
],
});
return converter.makeHtml(newmd);
}
getReviseAttachments = () => {
let studentWorkId =this.props.match.params.studentWorkId;
@ -99,22 +92,6 @@ class CommonWorkAppraise extends Component{
componentDidMount() {
this.getWork();
this.getReviseAttachments()
let workId =this.props.match.params.workId;
let studentWorkId =this.props.match.params.studentWorkId;
// const url = `/student_works/${studentWorkId}/comment_list.json`
// axios.get(url).then((result)=> {
// if (result.data.course_id) {
// this.setState({
// ...result.data
// })
// }
// }).catch((error)=>{
// console.log(error)
// })
}
onAttachmentRemove = (id) => {
@ -205,7 +182,7 @@ class CommonWorkAppraise extends Component{
<div className={"color-grey-6 mb15 font-16"}>
内容
</div>
<div className="markdown-body ml20" dangerouslySetInnerHTML={{__html: markdownToHTML(description)}}>
<div className="markdown-body ml20" dangerouslySetInnerHTML={{__html: this.exportMdtoHtml(description)}}>
</div>
{attachments.map((item,key)=>{

@ -1,9 +1,12 @@
import '../../katex.css';
import React,{ Component } from "react";
import { getImageUrl, markdownToHTML, WordsBtn, getUrl } from 'educoder';
import { Tooltip } from 'antd'
import TPMMDEditor from '../../../tpm/challengesnew/TPMMDEditor'
import axios from 'axios'
import moment from 'moment'
import { Tooltip } from 'antd';
import TPMMDEditor from '../../../tpm/challengesnew/TPMMDEditor';
import axios from 'axios';
import moment from 'moment';
import showdown from 'showdown';
import showdownKatex from 'showdown-katex';
const _origin = ''
/**
https://www.showdoc.cc/127895880302646?page_id=1962215317836957
@ -14,7 +17,7 @@ const REFUSE = 4
class CCommentItem extends Component{
constructor(props){
super(props);
this.state = {
show_reply: false,
show_appeal: false,
@ -46,7 +49,7 @@ class CCommentItem extends Component{
let { item, commentIndex }=this.props;
const url = `/student_works/${studentWorkId}/cancel_appeal.json`
axios.post(url, {
axios.post(url, {
score_id: item.id
})
.then((response) => {
@ -57,7 +60,7 @@ class CCommentItem extends Component{
})
.catch(function (error) {
console.log(error);
});
});
}
})
}
@ -77,7 +80,7 @@ class CCommentItem extends Component{
comment: this.state.secondReplyContent
}).then((result)=>{
if(result.data.status == 0){
this.props.replySuccess()
this.props.replySuccess()
this.cancelReply()
}
}).catch((error)=>{
@ -92,7 +95,7 @@ class CCommentItem extends Component{
if(result.data.status == 0){
this.props.replySuccess()
this.cancelAppeal()
}
}).catch((error)=>{
console.log(error)
@ -118,14 +121,14 @@ class CCommentItem extends Component{
})
.catch(function (error) {
console.log(error);
});
});
}
})
}
on_deal_appeal_score = (mode, item) => {
this.props.confirm({
// content: `确认要删除所选的${len}个帖子吗?`,
content:
content:
<div>
<div>{mode == ACCEPT ? '此匿评成绩将被废弃,评阅人的作品将被违规扣分' : '此匿评成绩将被认为合理'}</div>
<div>是否确认{mode == ACCEPT ? '接受申诉' : '拒绝申诉'}</div>
@ -146,13 +149,39 @@ class CCommentItem extends Component{
})
.catch(function (error) {
console.log(error);
});
});
}
})
}
parseCommentContent = (oldContent) => {
return markdownToHTML(oldContent);
}
exportMdtoHtml=(md)=> {
let newmd=md;
newmd=newmd.replace(/TOC/g, '');
newmd=newmd.replace(/\[|]/g,'');
newmd=newmd.replace(/`/g, '');
newmd=newmd.replace(/`/g, '');
newmd=newmd.replace(/"/g, '');
newmd=newmd.replace(/"/g, '');
newmd=newmd.replace(/"/g, '');
const converter = new showdown.Converter({
extensions: [
showdownKatex({
// maybe you want katex to throwOnError
throwOnError: true,
// disable displayMode
displayMode: false,
// change errorColor to blue
errorColor: '#1500ff',
}),
],
});
return converter.makeHtml(newmd);
}
renderChildenComments = (parent) => {
if (parent.journals.length == 0) {
return '';
@ -172,19 +201,19 @@ class CCommentItem extends Component{
// is_appeal_info true 是匿评人匿评信息,需要统一使用头像去掉链接
return parent.journals.map(item => {
// <div>{item.content} {item.user_info.user_name}</div>
// src={getImageUrl(`images/${item.image_url}`)}
const imgSrc = (!item.user_info.user_image_url || item.user_info.user_image_url === '--') ? `edu_user/anony.png` : item.user_info.user_image_url;
return (
<div className="comment_item_cont appraise df clearfix" key={item.id}>
<div className="J_Comment_Face fl">
{item.is_appeal_info == true ?
{item.is_appeal_info == true ?
<a href={`javascript:void(0)`} target="_blank">
<img alt="用户头像" height="50"
<img alt="用户头像" height="50"
src={`${getUrl()}/images/edu_user/anony.png`} width="50"/>
</a>
: <a href={`${_origin}/users/${item.user_info.user_login}`} target="_blank">
<img alt="用户头像" height="50"
<img alt="用户头像" height="50"
src={`${getImageUrl(`images/`+imgSrc)}`}
width="50"/>
</a>}
@ -204,21 +233,21 @@ class CCommentItem extends Component{
</a>}
<span className="t_area fl">{moment(item.time).format('YYYY-MM-DD HH:mm')}</span>
{item.is_appeal_info && (item.appeal_status == 1 ?
<span className={"edu-filter-btn edu-filter-btn-4CACFF ml15 fl typestyle "} >申诉中</span> :
item.appeal_status == 2 ?
{item.is_appeal_info && (item.appeal_status == 1 ?
<span className={"edu-filter-btn edu-filter-btn-4CACFF ml15 fl typestyle "} >申诉中</span> :
item.appeal_status == 2 ?
<span className={"edu-filter-btn edu-filter-btn-EDEDED ml15 fl typestyle color666666 "} >申诉已撤销</span> :
item.appeal_status == 3 ?
item.appeal_status == 3 ?
<span className={"edu-filter-btn edu-filter-btn-4CACFF ml15 fl typestyle "} >申诉成功</span> :
item.appeal_status == 4 ?
item.appeal_status == 4 ?
<span className={"edu-filter-btn edu-filter-btn-EDEDED ml15 fl typestyle color666666 "} >申诉被拒绝</span> :
item.appeal_status == 5 ?
item.appeal_status == 5 ?
<span className={"edu-filter-btn edu-filter-btn-EDEDED ml15 fl typestyle color666666 "} >申诉失败</span> : '')
}
}
{/* fr */}
{/* { item.is_invalid ? <span className="validate_area fr"></span> :
{/* { item.is_invalid ? <span className="validate_area fr"></span> :
<React.Fragment> */}
{!item.is_appeal_info && item.can_delete == true && <Tooltip title="删除">
<i className="iconfont icon-shanchu mr5 fr font-14" onClick={() => this.onDeleteSecondReply(item)}
@ -233,19 +262,19 @@ class CCommentItem extends Component{
</React.Fragment>}
{item.appeal_status == 1 && this.props.is_author == true && this.props.isStudent()===true &&
<WordsBtn style="blue" className="fr mr5" onClick={() => this.cancelMyAppeal()}>撤销申诉</WordsBtn>}
</div>
</div>
<div className="comment_content clearfix" id={`reply_content_${item.id}`}>
<div className="color-grey-3" id={`reply_content_${item.id}`}>
<div className={"break_word_comments markdown-body"}
dangerouslySetInnerHTML={{__html: this.parseCommentContent(item.content)}}></div>
<div className={"markdown-body"}
dangerouslySetInnerHTML={{__html:this.exportMdtoHtml(item.content)}}></div>
<div className="cl"></div>
</div>
</div>
</div>
</div>
</div>
@ -256,7 +285,7 @@ class CCommentItem extends Component{
render(){
let { item, commentIndex, homework_status, is_author }=this.props;
let { show_reply, show_appeal }=this.state;
const _content = item.content ? this.parseCommentContent(item.content) : ''
const _content = item.content ? this.exportMdtoHtml(item.content) : ''
const isAnonymous = homework_status && homework_status.indexOf('匿评中') != -1
const isAppealing = homework_status && homework_status.indexOf('申诉中') != -1
const attachments = item.attachments;
@ -266,13 +295,13 @@ class CCommentItem extends Component{
<div className="ccomment comment_item_cont df clearfix" key={item.id}>
<div className="J_Comment_Face fl">
{item.image_url == '--' ?
{item.image_url == '--' ?
<a href={`javascript:void(0)`} >
<img alt="用户头像" height="50"
<img alt="用户头像" height="50"
src={`${getUrl()}/images/edu_user/anony.png`} width="50"/>
</a>
: <a href={`${_origin}/users/${item.user_login}`} target="_blank">
<img alt="用户头像" height="50"
<img alt="用户头像" height="50"
src={`${getUrl()}/images/${item.image_url}`}
width="50"/>
</a>}
@ -285,7 +314,7 @@ class CCommentItem extends Component{
<div className="t_content fl">
<div className="J_Comment_Reply">
<div className="comment_orig_content" style={{ margin:"0px" }}>
<div className="J_Comment_Info clearfix mt3">
<div className="t_info fl">
@ -303,8 +332,8 @@ class CCommentItem extends Component{
<span className="t_area fl">{item.time}</span>
{/* 分数 */}
{item.score !== null && <span className="score_area fl">{item.score}</span>}
{/* item.is_invalid && */}
{/* { item.delete && isAdmin && <Tooltip title={ "" } >
<i className="iconfont icon-shanchu mr5 fr" style={{marginLeft: '6px'}}
@ -312,29 +341,29 @@ class CCommentItem extends Component{
</i>
</Tooltip>} */}
{/* fr */}
{/* <WordsBtn style="blue" className="fr">回复</WordsBtn> */}
{ item.is_invalid ? <span className="validate_area fr">失效</span> :
{ item.is_invalid ? <span className="validate_area fr">失效</span> :
<React.Fragment>
<WordsBtn style="blue" className="fr" onClick={this.state.show_reply ? this.cancelReply : this.showReply}>回复</WordsBtn>
{(isAppealing || isAnonymous) && item.can_appeal && item.appeal_status == 0 &&
{(isAppealing || isAnonymous) && item.can_appeal && item.appeal_status == 0 &&
<WordsBtn style="blue" className="fr mr20" onClick={this.state.show_appeal ? this.cancelAppeal : this.showAppeal}>申诉</WordsBtn>}
</React.Fragment>
}
{item.delete && isAdmin
&& <WordsBtn style="blue" className="fr mr12"
{item.delete && isAdmin
&& <WordsBtn style="blue" className="fr mr12"
onClick={() => this.props.onDelete(item)}>删除</WordsBtn>}
</div>
</div>
{!!_content && _content !== 'null' && <div className="comment_content clearfix mt8" id={`reply_content_${item.id}`}>
<div className="color-grey-3" id={`reply_content_${item.id}`}>
<div className={"break_word_comments markdown-body"} dangerouslySetInnerHTML={{__html: _content}}></div>
<div className={"markdown-body"} dangerouslySetInnerHTML={{__html: _content}}></div>
<div className="cl"></div>
</div>
</div>}
@ -367,7 +396,7 @@ class CCommentItem extends Component{
<div className="childrenCommentsView" style={{background: '#fff'}}>
{/* {(item && item.journals && item.journals.length) ? <div className="trangle"></div>: ''} */}
{this.renderChildenComments(item)}
{/* { item.isAllChildrenLoaded != true && item.journals && this.props.isChildCommentPagination == true && item.journals.length >= 5?
{/* { item.isAllChildrenLoaded != true && item.journals && this.props.isChildCommentPagination == true && item.journals.length >= 5?
<Tooltip title={ "点击查看更多回复" } disableFocusListener={true}>
<div className="loadMoreChildComments" onClick={() => {this.props.loadMoreChildComments && this.props.loadMoreChildComments(item)}}>
<i className="iconfont icon-xiajiantou"></i>
@ -379,9 +408,9 @@ class CCommentItem extends Component{
<p className="" >
{/* 第二排右侧按钮区域 */}
{/* ${this.state.show_reply ? '回复' : '申诉'} */}
{(show_reply || show_appeal) &&
{(show_reply || show_appeal) &&
<React.Fragment>
<TPMMDEditor mdID={`${commentIndex}`} watch={false}
<TPMMDEditor mdID={`${commentIndex}`} watch={false}
height={130} onChange={(val) => this.setState({ secondReplyContent: val})}
placeholder={`请输入内容`} noStorage={true}
></TPMMDEditor>
@ -389,15 +418,15 @@ class CCommentItem extends Component{
<a className="task-btn task-btn-orange fr" style={{height: '26px', lineHeight: '26px', width: '60px'}}
onClick={this.onSubmit}
>{this.state.show_reply ? '回复' : '申诉'}</a>
<a onClick={this.onCancel} className="defalutCancelbtn fr"
<a onClick={this.onCancel} className="defalutCancelbtn fr"
style={{height: '26px', width: '60px', fontSize: '14px', lineHeight: '26px', marginRight: '10px'}}>取消</a>
</div>
</React.Fragment>
}
</p>
</div>
</div>
</div>

@ -141,10 +141,24 @@ class OneSelfOrderModal extends Component{
//勾选实训
shixunhomeworkedit=(list)=>{
if(this.state.course_groups){
if(this.state.course_groups.length===list.length){
this.setState({
Checkboxtype:true,
group_ids:list
})
}else{
this.setState({
Checkboxtype:false,
group_ids:list
})
}
}else{
this.setState({
group_ids:list
})
}
this.setState({
group_ids:list
})
this.props.getcourse_groupslist && this.props.getcourse_groupslist(list)
}

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save