import { Link } from "react-router"; import { useIntl } from "react-intl"; import { Button, Popover, Dropdown, Typography, Modal, message, Space, Table, Badge, } from "antd"; import { type ActionType, ProTable } from "@ant-design/pro-components"; import { PlusOutlined, DeleteOutlined, TeamOutlined, ExclamationCircleOutlined, FolderAddOutlined, ReconciliationOutlined, } from "@ant-design/icons"; import ArticleCreate from "./ArticleCreate"; import { delete_, get } from "../../request"; import type { IArticleListResponse, IDeleteResponse } from "../../api/Article"; import { PublicityValueEnum } from "../studio/table"; import { useEffect, useRef, useState } from "react"; import { ArticleTplModal } from "../template/Builder/ArticleTpl"; import Share, { EResType } from "../share/Share"; import AddToAnthology from "./AddToAnthology"; import AnthologySelect from "../anthology/AnthologySelect"; import StudioName, { type IStudio } from "../auth/Studio"; import type { IUser } from "../auth/User"; import { getSorterUrl } from "../../utils"; import TransferCreate from "../transfer/TransferCreate"; import { TransferOutLinedIcon } from "../../assets/icon"; const { Text } = Typography; interface IArticleNumberResponse { ok: boolean; message: string; data: { my: number; collaboration: number; }; } const renderBadge = (count: number, active = false) => { return ( ); }; interface DataItem { sn: number; id: string; title: string; subtitle: string; summary?: string | null; anthologyCount?: number; anthologyTitle?: string; publicity: number; studio?: IStudio; editor?: IUser; updated_at?: string; } interface IWidget { studioName?: string; editable?: boolean; multiple?: boolean; onSelect?: ( id: string, title: string, event: React.MouseEvent ) => void; } const ArticleListWidget = ({ studioName, multiple = true, editable = false, onSelect, }: IWidget) => { const intl = useIntl(); //i18n const [openCreate, setOpenCreate] = useState(false); const [anthologyId, setAnthologyId] = useState(); const [activeKey, setActiveKey] = useState("my"); const [myNumber, setMyNumber] = useState(0); const [collaborationNumber, setCollaborationNumber] = useState(0); const [transfer, setTransfer] = useState(); const [transferName, setTransferName] = useState(); const [transferOpen, setTransferOpen] = useState(false); const [pageSize, setPageSize] = useState(10); useEffect(() => { /** * 获取各种课程的数量 */ const url = `/v2/article-my-number?studio=${studioName}`; console.log("url", url); get(url).then((json) => { if (json.ok) { setMyNumber(json.data.my); setCollaborationNumber(json.data.collaboration); } }); }, [studioName]); const showDeleteConfirm = (id: string, title: string) => { Modal.confirm({ icon: , title: intl.formatMessage({ id: "message.delete.confirm", }) + intl.formatMessage({ id: "message.irrevocable", }), content: title, okText: intl.formatMessage({ id: "buttons.delete", }), okType: "danger", cancelText: intl.formatMessage({ id: "buttons.no", }), onOk() { console.log("delete", id); return delete_(`/v2/article/${id}`) .then((json) => { if (json.ok) { message.success("删除成功"); ref.current?.reload(); } else { message.error(json.message); } }) .catch((e) => console.log("Oops errors!", e)); }, }); }; const ref = useRef(null); const [isModalOpen, setIsModalOpen] = useState(false); const [shareResId, setShareResId] = useState(""); const [shareResType, setShareResType] = useState(EResType.article); const showShareModal = (resId: string, resType: EResType) => { setShareResId(resId); setShareResType(resType); setIsModalOpen(true); }; const handleOk = () => { setIsModalOpen(false); }; const handleCancel = () => { setIsModalOpen(false); }; return ( <> actionRef={ref} columns={[ { title: intl.formatMessage({ id: "dict.fields.sn.label", }), dataIndex: "sn", key: "sn", width: 50, search: false, }, { title: intl.formatMessage({ id: "forms.fields.title.label", }), dataIndex: "title", key: "title", tooltip: "过长会自动收缩", ellipsis: true, render: (_text, row) => { return ( <>
) => { if (typeof onSelect !== "undefined") { onSelect(row.id, row.title, event); } }} > {row.title}
{row.subtitle}
{activeKey !== "my" ? (
) : undefined} ); }, }, { title: intl.formatMessage({ id: "columns.library.anthology.title", }), dataIndex: "subtitle", key: "subtitle", render: (_text, row) => { return ( {row.anthologyTitle} {row.anthologyCount ? ( ) : undefined} ); }, }, { title: intl.formatMessage({ id: "forms.fields.summary.label", }), dataIndex: "summary", key: "summary", tooltip: "过长会自动收缩", ellipsis: true, }, { title: intl.formatMessage({ id: "forms.fields.publicity.label", }), dataIndex: "publicity", key: "publicity", width: 100, search: false, filters: true, onFilter: true, valueEnum: PublicityValueEnum(), }, { title: intl.formatMessage({ id: "forms.fields.updated-at.label", }), key: "updated_at", width: 100, search: false, dataIndex: "updated_at", valueType: "date", sorter: true, }, { title: intl.formatMessage({ id: "buttons.option" }), key: "option", width: 120, valueType: "option", hideInTable: !editable, render: (_text, row, index) => { return [ 模版} /> ), icon: , }, { key: "share", label: intl.formatMessage({ id: "buttons.share", }), icon: , }, { key: "addToAnthology", label: ( 加入文集} studioName={studioName} articleIds={[row.id]} /> ), icon: , }, { key: "transfer", label: intl.formatMessage({ id: "columns.studio.transfer.title", }), icon: , }, { key: "remove", label: intl.formatMessage({ id: "buttons.delete", }), icon: , danger: true, }, ], onClick: (e) => { switch (e.key) { case "share": showShareModal(row.id, EResType.article); break; case "remove": showDeleteConfirm(row.id, row.title); break; case "transfer": setTransfer([row.id]); setTransferName(row.title); setTransferOpen(true); break; default: break; } }, }} > {intl.formatMessage({ id: "buttons.view", })} , ]; }, }, ]} rowSelection={ multiple ? { // 自定义选择项参考: https://ant.design/components/table-cn/#components-table-demo-row-selection-custom // 注释该行则默认不显示下拉选项 selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT], } : undefined } tableAlertRender={({ selectedRowKeys, onCleanSelected }) => ( {intl.formatMessage({ id: "buttons.selected" })} {selectedRowKeys.length} )} tableAlertOptionRender={({ selectedRowKeys, onCleanSelected }) => { return ( 加入文集} articleIds={selectedRowKeys.map((item) => item.toString())} onFinally={() => { onCleanSelected(); }} /> ); }} request={async (params = {}, sorter) => { let url = `/v2/article?view=studio&view2=${activeKey}&name=${studioName}`; const offset = ((params.current ? params.current : 1) - 1) * (params.pageSize ? params.pageSize : pageSize); if (params.pageSize) { setPageSize(params.pageSize); } url += `&limit=${params.pageSize}&offset=${offset}`; url += params.keyword ? "&search=" + params.keyword : ""; if (typeof anthologyId !== "undefined") { url += "&anthology=" + anthologyId; } url += getSorterUrl(sorter); console.log("url", url); const res = await get(url); const items: DataItem[] = res.data.rows.map((item, id) => { return { sn: id + offset + 1, id: item.uid, title: item.title, subtitle: item.subtitle, summary: item.summary, anthologyCount: item.anthology_count, anthologyTitle: item.anthology_first?.title, publicity: item.status, updated_at: item.updated_at, studio: item.studio, editor: item.editor, }; }); return { total: res.data.count, succcess: true, data: items, }; }} rowKey="id" bordered pagination={{ showQuickJumper: true, showSizeChanger: true, pageSize: pageSize, }} search={false} options={{ search: true, }} toolBarRender={() => [ activeKey === "my" ? ( { setAnthologyId(value); ref.current?.reload(); }} /> ) : undefined, { setOpenCreate(false); ref.current?.reload(); }} /> } placement="bottomRight" trigger="click" open={openCreate} onOpenChange={(open: boolean) => { setOpenCreate(open); }} > , ]} toolbar={{ menu: { activeKey, items: [ { key: "my", label: ( {intl.formatMessage({ id: "labels.this-studio" })} {renderBadge(myNumber, activeKey === "my")} ), }, { key: "collaboration", label: ( {intl.formatMessage({ id: "labels.collaboration" })} {renderBadge( collaborationNumber, activeKey === "collaboration" )} ), }, ], onChange(key) { console.log("show course", key); setActiveKey(key); setAnthologyId(undefined); ref.current?.reload(); }, }, }} /> setTransferOpen(visible)} /> ); }; export default ArticleListWidget;