UpdateForm.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import React, {useEffect, useState} from 'react';
  2. import {Button, message, Modal} from 'antd';
  3. import MyQuill from '@/pages/Memory/components/MyQuill';
  4. import service from '@/pages/Memory/service';
  5. import {useSingleState} from 'nice-hooks';
  6. import {getTextFromHtml} from '@/utils/utils';
  7. import {TableListItem} from '../../MemoryList/data.d';
  8. // 表单特殊字段
  9. export interface FormValueType extends Partial<TableListItem> {
  10. }
  11. export interface UpdateFormProps {
  12. onCancel: (fresh?: boolean) => void;
  13. modalVisible: boolean;
  14. values: Partial<TableListItem>;
  15. }
  16. const dealImage = (base64: string, targetWidth: number, targetSize: number, callback: Function) => {
  17. const newImage = new Image();
  18. let quality = 0.8;
  19. newImage.src = base64;
  20. // url为外域时需要
  21. newImage.setAttribute('crossOrigin', 'Anonymous');
  22. let imgWidth;
  23. let imgHeight;
  24. newImage.onload = function () {
  25. imgWidth = newImage.width;
  26. imgHeight = newImage.height;
  27. const canvas = document.createElement('canvas');
  28. const ctx = canvas.getContext('2d');
  29. if (Math.max(imgWidth, imgHeight) > targetWidth) {
  30. if (imgWidth > imgHeight) {
  31. canvas.width = targetWidth;
  32. canvas.height = (targetWidth * imgHeight) / imgWidth;
  33. } else {
  34. canvas.height = targetWidth;
  35. canvas.width = (targetWidth * imgWidth) / imgHeight;
  36. }
  37. } else {
  38. canvas.width = imgWidth;
  39. canvas.height = imgHeight;
  40. }
  41. // @ts-ignore
  42. ctx.clearRect(0, 0, canvas.width, canvas.height);
  43. // @ts-ignore
  44. ctx.drawImage(newImage, 0, 0, canvas.width, canvas.height);
  45. // 如想确保图片压缩到自己想要的尺寸,如要求在50-150kb之间,请加以下语句,quality初始值根据情况自定
  46. while (base64.length / 1024 > targetSize) {
  47. quality -= 0.01;
  48. // eslint-disable-next-line no-param-reassign
  49. base64 = canvas.toDataURL('image/jpeg', quality);
  50. }
  51. // 防止最后一次压缩低于最低尺寸,只要quality递减合理,无需考虑
  52. // while (base64.length / 1024 < 50) {
  53. // quality += 0.001;
  54. // base64 = canvas.toDataURL("image/jpeg", quality);
  55. // }
  56. callback(base64); // 必须通过回调函数返回,否则无法及时拿到该值
  57. };
  58. };
  59. /**
  60. * 压缩html中的base64
  61. */
  62. const dealHtml = (html: string, callBack: Function) => {
  63. callBack(html);
  64. const htmlDoc = new DOMParser().parseFromString(html, 'text/html');
  65. const imgs = htmlDoc.querySelectorAll('img');
  66. for (let i = 0; i < imgs.length; i += 1) {
  67. const {src} = imgs[i];
  68. if (src.startsWith('data')) {
  69. dealImage(src, 500, 150, (base64: string) => {
  70. imgs[i].src = base64;
  71. callBack(htmlDoc.body.innerHTML);
  72. console.log(`压缩图片${i}`);
  73. });
  74. }
  75. }
  76. };
  77. const UpdateForm: React.FC<UpdateFormProps> = (props) => {
  78. const [btnDisable, setBtnDisable] = useState(false);
  79. const [formValues, setFormValues] = useSingleState<TableListItem>({
  80. back: '',
  81. front: '',
  82. id: undefined,
  83. period: 0,
  84. remindTime: new Date(),
  85. tag: '',
  86. updateTime: '',
  87. userId: 0,
  88. ...props.values,
  89. });
  90. const {onCancel: hideModal, modalVisible} = props;
  91. const addHandle = async () => {
  92. /**
  93. * 判断
  94. */
  95. console.log(formValues);
  96. if (getTextFromHtml(formValues.front + formValues.back).length <= 1) {
  97. message.info('你是不是没有输入文字?');
  98. return;
  99. }
  100. if (formValues.front.length >= 300000 || formValues.back.length >= 300000) {
  101. message.info('文字太长了,减少一些吧!');
  102. return;
  103. }
  104. setBtnDisable(true); // 禁用按钮
  105. let res;
  106. if (formValues.id !== undefined) {
  107. res = await service.update(formValues);
  108. } else {
  109. res = await service.insert(formValues);
  110. }
  111. setBtnDisable(false); // 释放按钮
  112. if (res.success) {
  113. message.info('操作成功');
  114. if (formValues.id !== undefined) {
  115. hideModal(true);
  116. } else {
  117. setFormValues({front: '', back: ''});
  118. }
  119. } else {
  120. message.info(`操作失败: ${res.message}`);
  121. }
  122. };
  123. useEffect(() => {
  124. console.log(props);
  125. document.onkeydown = (ev) => {
  126. if (ev.ctrlKey && ev.key.toLowerCase() === 'enter') {
  127. addHandle();
  128. } else if (ev.key.toLowerCase() === 'escape') {
  129. hideModal(false);
  130. }
  131. };
  132. }, []);
  133. return (
  134. <Modal
  135. maskClosable={false}
  136. width={640}
  137. bodyStyle={{padding: '15px 15px 15px'}}
  138. destroyOnClose
  139. title="配置模型"
  140. visible={modalVisible}
  141. onCancel={() => hideModal(false)}
  142. footer={null}
  143. >
  144. <div>
  145. <h4>正面</h4>
  146. <MyQuill
  147. theme="snow"
  148. readonly={false}
  149. onChange={(value) => {
  150. dealHtml(value, (html: string) => {
  151. setFormValues({front: html});
  152. });
  153. }}
  154. value={formValues.front}
  155. />
  156. <p/>
  157. <h4>反面</h4>
  158. <MyQuill
  159. theme="snow"
  160. readonly={false}
  161. onChange={(value) => {
  162. dealHtml(value, (html: string) => {
  163. setFormValues({back: html});
  164. });
  165. }}
  166. value={formValues.back}
  167. />
  168. <p/>
  169. <Button type="primary" disabled={btnDisable} onClick={addHandle}>
  170. 确定
  171. </Button>
  172. <span> </span>
  173. <Button
  174. type="primary"
  175. onClick={() => {
  176. hideModal(false);
  177. }}
  178. >
  179. 关闭
  180. </Button>
  181. </div>
  182. </Modal>
  183. );
  184. };
  185. export default UpdateForm;