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/forge/Order/Detail.js

572 lines
19 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden 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 , {Component} from 'react';
import {Link} from 'react-router-dom';
import axios from 'axios';
import Nav from './Nav';
import UploadComponent from '../Upload/Index';
import { getImageUrl } from 'educoder';
import {Modal, Col, Form, Input, Tooltip, Popconfirm, Pagination , Spin} from 'antd'
import NoneData from '../../modules/courses/coursesPublic/NoneData';
import Attachments from '../Upload/attachment';
import QuillForEditor from '../quillForEditor';
import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html'
const TextArea = Input.TextArea;
const options = [
['bold', 'italic', 'underline'],
[{header: [1,2,3,false]}],
['blockquote', 'code-block'],
['link', 'image'],
['formula']
];
class Detail extends Component{
constructor(props){
super(props);
this.state={
data:undefined,
isShow:false,
imgsrc:'',
journalsdata:undefined,
//图片区域是否显示 none 隐藏 block 显示
display:'none',
titledisplay:'none',
countvalue:'',
//是否需要编辑
isedit:undefined,
fileList:undefined,
limit:10,
page:1,
search_count:undefined,
isSpin:false,
showFiles: true,
quillValue:'',
quillFlag:false
}
}
componentDidMount=()=>{
this.getDetail();
}
getDetail=()=>{
const { projectsId , orderId} = this.props.match.params;
const url = `/projects/${projectsId}/issues/${orderId}.json`;
axios.get(url).then((result)=>{
if(result){
this.setState({
data:result.data
})
this.getjournalslist();
}
}).catch((error)=>{
console.log(error);
})
}
handleok=() => {
this.setState({
isShow:false
});
};
handleCancel=()=>{
this.setState({
isShow:false
});
}
imgshow=()=>{
this.setState({
isShow:true
});
};
//添加评论
addjournals=()=>{
const { quillValue } = this.state;
if(!quillValue){
this.setState({
quillFlag:true
})
return;
}
let _html = '';
try {
_html = new QuillDeltaToHtmlConverter(quillValue.ops, {}).convert();
} catch (error) {
console.log(error);
}
this.props.form.validateFieldsAndScroll((err, values) => {
if(!err){
const { data, page, limit, fileList } = this.state;
const url = `/issues/${data.id}/journals.json`;
axios.post(url,{
...values,
content:_html,
issue_id:data.id,
attachment_ids:fileList
}).then(result=>{
if(result){
this.props.form.setFieldsValue({
content: ""
});
this.setState({
showFiles: false,
quillValue:''
})
this.getjournalslist(page, limit);
this.props.showNotification("评论成功!");
// this.UploadFunc(undefined)
}
}).catch(error=>{
console.log(error);
})
}
})
}
//获取评论信息
getjournalslist=(page, limit)=>{
const { data} = this.state;
const url = `/issues/${data.id}/journals.json`;
let id=data.id;
axios.get(url,{
params:{
id,page,limit
}
}).then(result=>{
if(result){
this.setState({
journalsdata:result.data,
search_count:result.data.journals_count,
isSpin:false,
fileList:undefined,
})
}
}).catch(error=>{
console.log(error);
})
}
//删除工单信息
deletedetail=(id)=>{
const { projectsId , orderId} = this.props.match.params;
const url = `/projects/${projectsId}/issues/${orderId}.json`;
axios.delete(url,{ data: {
project_id: projectsId,
id:id
}
}).then((result)=>{
if(result){
this.props.history.push(`/projects/${projectsId}/orders`);
}
}).catch((error)=>{
console.log(error);
})
}
//关闭工单
closedetail=(id)=>{
const {projectsId,orderId} = this.props.match.params;
const url = `/projects/${projectsId}/issues/${orderId}/close_issue.json`;
axios.post(url,{
project_id:projectsId,
id:orderId,
status_id:id,
}).then(result=>{
if(result){
this.getDetail();
}
}).catch(error=>{
console.log(error);
})
}
//修改评论
updatedetail=(id)=>{
const {page, limit } = this.state;
const {orderId} = this.props.match.params;
const url = `/issues/${orderId}/journals/${id}.json`;
axios.put(url,{
issue_id:orderId,
id:id,
content:this.state.countvalue
}).then(result=>{
if(result){
this.setState({
isedit: undefined
})
this.getjournalslist(page, limit);
}
}).catch(error=>{
console.log(error);
})
}
// 获取上传后的文件id数组
UploadFunc=(fileList)=>{
this.setState({
fileList
})
}
//删除评论
deleteorder=(id)=>{
const { orderId} = this.props.match.params;
const { page, limit } = this.state;
const url = `/issues/${orderId}/journals/${id}.json`;
axios.delete(url,{ data: {
issue_id: orderId,
id:id
}
}).then((result)=>{
if(result){
this.getjournalslist(page,limit)
}
}).catch((error)=>{
console.log(error);
})
}
changmodelname=(e)=>{
this.setState({
countvalue:e.target.value
})
}
editdetail=(count,status)=>{
this.setState({
countvalue:count,
isedit:status
})
}
renderJournalList=(list)=>{
// console.log(list);
if(list && list.length >0){
return(
list.map((item,key)=>{
return(
<div key={key+1} className="journal-list-item">
<span className="font-weight-bold mr3">
{item.detail}
</span>
<span className="mr5 color-grey-9">
{item.old_value && item.old_value.length > 0 ? "更新为" : "新增"}
</span>
<span>
{item.value && item.value.length > 0 ?
item.detail === "标签" ? <span className="issue-tag-show" style={{background: item.value[0].color}}>{item.value[0].name}</span> : item.value
:
"无"
}
</span>
</div>
)
})
)
}else{
return(
<div>
<span>没有评论~</span>
</div>
)
}
}
//复制
copydetail=()=>{
const {projectsId,orderId} = this.props.match.params;
const url = `/projects/${projectsId}/issues/${orderId}/copy.json`;
axios.post(url,{
project_id:projectsId,
id:orderId,
}).then(result=>{
if(result){
this.props.history.push(`/projects/${projectsId}/orders/${result.data.issue_id}/copyetail`);
}
}).catch(error=>{
console.log(error);
})
}
// 翻页
ChangePage=(page)=>{
this.setState({
page,
isSpin:true
})
const {limit} = this.state;
this.getjournalslist(page,limit);
}
// 判断是否重新上传文件
changeIsComplete=(flag)=>{
this.setState({
showFiles:flag
})
}
onContentChange=(value)=>{
this.setState({
quillValue:value
})
}
render(){
const { projectsId,orderId} = this.props.match.params;
const { data,journalsdata, page, limit, search_count, isSpin, isedit, showFiles , quillValue , quillFlag } = this.state;
const { getFieldDecorator } = this.props.form;
const { current_user } = this.props;
const Paginations = (
<React.Fragment>
{
search_count > limit ?
<div className="pt30 mb50 edu-txt-center btp1">
<Pagination simple defaultCurrent={page} total={search_count} pageSize={limit} onChange={this.ChangePage}></Pagination>
</div>:""
}
</React.Fragment>
)
const renderList =()=>{
if(journalsdata && journalsdata.issue_journals && journalsdata.issue_journals.length>0 ){
return(
<div className="tagList">{
journalsdata.issue_journals.map((item,key)=>{
return(
<li key={key}>
<div className="df">
<Link to={``}><img className="user_img" src={getImageUrl(`images/${item.user_picture && item.user_picture}`)} alt=""/></Link>
<div className="detail_context" >
<div className="topWrapper_detali">
<p className="ml6 detail_p lineH40">
{item.user_name}
<span className="color-grey-9 ml3 mr3">评论于</span>
<Tooltip title={item.format_time} placement="bottom">
<span>{item.created_at}</span>
</Tooltip>
</p>
<div className="detail_right" style={{display: current_user && isedit === undefined && (current_user.admin || current_user.login === item.user_login) ? "block" : "none"}}>
<span onClick={()=>this.editdetail(item.content,item.id)} className="detail_edit_action">编辑</span>
<Popconfirm placement="bottom" title={'确定要删除当前评论吗?'} okText="是" cancelText="否" onConfirm={()=>this.deleteorder(item.id)}>
<span className="detail_edit_action">删除</span>
</Popconfirm>
</div>
</div>
<div className="detail_ptitlecount">
<div style={{display: (isedit && isedit === item.id) ? "none" : "block"}} >
{
item.content ?
<QuillForEditor
readOnly={true}
value={item.content}
/>
:
<div>
{this.renderJournalList(item.journal_details)}
</div>
}
{
item && item.attachments && item.attachments.length > 0 ?
<Attachments attachments={item.attachments} showNotification={this.props.showNotification} canDelete={current_user && (current_user.admin || current_user.login === item.user_login)}/>
:
""
}
</div>
<div style={{display: (isedit && isedit === item.id) ? "block" : "none"}}>
<TextArea style={{height:"200px"}} value={this.state.countvalue} onChange={this.changmodelname}/>
<p className="clearfix mt15">
<a className="topWrapper_btn fr" type="submit" onClick={()=>this.updatedetail(item.id)}>保存</a>
<a className="a_btn cancel_btn fr" type="submit" onClick={()=>this.editdetail(item.content,undefined)}>取消</a>
</p>
</div>
</div>
<div style={{display: this.state.display}}>
<div className="div_line" ></div>
{/* <List
grid={{ gutter: 16, column: 6 }}
dataSource={valuse}
renderItem={obj => (
<List.Item>
<img class="list_img" onClick={this.imgshow} src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1608431072,669449145&fm=27&gp=0.jpg" alt=""/>
</List.Item>
)}
/> */}
</div>
</div>
</div>
<div className="order_line" style={{marginLeft:80}}></div>
</li>
)
})
}
</div>
)
}
}
return(
<div className="main">
<div className="topWrapper">
<Nav {...this.props} {...this.state}/>
<Link to={`/projects/${projectsId}/orders/new`} className="topWrapper_btn">创建工单</Link>
</div>
<div>
<div className="detailContent">
<p>
{
data ?
<span className="font-20">{data.issue_classify === "issue" ? data.tracker : "合并请求"}</span>
:
""
}
<span className="font-20" > { data && data.subject }</span>
</p>
<p className="mt10 color-grey-c">
<span className={data&&data.issue_status==="关闭"?"closedetail":"opendetail"}>{data&&data.issue_status==="关闭"?"关闭中":"开启中"} </span>
<span className="ml10 lineH32">
{ data && data.author_name} { data && data.created_at }创建{ data && data.journals_count && data.journals_count > 0 ?` · ${data.journals_count} 条评论`:""}
</span>
{
data && data.user_permission ?
<span className="pull-right lineH32">
<a className="color-blue fr" onClick={this.copydetail}>复制</a>
<Popconfirm placement="bottom" title={'您确定要删除吗'} okText="是" cancelText="否" onConfirm={()=>this.deletedetail(orderId)}>
<a className="color-blue fr" style={{marginLeft:20,marginRight:20}}>删除</a>
</Popconfirm>
<Link to={`/projects/${projectsId}/orders/${orderId}/updatedetail`} className="color-blue fr">编辑</Link>
</span>
:
""
}
</p>
<div className="df mt20">
<Link to={``}><img className="user_img" src={getImageUrl(`images/${data && data.author_picture}`)} alt=""/></Link>
<div className="detail_context">
<div className="detail_p">
{ data && data.description }
</div>
{
data && data.attachments && data.attachments.length > 0 ?
<Attachments attachments={data.attachments} showNotification={this.props.showNotification}/>
:
""
}
</div>
</div>
</div>
<div className="f-wrap-between mt5" style={{alignItems:"flex-start"}}>
<div className="item-list-right" >
<Spin spinning={isSpin}>
<ul className="ul_width">
{renderList()}
</ul>
</Spin>
{ Paginations }
<div className="df">
<Link to={``}><img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/></Link>
<div className="new_context">
<div className="quillContent">
<QuillForEditor
imgAttrs={{ width: '60px', height: '30px' }}
wrapStyle={{
height: '200px',
opacity:1,
}}
autoFocus={true}
style={{ height: '150px' }}
placeholder="添加评论..."
options={options}
value={quillValue}
onContentChange={this.onContentChange}
// showUploadImage={handleShowImage}
// onContentChange={handleContentChange}
/>
<p className="quillFlag">
{ quillFlag && <span className="">请输入评论内容</span>}
</p>
</div>
<UploadComponent load={this.UploadFunc} isComplete={showFiles} changeIsComplete={this.changeIsComplete}></UploadComponent>
<p className="clearfix mt15">
<a className="topWrapper_btn fr" type="submit" onClick={this.addjournals}>评论</a>
{
data && data.user_permission ?
<a className="Closeor_btn fr" type="submit"
onClick={() => this.closedetail(data && data.issue_status === "关闭" ? 2 : 5)}>{data && data.issue_status === "关闭" ? "重新开启" : "关闭"}</a>
:
""
}
</p>
</div>
</div>
</div>
<div className="list-left DetailRight mt10">
<p>
<span className="span_title">分支</span>
<span>{
data && data.branch_name ? data.branch_name : "--"
}</span>
</p>
<p>
<span className="span_title">标签</span>
<span>{
data && data.issue_tags ? <span className="issue-tag-show" style={{background: data.issue_tags[0].color}}>{data.issue_tags[0].name}</span> : "--"
}</span>
</p>
<p>
<span className="span_title">里程碑</span>
<span>{
data && data.version ? data.version : "--"
}</span>
</p>
<p>
<span className="span_title">当前状态</span>
<span>{
data && data.issue_status ? data.issue_status : "--"
}</span>
</p>
<p>
<span className="span_title">分类</span>
<span>{
data && data.tracker ? data.tracker : "--"
}</span>
</p>
<p>
<span className="span_title">指派给</span>
<span>{data && data.assign_user_name ? data.assign_user_name : "--"}</span>
</p>
<p>
<span className="span_title">优先级</span>
<span>{data && data.priority ? data.priority : "--"}</span>
</p>
<p>
<span className="span_title">完成度</span>
<span>{data && data.done_ratio ? data.done_ratio : "--"}</span>
</p>
</div>
</div>
</div>
<Modal
onCancel={this.handleCancel}
visible={this.state.isShow}
width="400px"
footer={
[]
}
bodyStyle={{textAlign:'center'}}
>
<img className="list_img" src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1608431072,669449145&fm=27&gp=0.jpg" alt=""/>
</Modal>
</div>
)
}
}
const WrappedDetailForm = Form.create({ name: 'DetailOrderForm' })(Detail);
export default WrappedDetailForm;