ArticleEdit.tsx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import { useState } from "react";
  2. import { useIntl } from "react-intl";
  3. import {
  4. ProForm,
  5. ProFormText,
  6. ProFormTextArea,
  7. } from "@ant-design/pro-components";
  8. import { Alert, Button, Form, message, Result, Space } from "antd";
  9. import { get, put } from "../../request";
  10. import {
  11. IArticleDataRequest,
  12. IArticleResponse,
  13. } from "../../components/api/Article";
  14. import LangSelect from "../../components/general/LangSelect";
  15. import PublicitySelect from "../../components/studio/PublicitySelect";
  16. import MDEditor from "@uiw/react-md-editor";
  17. import ArticlePrevDrawer from "../../components/article/ArticlePrevDrawer";
  18. interface IFormData {
  19. uid: string;
  20. title: string;
  21. subtitle: string;
  22. summary: string;
  23. content?: string;
  24. content_type?: string;
  25. status: number;
  26. lang: string;
  27. }
  28. interface IWidget {
  29. studioName?: string;
  30. articleId?: string;
  31. onReady?: Function;
  32. onChange?: Function;
  33. }
  34. const ArticleEditWidget = ({
  35. studioName,
  36. articleId,
  37. onReady,
  38. onChange,
  39. }: IWidget) => {
  40. const intl = useIntl();
  41. const [unauthorized, setUnauthorized] = useState(false);
  42. const [readonly, setReadonly] = useState(false);
  43. const [content, setContent] = useState<string>();
  44. return unauthorized ? (
  45. <Result
  46. status="403"
  47. title="无权访问"
  48. subTitle="您无权访问该内容。您可能没有登录,或者内容的所有者没有给您所需的权限。"
  49. extra={<></>}
  50. />
  51. ) : (
  52. <>
  53. {readonly ? (
  54. <Alert
  55. message="该资源为只读,如果需要修改,请联络拥有者分配权限。"
  56. type="warning"
  57. closable
  58. action={
  59. <Button disabled size="small" type="text">
  60. 详情
  61. </Button>
  62. }
  63. />
  64. ) : undefined}
  65. <ProForm<IFormData>
  66. onFinish={async (values: IFormData) => {
  67. const request = {
  68. uid: articleId ? articleId : "",
  69. title: values.title,
  70. subtitle: values.subtitle,
  71. summary: values.summary,
  72. content: values.content,
  73. content_type: "markdown",
  74. status: values.status,
  75. lang: values.lang,
  76. };
  77. console.log("save", request);
  78. put<IArticleDataRequest, IArticleResponse>(
  79. `/v2/article/${articleId}`,
  80. request
  81. )
  82. .then((res) => {
  83. console.log("save response", res);
  84. if (res.ok) {
  85. if (typeof onChange !== "undefined") {
  86. onChange(res.data);
  87. }
  88. message.success(intl.formatMessage({ id: "flashes.success" }));
  89. } else {
  90. message.error(res.message);
  91. }
  92. })
  93. .catch((e: IArticleResponse) => {
  94. message.error(e.message);
  95. });
  96. }}
  97. request={async () => {
  98. const res = await get<IArticleResponse>(`/v2/article/${articleId}`);
  99. console.log("article", res);
  100. let mTitle: string,
  101. mReadonly = false;
  102. if (res.ok) {
  103. mReadonly = res.data.role === "editor" ? false : true;
  104. setReadonly(mReadonly);
  105. mTitle = res.data.title;
  106. setContent(res.data.content);
  107. } else {
  108. setUnauthorized(true);
  109. mTitle = "无权访问";
  110. }
  111. if (typeof onReady !== "undefined") {
  112. onReady(mTitle, mReadonly, res.data.studio?.realName);
  113. }
  114. return {
  115. uid: res.data.uid,
  116. title: res.data.title,
  117. subtitle: res.data.subtitle,
  118. summary: res.data.summary,
  119. content: res.data.content,
  120. content_type: res.data.content_type,
  121. lang: res.data.lang,
  122. status: res.data.status,
  123. };
  124. }}
  125. >
  126. <ProForm.Group>
  127. <ProFormText
  128. width="md"
  129. name="title"
  130. required
  131. label={intl.formatMessage({
  132. id: "forms.fields.title.label",
  133. })}
  134. rules={[
  135. {
  136. required: true,
  137. message: intl.formatMessage({
  138. id: "forms.message.title.required",
  139. }),
  140. },
  141. ]}
  142. />
  143. <ProFormText
  144. width="md"
  145. name="subtitle"
  146. label={intl.formatMessage({
  147. id: "forms.fields.subtitle.label",
  148. })}
  149. />
  150. </ProForm.Group>
  151. <ProForm.Group>
  152. <LangSelect width="md" />
  153. <PublicitySelect width="md" />
  154. </ProForm.Group>
  155. <ProForm.Group>
  156. <ProFormTextArea
  157. name="summary"
  158. width="lg"
  159. label={intl.formatMessage({
  160. id: "forms.fields.summary.label",
  161. })}
  162. />
  163. </ProForm.Group>
  164. <ProForm.Group>
  165. <Form.Item
  166. name="content"
  167. style={{ width: "100%" }}
  168. label={
  169. <Space>
  170. {intl.formatMessage({
  171. id: "forms.fields.content.label",
  172. })}
  173. {articleId ? (
  174. <ArticlePrevDrawer
  175. trigger={<Button>预览</Button>}
  176. articleId={articleId}
  177. content={content}
  178. />
  179. ) : undefined}
  180. </Space>
  181. }
  182. >
  183. <MDEditor
  184. onChange={(value) => setContent(value)}
  185. height={550}
  186. style={{ width: "100%" }}
  187. />
  188. </Form.Item>
  189. </ProForm.Group>
  190. </ProForm>
  191. </>
  192. );
  193. };
  194. export default ArticleEditWidget;