forked from Gitlink/forgeplus-react
issue
This commit is contained in:
parent
78ba918514
commit
7dbcdd7b77
|
@ -25,7 +25,7 @@ class IndexItem extends Component{
|
|||
<img className="p-r-photo" alt="" src={getImageUrl(`images/${item.author && item.author.image_url}`)} ></img>
|
||||
<div className="p-r-Infos">
|
||||
<div className="p-r-name">
|
||||
<a onClick={()=>this.TurnToDetail(`${item.author && item.author.login}`,`/projects/${item.identifier}/coder`)} className="hide-1 font-16 color-grey-3" style={{whiteSpace:"wrap"}}>{item.name}</a>
|
||||
<a onClick={()=>this.TurnToDetail(`${item.author && item.author.login}`,`/projects/${item.id}/coder`)} className="hide-1 font-16 color-grey-3" style={{whiteSpace:"wrap"}}>{item.name}</a>
|
||||
</div>
|
||||
<div className="p-r-content">
|
||||
<p className="break_word task-hide flex1" style={{maxHeight:"40px"}}>{item.description}</p>
|
||||
|
|
|
@ -90,19 +90,14 @@ class Detail extends Component{
|
|||
})
|
||||
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,
|
||||
content:JSON.stringify(quillValue),
|
||||
issue_id:data.id,
|
||||
attachment_ids:fileList
|
||||
}).then(result=>{
|
||||
|
@ -313,10 +308,29 @@ class Detail extends Component{
|
|||
}
|
||||
}
|
||||
|
||||
handleShowImage=(value)=>{
|
||||
console.log("imgOnclick",value);
|
||||
}
|
||||
|
||||
commentCtx = (ctx) => {
|
||||
let _ctx = null;
|
||||
try {
|
||||
_ctx = JSON.parse(ctx);
|
||||
} catch (e) {
|
||||
_ctx = ctx;
|
||||
}
|
||||
return (
|
||||
<QuillForEditor
|
||||
readOnly={true}
|
||||
value={_ctx}
|
||||
showUploadImage={this.handleShowImage}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
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>
|
||||
|
@ -336,7 +350,7 @@ class Detail extends Component{
|
|||
return(
|
||||
<li key={key}>
|
||||
<div className="df">
|
||||
<Link to={``}><img className="user_img" src={getImageUrl(`images/${item.user_picture && item.user_picture}`)} alt=""/></Link>
|
||||
<img className="user_img" src={getImageUrl(`images/${item.user_picture && item.user_picture}`)} alt=""/>
|
||||
<div className="detail_context" >
|
||||
<div className="topWrapper_detali">
|
||||
<p className="ml6 detail_p lineH40">
|
||||
|
@ -356,11 +370,8 @@ class Detail extends Component{
|
|||
<div className="detail_ptitlecount">
|
||||
<div style={{display: (isedit && isedit === item.id) ? "none" : "block"}} >
|
||||
{
|
||||
item.content ?
|
||||
<QuillForEditor
|
||||
readOnly={true}
|
||||
value={item.content}
|
||||
/>
|
||||
item.content ?
|
||||
this.commentCtx(item.content)
|
||||
:
|
||||
<div>
|
||||
{this.renderJournalList(item.journal_details)}
|
||||
|
@ -448,10 +459,11 @@ class Detail extends Component{
|
|||
<Link to={``}><img className="user_img" src={getImageUrl(`images/${data && data.author_picture}`)} alt=""/></Link>
|
||||
<div className="detail_context">
|
||||
<div className="detail_p">
|
||||
<QuillForEditor
|
||||
{/* <QuillForEditor
|
||||
readOnly={true}
|
||||
value={ data && data.description}
|
||||
/>
|
||||
/> */}
|
||||
{this.commentCtx(data && data.description)}
|
||||
</div>
|
||||
{
|
||||
data && data.attachments && data.attachments.length > 0 ?
|
||||
|
@ -473,11 +485,11 @@ class Detail extends Component{
|
|||
{ Paginations }
|
||||
|
||||
<div className="df">
|
||||
<Link to={``}><img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/></Link>
|
||||
<img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/>
|
||||
<div className="new_context">
|
||||
<div className="quillContent">
|
||||
<QuillForEditor
|
||||
imgAttrs={{ width: '60px', height: '30px' }}
|
||||
imgAttrs={{ width: '30px' }}
|
||||
wrapStyle={{
|
||||
height: '220px',
|
||||
opacity:1,
|
||||
|
@ -488,7 +500,7 @@ class Detail extends Component{
|
|||
options={options}
|
||||
value={quillValue}
|
||||
onContentChange={this.onContentChange}
|
||||
// showUploadImage={handleShowImage}
|
||||
showUploadImage={this.handleShowImage}
|
||||
// onContentChange={handleContentChange}
|
||||
/>
|
||||
<p className="quillFlag">
|
||||
|
|
|
@ -104,15 +104,10 @@ class New extends Component{
|
|||
values.issue_tag_ids = [values.issue_tag_ids]
|
||||
}
|
||||
const { description } = this.state;
|
||||
let _html = '';
|
||||
try {
|
||||
_html = new QuillDeltaToHtmlConverter(description.ops, {}).convert();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
axios.post(url,{
|
||||
...values,
|
||||
description:_html,
|
||||
description:JSON.stringify(description),
|
||||
attachment_ids:fileList
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
|
|
|
@ -159,17 +159,12 @@ class UpdateDetail extends Component{
|
|||
values.assigned_to_id = ""
|
||||
}
|
||||
const { textcount } = this.state;
|
||||
let _html = '';
|
||||
try {
|
||||
_html = new QuillDeltaToHtmlConverter(textcount.ops, {}).convert();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
axios.put(url,{
|
||||
project_id:projectsId,
|
||||
subject:subject,
|
||||
id: orderId,
|
||||
description:_html,
|
||||
description:JSON.stringify(textcount),
|
||||
attachment_ids:fileList,
|
||||
...values
|
||||
}).then(result=>{
|
||||
|
|
|
@ -8,19 +8,15 @@
|
|||
*/
|
||||
import Quill from 'quill';
|
||||
let Inline = Quill.import('blots/inline');
|
||||
// const BlockEmbed = Quill.import('blots/embed');
|
||||
class FillBlot extends Inline {
|
||||
static create (value) {
|
||||
static create(value) {
|
||||
const node = super.cerate(value);
|
||||
// node.classList.add('icon icon-bianji2');
|
||||
// node.setAttribute('data-fill', 'fill');
|
||||
console.log('编辑器值===》》》》》', value);
|
||||
node.setAttribute('data_index', value.data_index);
|
||||
node.nodeValue = value.text;
|
||||
node.nodeValue = value.text;
|
||||
return node;
|
||||
}
|
||||
|
||||
static value (node) {
|
||||
|
||||
static value(node) {
|
||||
return {
|
||||
// dataSet: node.getAttribute('data-fill'),
|
||||
data_index: node.getAttribute('data_index')
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @Description: 重写图片
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Github:
|
||||
* @Date: 2019-12-16 15:50:45
|
||||
* @LastEditors : tangjiang
|
||||
* @LastEditTime : 2019-12-31 13:59:02
|
||||
|
@ -17,10 +17,14 @@ export default class ImageBlot extends BlockEmbed {
|
|||
const node = super.create();
|
||||
node.setAttribute('alt', value.alt);
|
||||
node.setAttribute('src', value.url);
|
||||
// console.log('~~~~~~~~~~~', node, value);
|
||||
console.log('~~~~~~~~~~~', node, value);
|
||||
node.addEventListener('click', function () {
|
||||
value.onclick(value.url);
|
||||
}, false);
|
||||
try {
|
||||
value.onclick(value.url);
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
}, false);
|
||||
if (value.width) {
|
||||
node.setAttribute('width', value.width);
|
||||
}
|
||||
|
@ -33,7 +37,6 @@ export default class ImageBlot extends BlockEmbed {
|
|||
}
|
||||
// 宽度和高度都不存在时,
|
||||
if (!value.width && !value.height) {
|
||||
// node.setAttribute('display', 'block');
|
||||
node.setAttribute('width', '100%');
|
||||
}
|
||||
|
||||
|
@ -51,7 +54,7 @@ export default class ImageBlot extends BlockEmbed {
|
|||
}
|
||||
|
||||
// 获取节点值
|
||||
static value (node) {
|
||||
static value(node) {
|
||||
|
||||
return {
|
||||
alt: node.getAttribute('alt'),
|
||||
|
@ -61,10 +64,9 @@ export default class ImageBlot extends BlockEmbed {
|
|||
height: node.height,
|
||||
display: node.getAttribute('display'),
|
||||
id: node.id,
|
||||
// style: node.style
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
ImageBlot.blotName = 'image';
|
||||
ImageBlot.tagName = 'img';
|
||||
ImageBlot.tagName = 'img';
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
@charset "utf-8";
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
|
||||
content: "宋体";
|
||||
font-family:SimSun !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
|
||||
content: "黑体";
|
||||
font-family:SimHei !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
|
||||
content: "微软雅黑";
|
||||
font-family:Microsoft YaHei !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
|
||||
content: "楷体";
|
||||
font-family:KaiTi !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=FangSong]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=FangSong]::before {
|
||||
content: "仿宋";
|
||||
font-family:FangSong !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
|
||||
content: "Arial";
|
||||
font-family:Arial !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
|
||||
content: "Times New Roman";
|
||||
font-family:Times New Roman !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=sans-serif]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=sans-serif]::before {
|
||||
content: "sans-serif";
|
||||
font-family:sans-serif !important;
|
||||
}
|
||||
|
||||
.ql-font-SimSun {
|
||||
font-family:SimSun !important;
|
||||
}
|
||||
.ql-font-SimHei {
|
||||
font-family:SimHei !important;
|
||||
}
|
||||
.ql-font-Microsoft-YaHei {
|
||||
font-family:Microsoft YaHei !important;
|
||||
}
|
||||
.ql-font-KaiTi {
|
||||
font-family:KaiTi !important;
|
||||
}
|
||||
.ql-font-FangSong {
|
||||
font-family:FangSong !important;
|
||||
}
|
||||
.ql-font-Arial {
|
||||
font-family:Arial !important;
|
||||
}
|
||||
.ql-font-Times-New-Roman {
|
||||
font-family:Times New Roman !important;
|
||||
}
|
||||
.ql-font-sans-serif {
|
||||
font-family:sans-serif !important;
|
||||
}
|
|
@ -11,6 +11,7 @@ import 'quill/dist/quill.core.css'; // 核心样式
|
|||
import 'quill/dist/quill.snow.css'; // 有工具栏
|
||||
import 'quill/dist/quill.bubble.css'; // 无工具栏
|
||||
import 'katex/dist/katex.min.css'; // katex 表达式样式
|
||||
import './font.css'
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import Quill from 'quill';
|
||||
import katex from 'katex';
|
||||
|
@ -19,16 +20,17 @@ import { fetchUploadImage } from '../../services/ojService.js';
|
|||
import { getImageUrl } from 'educoder'
|
||||
import ImageBlot from './ImageBlot';
|
||||
import FillBlot from './FillBlot';
|
||||
const Size = Quill.import('attributors/style/size');
|
||||
const Font = Quill.import('formats/font');
|
||||
// const Color = Quill.import('attributes/style/color');
|
||||
Size.whitelist = ['12px', '14px', '16px', '18px', '20px', false];
|
||||
Font.whitelist = ['SimSun', 'SimHei','Microsoft-YaHei','KaiTi','FangSong','Arial','Times-New-Roman','sans-serif'];
|
||||
|
||||
import LinkBlot from './link-blot'
|
||||
var Size = Quill.import('attributors/style/size');
|
||||
Size.whitelist = ['14px', '16px', '18px', '20px', false];
|
||||
var fonts = ['Microsoft-YaHei', 'SimSun', 'SimHei', 'KaiTi', 'FangSong'];
|
||||
var Font = Quill.import('formats/font');
|
||||
Font.whitelist = fonts; //将字体加入到白名单
|
||||
window.Quill = Quill;
|
||||
window.katex = katex;
|
||||
Quill.register(ImageBlot);
|
||||
Quill.register(Size);
|
||||
Quill.register(LinkBlot);
|
||||
Quill.register(Font, true);
|
||||
// Quill.register({'modules/toolbar': Toolbar});
|
||||
Quill.register({
|
||||
|
@ -37,7 +39,7 @@ Quill.register({
|
|||
// Quill.register(Color);
|
||||
|
||||
|
||||
function QuillForEditor ({
|
||||
function QuillForEditor({
|
||||
placeholder,
|
||||
readOnly,
|
||||
autoFocus = false,
|
||||
|
@ -50,16 +52,16 @@ function QuillForEditor ({
|
|||
onContentChange,
|
||||
addFill, // 点击填空成功的回调
|
||||
deleteFill // 删除填空,返回删除的下标
|
||||
// getQuillContent
|
||||
}) {
|
||||
// toolbar 默认值
|
||||
const defaultConfig = [
|
||||
'bold', 'italic', 'underline',
|
||||
{size: ['12px', '14px', '16px', '18px', '20px']},
|
||||
{align: []}, {list: 'ordered'}, {list: 'bullet'}, // 列表
|
||||
{script: 'sub'}, {script: 'super'},
|
||||
{ size: ['14px', '16px', '18px', '20px'] },
|
||||
{ align: [] }, { list: 'ordered' }, { list: 'bullet' }, // 列表
|
||||
{ script: 'sub' }, { script: 'super' },
|
||||
{ 'color': [] }, { 'background': [] },
|
||||
{header: [1,2,3,4,5,false]},
|
||||
{ 'font': [] },
|
||||
{ header: [1, 2, 3, 4, 5, false] },
|
||||
'blockquote', 'code-block',
|
||||
'link', 'image', 'video',
|
||||
'formula',
|
||||
|
@ -75,7 +77,6 @@ function QuillForEditor ({
|
|||
|
||||
// 文本内容变化时
|
||||
const handleOnChange = content => {
|
||||
// getQuillContent && getQuillContent(quill);
|
||||
onContentChange && onContentChange(content, quill);
|
||||
};
|
||||
|
||||
|
@ -84,9 +85,7 @@ function QuillForEditor ({
|
|||
const bindings = {
|
||||
tab: {
|
||||
key: 9,
|
||||
handler: function () {
|
||||
console.log('调用了tab=====>>>>');
|
||||
}
|
||||
handler: function () { }
|
||||
},
|
||||
backspace: {
|
||||
key: 'Backspace',
|
||||
|
@ -99,14 +98,13 @@ function QuillForEditor ({
|
|||
*/
|
||||
handler: function (range, context) {
|
||||
/**
|
||||
* index: 删除元素的位置
|
||||
* index: 删除元素的位置
|
||||
* length: 删除元素的个数
|
||||
*/
|
||||
const {index, length} = range;
|
||||
const { index, length } = range;
|
||||
const _start = length === 0 ? index - 1 : index;
|
||||
const _length = length || 1;
|
||||
let delCtx = this.quill.getText(_start, _length); // 删除的元素
|
||||
// aa
|
||||
const reg = /▁/g;
|
||||
const delArrs = delCtx.match(reg);
|
||||
if (delArrs) {
|
||||
|
@ -123,7 +121,7 @@ function QuillForEditor ({
|
|||
let delIndexs = [];
|
||||
// 获取删除元素的下标
|
||||
delArrs.forEach((item, i) => {
|
||||
leaveLen === 0 ? delIndexs.push(i) : delIndexs.push(leaveLen + i);
|
||||
leaveLen === 0 ? delIndexs.push(i) : delIndexs.push(leaveLen + i);
|
||||
});
|
||||
deleteFill && deleteFill(delIndexs); // 调用删除回调, 返回删除的元素下标[]
|
||||
return true
|
||||
|
@ -177,7 +175,7 @@ function QuillForEditor ({
|
|||
const result = await fetchUploadImage(formData);
|
||||
// 获取上传图片的url
|
||||
if (result.data && result.data.id) {
|
||||
fileUrl = getImageUrl(`api/attachments/${result.data.id}`);
|
||||
fileUrl = (`http://123.59.135.93:56666/api/attachments/${result.data.id}`);
|
||||
}
|
||||
// 根据id获取文件路径
|
||||
const { width, height } = imgAttrs;
|
||||
|
@ -214,7 +212,7 @@ function QuillForEditor ({
|
|||
const ops = value.ops || [];
|
||||
ops.forEach((item, i) => {
|
||||
if (item.insert['image']) {
|
||||
item.insert['image'] = Object.assign({}, item.insert['image'], {style: { cursor: 'pointer' }, onclick: (url) => showUploadImage(url)});
|
||||
item.insert['image'] = Object.assign({}, item.insert['image'], { style: { cursor: 'pointer' }, onclick: (url) => showUploadImage(url) });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -223,7 +221,7 @@ function QuillForEditor ({
|
|||
if (!deepEqual(previous, current)) {
|
||||
setSelection(quill.getSelection())
|
||||
if (typeof value === 'string' && value) {
|
||||
// debugger
|
||||
// debugger
|
||||
quill.clipboard.dangerouslyPasteHTML(value, 'api');
|
||||
if (autoFocus) {
|
||||
quill.focus();
|
||||
|
@ -271,9 +269,9 @@ function QuillForEditor ({
|
|||
|
||||
// 返回结果
|
||||
return (
|
||||
<div className='quill_editor_for_react_area' style={wrapStyle}>
|
||||
<div ref={editorRef} style={style}></div>
|
||||
</div>
|
||||
<div className='quill_editor_for_react_area' style={wrapStyle}>
|
||||
<div ref={editorRef} style={style}></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import Quill from "quill";
|
||||
const Inline = Quill.import('blots/inline');
|
||||
|
||||
export default class LinkBlot extends Inline {
|
||||
static create(value) {
|
||||
let node = super.create()
|
||||
let rs = value
|
||||
if (rs.indexOf('http://') < 0) {
|
||||
rs = 'http://' + rs
|
||||
}
|
||||
node.setAttribute('href', rs)
|
||||
node.setAttribute('target', '_blank')
|
||||
return node;
|
||||
}
|
||||
|
||||
static formats(node) {
|
||||
return node.getAttribute('href');
|
||||
}
|
||||
}
|
||||
LinkBlot.blotName = 'link'
|
||||
LinkBlot.tagName = 'a'
|
|
@ -0,0 +1,18 @@
|
|||
.ql-editor .ql-font-Microsoft-YaHei {
|
||||
font-family: "Microsoft YaHei";
|
||||
}
|
||||
.ql-editor .ql-font-SimSun {
|
||||
font-family: "SimSun";
|
||||
}
|
||||
.ql-editor .ql-font-SimHei {
|
||||
font-family: "SimHei";
|
||||
}
|
||||
.ql-editor .ql-font-KaiTi {
|
||||
font-family: "KaiTi";
|
||||
}
|
||||
.ql-editor .ql-font-Arial {
|
||||
font-family: "Arial";
|
||||
}
|
||||
.ql-editor .Times-New-Roman {
|
||||
font-family: "Times New Roman";
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
|
||||
content: '微软雅黑';
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
|
||||
content: "微软雅黑";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
|
||||
content: "宋体";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
|
||||
content: "黑体";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
|
||||
content: "楷体";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
|
||||
content: "Arial";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
|
||||
content: "Times New Roman";
|
||||
}
|
Loading…
Reference in New Issue