import { useIntl } from "react-intl"; import { Button, Space, Table, Dropdown, message, Modal, Typography, Image, Segmented, } from "antd"; import { PlusOutlined, ExclamationCircleOutlined, FileOutlined, AudioOutlined, FileImageOutlined, MoreOutlined, BarsOutlined, AppstoreOutlined, } from "@ant-design/icons"; import { type ActionType, ProList } from "@ant-design/pro-components"; import type { IUserDictDeleteRequest } from "../../api/Dict"; import { delete_2, get, put } from "../../request"; import { useRef, useState } from "react"; import type { IDeleteResponse } from "../../api/Article"; import TimeShow from "../general/TimeShow"; import { getSorterUrl } from "../../utils"; import type { IAttachmentListResponse, IAttachmentRequest, IAttachmentResponse, IAttachmentUpdate, } from "../../api/Attachments"; import { VideoIcon } from "../../assets/icon"; import AttachmentImport, { deleteRes } from "./AttachmentImport"; import VideoModal from "../general/VideoModal"; import FileSize from "../general/FileSize"; import modal from "antd/lib/modal"; import { useAppSelector } from "../../hooks"; import { currentUser } from "../../reducers/current-user"; const { Text } = Typography; export interface IAttachment { id: string; name: string; filename: string; title: string; size: number; content_type: string; url: string; } interface IParams { content_type?: string; } interface IWidget { studioName?: string; view?: "studio" | "all"; multiSelect?: boolean; onClick?: (record: IAttachmentRequest) => void; } const AttachmentWidget = ({ studioName, view = "studio", multiSelect = false, onClick, }: IWidget) => { const intl = useIntl(); const [replaceId, setReplaceId] = useState(); const [importOpen, setImportOpen] = useState(false); const [imgVisible, setImgVisible] = useState(false); const [imgPrev, setImgPrev] = useState(); const [list, setList] = useState("list"); const [videoVisible, setVideoVisible] = useState(false); const [videoUrl, setVideoUrl] = useState(); const user = useAppSelector(currentUser); const currStudio = studioName ? studioName : user?.realName; 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_2( `/v2/userdict/${id}`, { id: JSON.stringify(id), } ) .then((json) => { if (json.ok) { message.success("删除成功"); ref.current?.reload(); } else { message.error(json.message); } }) .catch((e: unknown) => console.log("Oops errors!", e)); }, }); }; const ref = useRef(null); return ( <> actionRef={ref} editable={{ onSave: async (key, record, originRow) => { console.log(key, record, originRow); const url = `/v2/attachment/${key}`; const res = await put(url, { title: record.title, }); return res.ok; }, }} ghost={list === "list" ? false : true} onItem={(record: IAttachmentRequest) => { return { onClick: () => { // 点击行 if (typeof onClick !== "undefined") { onClick(record); } }, }; }} //TODO remove meta metas={{ title: { dataIndex: "title", search: false, render: (_dom, entity) => { return ( ); }, }, description: { editable: false, search: false, render: (_dom, entity) => { return ( {entity.content_type} ); }, }, content: list === "list" ? { editable: false, search: false } : { editable: false, search: false, render: (_dom, entity) => { const thumbnail = entity.thumbnail ? entity.thumbnail.middle : entity.url; return ( ); }, }, avatar: { editable: false, search: false, render: (_dom, entity) => { const ct = entity.content_type.split("/"); let icon = ; switch (ct[0]) { case "video": icon = ; break; case "audio": icon = ; break; case "image": icon = ; break; } return icon; }, }, actions: { render: (_text, row, _index, action) => { return [ , { console.log("click ", e.key); switch (e.key) { case "link": { const link = `/attachments/${row.filename}`; navigator.clipboard.writeText(link).then(() => { message.success("已经拷贝到剪贴板"); }); break; } case "markdown": { const markdown = `![${row.title}](/attachments/${row.filename})`; navigator.clipboard.writeText(markdown).then(() => { message.success("已经拷贝到剪贴板"); }); break; } case "replace": setReplaceId(row.id); setImportOpen(true); break; case "delete": modal.confirm({ title: intl.formatMessage({ id: "message.delete.confirm", }), icon: , content: intl.formatMessage({ id: "message.irrevocable", }), okText: "确认", cancelText: "取消", okType: "danger", onOk: () => { deleteRes(row.id); ref.current?.reload(); }, }); break; default: break; } }, }} placement="bottomRight" > ) } tableAlertOptionRender={ view === "all" ? undefined : ({ selectedRowKeys, onCleanSelected }) => { return ( ); } } request={async (params = {}, sorter, filter) => { console.log(params, sorter, filter); const offset = ((params.current ? params.current : 1) - 1) * (params.pageSize ? params.pageSize : 20); let url = "/v2/attachment?"; switch (view) { case "studio": url += `view=studio&studio=${currStudio}`; break; case "all": url += `view=all`; break; default: break; } url += `&limit=${params.pageSize}&offset=${offset}`; url += params.keyword ? "&search=" + params.keyword : ""; if (params.content_type && params.content_type !== "all") { url += "&content_type=" + params.content_type; } url += getSorterUrl(sorter); console.log(url); const res = await get(url); return { total: res.data.count, success: res.ok, data: res.data.rows, }; }} rowKey="id" bordered pagination={{ showQuickJumper: true, showSizeChanger: true, }} search={{ filterType: "light", }} options={{ search: true, }} grid={list === "list" ? undefined : { gutter: 16, column: 3 }} headerTitle="" toolBarRender={() => [ }, { label: "Thumbnail", value: "thumbnail", icon: , }, ]} onChange={(value) => { console.log(value); // string setList(value.toString()); }} />, , ]} /> { setImportOpen(open); ref.current?.reload(); }} /> { setImgVisible(value); }, }} /> setVideoVisible(open)} /> ); }; export default AttachmentWidget;