Compare commits
No commits in common. "271f2e081e9aea49e43233fc0c51191d08861db2" and "89102d7f8c70e61f3dedcd5ebf552c4e54aa6300" have entirely different histories.
271f2e081e
...
89102d7f8c
|
@ -10,9 +10,6 @@ import {
|
||||||
Input,
|
Input,
|
||||||
Alert,
|
Alert,
|
||||||
Pagination,
|
Pagination,
|
||||||
Select,
|
|
||||||
Space,
|
|
||||||
Tag,
|
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import { TusUploader } from "@web/src/components/common/uploader/TusUploader";
|
import { TusUploader } from "@web/src/components/common/uploader/TusUploader";
|
||||||
import { SendOutlined, DeleteOutlined, LoginOutlined } from "@ant-design/icons";
|
import { SendOutlined, DeleteOutlined, LoginOutlined } from "@ant-design/icons";
|
||||||
|
@ -30,7 +27,6 @@ export function VideoContent() {
|
||||||
const [fileIds, setFileIds] = useState<string[]>([]);
|
const [fileIds, setFileIds] = useState<string[]>([]);
|
||||||
const [uploaderKey, setUploaderKey] = useState<number>(0);
|
const [uploaderKey, setUploaderKey] = useState<number>(0);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [fileType, setFileType] = useState<string>("all");
|
|
||||||
|
|
||||||
// 分页状态
|
// 分页状态
|
||||||
const [imagePage, setImagePage] = useState(1);
|
const [imagePage, setImagePage] = useState(1);
|
||||||
|
@ -47,34 +43,18 @@ export function VideoContent() {
|
||||||
data: resources,
|
data: resources,
|
||||||
refetch,
|
refetch,
|
||||||
isLoading,
|
isLoading,
|
||||||
}: {
|
}: { data: ResourceDto[]; refetch: () => void; isLoading: boolean } =
|
||||||
data: ResourceDto[];
|
api.resource.findMany.useQuery({
|
||||||
refetch: () => void;
|
where: {
|
||||||
isLoading: boolean;
|
deletedAt: null,
|
||||||
} = api.resource.findMany.useQuery({
|
postId: null,
|
||||||
where: {
|
},
|
||||||
deletedAt: null,
|
orderBy: {
|
||||||
postId: null,
|
createdAt: "desc",
|
||||||
},
|
},
|
||||||
orderBy: {
|
});
|
||||||
createdAt: "desc",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 定义常见文件类型和它们的扩展名
|
// 处理资源数据
|
||||||
const fileTypes = {
|
|
||||||
all: { label: "全部", extensions: [] },
|
|
||||||
document: { label: "文档", extensions: ["doc", "docx", "pdf", "txt"] },
|
|
||||||
spreadsheet: { label: "表格", extensions: ["xls", "xlsx", "csv"] },
|
|
||||||
presentation: { label: "ppt", extensions: ["ppt", "pptx"] },
|
|
||||||
video: {
|
|
||||||
label: "音视频",
|
|
||||||
extensions: ["mp4", "avi", "mov", "webm", "mp3", "wav", "ogg"],
|
|
||||||
},
|
|
||||||
archive: { label: "压缩包", extensions: ["zip", "rar", "7z"] },
|
|
||||||
};
|
|
||||||
|
|
||||||
// 修改资源处理逻辑,加入文件类型筛选
|
|
||||||
const { imageResources, fileResources, imagePagination, filePagination } =
|
const { imageResources, fileResources, imagePagination, filePagination } =
|
||||||
useMemo(() => {
|
useMemo(() => {
|
||||||
if (!resources) {
|
if (!resources) {
|
||||||
|
@ -94,11 +74,10 @@ export function VideoContent() {
|
||||||
const original = `http://${env.SERVER_IP}:${env.UPLOAD_PORT}/uploads/${resource.url}`;
|
const original = `http://${env.SERVER_IP}:${env.UPLOAD_PORT}/uploads/${resource.url}`;
|
||||||
const isImg = isImage(resource.url);
|
const isImg = isImage(resource.url);
|
||||||
|
|
||||||
// 提取文件扩展名
|
// 确保 title 存在,优先使用 resource.title,然后是 resource.meta.filename
|
||||||
const extension = resource.url.split(".").pop()?.toLowerCase() || "";
|
|
||||||
|
|
||||||
const displayTitle =
|
const displayTitle =
|
||||||
resource.title || resource.meta?.filename || "未命名文件";
|
resource.title || resource.meta?.filename || "未命名文件";
|
||||||
|
// 用于搜索的名称,确保从 meta.filename 获取(如果存在)
|
||||||
const searchableFilename = resource.meta?.filename || "";
|
const searchableFilename = resource.meta?.filename || "";
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -106,27 +85,20 @@ export function VideoContent() {
|
||||||
url: isImg ? getCompressedImageUrl(original) : original,
|
url: isImg ? getCompressedImageUrl(original) : original,
|
||||||
originalUrl: original,
|
originalUrl: original,
|
||||||
isImage: isImg,
|
isImage: isImg,
|
||||||
title: displayTitle,
|
title: displayTitle, // 用于显示
|
||||||
searchableFilename: searchableFilename,
|
searchableFilename: searchableFilename, // 用于搜索
|
||||||
extension: extension,
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
|
||||||
// 根据搜索词和文件类型筛选
|
// 根据搜索词筛选文件资源 (基于 searchableFilename)
|
||||||
const filteredFileResources = processedResources.filter((res) => {
|
const filteredFileResources = processedResources.filter(
|
||||||
// 首先检查是否符合搜索词
|
(res) =>
|
||||||
const matchesSearch = res.searchableFilename
|
!res.isImage &&
|
||||||
.toLowerCase()
|
res.searchableFilename
|
||||||
.includes(searchTerm.toLowerCase());
|
.toLowerCase()
|
||||||
|
.includes(searchTerm.toLowerCase())
|
||||||
// 然后检查文件类型
|
);
|
||||||
const matchesType =
|
|
||||||
fileType === "all" ||
|
|
||||||
fileTypes[fileType]?.extensions.includes(res.extension);
|
|
||||||
|
|
||||||
return !res.isImage && matchesSearch && matchesType;
|
|
||||||
});
|
|
||||||
|
|
||||||
const allImageResources = processedResources.filter((res) => res.isImage);
|
const allImageResources = processedResources.filter((res) => res.isImage);
|
||||||
|
|
||||||
|
@ -152,7 +124,7 @@ export function VideoContent() {
|
||||||
data: filteredFileResources,
|
data: filteredFileResources,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}, [resources, imagePage, filePage, searchTerm, fileType]); // 添加fileType依赖
|
}, [resources, imagePage, filePage, searchTerm]); // searchTerm 作为依赖项
|
||||||
|
|
||||||
const createMutation = api.resource.create.useMutation({});
|
const createMutation = api.resource.create.useMutation({});
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
|
@ -251,31 +223,13 @@ export function VideoContent() {
|
||||||
<p>支持视频、excel、文档、ppt等多种格式文件</p>
|
<p>支持视频、excel、文档、ppt等多种格式文件</p>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div className="flex flex-wrap items-center gap-4 mb-4">
|
<Input.Search
|
||||||
<Input.Search
|
placeholder="搜索文件名"
|
||||||
placeholder="搜索文件名"
|
allowClear
|
||||||
allowClear
|
onSearch={(value) => setSearchTerm(value)}
|
||||||
onSearch={(value) => setSearchTerm(value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
style={{ width: 300 }}
|
||||||
style={{ width: 300 }}
|
/>
|
||||||
/>
|
|
||||||
|
|
||||||
<Select
|
|
||||||
value={fileType}
|
|
||||||
onChange={(value) => setFileType(value)}
|
|
||||||
style={{ width: 120 }}
|
|
||||||
options={Object.entries(fileTypes).map(([key, { label }]) => ({
|
|
||||||
value: key,
|
|
||||||
label: label,
|
|
||||||
}))}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* {fileType !== "all" && (
|
|
||||||
<Tag color="blue" closable onClose={() => setFileType("all")}>
|
|
||||||
{fileTypes[fileType]?.label}
|
|
||||||
</Tag>
|
|
||||||
)} */}
|
|
||||||
</div>
|
|
||||||
{!isAuthenticated && (
|
{!isAuthenticated && (
|
||||||
<Alert
|
<Alert
|
||||||
message="请先登录"
|
message="请先登录"
|
||||||
|
@ -419,20 +373,20 @@ export function VideoContent() {
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<div className="font-medium truncate">
|
<div className="font-medium truncate">
|
||||||
{resource.meta?.filename}
|
{resource.title}
|
||||||
</div>
|
</div>
|
||||||
{/* {resource.meta?.filetype && (
|
{resource.description && (
|
||||||
<div className="text-xs text-gray-500 mt-1">
|
<div className="text-xs text-gray-500 mt-1">
|
||||||
类型: {resource.meta?.filetype}
|
描述: {resource.description}
|
||||||
</div>
|
</div>
|
||||||
)} */}
|
)}
|
||||||
<div className="text-xs text-gray-500 flex items-center gap-2">
|
<div className="text-xs text-gray-500 flex items-center gap-2">
|
||||||
<span>
|
<span>
|
||||||
{dayjs(resource.createdAt).format("YYYY-MM-DD")}
|
{dayjs(resource.createdAt).format("YYYY-MM-DD")}
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
{resource.meta?.size &&
|
{resource.meta?.size &&
|
||||||
formatFileSize(resource.meta?.size)}
|
formatFileSize(resource.meta.size)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -462,6 +416,12 @@ export function VideoContent() {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{fileResources.length === 0 && searchTerm && (
|
||||||
|
<div className="text-center py-4 text-gray-500">
|
||||||
|
未找到匹配 "{searchTerm}" 的文件。
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* 文件分页 */}
|
{/* 文件分页 */}
|
||||||
{filePagination.total > pageSize && (
|
{filePagination.total > pageSize && (
|
||||||
<div className="flex justify-center mt-6">
|
<div className="flex justify-center mt-6">
|
||||||
|
|
|
@ -14,7 +14,7 @@ export function ExampleContent() {
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const pageSize = 10; // 每页显示5条案例
|
const pageSize = 6; // 每页显示5条案例
|
||||||
const isDomainAdmin = useMemo(() => {
|
const isDomainAdmin = useMemo(() => {
|
||||||
return hasSomePermissions("MANAGE_DOM_STAFF", "MANAGE_ANY_STAFF");
|
return hasSomePermissions("MANAGE_DOM_STAFF", "MANAGE_ANY_STAFF");
|
||||||
}, [hasSomePermissions]);
|
}, [hasSomePermissions]);
|
||||||
|
|
|
@ -14,7 +14,7 @@ export function PublicityContent() {
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const pageSize = 10; // 每页显示5条新闻
|
const pageSize = 6; // 每页显示5条新闻
|
||||||
const isDomainAdmin = useMemo(() => {
|
const isDomainAdmin = useMemo(() => {
|
||||||
return hasSomePermissions("MANAGE_DOM_STAFF", "MANAGE_ANY_STAFF");
|
return hasSomePermissions("MANAGE_DOM_STAFF", "MANAGE_ANY_STAFF");
|
||||||
}, [hasSomePermissions]);
|
}, [hasSomePermissions]);
|
||||||
|
|
|
@ -14,7 +14,7 @@ export function ScienceContent() {
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const pageSize = 10; // 每页显示5条科普
|
const pageSize = 6; // 每页显示5条科普
|
||||||
const isDomainAdmin = useMemo(() => {
|
const isDomainAdmin = useMemo(() => {
|
||||||
return hasSomePermissions("MANAGE_DOM_STAFF", "MANAGE_ANY_STAFF");
|
return hasSomePermissions("MANAGE_DOM_STAFF", "MANAGE_ANY_STAFF");
|
||||||
}, [hasSomePermissions]);
|
}, [hasSomePermissions]);
|
||||||
|
|
|
@ -1,180 +1,121 @@
|
||||||
import { useState, useEffect, useMemo } from "react";
|
import { useState, useEffect, useMemo } from "react";
|
||||||
import { Input, Pagination, Empty, Spin, Radio, Space, Tag } from "antd";
|
import { Input, Pagination, Empty, Spin } from "antd";
|
||||||
import { api, RouterInputs } from "@nice/client";
|
import { api, RouterInputs } from "@nice/client";
|
||||||
import { LetterCard } from "../LetterCard";
|
import { LetterCard } from "../LetterCard";
|
||||||
import { NonVoid } from "@nice/utils";
|
import { NonVoid } from "@nice/utils";
|
||||||
import { SearchOutlined, FilterOutlined } from "@ant-design/icons";
|
import { SearchOutlined } from "@ant-design/icons";
|
||||||
import debounce from "lodash/debounce";
|
import debounce from "lodash/debounce";
|
||||||
import { postDetailSelect } from "@nice/common";
|
import { postDetailSelect } from "@nice/common";
|
||||||
|
|
||||||
export default function LetterList({
|
export default function LetterList({
|
||||||
params,
|
params,
|
||||||
search = "",
|
search = ''
|
||||||
}: {
|
}: {
|
||||||
search?: string;
|
search?: string,
|
||||||
params: NonVoid<RouterInputs["post"]["findManyWithPagination"]>;
|
params: NonVoid<RouterInputs["post"]["findManyWithPagination"]>;
|
||||||
}) {
|
}) {
|
||||||
const [keyword, setKeyword] = useState<string | undefined>("");
|
const [keyword, setKeyword] = useState<string | undefined>('');
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [selectedCategory, setSelectedCategory] = useState<string>("all");
|
useEffect(() => {
|
||||||
|
|
||||||
const { data: categoriesData } = api.term.findMany.useQuery({
|
setKeyword(search || '')
|
||||||
where: {
|
}, [search])
|
||||||
taxonomy: {
|
const { data, isLoading } = api.post.findManyWithPagination.useQuery({
|
||||||
slug: "category",
|
page: currentPage,
|
||||||
},
|
pageSize: params.pageSize,
|
||||||
},
|
where: {
|
||||||
});
|
OR: [
|
||||||
|
{
|
||||||
const categoryOptions = useMemo(() => {
|
title: {
|
||||||
const options = [{ value: "all", label: "全部分类" }];
|
contains: keyword,
|
||||||
if (categoriesData) {
|
},
|
||||||
categoriesData.forEach((category) => {
|
},
|
||||||
options.push({
|
],
|
||||||
value: category.id,
|
...params?.where,
|
||||||
label: category.name,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
}, [categoriesData]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setKeyword(search || "");
|
|
||||||
}, [search]);
|
|
||||||
|
|
||||||
const { data, isLoading } = api.post.findManyWithPagination.useQuery({
|
|
||||||
page: currentPage,
|
|
||||||
pageSize: params.pageSize,
|
|
||||||
where: {
|
|
||||||
OR: [
|
|
||||||
{
|
|
||||||
title: {
|
|
||||||
contains: keyword,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
],
|
orderBy: {
|
||||||
...(selectedCategory !== "all"
|
updatedAt: "desc",
|
||||||
? {
|
},
|
||||||
terms: {
|
select: {
|
||||||
some: {
|
...postDetailSelect,
|
||||||
id: selectedCategory,
|
...params.select,
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
}
|
|
||||||
: {}),
|
|
||||||
...params?.where,
|
|
||||||
},
|
|
||||||
orderBy: {
|
|
||||||
updatedAt: "desc",
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
...postDetailSelect,
|
|
||||||
...params.select,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const debouncedSearch = useMemo(
|
const debouncedSearch = useMemo(
|
||||||
() =>
|
() =>
|
||||||
debounce((value: string) => {
|
debounce((value: string) => {
|
||||||
setKeyword(value);
|
setKeyword(value);
|
||||||
setCurrentPage(1);
|
setCurrentPage(1);
|
||||||
}, 300),
|
}, 300),
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
// Cleanup debounce on unmount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
debouncedSearch.cancel();
|
debouncedSearch.cancel();
|
||||||
|
};
|
||||||
|
}, [debouncedSearch]);
|
||||||
|
const handleSearch = (value: string) => {
|
||||||
|
debouncedSearch(value);
|
||||||
};
|
};
|
||||||
}, [debouncedSearch]);
|
|
||||||
|
|
||||||
const handleSearch = (value: string) => {
|
const handlePageChange = (page: number) => {
|
||||||
debouncedSearch(value);
|
setCurrentPage(page);
|
||||||
};
|
// Scroll to top when page changes
|
||||||
|
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||||
|
};
|
||||||
|
|
||||||
const handlePageChange = (page: number) => {
|
return (
|
||||||
setCurrentPage(page);
|
<div className="flex flex-col h-full">
|
||||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
{/* Search Bar */}
|
||||||
};
|
<div className="p-6 transition-all ">
|
||||||
|
<Input
|
||||||
|
value={keyword}
|
||||||
|
variant="filled"
|
||||||
|
className="w-full bg-white"
|
||||||
|
placeholder="搜索信件标题..."
|
||||||
|
allowClear
|
||||||
|
size="large"
|
||||||
|
onChange={(e) => handleSearch(e.target.value)}
|
||||||
|
prefix={<SearchOutlined className="text-gray-400" />}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
const handleCategoryChange = (value: string) => {
|
{/* Content Area */}
|
||||||
setSelectedCategory(value);
|
<div className="flex-grow px-6">
|
||||||
setCurrentPage(1);
|
{isLoading ? (
|
||||||
};
|
<div className="flex justify-center items-center pt-6">
|
||||||
|
<Spin size="large"></Spin>
|
||||||
|
</div>
|
||||||
|
) : data?.items.length ? (
|
||||||
|
<>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-1 lg:grid-cols-1 gap-4 mb-6">
|
||||||
|
{data.items.map((letter: any) => (
|
||||||
|
<LetterCard key={letter.id} letter={letter} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-center pb-6">
|
||||||
|
<Pagination
|
||||||
|
current={currentPage}
|
||||||
|
total={data.totalCount}
|
||||||
|
pageSize={params.pageSize}
|
||||||
|
onChange={handlePageChange}
|
||||||
|
showSizeChanger={false}
|
||||||
|
showQuickJumper
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-col justify-center items-center pt-6">
|
||||||
|
<Empty
|
||||||
|
|
||||||
return (
|
description={
|
||||||
<div className="flex flex-col h-full">
|
keyword ? "未找到相关信件" : "暂无信件"
|
||||||
<div className="p-6 transition-all">
|
}
|
||||||
<div className="flex items-center mb-4">
|
/>
|
||||||
<Radio.Group
|
</div>
|
||||||
value={selectedCategory}
|
)}
|
||||||
onChange={(e) => handleCategoryChange(e.target.value)}
|
</div>
|
||||||
optionType="button"
|
|
||||||
buttonStyle="solid"
|
|
||||||
className="flex-wrap"
|
|
||||||
>
|
|
||||||
{categoryOptions.map((option) => (
|
|
||||||
<Radio.Button
|
|
||||||
key={option.value}
|
|
||||||
value={option.value}
|
|
||||||
className="my-1"
|
|
||||||
>
|
|
||||||
{option.label}
|
|
||||||
</Radio.Button>
|
|
||||||
))}
|
|
||||||
</Radio.Group>
|
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
<Space direction="vertical" className="w-full" size="middle">
|
|
||||||
<Input
|
|
||||||
value={keyword}
|
|
||||||
variant="filled"
|
|
||||||
className="w-full bg-white"
|
|
||||||
placeholder="搜索信件标题..."
|
|
||||||
allowClear
|
|
||||||
size="large"
|
|
||||||
onChange={(e) => handleSearch(e.target.value)}
|
|
||||||
prefix={<SearchOutlined className="text-gray-400" />}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex-grow px-6">
|
|
||||||
{isLoading ? (
|
|
||||||
<div className="flex justify-center items-center pt-6">
|
|
||||||
<Spin size="large"></Spin>
|
|
||||||
</div>
|
|
||||||
) : data?.items.length ? (
|
|
||||||
<>
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-1 lg:grid-cols-1 gap-4 mb-6">
|
|
||||||
{data.items.map((letter: any) => (
|
|
||||||
<LetterCard key={letter.id} letter={letter} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<div className="flex justify-center pb-6">
|
|
||||||
<Pagination
|
|
||||||
current={currentPage}
|
|
||||||
total={data.totalCount}
|
|
||||||
pageSize={params.pageSize}
|
|
||||||
onChange={handlePageChange}
|
|
||||||
showSizeChanger={false}
|
|
||||||
showQuickJumper
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<div className="flex flex-col justify-center items-center pt-6">
|
|
||||||
<Empty
|
|
||||||
description={
|
|
||||||
keyword || selectedCategory !== "all"
|
|
||||||
? "未找到相关信件"
|
|
||||||
: "暂无信件"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue