MyCreate.tsx 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. import { Button, Col, Divider, Input, message, notification, Row } from "antd";
  2. import { useEffect, useState } from "react";
  3. import { useIntl } from "react-intl";
  4. import { SaveOutlined } from "@ant-design/icons";
  5. import WbwDetailBasic from "../template/Wbw/WbwDetailBasic";
  6. import WbwDetailNote from "../template/Wbw/WbwDetailNote";
  7. import type { IWbw, IWbwField, TFieldName } from "../template/Wbw/WbwWord";
  8. import { get, post } from "../../request";
  9. import type {
  10. IApiResponseDictList,
  11. IDictRequest,
  12. IDictResponse,
  13. IUserDictCreate,
  14. } from "../../api/Dict";
  15. import { useAppSelector } from "../../hooks";
  16. import { add, updateIndex, wordIndex } from "../../reducers/inline-dict";
  17. import store from "../../store";
  18. import { get as getUiLang } from "../../locales";
  19. import { myDictDirty } from "../../reducers/command";
  20. import { currentUser } from "../../reducers/current-user";
  21. export const UserWbwPost = (data: IDictRequest[], view: string) => {
  22. let wordData: IDictRequest[] = data;
  23. data.forEach((value: IDictRequest) => {
  24. if (value.parent && value.type !== "") {
  25. if (!value.type?.includes("base") && value.type !== ".ind.") {
  26. let pFactors = "";
  27. let pFm;
  28. const orgFactors = value.factors?.split("+");
  29. if (
  30. orgFactors &&
  31. orgFactors.length > 0 &&
  32. orgFactors[orgFactors.length - 1].includes("[")
  33. ) {
  34. pFactors = orgFactors.slice(0, -1).join("+");
  35. pFm = value.factormean
  36. ?.split("+")
  37. .slice(0, orgFactors.length - 1)
  38. .join("+");
  39. }
  40. let grammar = value.grammar?.split("$").slice(0, 1).join("");
  41. if (value.type?.includes(".v")) {
  42. grammar = "";
  43. }
  44. wordData.push({
  45. word: value.parent,
  46. type: "." + value.type?.replaceAll(".", "") + ":base.",
  47. grammar: grammar,
  48. mean: value.mean,
  49. parent: value.parent2 ?? undefined,
  50. factors: pFactors,
  51. factormean: pFm,
  52. confidence: value.confidence,
  53. language: value.language,
  54. status: value.status,
  55. });
  56. }
  57. }
  58. if (value.factors && value.factors.split("+").length > 0) {
  59. const fm = value.factormean?.split("+");
  60. const factors: IDictRequest[] = [];
  61. value.factors.split("+").forEach((factor: string, index: number) => {
  62. const currWord = factor.replaceAll("-", "");
  63. console.debug("currWord", currWord);
  64. const meaning = fm ? (fm[index].replaceAll("-", "") ?? null) : null;
  65. if (meaning) {
  66. factors.push({
  67. word: currWord,
  68. type: ".part.",
  69. grammar: "",
  70. mean: meaning,
  71. confidence: value.confidence,
  72. language: value.language,
  73. status: value.status,
  74. });
  75. }
  76. const subFactorsMeaning: string[] = fm ? fm[index].split("-") : [];
  77. factor.split("-").forEach((subFactor, index1) => {
  78. if (subFactorsMeaning[index1] && subFactorsMeaning[index1] !== "") {
  79. factors.push({
  80. word: subFactor,
  81. type: ".part.",
  82. grammar: "",
  83. mean: subFactorsMeaning[index1],
  84. confidence: value.confidence,
  85. language: value.language,
  86. status: value.status,
  87. });
  88. }
  89. });
  90. });
  91. wordData = [...wordData, ...factors];
  92. }
  93. });
  94. return post<IUserDictCreate, IDictResponse>("/v2/userdict", {
  95. view: view,
  96. data: JSON.stringify(wordData),
  97. });
  98. };
  99. interface IWidget {
  100. word?: string;
  101. onSave?: Function;
  102. }
  103. const MyCreateWidget = ({ word, onSave }: IWidget) => {
  104. const intl = useIntl();
  105. const [dirty, setDirty] = useState(false);
  106. const [wordSpell, setWordSpell] = useState(word);
  107. const [editWord, setEditWord] = useState<IWbw>({
  108. word: { value: word ? word : "", status: 7 },
  109. real: { value: word ? word : "", status: 7 },
  110. book: 0,
  111. para: 0,
  112. sn: [0],
  113. confidence: 100,
  114. });
  115. const [loading, setLoading] = useState(false);
  116. const inlineWordIndex = useAppSelector(wordIndex);
  117. const user = useAppSelector(currentUser);
  118. useEffect(() => setWordSpell(word), [word]);
  119. useEffect(() => {
  120. //查询这个词在内存字典里是否有
  121. if (typeof wordSpell === "undefined") {
  122. return;
  123. }
  124. if (inlineWordIndex.includes(wordSpell)) {
  125. //已经有了,退出
  126. return;
  127. }
  128. get<IApiResponseDictList>(`/v2/wbwlookup?word=${wordSpell}`).then(
  129. (json) => {
  130. console.log("lookup ok", json.data.count);
  131. //存储到redux
  132. store.dispatch(add(json.data.rows));
  133. store.dispatch(updateIndex([wordSpell]));
  134. }
  135. );
  136. }, [inlineWordIndex, wordSpell]);
  137. const setDataDirty = (dirty: boolean) => {
  138. store.dispatch(myDictDirty(dirty));
  139. setDirty(dirty);
  140. };
  141. function fieldChanged(field: TFieldName, value: string) {
  142. const mData: IWbw = JSON.parse(JSON.stringify(editWord));
  143. switch (field) {
  144. case "note":
  145. mData.note = { value: value, status: 7 };
  146. break;
  147. case "word":
  148. mData.word = { value: value, status: 7 };
  149. break;
  150. case "real":
  151. mData.real = { value: value, status: 7 };
  152. break;
  153. case "meaning":
  154. mData.meaning = { value: value, status: 7 };
  155. break;
  156. case "factors":
  157. mData.factors = { value: value, status: 7 };
  158. break;
  159. case "factorMeaning":
  160. mData.factorMeaning = { value: value, status: 7 };
  161. break;
  162. case "parent":
  163. mData.parent = { value: value, status: 7 };
  164. break;
  165. case "case":
  166. console.log("case", value);
  167. const _case = value.replaceAll("#", "$").split("$");
  168. const _type = _case[0];
  169. const _grammar = _case.slice(1).join("$");
  170. mData.type = { value: _type, status: 7 };
  171. mData.grammar = { value: _grammar, status: 7 };
  172. mData.case = { value: value, status: 7 };
  173. break;
  174. case "confidence":
  175. mData.confidence = parseFloat(value);
  176. break;
  177. default:
  178. break;
  179. }
  180. console.debug("field changed", mData);
  181. setEditWord(mData);
  182. setDataDirty(true);
  183. }
  184. const reset = () => {
  185. const mData: IWbw = JSON.parse(JSON.stringify(editWord));
  186. mData.note = { value: "", status: 7 };
  187. mData.meaning = { value: "", status: 7 };
  188. mData.type = { value: "", status: 7 };
  189. mData.grammar = { value: "", status: 7 };
  190. mData.factors = { value: "", status: 7 };
  191. mData.factorMeaning = { value: "", status: 7 };
  192. setEditWord(mData);
  193. };
  194. return (
  195. <div style={{ padding: "0 5px" }}>
  196. <Row>
  197. <Col
  198. span={4}
  199. style={{
  200. display: "inline-block",
  201. flexGrow: 0,
  202. overflow: "hidden",
  203. whiteSpace: "nowrap",
  204. textAlign: "right",
  205. verticalAlign: "middle",
  206. padding: 5,
  207. }}
  208. >
  209. 拼写
  210. </Col>
  211. <Col span={20}>
  212. <Input
  213. value={wordSpell}
  214. placeholder="Basic usage"
  215. onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
  216. console.debug("spell onChange", event.target.value);
  217. setWordSpell(event.target.value);
  218. fieldChanged("word", event.target.value);
  219. }}
  220. />
  221. </Col>
  222. </Row>
  223. <WbwDetailBasic
  224. data={editWord}
  225. showRelation={false}
  226. onChange={(e: IWbwField) => {
  227. console.log("WbwDetailBasic onchange", e);
  228. fieldChanged(e.field, e.value);
  229. }}
  230. />
  231. <Divider>{intl.formatMessage({ id: "buttons.note" })}</Divider>
  232. <WbwDetailNote
  233. data={editWord}
  234. onChange={(e: IWbwField) => {
  235. fieldChanged(e.field, e.value);
  236. }}
  237. />
  238. <Divider></Divider>
  239. <div
  240. style={{ display: "flex", justifyContent: "space-between", padding: 5 }}
  241. >
  242. <Button
  243. onClick={() => {
  244. reset();
  245. setDataDirty(false);
  246. }}
  247. >
  248. 重置
  249. </Button>
  250. <Button
  251. loading={loading}
  252. icon={<SaveOutlined />}
  253. disabled={!dirty}
  254. onClick={() => {
  255. setLoading(true);
  256. const data: IDictRequest[] = [
  257. {
  258. word: editWord.word.value,
  259. type: editWord.type?.value,
  260. grammar: editWord.grammar?.value,
  261. mean: editWord.meaning?.value,
  262. parent: editWord.parent?.value,
  263. note: editWord.note?.value,
  264. factors: editWord.factors?.value,
  265. factormean: editWord.factorMeaning?.value,
  266. language: getUiLang(),
  267. status: user?.roles?.includes("basic") ? 5 : 30,
  268. confidence: 100,
  269. },
  270. ];
  271. UserWbwPost(data, "dict")
  272. .finally(() => {
  273. setLoading(false);
  274. })
  275. .then((json) => {
  276. if (json.ok) {
  277. setDataDirty(false);
  278. reset();
  279. notification.info({
  280. message: intl.formatMessage({ id: "flashes.success" }),
  281. });
  282. if (typeof onSave !== "undefined") {
  283. onSave();
  284. }
  285. } else {
  286. message.error(json.message);
  287. }
  288. });
  289. }}
  290. type="primary"
  291. >
  292. {intl.formatMessage({ id: "buttons.save" })}
  293. </Button>
  294. </div>
  295. </div>
  296. );
  297. };
  298. export default MyCreateWidget;