Merge remote-tracking branch 'origin/factory' into factory

This commit is contained in:
黄心宇 2026-01-16 10:31:22 +08:00
commit f2b44a4e8e
20 changed files with 562 additions and 58 deletions

View File

@ -1818,6 +1818,10 @@ a.decoration {
margin-left: 85px
}
.ml100 {
margin-left: 100px
}
.ml180 {
margin-left: 180px
}

View File

@ -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', () => {

View File

@ -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(){

View File

@ -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;

View File

@ -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
}
});
}

View File

@ -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'>

View File

@ -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>
)
}

View File

@ -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 {

228
src/forums/edit/index.jsx Normal file
View File

@ -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);

View File

@ -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

View File

@ -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) => (

View File

@ -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)}}>

View File

@ -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%;

View File

@ -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';

View File

@ -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;
}
}
}
}