| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- import * as React from 'react';
- import { useNavigate } from 'react-router-dom';
- import { Button, Table, TableColumnsType, TablePaginationConfig, Input, Space, Tabs, message, Tooltip } from 'antd';
- import { PlusOutlined, SearchOutlined, EditFilled, FileWordFilled, FileMarkdownFilled, DeleteFilled } from '@ant-design/icons';
- import { GuideTips, FilterBar } from '@/components/common';
- import InfoModal from './components/InfoModal';
- import { useKnowledgeLibListStore } from './store';
- import { Record } from './types';
- import './style.less';
- import LocalStorage from '@/LocalStorage';
- import dayjs from 'dayjs';
- // 导入 GuideTips 配置
- import { getGuideTipsConfig } from '@/config/guideTips';
- const KnowledgeLibList: React.FC = () => {
- const navigate = useNavigate();
-
- const {
- listLoading,
- list,
- infoModalId,
- infoModalOpen,
- page,
- setListLoading,
- setList,
- setInfoModalId,
- setInfoModalOpen,
- setPage,
- fetchKnowledgeLibList,
- onCreateKnowledgeLib,
- onModifyKnowledgeLib,
- onDeleteKnowledgeLib,
- onInfoModalOpenChange,
- init,
- reset,
- } = useKnowledgeLibListStore();
- const [activeTab, setActiveTab] = React.useState('all'); // 'all' | 'mine'
- const [searchName, setSearchName] = React.useState('');
- const [currentPage, setCurrentPage] = React.useState(1);
- const [pageSize, setPageSize] = React.useState(10);
-
- const userInfoAll = LocalStorage.getUserInfo();
- const listFlag = LocalStorage.getStatusFlag('knowledge:knowledgeLib:list');
- const updateFlag = LocalStorage.getStatusFlag('knowledge:knowledgeLib:update');
- const downloadOriginal = LocalStorage.getStatusFlag('knowledge:knowledgeLib:downloadOriginal');
- const downloadMd = LocalStorage.getStatusFlag('knowledge:knowledgeLib:downloadMd');
- // 初始化加载数据
- React.useEffect(() => {
- init();
- }, [init]);
- // 监听创建事件
- React.useEffect(() => {
- const handleCreate = () => {
- onCreateKnowledgeLibClick();
- };
- window.addEventListener('knowledgeLibCreate', handleCreate as EventListener);
- return () => {
- window.removeEventListener('knowledgeLibCreate', handleCreate as EventListener);
- };
- }, []);
- // 处理函数
- const onCreateKnowledgeLibClick = () => {
- setInfoModalId('');
- setInfoModalOpen(true);
- message.info('创建知识库');
- };
- const onClickModify = (record: Record) => {
- setInfoModalId(record.knowledgeId);
- setInfoModalOpen(true);
- message.info('编辑知识库');
- };
- const infoModalOnClickConfirm = () => {
- const data = {
- name: '测试知识库',
- description: '测试描述',
- };
-
- if (infoModalId) {
- onModifyKnowledgeLib(infoModalId, data);
- } else {
- onCreateKnowledgeLib(data);
- }
- };
- const infoModalOnClickCancel = () => {
- setInfoModalOpen(false);
- setInfoModalId('');
- };
- const onClickDelete = (record: Record) => {
- message.loading('删除中...', 0);
- setTimeout(() => {
- onDeleteKnowledgeLib(record.knowledgeId);
- message.success('删除成功');
- }, 500);
- };
- const onClickDownload = (record: Record) => {
- // 下载原始文档
- message.info(`下载原始文档:${record.name}`);
- // TODO: 调用原始文档下载 API
- };
- const onClickDownloadMd = (record: Record) => {
- // 下载 MD 文档
- message.info(`下载 MD 文档:${record.name}`);
- // TODO: 调用 MD 文档下载 API
- };
- // 过滤数据
- const filteredList = list.filter(item => {
- const matchSearch = !searchName || item.name.toLowerCase().includes(searchName.toLowerCase());
- // TAB 过滤:全部 | 我创建的 | 我可以维护的
- let matchTab = true;
- if (activeTab === 'mine') {
- // 我创建的
- matchTab = userInfoAll?.id === item.createBy;
- } else if (activeTab === 'maintainer') {
- // 我可以维护的(创建者或维护者)
- matchTab = userInfoAll?.id === item.createBy ||
- (item.maintainers && item.maintainers.includes(userInfoAll?.id));
- }
- return matchSearch && matchTab;
- });
- // 分页
- const paginatedList = filteredList.slice((currentPage - 1) * pageSize, currentPage * pageSize);
- // 分页处理
- const handlePageChange = (page: number, size: number) => {
- setCurrentPage(page);
- setPageSize(size);
- setPage({ pageNum: page, pageSize: size, total: filteredList.length });
- };
- // 表格列定义 - 匹配实际 API 字段(紧凑布局)
- const columns: TableColumnsType<Record> = [
- {
- title: '序号',
- dataIndex: 'index',
- width: 60, // 更紧凑
- align: 'center',
- render: (_text, _record, index) => {
- return ((currentPage - 1) * pageSize) + index + 1;
- }
- },
- {
- title: '知识库名称',
- dataIndex: 'name',
- width: 180, // 更紧凑
- render: (text, record) => {
- return (
- <div>
- <p
- className='text-primary cursor-pointer'
- style={{ fontWeight: 600, fontSize: '@font-base' }}
- onClick={() => {
- navigate(`/knowledge/knowledgeLib/${record.knowledgeId}/${record.createBy}`);
- }}
- >
- {text}
- </p>
- <div style={{ color: '#999', fontSize: 11, marginTop: 2 }}>
- ID: {record.knowledgeId}
- </div>
- </div>
- );
- }
- },
- {
- title: '使用空间',
- dataIndex: 'length',
- width: 90, // 更紧凑
- align: 'center',
- render: (text) => text || '--',
- },
- {
- title: '字符数量',
- dataIndex: 'wordNum',
- width: 100, // 更紧凑
- align: 'center',
- render: (text) => text && text !== '--' ? text.toLocaleString() : '--',
- },
- {
- title: '文件数量',
- dataIndex: 'documentSize',
- width: 80, // 更紧凑
- align: 'center',
- render: (text) => text && text !== '--' ? text : '--',
- },
- {
- title: '切片数量',
- dataIndex: 'sliceCount',
- width: 80, // 更紧凑
- align: 'center',
- render: (text) => text && text !== '--' ? text.toLocaleString() : '--',
- },
- {
- title: '是否公开',
- dataIndex: 'isOpen',
- width: 80, // 更紧凑
- align: 'center',
- render: (value) => value === 1 ? '公开' : '私有',
- },
- {
- title: '创建时间',
- dataIndex: 'createTime',
- width: 160, // 更紧凑
- align: 'center',
- render: (text) => text && text !== '--' ? dayjs(text).format('YYYY-MM-DD HH:mm:ss') : '--',
- },
- {
- title: '更新时间',
- dataIndex: 'updateTime',
- width: 160, // 更紧凑
- align: 'center',
- render: (text) => text && text !== '--' ? dayjs(text).format('YYYY-MM-DD HH:mm:ss') : '--',
- },
- {
- title: '操作',
- key: 'action',
- width: 160, // 适配 Ant Design 图标
- fixed: 'right',
- align: 'center',
- render: (_text, record) => (
- <Space size={0}> {/* 无间距,更紧凑 */}
- {/* 编辑按钮 */}
- <Tooltip title="编辑" placement="top">
- <Button
- type="text"
- size="large"
- onClick={() => onClickModify(record)}
- className="action-btn"
- icon={<EditFilled />}
- />
- </Tooltip>
- {/* 下载原文档按钮 */}
- <Tooltip title="下载原文档" placement="top">
- <Button
- type="text"
- size="large"
- onClick={() => onClickDownload(record)}
- className="action-btn"
- icon={<FileWordFilled />}
- />
- </Tooltip>
- {/* 下载 MD 文档按钮 */}
- <Tooltip title="下载 MD 文档" placement="top">
- <Button
- type="text"
- size="large"
- onClick={() => onClickDownloadMd(record)}
- className="action-btn"
- icon={<FileMarkdownFilled />}
- />
- </Tooltip>
- {/* 删除按钮 */}
- <Tooltip title="删除" placement="top">
- <Button
- type="text"
- size="large"
- danger
- onClick={() => onClickDelete(record)}
- className="action-btn"
- icon={<DeleteFilled />}
- />
- </Tooltip>
- </Space>
- )
- },
- ];
- // 获取 GuideTips 配置
- const guideTipsConfig = getGuideTipsConfig('knowledgeLib');
- return (
- <div className="page-container">
- {/* 标题区域 */}
- <div className="list-header with-tips">
- <div className='list-header-title'>
- <h1>知识库管理</h1>
- <p>管理您的所有知识库</p>
- </div>
- <div className='list-header-actions'>
- <Button
- type='primary'
- icon={<PlusOutlined />}
- onClick={onCreateKnowledgeLibClick}
- >
- 创建
- </Button>
- </div>
- </div>
- {/* Tips 提示组件 */}
- {guideTipsConfig && (
- <GuideTips
- visible={true}
- title={guideTipsConfig.title}
- steps={guideTipsConfig.steps}
- />
- )}
- {/* 筛选区域 - 使用 FilterBar 组件 */}
- <FilterBar
- tabs={[
- { key: 'all', label: '全部' },
- { key: 'mine', label: '我创建的' },
- { key: 'maintainer', label: '我可以维护的' },
- ]}
- activeTab={activeTab}
- onTabChange={setActiveTab}
- searchPlaceholder="请输入知识库名称"
- searchValue={searchName}
- onSearchChange={setSearchName}
- onSearch={async () => {
- // 模拟异步搜索
- await new Promise(resolve => setTimeout(resolve, 500));
- message.info('搜索功能开发中');
- }}
- searchWidth={300}
- />
- {/* 表格区域 */}
- <div className="content-section">
- <Table
- rowKey="knowledgeId"
- loading={listLoading}
- columns={columns}
- dataSource={paginatedList}
- pagination={{
- current: currentPage,
- pageSize: pageSize,
- total: filteredList.length,
- onChange: handlePageChange,
- showSizeChanger: true,
- showQuickJumper: true,
- showTotal: (total) => `共 ${total} 条`,
- pageSizeOptions: ['10', '20', '50', '100'],
- }}
- scroll={{ x: 1200 }}
- />
- </div>
- {/* 创建/编辑弹窗 */}
- <InfoModal
- id={infoModalId}
- open={infoModalOpen}
- onClickConfirm={infoModalOnClickConfirm}
- onClickCancel={infoModalOnClickCancel}
- />
- </div>
- );
- };
- export default KnowledgeLibList;
|