Files
leaudit-platform-frontend/app/routes/contract-template.search.results.tsx
T
2025-05-29 17:42:35 +08:00

276 lines
8.4 KiB
TypeScript

import type { MetaFunction, LoaderFunctionArgs } from '@remix-run/node';
import { useLoaderData, useSearchParams, useNavigate } from '@remix-run/react';
import { useState } from 'react';
import { CompactSearchBox } from '~/components/contract-template/CompactSearchBox';
import { SearchResultHeader } from '~/components/contract-template/SearchResultHeader';
import { FilterTabs } from '~/components/contract-template/FilterTabs';
import { TemplateGrid } from '~/components/contract-template/TemplateGrid';
import { Pagination } from '~/components/ui/Pagination';
import styles from '~/styles/pages/contract-template.css?url';
export const links = () => [
{ rel: 'stylesheet', href: styles }
];
export const meta: MetaFunction = () => {
return [
{ title: '搜索结果 - AI智能合同模板搜索 - 智慧法务' },
{
name: 'description',
content: 'AI智能搜索合同模板结果,快速找到最适合的模板。'
}
];
};
// 面包屑导航配置
export const handle = {
breadcrumb: "搜索结果"
};
// 模拟数据 - 扩展搜索结果
const mockSearchResults = [
{
id: '1',
title: '烟草产品销售合同标准模板',
type: '销售合同',
description: '适用于烟草产品销售业务,包含完整的违约责任条款、付款方式、交付条件等核心要素,符合行业规范要求。',
updateTime: '2023-10-25',
useCount: 1248,
rating: 4.8,
category: '销售合同'
},
{
id: '2',
title: '零售商销售协议模板',
type: '销售合同',
description: '专为零售商设计的销售协议,详细规定了违约责任、退换货政策、结算方式等条款。',
updateTime: '2023-10-20',
useCount: 856,
rating: 4.6,
category: '销售合同'
},
{
id: '3',
title: '设备采购合同(含违约条款)',
type: '采购合同',
description: '设备采购专用合同模板,包含详细的违约责任条款、质量保证、验收标准等内容。',
updateTime: '2023-10-18',
useCount: 642,
rating: 4.7,
category: '采购合同'
},
{
id: '4',
title: '批发销售合同模板',
type: '销售合同',
description: '适用于大宗批发业务的销售合同,强化了违约责任条款和风险控制措施。',
updateTime: '2023-10-15',
useCount: 534,
rating: 4.5,
category: '销售合同'
},
{
id: '5',
title: '技术服务合同(标准版)',
type: '服务合同',
description: '技术服务类合同模板,包含服务标准、违约责任、知识产权保护等关键条款。',
updateTime: '2023-10-12',
useCount: 423,
rating: 4.4,
category: '服务合同'
},
{
id: '6',
title: '区域代理销售合同',
type: '销售合同',
description: '区域代理商专用销售合同,明确代理权限、销售目标、违约责任等核心条款。',
updateTime: '2023-10-10',
useCount: 312,
rating: 4.3,
category: '销售合同'
},
{
id: '7',
title: '物流运输服务合同',
type: '物流运输',
description: '专业的物流运输服务合同模板,涵盖运输责任、保险、违约赔偿等关键条款。',
updateTime: '2023-10-08',
useCount: 267,
rating: 4.2,
category: '物流运输'
},
{
id: '8',
title: '仓储管理服务协议',
type: '物流运输',
description: '仓储管理专用合同,包含货物保管、出入库管理、损失责任等详细条款。',
updateTime: '2023-10-05',
useCount: 189,
rating: 4.1,
category: '物流运输'
},
{
id: '9',
title: '劳务派遣合同模板',
type: '人事劳务',
description: '劳务派遣服务合同,明确派遣关系、工资福利、社保缴纳等人事管理条款。',
updateTime: '2023-10-03',
useCount: 345,
rating: 4.6,
category: '人事劳务'
},
{
id: '10',
title: '商业机密保护协议',
type: '保密协议',
description: '企业商业机密保护专用协议,涵盖信息范围、保密义务、违约责任等核心内容。',
updateTime: '2023-10-01',
useCount: 156,
rating: 4.5,
category: '保密协议'
},
{
id: '11',
title: '办公场地租赁合同',
type: '租赁合同',
description: '办公场地租赁标准合同,包含租金支付、物业管理、违约处理等全面条款。',
updateTime: '2023-09-28',
useCount: 278,
rating: 4.3,
category: '租赁合同'
},
{
id: '12',
title: '设备租赁协议(长期)',
type: '租赁合同',
description: '长期设备租赁专用协议,详细规定租赁期限、维护责任、续租条件等关键条款。',
updateTime: '2023-09-25',
useCount: 198,
rating: 4.4,
category: '租赁合同'
}
];
export async function loader({ request }: LoaderFunctionArgs) {
const url = new URL(request.url);
const query = url.searchParams.get('q') || '';
const category = url.searchParams.get('category') || '';
const page = parseInt(url.searchParams.get('page') || '1');
// 模拟搜索耗时
const startTime = Date.now();
// 这里应该是实际的搜索逻辑
// 目前返回模拟数据
let filteredResults = mockSearchResults;
// 如果有查询条件,进行筛选
if (query || category) {
filteredResults = mockSearchResults.filter(item => {
const matchesQuery = !query ||
item.title.toLowerCase().includes(query.toLowerCase()) ||
item.description.toLowerCase().includes(query.toLowerCase());
const matchesCategory = !category || item.category === category;
return matchesQuery && matchesCategory;
});
}
// 计算搜索耗时
const endTime = Date.now();
const searchTime = (endTime - startTime) / 1000;
const searchTimeText = `搜索用时 ${searchTime.toFixed(1)}`;
return {
results: filteredResults,
query,
category,
total: filteredResults.length,
page,
pageSize: 6,
searchTime: searchTimeText
};
}
export default function ContractTemplateSearchResults() {
const { results, query, total, page, pageSize, searchTime } = useLoaderData<typeof loader>();
const [searchParams] = useSearchParams();
const navigate = useNavigate();
const [activeFilter, setActiveFilter] = useState('全部');
const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');
const [sortBy, setSortBy] = useState('relevance');
const handleSearch = (newQuery: string) => {
if (newQuery.trim()) {
navigate(`/contract-template/search/results?q=${encodeURIComponent(newQuery)}`);
}
};
const handleTemplateClick = (templateId: string) => {
navigate(`/contract-template/detail/${templateId}`);
};
const handleFilterChange = (filter: string) => {
setActiveFilter(filter);
// 这里可以添加实际的筛选逻辑
};
const handlePageChange = (newPage: number) => {
const params = new URLSearchParams(searchParams);
params.set('page', newPage.toString());
navigate(`/contract-template/search/results?${params.toString()}`);
};
const filters = [
{ label: '全部', count: total },
{ label: '销售合同', count: results.filter(r => r.category === '销售合同').length },
{ label: '采购合同', count: results.filter(r => r.category === '采购合同').length },
{ label: '服务合同', count: results.filter(r => r.category === '服务合同').length }
];
const totalPages = Math.ceil(total / pageSize);
return (
<div className="contract-search-results">
{/* 紧凑搜索框 */}
<CompactSearchBox
initialQuery={query}
onSearch={handleSearch}
searchTime={searchTime}
/>
{/* 搜索结果头部 */}
<SearchResultHeader
total={total}
viewMode={viewMode}
onViewModeChange={setViewMode}
sortBy={sortBy}
onSortChange={setSortBy}
/>
{/* 筛选标签 */}
<FilterTabs
filters={filters}
activeFilter={activeFilter}
onFilterChange={handleFilterChange}
/>
{/* 模板网格 */}
<TemplateGrid
templates={results}
viewMode={viewMode}
onTemplateClick={handleTemplateClick}
/>
{/* 分页 */}
{totalPages > 1 && (
<Pagination
currentPage={page}
total={total}
pageSize={pageSize}
onChange={handlePageChange}
showPageSizeChanger={false}
/>
)}
</div>
);
}