base.tsx 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import React from 'react';
  2. import { UploadOutlined } from '@ant-design/icons';
  3. import { Button, Input, Upload, message } from 'antd';
  4. import ProForm, {
  5. ProFormDependency,
  6. ProFormFieldSet,
  7. ProFormSelect,
  8. ProFormText,
  9. ProFormTextArea,
  10. } from '@ant-design/pro-form';
  11. import { useRequest } from 'umi';
  12. import { queryCurrent } from '../service';
  13. import { queryProvince, queryCity } from '../service';
  14. import styles from './BaseView.less';
  15. const validatorPhone = (rule: any, value: string, callback: (message?: string) => void) => {
  16. const values = value.split('-');
  17. if (!values[0]) {
  18. callback('Please input your area code!');
  19. }
  20. if (!values[1]) {
  21. callback('Please input your phone number!');
  22. }
  23. callback();
  24. };
  25. // 头像组件 方便以后独立,增加裁剪之类的功能
  26. const AvatarView = ({ avatar }: { avatar: string }) => (
  27. <>
  28. <div className={styles.avatar_title}>头像</div>
  29. <div className={styles.avatar}>
  30. <img src={avatar} alt="avatar" />
  31. </div>
  32. <Upload showUploadList={false}>
  33. <div className={styles.button_view}>
  34. <Button>
  35. <UploadOutlined />
  36. 更换头像
  37. </Button>
  38. </div>
  39. </Upload>
  40. </>
  41. );
  42. const BaseView: React.FC = () => {
  43. const { data: currentUser, loading } = useRequest(() => {
  44. return queryCurrent();
  45. });
  46. const getAvatarURL = () => {
  47. if (currentUser) {
  48. if (currentUser.avatar) {
  49. return currentUser.avatar;
  50. }
  51. const url = 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png';
  52. return url;
  53. }
  54. return '';
  55. };
  56. const handleFinish = async () => {
  57. message.success('更新基本信息成功');
  58. };
  59. return (
  60. <div className={styles.baseView}>
  61. {loading ? null : (
  62. <>
  63. <div className={styles.left}>
  64. <ProForm
  65. layout="vertical"
  66. onFinish={handleFinish}
  67. submitter={{
  68. resetButtonProps: {
  69. style: {
  70. display: 'none',
  71. },
  72. },
  73. submitButtonProps: {
  74. children: '更新基本信息',
  75. },
  76. }}
  77. initialValues={{
  78. ...currentUser,
  79. phone: currentUser?.phone.split('-'),
  80. }}
  81. hideRequiredMark
  82. >
  83. <ProFormText
  84. width="md"
  85. name="email"
  86. label="邮箱"
  87. rules={[
  88. {
  89. required: true,
  90. message: '请输入您的邮箱!',
  91. },
  92. ]}
  93. />
  94. <ProFormText
  95. width="md"
  96. name="name"
  97. label="昵称"
  98. rules={[
  99. {
  100. required: true,
  101. message: '请输入您的昵称!',
  102. },
  103. ]}
  104. />
  105. <ProFormTextArea
  106. name="profile"
  107. label="个人简介"
  108. rules={[
  109. {
  110. required: true,
  111. message: '请输入个人简介!',
  112. },
  113. ]}
  114. placeholder="个人简介"
  115. />
  116. <ProFormSelect
  117. width="sm"
  118. name="country"
  119. label="国家/地区"
  120. rules={[
  121. {
  122. required: true,
  123. message: '请输入您的国家或地区!',
  124. },
  125. ]}
  126. options={[
  127. {
  128. label: '中国',
  129. value: 'China',
  130. },
  131. ]}
  132. />
  133. <ProForm.Group title="所在省市" size={8}>
  134. <ProFormSelect
  135. rules={[
  136. {
  137. required: true,
  138. message: '请输入您的所在省!',
  139. },
  140. ]}
  141. width="sm"
  142. fieldProps={{
  143. labelInValue: true,
  144. }}
  145. name="province"
  146. className={styles.item}
  147. request={async () => {
  148. return queryProvince().then(({ data }) => {
  149. return data.map((item) => {
  150. return {
  151. label: item.name,
  152. value: item.id,
  153. };
  154. });
  155. });
  156. }}
  157. />
  158. <ProFormDependency name={['province']}>
  159. {({ province }) => {
  160. return (
  161. <ProFormSelect
  162. params={{
  163. key: province?.value,
  164. }}
  165. name="city"
  166. width="sm"
  167. rules={[
  168. {
  169. required: true,
  170. message: '请输入您的所在城市!',
  171. },
  172. ]}
  173. disabled={!province}
  174. className={styles.item}
  175. request={async () => {
  176. if (!province?.key) {
  177. return [];
  178. }
  179. return queryCity(province.key || '').then(({ data }) => {
  180. return data.map((item) => {
  181. return {
  182. label: item.name,
  183. value: item.id,
  184. };
  185. });
  186. });
  187. }}
  188. />
  189. );
  190. }}
  191. </ProFormDependency>
  192. </ProForm.Group>
  193. <ProFormText
  194. width="md"
  195. name="address"
  196. label="街道地址"
  197. rules={[
  198. {
  199. required: true,
  200. message: '请输入您的街道地址!',
  201. },
  202. ]}
  203. />
  204. <ProFormFieldSet
  205. name="phone"
  206. label="联系电话"
  207. rules={[
  208. {
  209. required: true,
  210. message: '请输入您的联系电话!',
  211. },
  212. { validator: validatorPhone },
  213. ]}
  214. >
  215. <Input className={styles.area_code} />
  216. <Input className={styles.phone_number} />
  217. </ProFormFieldSet>
  218. </ProForm>
  219. </div>
  220. <div className={styles.right}>
  221. <AvatarView avatar={getAvatarURL()} />
  222. </div>
  223. </>
  224. )}
  225. </div>
  226. );
  227. };
  228. export default BaseView;