DiscussionCreate.tsx 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. import { useIntl } from "react-intl";
  2. import { App, Form } from "antd";
  3. import {
  4. ProForm,
  5. type ProFormInstance,
  6. ProFormText,
  7. ProFormTextArea,
  8. } from "@ant-design/pro-components";
  9. import { post } from "../../request";
  10. import type { ICommentRequest, ICommentResponse } from "../../api/Comment";
  11. import { useAppSelector } from "../../hooks";
  12. import { currentUser as _currentUser } from "../../reducers/current-user";
  13. import { useEffect, useRef, useState } from "react";
  14. import MDEditor from "@uiw/react-md-editor";
  15. import type { IComment, TDiscussionType } from "../../api/discussion";
  16. import type { TContentType } from "../../api/article";
  17. import { discussionCountUpgrade, toIComment } from "./utils";
  18. interface IWidget {
  19. resId?: string;
  20. resType?: string; //TODO change
  21. parent?: string;
  22. topicId?: string;
  23. type?: TDiscussionType;
  24. topic?: IComment;
  25. contentType?: TContentType;
  26. onCreated?: (value: IComment) => void;
  27. onTopicCreated?: (value: IComment) => void;
  28. }
  29. const DiscussionCreateWidget = ({
  30. resId,
  31. resType,
  32. contentType = "html",
  33. parent,
  34. topicId,
  35. topic,
  36. type = "discussion",
  37. onCreated,
  38. onTopicCreated,
  39. }: IWidget) => {
  40. const intl = useIntl();
  41. const { message } = App.useApp();
  42. const formRef = useRef<ProFormInstance | undefined>(undefined);
  43. const _currUser = useAppSelector(_currentUser);
  44. const [currParent, setCurrParent] = useState(parent);
  45. useEffect(() => {
  46. setCurrParent(parent);
  47. }, [parent]);
  48. if (typeof _currUser === "undefined") {
  49. return <></>;
  50. } else {
  51. return (
  52. <div>
  53. <div>{_currUser?.nickName}:</div>
  54. <div>
  55. <ProForm<IComment>
  56. formRef={formRef}
  57. autoFocusFirstInput={false}
  58. onFinish={async (values) => {
  59. //新建
  60. console.log("create", resId, resType, currParent, topic);
  61. console.log("value", values);
  62. let newParent: string | undefined;
  63. if (typeof currParent === "undefined") {
  64. if (typeof topic !== "undefined" && topic.tplId) {
  65. /**
  66. * 在模版下跟帖
  67. * 先建立模版topic,再建立跟帖
  68. */
  69. const topicData: ICommentRequest = {
  70. res_id: resId,
  71. res_type: resType,
  72. title: topic.title,
  73. tpl_id: topic.tplId,
  74. content: topic.content,
  75. content_type: "markdown",
  76. type: topic.type,
  77. };
  78. const url = `/api/v2/discussion`;
  79. console.log("create topic api request", url, topicData);
  80. const newTopic = await post<
  81. ICommentRequest,
  82. ICommentResponse
  83. >(url, topicData);
  84. if (newTopic.ok) {
  85. discussionCountUpgrade(resId);
  86. setCurrParent(newTopic.data.id);
  87. newParent = newTopic.data.id;
  88. if (typeof onTopicCreated !== "undefined") {
  89. onTopicCreated(toIComment(newTopic.data));
  90. }
  91. } else {
  92. console.error("no parent id");
  93. return;
  94. }
  95. }
  96. }
  97. const url = `/api/v2/discussion`;
  98. const data: ICommentRequest = {
  99. res_id: resId,
  100. res_type: resType,
  101. parent: newParent ? newParent : currParent,
  102. topicId: topicId,
  103. title: values.title,
  104. content: values.content,
  105. content_type: contentType,
  106. type: topic ? topic.type : type,
  107. };
  108. console.info("api request", url, data);
  109. post<ICommentRequest, ICommentResponse>(url, data)
  110. .then((json) => {
  111. console.debug("new discussion api response", json);
  112. if (json.ok) {
  113. formRef.current?.resetFields();
  114. discussionCountUpgrade(resId);
  115. if (typeof onCreated !== "undefined") {
  116. onCreated(toIComment(json.data));
  117. }
  118. } else {
  119. message.error(json.message);
  120. }
  121. })
  122. .catch((e) => {
  123. message.error(e.message);
  124. });
  125. }}
  126. params={{}}
  127. >
  128. <ProForm.Group>
  129. <ProFormText
  130. name="title"
  131. width={"lg"}
  132. hidden={
  133. typeof currParent !== "undefined" ||
  134. typeof topic?.tplId !== "undefined"
  135. }
  136. label={intl.formatMessage({ id: "forms.fields.title.label" })}
  137. tooltip="最长为 24 位"
  138. placeholder={intl.formatMessage({
  139. id: "forms.message.question.required",
  140. })}
  141. rules={[
  142. { required: currParent || topic?.tplId ? false : true },
  143. ]}
  144. />
  145. </ProForm.Group>
  146. <ProForm.Group>
  147. {contentType === "text" ? (
  148. <ProFormTextArea
  149. name="content"
  150. label={intl.formatMessage({
  151. id: "forms.fields.content.label",
  152. })}
  153. placeholder={intl.formatMessage({
  154. id: "forms.fields.content.placeholder",
  155. })}
  156. />
  157. ) : contentType === "html" ? (
  158. <Form.Item
  159. name="content"
  160. label={intl.formatMessage({
  161. id: "forms.fields.content.label",
  162. })}
  163. tooltip="可以直接粘贴屏幕截图"
  164. ></Form.Item>
  165. ) : contentType === "markdown" ? (
  166. <Form.Item
  167. name="content"
  168. rules={[
  169. {
  170. required:
  171. typeof currParent !== "undefined" ||
  172. typeof topic?.tplId !== "undefined",
  173. },
  174. ]}
  175. label={
  176. typeof currParent === "undefined" &&
  177. typeof topic?.tplId === "undefined"
  178. ? intl.formatMessage({
  179. id: "forms.message.question.description.option",
  180. })
  181. : intl.formatMessage({
  182. id: "forms.fields.replay.label",
  183. })
  184. }
  185. >
  186. <MDEditor
  187. textareaProps={{
  188. placeholder:
  189. "问题的详细描述" +
  190. (typeof currParent !== "undefined" &&
  191. typeof topic?.tplId !== "undefined"
  192. ? ""
  193. : "(选填)"),
  194. maxLength: 10000,
  195. }}
  196. />
  197. </Form.Item>
  198. ) : (
  199. <></>
  200. )}
  201. </ProForm.Group>
  202. </ProForm>
  203. </div>
  204. </div>
  205. );
  206. }
  207. };
  208. export default DiscussionCreateWidget;