fix: bug修复
This commit is contained in:
@@ -156,7 +156,10 @@ export const getUserInfoApi = (userId: string): any => {
|
|||||||
export const updateUserInfo = (data: any): any => {
|
export const updateUserInfo = (data: any): any => {
|
||||||
return web.request({
|
return web.request({
|
||||||
url: "/auth/auth/user/update",
|
url: "/auth/auth/user/update",
|
||||||
method: "get",
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
|
},
|
||||||
data: data,
|
data: data,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -195,3 +198,29 @@ export const logout = (userId: any): any => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 检查用户名是否已存在
|
||||||
|
* @param userName
|
||||||
|
*/
|
||||||
|
export const checkUserName = (userName: any): any => {
|
||||||
|
return web.request({
|
||||||
|
url: "/auth/auth/user/checkUserName",
|
||||||
|
method: "post",
|
||||||
|
params: {
|
||||||
|
userName: userName,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 获取最近分享
|
||||||
|
* @param userId
|
||||||
|
*/
|
||||||
|
export const getRecentShare = (userId: any): any => {
|
||||||
|
return web.request({
|
||||||
|
url: "/share/share/detail/getRecentShare",
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
userId: userId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@@ -29,10 +29,7 @@ const FileUpload = (props: any) => {
|
|||||||
|
|
||||||
const uploadFile = async (options: any) => {
|
const uploadFile = async (options: any) => {
|
||||||
const { onSuccess, onError, file }: { onSuccess: any; onError: any; file: any } = options;
|
const { onSuccess, onError, file }: { onSuccess: any; onError: any; file: any } = options;
|
||||||
if (
|
if (store.getUploadFileBucket() === null || store.getUploadFileStorage() === null) {
|
||||||
store.getUploadFilePath() === null ||
|
|
||||||
(store.getUploadFileBucket() === null && store.getUploadFileStorage() === null)
|
|
||||||
) {
|
|
||||||
message.open({
|
message.open({
|
||||||
content: "请选择存储桶和存储路径",
|
content: "请选择存储桶和存储路径",
|
||||||
type: "error",
|
type: "error",
|
||||||
|
@@ -339,7 +339,7 @@ const MainHome: React.FC = observer(() => {
|
|||||||
color: "coral",
|
color: "coral",
|
||||||
fontWeight: "bolder",
|
fontWeight: "bolder",
|
||||||
}}>
|
}}>
|
||||||
{storageCount}
|
{storageCount || 0}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
/个
|
/个
|
||||||
@@ -400,7 +400,7 @@ const MainHome: React.FC = observer(() => {
|
|||||||
color: "lightblue",
|
color: "lightblue",
|
||||||
fontWeight: "bolder",
|
fontWeight: "bolder",
|
||||||
}}>
|
}}>
|
||||||
{bucketCount}
|
{bucketCount || 0}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
/个
|
/个
|
||||||
@@ -467,7 +467,7 @@ const MainHome: React.FC = observer(() => {
|
|||||||
color: "orange",
|
color: "orange",
|
||||||
marginLeft: 5,
|
marginLeft: 5,
|
||||||
}}>
|
}}>
|
||||||
{uploadFile}
|
{uploadFile || 0}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
@@ -483,7 +483,7 @@ const MainHome: React.FC = observer(() => {
|
|||||||
color: "green",
|
color: "green",
|
||||||
marginLeft: 5,
|
marginLeft: 5,
|
||||||
}}>
|
}}>
|
||||||
{downloadFile}
|
{downloadFile || 0}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -531,7 +531,7 @@ const MainHome: React.FC = observer(() => {
|
|||||||
color: "orange",
|
color: "orange",
|
||||||
marginLeft: 5,
|
marginLeft: 5,
|
||||||
}}>
|
}}>
|
||||||
{uploadFlow}
|
{uploadFlow || 0}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
@@ -547,7 +547,7 @@ const MainHome: React.FC = observer(() => {
|
|||||||
color: "green",
|
color: "green",
|
||||||
marginLeft: 5,
|
marginLeft: 5,
|
||||||
}}>
|
}}>
|
||||||
{downloadFlow}
|
{downloadFlow || 0}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@@ -31,7 +31,7 @@ import { cyan, generate, green, presetPalettes, red } from "@ant-design/colors";
|
|||||||
|
|
||||||
type Presets = Required<ColorPickerProps>["presets"][number];
|
type Presets = Required<ColorPickerProps>["presets"][number];
|
||||||
|
|
||||||
const ShareAdd: React.FunctionComponent = observer(() => {
|
const ShareAdd: React.FunctionComponent = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const divRef = useRef(null);
|
const divRef = useRef(null);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
@@ -373,5 +373,5 @@ const ShareAdd: React.FunctionComponent = observer(() => {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
});
|
};
|
||||||
export default observer(ShareAdd);
|
export default observer(ShareAdd);
|
||||||
|
@@ -8,6 +8,8 @@ import {
|
|||||||
HeartOutlined,
|
HeartOutlined,
|
||||||
InfoCircleOutlined,
|
InfoCircleOutlined,
|
||||||
LeftOutlined,
|
LeftOutlined,
|
||||||
|
LikeOutlined,
|
||||||
|
StarOutlined,
|
||||||
TagsOutlined,
|
TagsOutlined,
|
||||||
WarningOutlined,
|
WarningOutlined,
|
||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
@@ -22,10 +24,10 @@ const { Paragraph } = Typography;
|
|||||||
import like from "@/assets/icons/like.svg";
|
import like from "@/assets/icons/like.svg";
|
||||||
import favorite from "@/assets/icons/favorite.svg";
|
import favorite from "@/assets/icons/favorite.svg";
|
||||||
import useStore from "@/utils/store/useStore.tsx";
|
import useStore from "@/utils/store/useStore.tsx";
|
||||||
import { addLikeDetail, getShareDetail } from "@/api/share";
|
import { addLikeDetail, deletedLikeDetail, getShareDetail } from "@/api/share";
|
||||||
import StorageIcon from "@/constant/stroage-icon.ts";
|
import StorageIcon from "@/constant/stroage-icon.ts";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { addFavorites } from "@/api/user";
|
import { addFavorites, deleteFavorites } from "@/api/user";
|
||||||
const ShareDetail: React.FunctionComponent = () => {
|
const ShareDetail: React.FunctionComponent = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const store = useStore("share");
|
const store = useStore("share");
|
||||||
@@ -44,18 +46,20 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
}
|
}
|
||||||
async function addLike() {
|
async function addLike() {
|
||||||
const data: any = {
|
const data: any = {
|
||||||
|
circleId: store.getCircleId(),
|
||||||
userId: userId,
|
userId: userId,
|
||||||
detailId: params.id,
|
detailId: params.id,
|
||||||
};
|
};
|
||||||
addLikeDetail(data).then();
|
addLikeDetail(data).then();
|
||||||
}
|
}
|
||||||
// async function delLike() {
|
async function delLike() {
|
||||||
// const data: any = {
|
const data: any = {
|
||||||
// userId: userId,
|
circleId: store.getCircleId(),
|
||||||
// detailId: params.id,
|
userId: userId,
|
||||||
// };
|
detailId: params.id,
|
||||||
// deletedLikeDetail(data).then();
|
};
|
||||||
// }
|
deletedLikeDetail(data).then();
|
||||||
|
}
|
||||||
async function setFavorites() {
|
async function setFavorites() {
|
||||||
const data: any = {
|
const data: any = {
|
||||||
userId: userId,
|
userId: userId,
|
||||||
@@ -68,6 +72,7 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
type: "success",
|
type: "success",
|
||||||
content: "收藏成功",
|
content: "收藏成功",
|
||||||
});
|
});
|
||||||
|
getDetail().then();
|
||||||
} else {
|
} else {
|
||||||
message.open({
|
message.open({
|
||||||
type: "error",
|
type: "error",
|
||||||
@@ -76,6 +81,27 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
async function cancelFavorites() {
|
||||||
|
const data: any = {
|
||||||
|
userId: userId,
|
||||||
|
detailId: params.id,
|
||||||
|
circleId: store.getCircleId(),
|
||||||
|
};
|
||||||
|
deleteFavorites(data).then((res: any) => {
|
||||||
|
if (res && res.success) {
|
||||||
|
message.open({
|
||||||
|
type: "success",
|
||||||
|
content: "取消成功",
|
||||||
|
});
|
||||||
|
getDetail().then();
|
||||||
|
} else {
|
||||||
|
message.open({
|
||||||
|
type: "error",
|
||||||
|
content: "取消失败",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getDetail().then();
|
getDetail().then();
|
||||||
@@ -109,7 +135,7 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
color: "gray",
|
color: "gray",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
}}>
|
}}>
|
||||||
{detail.nickname}
|
{detail.nickname || "unknown"}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
@@ -119,7 +145,7 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: "gray",
|
color: "gray",
|
||||||
}}>
|
}}>
|
||||||
{detail.likesCount}
|
{detail.likesCount || 0}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
@@ -129,7 +155,7 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: "gray",
|
color: "gray",
|
||||||
}}>
|
}}>
|
||||||
{detail.commentCount}
|
{detail.commentCount || 0}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
@@ -139,7 +165,7 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: "gray",
|
color: "gray",
|
||||||
}}>
|
}}>
|
||||||
{detail.views}
|
{detail.views || 0}
|
||||||
</span>
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
@@ -218,7 +244,7 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
color: "#1677FF",
|
color: "#1677FF",
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
}}>
|
}}>
|
||||||
百度云
|
{url.typeName}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ExportOutlined
|
<ExportOutlined
|
||||||
@@ -277,7 +303,7 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
Array.from(detail.tags).map((tag: any, index: number) => {
|
Array.from(detail.tags).map((tag: any, index: number) => {
|
||||||
return (
|
return (
|
||||||
<div key={index}>
|
<div key={index}>
|
||||||
<Tag bordered={false} color={getRandomColor()}>
|
<Tag bordered={false} color={"#" + detail.color}>
|
||||||
{tag.tagName}
|
{tag.tagName}
|
||||||
</Tag>
|
</Tag>
|
||||||
</div>
|
</div>
|
||||||
@@ -290,21 +316,54 @@ const ShareDetail: React.FunctionComponent = () => {
|
|||||||
align={"center"}
|
align={"center"}
|
||||||
justify={"center"}
|
justify={"center"}
|
||||||
style={{ height: 50 }}>
|
style={{ height: 50 }}>
|
||||||
<Avatar
|
{detail.isLike === true ? (
|
||||||
className={styles.like_icon}
|
<>
|
||||||
src={like as any}
|
<Tooltip title={"取消点赞"} placement={"bottom"}>
|
||||||
onClick={() => {
|
<Avatar
|
||||||
addLike().then();
|
className={styles.like_icon}
|
||||||
}}
|
src={like as any}
|
||||||
size={"large"}></Avatar>
|
onClick={() => {
|
||||||
{/*isFavor*/}
|
delLike().then();
|
||||||
<Avatar
|
}}
|
||||||
className={styles.favtorie_icon}
|
size={"large"}></Avatar>
|
||||||
src={favorite as any}
|
</Tooltip>
|
||||||
onClick={() => {
|
</>
|
||||||
setFavorites().then();
|
) : (
|
||||||
}}
|
<>
|
||||||
size={"large"}></Avatar>
|
<Tooltip title={"点赞"} placement={"bottom"}>
|
||||||
|
<LikeOutlined
|
||||||
|
className={styles.detail_link_btn}
|
||||||
|
onClick={() => {
|
||||||
|
addLike().then();
|
||||||
|
}}></LikeOutlined>
|
||||||
|
</Tooltip>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{detail.isFavor === true ? (
|
||||||
|
<>
|
||||||
|
<Tooltip title={"取消收藏"} placement={"bottom"}>
|
||||||
|
<Avatar
|
||||||
|
className={styles.favtorie_icon}
|
||||||
|
src={favorite as any}
|
||||||
|
onClick={() => {
|
||||||
|
cancelFavorites().then();
|
||||||
|
}}
|
||||||
|
size={"large"}></Avatar>
|
||||||
|
</Tooltip>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Tooltip title={"收藏"} placement={"bottom"}>
|
||||||
|
<StarOutlined
|
||||||
|
onClick={() => {
|
||||||
|
setFavorites().then();
|
||||||
|
}}
|
||||||
|
className={styles.detail_link_btn}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -44,33 +44,38 @@ const Comment = observer((props: any) => {
|
|||||||
const userStore = useStore("user");
|
const userStore = useStore("user");
|
||||||
const userId: any = userStore.getUserId();
|
const userId: any = userStore.getUserId();
|
||||||
async function listComments() {
|
async function listComments() {
|
||||||
|
setComment([]);
|
||||||
listComment(params.id, userId).then((res: any) => {
|
listComment(params.id, userId).then((res: any) => {
|
||||||
console.log(res);
|
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
setComment([]);
|
|
||||||
setComment(res.data);
|
setComment(res.data);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async function addLike(commentId: any) {
|
async function addLike(commentId: any) {
|
||||||
|
setComment([]);
|
||||||
const data: any = {
|
const data: any = {
|
||||||
|
detailId: params.id,
|
||||||
userId: userId,
|
userId: userId,
|
||||||
commentId: commentId,
|
commentId: commentId,
|
||||||
};
|
};
|
||||||
addLikeComment(data).then();
|
addLikeComment(data).then();
|
||||||
|
listComments().then();
|
||||||
}
|
}
|
||||||
async function delLike(commentId: any) {
|
async function delLike(commentId: any) {
|
||||||
|
setComment([]);
|
||||||
const data: any = {
|
const data: any = {
|
||||||
|
detailId: params.id,
|
||||||
userId: userId,
|
userId: userId,
|
||||||
commentId: commentId,
|
commentId: commentId,
|
||||||
};
|
};
|
||||||
deletedLikeComment(data).then();
|
deletedLikeComment(data).then();
|
||||||
|
listComments().then();
|
||||||
}
|
}
|
||||||
async function getCommentHot() {
|
async function getCommentHot() {
|
||||||
|
setComment([]);
|
||||||
listCommentHot(params.id, userId).then((res: any) => {
|
listCommentHot(params.id, userId).then((res: any) => {
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
setComment([]);
|
|
||||||
setComment(res.data);
|
setComment(res.data);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -85,7 +90,7 @@ const Comment = observer((props: any) => {
|
|||||||
}
|
}
|
||||||
async function addComments(data: any) {
|
async function addComments(data: any) {
|
||||||
addComment(data).then((res: any) => {
|
addComment(data).then((res: any) => {
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success) {
|
||||||
message.open({
|
message.open({
|
||||||
content: "评论成功",
|
content: "评论成功",
|
||||||
type: "success",
|
type: "success",
|
||||||
@@ -108,7 +113,7 @@ const Comment = observer((props: any) => {
|
|||||||
}
|
}
|
||||||
async function addReplies(data: any) {
|
async function addReplies(data: any) {
|
||||||
addReply(data).then((res: any) => {
|
addReply(data).then((res: any) => {
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success) {
|
||||||
message.open({
|
message.open({
|
||||||
content: "回复成功",
|
content: "回复成功",
|
||||||
type: "success",
|
type: "success",
|
||||||
@@ -132,7 +137,7 @@ const Comment = observer((props: any) => {
|
|||||||
setIsReplyComment(isReplyComment === index ? null : index);
|
setIsReplyComment(isReplyComment === index ? null : index);
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
listComments().then();
|
getCommentHot().then();
|
||||||
getAllCommentAndReply(params.id).then();
|
getAllCommentAndReply(params.id).then();
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
@@ -264,99 +269,136 @@ const Comment = observer((props: any) => {
|
|||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
align={"center"}
|
align={"center"}
|
||||||
style={{
|
justify={"space-between"}>
|
||||||
marginTop: 10,
|
<Flex
|
||||||
width: "100%",
|
vertical={false}
|
||||||
}}>
|
align={"center"}
|
||||||
<span
|
|
||||||
style={{
|
style={{
|
||||||
fontSize: 13,
|
marginTop: 10,
|
||||||
color: "grey",
|
width: "100%",
|
||||||
}}>
|
}}>
|
||||||
{item.createdTime}
|
<span
|
||||||
</span>
|
style={{
|
||||||
<Flex
|
fontSize: 13,
|
||||||
vertical={false}
|
color: "grey",
|
||||||
align={"center"}>
|
}}>
|
||||||
{item.isLike === false ? (
|
{item.createdTime}
|
||||||
<LikeOutlined
|
</span>
|
||||||
onClick={() => {
|
<Flex
|
||||||
delLike(
|
vertical={false}
|
||||||
item.id,
|
align={"center"}>
|
||||||
).then();
|
{item.isLike ===
|
||||||
}}
|
true ? (
|
||||||
className={
|
<LikeFilled
|
||||||
styles.like_icon
|
onClick={() => {
|
||||||
}
|
delLike(
|
||||||
/>
|
item.id,
|
||||||
) : (
|
).then();
|
||||||
<LikeFilled
|
}}
|
||||||
className={
|
style={{
|
||||||
styles.like_icon
|
color: "red",
|
||||||
}
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<LikeOutlined
|
||||||
|
className={
|
||||||
|
styles.like_icon
|
||||||
|
}
|
||||||
|
onClick={() => {
|
||||||
|
addLike(
|
||||||
|
item.id,
|
||||||
|
).then();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<span
|
||||||
style={{
|
style={{
|
||||||
color: "red",
|
fontSize: 13,
|
||||||
}}
|
color: "grey",
|
||||||
|
}}>
|
||||||
|
{item.likes}
|
||||||
|
</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex
|
||||||
|
vertical={false}
|
||||||
|
align={"center"}>
|
||||||
|
<CommentOutlined
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
addLike(
|
setReply([]);
|
||||||
item.id,
|
if (item.id) {
|
||||||
).then();
|
replyComment(
|
||||||
}}
|
item.id,
|
||||||
/>
|
).then(
|
||||||
)}
|
() => {
|
||||||
<span
|
handleExpandReplyCommentClick(
|
||||||
style={{
|
index,
|
||||||
fontSize: 13,
|
);
|
||||||
color: "grey",
|
},
|
||||||
}}>
|
|
||||||
{item.likes}
|
|
||||||
</span>
|
|
||||||
</Flex>
|
|
||||||
<Flex
|
|
||||||
vertical={false}
|
|
||||||
align={"center"}>
|
|
||||||
<CommentOutlined
|
|
||||||
onClick={() => {
|
|
||||||
setReply([]);
|
|
||||||
if (item.id) {
|
|
||||||
replyComment(
|
|
||||||
item.id,
|
|
||||||
).then(() => {
|
|
||||||
handleExpandReplyCommentClick(
|
|
||||||
index,
|
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
}}
|
||||||
|
className={
|
||||||
|
styles.comment_icon
|
||||||
}
|
}
|
||||||
}}
|
/>
|
||||||
className={
|
<span
|
||||||
styles.comment_icon
|
style={{
|
||||||
}
|
fontSize: 13,
|
||||||
/>
|
color: "grey",
|
||||||
<span
|
}}>
|
||||||
style={{
|
{item.replyCount}
|
||||||
fontSize: 13,
|
</span>
|
||||||
color: "grey",
|
</Flex>
|
||||||
}}>
|
<Flex
|
||||||
{item.replyCount}
|
vertical={false}
|
||||||
</span>
|
align={"center"}>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
size={"small"}
|
||||||
|
onClick={() => {
|
||||||
|
handleExpandClick(
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
fontSize: 13,
|
||||||
|
color: "grey",
|
||||||
|
}}>
|
||||||
|
回复
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
align={"center"}>
|
align={"center"}>
|
||||||
<Button
|
<span
|
||||||
type="text"
|
|
||||||
size={"small"}
|
|
||||||
onClick={() => {
|
|
||||||
handleExpandClick(
|
|
||||||
index,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
style={{
|
style={{
|
||||||
|
textWrap: "nowrap",
|
||||||
|
fontSize: 12,
|
||||||
|
color: "grey",
|
||||||
|
textAlign: "end",
|
||||||
|
}}>
|
||||||
|
{item.location ||
|
||||||
|
"unknown"}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
marginLeft: 10,
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: "grey",
|
color: "grey",
|
||||||
}}>
|
}}>
|
||||||
回复
|
{item.browser ||
|
||||||
</Button>
|
"unknown"}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
marginLeft: 10,
|
||||||
|
fontSize: 13,
|
||||||
|
color: "grey",
|
||||||
|
}}>
|
||||||
|
{item.browserVersion ||
|
||||||
|
"unknown"}
|
||||||
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
@@ -573,62 +615,97 @@ const Comment = observer((props: any) => {
|
|||||||
vertical={
|
vertical={
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
style={{
|
align={
|
||||||
marginTop: 10,
|
"center"
|
||||||
width: "100%",
|
}
|
||||||
}}>
|
justify={
|
||||||
<span
|
"space-between"
|
||||||
style={{
|
}>
|
||||||
fontSize: 13,
|
|
||||||
color: "grey",
|
|
||||||
}}>
|
|
||||||
{
|
|
||||||
replyItem.createdTime
|
|
||||||
}
|
|
||||||
</span>
|
|
||||||
<Flex
|
<Flex
|
||||||
vertical={
|
vertical={
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
align={
|
style={{
|
||||||
"center"
|
marginTop: 10,
|
||||||
}>
|
width: "100%",
|
||||||
{replyItem.isLike ===
|
}}>
|
||||||
false ? (
|
|
||||||
<LikeOutlined
|
|
||||||
onClick={() => {
|
|
||||||
delLike(
|
|
||||||
replyItem.id,
|
|
||||||
).then();
|
|
||||||
}}
|
|
||||||
className={
|
|
||||||
styles.like_icon
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<LikeFilled
|
|
||||||
className={
|
|
||||||
styles.like_icon
|
|
||||||
}
|
|
||||||
style={{
|
|
||||||
color: "red",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
addLike(
|
|
||||||
replyItem.id,
|
|
||||||
).then();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: "grey",
|
color: "grey",
|
||||||
}}>
|
}}>
|
||||||
{
|
{
|
||||||
replyItem.likes
|
replyItem.createdTime
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
|
<Flex
|
||||||
|
vertical={
|
||||||
|
false
|
||||||
|
}
|
||||||
|
align={
|
||||||
|
"center"
|
||||||
|
}>
|
||||||
|
{replyItem.isLike ===
|
||||||
|
false ? (
|
||||||
|
<LikeOutlined
|
||||||
|
onClick={() => {
|
||||||
|
addLike(
|
||||||
|
replyItem.id,
|
||||||
|
).then();
|
||||||
|
}}
|
||||||
|
className={
|
||||||
|
styles.like_icon
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<LikeFilled
|
||||||
|
className={
|
||||||
|
styles.like_icon
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
color: "red",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
delLike(
|
||||||
|
replyItem.id,
|
||||||
|
).then();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: 13,
|
||||||
|
color: "grey",
|
||||||
|
}}>
|
||||||
|
{
|
||||||
|
replyItem.likes
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
</Flex>
|
||||||
|
<Flex
|
||||||
|
vertical={
|
||||||
|
false
|
||||||
|
}
|
||||||
|
align={
|
||||||
|
"center"
|
||||||
|
}>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
size={
|
||||||
|
"small"
|
||||||
|
}
|
||||||
|
onClick={() => {
|
||||||
|
handleExpandReplyReplyClick(
|
||||||
|
replyItem.id,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
fontSize: 13,
|
||||||
|
color: "grey",
|
||||||
|
}}>
|
||||||
|
回复
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={
|
vertical={
|
||||||
@@ -637,22 +714,36 @@ const Comment = observer((props: any) => {
|
|||||||
align={
|
align={
|
||||||
"center"
|
"center"
|
||||||
}>
|
}>
|
||||||
<Button
|
<span
|
||||||
type="text"
|
|
||||||
size={
|
|
||||||
"small"
|
|
||||||
}
|
|
||||||
onClick={() => {
|
|
||||||
handleExpandReplyReplyClick(
|
|
||||||
replyItem.id,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
style={{
|
style={{
|
||||||
|
textWrap:
|
||||||
|
"nowrap",
|
||||||
|
fontSize: 12,
|
||||||
|
color: "grey",
|
||||||
|
textAlign:
|
||||||
|
"end",
|
||||||
|
}}>
|
||||||
|
{replyItem.location ||
|
||||||
|
"unknown"}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
marginLeft: 10,
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: "grey",
|
color: "grey",
|
||||||
}}>
|
}}>
|
||||||
回复
|
{replyItem.browser ||
|
||||||
</Button>
|
"unknown"}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
marginLeft: 10,
|
||||||
|
fontSize: 13,
|
||||||
|
color: "grey",
|
||||||
|
}}>
|
||||||
|
{replyItem.browserVersion ||
|
||||||
|
"unknown"}
|
||||||
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
|
@@ -21,3 +21,10 @@
|
|||||||
width: 50px;
|
width: 50px;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
.detail_link_btn{
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
.detail_link_btn:hover{
|
||||||
|
font-size: 35px;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
|
|
||||||
import { ProCard } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import { Avatar, Button, Flex, Input, List, Skeleton, Tag } from "antd";
|
import { Avatar, Button, Empty, Flex, Input, List, Skeleton, Tag } from "antd";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
|
|
||||||
@@ -25,24 +25,7 @@ export default observer(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// async function cancelFavorites(id: any) {
|
|
||||||
// const data: any = {
|
|
||||||
// id: id,
|
|
||||||
// };
|
|
||||||
// deleteFavorites(data).then((res: any) => {
|
|
||||||
// if (res && res.success) {
|
|
||||||
// message.open({
|
|
||||||
// type: "success",
|
|
||||||
// content: "取消成功",
|
|
||||||
// });
|
|
||||||
// } else {
|
|
||||||
// message.open({
|
|
||||||
// type: "error",
|
|
||||||
// content: "取消失败",
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getMyShare().then();
|
getMyShare().then();
|
||||||
}, []);
|
}, []);
|
||||||
@@ -75,110 +58,128 @@ export default observer(() => {
|
|||||||
</div>
|
</div>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
<ProCard bordered={false} boxShadow={false}>
|
<ProCard bordered={false} boxShadow={false}>
|
||||||
<Skeleton loading={loading} active={true} paragraph={{ rows: 14 }}>
|
{data.length === 0 ? (
|
||||||
<List
|
<Empty description={"暂无数据"}></Empty>
|
||||||
dataSource={data}
|
) : (
|
||||||
header={
|
<>
|
||||||
<>
|
<Skeleton loading={loading} active={true} paragraph={{ rows: 14 }}>
|
||||||
<h4>分享列表</h4>
|
<List
|
||||||
</>
|
dataSource={data}
|
||||||
}
|
header={
|
||||||
renderItem={(item: any) => (
|
<>
|
||||||
<List.Item key={item.id}>
|
<h4>分享列表</h4>
|
||||||
<List.Item.Meta
|
</>
|
||||||
avatar={<Avatar src={item.icon} />}
|
}
|
||||||
title={
|
renderItem={(item: any) => (
|
||||||
<Flex vertical={false} align={"center"}>
|
<List.Item key={item.id}>
|
||||||
<Link to={"/main/share/detail/" + item.id}>
|
<List.Item.Meta
|
||||||
{item.title}
|
avatar={<Avatar src={item.icon} />}
|
||||||
</Link>
|
title={
|
||||||
{item.tags &&
|
<Flex vertical={false} align={"center"}>
|
||||||
Array.from(item.tags).map(
|
<Link to={"/main/share/detail/" + item.id}>
|
||||||
(tag: any, index: number) => {
|
{item.title}
|
||||||
return (
|
</Link>
|
||||||
|
{item.tags &&
|
||||||
|
Array.from(item.tags).map(
|
||||||
|
(tag: any, index: number) => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
vertical={false}
|
||||||
|
align={"center"}
|
||||||
|
key={index}>
|
||||||
|
<Tag
|
||||||
|
bordered={false}
|
||||||
|
color={
|
||||||
|
"#" + tag.color
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
marginLeft: 10,
|
||||||
|
}}>
|
||||||
|
{tag.tagName}
|
||||||
|
</Tag>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
}
|
||||||
|
description={
|
||||||
|
<>
|
||||||
|
<Flex
|
||||||
|
vertical={false}
|
||||||
|
justify={"space-between"}
|
||||||
|
align={"center"}>
|
||||||
|
{item.description}
|
||||||
|
<Flex
|
||||||
|
vertical={false}
|
||||||
|
align={"center"}
|
||||||
|
justify={"space-between"}
|
||||||
|
style={{ width: "300px" }}>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
align={"center"}
|
align={"center"}>
|
||||||
key={index}>
|
<Avatar
|
||||||
<Tag
|
src={item.avatar as any}
|
||||||
bordered={false}
|
size={"small"}
|
||||||
color={"#" + tag.color}
|
/>
|
||||||
style={{ marginLeft: 10 }}>
|
<span
|
||||||
{tag.tagName}
|
style={{
|
||||||
</Tag>
|
fontSize: 12,
|
||||||
|
color: "gray",
|
||||||
|
overflow: "hidden",
|
||||||
|
}}>
|
||||||
|
{item.nickname}
|
||||||
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
<Flex
|
||||||
},
|
vertical={false}
|
||||||
)}
|
align={"center"}>
|
||||||
</Flex>
|
<HeartOutlined />
|
||||||
}
|
<span
|
||||||
description={
|
style={{
|
||||||
<>
|
fontSize: 12,
|
||||||
<Flex
|
color: "gray",
|
||||||
vertical={false}
|
}}>
|
||||||
justify={"space-between"}
|
{item.likesCount}
|
||||||
align={"center"}>
|
</span>
|
||||||
{item.description}
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
align={"center"}
|
align={"center"}>
|
||||||
justify={"space-between"}
|
<CommentOutlined />
|
||||||
style={{ width: "300px" }}>
|
<span
|
||||||
<Flex vertical={false} align={"center"}>
|
style={{
|
||||||
<Avatar
|
fontSize: 12,
|
||||||
src={item.avatar as any}
|
color: "gray",
|
||||||
size={"small"}
|
}}>
|
||||||
/>
|
{item.commentCount}
|
||||||
<span
|
</span>
|
||||||
style={{
|
</Flex>
|
||||||
fontSize: 12,
|
<Flex
|
||||||
color: "gray",
|
vertical={false}
|
||||||
overflow: "hidden",
|
align={"center"}>
|
||||||
}}>
|
<EyeOutlined
|
||||||
{item.nickname}
|
style={{ color: "gray" }}
|
||||||
</span>
|
/>{" "}
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: 12,
|
||||||
|
color: "gray",
|
||||||
|
}}>
|
||||||
|
{item.views}
|
||||||
|
</span>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
</>
|
||||||
<HeartOutlined />
|
}
|
||||||
<span
|
/>
|
||||||
style={{
|
</List.Item>
|
||||||
fontSize: 12,
|
)}
|
||||||
color: "gray",
|
/>
|
||||||
}}>
|
</Skeleton>
|
||||||
{item.likesCount}
|
</>
|
||||||
</span>
|
)}
|
||||||
</Flex>
|
|
||||||
<Flex vertical={false} align={"center"}>
|
|
||||||
<CommentOutlined />
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 12,
|
|
||||||
color: "gray",
|
|
||||||
}}>
|
|
||||||
{item.commentCount}
|
|
||||||
</span>
|
|
||||||
</Flex>
|
|
||||||
<Flex vertical={false} align={"center"}>
|
|
||||||
<EyeOutlined
|
|
||||||
style={{ color: "gray" }}
|
|
||||||
/>{" "}
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 12,
|
|
||||||
color: "gray",
|
|
||||||
}}>
|
|
||||||
{item.views}
|
|
||||||
</span>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</List.Item>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Skeleton>
|
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
|
|
||||||
import { ProCard } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import { Avatar, Button, Flex, Input, List, Skeleton, Tag } from "antd";
|
import { Avatar, Button, Empty, Flex, Input, List, Skeleton, Tag } from "antd";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
|
|
||||||
@@ -58,110 +58,128 @@ export default observer(() => {
|
|||||||
</div>
|
</div>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
<ProCard bordered={false} boxShadow={false}>
|
<ProCard bordered={false} boxShadow={false}>
|
||||||
<Skeleton loading={loading} active={true} paragraph={{ rows: 14 }}>
|
{data.length === 0 ? (
|
||||||
<List
|
<Empty description={"暂无数据"}></Empty>
|
||||||
dataSource={data}
|
) : (
|
||||||
header={
|
<>
|
||||||
<>
|
<Skeleton loading={loading} active={true} paragraph={{ rows: 14 }}>
|
||||||
<h4>分享列表</h4>
|
<List
|
||||||
</>
|
dataSource={data}
|
||||||
}
|
header={
|
||||||
renderItem={(item: any) => (
|
<>
|
||||||
<List.Item key={item.id}>
|
<h4>分享列表</h4>
|
||||||
<List.Item.Meta
|
</>
|
||||||
avatar={<Avatar src={item.icon} />}
|
}
|
||||||
title={
|
renderItem={(item: any) => (
|
||||||
<Flex vertical={false} align={"center"}>
|
<List.Item key={item.id}>
|
||||||
<Link to={"/main/share/detail/" + item.id}>
|
<List.Item.Meta
|
||||||
{item.title}
|
avatar={<Avatar src={item.icon} />}
|
||||||
</Link>
|
title={
|
||||||
{item.tags &&
|
<Flex vertical={false} align={"center"}>
|
||||||
Array.from(item.tags).map(
|
<Link to={"/main/share/detail/" + item.id}>
|
||||||
(tag: any, index: number) => {
|
{item.title}
|
||||||
return (
|
</Link>
|
||||||
|
{item.tags &&
|
||||||
|
Array.from(item.tags).map(
|
||||||
|
(tag: any, index: number) => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
vertical={false}
|
||||||
|
align={"center"}
|
||||||
|
key={index}>
|
||||||
|
<Tag
|
||||||
|
bordered={false}
|
||||||
|
color={
|
||||||
|
"#" + tag.color
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
marginLeft: 10,
|
||||||
|
}}>
|
||||||
|
{tag.tagName}
|
||||||
|
</Tag>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
}
|
||||||
|
description={
|
||||||
|
<>
|
||||||
|
<Flex
|
||||||
|
vertical={false}
|
||||||
|
justify={"space-between"}
|
||||||
|
align={"center"}>
|
||||||
|
{item.description}
|
||||||
|
<Flex
|
||||||
|
vertical={false}
|
||||||
|
align={"center"}
|
||||||
|
justify={"space-between"}
|
||||||
|
style={{ width: "300px" }}>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
align={"center"}
|
align={"center"}>
|
||||||
key={index}>
|
<Avatar
|
||||||
<Tag
|
src={item.avatar as any}
|
||||||
bordered={false}
|
size={"small"}
|
||||||
color={"#" + tag.color}
|
/>
|
||||||
style={{ marginLeft: 10 }}>
|
<span
|
||||||
{tag.tagName}
|
style={{
|
||||||
</Tag>
|
fontSize: 12,
|
||||||
|
color: "gray",
|
||||||
|
overflow: "hidden",
|
||||||
|
}}>
|
||||||
|
{item.nickname}
|
||||||
|
</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
<Flex
|
||||||
},
|
vertical={false}
|
||||||
)}
|
align={"center"}>
|
||||||
</Flex>
|
<HeartOutlined />
|
||||||
}
|
<span
|
||||||
description={
|
style={{
|
||||||
<>
|
fontSize: 12,
|
||||||
<Flex
|
color: "gray",
|
||||||
vertical={false}
|
}}>
|
||||||
justify={"space-between"}
|
{item.likesCount}
|
||||||
align={"center"}>
|
</span>
|
||||||
{item.description}
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
align={"center"}
|
align={"center"}>
|
||||||
justify={"space-between"}
|
<CommentOutlined />
|
||||||
style={{ width: "300px" }}>
|
<span
|
||||||
<Flex vertical={false} align={"center"}>
|
style={{
|
||||||
<Avatar
|
fontSize: 12,
|
||||||
src={item.avatar as any}
|
color: "gray",
|
||||||
size={"small"}
|
}}>
|
||||||
/>
|
{item.commentCount}
|
||||||
<span
|
</span>
|
||||||
style={{
|
</Flex>
|
||||||
fontSize: 12,
|
<Flex
|
||||||
color: "gray",
|
vertical={false}
|
||||||
overflow: "hidden",
|
align={"center"}>
|
||||||
}}>
|
<EyeOutlined
|
||||||
{item.nickname}
|
style={{ color: "gray" }}
|
||||||
</span>
|
/>{" "}
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
fontSize: 12,
|
||||||
|
color: "gray",
|
||||||
|
}}>
|
||||||
|
{item.views}
|
||||||
|
</span>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={false} align={"center"}>
|
</>
|
||||||
<HeartOutlined />
|
}
|
||||||
<span
|
/>
|
||||||
style={{
|
</List.Item>
|
||||||
fontSize: 12,
|
)}
|
||||||
color: "gray",
|
/>
|
||||||
}}>
|
</Skeleton>
|
||||||
{item.likesCount}
|
</>
|
||||||
</span>
|
)}
|
||||||
</Flex>
|
|
||||||
<Flex vertical={false} align={"center"}>
|
|
||||||
<CommentOutlined />
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 12,
|
|
||||||
color: "gray",
|
|
||||||
}}>
|
|
||||||
{item.commentCount}
|
|
||||||
</span>
|
|
||||||
</Flex>
|
|
||||||
<Flex vertical={false} align={"center"}>
|
|
||||||
<EyeOutlined
|
|
||||||
style={{ color: "gray" }}
|
|
||||||
/>{" "}
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 12,
|
|
||||||
color: "gray",
|
|
||||||
}}>
|
|
||||||
{item.views}
|
|
||||||
</span>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</List.Item>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Skeleton>
|
|
||||||
</ProCard>
|
</ProCard>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@@ -1,46 +1,37 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
import { FunctionComponent, useEffect, useState } from "react";
|
import { FunctionComponent, useEffect, useState } from "react";
|
||||||
import { Avatar, Card, Empty, Flex, List, Skeleton } from "antd";
|
import { Avatar, Card, Empty, Flex, List, Skeleton } from "antd";
|
||||||
import {
|
import { BankOutlined, BulbOutlined, EnvironmentOutlined } from "@ant-design/icons";
|
||||||
BankOutlined,
|
|
||||||
BulbOutlined,
|
|
||||||
EnvironmentOutlined,
|
|
||||||
} from "@ant-design/icons";
|
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { ProCard } from "@ant-design/pro-components";
|
import { ProCard } from "@ant-design/pro-components";
|
||||||
import Meta from "antd/es/card/Meta";
|
import Meta from "antd/es/card/Meta";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import { getAllStorage } from "@/api/oss";
|
import { getAllStorage } from "@/api/oss";
|
||||||
import StorageIcon from "@/constant/stroage-icon.ts";
|
import StorageIcon from "@/constant/stroage-icon.ts";
|
||||||
import { getUserInfoApi } from "@/api/user";
|
import { getRecentShare, getUserInfoApi } from "@/api/user";
|
||||||
import useStore from "@/utils/store/useStore.tsx";
|
import useStore from "@/utils/store/useStore.tsx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
|
|
||||||
const UserInfo: FunctionComponent = observer(() => {
|
const UserInfo: FunctionComponent = observer(() => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [loadingStorage, setLoadingStorage] = useState(true);
|
||||||
const [userStorage, setUserStorage] = useState([]);
|
const [userStorage, setUserStorage] = useState([]);
|
||||||
|
const [recentShare, setRecentShare] = useState([]);
|
||||||
const [userInfo, setUserInfo] = useState<any>({} as any);
|
const [userInfo, setUserInfo] = useState<any>({} as any);
|
||||||
const store = useStore("user");
|
const store = useStore("user");
|
||||||
const userId: any = store.getUserId();
|
const userId: any = store.getUserId();
|
||||||
const data = [
|
|
||||||
{
|
|
||||||
title: "Ant Design Title 1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Ant Design Title 2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Ant Design Title 3",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Ant Design Title 4",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
async function getUserStorage() {
|
async function getUserStorage() {
|
||||||
const res: any = await getAllStorage(userId);
|
const res: any = await getAllStorage(userId);
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
setUserStorage(res.data);
|
setUserStorage(res.data);
|
||||||
|
setLoadingStorage(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function getUserRecentShare() {
|
||||||
|
const res: any = await getRecentShare(userId);
|
||||||
|
if (res && res.success && res.data) {
|
||||||
|
setRecentShare(res.data);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,6 +44,7 @@ const UserInfo: FunctionComponent = observer(() => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getUserInfo().then();
|
getUserInfo().then();
|
||||||
getUserStorage().then();
|
getUserStorage().then();
|
||||||
|
getUserRecentShare().then();
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -79,81 +71,92 @@ const UserInfo: FunctionComponent = observer(() => {
|
|||||||
<div className={styles.user_info_center_content}>
|
<div className={styles.user_info_center_content}>
|
||||||
<ProCard
|
<ProCard
|
||||||
bordered
|
bordered
|
||||||
style={{ maxWidth: "64%" }}
|
style={{ maxWidth: "100%" }}
|
||||||
title="我的存储商"
|
title="我的存储商"
|
||||||
boxShadow
|
boxShadow
|
||||||
extra={<Link to={"/main/setting"}>查看更多</Link>}>
|
extra={<Link to={"/main/setting"}>查看更多</Link>}>
|
||||||
<Flex vertical={false} align={"center"} justify={"space-between"} wrap={true}>
|
<Flex vertical={false} align={"center"} justify={"space-between"} wrap={true}>
|
||||||
<Skeleton loading={loading} active>
|
{userStorage && userStorage.length === 0 ? (
|
||||||
{userStorage.map((item: any, index: number) => {
|
<Empty description={"暂无数据"}></Empty>
|
||||||
return (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Card
|
<Skeleton loading={loadingStorage} active>
|
||||||
key={index}
|
{userStorage.map((item: any, index: number) => {
|
||||||
onClick={() => {
|
return (
|
||||||
navigate(`/main/setting/${item.ossType}`);
|
<div key={index}>
|
||||||
}}
|
<Card
|
||||||
style={{ width: 350, marginTop: 16, marginLeft: 10 }}
|
onClick={() => {
|
||||||
hoverable={true}>
|
navigate(`/main/setting/${item.ossType}`);
|
||||||
<Meta
|
}}
|
||||||
avatar={<Avatar src={StorageIcon[item.ossType]} />}
|
style={{
|
||||||
title={item.name}
|
width: 350,
|
||||||
description={
|
marginTop: 16,
|
||||||
<>
|
marginLeft: 10,
|
||||||
<span> 配置:{item.configCount}</span>
|
}}
|
||||||
<span style={{ marginLeft: 10 }}>
|
hoverable={true}>
|
||||||
存储桶: {item.bucketCount}
|
<Meta
|
||||||
</span>
|
avatar={
|
||||||
</>
|
<Avatar
|
||||||
}></Meta>
|
src={StorageIcon[item.ossType]}
|
||||||
</Card>
|
/>
|
||||||
</>
|
}
|
||||||
);
|
title={item.name}
|
||||||
})}
|
description={
|
||||||
</Skeleton>
|
<>
|
||||||
|
<span>
|
||||||
|
{" "}
|
||||||
|
配置:{item.configCount}
|
||||||
|
</span>
|
||||||
|
<span style={{ marginLeft: 10 }}>
|
||||||
|
存储桶: {item.bucketCount}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
}></Meta>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Skeleton>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</ProCard>
|
</ProCard>
|
||||||
|
|
||||||
<ProCard bordered style={{ maxWidth: "34%" }} title="我的存储桶" boxShadow>
|
{/*<ProCard bordered style={{ maxWidth: "34%" }} title="我的存储桶" boxShadow>*/}
|
||||||
<Skeleton loading={loading} active>
|
{/* <Skeleton loading={loading} active>*/}
|
||||||
<Card style={{ width: 300, marginTop: 16 }} hoverable={true}>
|
{/* <Card style={{ width: 300, marginTop: 16 }} hoverable={true}>*/}
|
||||||
<Meta
|
{/* <Meta*/}
|
||||||
avatar={
|
{/* avatar={*/}
|
||||||
<Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=1" />
|
{/* <Avatar src="https://api.dicebear.com/7.x/miniavs/svg?seed=1" />*/}
|
||||||
}
|
{/* }*/}
|
||||||
title="Card title"
|
{/* title="Card title"*/}
|
||||||
description="This is the description"
|
{/* description="This is the description"*/}
|
||||||
/>
|
{/* />*/}
|
||||||
</Card>
|
{/* </Card>*/}
|
||||||
</Skeleton>
|
{/* </Skeleton>*/}
|
||||||
</ProCard>
|
{/*</ProCard>*/}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.user_info_bottom_content}>
|
<div className={styles.user_info_bottom_content}>
|
||||||
<ProCard
|
<ProCard bordered style={{ maxWidth: "64%" }} title="最近动态" boxShadow>
|
||||||
bordered
|
{recentShare && recentShare.length === 0 ? (
|
||||||
style={{ maxWidth: "64%" }}
|
<Empty description={"暂无数据"}></Empty>
|
||||||
title="最近动态"
|
) : (
|
||||||
boxShadow
|
<Skeleton loading={loading} active avatar>
|
||||||
extra={<Link to={"#"}>查看更多</Link>}>
|
<List
|
||||||
<Skeleton loading={loading} active avatar>
|
itemLayout="horizontal"
|
||||||
<List
|
dataSource={recentShare}
|
||||||
itemLayout="horizontal"
|
renderItem={(item: any) => (
|
||||||
dataSource={data}
|
<List.Item>
|
||||||
renderItem={(item, index) => (
|
<List.Item.Meta
|
||||||
<List.Item>
|
avatar={<Avatar src={userInfo.avatar} />}
|
||||||
<List.Item.Meta
|
title={item.title}
|
||||||
avatar={
|
description={item.date}
|
||||||
<Avatar
|
/>
|
||||||
src={`https://api.dicebear.com/7.x/miniavs/svg?seed=${index}`}
|
</List.Item>
|
||||||
/>
|
)}
|
||||||
}
|
/>
|
||||||
title={<a href="https://ant.design">{item.title}</a>}
|
</Skeleton>
|
||||||
description="Ant Design, a design language for background applications, is refined by Ant UED Team"
|
)}
|
||||||
/>
|
|
||||||
</List.Item>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Skeleton>
|
|
||||||
</ProCard>
|
</ProCard>
|
||||||
<ProCard bordered style={{ maxWidth: "34%" }} title="站内通知" boxShadow>
|
<ProCard bordered style={{ maxWidth: "34%" }} title="站内通知" boxShadow>
|
||||||
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}></Empty>
|
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}></Empty>
|
||||||
|
@@ -33,6 +33,7 @@ const UserSetting: FunctionComponent = observer(() => {
|
|||||||
const userId: any = store.getUserId();
|
const userId: any = store.getUserId();
|
||||||
async function getUserInfo() {
|
async function getUserInfo() {
|
||||||
getUserInfoApi(userId).then((res: any) => {
|
getUserInfoApi(userId).then((res: any) => {
|
||||||
|
console.log(res);
|
||||||
if (res && res.success && res.data) {
|
if (res && res.success && res.data) {
|
||||||
setUserInfo(res.data);
|
setUserInfo(res.data);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -40,8 +41,8 @@ const UserSetting: FunctionComponent = observer(() => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
type FieldType = {
|
type FieldType = {
|
||||||
nickname?: string;
|
nickName?: string;
|
||||||
location?: string;
|
// location?: string;
|
||||||
introduce?: string;
|
introduce?: string;
|
||||||
gender?: string;
|
gender?: string;
|
||||||
company?: string;
|
company?: string;
|
||||||
@@ -64,7 +65,7 @@ const UserSetting: FunctionComponent = observer(() => {
|
|||||||
}
|
}
|
||||||
const onFinish: FormProps<FieldType>["onFinish"] = (values) => {
|
const onFinish: FormProps<FieldType>["onFinish"] = (values) => {
|
||||||
const data: any = {
|
const data: any = {
|
||||||
userId: userId,
|
id: userId,
|
||||||
...values,
|
...values,
|
||||||
};
|
};
|
||||||
updateUserInfo(data).then((res: any) => {
|
updateUserInfo(data).then((res: any) => {
|
||||||
@@ -92,24 +93,22 @@ const UserSetting: FunctionComponent = observer(() => {
|
|||||||
getUserInfo().then();
|
getUserInfo().then();
|
||||||
}, []);
|
}, []);
|
||||||
const prefixSelector = (
|
const prefixSelector = (
|
||||||
<Form.Item name="prefix" noStyle>
|
<Select style={{ width: 90 }}>
|
||||||
<Select style={{ width: 90 }}>
|
<Select.Option value="https://">https://</Select.Option>
|
||||||
<Select.Option value="https://">https://</Select.Option>
|
<Select.Option value="http://">http://</Select.Option>
|
||||||
<Select.Option value="http://">http://</Select.Option>
|
</Select>
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
);
|
);
|
||||||
const ProFormText = (props: any) => {
|
// const ProFormText = (props: any) => {
|
||||||
return (
|
// return (
|
||||||
<ProForm.Item {...props} style={{ height: "10px" }}>
|
// <ProForm.Item {...props} style={{ height: "10px" }}>
|
||||||
<ProFormCascader
|
// <ProFormCascader
|
||||||
request={async () => city}
|
// request={async () => city}
|
||||||
width="md"
|
// width="md"
|
||||||
name="location"
|
// name="location"
|
||||||
disabled={disable}></ProFormCascader>
|
// disabled={disable}></ProFormCascader>
|
||||||
</ProForm.Item>
|
// </ProForm.Item>
|
||||||
);
|
// );
|
||||||
};
|
// };
|
||||||
useEffect(() => {}, []);
|
useEffect(() => {}, []);
|
||||||
const TabItems = [
|
const TabItems = [
|
||||||
{
|
{
|
||||||
@@ -142,7 +141,7 @@ const UserSetting: FunctionComponent = observer(() => {
|
|||||||
{/*</Form.Item>*/}
|
{/*</Form.Item>*/}
|
||||||
<Form.Item<FieldType>
|
<Form.Item<FieldType>
|
||||||
label="昵称"
|
label="昵称"
|
||||||
name="nickname"
|
name="nickName"
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
type: "string",
|
type: "string",
|
||||||
@@ -167,12 +166,12 @@ const UserSetting: FunctionComponent = observer(() => {
|
|||||||
<Select.Option value="UNKNOWN">隐私</Select.Option>
|
<Select.Option value="UNKNOWN">隐私</Select.Option>
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item<FieldType>
|
{/*<Form.Item<FieldType>*/}
|
||||||
label="地区"
|
{/* label="地区"*/}
|
||||||
name="location"
|
{/* name="location"*/}
|
||||||
rules={[{ required: true, message: "请输入地区!" }]}>
|
{/* rules={[{ required: true, message: "请输入地区!" }]}>*/}
|
||||||
<ProFormText />
|
{/* <ProFormText />*/}
|
||||||
</Form.Item>
|
{/*</Form.Item>*/}
|
||||||
<Form.Item<FieldType> label="公司" name="company">
|
<Form.Item<FieldType> label="公司" name="company">
|
||||||
<Input allowClear disabled={disable} />
|
<Input allowClear disabled={disable} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -240,7 +239,7 @@ const UserSetting: FunctionComponent = observer(() => {
|
|||||||
type="text"
|
type="text"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const data: any = {
|
const data: any = {
|
||||||
userId: userId,
|
id: userId,
|
||||||
password: password,
|
password: password,
|
||||||
};
|
};
|
||||||
await updateUser(data);
|
await updateUser(data);
|
||||||
@@ -264,7 +263,7 @@ const UserSetting: FunctionComponent = observer(() => {
|
|||||||
type="text"
|
type="text"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const data: any = {
|
const data: any = {
|
||||||
userId: userId,
|
id: userId,
|
||||||
phone: phone,
|
phone: phone,
|
||||||
};
|
};
|
||||||
await updateUser(data);
|
await updateUser(data);
|
||||||
@@ -288,7 +287,7 @@ const UserSetting: FunctionComponent = observer(() => {
|
|||||||
type="text"
|
type="text"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const data: any = {
|
const data: any = {
|
||||||
userId: userId,
|
id: userId,
|
||||||
email: email,
|
email: email,
|
||||||
};
|
};
|
||||||
await updateUser(data);
|
await updateUser(data);
|
||||||
@@ -323,14 +322,14 @@ const UserSetting: FunctionComponent = observer(() => {
|
|||||||
<Flex vertical={true} justify={"flex-start"}>
|
<Flex vertical={true} justify={"flex-start"}>
|
||||||
<Flex vertical={false} align={"center"}>
|
<Flex vertical={false} align={"center"}>
|
||||||
<span style={{ color: "grey" }}>用户名:</span>
|
<span style={{ color: "grey" }}>用户名:</span>
|
||||||
<span style={{ width: 130 }}>{userInfo.userName}</span>
|
<span style={{ width: 200 }}>{userInfo.userName}</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
vertical={false}
|
vertical={false}
|
||||||
align={"center"}
|
align={"center"}
|
||||||
style={{ marginTop: 20 }}>
|
style={{ marginTop: 20 }}>
|
||||||
<span style={{ color: "grey" }}>账号ID:</span>
|
<span style={{ color: "grey" }}>账号ID:</span>
|
||||||
<span style={{ width: 130 }}>{userInfo.id}</span>
|
<span style={{ width: 200 }}>{userInfo.id}</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex vertical={true} style={{ marginLeft: 50 }}>
|
<Flex vertical={true} style={{ marginLeft: 50 }}>
|
||||||
|
@@ -4,7 +4,7 @@ import Request from "./request";
|
|||||||
|
|
||||||
const web: Request = new Request({
|
const web: Request = new Request({
|
||||||
baseURL: import.meta.env.VITE_APP_BASE_API,
|
baseURL: import.meta.env.VITE_APP_BASE_API,
|
||||||
timeout: 10000,
|
// timeout: 10000,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default web;
|
export default web;
|
||||||
|
@@ -16,6 +16,8 @@ import { logout } from "@/api/user";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import useStore from "@/utils/store/useStore.tsx";
|
import useStore from "@/utils/store/useStore.tsx";
|
||||||
import { getUserMenuPermission } from "@/api/user";
|
import { getUserMenuPermission } from "@/api/user";
|
||||||
|
import { clearStorage, getStorageFromKey, removeStorageFromKey } from "@/utils/localStorage/config.ts";
|
||||||
|
import localforage from "localforage";
|
||||||
|
|
||||||
const Layout = () => {
|
const Layout = () => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -75,7 +77,14 @@ const Layout = () => {
|
|||||||
label: "退出登录",
|
label: "退出登录",
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
logout(store.getUserId());
|
logout(store.getUserId());
|
||||||
navigate("/login");
|
clearStorage();
|
||||||
|
store.setToken("");
|
||||||
|
store.setUserId("");
|
||||||
|
store.setAvatar("");
|
||||||
|
store.setNickName("");
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate("/login");
|
||||||
|
}, 1000);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@@ -1,375 +1,373 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
|
|
||||||
import { LockOutlined, MobileOutlined, SafetyOutlined, WechatOutlined } from "@ant-design/icons";
|
import { LockOutlined, MobileOutlined, SafetyOutlined, WechatOutlined } from "@ant-design/icons";
|
||||||
import { CaptFieldRef, ProFormCaptcha, ProFormText } from "@ant-design/pro-components";
|
import { CaptFieldRef, ProFormCaptcha, ProFormText } from "@ant-design/pro-components";
|
||||||
import { Alert, Button, ConfigProvider, Form, Image, message, Space, Spin, Tabs } from "antd";
|
import { Alert, Button, ConfigProvider, Form, Image, message, Space, Spin, Tabs } from "antd";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { TinyColor } from "@ctrl/tinycolor";
|
import { TinyColor } from "@ctrl/tinycolor";
|
||||||
import logo from "@/assets/images/logo.png";
|
import logo from "@/assets/images/logo.png";
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import FooterComponent from "@/components/Footer";
|
import FooterComponent from "@/components/Footer";
|
||||||
import { createClientId, findPassword, generateQRCode, getClientToken, getSms } from "@/api/user";
|
import { createClientId, findPassword, generateQRCode, getClientToken, getSms } from "@/api/user";
|
||||||
import RotateCaptcha, { CaptchaInstance, type TicketInfoType } from "react-rotate-captcha";
|
import RotateCaptcha, { CaptchaInstance, type TicketInfoType } from "react-rotate-captcha";
|
||||||
import { get, load } from "@/api/captcha";
|
import { get, load } from "@/api/captcha";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import useStore from "@/utils/store/useStore.tsx";
|
import useStore from "@/utils/store/useStore.tsx";
|
||||||
import { setStorage } from "@/utils/localStorage/config.ts";
|
import { setStorage } from "@/utils/localStorage/config.ts";
|
||||||
import { TimerManager } from "timer-manager-lib";
|
import { TimerManager } from "timer-manager-lib";
|
||||||
|
|
||||||
type LoginType = "phone";
|
type LoginType = "phone";
|
||||||
|
|
||||||
export default observer(() => {
|
export default observer(() => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const captchaRef = useRef<CaptFieldRef | null | undefined>();
|
const captchaRef = useRef<CaptFieldRef | null | undefined>();
|
||||||
const smsCaptcha = useRef<CaptchaInstance>(null);
|
const smsCaptcha = useRef<CaptchaInstance>(null);
|
||||||
const findPasswordCaptcha = useRef<CaptchaInstance>(null);
|
const findPasswordCaptcha = useRef<CaptchaInstance>(null);
|
||||||
const [loginType, setLoginType] = useState<LoginType>("phone");
|
const [loginType, setLoginType] = useState<LoginType>("phone");
|
||||||
const colors = ["#fc6076", "#ff9a44", "#ef9d43", "#e75516"];
|
const colors = ["#fc6076", "#ff9a44", "#ef9d43", "#e75516"];
|
||||||
const [QRCode, setQRCode] = useState<string>("");
|
const [QRCode, setQRCode] = useState<string>("");
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const store = useStore("user");
|
const store = useStore("user");
|
||||||
const timerManager = new TimerManager();
|
const timerManager = new TimerManager();
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
|
||||||
const getHoverColors = (colors: string[]) =>
|
const getHoverColors = (colors: string[]) =>
|
||||||
colors.map((color) => new TinyColor(color).lighten(5).toString());
|
colors.map((color) => new TinyColor(color).lighten(5).toString());
|
||||||
const getActiveColors = (colors: string[]) =>
|
const getActiveColors = (colors: string[]) =>
|
||||||
colors.map((color) => new TinyColor(color).darken(5).toString());
|
colors.map((color) => new TinyColor(color).darken(5).toString());
|
||||||
|
|
||||||
async function smsVerify(token: string, deg: number): Promise<TicketInfoType> {
|
async function smsVerify(token: string, deg: number): Promise<TicketInfoType> {
|
||||||
const phone = form.getFieldValue("phone");
|
const phone = form.getFieldValue("phone");
|
||||||
const data: any = {
|
const data: any = {
|
||||||
token: token,
|
token: token,
|
||||||
deg: deg,
|
deg: deg,
|
||||||
phone: phone,
|
phone: phone,
|
||||||
};
|
};
|
||||||
const res: any = await getSms(data);
|
const res: any = await getSms(data);
|
||||||
if (res && res.code === 0) {
|
if (res && res.code === 0) {
|
||||||
message.open({
|
message.open({
|
||||||
content: res.data,
|
content: res.data,
|
||||||
type: "success",
|
type: "success",
|
||||||
duration: 5,
|
duration: 5,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
message.open({
|
message.open({
|
||||||
content: res.data,
|
content: res.data,
|
||||||
type: "warning",
|
type: "warning",
|
||||||
duration: 5,
|
duration: 5,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function findPasswordVerify(token: string, deg: number): Promise<TicketInfoType> {
|
async function findPasswordVerify(token: string, deg: number): Promise<TicketInfoType> {
|
||||||
const mobile = form.getFieldValue("phone");
|
const mobile = form.getFieldValue("phone");
|
||||||
const captcha = form.getFieldValue("activeCode");
|
const captcha = form.getFieldValue("activeCode");
|
||||||
const password = form.getFieldValue("password");
|
const password = form.getFieldValue("password");
|
||||||
const confirmPassword = form.getFieldValue("confirmPassword");
|
const confirmPassword = form.getFieldValue("confirmPassword");
|
||||||
|
|
||||||
const data: API.findPasswordRequest = {
|
const data: API.findPasswordRequest = {
|
||||||
token: token,
|
token: token,
|
||||||
deg: deg,
|
deg: deg,
|
||||||
phone: mobile,
|
phone: mobile,
|
||||||
activeCode: captcha,
|
activeCode: captcha,
|
||||||
password: password,
|
password: password,
|
||||||
confirmPassword: confirmPassword,
|
confirmPassword: confirmPassword,
|
||||||
};
|
};
|
||||||
const res: any = await findPassword(data);
|
const res: any = await findPassword(data);
|
||||||
if (res && res.success && res.code === 0) {
|
if (res && res.success && res.code === 0) {
|
||||||
message.open({
|
message.open({
|
||||||
content: res.data,
|
content: res.data,
|
||||||
type: "success",
|
type: "success",
|
||||||
duration: 5,
|
duration: 5,
|
||||||
});
|
});
|
||||||
} else if (res.code === 0 && !res.success) {
|
} else if (res.code === 0 && !res.success) {
|
||||||
message.open({
|
message.open({
|
||||||
content: res.data,
|
content: res.data,
|
||||||
type: "error",
|
type: "error",
|
||||||
duration: 5,
|
duration: 5,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function openSmsCaptcha() {
|
async function openSmsCaptcha() {
|
||||||
smsCaptcha.current!.open();
|
smsCaptcha.current!.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fopenFindPasswordCaptcha() {
|
async function fopenFindPasswordCaptcha() {
|
||||||
findPasswordCaptcha.current!.open();
|
findPasswordCaptcha.current!.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
const items = [
|
const items = [
|
||||||
{
|
{
|
||||||
key: "phone",
|
key: "phone",
|
||||||
label: (
|
label: (
|
||||||
<span>
|
<span>
|
||||||
<SafetyOutlined />
|
<SafetyOutlined />
|
||||||
重置密码
|
重置密码
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
async function wechatLogin() {
|
async function wechatLogin() {
|
||||||
createClientId().then((res: any) => {
|
createClientId().then((res: any) => {
|
||||||
generateQRCode(res.data).then((response: any) => {
|
generateQRCode(res.data).then((response: any) => {
|
||||||
if (response.success) {
|
if (res && response.success && res.data) {
|
||||||
setQRCode(response.data.qrCodeUrl);
|
setQRCode(response.data.qrCodeUrl);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
timerManager.add(() => {
|
timerManager.add(() => {
|
||||||
getClientToken(res.data).then((result: any) => {
|
getClientToken(res.data).then((result: any) => {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
timerManager.clear();
|
timerManager.clear();
|
||||||
store.setToken(result.data.tokenValue);
|
store.setToken(result.data.tokenValue);
|
||||||
store.setUserId(result.data.loginId);
|
store.setUserId(result.data.loginId);
|
||||||
setStorage("token", result.data.tokenValue, 24 * 60 * 30);
|
setStorage("token", result.data.tokenValue, 24 * 60 * 30);
|
||||||
setStorage("userId", result.data.loginId, 24 * 60 * 30);
|
setStorage("userId", result.data.loginId, 24 * 60 * 30);
|
||||||
message
|
message
|
||||||
.open({
|
.open({
|
||||||
content: "登录成功!",
|
content: "登录成功!",
|
||||||
type: "success",
|
type: "success",
|
||||||
})
|
})
|
||||||
.then();
|
.then();
|
||||||
if (store.getToken() !== null || store.getUserId() !== null) {
|
if (store.getToken() !== null || store.getUserId() !== null) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate("/main");
|
navigate("/main");
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 3000);
|
}, 3000);
|
||||||
} else {
|
} else {
|
||||||
message
|
message
|
||||||
.open({
|
.open({
|
||||||
content: response.data,
|
content: response.data,
|
||||||
type: "error",
|
type: "error",
|
||||||
})
|
})
|
||||||
.then();
|
.then();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
wechatLogin().then();
|
wechatLogin().then();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<RotateCaptcha get={get} load={load} verify={smsVerify} limit={2} ref={smsCaptcha} />
|
<RotateCaptcha get={get} load={load} verify={smsVerify} limit={2} ref={smsCaptcha} />
|
||||||
<RotateCaptcha
|
<RotateCaptcha
|
||||||
get={get}
|
get={get}
|
||||||
load={load}
|
load={load}
|
||||||
verify={findPasswordVerify}
|
verify={findPasswordVerify}
|
||||||
limit={2}
|
limit={2}
|
||||||
ref={findPasswordCaptcha}
|
ref={findPasswordCaptcha}
|
||||||
/>
|
/>
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<Space>
|
<Space>
|
||||||
<Space className={styles.login_content}>
|
<Space className={styles.login_content}>
|
||||||
<Space align="center" className={styles.mp_code}>
|
<Space align="center" className={styles.mp_code}>
|
||||||
<Space direction="vertical" align="center">
|
<Space direction="vertical" align="center">
|
||||||
<span className={styles.mp_code_title}>微信扫码登录</span>
|
<span className={styles.mp_code_title}>微信扫码登录</span>
|
||||||
<Spin tip="Loading" size="large" spinning={loading}>
|
<Spin tip="Loading" size="large" spinning={loading}>
|
||||||
<Image
|
<Image
|
||||||
preview={false}
|
preview={false}
|
||||||
height={200}
|
height={200}
|
||||||
width={200}
|
width={200}
|
||||||
className={styles.mp_code_img}
|
className={styles.mp_code_img}
|
||||||
// src={generateMpRegCodeData.data?.qrCodeUrl}
|
// src={generateMpRegCodeData.data?.qrCodeUrl}
|
||||||
src={QRCode}
|
src={QRCode}
|
||||||
fallback="data:image/png;base64,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"
|
/>
|
||||||
|
</Spin>
|
||||||
/>
|
<Alert
|
||||||
</Spin>
|
// message={(<span>微信扫码<span>关注公众号</span></span>)}
|
||||||
<Alert
|
description={
|
||||||
// message={(<span>微信扫码<span>关注公众号</span></span>)}
|
<div>
|
||||||
description={
|
<span>
|
||||||
<div>
|
微信扫码
|
||||||
<span>
|
<span className={styles.mp_tips}>关注公众号</span>
|
||||||
微信扫码
|
</span>
|
||||||
<span className={styles.mp_tips}>关注公众号</span>
|
<br />
|
||||||
</span>
|
登录更快更安全
|
||||||
<br />
|
</div>
|
||||||
登录更快更安全
|
}
|
||||||
</div>
|
// type="success"
|
||||||
}
|
showIcon={true}
|
||||||
// type="success"
|
className={styles.alert}
|
||||||
showIcon={true}
|
icon={<WechatOutlined />}
|
||||||
className={styles.alert}
|
/>
|
||||||
icon={<WechatOutlined />}
|
</Space>
|
||||||
/>
|
</Space>
|
||||||
</Space>
|
<Form
|
||||||
</Space>
|
form={form}
|
||||||
<Form
|
className={styles.login_form}
|
||||||
form={form}
|
initialValues={{
|
||||||
className={styles.login_form}
|
autoLogin: true,
|
||||||
initialValues={{
|
}}>
|
||||||
autoLogin: true,
|
<Space direction="vertical" align="center">
|
||||||
}}>
|
<Space className={styles.logo}>
|
||||||
<Space direction="vertical" align="center">
|
<img
|
||||||
<Space className={styles.logo}>
|
alt="logo"
|
||||||
<img
|
src={logo}
|
||||||
alt="logo"
|
style={{ width: "44px", height: "44px" }}
|
||||||
src={logo}
|
/>
|
||||||
style={{ width: "44px", height: "44px" }}
|
<span>五味子云存储</span>
|
||||||
/>
|
</Space>
|
||||||
<span>五味子云存储</span>
|
<div className={styles.subTitle}>随时随地分享你的美好瞬间</div>
|
||||||
</Space>
|
</Space>
|
||||||
<div className={styles.subTitle}>随时随地分享你的美好瞬间</div>
|
|
||||||
</Space>
|
<Tabs
|
||||||
|
centered={true}
|
||||||
<Tabs
|
items={items}
|
||||||
centered={true}
|
activeKey={loginType}
|
||||||
items={items}
|
onChange={(activeKey) =>
|
||||||
activeKey={loginType}
|
setLoginType(activeKey as LoginType)
|
||||||
onChange={(activeKey) =>
|
}></Tabs>
|
||||||
setLoginType(activeKey as LoginType)
|
|
||||||
}></Tabs>
|
<>
|
||||||
|
<ProFormText
|
||||||
<>
|
fieldProps={{
|
||||||
<ProFormText
|
size: "large",
|
||||||
fieldProps={{
|
prefix: <MobileOutlined className={"prefixIcon"} />,
|
||||||
size: "large",
|
autoComplete: "off",
|
||||||
prefix: <MobileOutlined className={"prefixIcon"} />,
|
}}
|
||||||
autoComplete: "off",
|
name="phone"
|
||||||
}}
|
placeholder="请输入手机号"
|
||||||
name="phone"
|
rules={[
|
||||||
placeholder="请输入手机号"
|
{
|
||||||
rules={[
|
required: true,
|
||||||
{
|
message: "请输入手机号!",
|
||||||
required: true,
|
},
|
||||||
message: "请输入手机号!",
|
{
|
||||||
},
|
pattern: /^1\d{10}$/,
|
||||||
{
|
message: "手机号格式错误!",
|
||||||
pattern: /^1\d{10}$/,
|
},
|
||||||
message: "手机号格式错误!",
|
]}
|
||||||
},
|
/>
|
||||||
]}
|
|
||||||
/>
|
<ProFormCaptcha
|
||||||
|
fieldProps={{
|
||||||
<ProFormCaptcha
|
size: "large",
|
||||||
fieldProps={{
|
prefix: <SafetyOutlined className={"prefixIcon"} />,
|
||||||
size: "large",
|
}}
|
||||||
prefix: <SafetyOutlined className={"prefixIcon"} />,
|
captchaProps={{
|
||||||
}}
|
size: "large",
|
||||||
captchaProps={{
|
}}
|
||||||
size: "large",
|
placeholder={"请输入验证码"}
|
||||||
}}
|
captchaTextRender={(timing: boolean, count: number) => {
|
||||||
placeholder={"请输入验证码"}
|
if (timing) {
|
||||||
captchaTextRender={(timing: boolean, count: number) => {
|
return `${count} ${"获取验证码"}`;
|
||||||
if (timing) {
|
// return `${"获取验证码"}`;
|
||||||
return `${count} ${"获取验证码"}`;
|
}
|
||||||
// return `${"获取验证码"}`;
|
return "获取验证码";
|
||||||
}
|
}}
|
||||||
return "获取验证码";
|
name="activeCode"
|
||||||
}}
|
phoneName={"phone"}
|
||||||
name="activeCode"
|
countDown={60}
|
||||||
phoneName={"phone"}
|
rules={[
|
||||||
countDown={60}
|
{
|
||||||
rules={[
|
required: true,
|
||||||
{
|
message: "请输入验证码!",
|
||||||
required: true,
|
},
|
||||||
message: "请输入验证码!",
|
]}
|
||||||
},
|
fieldRef={captchaRef}
|
||||||
]}
|
onGetCaptcha={async () => {
|
||||||
fieldRef={captchaRef}
|
await openSmsCaptcha();
|
||||||
onGetCaptcha={async () => {
|
}}
|
||||||
await openSmsCaptcha();
|
/>
|
||||||
}}
|
|
||||||
/>
|
<ProFormText.Password
|
||||||
|
name="password"
|
||||||
<ProFormText.Password
|
fieldProps={{
|
||||||
name="password"
|
size: "large",
|
||||||
fieldProps={{
|
prefix: <LockOutlined className={"prefixIcon"} />,
|
||||||
size: "large",
|
}}
|
||||||
prefix: <LockOutlined className={"prefixIcon"} />,
|
placeholder="请输入新密码"
|
||||||
}}
|
rules={[
|
||||||
placeholder="请输入新密码"
|
{
|
||||||
rules={[
|
required: true,
|
||||||
{
|
message: "请输入新密码!",
|
||||||
required: true,
|
},
|
||||||
message: "请输入新密码!",
|
{
|
||||||
},
|
pattern:
|
||||||
{
|
/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z\\W]{6,18}$/,
|
||||||
pattern:
|
message:
|
||||||
/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z\\W]{6,18}$/,
|
"密码长度需在6~18位字符,且必须包含字母和数字!",
|
||||||
message:
|
},
|
||||||
"密码长度需在6~18位字符,且必须包含字母和数字!",
|
]}
|
||||||
},
|
/>
|
||||||
]}
|
|
||||||
/>
|
<ProFormText.Password
|
||||||
|
name="confirmPassword"
|
||||||
<ProFormText.Password
|
dependencies={["password"]}
|
||||||
name="confirmPassword"
|
fieldProps={{
|
||||||
dependencies={["password"]}
|
size: "large",
|
||||||
fieldProps={{
|
prefix: <LockOutlined className={"prefixIcon"} />,
|
||||||
size: "large",
|
}}
|
||||||
prefix: <LockOutlined className={"prefixIcon"} />,
|
placeholder="请再次确认密码"
|
||||||
}}
|
rules={[
|
||||||
placeholder="请再次确认密码"
|
{
|
||||||
rules={[
|
required: true,
|
||||||
{
|
message: "请再次确认密码!",
|
||||||
required: true,
|
},
|
||||||
message: "请再次确认密码!",
|
({ getFieldValue }) => ({
|
||||||
},
|
validator(_, value) {
|
||||||
({ getFieldValue }) => ({
|
if (!value || getFieldValue("password") === value) {
|
||||||
validator(_, value) {
|
return Promise.resolve();
|
||||||
if (!value || getFieldValue("password") === value) {
|
}
|
||||||
return Promise.resolve();
|
return Promise.reject(
|
||||||
}
|
new Error("两次输入的密码不一致!"),
|
||||||
return Promise.reject(
|
);
|
||||||
new Error("两次输入的密码不一致!"),
|
},
|
||||||
);
|
}),
|
||||||
},
|
]}
|
||||||
}),
|
/>
|
||||||
]}
|
</>
|
||||||
/>
|
<ConfigProvider
|
||||||
</>
|
theme={{
|
||||||
<ConfigProvider
|
components: {
|
||||||
theme={{
|
Button: {
|
||||||
components: {
|
colorPrimary: `linear-gradient(135deg, ${colors.join(", ")})`,
|
||||||
Button: {
|
colorPrimaryHover: `linear-gradient(135deg, ${getHoverColors(colors).join(", ")})`,
|
||||||
colorPrimary: `linear-gradient(135deg, ${colors.join(", ")})`,
|
colorPrimaryActive: `linear-gradient(135deg, ${getActiveColors(colors).join(", ")})`,
|
||||||
colorPrimaryHover: `linear-gradient(135deg, ${getHoverColors(colors).join(", ")})`,
|
lineWidth: 0,
|
||||||
colorPrimaryActive: `linear-gradient(135deg, ${getActiveColors(colors).join(", ")})`,
|
},
|
||||||
lineWidth: 0,
|
},
|
||||||
},
|
}}>
|
||||||
},
|
<Button
|
||||||
}}>
|
type="primary"
|
||||||
<Button
|
block
|
||||||
type="primary"
|
size="large"
|
||||||
block
|
onClick={async () => {
|
||||||
size="large"
|
const validateFields = [
|
||||||
onClick={async () => {
|
"phone",
|
||||||
const validateFields = [
|
"password",
|
||||||
"phone",
|
"activeCode",
|
||||||
"password",
|
"confirmPassword",
|
||||||
"activeCode",
|
];
|
||||||
"confirmPassword",
|
await form
|
||||||
];
|
.validateFields(validateFields)
|
||||||
await form
|
.then(async () => {
|
||||||
.validateFields(validateFields)
|
await fopenFindPasswordCaptcha();
|
||||||
.then(async () => {
|
})
|
||||||
await fopenFindPasswordCaptcha();
|
.catch((error) => {
|
||||||
})
|
console.error(error);
|
||||||
.catch((error) => {
|
});
|
||||||
console.error(error);
|
}}>
|
||||||
});
|
重置
|
||||||
}}>
|
</Button>
|
||||||
重置
|
</ConfigProvider>
|
||||||
</Button>
|
</Form>
|
||||||
</ConfigProvider>
|
<a href="/login" className={styles.go_to_register}>
|
||||||
</Form>
|
<span>登录</span>
|
||||||
<a href="/login" className={styles.go_to_register}>
|
</a>
|
||||||
<span>登录</span>
|
</Space>
|
||||||
</a>
|
</Space>
|
||||||
</Space>
|
</div>
|
||||||
</Space>
|
<FooterComponent />
|
||||||
</div>
|
</div>
|
||||||
<FooterComponent />
|
);
|
||||||
</div>
|
});
|
||||||
);
|
|
||||||
});
|
|
||||||
|
@@ -120,6 +120,7 @@ export default observer(() => {
|
|||||||
store.setAvatar(res.data.user.avatar);
|
store.setAvatar(res.data.user.avatar);
|
||||||
store.setNickName(res.data.user.nickName);
|
store.setNickName(res.data.user.nickName);
|
||||||
setStorage("token", res.data.token, 24 * 60 * 30);
|
setStorage("token", res.data.token, 24 * 60 * 30);
|
||||||
|
setStorage("userId", res.data.user.id, 24 * 60 * 30);
|
||||||
if (store.getToken() !== null || store.getUserId() !== null) {
|
if (store.getToken() !== null || store.getUserId() !== null) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate("/main/home");
|
navigate("/main/home");
|
||||||
@@ -154,6 +155,7 @@ export default observer(() => {
|
|||||||
store.setToken(res.data.token);
|
store.setToken(res.data.token);
|
||||||
store.setUserId(res.data.user.id);
|
store.setUserId(res.data.user.id);
|
||||||
setStorage("token", res.data.token, 24 * 60 * 30);
|
setStorage("token", res.data.token, 24 * 60 * 30);
|
||||||
|
setStorage("userId", res.data.user.id, 24 * 60 * 30);
|
||||||
if (store.getToken() !== null || store.getUserId() !== null) {
|
if (store.getToken() !== null || store.getUserId() !== null) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate("/main");
|
navigate("/main");
|
||||||
@@ -217,7 +219,7 @@ export default observer(() => {
|
|||||||
async function wechatLogin() {
|
async function wechatLogin() {
|
||||||
createClientId().then((res: any) => {
|
createClientId().then((res: any) => {
|
||||||
generateQRCode(res.data).then((response: any) => {
|
generateQRCode(res.data).then((response: any) => {
|
||||||
if (response.success) {
|
if (res && response.success && res.data) {
|
||||||
setQRCode(response.data.qrCodeUrl);
|
setQRCode(response.data.qrCodeUrl);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
timerManager.add(() => {
|
timerManager.add(() => {
|
||||||
@@ -289,7 +291,6 @@ export default observer(() => {
|
|||||||
className={styles.mp_code_img}
|
className={styles.mp_code_img}
|
||||||
// src={generateMpRegCodeData.data?.qrCodeUrl}
|
// src={generateMpRegCodeData.data?.qrCodeUrl}
|
||||||
src={QRCode}
|
src={QRCode}
|
||||||
fallback="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMIAAADDCAYAAADQvc6UAAABRWlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGASSSwoyGFhYGDIzSspCnJ3UoiIjFJgf8LAwSDCIMogwMCcmFxc4BgQ4ANUwgCjUcG3awyMIPqyLsis7PPOq3QdDFcvjV3jOD1boQVTPQrgSkktTgbSf4A4LbmgqISBgTEFyFYuLykAsTuAbJEioKOA7DkgdjqEvQHEToKwj4DVhAQ5A9k3gGyB5IxEoBmML4BsnSQk8XQkNtReEOBxcfXxUQg1Mjc0dyHgXNJBSWpFCYh2zi+oLMpMzyhRcASGUqqCZ16yno6CkYGRAQMDKMwhqj/fAIcloxgHQqxAjIHBEugw5sUIsSQpBobtQPdLciLEVJYzMPBHMDBsayhILEqEO4DxG0txmrERhM29nYGBddr//5/DGRjYNRkY/l7////39v///y4Dmn+LgeHANwDrkl1AuO+pmgAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAwqADAAQAAAABAAAAwwAAAAD9b/HnAAAHlklEQVR4Ae3dP3PTWBSGcbGzM6GCKqlIBRV0dHRJFarQ0eUT8LH4BnRU0NHR0UEFVdIlFRV7TzRksomPY8uykTk/zewQfKw/9znv4yvJynLv4uLiV2dBoDiBf4qP3/ARuCRABEFAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghgg0Aj8i0JO4OzsrPv69Wv+hi2qPHr0qNvf39+iI97soRIh4f3z58/u7du3SXX7Xt7Z2enevHmzfQe+oSN2apSAPj09TSrb+XKI/f379+08+A0cNRE2ANkupk+ACNPvkSPcAAEibACyXUyfABGm3yNHuAECRNgAZLuYPgEirKlHu7u7XdyytGwHAd8jjNyng4OD7vnz51dbPT8/7z58+NB9+/bt6jU/TI+AGWHEnrx48eJ/EsSmHzx40L18+fLyzxF3ZVMjEyDCiEDjMYZZS5wiPXnyZFbJaxMhQIQRGzHvWR7XCyOCXsOmiDAi1HmPMMQjDpbpEiDCiL358eNHurW/5SnWdIBbXiDCiA38/Pnzrce2YyZ4//59F3ePLNMl4PbpiL2J0L979+7yDtHDhw8vtzzvdGnEXdvUigSIsCLAWavHp/+qM0BcXMd/q25n1vF57TYBp0a3mUzilePj4+7k5KSLb6gt6ydAhPUzXnoPR0dHl79WGTNCfBnn1uvSCJdegQhLI1vvCk+fPu2ePXt2tZOYEV6/fn31dz+shwAR1sP1cqvLntbEN9MxA9xcYjsxS1jWR4AIa2Ibzx0tc44fYX/16lV6NDFLXH+YL32jwiACRBiEbf5KcXoTIsQSpzXx4N28Ja4BQoK7rgXiydbHjx/P25TaQAJEGAguWy0+2Q8PD6/Ki4R8EVl+bzBOnZY95fq9rj9zAkTI2SxdidBHqG9+skdw43borCXO/ZcJdraPWdv22uIEiLA4q7nvvCug8WTqzQveOH26fodo7g6uFe/a17W3+nFBAkRYENRdb1vkkz1CH9cPsVy/jrhr27PqMYvENYNlHAIesRiBYwRy0V+8iXP8+/fvX11Mr7L7ECueb/r48eMqm7FuI2BGWDEG8cm+7G3NEOfmdcTQw4h9/55lhm7DekRYKQPZF2ArbXTAyu4kDYB2YxUzwg0gi/41ztHnfQG26HbGel/crVrm7tNY+/1btkOEAZ2M05r4FB7r9GbAIdxaZYrHdOsgJ/wCEQY0J74TmOKnbxxT9n3FgGGWWsVdowHtjt9Nnvf7yQM2aZU/TIAIAxrw6dOnAWtZZcoEnBpNuTuObWMEiLAx1HY0ZQJEmHJ3HNvGCBBhY6jtaMoEiJB0Z29vL6ls58vxPcO8/zfrdo5qvKO+d3Fx8Wu8zf1dW4p/cPzLly/dtv9Ts/EbcvGAHhHyfBIhZ6NSiIBTo0LNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiEC/wGgKKC4YMA4TAAAAABJRU5ErkJggg=="
|
|
||||||
/>
|
/>
|
||||||
</Spin>
|
</Spin>
|
||||||
<Alert
|
<Alert
|
||||||
|
@@ -1,400 +1,399 @@
|
|||||||
/** @format */
|
/** @format */
|
||||||
|
|
||||||
import {
|
import {
|
||||||
LockOutlined,
|
LockOutlined,
|
||||||
MobileOutlined,
|
MobileOutlined,
|
||||||
SafetyOutlined,
|
SafetyOutlined,
|
||||||
UserOutlined,
|
UserOutlined,
|
||||||
WechatOutlined,
|
WechatOutlined,
|
||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
import { CaptFieldRef, ProFormCaptcha, ProFormText } from "@ant-design/pro-components";
|
import { CaptFieldRef, ProFormCaptcha, ProFormText } from "@ant-design/pro-components";
|
||||||
import { Alert, Button, ConfigProvider, Form, Image, message, Space, Spin, Tabs } from "antd";
|
import { Alert, Button, ConfigProvider, Form, Image, message, Space, Spin, Tabs } from "antd";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import logo from "@/assets/images/logo.png";
|
import logo from "@/assets/images/logo.png";
|
||||||
// import background from '@/assets/images/background.png'
|
// import background from '@/assets/images/background.png'
|
||||||
import styles from "./index.module.less";
|
import styles from "./index.module.less";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import FooterComponent from "@/components/Footer";
|
import FooterComponent from "@/components/Footer";
|
||||||
import { createClientId, generateQRCode, getClientToken, getSms, register } from "@/api/user";
|
import { createClientId, generateQRCode, getClientToken, getSms, register } from "@/api/user";
|
||||||
import { TinyColor } from "@ctrl/tinycolor";
|
import { TinyColor } from "@ctrl/tinycolor";
|
||||||
import { get, load } from "@/api/captcha";
|
import { get, load } from "@/api/captcha";
|
||||||
import RotateCaptcha, { CaptchaInstance, type TicketInfoType } from "react-rotate-captcha";
|
import RotateCaptcha, { CaptchaInstance, type TicketInfoType } from "react-rotate-captcha";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { setStorage } from "@/utils/localStorage/config.ts";
|
import { setStorage } from "@/utils/localStorage/config.ts";
|
||||||
import useStore from "@/utils/store/useStore.tsx";
|
import useStore from "@/utils/store/useStore.tsx";
|
||||||
import { TimerManager } from "timer-manager-lib";
|
import { TimerManager } from "timer-manager-lib";
|
||||||
// import useStore from '@/utils/store/useStore.tsx'
|
// import useStore from '@/utils/store/useStore.tsx'
|
||||||
type LoginType = "phone";
|
type LoginType = "phone";
|
||||||
|
|
||||||
export default observer(() => {
|
export default observer(() => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const registerCaptcha = useRef<CaptchaInstance>(null);
|
const registerCaptcha = useRef<CaptchaInstance>(null);
|
||||||
const smsCaptcha = useRef<CaptchaInstance>(null);
|
const smsCaptcha = useRef<CaptchaInstance>(null);
|
||||||
const captchaRef = useRef<CaptFieldRef | null | undefined>();
|
const captchaRef = useRef<CaptFieldRef | null | undefined>();
|
||||||
const [QRCode, setQRCode] = useState<string>("");
|
const [QRCode, setQRCode] = useState<string>("");
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const store = useStore("user");
|
const store = useStore("user");
|
||||||
const colors = ["#6253E1", "#04BEFE"];
|
const colors = ["#6253E1", "#04BEFE"];
|
||||||
const timerManager = new TimerManager();
|
const timerManager = new TimerManager();
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
|
||||||
const getHoverColors = (colors: string[]) =>
|
const getHoverColors = (colors: string[]) =>
|
||||||
colors.map((color) => new TinyColor(color).lighten(5).toString());
|
colors.map((color) => new TinyColor(color).lighten(5).toString());
|
||||||
const getActiveColors = (colors: string[]) =>
|
const getActiveColors = (colors: string[]) =>
|
||||||
colors.map((color) => new TinyColor(color).darken(5).toString());
|
colors.map((color) => new TinyColor(color).darken(5).toString());
|
||||||
|
|
||||||
const items = [
|
const items = [
|
||||||
{
|
{
|
||||||
key: "phone",
|
key: "phone",
|
||||||
label: (
|
label: (
|
||||||
<span>
|
<span>
|
||||||
<MobileOutlined />
|
<MobileOutlined />
|
||||||
手机号注册
|
手机号注册
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const [loginType, setLoginType] = useState<LoginType>("phone");
|
const [loginType, setLoginType] = useState<LoginType>("phone");
|
||||||
|
|
||||||
async function smsVerify(token: string, deg: number): Promise<TicketInfoType> {
|
async function smsVerify(token: string, deg: number): Promise<TicketInfoType> {
|
||||||
const phone = form.getFieldValue("phone");
|
const phone = form.getFieldValue("phone");
|
||||||
const data: any = {
|
const data: any = {
|
||||||
token: token,
|
token: token,
|
||||||
deg: deg,
|
deg: deg,
|
||||||
phone: phone,
|
phone: phone,
|
||||||
};
|
};
|
||||||
const res: any = await getSms(data);
|
const res: any = await getSms(data);
|
||||||
if (res && res.code === 0) {
|
if (res && res.code === 0) {
|
||||||
message.open({
|
message.open({
|
||||||
content: res.data,
|
content: res.data,
|
||||||
type: "success",
|
type: "success",
|
||||||
duration: 5,
|
duration: 5,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
message.open({
|
message.open({
|
||||||
content: res.data,
|
content: res.data,
|
||||||
type: "warning",
|
type: "warning",
|
||||||
duration: 5,
|
duration: 5,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function openRegisterCaptcha() {
|
async function openRegisterCaptcha() {
|
||||||
registerCaptcha.current!.open();
|
registerCaptcha.current!.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function openSmsCaptcha() {
|
async function openSmsCaptcha() {
|
||||||
smsCaptcha.current!.open();
|
smsCaptcha.current!.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function registerVerify(token: string, deg: number): Promise<TicketInfoType> {
|
async function registerVerify(token: string, deg: number): Promise<TicketInfoType> {
|
||||||
const userName = form.getFieldValue("username");
|
const userName = form.getFieldValue("username");
|
||||||
const password = form.getFieldValue("password");
|
const password = form.getFieldValue("password");
|
||||||
const phone = form.getFieldValue("phone");
|
const phone = form.getFieldValue("phone");
|
||||||
const activeCode = form.getFieldValue("activeCode");
|
const activeCode = form.getFieldValue("activeCode");
|
||||||
const data: any = {
|
const data: any = {
|
||||||
token: token,
|
token: token,
|
||||||
deg: deg,
|
deg: deg,
|
||||||
userName: userName,
|
userName: userName,
|
||||||
password: password,
|
password: password,
|
||||||
phone: phone,
|
phone: phone,
|
||||||
activeCode: activeCode,
|
activeCode: activeCode,
|
||||||
};
|
};
|
||||||
const res: any = await register(data);
|
const res: any = await register(data);
|
||||||
if (res && res.success && res.code === 0) {
|
if (res && res.success && res.code === 0) {
|
||||||
message
|
message
|
||||||
.open({
|
.open({
|
||||||
content: res.data,
|
content: res.data,
|
||||||
type: "success",
|
type: "success",
|
||||||
duration: 5,
|
duration: 5,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
navigate("/login");
|
navigate("/login");
|
||||||
});
|
});
|
||||||
} else if (res.code === 0 && !res.success) {
|
} else if (res.code === 0 && !res.success) {
|
||||||
message.open({
|
message.open({
|
||||||
content: res.data,
|
content: res.data,
|
||||||
type: "error",
|
type: "error",
|
||||||
duration: 5,
|
duration: 5,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function wechatLogin() {
|
async function wechatLogin() {
|
||||||
createClientId().then((res: any) => {
|
createClientId().then((res: any) => {
|
||||||
generateQRCode(res.data).then((response: any) => {
|
generateQRCode(res.data).then((response: any) => {
|
||||||
if (response.success) {
|
if (res && response.success && res.data) {
|
||||||
setQRCode(response.data.qrCodeUrl);
|
setQRCode(response.data.qrCodeUrl);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
timerManager.add(() => {
|
timerManager.add(() => {
|
||||||
getClientToken(res.data).then((result: any) => {
|
getClientToken(res.data).then((result: any) => {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
timerManager.clear();
|
timerManager.clear();
|
||||||
store.setToken(result.data.tokenValue);
|
store.setToken(result.data.tokenValue);
|
||||||
store.setUserId(result.data.loginId);
|
store.setUserId(result.data.loginId);
|
||||||
setStorage("token", result.data.tokenValue, 24 * 60 * 30);
|
setStorage("token", result.data.tokenValue, 24 * 60 * 30);
|
||||||
setStorage("userId", result.data.loginId, 24 * 60 * 30);
|
setStorage("userId", result.data.loginId, 24 * 60 * 30);
|
||||||
message
|
message
|
||||||
.open({
|
.open({
|
||||||
content: "登录成功!",
|
content: "登录成功!",
|
||||||
type: "success",
|
type: "success",
|
||||||
})
|
})
|
||||||
.then();
|
.then();
|
||||||
if (store.getToken() !== null || store.getUserId() !== null) {
|
if (store.getToken() !== null || store.getUserId() !== null) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate("/main");
|
navigate("/main");
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 3000);
|
}, 3000);
|
||||||
} else {
|
} else {
|
||||||
message
|
message
|
||||||
.open({
|
.open({
|
||||||
content: response.data,
|
content: response.data,
|
||||||
type: "error",
|
type: "error",
|
||||||
})
|
})
|
||||||
.then();
|
.then();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
wechatLogin().then();
|
wechatLogin().then();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<RotateCaptcha get={get} load={load} verify={registerVerify} ref={registerCaptcha} />
|
<RotateCaptcha get={get} load={load} verify={registerVerify} ref={registerCaptcha} />
|
||||||
<RotateCaptcha get={get} load={load} verify={smsVerify} ref={smsCaptcha} />
|
<RotateCaptcha get={get} load={load} verify={smsVerify} ref={smsCaptcha} />
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<Space>
|
<Space>
|
||||||
<Space className={styles.login_content}>
|
<Space className={styles.login_content}>
|
||||||
<Space align="center" className={styles.mp_code}>
|
<Space align="center" className={styles.mp_code}>
|
||||||
<Space direction="vertical" align="center">
|
<Space direction="vertical" align="center">
|
||||||
<span className={styles.mp_code_title}>微信扫码登录</span>
|
<span className={styles.mp_code_title}>微信扫码登录</span>
|
||||||
<Spin tip="Loading" size="large" spinning={loading}>
|
<Spin tip="Loading" size="large" spinning={loading}>
|
||||||
<Image
|
<Image
|
||||||
preview={false}
|
preview={false}
|
||||||
height={200}
|
height={200}
|
||||||
width={200}
|
width={200}
|
||||||
className={styles.mp_code_img}
|
className={styles.mp_code_img}
|
||||||
// src={generateMpRegCodeData.data?.qrCodeUrl}
|
// src={generateMpRegCodeData.data?.qrCodeUrl}
|
||||||
src={QRCode}
|
src={QRCode}
|
||||||
fallback="data:image/png;base64,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"
|
/>
|
||||||
/>
|
</Spin>
|
||||||
</Spin>
|
<Alert
|
||||||
<Alert
|
// message={(<span>微信扫码<span>关注公众号</span></span>)}
|
||||||
// message={(<span>微信扫码<span>关注公众号</span></span>)}
|
description={
|
||||||
description={
|
<div>
|
||||||
<div>
|
<span>
|
||||||
<span>
|
微信扫码
|
||||||
微信扫码
|
<span className={styles.mp_tips}>关注公众号</span>
|
||||||
<span className={styles.mp_tips}>关注公众号</span>
|
</span>
|
||||||
</span>
|
<br />
|
||||||
<br />
|
登录更快更安全
|
||||||
登录更快更安全
|
</div>
|
||||||
</div>
|
}
|
||||||
}
|
// type="success"
|
||||||
// type="success"
|
showIcon={true}
|
||||||
showIcon={true}
|
className={styles.alert}
|
||||||
className={styles.alert}
|
icon={<WechatOutlined />}
|
||||||
icon={<WechatOutlined />}
|
/>
|
||||||
/>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
</Space>
|
<Form
|
||||||
<Form
|
form={form}
|
||||||
form={form}
|
className={styles.login_form}
|
||||||
className={styles.login_form}
|
initialValues={{
|
||||||
initialValues={{
|
autoLogin: true,
|
||||||
autoLogin: true,
|
}}>
|
||||||
}}>
|
<Space direction="vertical" align="center">
|
||||||
<Space direction="vertical" align="center">
|
<Space className={styles.logo}>
|
||||||
<Space className={styles.logo}>
|
<img
|
||||||
<img
|
alt="logo"
|
||||||
alt="logo"
|
src={logo}
|
||||||
src={logo}
|
style={{ width: "44px", height: "44px" }}
|
||||||
style={{ width: "44px", height: "44px" }}
|
/>
|
||||||
/>
|
<span>五味子云存储</span>
|
||||||
<span>五味子云存储</span>
|
</Space>
|
||||||
</Space>
|
<div className={styles.subTitle}>随时随地分享你的美好瞬间</div>
|
||||||
<div className={styles.subTitle}>随时随地分享你的美好瞬间</div>
|
</Space>
|
||||||
</Space>
|
|
||||||
|
<Tabs
|
||||||
<Tabs
|
centered={true}
|
||||||
centered={true}
|
items={items}
|
||||||
items={items}
|
activeKey={loginType}
|
||||||
activeKey={loginType}
|
onChange={(activeKey) =>
|
||||||
onChange={(activeKey) =>
|
setLoginType(activeKey as LoginType)
|
||||||
setLoginType(activeKey as LoginType)
|
}></Tabs>
|
||||||
}></Tabs>
|
|
||||||
|
<>
|
||||||
<>
|
<ProFormText
|
||||||
<ProFormText
|
fieldProps={{
|
||||||
fieldProps={{
|
size: "large",
|
||||||
size: "large",
|
prefix: <UserOutlined className={"prefixIcon"} />,
|
||||||
prefix: <UserOutlined className={"prefixIcon"} />,
|
autoComplete: "off",
|
||||||
autoComplete: "off",
|
}}
|
||||||
}}
|
name="username"
|
||||||
name="username"
|
placeholder="请输入用户名"
|
||||||
placeholder="请输入用户名"
|
rules={[
|
||||||
rules={[
|
{
|
||||||
{
|
required: true,
|
||||||
required: true,
|
message: "请输入用户名!",
|
||||||
message: "请输入用户名!",
|
},
|
||||||
},
|
{
|
||||||
{
|
pattern: /^[a-zA-Z0-9_-]{3,16}$/,
|
||||||
pattern: /^[a-zA-Z0-9_-]{3,16}$/,
|
message:
|
||||||
message:
|
"用户名只能是3到16位(字母,数字,下划线,减号)",
|
||||||
"用户名只能是3到16位(字母,数字,下划线,减号)",
|
},
|
||||||
},
|
]}
|
||||||
]}
|
/>
|
||||||
/>
|
|
||||||
|
<ProFormText
|
||||||
<ProFormText
|
fieldProps={{
|
||||||
fieldProps={{
|
size: "large",
|
||||||
size: "large",
|
prefix: <MobileOutlined className={"prefixIcon"} />,
|
||||||
prefix: <MobileOutlined className={"prefixIcon"} />,
|
autoComplete: "off",
|
||||||
autoComplete: "off",
|
}}
|
||||||
}}
|
name="phone"
|
||||||
name="phone"
|
placeholder="请输入手机号"
|
||||||
placeholder="请输入手机号"
|
rules={[
|
||||||
rules={[
|
{
|
||||||
{
|
required: true,
|
||||||
required: true,
|
message: "请输入手机号!",
|
||||||
message: "请输入手机号!",
|
},
|
||||||
},
|
{
|
||||||
{
|
pattern: /^1\d{10}$/,
|
||||||
pattern: /^1\d{10}$/,
|
message: "手机号格式错误!",
|
||||||
message: "手机号格式错误!",
|
},
|
||||||
},
|
]}
|
||||||
]}
|
/>
|
||||||
/>
|
|
||||||
|
<ProFormCaptcha
|
||||||
<ProFormCaptcha
|
fieldProps={{
|
||||||
fieldProps={{
|
size: "large",
|
||||||
size: "large",
|
prefix: <SafetyOutlined className={"prefixIcon"} />,
|
||||||
prefix: <SafetyOutlined className={"prefixIcon"} />,
|
}}
|
||||||
}}
|
captchaProps={{
|
||||||
captchaProps={{
|
size: "large",
|
||||||
size: "large",
|
}}
|
||||||
}}
|
placeholder={"请输入验证码"}
|
||||||
placeholder={"请输入验证码"}
|
captchaTextRender={(timing: boolean, count: number) => {
|
||||||
captchaTextRender={(timing: boolean, count: number) => {
|
if (timing) {
|
||||||
if (timing) {
|
return `${count} ${"获取验证码"}`;
|
||||||
return `${count} ${"获取验证码"}`;
|
// return `${"获取验证码"}`;
|
||||||
// return `${"获取验证码"}`;
|
}
|
||||||
}
|
return "获取验证码";
|
||||||
return "获取验证码";
|
}}
|
||||||
}}
|
name="activeCode"
|
||||||
name="activeCode"
|
phoneName={"phone"}
|
||||||
phoneName={"phone"}
|
countDown={60}
|
||||||
countDown={60}
|
rules={[
|
||||||
rules={[
|
{
|
||||||
{
|
required: true,
|
||||||
required: true,
|
message: "请输入验证码!",
|
||||||
message: "请输入验证码!",
|
},
|
||||||
},
|
]}
|
||||||
]}
|
fieldRef={captchaRef}
|
||||||
fieldRef={captchaRef}
|
onGetCaptcha={async () => {
|
||||||
onGetCaptcha={async () => {
|
await openSmsCaptcha();
|
||||||
await openSmsCaptcha();
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
|
||||||
|
<ProFormText.Password
|
||||||
<ProFormText.Password
|
name="password"
|
||||||
name="password"
|
fieldProps={{
|
||||||
fieldProps={{
|
size: "large",
|
||||||
size: "large",
|
prefix: <LockOutlined className={"prefixIcon"} />,
|
||||||
prefix: <LockOutlined className={"prefixIcon"} />,
|
}}
|
||||||
}}
|
placeholder="请输入密码"
|
||||||
placeholder="请输入密码"
|
rules={[
|
||||||
rules={[
|
{
|
||||||
{
|
required: true,
|
||||||
required: true,
|
message: "请输入密码!",
|
||||||
message: "请输入密码!",
|
},
|
||||||
},
|
{
|
||||||
{
|
pattern:
|
||||||
pattern:
|
/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z\\W]{6,18}$/,
|
||||||
/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z\\W]{6,18}$/,
|
message:
|
||||||
message:
|
"密码长度需在6~18位字符,且必须包含字母和数字!",
|
||||||
"密码长度需在6~18位字符,且必须包含字母和数字!",
|
},
|
||||||
},
|
]}
|
||||||
]}
|
/>
|
||||||
/>
|
|
||||||
|
<ProFormText.Password
|
||||||
<ProFormText.Password
|
name="confirmPassword"
|
||||||
name="confirmPassword"
|
dependencies={["password"]}
|
||||||
dependencies={["password"]}
|
fieldProps={{
|
||||||
fieldProps={{
|
size: "large",
|
||||||
size: "large",
|
prefix: <LockOutlined className={"prefixIcon"} />,
|
||||||
prefix: <LockOutlined className={"prefixIcon"} />,
|
}}
|
||||||
}}
|
placeholder="请再次确认密码"
|
||||||
placeholder="请再次确认密码"
|
rules={[
|
||||||
rules={[
|
{
|
||||||
{
|
required: true,
|
||||||
required: true,
|
message: "请再次确认密码!",
|
||||||
message: "请再次确认密码!",
|
},
|
||||||
},
|
({ getFieldValue }) => ({
|
||||||
({ getFieldValue }) => ({
|
validator(_, value) {
|
||||||
validator(_, value) {
|
if (!value || getFieldValue("password") === value) {
|
||||||
if (!value || getFieldValue("password") === value) {
|
return Promise.resolve();
|
||||||
return Promise.resolve();
|
}
|
||||||
}
|
return Promise.reject(
|
||||||
return Promise.reject(
|
new Error("两次输入的密码不一致!"),
|
||||||
new Error("两次输入的密码不一致!"),
|
);
|
||||||
);
|
},
|
||||||
},
|
}),
|
||||||
}),
|
]}
|
||||||
]}
|
/>
|
||||||
/>
|
</>
|
||||||
</>
|
<ConfigProvider
|
||||||
<ConfigProvider
|
theme={{
|
||||||
theme={{
|
components: {
|
||||||
components: {
|
Button: {
|
||||||
Button: {
|
colorPrimary: `linear-gradient(90deg, ${colors.join(", ")})`,
|
||||||
colorPrimary: `linear-gradient(90deg, ${colors.join(", ")})`,
|
colorPrimaryHover: `linear-gradient(90deg, ${getHoverColors(colors).join(", ")})`,
|
||||||
colorPrimaryHover: `linear-gradient(90deg, ${getHoverColors(colors).join(", ")})`,
|
colorPrimaryActive: `linear-gradient(90deg, ${getActiveColors(colors).join(", ")})`,
|
||||||
colorPrimaryActive: `linear-gradient(90deg, ${getActiveColors(colors).join(", ")})`,
|
lineWidth: 0,
|
||||||
lineWidth: 0,
|
},
|
||||||
},
|
},
|
||||||
},
|
}}>
|
||||||
}}>
|
<Button
|
||||||
<Button
|
type="primary"
|
||||||
type="primary"
|
block
|
||||||
block
|
size="large"
|
||||||
size="large"
|
onClick={async () => {
|
||||||
onClick={async () => {
|
const validateFields = [
|
||||||
const validateFields = [
|
"phone",
|
||||||
"phone",
|
"username",
|
||||||
"username",
|
"password",
|
||||||
"password",
|
"activeCode",
|
||||||
"activeCode",
|
"confirmPassword",
|
||||||
"confirmPassword",
|
];
|
||||||
];
|
await form
|
||||||
await form
|
.validateFields(validateFields)
|
||||||
.validateFields(validateFields)
|
.then(async () => {
|
||||||
.then(async () => {
|
await openRegisterCaptcha();
|
||||||
await openRegisterCaptcha();
|
})
|
||||||
})
|
.catch((error) => {
|
||||||
.catch((error) => {
|
console.error(error);
|
||||||
console.error(error);
|
});
|
||||||
});
|
}}>
|
||||||
}}>
|
注册
|
||||||
注册
|
</Button>
|
||||||
</Button>
|
</ConfigProvider>
|
||||||
</ConfigProvider>
|
</Form>
|
||||||
</Form>
|
<a href="/login" className={styles.go_to_register}>
|
||||||
<a href="/login" className={styles.go_to_register}>
|
<span>登录</span>
|
||||||
<span>登录</span>
|
</a>
|
||||||
</a>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</div>
|
||||||
</div>
|
<FooterComponent />
|
||||||
<FooterComponent />
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
});
|
||||||
});
|
|
||||||
|
Reference in New Issue
Block a user