Merge remote-tracking branch 'origin/factory' into factory
This commit is contained in:
commit
f2b44a4e8e
|
|
@ -1818,6 +1818,10 @@ a.decoration {
|
|||
margin-left: 85px
|
||||
}
|
||||
|
||||
.ml100 {
|
||||
margin-left: 100px
|
||||
}
|
||||
|
||||
.ml180 {
|
||||
margin-left: 180px
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { requestProxy } from "./indexEduplus2RequestProxy";
|
|||
import { broadcastChannelOnmessage, isDev, queryString } from 'educoder';
|
||||
import { notification } from 'antd';
|
||||
|
||||
import './index.css';
|
||||
import './index.scss';
|
||||
|
||||
let message501 = false;
|
||||
broadcastChannelOnmessage('refreshPage', () => {
|
||||
|
|
|
|||
|
|
@ -86,14 +86,7 @@ function SiderBar(props) {
|
|||
|
||||
// 意见反馈按钮点击事件
|
||||
function feedBackClick(){
|
||||
if(login){
|
||||
if(forumsDoMain){
|
||||
return window.location.href=`${forumsDoMain}/forums/new`;
|
||||
}
|
||||
setFeedBackModal(true);
|
||||
}else{
|
||||
history.push(forumsDoMain ? `/login?go_page=${forumsDoMain}/forums/new` : `/login`);
|
||||
}
|
||||
history.push(login ? `/forums/add?sec=4,8` : `/login?go_page=/forums/add?sec=4,8`);
|
||||
}
|
||||
|
||||
function applyFeedBack(){
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Upload , Icon , message } from "antd";
|
||||
import { Upload , Icon , message, Modal } from "antd";
|
||||
import { getUploadActionUrl } from 'educoder';
|
||||
import cookie from 'react-cookies';
|
||||
|
||||
|
|
@ -8,8 +8,12 @@ const TokenKey = 'autologin_trustie';
|
|||
function UploadImage({ getImage , url, getImageId, maxSize = 2, action = getUploadActionUrl(), getImageUrl }){
|
||||
const [ imageUrl , setImageUrl ] = useState(undefined);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [previewVisible, setPreviewVisible] = useState(false);
|
||||
const [fileList, setFileList] = useState([]);
|
||||
|
||||
useEffect(()=>{
|
||||
setImageUrl(url);
|
||||
url && setFileList([{ uid: '-1', url: url }])
|
||||
},[url])
|
||||
|
||||
function getBase64(img, callback) {
|
||||
|
|
@ -35,6 +39,7 @@ function UploadImage({ getImage , url, getImageId, maxSize = 2, action = getUplo
|
|||
}
|
||||
// 上传完成后
|
||||
function handleChange(info){
|
||||
setFileList([info.file]);
|
||||
if(info && info.file && info.file.status === "done"){
|
||||
setLoading(false);
|
||||
getImageId && getImageId(info.file.response.id);
|
||||
|
|
@ -42,30 +47,54 @@ function UploadImage({ getImage , url, getImageId, maxSize = 2, action = getUplo
|
|||
getBase64(info.file.originFileObj, imageUrl =>
|
||||
setImageUrl(imageUrl)
|
||||
);
|
||||
|
||||
}else if(info && info.file && info.file.status === "removed"){
|
||||
setLoading(false);
|
||||
getImageId && getImageId(undefined);
|
||||
getImageUrl && getImageUrl(undefined);
|
||||
setImageUrl(undefined);
|
||||
setFileList([]);
|
||||
}
|
||||
}
|
||||
|
||||
const handlePreview = async (file) => {
|
||||
setPreviewVisible(true);
|
||||
};
|
||||
|
||||
const handleRemove = (file) => {
|
||||
setImageUrl(undefined);
|
||||
setFileList([]);
|
||||
};
|
||||
return(
|
||||
<Upload
|
||||
name="file"
|
||||
listType="picture-card"
|
||||
className="avatar-uploader"
|
||||
showUploadList={false}
|
||||
action={action}
|
||||
beforeUpload={beforeUpload}
|
||||
onChange={handleChange}
|
||||
accept=".png,.jpg,.jpeg"
|
||||
withCredentials={ true }
|
||||
headers={{ Authorization: cookie.load(TokenKey) }}>
|
||||
{
|
||||
imageUrl ?
|
||||
<img src={imageUrl} alt="avatar" style={{ width: '100%' }} />
|
||||
:
|
||||
<div>
|
||||
<Icon type={loading ? 'loading' : 'plus'} />
|
||||
<div className="ant-upload-text">点击上传</div>
|
||||
</div>
|
||||
}
|
||||
</Upload>
|
||||
<div>
|
||||
<Upload
|
||||
name="file"
|
||||
listType="picture-card"
|
||||
className="avatar-uploader"
|
||||
showUploadList={{showPreviewIcon: true, showRemoveIcon: true}}
|
||||
action={action}
|
||||
beforeUpload={beforeUpload}
|
||||
onChange={handleChange}
|
||||
accept=".png,.jpg,.jpeg"
|
||||
withCredentials={ true }
|
||||
headers={{ Authorization: cookie.load(TokenKey) }}
|
||||
fileList={fileList}
|
||||
onPreview={handlePreview}
|
||||
onRemove={handleRemove}>
|
||||
{
|
||||
fileList.length >= 1 ?
|
||||
null
|
||||
:
|
||||
<div>
|
||||
<Icon type={loading ? 'loading' : 'plus'} />
|
||||
<div className="ant-upload-text">点击上传</div>
|
||||
</div>
|
||||
}
|
||||
</Upload>
|
||||
<Modal width={"40%"} visible={previewVisible} footer={null} onCancel={() => setPreviewVisible(false)}>
|
||||
<img alt="example" style={{ width: '100%' }} src={imageUrl} />
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default UploadImage;
|
||||
|
|
@ -46,6 +46,7 @@ export function postReply(id,data) {
|
|||
});
|
||||
}
|
||||
|
||||
// 也可以用于删除帖子
|
||||
export function deleteReply(id) {
|
||||
return fetch({
|
||||
url: `/api/memos/${id}.json`,
|
||||
|
|
@ -68,4 +69,58 @@ export function setWatch(id,isWatch) {
|
|||
is_watch:isWatch,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function getForumSectionList(params) {
|
||||
return fetch({
|
||||
url: `/api/forum_sections.json`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
export function createMemo(data) {
|
||||
return fetch({
|
||||
url: `/api/memos.json`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
export function updateMemo(data) {
|
||||
return fetch({
|
||||
url: `/api/memos/${data.id}.json`,
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
}
|
||||
export async function getMemoByEditor(id) {
|
||||
return fetch({
|
||||
url: `/api/memos/${id}/edit.json`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
export async function setMemoTopStatus(id, sticky) {
|
||||
return fetch({
|
||||
url: `/api/memos/${id}/set_top_or_down.json?sticky=${sticky}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
export async function setMemoFineStatus(id, is_fine) {
|
||||
return fetch({
|
||||
url: `/api/memos/${id}/is_fine.json`,
|
||||
method: 'POST',
|
||||
data: {is_fine}
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteUserForums(id,is_apply) {
|
||||
return fetch({
|
||||
url: `/api/memos/${id}/confirm_delete.json`,
|
||||
method: 'post',
|
||||
data:{
|
||||
is_apply
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -12,8 +12,6 @@ import RenderHtml from '../../components/render-html';
|
|||
import { deleteReply, getReplyList } from '../api';
|
||||
|
||||
function IssueCommentList(props){
|
||||
console.log('props', props);
|
||||
|
||||
const{docId, history: {location}, reload, reloadComment, showNotification, current_user:{login, admin, image_url, username}, isManager, showLoginDialog, author} = props;
|
||||
const {owner, projectsId, index} = props.match.params;
|
||||
const [category, setCategory] = useState('comment');
|
||||
|
|
@ -57,8 +55,6 @@ function IssueCommentList(props){
|
|||
page: page
|
||||
}
|
||||
getReplyList(docId, params).then(res=>{
|
||||
console.log('res', res);
|
||||
|
||||
if(res){
|
||||
const {memo_replies, memos_count, total_count} = res;
|
||||
// if(category === 'all'){
|
||||
|
|
@ -90,7 +86,7 @@ function IssueCommentList(props){
|
|||
setSpin(false)
|
||||
}
|
||||
})
|
||||
}, [reload, category, page])
|
||||
}, [reload, category, page, docId])
|
||||
|
||||
function commentCtx(v){
|
||||
return <RenderHtml owner={owner} projectsId={projectsId} className="break_word_comments imageLayerParent commentRenderHtml" value={v} url={location}/>;
|
||||
|
|
@ -112,7 +108,7 @@ function IssueCommentList(props){
|
|||
}
|
||||
|
||||
return(
|
||||
(isPhone() && journalsCount === 0) ? '' : <div className="commentListBox_forums mt30">
|
||||
(isPhone() && journalsCount === 0) ? '' : <div className="commentListBox_forums mt30" id="commentListBox_forums">
|
||||
{/* 评论 */}
|
||||
<div className={`${!login && journalsCount > 0 && 'pb15'}`}>
|
||||
<div className='font-22'>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import './index.scss';
|
||||
import { getForumMemoById, postPlus, setWatch } from "../api";
|
||||
import { Divider, message, Tag } from "antd";
|
||||
import { deleteReply, deleteUserForums, getForumMemoById, postPlus, setMemoFineStatus, setMemoTopStatus, setWatch } from "../api";
|
||||
import { Button, Divider, Dropdown, message, Modal, Tag } from "antd";
|
||||
import icon12 from '../image/icon12.png';
|
||||
import icon6 from '../image/icon6.png';
|
||||
import icon10 from '../image/icon10.png';
|
||||
|
|
@ -12,11 +12,13 @@ import CommentList from '../comments/list'
|
|||
import { httpUrl } from "../fetch";
|
||||
|
||||
function detail(props) {
|
||||
const { match: { params: { id } }, current_user } = props;
|
||||
const { match: { params: { id } }, current_user, history } = props;
|
||||
const [reload, setReload] = useState(undefined);
|
||||
const [detail, setDetail] = useState(undefined);
|
||||
const [commentReload, setCommentReload] = useState(undefined);
|
||||
const { memo = {}, author_info = {}, recent_memos=[], memo_image_info } = detail || {};
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { memo = {}, author_info = {}, recent_memos=[], memo_image_info, banned_permission=false } = detail || {};
|
||||
const {apply_destroy=false} = memo || {};
|
||||
|
||||
useEffect(() => {
|
||||
id && getForumMemoById(id).then(res => {
|
||||
|
|
@ -56,7 +58,7 @@ function detail(props) {
|
|||
]
|
||||
|
||||
function actionClick(item){
|
||||
const {memoKey} = item;
|
||||
const {memoKey, id} = item;
|
||||
if(memoKey === "user_praise"){
|
||||
postPlus({
|
||||
container_type: "Memo",
|
||||
|
|
@ -75,9 +77,21 @@ function detail(props) {
|
|||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
}else if(id === "reply"){
|
||||
// 点击按钮,页面滚动到评论区,并且打开新增评论编辑框
|
||||
const commentsSection = document.getElementById('commentListBox_forums');
|
||||
if (commentsSection) {
|
||||
commentsSection.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const tipByModal = {
|
||||
1: ["确定删除该帖子吗?", "删除后将无法恢复,请谨慎操作!", "删除帖子"],
|
||||
2: ["确定申请删除该帖子吗?", "申请后请耐心等待管理员审核,删除后将无法恢复,请谨慎操作!", "申请删除帖子"],
|
||||
3: ["确定撤销删除申请吗?", "撤销后该帖子将恢复正常!", "撤销删除申请"]
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="forums-detail-box">
|
||||
<div className="width1600 pt25 pb20">
|
||||
|
|
@ -88,7 +102,7 @@ function detail(props) {
|
|||
{/* 左侧操作区 */}
|
||||
<div className="forums-detail-left">
|
||||
{actions.map((item, index) => (
|
||||
<span className={`mb20 ${["praises", "watcher"].includes(item.id) && "pointer"}`} key={index} onClick={()=>{actionClick(item)}}>
|
||||
<span className={`mb20 ${["praises", "watcher", "reply"].includes(item.id) && "pointer"}`} key={index} onClick={()=>{actionClick(item)}}>
|
||||
<span className="action-fo AlignCenter">
|
||||
<span className={`action-fo-icon ${item.id}`}>
|
||||
{item.icon ? <img src={item.icon} /> : <span className={`action-fo-icon-img ${item.id}`}></span>}
|
||||
|
|
@ -102,11 +116,55 @@ function detail(props) {
|
|||
<div className="forums-detail-center flex1">
|
||||
<div className="forums-detail-content forums-white-bk">
|
||||
{memo.is_original && <span className="original_tag font-13 font-bd color-white">原创</span>}
|
||||
<div className="font-22 AlignCenter">
|
||||
<span className="font-bd" style={{flexShrink: 0}}>【{memo.tag_name}】</span>
|
||||
{memo.subject}
|
||||
{memo.sticky && <Tag color="#d06d3c">置顶</Tag>}
|
||||
{memo.is_fine && <Tag color="#2E89FF">精华</Tag>}
|
||||
<div className="font-22 FlexAJ">
|
||||
<div className="AlignCenter">
|
||||
<span className="font-bd" style={{flexShrink: 0}}>【{memo.tag_name}】</span>
|
||||
{memo.subject}
|
||||
{memo.sticky && <Tag color="#d06d3c">置顶</Tag>}
|
||||
{memo.is_fine && <Tag color="#2E89FF">精华</Tag>}
|
||||
</div>
|
||||
{(memo.is_current_user||banned_permission)&& <Dropdown
|
||||
placement="bottomCenter"
|
||||
className="forumsDetail_edit_dropdown"
|
||||
getPopupContainer={trigger => trigger.parentNode}
|
||||
overlay={
|
||||
<div className="forumsDetail_edit_dropdownList">
|
||||
{banned_permission && <Fragment>
|
||||
<a onClick={()=>{
|
||||
setMemoTopStatus(id, !memo.sticky ? 1 : 0).then(res=>{
|
||||
if(!res.status){
|
||||
message.success(res.message);
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
}}>{memo.sticky ? "取消置顶" : "置顶"}</a>
|
||||
|
||||
<a onClick={()=>{
|
||||
setMemoFineStatus(id, !memo.is_fine ? 1 : 0).then(res=>{
|
||||
if(!res.status){
|
||||
message.success(res.message);
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
}}>{memo.is_fine ? "取消推荐" : "推荐"}</a>
|
||||
|
||||
<a onClick={()=>{setVisible(1)}}>删除</a>
|
||||
</Fragment>}
|
||||
|
||||
{(memo.is_current_user || banned_permission) && <Fragment>
|
||||
<Link to={`/forums/${memo.id}/edit`}>编辑</Link>
|
||||
</Fragment>}
|
||||
|
||||
{memo.is_current_user && !banned_permission && <Fragment>
|
||||
<a onClick={()=>{
|
||||
setVisible(apply_destroy ? 3 : 2)
|
||||
}}>{apply_destroy ? "撤销申请" : "申请删帖"}</a>
|
||||
</Fragment>}
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Button className="font-16">更多</Button>
|
||||
</Dropdown>}
|
||||
</div>
|
||||
<div className="opacity8 mt20">
|
||||
<img src={author_info.image_url} alt="" className="user-img" />
|
||||
|
|
@ -168,6 +226,37 @@ function detail(props) {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{!!visible && <Modal
|
||||
okText="确认"
|
||||
cancelText="取消"
|
||||
okType='default'
|
||||
title={tipByModal[visible][2]}
|
||||
visible={true}
|
||||
onCancel={()=>{setVisible(false)}}
|
||||
onOk={()=>{
|
||||
if(visible === 1){
|
||||
deleteReply(id).then(res=>{
|
||||
if(res && !res.status){
|
||||
setVisible(false);
|
||||
message.success('删除成功');
|
||||
history.push(`/forums`)
|
||||
}
|
||||
})
|
||||
}else{
|
||||
deleteUserForums(id, apply_destroy ? 0 : 1).then(res=>{
|
||||
if(res && res.status === 1){
|
||||
setVisible(false);
|
||||
message.success(res.message);
|
||||
setReload(Math.random());
|
||||
}
|
||||
})
|
||||
}
|
||||
}}
|
||||
className="purpleGradient"
|
||||
>
|
||||
<div className='tilTask mt20 font-18 mb20 ml20'><i className="iconfont icon-shanchu_tc_icon1 color-red mr10 font-20"></i>{tipByModal[visible][0]}</div>
|
||||
<p className='tipTask mb30 ml50 font-16'>{tipByModal[visible][1]}</p>
|
||||
</Modal>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,6 +94,12 @@
|
|||
img:not(.forums-detail-content-headImg){
|
||||
max-width: 100%;
|
||||
}
|
||||
.forumsDetail_edit_dropdown{
|
||||
border-radius: 15px;
|
||||
padding: 0 14px;
|
||||
height: 30px;
|
||||
line-height: 29px;
|
||||
}
|
||||
}
|
||||
.forums-detail-right{
|
||||
width: 21%;
|
||||
|
|
@ -131,6 +137,20 @@
|
|||
background-size: 100% 100%;
|
||||
padding: 14px 25px;
|
||||
}
|
||||
.forumsDetail_edit_dropdownList{
|
||||
background: #fff;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 4px 8px rgba(65, 84, 241, .1);
|
||||
padding: 10px 5px;
|
||||
width: 100px;
|
||||
a{
|
||||
text-align: center;
|
||||
display: block;
|
||||
padding: 6px 0px;
|
||||
font-size: 15px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes gifEmoji {
|
||||
from {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,228 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { createMemo, getForumSectionList, getMemoByEditor, updateMemo } from "../api";
|
||||
import './index.scss';
|
||||
import { Divider, Form, Input, Cascader, Select, Breadcrumb, Upload, Button, Icon, Radio, message } from "antd";
|
||||
import RichEditor from '../../forge/Component/RichEditor';
|
||||
import UploadImage from '../../forge/Team/Component/UploadImage';
|
||||
import { httpUrl } from "../fetch";
|
||||
const { Option } = Select;
|
||||
|
||||
function EditForum(props) {
|
||||
const { match, form, history, location:{ search } } = props;
|
||||
const { id } = match.params;
|
||||
const { getFieldDecorator, validateFields, setFieldsValue, getFieldsValue } = form;
|
||||
const searchParams = new URLSearchParams(search.substring(1));
|
||||
const sec = searchParams.get("sec");
|
||||
const [sectionList, setSectionList] = useState([]);
|
||||
const [fileList, setFileList] = useState(undefined);
|
||||
const [detail, setDetail] = useState(undefined);
|
||||
const { is_original } = getFieldsValue();
|
||||
|
||||
useEffect(() => {
|
||||
getForumSectionList().then(res => {
|
||||
const processedSections = res.forum_sections.map(item => {
|
||||
const section = {
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
};
|
||||
if (item.children_tags && !!item.children_tags.length) {
|
||||
section.children = item.children_tags.map(ele => ({
|
||||
value: ele.id,
|
||||
label: ele.title,
|
||||
}));
|
||||
}
|
||||
return section;
|
||||
});
|
||||
setSectionList(processedSections);
|
||||
if(!!sec && !id){
|
||||
setFieldsValue({
|
||||
// 转成int数组
|
||||
forumList: sec.split(",").map(item => parseInt(item))
|
||||
})
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (id) {
|
||||
getMemoByEditor(id).then(res => {
|
||||
setDetail(res)
|
||||
const {subject, forum_section: {forum_id}, children_forum_section: {children_forum_id}, attachments_url=[]} = res;
|
||||
document.title = `编辑-${subject}`;
|
||||
const files = attachments_url.map(item=>{
|
||||
return {
|
||||
name: item.title,
|
||||
uid: item.id,
|
||||
id: item.id
|
||||
}
|
||||
})
|
||||
setFieldsValue({
|
||||
...res,
|
||||
forumList:[forum_id,children_forum_id],
|
||||
is_original: res.is_original? 1 : 0,
|
||||
attachments: {fileList: files}
|
||||
})
|
||||
setFileList(files)
|
||||
})
|
||||
} else {
|
||||
document.title = `新增-论坛交流`;
|
||||
setFieldsValue({
|
||||
is_original: 1
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
|
||||
function beforeUpload(file) {
|
||||
const isLt100M = file.size / 1024 / 1024 < 100;
|
||||
if (!isLt100M) {
|
||||
message.error(`文件大小必须小于${100}MB!`);
|
||||
}
|
||||
return isLt100M;
|
||||
}
|
||||
|
||||
function changeFileList(info) {
|
||||
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
|
||||
const fileList = info.fileList || [];
|
||||
setFileList(fileList);
|
||||
}
|
||||
}
|
||||
|
||||
const submitForm = () => {
|
||||
validateFields((error, values) => {
|
||||
if (!error) {
|
||||
const {attachments} = values;
|
||||
const attachmentIdArray = attachments && attachments.fileList.map(item => item.response && item.response.id ? item.response.id : item.id ? item.id : item)
|
||||
const params = {
|
||||
attachment_id: values.attachment_id,
|
||||
attachments: attachmentIdArray,
|
||||
children_forum_id: values.forumList[1] || '0',
|
||||
forum_id: values.forumList[0],
|
||||
id,
|
||||
memo: {
|
||||
content: values.content,
|
||||
is_original: values.is_original,
|
||||
reprint_link: values.reprint_link,
|
||||
subject: values.subject,
|
||||
tag_id: values.tag_id,
|
||||
},
|
||||
}
|
||||
if (id) {
|
||||
updateMemo(params).then(ret => {
|
||||
message.success(ret.message);
|
||||
if(ret.status === 1){
|
||||
history.push("/forums/" + id);
|
||||
}
|
||||
})
|
||||
}else {
|
||||
createMemo(params).then(ret => {
|
||||
message.success(ret.message);
|
||||
if(ret.status === 1){
|
||||
history.push("/forums/" + ret.memo_id);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const layout = {
|
||||
labelCol: { span: 2 },
|
||||
wrapperCol: { span: 14 },
|
||||
};
|
||||
|
||||
return <div className="forums_edit_box pt30 pb10">
|
||||
<div className="width1600 mb20">
|
||||
<Breadcrumb separator=">">
|
||||
<Breadcrumb.Item href={`/forums`}>论坛交流</Breadcrumb.Item>
|
||||
{id && detail && <Breadcrumb.Item href={`/forums/${id}`}>{detail.subject}</Breadcrumb.Item>}
|
||||
<Breadcrumb.Item>{id ? '编辑' : '新建'}帖子</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
</div>
|
||||
<div className="width1600 forums_edit_content mb100">
|
||||
<h3>{id ? `编辑` : `新增`}</h3>
|
||||
<Divider className="mt10" />
|
||||
<Form {...layout} className="forum_edit_form">
|
||||
<Form.Item label="标题">
|
||||
{getFieldDecorator("subject", {
|
||||
rules: [{ required: true, message: "请输入标题" }]
|
||||
})(
|
||||
<Input placeholder="请输入标题" maxLength={500} />
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="主题板块">
|
||||
{getFieldDecorator("forumList", {
|
||||
rules: [{ required: true, message: "请选择主题板块" }]
|
||||
})(
|
||||
<Cascader options={sectionList} placeholder="请选择主题板块" ></Cascader>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="帖子标签">
|
||||
{getFieldDecorator("tag_id", {
|
||||
rules: [{ required: true, message: "请选择帖子标签" }]
|
||||
})(
|
||||
<Select placeholder="请选择帖子标签" >
|
||||
<Option value={1}>交流</Option>
|
||||
<Option value={2}>求助</Option>
|
||||
<Option value={3}>新闻</Option>
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="是否原创">
|
||||
{getFieldDecorator("is_original", {
|
||||
rules: [{ required: true, message: "请选择是否原创" }]
|
||||
})(
|
||||
<Radio.Group>
|
||||
<Radio value={1}>是</Radio>
|
||||
<Radio value={0}>否</Radio>
|
||||
</Radio.Group>
|
||||
)}
|
||||
</Form.Item>
|
||||
{!is_original && <Form.Item label="转载自">
|
||||
{getFieldDecorator("reprint_link")(
|
||||
<Input placeholder="请输入转载自" />
|
||||
)}
|
||||
</Form.Item>}
|
||||
<Form.Item label="内容" wrapperCol={{ span: 22 }}>
|
||||
{getFieldDecorator("content", {
|
||||
rules: [{ required: true, message: "请输入内容" }],
|
||||
})(
|
||||
<RichEditor uploadUrl={`${httpUrl}/api/attachments.json`} videoUploadUrl={`${httpUrl}/api/attachments.json`} setValue={(value) => { setFieldsValue({ "content": value }) }} />
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="头图" extra="上传png、jpg、jpeg格式的图片">
|
||||
{getFieldDecorator("attachment_id")(
|
||||
<UploadImage url={detail && detail.memo_image_info ? encodeURI(`${httpUrl}${detail.memo_image_info.url}`) : undefined} maxSize={5} getImageId={(id) => setFieldsValue({ "attachment_id": id })} action={`${httpUrl}/api/attachments.json`} />
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="上传附件">
|
||||
{getFieldDecorator('attachments')(
|
||||
<Upload.Dragger action={`${httpUrl}/api/attachments.json`} beforeUpload={beforeUpload} onChange={changeFileList} fileList={fileList}>
|
||||
<p className="ant-upload-drag-icon">
|
||||
<Icon type="inbox" />
|
||||
</p>
|
||||
<p className="mt10">点击或拖拽文件到此区域上传,文件大小不超过 100MB</p>
|
||||
</Upload.Dragger>)}
|
||||
</Form.Item>
|
||||
<div className="ml100 pt30">
|
||||
<Form.Item className="submit_button">
|
||||
<Button
|
||||
className="mr20"
|
||||
onClick={() => {
|
||||
history.push("/forums");
|
||||
}}
|
||||
>
|
||||
返回
|
||||
</Button>
|
||||
<Button type="primary" onClick={submitForm}>
|
||||
提交
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
export default Form.create()(EditForum);
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
.forums_edit_box{
|
||||
background-color: #f1f6fd;
|
||||
background-image: url('../image/bk.png');
|
||||
background-size: 100% auto;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.forums_edit_content{
|
||||
box-shadow: rgba(35, 44, 121, 0.07) 0px 1px 3px 1px;
|
||||
background: rgb(255, 255, 255);
|
||||
border-radius: 4px;
|
||||
padding: 20px 30px 40px;
|
||||
}
|
||||
.forum_edit_form{
|
||||
.ant-col-2{
|
||||
width: 6%;
|
||||
}
|
||||
.submit_button{
|
||||
button{
|
||||
padding: 6px 30px;
|
||||
height: auto;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.5 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
|
|
@ -15,10 +15,26 @@ const List = Loadable({
|
|||
loader : () => import("./list"),
|
||||
loading: Loading,
|
||||
})
|
||||
const Editor = Loadable({
|
||||
loader : () => import("./edit"),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
function SoftBot(props){
|
||||
return <div>
|
||||
<Switch {...props}>
|
||||
<Route
|
||||
path="/forums/add"
|
||||
render={(p) => (
|
||||
<Editor {...props} {...p} />
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/forums/:id/edit"
|
||||
render={(p) => (
|
||||
<Editor {...props} {...p} />
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/forums/:id"
|
||||
render={(p) => (
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import { rollingButton } from "../../components/button";
|
|||
import { HoverUnderline } from "../../components/title";
|
||||
|
||||
function List(props) {
|
||||
const {mygetHelmetapi, location} = props;
|
||||
const {mygetHelmetapi, location, current_user} = props;
|
||||
const {common} = mygetHelmetapi || {};
|
||||
const {forums: forumsDoMain} = common || {};
|
||||
const tagNameByState = location && location.state && location.state.name;
|
||||
|
|
@ -151,7 +151,7 @@ function List(props) {
|
|||
<div className="width1600 center">
|
||||
<div className="font-60 font-bd forums-banner-title1 mb10"><span>论坛交流·</span><span className="carousel-text">开始思想的</span><span className="carousel-text">联接与互动</span></div>
|
||||
<div className="font-18 mb35 forums-banner-title2">需求反馈 技术交流 创意分享</div>
|
||||
{forumsDoMain && rollingButton({href: `${forumsDoMain}/forums/new`, name: '发布帖子', hoverName: '发布帖子', classname: "add-forums"})}
|
||||
{forumsDoMain && rollingButton({href: current_user && current_user.login ? `/forums/add` : `/login?go_page=/forums/add`, name: '发布帖子', hoverName: '发布帖子', classname: "add-forums"})}
|
||||
</div>
|
||||
<div className="width1600 df pt50 forums-hot-list">
|
||||
{forumsImgList && !!forumsImgList.length && <Carousel autoplay className='forums-list-left-Carousel' beforeChange={(_, nextId)=>{setActiveId(nextId)}}>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
.forums-banner-box {
|
||||
background-image: url('../image/banner.png');
|
||||
background-size: 100% 100%;
|
||||
padding: 70px 0 45px;
|
||||
padding: 70px 0 145px;
|
||||
|
||||
.forums-banner-title1 {
|
||||
font-family: 'DouyinSansBold';
|
||||
|
|
@ -170,7 +170,8 @@
|
|||
background-image: linear-gradient(179.88deg, #ffffff 0%, rgba(255, 255, 255, 0.62) 16.1%, rgba(255, 255, 255, 0) 100%);
|
||||
border-radius: 40px;
|
||||
position: relative;
|
||||
--offsetTop: 66px;
|
||||
--offsetTop: 116px;
|
||||
--top: -60px;
|
||||
animation: itemUp .4s ease-in-out 1.56s forwards, bgOpacity .4s linear 1.56s reverse backwards;
|
||||
.user-img{
|
||||
width:24px;
|
||||
|
|
@ -211,20 +212,24 @@
|
|||
}
|
||||
}
|
||||
&:nth-of-type(3) .forums-section-item{
|
||||
background-image:linear-gradient(90deg,#D7DEFF 0% 49.37%,#C7CFFF 100%);
|
||||
background-image: url('../image/forums3.png');
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
&:nth-of-type(2) .forums-section-item{
|
||||
background-image:linear-gradient(90deg,#C7E3FF 0% 49.37%,#B2D6FF 100%);
|
||||
background-image: url('../image/forums2.png');
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
&:nth-of-type(4) .forums-section-item{
|
||||
background-image:linear-gradient(90deg,#DCF6D6 0% 49.37%,#C8FFDF 100%);
|
||||
background-image: url('../image/forums4.png');
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
.forums-section-item{
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
border-radius:15px;
|
||||
background-image:linear-gradient(90deg,#C0E9FE 0% 49.37%,#A6DDFC 100%);
|
||||
background-image: url('../image/forums1.png');
|
||||
background-size: 100% 100%;
|
||||
|
||||
.memo_image_info{
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { AppContainer } from 'react-hot-loader';
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { BrowserRouter, Route } from 'react-router-dom'
|
||||
import './index.css';
|
||||
import './index.scss';
|
||||
import App from './App';
|
||||
import { configureUrlQuery } from 'react-url-query';
|
||||
import history from './history';
|
||||
|
|
|
|||
|
|
@ -256,4 +256,49 @@ i.color-orange05:hover {
|
|||
margin-top: -48px;
|
||||
vertical-align:bottom;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
/* 紫色渐变弹窗 */
|
||||
.purpleGradient.ant-modal{
|
||||
&.headerBgImage .ant-modal-content{
|
||||
// background-image: url("./images/modalbk.png");
|
||||
background-size: 100% auto;
|
||||
background-color:#fbfcff;
|
||||
background-repeat: no-repeat;
|
||||
border-radius:34px;
|
||||
}
|
||||
.ant-modal-title{
|
||||
color: #191919;
|
||||
text-align: center;
|
||||
}
|
||||
.ant-modal-content{
|
||||
border-radius: 20px;
|
||||
background:linear-gradient(179.76deg, #D8DDFF 0%, #fbfcff 27%)
|
||||
}
|
||||
.ant-modal-header, .agreement-content{
|
||||
background: none;
|
||||
}
|
||||
.ant-modal-header{
|
||||
margin: 0 20px;
|
||||
border-bottom:1px dashed rgba(174, 175, 185, 0.39);
|
||||
}
|
||||
.ant-modal-body{
|
||||
padding-bottom: 0px;
|
||||
.ant-input:hover{
|
||||
border-color: #4154F1;
|
||||
}
|
||||
}
|
||||
.ant-modal-footer{
|
||||
padding-bottom: 55px;
|
||||
text-align: center;
|
||||
border-top: none;
|
||||
button{
|
||||
width:101px;
|
||||
height:36px;
|
||||
border-radius:6px;
|
||||
&:not(:last-of-type){
|
||||
margin-right: 35px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue