383 lines
11 KiB
TypeScript
383 lines
11 KiB
TypeScript
/** @format */
|
||
import { FunctionComponent, useEffect, useState } from "react";
|
||
import { ProCard } from "@ant-design/pro-components";
|
||
import {
|
||
Avatar,
|
||
Button,
|
||
Flex,
|
||
Form,
|
||
FormProps,
|
||
Input,
|
||
message,
|
||
Select,
|
||
Skeleton,
|
||
Space,
|
||
Tabs,
|
||
Tag,
|
||
} from "antd";
|
||
import styles from "./index.module.less";
|
||
import TextArea from "antd/es/input/TextArea";
|
||
import { getUserInfoApi, updateUserInfo } from "@/api/user";
|
||
import { observer } from "mobx-react";
|
||
import useStore from "@/utils/store/useStore.tsx";
|
||
|
||
const UserSetting: FunctionComponent = observer(() => {
|
||
const [disable, setDisable] = useState<boolean>(true);
|
||
const [loading, setLoading] = useState<boolean>(true);
|
||
const [userInfo, setUserInfo] = useState<any>({} as any);
|
||
const [password, setPassword] = useState<string>("");
|
||
const [phone, setPhone] = useState<string>("");
|
||
const [email, setEmail] = useState<string>("");
|
||
const store = useStore("user");
|
||
const userId: any = store.getUserId();
|
||
async function getUserInfo() {
|
||
getUserInfoApi(userId).then((res: any) => {
|
||
console.log(res);
|
||
if (res && res.success && res.data) {
|
||
setUserInfo(res.data);
|
||
setLoading(false);
|
||
}
|
||
});
|
||
}
|
||
type FieldType = {
|
||
nickName?: string;
|
||
// location?: string;
|
||
introduce?: string;
|
||
gender?: string;
|
||
company?: string;
|
||
blog?: string;
|
||
};
|
||
async function updateUser(data: any) {
|
||
updateUserInfo(data).then((res: any) => {
|
||
if (res && res.success) {
|
||
message.open({
|
||
type: "success",
|
||
content: "修改成功",
|
||
});
|
||
} else {
|
||
message.open({
|
||
type: "error",
|
||
content: "修改失败",
|
||
});
|
||
}
|
||
});
|
||
}
|
||
const onFinish: FormProps<FieldType>["onFinish"] = (values) => {
|
||
const data: any = {
|
||
id: userId,
|
||
...values,
|
||
};
|
||
updateUserInfo(data).then((res: any) => {
|
||
if (res && res.success) {
|
||
message.open({
|
||
type: "success",
|
||
content: "修改成功",
|
||
});
|
||
} else {
|
||
message.open({
|
||
type: "error",
|
||
content: "修改失败",
|
||
});
|
||
}
|
||
});
|
||
};
|
||
|
||
const onFinishFailed: FormProps<FieldType>["onFinishFailed"] = (errorInfo: any) => {
|
||
message.open({
|
||
type: "error",
|
||
content: errorInfo,
|
||
});
|
||
};
|
||
useEffect(() => {
|
||
getUserInfo().then();
|
||
}, []);
|
||
const prefixSelector = (
|
||
<Select style={{ width: 90 }}>
|
||
<Select.Option value="https://">https://</Select.Option>
|
||
<Select.Option value="http://">http://</Select.Option>
|
||
</Select>
|
||
);
|
||
// const ProFormText = (props: any) => {
|
||
// return (
|
||
// <ProForm.Item {...props} style={{ height: "10px" }}>
|
||
// <ProFormCascader
|
||
// request={async () => city}
|
||
// width="md"
|
||
// name="location"
|
||
// disabled={disable}></ProFormCascader>
|
||
// </ProForm.Item>
|
||
// );
|
||
// };
|
||
useEffect(() => {}, []);
|
||
const TabItems = [
|
||
{
|
||
label: <span>基础信息</span>,
|
||
key: "baseInfo",
|
||
children: (
|
||
<>
|
||
<Skeleton loading={loading} active>
|
||
<div>
|
||
<Form
|
||
name="basic"
|
||
labelCol={{ span: 3 }}
|
||
wrapperCol={{ span: 16 }}
|
||
style={{ maxWidth: 600 }}
|
||
onFinish={onFinish}
|
||
onFinishFailed={onFinishFailed}
|
||
initialValues={{ prefix: "https://" }}
|
||
autoComplete="off">
|
||
{/*<Form.Item<FieldType>*/}
|
||
{/* label="邮箱"*/}
|
||
{/* name="email"*/}
|
||
{/* rules={[*/}
|
||
{/* {*/}
|
||
{/* type: "email",*/}
|
||
{/* message: "请输入正确的邮箱!",*/}
|
||
{/* },*/}
|
||
{/* { required: true, message: "请输入邮箱!" },*/}
|
||
{/* ]}>*/}
|
||
{/* <Input allowClear disabled={disable} />*/}
|
||
{/*</Form.Item>*/}
|
||
<Form.Item<FieldType>
|
||
label="昵称"
|
||
name="nickName"
|
||
rules={[
|
||
{
|
||
type: "string",
|
||
message:
|
||
"用户名只能是3到16位(字母,数字,下划线,减号)!",
|
||
pattern: /^[a-zA-Z0-9_-]{3,16}$/,
|
||
},
|
||
{
|
||
required: true,
|
||
message: "请输入昵称!",
|
||
},
|
||
]}>
|
||
<Input allowClear disabled={disable} />
|
||
</Form.Item>
|
||
<Form.Item<FieldType>
|
||
label="性别"
|
||
name="gender"
|
||
rules={[{ required: true, message: "请输入性别!" }]}>
|
||
<Select disabled={disable}>
|
||
<Select.Option value="男">男</Select.Option>
|
||
<Select.Option value="女">女</Select.Option>
|
||
<Select.Option value="UNKNOWN">隐私</Select.Option>
|
||
</Select>
|
||
</Form.Item>
|
||
{/*<Form.Item<FieldType>*/}
|
||
{/* label="地区"*/}
|
||
{/* name="location"*/}
|
||
{/* rules={[{ required: true, message: "请输入地区!" }]}>*/}
|
||
{/* <ProFormText />*/}
|
||
{/*</Form.Item>*/}
|
||
<Form.Item<FieldType> label="公司" name="company">
|
||
<Input allowClear disabled={disable} />
|
||
</Form.Item>
|
||
<Form.Item<FieldType> label="博客" name="blog">
|
||
<Input
|
||
addonBefore={prefixSelector}
|
||
allowClear
|
||
disabled={disable}
|
||
/>
|
||
</Form.Item>
|
||
<Form.Item<FieldType> label="个人简介" name="introduce">
|
||
<TextArea
|
||
rows={4}
|
||
allowClear
|
||
maxLength={200}
|
||
showCount
|
||
placeholder="请输入您的个人简介,最多不超过200字。"
|
||
disabled={disable}
|
||
/>
|
||
</Form.Item>
|
||
<Form.Item wrapperCol={{ offset: 3, span: 16 }}>
|
||
<Space
|
||
style={{
|
||
display: "flex",
|
||
flexDirection: "row",
|
||
justifyContent: "space-between",
|
||
width: "400px",
|
||
}}>
|
||
<Button
|
||
htmlType="button"
|
||
onClick={() => {
|
||
setDisable(!disable);
|
||
}}>
|
||
修改
|
||
</Button>
|
||
<Button type="primary" htmlType="submit" disabled={disable}>
|
||
保存
|
||
</Button>
|
||
</Space>
|
||
</Form.Item>
|
||
</Form>
|
||
</div>
|
||
</Skeleton>
|
||
</>
|
||
),
|
||
},
|
||
{
|
||
label: <span>安全设置</span>,
|
||
key: "security",
|
||
children: (
|
||
<>
|
||
<Skeleton loading={loading} active>
|
||
<Space direction={"vertical"} style={{ width: "100%" }}>
|
||
<ProCard hoverable bordered>
|
||
<Flex vertical={false} align={"center"}>
|
||
<span style={{ width: 100 }}>登录密码:</span>
|
||
<Space.Compact style={{ width: "100%" }}>
|
||
<Input.Password
|
||
onChange={(e: any) => {
|
||
setPassword(e.target.value);
|
||
}}
|
||
variant="borderless"
|
||
/>
|
||
<Button
|
||
type="text"
|
||
onClick={async () => {
|
||
const data: any = {
|
||
id: userId,
|
||
password: password,
|
||
};
|
||
await updateUser(data);
|
||
}}>
|
||
保存
|
||
</Button>
|
||
</Space.Compact>
|
||
</Flex>
|
||
</ProCard>
|
||
<ProCard hoverable bordered>
|
||
<Flex vertical={false} align={"center"}>
|
||
<span style={{ width: 100 }}>安全手机:</span>
|
||
<Space.Compact style={{ width: "100%" }}>
|
||
<Input.Password
|
||
onChange={(e: any) => {
|
||
setPhone(e.target.value);
|
||
}}
|
||
variant="borderless"
|
||
/>
|
||
<Button
|
||
type="text"
|
||
onClick={async () => {
|
||
const data: any = {
|
||
id: userId,
|
||
phone: phone,
|
||
};
|
||
await updateUser(data);
|
||
}}>
|
||
保存
|
||
</Button>
|
||
</Space.Compact>
|
||
</Flex>
|
||
</ProCard>
|
||
<ProCard hoverable bordered>
|
||
<Flex vertical={false} align={"center"}>
|
||
<span style={{ width: 100 }}>安全邮箱:</span>
|
||
<Space.Compact style={{ width: "100%" }}>
|
||
<Input.Password
|
||
onChange={(e: any) => {
|
||
setEmail(e.target.value);
|
||
}}
|
||
variant="borderless"
|
||
/>
|
||
<Button
|
||
type="text"
|
||
onClick={async () => {
|
||
const data: any = {
|
||
id: userId,
|
||
email: email,
|
||
};
|
||
await updateUser(data);
|
||
}}>
|
||
保存
|
||
</Button>
|
||
</Space.Compact>
|
||
</Flex>
|
||
</ProCard>
|
||
</Space>
|
||
</Skeleton>
|
||
</>
|
||
),
|
||
},
|
||
];
|
||
|
||
return (
|
||
<>
|
||
<div className={styles.user_setting_main}>
|
||
<ProCard boxShadow>
|
||
<Skeleton loading={loading} active avatar>
|
||
<div className={styles.user_setting_header}>
|
||
<Avatar
|
||
size={{ xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100 }}
|
||
src={userInfo.avatar}
|
||
/>
|
||
|
||
<Flex
|
||
vertical={false}
|
||
align={"center"}
|
||
style={{ height: "100px", marginLeft: 40 }}>
|
||
<Flex vertical={true} justify={"flex-start"}>
|
||
<Flex vertical={false} align={"center"}>
|
||
<span style={{ color: "grey" }}>用户名:</span>
|
||
<span style={{ width: 200 }}>{userInfo.userName}</span>
|
||
</Flex>
|
||
<Flex
|
||
vertical={false}
|
||
align={"center"}
|
||
style={{ marginTop: 20 }}>
|
||
<span style={{ color: "grey" }}>账号ID:</span>
|
||
<span style={{ width: 200 }}>{userInfo.id}</span>
|
||
</Flex>
|
||
</Flex>
|
||
<Flex vertical={true} style={{ marginLeft: 50 }}>
|
||
<Flex vertical={false} align={"center"}>
|
||
<span style={{ color: "grey" }}>邮 箱:</span>
|
||
<span style={{ width: 130 }}>
|
||
{userInfo.email || "---------"}
|
||
</span>
|
||
</Flex>
|
||
<Flex
|
||
vertical={false}
|
||
align={"center"}
|
||
style={{ marginTop: 20 }}>
|
||
<span style={{ color: "grey" }}>手机号:</span>
|
||
<span style={{ width: 130 }}>
|
||
{userInfo.phone || "---------"}
|
||
</span>
|
||
</Flex>
|
||
</Flex>
|
||
<Flex vertical={true} style={{ marginLeft: 50 }}>
|
||
<Flex vertical={false} align={"center"}>
|
||
<span style={{ color: "grey" }}>注册时间:</span>
|
||
<span style={{ width: 130 }}>{userInfo.createdTime}</span>
|
||
</Flex>
|
||
<Flex
|
||
vertical={false}
|
||
align={"center"}
|
||
style={{ marginTop: 20 }}>
|
||
<span style={{ color: "grey" }}>状 态:</span>
|
||
{userInfo.status === 0 ? (
|
||
<Tag color={"success"}>正常</Tag>
|
||
) : (
|
||
<Tag color={"red"}>禁用</Tag>
|
||
)}
|
||
</Flex>
|
||
</Flex>
|
||
</Flex>
|
||
</div>
|
||
</Skeleton>
|
||
</ProCard>
|
||
|
||
<div className={styles.user_setting_content}>
|
||
<ProCard boxShadow>
|
||
<Tabs type="card" items={TabItems}></Tabs>
|
||
</ProCard>
|
||
</div>
|
||
</div>
|
||
</>
|
||
);
|
||
});
|
||
export default UserSetting;
|