| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- import { Button, message } from "antd";
- import { useEffect, useState } from "react";
- import { FolderOpenOutlined } from "@ant-design/icons";
- import { get as getUiLang } from "../../locales";
- import { get, post, put } from "../../request";
- import type {
- IAnthologyDataResponse,
- IArticleCreateRequest,
- IArticleDataResponse,
- IArticleMapAddResponse,
- IArticleMapListResponse,
- IArticleMapRequest,
- IArticleMapUpdateRequest,
- IArticleResponse,
- } from "../../api/Article";
- import ArticleListModal from "../article/ArticleListModal";
- import EditableTree, {
- type ListNodeData,
- type TreeNodeData,
- } from "../article/EditableTree";
- import ArticleDrawer from "../article/ArticleDrawer";
- import { fullUrl, randomString } from "../../utils";
- interface IWidget {
- anthologyId?: string;
- studioName?: string;
- myStudioName?: string;
- anthology?: IAnthologyDataResponse;
- }
- const EditableTocTreeWidget = ({
- anthologyId,
- anthology,
- studioName,
- myStudioName,
- }: IWidget) => {
- const [tocData, setTocData] = useState<ListNodeData[]>([]);
- const [addArticle, setAddArticle] = useState<TreeNodeData>();
- const [updatedArticle, setUpdatedArticle] = useState<TreeNodeData>();
- const [openViewer, setOpenViewer] = useState(false);
- const [viewArticle, setViewArticle] = useState<TreeNodeData>();
- const save = (data?: ListNodeData[]) => {
- console.debug("onSave", data);
- if (typeof data === "undefined") {
- console.warn("data === undefined");
- return;
- }
- const url = `/v2/article-map/${anthologyId}`;
- console.info("url", url);
- const newData: IArticleMapRequest[] = data.map((item) => {
- let title = "";
- if (typeof item.title === "string") {
- title = item.title;
- }
- //TODO 整一个string title
- return {
- article_id: item.key,
- level: item.level,
- title: title,
- children: item.children,
- status: item.status,
- deleted_at: item.deletedAt,
- };
- });
- put<IArticleMapUpdateRequest, IArticleMapAddResponse>(url, {
- data: newData,
- operation: "anthology",
- })
- .finally(() => {})
- .then((json) => {
- if (json.ok) {
- message.success(json.data);
- } else {
- message.error(json.message);
- }
- })
- .catch((e) => message.error(e));
- };
- useEffect(() => {
- get<IArticleMapListResponse>(
- `/v2/article-map?view=anthology&id=${anthologyId}`
- ).then((json) => {
- if (json.ok) {
- const toc: ListNodeData[] = json.data.rows.map((item) => {
- return {
- key: item.article_id ? item.article_id : item.title,
- title: item.title,
- title_text: item.title_text ? item.title_text : item.title,
- level: item.level,
- status: item.status,
- deletedAt: item.deleted_at,
- };
- });
- setTocData(toc);
- }
- });
- }, [anthologyId]);
- return (
- <div>
- <EditableTree
- treeData={tocData}
- addOnArticle={addArticle}
- addFileButton={
- <ArticleListModal
- studioName={myStudioName}
- trigger={<Button icon={<FolderOpenOutlined />}>添加</Button>}
- multiple={false}
- onSelect={(id: string, title: string) => {
- console.log("add article", id);
- const newNode: TreeNodeData = {
- key: randomString(),
- id: id,
- title: title,
- title_text: title,
- children: [],
- level: 1,
- };
- setAddArticle(newNode);
- }}
- />
- }
- updatedNode={updatedArticle}
- onChange={(data: ListNodeData[]) => {
- save(data);
- }}
- onSave={(data: ListNodeData[]) => {
- save(data);
- }}
- onAppend={async (
- node: TreeNodeData
- ): Promise<TreeNodeData | undefined> => {
- /**
- * 在某节点下append新的节点
- */
- if (typeof studioName === "undefined") {
- console.log("studio", studioName);
- return;
- }
- const res = await post<IArticleCreateRequest, IArticleResponse>(
- `/v2/article`,
- {
- title: "new article",
- lang: anthology?.lang ?? getUiLang(),
- studio: studioName,
- anthologyId: anthologyId,
- status: anthology?.status ?? undefined,
- }
- );
- console.log(res);
- if (res.ok) {
- return {
- key: randomString(),
- id: res.data.uid,
- title: res.data.title,
- title_text: res.data.title,
- children: [],
- level: node.level + 1,
- };
- } else {
- return;
- }
- }}
- onTitleClick={(
- e: React.MouseEvent<HTMLElement, MouseEvent>,
- node: TreeNodeData
- ) => {
- if (e.ctrlKey || e.metaKey) {
- window.open(fullUrl(`/article/article/${node.id}`), "_blank");
- } else {
- setViewArticle(node);
- setOpenViewer(true);
- }
- }}
- />
- <ArticleDrawer
- articleId={viewArticle?.id}
- anthologyId={anthologyId}
- type="article"
- open={openViewer}
- title={viewArticle?.title_text}
- onClose={() => setOpenViewer(false)}
- onArticleEdit={(value: IArticleDataResponse) => {
- setUpdatedArticle({
- key: randomString(),
- id: value.uid,
- title: value.title,
- title_text: value.title_text,
- level: 0,
- children: [],
- });
- }}
- onTitleChange={(value: string) => {
- if (viewArticle?.id) {
- setUpdatedArticle({
- key: randomString(),
- id: viewArticle?.id,
- title: value,
- title_text: value,
- level: 0,
- children: [],
- });
- }
- }}
- />
- </div>
- );
- };
- export default EditableTocTreeWidget;
|