You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
educoder/public/react/src/modules/courses/common/comments/commonent-item/index.jsx

225 lines
7.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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, 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(() => {
return content ? markdownToHTML(content) : ''
}, [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 >
)
}