This commit is contained in:
Li1304553726 2025-05-09 10:01:51 +08:00
parent 84a5066097
commit 271f2e081e
5 changed files with 169 additions and 107 deletions

View File

@ -67,7 +67,10 @@ export function VideoContent() {
document: { label: "文档", extensions: ["doc", "docx", "pdf", "txt"] }, document: { label: "文档", extensions: ["doc", "docx", "pdf", "txt"] },
spreadsheet: { label: "表格", extensions: ["xls", "xlsx", "csv"] }, spreadsheet: { label: "表格", extensions: ["xls", "xlsx", "csv"] },
presentation: { label: "ppt", extensions: ["ppt", "pptx"] }, presentation: { label: "ppt", extensions: ["ppt", "pptx"] },
video: { label: "音视频", extensions: ["mp4", "avi", "mov", "webm","mp3", "wav", "ogg"] }, video: {
label: "音视频",
extensions: ["mp4", "avi", "mov", "webm", "mp3", "wav", "ogg"],
},
archive: { label: "压缩包", extensions: ["zip", "rar", "7z"] }, archive: { label: "压缩包", extensions: ["zip", "rar", "7z"] },
}; };

View File

@ -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 = 6; // 每页显示5条案例 const pageSize = 10; // 每页显示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]);

View File

@ -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 = 6; // 每页显示5条新闻 const pageSize = 10; // 每页显示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]);

View File

@ -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 = 6; // 每页显示5条科普 const pageSize = 10; // 每页显示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]);

View File

@ -1,121 +1,180 @@
import { useState, useEffect, useMemo } from "react"; import { useState, useEffect, useMemo } from "react";
import { Input, Pagination, Empty, Spin } from "antd"; import { Input, Pagination, Empty, Spin, Radio, Space, Tag } 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 } from "@ant-design/icons"; import { SearchOutlined, FilterOutlined } 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);
useEffect(() => { const [selectedCategory, setSelectedCategory] = useState<string>("all");
setKeyword(search || '') const { data: categoriesData } = api.term.findMany.useQuery({
}, [search]) where: {
const { data, isLoading } = api.post.findManyWithPagination.useQuery({ taxonomy: {
page: currentPage, slug: "category",
pageSize: params.pageSize, },
where: { },
OR: [ });
{
title: {
contains: keyword,
},
},
],
...params?.where,
},
orderBy: {
updatedAt: "desc",
},
select: {
...postDetailSelect,
...params.select,
},
});
const debouncedSearch = useMemo( const categoryOptions = useMemo(() => {
() => const options = [{ value: "all", label: "全部分类" }];
debounce((value: string) => { if (categoriesData) {
setKeyword(value); categoriesData.forEach((category) => {
setCurrentPage(1); options.push({
}, 300), value: category.id,
[] label: category.name,
); });
// Cleanup debounce on unmount });
useEffect(() => { }
return () => { return options;
debouncedSearch.cancel(); }, [categoriesData]);
};
}, [debouncedSearch]); useEffect(() => {
const handleSearch = (value: string) => { setKeyword(search || "");
debouncedSearch(value); }, [search]);
const { data, isLoading } = api.post.findManyWithPagination.useQuery({
page: currentPage,
pageSize: params.pageSize,
where: {
OR: [
{
title: {
contains: keyword,
},
},
],
...(selectedCategory !== "all"
? {
terms: {
some: {
id: selectedCategory,
},
},
}
: {}),
...params?.where,
},
orderBy: {
updatedAt: "desc",
},
select: {
...postDetailSelect,
...params.select,
},
});
const debouncedSearch = useMemo(
() =>
debounce((value: string) => {
setKeyword(value);
setCurrentPage(1);
}, 300),
[]
);
useEffect(() => {
return () => {
debouncedSearch.cancel();
}; };
}, [debouncedSearch]);
const handlePageChange = (page: number) => { const handleSearch = (value: string) => {
setCurrentPage(page); debouncedSearch(value);
// Scroll to top when page changes };
window.scrollTo({ top: 0, behavior: "smooth" });
};
return ( const handlePageChange = (page: number) => {
<div className="flex flex-col h-full"> setCurrentPage(page);
{/* Search Bar */} window.scrollTo({ top: 0, behavior: "smooth" });
<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>
{/* Content Area */} const handleCategoryChange = (value: string) => {
<div className="flex-grow px-6"> setSelectedCategory(value);
{isLoading ? ( setCurrentPage(1);
<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={ return (
keyword ? "未找到相关信件" : "暂无信件" <div className="flex flex-col h-full">
} <div className="p-6 transition-all">
/> <div className="flex items-center mb-4">
</div> <Radio.Group
)} value={selectedCategory}
</div> onChange={(e) => handleCategoryChange(e.target.value)}
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>
);
} }