EditRedemption.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import React, { useEffect, useState } from 'react';
  2. import { useNavigate, useParams } from 'react-router-dom';
  3. import { useTranslation } from 'react-i18next';
  4. import {
  5. API,
  6. downloadTextAsFile,
  7. isMobile,
  8. showError,
  9. showSuccess,
  10. } from '../../helpers';
  11. import { getQuotaPerUnit, renderQuota, renderQuotaWithPrompt } from '../../helpers/render';
  12. import {
  13. AutoComplete,
  14. Button,
  15. Input,
  16. Modal,
  17. SideSheet,
  18. Space,
  19. Spin,
  20. Typography,
  21. } from '@douyinfe/semi-ui';
  22. import Title from '@douyinfe/semi-ui/lib/es/typography/title';
  23. import { Divider } from 'semantic-ui-react';
  24. const EditRedemption = (props) => {
  25. const { t } = useTranslation();
  26. const isEdit = props.editingRedemption.id !== undefined;
  27. const [loading, setLoading] = useState(isEdit);
  28. const params = useParams();
  29. const navigate = useNavigate();
  30. const originInputs = {
  31. name: '',
  32. quota: 100000,
  33. count: 1,
  34. };
  35. const [inputs, setInputs] = useState(originInputs);
  36. const { name, quota, count } = inputs;
  37. const handleCancel = () => {
  38. props.handleClose();
  39. };
  40. const handleInputChange = (name, value) => {
  41. setInputs((inputs) => ({ ...inputs, [name]: value }));
  42. };
  43. const loadRedemption = async () => {
  44. setLoading(true);
  45. let res = await API.get(`/api/redemption/${props.editingRedemption.id}`);
  46. const { success, message, data } = res.data;
  47. if (success) {
  48. setInputs(data);
  49. } else {
  50. showError(message);
  51. }
  52. setLoading(false);
  53. };
  54. useEffect(() => {
  55. if (isEdit) {
  56. loadRedemption().then(() => {
  57. // console.log(inputs);
  58. });
  59. } else {
  60. setInputs(originInputs);
  61. }
  62. }, [props.editingRedemption.id]);
  63. const submit = async () => {
  64. let name = inputs.name;
  65. if (!isEdit && inputs.name === '') {
  66. // set default name
  67. name = renderQuota(quota);
  68. }
  69. setLoading(true);
  70. let localInputs = inputs;
  71. localInputs.count = parseInt(localInputs.count);
  72. localInputs.quota = parseInt(localInputs.quota);
  73. localInputs.name = name;
  74. let res;
  75. if (isEdit) {
  76. res = await API.put(`/api/redemption/`, {
  77. ...localInputs,
  78. id: parseInt(props.editingRedemption.id),
  79. });
  80. } else {
  81. res = await API.post(`/api/redemption/`, {
  82. ...localInputs,
  83. });
  84. }
  85. const { success, message, data } = res.data;
  86. if (success) {
  87. if (isEdit) {
  88. showSuccess(t('兑换码更新成功!'));
  89. props.refresh();
  90. props.handleClose();
  91. } else {
  92. showSuccess(t('兑换码创建成功!'));
  93. setInputs(originInputs);
  94. props.refresh();
  95. props.handleClose();
  96. }
  97. } else {
  98. showError(message);
  99. }
  100. if (!isEdit && data) {
  101. let text = '';
  102. for (let i = 0; i < data.length; i++) {
  103. text += data[i] + '\n';
  104. }
  105. Modal.confirm({
  106. title: t('兑换码创建成功'),
  107. content: (
  108. <div>
  109. <p>{t('兑换码创建成功,是否下载兑换码?')}</p>
  110. <p>{t('兑换码将以文本文件的形式下载,文件名为兑换码的名称。')}</p>
  111. </div>
  112. ),
  113. onOk: () => {
  114. downloadTextAsFile(text, `${inputs.name}.txt`);
  115. },
  116. });
  117. }
  118. setLoading(false);
  119. };
  120. return (
  121. <>
  122. <SideSheet
  123. placement={isEdit ? 'right' : 'left'}
  124. title={
  125. <Title level={3}>
  126. {isEdit ? t('更新兑换码信息') : t('创建新的兑换码')}
  127. </Title>
  128. }
  129. headerStyle={{ borderBottom: '1px solid var(--semi-color-border)' }}
  130. bodyStyle={{ borderBottom: '1px solid var(--semi-color-border)' }}
  131. visible={props.visiable}
  132. footer={
  133. <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
  134. <Space>
  135. <Button theme='solid' size={'large'} onClick={submit}>
  136. {t('提交')}
  137. </Button>
  138. <Button
  139. theme='solid'
  140. size={'large'}
  141. type={'tertiary'}
  142. onClick={handleCancel}
  143. >
  144. {t('取消')}
  145. </Button>
  146. </Space>
  147. </div>
  148. }
  149. closeIcon={null}
  150. onCancel={() => handleCancel()}
  151. width={isMobile() ? '100%' : 600}
  152. >
  153. <Spin spinning={loading}>
  154. <Input
  155. style={{ marginTop: 20 }}
  156. label={t('名称')}
  157. name='name'
  158. placeholder={t('请输入名称')}
  159. onChange={(value) => handleInputChange('name', value)}
  160. value={name}
  161. autoComplete='new-password'
  162. required={!isEdit}
  163. />
  164. <Divider />
  165. <div style={{ marginTop: 20 }}>
  166. <Typography.Text>{t('额度') + renderQuotaWithPrompt(quota)}</Typography.Text>
  167. </div>
  168. <AutoComplete
  169. style={{ marginTop: 8 }}
  170. name='quota'
  171. placeholder={t('请输入额度')}
  172. onChange={(value) => handleInputChange('quota', value)}
  173. value={quota}
  174. autoComplete='new-password'
  175. type='number'
  176. position={'bottom'}
  177. data={[
  178. { value: 500000, label: '1$' },
  179. { value: 5000000, label: '10$' },
  180. { value: 25000000, label: '50$' },
  181. { value: 50000000, label: '100$' },
  182. { value: 250000000, label: '500$' },
  183. { value: 500000000, label: '1000$' },
  184. ]}
  185. />
  186. {!isEdit && (
  187. <>
  188. <Divider />
  189. <Typography.Text>{t('生成数量')}</Typography.Text>
  190. <Input
  191. style={{ marginTop: 8 }}
  192. label={t('生成数量')}
  193. name='count'
  194. placeholder={t('请输入生成数量')}
  195. onChange={(value) => handleInputChange('count', value)}
  196. value={count}
  197. autoComplete='new-password'
  198. type='number'
  199. />
  200. </>
  201. )}
  202. </Spin>
  203. </SideSheet>
  204. </>
  205. );
  206. };
  207. export default EditRedemption;