fix: 论坛样式优化
This commit is contained in:
parent
b7f33da8b5
commit
fe7b58cb6d
@ -1,4 +1,4 @@
|
||||
import { GithubOutlined, HeartFilled, WechatOutlined, MailOutlined } from '@ant-design/icons';
|
||||
import { HeartFilled } from '@ant-design/icons';
|
||||
import { DefaultFooter } from '@ant-design/pro-components';
|
||||
import React from 'react';
|
||||
|
||||
@ -16,7 +16,7 @@ const Footer: React.FC = () => {
|
||||
copyright={
|
||||
<div>
|
||||
<div >
|
||||
Copyright © 2023-{currentYear} 陕西科技大学镐京学院
|
||||
Copyright © {currentYear} 陕西科技大学镐京学院
|
||||
</div>
|
||||
<div >
|
||||
Powered by <HeartFilled /> SunHe
|
||||
@ -31,12 +31,7 @@ const Footer: React.FC = () => {
|
||||
href: 'https://www.sust.edu.cn/',
|
||||
blankTarget: true,
|
||||
},
|
||||
{
|
||||
key: 'github',
|
||||
title: <GithubOutlined />,
|
||||
href: 'https://github.com/shuguangnet',
|
||||
blankTarget: true,
|
||||
},
|
||||
|
||||
|
||||
]}
|
||||
/>
|
||||
|
62
src/pages/Forum/List/index.less
Normal file
62
src/pages/Forum/List/index.less
Normal file
@ -0,0 +1,62 @@
|
||||
.forumContainer {
|
||||
.searchBar {
|
||||
background: #fff;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.postItem {
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.postTitle {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #1a1a1a;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
|
||||
.postMeta {
|
||||
color: #8c8c8c;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.postStats {
|
||||
color: #595959;
|
||||
font-size: 14px;
|
||||
|
||||
.statItem {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.coverImage {
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
transition: transform 0.3s;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.categoryTag {
|
||||
border-radius: 12px;
|
||||
padding: 2px 12px;
|
||||
}
|
||||
}
|
@ -1,7 +1,14 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Card, List, Tag, Space, Input, Button, Select } from 'antd';
|
||||
import { Card, List, Tag, Space, Input, Button, Select, Badge } from 'antd';
|
||||
import { history } from '@umijs/max';
|
||||
import { SearchOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
SearchOutlined,
|
||||
PlusOutlined,
|
||||
EyeOutlined,
|
||||
MessageOutlined,
|
||||
LikeOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import styles from './index.less';
|
||||
|
||||
const { Search } = Input;
|
||||
|
||||
@ -9,6 +16,74 @@ const ForumList: React.FC = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [filter, setFilter] = useState('all');
|
||||
|
||||
const mockPosts = [
|
||||
{
|
||||
id: 1,
|
||||
title: '使用 GPT-4 进行高级数据分析的实践经验',
|
||||
category: '技术讨论',
|
||||
author: '数据专家',
|
||||
createTime: '2024-01-15 14:30',
|
||||
description: '分享在大规模数据集上使用 GPT-4 进行智能分析的经验,包括提示词工程、数据预处理技巧,以及如何提高分析准确率...',
|
||||
views: 2150,
|
||||
comments: 156,
|
||||
likes: 342,
|
||||
isTop: true,
|
||||
cover: 'https://picsum.photos/272/153',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'AI 辅助数据可视化最佳实践',
|
||||
category: '经验分享',
|
||||
author: '可视化工程师',
|
||||
createTime: '2024-01-14 16:20',
|
||||
description: '探讨如何利用 AI 技术自动生成数据可视化方案,包括图表类型选择、配色方案优化、以及交互设计的智能推荐...',
|
||||
views: 1856,
|
||||
comments: 89,
|
||||
likes: 267,
|
||||
isTop: false,
|
||||
cover: 'https://picsum.photos/272/153?random=2',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '智能预测模型准确率问题求助',
|
||||
category: '问题求助',
|
||||
author: '数据新手',
|
||||
createTime: '2024-01-13 09:45',
|
||||
description: '在使用系统进行销售预测时发现准确率不够理想,数据预处理已经做了基础清洗,请问还有哪些方面需要优化?...',
|
||||
views: 632,
|
||||
comments: 42,
|
||||
likes: 28,
|
||||
isTop: false,
|
||||
cover: null,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: 'AIGC 在金融数据分析中的应用实践',
|
||||
category: '技术讨论',
|
||||
author: '金融分析师',
|
||||
createTime: '2024-01-12 11:30',
|
||||
description: '分享我们团队使用 AIGC 技术进行金融市场分析的经验,包括风险评估、趋势预测和投资建议生成的完整流程...',
|
||||
views: 1967,
|
||||
comments: 156,
|
||||
likes: 420,
|
||||
isTop: true,
|
||||
cover: 'https://picsum.photos/272/153?random=4',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: '大规模数据集的智能分析方法论',
|
||||
category: '经验分享',
|
||||
author: '资深数据科学家',
|
||||
createTime: '2024-01-11 15:15',
|
||||
description: '详细介绍如何处理和分析大规模数据集,包括数据清洗策略、特征工程技巧、模型选择以及结果验证方法...',
|
||||
views: 2543,
|
||||
comments: 189,
|
||||
likes: 534,
|
||||
isTop: false,
|
||||
cover: 'https://picsum.photos/272/153?random=5',
|
||||
},
|
||||
];
|
||||
|
||||
const categories = [
|
||||
{ value: 'all', label: '全部' },
|
||||
{ value: 'tech', label: '技术讨论' },
|
||||
@ -21,51 +96,67 @@ const ForumList: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<div style={{ marginBottom: 16 }}>
|
||||
<Space size="large">
|
||||
<div className={styles.forumContainer}>
|
||||
<Card className={styles.searchBar} bordered={false}>
|
||||
<Space size="large" wrap>
|
||||
<Search
|
||||
placeholder="搜索帖子"
|
||||
placeholder="搜索帖子标题或内容"
|
||||
onSearch={handleSearch}
|
||||
style={{ width: 300 }}
|
||||
allowClear
|
||||
/>
|
||||
<Select
|
||||
value={filter}
|
||||
onChange={setFilter}
|
||||
options={categories}
|
||||
style={{ width: 120 }}
|
||||
placeholder="选择分类"
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => history.push('/forum/publish')}
|
||||
size="large"
|
||||
>
|
||||
发布帖子
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<List
|
||||
loading={loading}
|
||||
itemLayout="vertical"
|
||||
size="large"
|
||||
pagination={{
|
||||
pageSize: 10,
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条帖子`,
|
||||
}}
|
||||
dataSource={[]} // 这里需要接入实际数据
|
||||
renderItem={(item: any) => (
|
||||
dataSource={mockPosts} // 使用模拟数据
|
||||
renderItem={(item) => (
|
||||
<List.Item
|
||||
key={item.id}
|
||||
className={styles.postItem}
|
||||
actions={[
|
||||
<Space>
|
||||
<span>浏览 {item.views}</span>
|
||||
<span>评论 {item.comments}</span>
|
||||
<span>点赞 {item.likes}</span>
|
||||
<Space className={styles.postStats}>
|
||||
<span className={styles.statItem}>
|
||||
<EyeOutlined /> {item.views}
|
||||
</span>
|
||||
<span className={styles.statItem}>
|
||||
<MessageOutlined /> {item.comments}
|
||||
</span>
|
||||
<span className={styles.statItem}>
|
||||
<LikeOutlined /> {item.likes}
|
||||
</span>
|
||||
</Space>,
|
||||
]}
|
||||
extra={
|
||||
item.cover && (
|
||||
<img
|
||||
className={styles.coverImage}
|
||||
width={272}
|
||||
height={153}
|
||||
alt="cover"
|
||||
src={item.cover}
|
||||
/>
|
||||
@ -74,23 +165,35 @@ const ForumList: React.FC = () => {
|
||||
>
|
||||
<List.Item.Meta
|
||||
title={
|
||||
<Space>
|
||||
<a onClick={() => history.push(`/forum/detail/${item.id}`)}>{item.title}</a>
|
||||
<Tag color="blue">{item.category}</Tag>
|
||||
<Space size="middle" align="center">
|
||||
<a
|
||||
className={styles.postTitle}
|
||||
onClick={() => history.push(`/forum/detail/${item.id}`)}
|
||||
>
|
||||
{item.title}
|
||||
</a>
|
||||
<Tag className={styles.categoryTag} color="blue">
|
||||
{item.category}
|
||||
</Tag>
|
||||
{item.isTop && (
|
||||
<Badge color="red" text="置顶" />
|
||||
)}
|
||||
</Space>
|
||||
}
|
||||
description={
|
||||
<Space>
|
||||
<Space className={styles.postMeta} size="middle">
|
||||
<span>{item.author}</span>
|
||||
<span>{item.createTime}</span>
|
||||
<span>发布于 {item.createTime}</span>
|
||||
</Space>
|
||||
}
|
||||
/>
|
||||
<div className={styles.postContent}>
|
||||
{item.description}
|
||||
</div>
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
44
src/pages/Forum/Publish/index.less
Normal file
44
src/pages/Forum/Publish/index.less
Normal file
@ -0,0 +1,44 @@
|
||||
.publishContainer {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 24px;
|
||||
|
||||
.publishCard {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
|
||||
:global {
|
||||
.ant-card-head {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding: 16px 24px;
|
||||
|
||||
.ant-card-head-title {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-card-body {
|
||||
padding: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.formLabel {
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.uploadHint {
|
||||
color: #666;
|
||||
font-size: 13px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.buttonGroup {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Card, Form, Input, Button, Upload, Select, message } from 'antd';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { Card, Form, Input, Button, Upload, Select, message, Space, Alert } from 'antd';
|
||||
import { PlusOutlined, InfoCircleOutlined } from '@ant-design/icons';
|
||||
import type { UploadFile } from 'antd/es/upload/interface';
|
||||
import { history } from '@umijs/max';
|
||||
import styles from './index.less';
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
@ -11,6 +12,12 @@ const ForumPublish: React.FC = () => {
|
||||
const [fileList, setFileList] = useState<UploadFile[]>([]);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
|
||||
const categories = [
|
||||
{ value: 'tech', label: '技术讨论', description: '分享技术经验和最佳实践' },
|
||||
{ value: 'share', label: '经验分享', description: '分享数据分析案例和心得' },
|
||||
{ value: 'question', label: '问题求助', description: '寻求技术支持和解决方案' },
|
||||
];
|
||||
|
||||
const handleSubmit = async (values: any) => {
|
||||
setSubmitting(true);
|
||||
try {
|
||||
@ -25,61 +32,113 @@ const ForumPublish: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Card title="发布帖子">
|
||||
<div className={styles.publishContainer}>
|
||||
<Card title="发布帖子" className={styles.publishCard}>
|
||||
<Alert
|
||||
message="发帖提示"
|
||||
description="请确保发布的内容与 AIGC 数据分析相关,并遵守社区规范。"
|
||||
type="info"
|
||||
showIcon
|
||||
style={{ marginBottom: 24 }}
|
||||
/>
|
||||
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
onFinish={handleSubmit}
|
||||
requiredMark="optional"
|
||||
>
|
||||
<Form.Item
|
||||
name="title"
|
||||
label="标题"
|
||||
rules={[{ required: true, message: '请输入标题' }]}
|
||||
label={<span className={styles.formLabel}>标题</span>}
|
||||
rules={[
|
||||
{ required: true, message: '请输入标题' },
|
||||
{ max: 100, message: '标题最多100个字符' }
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入帖子标题" />
|
||||
<Input
|
||||
placeholder="请输入一个简洁明了的标题"
|
||||
showCount
|
||||
maxLength={100}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="category"
|
||||
label="分类"
|
||||
label={<span className={styles.formLabel}>分类</span>}
|
||||
rules={[{ required: true, message: '请选择分类' }]}
|
||||
tooltip={{
|
||||
title: '选择合适的分类有助于其他用户更好地找到您的帖子',
|
||||
icon: <InfoCircleOutlined />
|
||||
}}
|
||||
>
|
||||
<Select>
|
||||
<Select.Option value="tech">技术讨论</Select.Option>
|
||||
<Select.Option value="share">经验分享</Select.Option>
|
||||
<Select.Option value="question">问题求助</Select.Option>
|
||||
<Select placeholder="请选择帖子分类">
|
||||
{categories.map(cat => (
|
||||
<Select.Option key={cat.value} value={cat.value}>
|
||||
<Space>
|
||||
{cat.label}
|
||||
<span style={{ color: '#999', fontSize: '12px' }}>
|
||||
({cat.description})
|
||||
</span>
|
||||
</Space>
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="content"
|
||||
label="内容"
|
||||
rules={[{ required: true, message: '请输入内容' }]}
|
||||
label={<span className={styles.formLabel}>内容</span>}
|
||||
rules={[
|
||||
{ required: true, message: '请输入内容' },
|
||||
{ min: 20, message: '内容至少20个字符' }
|
||||
]}
|
||||
>
|
||||
<TextArea rows={8} placeholder="请输入帖子内容..." />
|
||||
<TextArea
|
||||
rows={12}
|
||||
placeholder="请详细描述您要分享的内容..."
|
||||
showCount
|
||||
maxLength={5000}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="封面图">
|
||||
<Form.Item
|
||||
label={<span className={styles.formLabel}>封面图</span>}
|
||||
extra={<div className={styles.uploadHint}>支持 jpg、png 格式,建议尺寸 800x450px</div>}
|
||||
>
|
||||
<Upload
|
||||
listType="picture-card"
|
||||
fileList={fileList}
|
||||
onChange={({ fileList }) => setFileList(fileList)}
|
||||
beforeUpload={() => false}
|
||||
beforeUpload={(file) => {
|
||||
const isImage = file.type.startsWith('image/');
|
||||
if (!isImage) {
|
||||
message.error('只能上传图片文件!');
|
||||
}
|
||||
return false;
|
||||
}}
|
||||
maxCount={1}
|
||||
>
|
||||
{fileList.length < 1 && <PlusOutlined />}
|
||||
{fileList.length < 1 && (
|
||||
<div>
|
||||
<PlusOutlined />
|
||||
<div style={{ marginTop: 8 }}>上传图片</div>
|
||||
</div>
|
||||
)}
|
||||
</Upload>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<Button type="primary" htmlType="submit" loading={submitting}>
|
||||
发布
|
||||
</Button>
|
||||
<Button style={{ marginLeft: 8 }} onClick={() => history.back()}>
|
||||
<div className={styles.buttonGroup}>
|
||||
<Button onClick={() => history.back()}>
|
||||
取消
|
||||
</Button>
|
||||
</Form.Item>
|
||||
<Button type="primary" htmlType="submit" loading={submitting}>
|
||||
发布帖子
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user