修正了部分页面显示问题
parent
e2211fbc9b
commit
e6794a1952
|
|
@ -2,6 +2,8 @@ import { useEffect } from 'react'
|
|||
import { BrowserRouter, Routes, Route, Navigate, useParams, Outlet } from 'react-router-dom'
|
||||
import { ConfigProvider, theme } from 'antd'
|
||||
import zhCN from 'antd/locale/zh_CN'
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/zh-cn'
|
||||
import useThemeStore from '@/stores/themeStore'
|
||||
import Login from '@/pages/Login/Login'
|
||||
import ProjectList from '@/pages/ProjectList/ProjectList'
|
||||
|
|
@ -21,6 +23,8 @@ import ProtectedRoute from '@/components/ProtectedRoute'
|
|||
import MainLayout from '@/components/MainLayout/MainLayout'
|
||||
import '@/App.css'
|
||||
|
||||
dayjs.locale('zh-cn')
|
||||
|
||||
// 重定向到文档页面的组件
|
||||
function RedirectToDocs() {
|
||||
const { projectId } = useParams()
|
||||
|
|
|
|||
|
|
@ -4,20 +4,51 @@
|
|||
|
||||
.page-title {
|
||||
margin-bottom: 24px;
|
||||
color: #333;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 日历卡片 */
|
||||
.calendar-card {
|
||||
height: 100%;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.calendar-card .ant-picker-calendar {
|
||||
padding: 12px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* 日历头部选择器 */
|
||||
.calendar-card .ant-picker-calendar-header {
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
/* 日历单元格 - 迷你模式 */
|
||||
.calendar-card .ant-picker-cell {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.calendar-card .ant-picker-cell .ant-picker-cell-inner {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
/* Badge 相对于日期本身定位 */
|
||||
.calendar-card .ant-badge {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.calendar-card .ant-badge-count {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
right: -2px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* 活动卡片 */
|
||||
.activity-card {
|
||||
height: 100%;
|
||||
min-height: 400px;
|
||||
|
|
@ -58,17 +89,17 @@
|
|||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* 日历单元格样式 */
|
||||
.ant-picker-calendar-date {
|
||||
position: relative;
|
||||
/* 暗色模式适配 */
|
||||
body.dark .activity-item-clickable:hover {
|
||||
background-color: rgba(24, 144, 255, 0.15);
|
||||
}
|
||||
|
||||
.ant-picker-calendar-date-today {
|
||||
border-color: #1890ff;
|
||||
body.dark .activity-item-clickable:active {
|
||||
background-color: rgba(24, 144, 255, 0.25);
|
||||
}
|
||||
|
||||
.ant-picker-calendar-date-selected {
|
||||
background-color: #e6f7ff;
|
||||
body.dark .activity-item-disabled:hover {
|
||||
background-color: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
|
|
|
|||
|
|
@ -53,22 +53,31 @@ function Desktop() {
|
|||
}
|
||||
|
||||
// 日历单元格渲染
|
||||
const dateCellRender = (value) => {
|
||||
const dateCellRender = (value, info) => {
|
||||
if (info.type !== 'date') return info.originNode
|
||||
|
||||
const dateStr = value.format('YYYY-MM-DD')
|
||||
const activity = activityDates.find(item => item.date === dateStr)
|
||||
|
||||
if (activity && activity.count > 0) {
|
||||
return (
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<Badge
|
||||
count={activity.count}
|
||||
style={{ backgroundColor: '#1890ff' }}
|
||||
overflowCount={99}
|
||||
/>
|
||||
</div>
|
||||
<Badge
|
||||
count={activity.count}
|
||||
style={{
|
||||
backgroundColor: '#ff4d4f',
|
||||
fontSize: '10px',
|
||||
height: '16px',
|
||||
lineHeight: '16px',
|
||||
minWidth: '16px',
|
||||
padding: '0 4px'
|
||||
}}
|
||||
>
|
||||
{info.originNode}
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
return null
|
||||
|
||||
return info.originNode
|
||||
}
|
||||
|
||||
// 日期选择事件
|
||||
|
|
@ -114,7 +123,7 @@ function Desktop() {
|
|||
value={selectedDate}
|
||||
onSelect={onSelect}
|
||||
onPanelChange={onPanelChange}
|
||||
cellRender={dateCellRender}
|
||||
fullCellRender={dateCellRender}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import {
|
|||
FilePdfOutlined,
|
||||
FileTextOutlined,
|
||||
UndoOutlined,
|
||||
CloseOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import { Editor } from '@bytemd/react'
|
||||
import gfm from '@bytemd/plugin-gfm'
|
||||
|
|
@ -889,7 +890,11 @@ function DocumentEditor() {
|
|||
className="document-sider"
|
||||
>
|
||||
<div className="sider-header">
|
||||
<h2>{projectName}</h2>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
|
||||
<h2 style={{ margin: 0, flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={projectName}>
|
||||
{projectName}
|
||||
</h2>
|
||||
</div>
|
||||
<div className="sider-actions">
|
||||
<Space size={8}>
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -75,3 +75,46 @@
|
|||
font-size: 12px;
|
||||
color: var(--text-color-secondary);
|
||||
}
|
||||
|
||||
/* 圆点分页指示器样式 */
|
||||
.dot-pagination.ant-pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dot-pagination .ant-pagination-item {
|
||||
border: none !important;
|
||||
background: transparent !important;
|
||||
min-width: 16px !important;
|
||||
height: 16px !important;
|
||||
line-height: 16px !important;
|
||||
margin: 0 4px !important;
|
||||
}
|
||||
|
||||
.dot-pagination .ant-pagination-item a {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.dot-pagination .pagination-dot {
|
||||
display: block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--text-color-secondary);
|
||||
opacity: 0.3;
|
||||
margin: 4px auto;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.dot-pagination .ant-pagination-item-active .pagination-dot {
|
||||
background-color: var(--link-color);
|
||||
opacity: 1;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.dot-pagination .ant-pagination-prev,
|
||||
.dot-pagination .ant-pagination-next {
|
||||
min-width: 24px !important;
|
||||
height: 24px !important;
|
||||
line-height: 24px !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { Card, Empty, Modal, Form, Input, Row, Col, Space, Button, Switch, message, Select, Table, Tag } from 'antd'
|
||||
import { Card, Empty, Modal, Form, Input, Row, Col, Space, Button, Switch, message, Select, Table, Tag, Pagination } from 'antd'
|
||||
import { PlusOutlined, FolderOutlined, TeamOutlined, EyeOutlined, ShareAltOutlined, CopyOutlined, DeleteOutlined, EditOutlined, FileOutlined, GithubOutlined, CheckOutlined, SwapOutlined } from '@ant-design/icons'
|
||||
import { getMyProjects, getOwnedProjects, getSharedProjects, createProject, deleteProject, updateProject, getProjectMembers, addProjectMember, removeProjectMember, getGitRepos, createGitRepo, updateGitRepo, deleteGitRepo, transferProject } from '@/api/project'
|
||||
import { getProjectShareInfo, updateShareSettings } from '@/api/share'
|
||||
|
|
@ -36,11 +36,18 @@ function ProjectList({ type = 'my' }) {
|
|||
const [transferModalVisible, setTransferModalVisible] = useState(false)
|
||||
const [transferForm] = Form.useForm()
|
||||
const navigate = useNavigate()
|
||||
const [currentPage, setCurrentPage] = useState(1)
|
||||
const pageSize = 8
|
||||
|
||||
useEffect(() => {
|
||||
fetchProjects()
|
||||
setCurrentPage(1)
|
||||
}, [type])
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentPage(1)
|
||||
}, [searchKeyword])
|
||||
|
||||
// ... (fetchProjects code)
|
||||
|
||||
const handleOpenTransfer = async () => {
|
||||
|
|
@ -472,6 +479,8 @@ function ProjectList({ type = 'my' }) {
|
|||
)
|
||||
: projects
|
||||
|
||||
const paginatedProjects = filteredProjects.slice((currentPage - 1) * pageSize, currentPage * pageSize)
|
||||
|
||||
return (
|
||||
<div className="project-list-container">
|
||||
<ListActionBar
|
||||
|
|
@ -545,55 +554,75 @@ function ProjectList({ type = 'my' }) {
|
|||
|
||||
{/* 正常项目列表 */}
|
||||
{!hasSearched && (
|
||||
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||
{filteredProjects.map((project) => (
|
||||
<Col xs={24} sm={12} md={8} lg={6} key={project.id}>
|
||||
<Card
|
||||
hoverable
|
||||
className="project-card"
|
||||
onClick={() => handleOpenProject(project.id)}
|
||||
actions={type === 'my' ? [
|
||||
<EditOutlined key="edit" onClick={(e) => handleEdit(e, project)} />,
|
||||
<GithubOutlined key="git" onClick={(e) => handleGitSettings(e, project)} />,
|
||||
<ShareAltOutlined key="share" onClick={(e) => handleShare(e, project)} />,
|
||||
<TeamOutlined key="members" onClick={(e) => handleMembers(e, project)} />,
|
||||
] : [
|
||||
<EyeOutlined key="view" />,
|
||||
<ShareAltOutlined key="share" onClick={(e) => handleShare(e, project)} />,
|
||||
]}
|
||||
>
|
||||
{/* 公开项目标识 */}
|
||||
{project.is_public === 1 && (
|
||||
<div className="project-card-public-badge">公开</div>
|
||||
)}
|
||||
<div className="project-card-icon">
|
||||
<FolderOutlined style={{ fontSize: 48, color: '#1890ff' }} />
|
||||
</div>
|
||||
<h3>{project.name}</h3>
|
||||
<p className="project-description">{project.description || '暂无描述'}</p>
|
||||
<div className="project-meta">
|
||||
<span>文档数: {project.doc_count || 0}</span>
|
||||
{type === 'share' && project.owner_name && (
|
||||
<span style={{ marginLeft: 12 }}>
|
||||
所有者: {project.owner_nickname || project.owner_name}
|
||||
</span>
|
||||
<>
|
||||
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||
{paginatedProjects.map((project) => (
|
||||
<Col xs={24} sm={12} md={8} lg={6} key={project.id}>
|
||||
<Card
|
||||
hoverable
|
||||
className="project-card"
|
||||
onClick={() => handleOpenProject(project.id)}
|
||||
actions={type === 'my' ? [
|
||||
<EditOutlined key="edit" onClick={(e) => handleEdit(e, project)} />,
|
||||
<GithubOutlined key="git" onClick={(e) => handleGitSettings(e, project)} />,
|
||||
<ShareAltOutlined key="share" onClick={(e) => handleShare(e, project)} />,
|
||||
<TeamOutlined key="members" onClick={(e) => handleMembers(e, project)} />,
|
||||
] : [
|
||||
<EyeOutlined key="view" />,
|
||||
<ShareAltOutlined key="share" onClick={(e) => handleShare(e, project)} />,
|
||||
]}
|
||||
>
|
||||
{/* 公开项目标识 */}
|
||||
{project.is_public === 1 && (
|
||||
<div className="project-card-public-badge">公开</div>
|
||||
)}
|
||||
{type === 'share' && project.user_role && (
|
||||
<span style={{ marginLeft: 12 }}>
|
||||
角色: {project.user_role === 'admin' ? '管理者' : project.user_role === 'editor' ? '编辑者' : '查看者'}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
))}
|
||||
<div className="project-card-icon">
|
||||
<FolderOutlined style={{ fontSize: 48, color: '#1890ff' }} />
|
||||
</div>
|
||||
<h3>{project.name}</h3>
|
||||
<p className="project-description">{project.description || '暂无描述'}</p>
|
||||
<div className="project-meta">
|
||||
<span>文档数: {project.doc_count || 0}</span>
|
||||
{type === 'share' && project.owner_name && (
|
||||
<span style={{ marginLeft: 12 }}>
|
||||
所有者: {project.owner_nickname || project.owner_name}
|
||||
</span>
|
||||
)}
|
||||
{type === 'share' && project.user_role && (
|
||||
<span style={{ marginLeft: 12 }}>
|
||||
角色: {project.user_role === 'admin' ? '管理者' : project.user_role === 'editor' ? '编辑者' : '查看者'}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
))}
|
||||
|
||||
{filteredProjects.length === 0 && !loading && (
|
||||
<Col span={24}>
|
||||
<Empty description={type === 'my' ? "还没有项目,创建一个开始吧" : "还没有参与的项目"} />
|
||||
</Col>
|
||||
{filteredProjects.length === 0 && !loading && (
|
||||
<Col span={24}>
|
||||
<Empty description={type === 'my' ? "还没有项目,创建一个开始吧" : "还没有参与的项目"} />
|
||||
</Col>
|
||||
)}
|
||||
</Row>
|
||||
{filteredProjects.length > 0 && (
|
||||
<div style={{ marginTop: 24, display: 'flex', justifyContent: 'center' }}>
|
||||
<Pagination
|
||||
current={currentPage}
|
||||
pageSize={pageSize}
|
||||
total={filteredProjects.length}
|
||||
onChange={setCurrentPage}
|
||||
showSizeChanger={false}
|
||||
className="dot-pagination"
|
||||
itemRender={(page, type, originalElement) => {
|
||||
if (type === 'page') {
|
||||
return <span className="pagination-dot" />
|
||||
}
|
||||
return originalElement
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Row>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 搜索无结果提示 */}
|
||||
|
|
|
|||
Loading…
Reference in New Issue