fix mdtohtml bug

dev_aliyun2
harry 5 years ago
parent 6fa8808a01
commit c2677bace1

@ -3,13 +3,6 @@ import React, { Component } from 'react';
import { Spin } from 'antd';
class Loading extends Component {
componentDidUpdate(prevProps, prevState) {
if (!prevProps.error && this.props.error) {
console.log(this.props.error)
window.location.reload()
}
}
render() {
return (
<div className="App" style={{ minHeight: '800px', width: "100%" }}>

@ -1,14 +1,25 @@
import { bytesToSize, getUrl, getUrl2 } from 'educoder';
const $ = window.$
import showdown from 'showdown'
import showdownKatex from 'showdown-katex'
export function isImageExtension(fileName) {
return fileName ? !!(fileName.match(/.(jpg|jpeg|png|gif)$/i)) : false
}
const katex = showdownKatex()
const converter = new showdown.Converter({
extensions: [katex]
})
// const katexRex = /(?:\$\$)([^\$]+)(?:\$\$)/g
export function markdownToHTML(oldContent) {
var converter = new showdown.Converter()
return converter.makeHtml(oldContent);
if (oldContent) {
//let rs = oldContent.replace(katexRex, (_, p1) => `$${p1}$`)
let rs = converter.makeHtml(oldContent)
return rs
}
return oldContent
}
function _doDownload(options) {
$.fileDownload(getUrl() + "/api" + options.url, {

@ -5,13 +5,12 @@ import _ from 'lodash';
import ImageLayerOfCommentHOC from '../../../page/layers/ImageLayerOfCommentHOC';
import GraduationTasksappraiseMainEditor from '../../graduation/tasks/GraduationTasksappraiseMainEditor';
import CCommentItem from '../../common/comments/CCommentItem';
import CCommentItem from '../../common/comments/commonent-item';
import '../../../forums/Post.css';
import '../../../comment/Comment.css';
import '../../common/courseMessage.css';
import '../../graduation/tasks/GraduationTasksappraiseReply.css';
import './CommonWorkAppraiseReply.css';
import ModulationModal from "../../coursesPublic/ModulationModal";
import Modals from '../../../modals/Modals';
@ -156,20 +155,12 @@ class CommonWorkAppraiseReply extends Component {
console.log(value, num)
let { operationId } = this.state;
let studentWorkId = this.props.match.params.studentWorkId;
// console.log(value,num)
let url = "/student_works/" + studentWorkId + "/adjust_score.json";
axios.post(url, {
score: num,
comment: value
}).then((result) => {
// console.log(result)
if (result.data.status === 0) {
// this.setState({
// Modalstype:true,
// Allocationtype:false,
// Modalstopval:result.data.message,
// ModalSave:this.cancelmodel,
// })
this.cancelmodel()
this.props.showNotification('调分成功')
this.props.onReplySuccess && this.props.onReplySuccess()

@ -109,10 +109,12 @@ class CCommentItem extends Component{
onOk: () => {
const url = `/commons/delete.json`
axios.delete(url, { data: {
axios.delete(url, {
data: {
object_id: item.id,
object_type: 'journals_for_message'
}})
}
})
.then((response) => {
if (response.data.status == 0) {
this.props.replySuccess()

@ -0,0 +1,13 @@
import React from 'react'
export default ({ url, title, filesize }) => {
return (
<div className="color-grey attachItem" >
<a className="color-grey ">
<i className="font-14 color-green iconfont icon-fujian mr8" aria-hidden="true"></i>
</a>
<a href={url} className="mr12 color9B9B" length="58"> {title} </a>
<span className="color656565 mt2 color-grey-6 font-12 mr8">{filesize}</span>
</div>
)
}

@ -0,0 +1,114 @@
import React, { useMemo } from 'react'
import { markdownToHTML, WordsBtn, getUrl, getImageUrl } from 'educoder'
const appealStatus = {
1: '申诉中',
2: '申诉已撤销',
3: '申诉成功',
4: '申诉被拒绝',
5: '申诉失败'
}
/**
can_delete: true
content: "qwe"
id: 81136
time: "2019-06-04T11:00:21.000+08:00"
user_image_url: "avatars/User/1"
user_login: "innov"
user_name: "社区导师"
*/
// is_appeal_info true 使
export default ({ isStudent = false, isAdmin, callback, is_author, ...item }) => {
const pre = getUrl()
const _origin = ''
function onDeleteReply() {
callback('del-replay-item', item)
}
function cancelMyAppeal() {
callback('cancel-my-appeal', item)
}
function refuseAppealScore() {
callback('refuse-appeal-score', item)
}
function acceptAppealScore() {
callback('accept-appeal-score', item)
}
const { id, user_info, time, appeal_status, content, is_appeal_info, can_delete } = item
const { user_image_url, user_login, user_name } = user_info
const imgSrc = (!user_image_url || user_image_url === '--') ? `edu_user/anony.png` : user_image_url;
const md = useMemo(() => {
return markdownToHTML(content)
}, [content])
return (
<div className="ccomment comment_item_cont df clearfix" key={id}>
<div className="J_Comment_Face fl">
{is_appeal_info == true ?
<a href={`javascript:void(0)`} target="_blank">
<img alt="用户头像" height="50"
src={`${pre}/images/edu_user/anony.png`} width="50" />
</a>
: <a href={`${_origin}/users/${user_login}`} target="_blank">
<img alt="用户头像" height="50"
src={`${getImageUrl(`images/` + imgSrc)}`}
width="50" />
</a>}
</div>
<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">
{user_login === "--" ?
<a className="content-username hide fl">
{user_name}
</a>
: <a href={`${_origin}/users/${user_login}`} className="content-username hide fl">
{user_name}
</a>}
<span className="t_area fl">{time}</span>
{is_appeal_info ? <span className="edu-filter-btn edu-filter-btn-4CACFF ml15 fl typestyle " >{appealStatus[appeal_status]}</span> : null}
{
!is_appeal_info && can_delete == true && <a title="删除">
<i className="iconfont icon-shanchu mr5 fr font-14" onClick={onDeleteReply}
style={{ cursor: 'pointer' }}
></i>
</a>
}
{
is_appeal_info && isAdmin && appeal_status == 1 ? <React.Fragment>
<WordsBtn style="grey" onClick={refuseAppealScore} className="fr ml6">拒绝申诉</WordsBtn>
<WordsBtn style="orange" onClick={acceptAppealScore} className="fr">接受申诉</WordsBtn>
</React.Fragment> : null
}
{
appeal_status == 1 && isStudent === true && is_author &&
<WordsBtn style="blue" className="fr mr5" onClick={cancelMyAppeal}>撤销申诉</WordsBtn>
}
</div>
</div>
<div className="comment_content clearfix" id={`reply_content_${id}`}>
<div className="color-grey-3" id={`reply_content_${id}`}>
<div className={"markdown-body"} dangerouslySetInnerHTML={{ __html: md }}></div>
<div className="cl"></div>
</div>
</div>
</div>
</div>
</div>
</div >
)
}

@ -0,0 +1,5 @@
.ccomment .childrenCommentsView .comment_item_cont .break_word_comments {
margin-top: 4px;
width: 94%;
font-size: 14px;
}

@ -0,0 +1,226 @@
import React, { Fragment, useState, useMemo } from 'react'
import AttachmentItem from '../attachment-item'
import CommentItemReplay from '../commonent-item-replay'
import { useParams } from 'react-router-dom'
import TPMMDEditor from '../../../../tpm/challengesnew/TPMMDEditor'
import axios from 'axios'
import { markdownToHTML, WordsBtn, getUrl } from 'educoder'
import './index.css'
const ACCEPT = 3
const REFUSE = 4
export default ({ confirm, item, showNotification, replySuccess, isStudent, isAdmin, homework_status, callback, is_author, commentIndex, onDelete }) => {
const [data, setData] = useState({
value: '',
isShow: false,
mode: 'reply'
})
const { studentWorkId, workId } = useParams()
const { value, isShow, mode } = data
function onCancelMyAppeal() {
confirm({
content: <div>
<p>撤销申诉后无法再对本评阅记录进行申诉</p>
<p>是否确认撤销申诉</p>
</div>,
onOk: () => {
const url = `/student_works/${studentWorkId}/cancel_appeal.json`
axios.post(url, {
score_id: item.id
})
.then((response) => {
if (response.data.status == 0) {
showNotification('撤销成功')
replySuccess()
}
})
.catch(function (error) {
console.log(error)
})
}
})
}
function onDeleteReply(source) {
confirm({
content: `是否确认删除?`,
onOk: () => {
const url = `/commons/delete.json`
axios.delete(url, {
data: {
object_id: source.id,
object_type: 'journals_for_message'
}
})
.then((response) => {
if (response.data.status == 0) {
replySuccess()
setData({ ...data, isShow: false })
}
})
.catch(function (error) {
console.log(error)
})
}
})
}
function onDeleteHandler() {
onDelete(item)
}
function onSubmit() {
if (!value || !value.trim()) {
showNotification('内容不能为空')
return
}
let url = `/student_works/${studentWorkId}/appeal_anonymous_score.json`
if (mode === 'reply') {
url = `/student_works/${studentWorkId}/add_score_reply.json`
axios.post(url, {
score_id: item.id,
comment: value
}).then((result) => {
if (result.data.status == 0) {
replySuccess()
setData({ ...data, isShow: false })
}
}).catch((error) => {
console.log(error)
})
}
}
function callback(type, source) {
if (type === 'refuse-appeal-score') {
onDealAppealScore(REFUSE, source)
}
if (type === 'accept-appeal-score') {
onDealAppealScore(ACCEPT, source)
}
if (type === 'cancel-my-appeal') {
onCancelMyAppeal()
}
if (type === 'del-replay-item') {
onDeleteReply(source)
}
}
function onDealAppealScore(mode, source) {
confirm({
content:
<div>
<div>{mode == ACCEPT ? '此匿评成绩将被废弃,评阅人的作品将被违规扣分' : '此匿评成绩将被认为合理'}</div>
<div>是否确认{mode == ACCEPT ? '接受申诉' : '拒绝申诉'}</div>
</div>
,
onOk: () => {
const url = `/student_works/${studentWorkId}/deal_appeal_score.json`
axios.post(url, {
score_id: source.score_id,
status: mode
})
.then((response) => {
if (response.data.status == 0) {
showNotification(`${mode == ACCEPT ? '接受申诉' : '拒绝申诉'}成功`)
replySuccess()
}
})
.catch(function (error) {
console.log(error);
});
}
})
}
const pre = getUrl()
const _origin = ''
function onChangeHandler(value) {
setData({ ...data, value })
}
function onReplayHandler() {
setData({ ...data, isShow: true, mode: 'reply' })
}
function onAppealHandler() {
setData({ ...data, isShow: true, mode: 'appeal' })
}
function onCancel() {
setData({ ...data, isShow: false })
}
const { id, image_url, user_login, username, comment_role, time, score, is_invalid, can_appeal, appeal_status, content, attachments, journals } = item
const isAnonymous = homework_status && homework_status.indexOf('匿评中') != -1
const isAppealing = homework_status && homework_status.indexOf('申诉中') != -1
const md = useMemo(() => {
let rs = markdownToHTML(content)
return rs
}, [content, id])
return (
<div className="ccomment comment_item_cont df clearfix" key={id}>
<div className="J_Comment_Face fl">
<a href={image_url === '--' ? `${_origin}/users/${user_login}` : 'javascript:void(0)'} target="_blank">
<img alt="用户头像" height="50"
src={`${pre}/images/${image_url}`}
width="50" />
</a>
</div>
<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">
<a href={user_login === "--" ? `${_origin}/users/${user_login}` : 'javascript:void(0)'} className="content-username hide fl"> {username}{comment_role}</a>
<span className="t_area fl">{time}</span>
{score !== null && <span className="score_area fl">{score}</span>}
{is_invalid ? <span className="validate_area fr">失效</span> :
<Fragment>
<WordsBtn style="blue" className="fr" onClick={onReplayHandler}>回复</WordsBtn>
{(isAppealing || isAnonymous) && can_appeal && appeal_status == 0 &&
<WordsBtn style="blue" className="fr mr20" onClick={onAppealHandler}>申诉</WordsBtn>}
</Fragment>
}
{item.delete && isAdmin() && <WordsBtn style="blue" className="fr mr12" onClick={onDeleteHandler}>删除</WordsBtn>}
</div>
</div>
{!!md ? <div className="comment_content clearfix" id={`reply_content_${id}`}>
<div className="color-grey-3" id={`reply_content_${id}`}>
<div className={"markdown-body"} dangerouslySetInnerHTML={{ __html: md }}></div>
<div className="cl"></div>
</div>
</div> : <span className="color656565 mt2 color-grey-9 font-12 mr8" style={{ display: 'inline-block' }}>{"暂未写评语"}</span>}
{attachments && attachments.length > 0 ? <div className="mt6"> {attachments.map((attaItem, key) => <AttachmentItem {...attaItem} key={key} />)} </div> : null}
{journals && journals.length > 0 ?
<div className="childrenCommentsView" style={{ background: '#fff' }}>
{journals.map(journal => <CommentItemReplay key={journal.id} {...journal} callback={callback} isAdmin={isAdmin()} is_author={is_author} isStudent={isStudent()} />)}
</div> : null
}
<div>
{isShow &&
<Fragment>
<TPMMDEditor mdID={`${commentIndex}`} watch={false}
height={130} onChange={onChangeHandler}
placeholder={`请输入内容`} noStorage={true}
></TPMMDEditor>
<div className="fr">
<a className="task-btn task-btn-orange fr" style={{ height: '26px', lineHeight: '26px', width: '60px' }}
onClick={onSubmit}
>{mode === 'reply' ? '回复' : '申诉'}</a>
<a onClick={onCancel} className="defalutCancelbtn fr"
style={{ height: '26px', width: '60px', fontSize: '14px', lineHeight: '26px', marginRight: '10px' }}>取消</a>
</div>
</Fragment>
}
</div>
</div>
</div>
</div>
</div >
)
}

@ -880,11 +880,6 @@ export default class TPMquestion extends Component {
gochooseid = (url) => {
window.location.href = url
// window.location.Reload(url)
// this.props.history.replace( url );
// this.props.history.push( url );
// 返回
// this.props.history.goBack();
}
render() {

Loading…
Cancel
Save