feat: 更新我的分享页面

This commit is contained in:
landaiqing
2024-07-20 16:54:08 +08:00
parent 6e8b2ae643
commit 3dacedf7fd
15 changed files with 399 additions and 208 deletions

View File

@@ -73,6 +73,19 @@ export const listComment = (detailId: any) => {
}, },
}); });
}; };
/**
* 分享圈详情热门评论列表
* @param detailId
*/
export const listCommentHot = (detailId: any) => {
return web.request({
url: `/share/share/comment/reply/listcommenthot`,
method: "get",
params: {
detailId: detailId,
},
});
};
/** /**
* 分享圈详情回复列表 * 分享圈详情回复列表
* @param commentId * @param commentId
@@ -115,9 +128,22 @@ export const addReply = (data: any) => {
export const returnAllCommentAndReplyCount = (detailId: any) => { export const returnAllCommentAndReplyCount = (detailId: any) => {
return web.request({ return web.request({
url: `/share/share/comment/reply/returncount`, url: `/share/share/comment/reply/returncount`,
method: "post", method: "get",
params: { params: {
detailId: detailId, detailId: detailId,
}, },
}); });
}; };
/**
* 获取我的分享圈列表
* @param userId
*/
export const getMyShareList = (userId: any) => {
return web.request({
url: `/share/share/detail/mydetail`,
method: "get",
params: {
userId: userId,
},
});
};

View File

@@ -8,7 +8,7 @@ import web from "@/utils/axios/web.ts";
*/ */
export const oauthLogin = (type: string) => { export const oauthLogin = (type: string) => {
return web.request({ return web.request({
url: "/auth/auth/oauth/render/" + type, url: "/auth/oauth/render/" + type,
method: "get", method: "get",
}); });
}; };

View File

@@ -1,17 +1,16 @@
/** @format */ /** @format */
import React, { useEffect, useState } from "react"; import { useState } from "react";
import { Avatar, Card, Flex, Input, message, Progress, Select, Upload } from "antd"; import { Avatar, Card, Flex, Input, message, Select, Upload } from "antd";
import { CloudUploadOutlined } from "@ant-design/icons"; import { CloudUploadOutlined } from "@ant-design/icons";
import { ProCard } from "@ant-design/pro-components"; import { ProCard } from "@ant-design/pro-components";
import StorageIcon from "@/constant/stroage-icon.ts"; import StorageIcon from "@/constant/stroage-icon.ts";
import { getStorageBuckets, uploadFiles } from "@/api/oss"; import { getStorageBuckets, uploadFiles } from "@/api/oss";
import useStore from "@/utils/store/useStore.tsx"; import useStore from "@/utils/store/useStore.tsx";
import axios from "axios";
const { Dragger } = Upload; const { Dragger } = Upload;
const FileUpload: React.FC = (props: any) => { const FileUpload = (props: any) => {
const [buckets, setBuckets] = useState<any[]>([]); const [buckets, setBuckets] = useState<any[]>([]);
const store = useStore("file"); const store = useStore("file");
const [defaultFileList, setDefaultFileList] = useState([]); const [defaultFileList, setDefaultFileList] = useState([]);
@@ -22,12 +21,12 @@ const FileUpload: React.FC = (props: any) => {
} }
}); });
} }
const handleOnChange = ({ fileList }) => { const handleOnChange = ({ fileList }: { fileList: any }) => {
setDefaultFileList(fileList); setDefaultFileList(fileList);
}; };
const uploadFile = async (options) => { const uploadFile = async (options: any) => {
const { onSuccess, onError, file, onProgress } = options; const { onSuccess, onError, file }: { onSuccess: any; onError: any; file: any } = options;
if ( if (
store.getUploadFilePath() === null || store.getUploadFilePath() === null ||
(store.getUploadFileBucket() === null && store.getUploadFileStorage() === null) (store.getUploadFileBucket() === null && store.getUploadFileStorage() === null)

View File

@@ -64,7 +64,7 @@ const File: FunctionComponent = () => {
const [loadingFile, setLoadingFile] = useState<boolean>(true); const [loadingFile, setLoadingFile] = useState<boolean>(true);
const [open, setOpen] = useState<boolean>(false); const [open, setOpen] = useState<boolean>(false);
const [openRename, setOpenRename] = useState<boolean>(false); const [openRename, setOpenRename] = useState<boolean>(false);
const [userStorage, setUserStorage] = useState([]); const [userStorage, setUserStorage] = useState<any>([] as any);
const [buckets, setBuckets] = useState<any[]>([]); const [buckets, setBuckets] = useState<any[]>([]);
const [newFileName, setNewFileName] = useState<any>(null); const [newFileName, setNewFileName] = useState<any>(null);
const [disable, setDisable] = useState<boolean>(true); const [disable, setDisable] = useState<boolean>(true);

View File

@@ -32,7 +32,7 @@ const AliSettings: React.FC = () => {
const [openModal, setOpenModal] = useState(false); const [openModal, setOpenModal] = useState(false);
const [configs, setConfigs] = useState<any>([]); const [configs, setConfigs] = useState<any>([]);
const [loading, setLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
const [configDetail, setConfigDetail] = useState<object>({}); const [configDetail, setConfigDetail] = useState<any>({} as any);
const columns: ProColumns<any[]>[] = [ const columns: ProColumns<any[]>[] = [
{ {
dataIndex: "index", dataIndex: "index",

View File

@@ -32,7 +32,7 @@ const MinioSettings: React.FC = () => {
const [configs, setConfigs] = useState<MinioOssConfigItem[]>([]); const [configs, setConfigs] = useState<MinioOssConfigItem[]>([]);
const [openModal, setOpenModal] = useState(false); const [openModal, setOpenModal] = useState(false);
const [loading, setLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
const [configDetail, setConfigDetail] = useState<object>({}); const [configDetail, setConfigDetail] = useState<any>({} as any);
const columns: ProColumns<MinioOssConfigItem>[] = [ const columns: ProColumns<MinioOssConfigItem>[] = [
{ {
dataIndex: "index", dataIndex: "index",

View File

@@ -32,7 +32,7 @@ const QiniuSettings: React.FC = () => {
const [config, setConfig] = useState<QiniuOssConfigItem[]>([]); const [config, setConfig] = useState<QiniuOssConfigItem[]>([]);
const [openModal, setOpenModal] = useState(false); const [openModal, setOpenModal] = useState(false);
const [loading, setLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
const [configDetail, setConfigDetail] = useState<object>({}); const [configDetail, setConfigDetail] = useState<any>({} as any);
const columns: ProColumns<QiniuOssConfigItem>[] = [ const columns: ProColumns<QiniuOssConfigItem>[] = [
{ {
dataIndex: "index", dataIndex: "index",

View File

@@ -34,7 +34,7 @@ const TencentSettings: React.FC = () => {
const [configs, setConfigs] = useState<TencentOssConfigItem[]>([]); const [configs, setConfigs] = useState<TencentOssConfigItem[]>([]);
const [openModal, setOpenModal] = useState(false); const [openModal, setOpenModal] = useState(false);
const [loading, setLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
const [configDetail, setConfigDetail] = useState<object>({}); const [configDetail, setConfigDetail] = useState<any>({} as any);
const columns: ProColumns<TencentOssConfigItem>[] = [ const columns: ProColumns<TencentOssConfigItem>[] = [
{ {
dataIndex: "index", dataIndex: "index",

View File

@@ -1,33 +1,41 @@
/** @format */ /** @format */
import React, { useEffect, useRef } from "react"; import React, { useEffect, useRef, useState } from "react";
import { AiEditor } from "aieditor"; import { AiEditor } from "aieditor";
import "aieditor/dist/style.css"; import "aieditor/dist/style.css";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import "aieditor/dist/style.css";
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 type { ColorPickerProps } from "antd";
import { import {
Button, Button,
Card, Card,
Col,
ColorPicker,
Divider,
Flex, Flex,
Form, Form,
FormListFieldData, FormListFieldData,
FormProps, FormProps,
Input, Input,
message, message,
Row,
Select, Select,
theme,
} from "antd"; } from "antd";
import { CloseOutlined, LeftOutlined, MinusCircleOutlined, PlusOutlined } from "@ant-design/icons"; import { CloseOutlined, LeftOutlined, MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
import selectOptions from "@/components/Main/Settings/settings.ts"; import selectOptions from "@/components/Main/Settings/settings.ts";
import { addShareDetail } from "@/api/share"; import { addShareDetail } from "@/api/share";
import useStore from "@/utils/store/useStore.tsx"; import useStore from "@/utils/store/useStore.tsx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { cyan, generate, green, presetPalettes, red } from "@ant-design/colors";
type Presets = Required<ColorPickerProps>["presets"][number];
const ShareAdd: React.FunctionComponent = () => { 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();
const [isDisabled, setIsDisabled] = React.useState(false); const [isDisabled, setIsDisabled] = useState(false);
const store = useStore("share"); const store = useStore("share");
const onFinish: FormProps["onFinish"] = (values) => { const onFinish: FormProps["onFinish"] = (values) => {
@@ -36,6 +44,7 @@ const ShareAdd: React.FunctionComponent = () => {
userId: 32, userId: 32,
...values, ...values,
}; };
console.log(formData);
addShareDetail(formData).then((res: any) => { addShareDetail(formData).then((res: any) => {
if (res && res.success) { if (res && res.success) {
message message
@@ -54,6 +63,46 @@ const ShareAdd: React.FunctionComponent = () => {
} }
}); });
}; };
const genPresets = (presets: any = presetPalettes) =>
Object.entries(presets).map<Presets>(([label, colors]: [label: any, colors: any]) => ({
label,
colors,
}));
const HorizontalLayoutDemo = () => {
const { token } = theme.useToken();
const presets = genPresets({
primary: generate(token.colorPrimary),
red,
green,
cyan,
});
const customPanelRender: ColorPickerProps["panelRender"] = (
_,
{ components: { Picker, Presets } },
) => (
<Row justify="space-between" wrap={false}>
<Col span={12}>
<Presets />
</Col>
<Divider type="vertical" style={{ height: "auto" }} />
<Col flex="auto">
<Picker />
</Col>
</Row>
);
return (
<ColorPicker
defaultValue={token.colorPrimary}
styles={{ popupOverlayInner: { width: 480 } }}
presets={presets}
panelRender={customPanelRender}
/>
);
};
useEffect(() => { useEffect(() => {
if (divRef.current) { if (divRef.current) {
const aiEditor = new AiEditor({ const aiEditor = new AiEditor({
@@ -104,7 +153,11 @@ const ShareAdd: React.FunctionComponent = () => {
</Flex> </Flex>
</ProCard> </ProCard>
<div className={styles.share_add_content}> <div className={styles.share_add_content}>
<Form onFinish={onFinish} autoComplete="off" form={form}> <Form
onFinish={onFinish}
autoComplete="off"
form={form}
initialValues={{ color: "#1677ff" }}>
<Form.Item <Form.Item
label={ label={
<> <>
@@ -160,7 +213,7 @@ const ShareAdd: React.FunctionComponent = () => {
if (!tags) { if (!tags) {
return Promise.reject(new Error("请至少填写一个标签")); return Promise.reject(new Error("请至少填写一个标签"));
} }
if (tags.length > 3) { if (tags.length >= 4) {
setIsDisabled(true); setIsDisabled(true);
return Promise.reject( return Promise.reject(
new Error("最多只能添加三个标签"), new Error("最多只能添加三个标签"),
@@ -172,35 +225,49 @@ const ShareAdd: React.FunctionComponent = () => {
{(fields: FormListFieldData[], { add, remove }, { errors }) => ( {(fields: FormListFieldData[], { add, remove }, { errors }) => (
<> <>
{fields.map((field: FormListFieldData, index: number) => ( {fields.map((field: FormListFieldData, index: number) => (
<Form.Item <Flex vertical={false} align={"center"} key={index}>
label={
<>
<h4>{"标签" + (index + 1)}</h4>
</>
}
key={index}
id={"tags"}>
<Form.Item <Form.Item
validateTrigger={["onChange", "onBlur"]} required={true}
name={[field.name, "tagName"] as any} label={
noStyle> <>
<Input <h4>{"标签" + (index + 1)}</h4>
placeholder="请输入标签" </>
maxLength={10} }
showCount key={index}
style={{ width: "20%" }} id={"tags"}>
/> <Flex vertical={false} align={"center"}>
<Form.Item
validateTrigger={["onChange", "onBlur"]}
name={[field.name, "tagName"] as any}
noStyle>
<Input
placeholder="请输入标签"
maxLength={10}
showCount
style={{ width: "250px" }}
/>
</Form.Item>
<Form.Item
validateTrigger={["onChange", "onBlur"]}
name={[field.name, "color"] as any}
noStyle>
<Input
addonBefore={"#"}
style={{ width: 150 }}></Input>
</Form.Item>
<HorizontalLayoutDemo />
{fields.length > 0 ? (
<MinusCircleOutlined
className="dynamic-delete-button"
onClick={() => {
setIsDisabled(false);
remove(field.name);
}}
/>
) : null}
</Flex>
</Form.Item> </Form.Item>
{fields.length > 0 ? ( </Flex>
<MinusCircleOutlined
className="dynamic-delete-button"
onClick={() => {
setIsDisabled(false);
remove(field.name);
}}
/>
) : null}
</Form.Item>
))} ))}
<Form.Item> <Form.Item>
<Button <Button

View File

@@ -16,7 +16,14 @@ import {
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import styles from "./index.module.less"; import styles from "./index.module.less";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { addComment, addReply, listComment, listReply } from "@/api/share"; import {
addComment,
addReply,
listComment,
listCommentHot,
listReply,
returnAllCommentAndReplyCount,
} from "@/api/share";
const Comment = () => { const Comment = () => {
const params = useParams(); const params = useParams();
const [isReply, setIsReply] = useState<any>(null); const [isReply, setIsReply] = useState<any>(null);
@@ -28,16 +35,32 @@ const Comment = () => {
const [commentData, setCommentData] = useState<any>(""); const [commentData, setCommentData] = useState<any>("");
const [replyData, setReplyData] = useState<any>(""); const [replyData, setReplyData] = useState<any>("");
const [replyReplyData, setReplyReplyData] = useState<any>(""); const [replyReplyData, setReplyReplyData] = useState<any>("");
const [count, setCount] = useState<any>(0);
async function listComments() { async function listComments() {
listComment(params.id).then((res: any) => { listComment(params.id).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 getCommentHot() {
listCommentHot(params.id).then((res: any) => {
if (res && res.success && res.data) {
setComment([]);
setComment(res.data);
setLoading(false);
}
});
}
async function getAllCommentAndReply(detailId: any) {
returnAllCommentAndReplyCount(detailId).then((res: any) => {
if (res && res.success && res.data) {
setCount(res.data);
}
});
}
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 && res.data) {
@@ -56,7 +79,6 @@ const Comment = () => {
} }
async function replyComment(commentId: any) { async function replyComment(commentId: any) {
listReply(commentId).then((res: any) => { listReply(commentId).then((res: any) => {
console.log(res);
if (res && res.success && res.data) { if (res && res.success && res.data) {
setReply(res.data); setReply(res.data);
} }
@@ -89,11 +111,12 @@ const Comment = () => {
}; };
useEffect(() => { useEffect(() => {
listComments().then(); listComments().then();
getAllCommentAndReply(params.id).then();
}, []); }, []);
return ( return (
<> <>
<div> <div>
<ProCard title={"评论"}> <ProCard title={"评论 " + count}>
<Skeleton active={true} loading={loading} paragraph={{ rows: 2 }}> <Skeleton active={true} loading={loading} paragraph={{ rows: 2 }}>
<Flex vertical={false}> <Flex vertical={false}>
<Flex vertical={true} justify={"flex-start"}> <Flex vertical={true} justify={"flex-start"}>
@@ -143,16 +166,26 @@ const Comment = () => {
block={false} block={false}
style={{ width: 145 }} style={{ width: 145 }}
size={"middle"} size={"middle"}
defaultValue={"hot"}
onChange={(value: any) => {
if (value === "hot") {
getCommentHot().then();
}
if (value === "new") {
listComments().then();
}
}}
options={[ options={[
{ {
label: "最", label: "最",
value: "List", value: "hot",
icon: <BarsOutlined />, icon: <FireOutlined />,
}, },
{ {
label: "最", label: "最",
value: "Kanban", value: "new",
icon: <FireOutlined />, icon: <BarsOutlined />,
}, },
]} ]}
/> />
@@ -688,7 +721,7 @@ const Comment = () => {
onClick={() => { onClick={() => {
const data: any = const data: any =
{ {
userId: 32, userId: 17,
detailId: detailId:
params.id, params.id,
content: content:

View File

@@ -13,7 +13,6 @@ import {
ShareAltOutlined, ShareAltOutlined,
} from "@ant-design/icons"; } from "@ant-design/icons";
import { shareDetailList } from "@/api/share"; import { shareDetailList } from "@/api/share";
import getRandomColor from "@/constant/random-color.ts";
import useStore from "@/utils/store/useStore.tsx"; import useStore from "@/utils/store/useStore.tsx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
interface DataType { interface DataType {
@@ -41,6 +40,7 @@ export default observer(() => {
async function getShareDetailList() { async function getShareDetailList() {
store.setCircleId(params.id as string); store.setCircleId(params.id as string);
shareDetailList(params.id).then((res: any) => { shareDetailList(params.id).then((res: any) => {
console.log(res);
if (res && res.data && res.data) { if (res && res.data && res.data) {
setData(res.data); setData(res.data);
setLoading(false); setLoading(false);
@@ -108,7 +108,7 @@ export default observer(() => {
key={index}> key={index}>
<Tag <Tag
bordered={false} bordered={false}
color={getRandomColor()} color={"#" + tag.color}
style={{ marginLeft: 10 }}> style={{ marginLeft: 10 }}>
{tag.tagName} {tag.tagName}
</Tag> </Tag>

View File

@@ -0,0 +1,10 @@
.share_list_main{
display: flex;
flex-direction: column;
min-height: 83vh;
.share_list_header{
display: flex;
flex-direction: row;
justify-content: space-between;
}
}

View File

@@ -1,84 +1,96 @@
/** @format */ /** @format */
import { ProCard } from "@ant-design/pro-components"; import { ProCard } from "@ant-design/pro-components";
import { Avatar, Divider, Flex, List, Skeleton, Tag } from "antd"; import { Avatar, Button, 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";
import InfiniteScroll from "react-infinite-scroll-component";
import { useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import { CommentOutlined, EyeOutlined, HeartOutlined } from "@ant-design/icons"; import { CommentOutlined, EyeOutlined, HeartOutlined } from "@ant-design/icons";
import logo from "@/assets/icons/aliyun.svg"; import { getMyShareList } from "@/api/share";
interface DataType {
gender: string;
name: {
title: string;
first: string;
last: string;
};
email: string;
picture: {
large: string;
medium: string;
thumbnail: string;
};
nat: string;
}
export default () => { export default () => {
const navigate = useNavigate(); const navigate = useNavigate();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(true);
const [data, setData] = useState<DataType[]>([]); const [data, setData] = useState<[]>([]);
const loadMoreData = () => { async function getMyShare() {
if (loading) { getMyShareList(32).then((res: any) => {
return; console.log(res);
} if (res && res.success && res.data) {
setLoading(true); setData(res.data);
fetch("https://randomuser.me/api/?results=10&inc=name,gender,email,nat,picture&noinfo")
.then((res) => res.json())
.then((body) => {
setData([...data, ...body.results]);
setLoading(false); setLoading(false);
}) }
.catch(() => { });
setLoading(false); }
});
};
useEffect(() => { useEffect(() => {
loadMoreData(); getMyShare().then();
}, []); }, []);
return ( return (
<> <>
<div className={styles.share_list_main}> <div className={styles.share_list_main}>
<ProCard bordered={true} boxShadow={true}> <ProCard bordered={false} boxShadow={false}>
<InfiniteScroll <div className={styles.share_list_header}>
dataLength={data.length} <Flex
next={loadMoreData} vertical={false}
hasMore={data.length < 50} align={"center"}
loader={<Skeleton avatar paragraph={{ rows: 1 }} active />} justify={"space-between"}
endMessage={<Divider plain>It is all, nothing more 🤐</Divider>} style={{ width: "100%" }}>
scrollableTarget="scrollableDiv"> <div>
<Input
placeholder="搜索"
style={{ borderRadius: 20, width: 500, marginLeft: 20 }}
/>
</div>
<div>
<Button
type={"primary"}
onClick={() => {
navigate("/main/share/add");
}}>
</Button>
</div>
</Flex>
</div>
</ProCard>
<ProCard bordered={false} boxShadow={false}>
<Skeleton loading={loading} active={true} paragraph={{ rows: 14 }}>
<List <List
dataSource={data} dataSource={data}
renderItem={(item) => ( header={
<List.Item key={item.email}> <>
<h4></h4>
</>
}
renderItem={(item: any) => (
<List.Item key={item.id}>
<List.Item.Meta <List.Item.Meta
avatar={<Avatar src={item.picture.large} />} avatar={<Avatar src={item.icon} />}
title={ title={
<> <Flex vertical={false} align={"center"}>
<a <Link to={"/main/share/detail/" + item.id}>
onClick={() => { {item.title}
navigate("/main/share/detail/1"); </Link>
}}> {item.tags &&
{item.name.last} Array.from(item.tags).map(
</a> (tag: any, index: number) => {
<Tag return (
bordered={false} <Flex
color="processing" vertical={false}
style={{ marginLeft: 10 }}> align={"center"}
IDM key={index}>
</Tag> <Tag
</> bordered={false}
color={"#" + tag.color}
style={{ marginLeft: 10 }}>
{tag.tagName}
</Tag>
</Flex>
);
},
)}
</Flex>
} }
description={ description={
<> <>
@@ -86,45 +98,67 @@ export default () => {
vertical={false} vertical={false}
justify={"space-between"} justify={"space-between"}
align={"center"}> align={"center"}>
{item.email} {item.description}
<Flex <Flex
vertical={false} vertical={false}
align={"center"} align={"center"}
justify={"space-between"} justify={"space-between"}
style={{ width: "250px" }}> style={{ width: "300px" }}>
<Avatar src={logo} size={"small"} /> <Flex vertical={false} align={"center"}>
<span <Avatar
style={{ src={item.avatar as any}
fontSize: 12, size={"small"}
color: "gray", />
}}> <span
landaiqing style={{
</span> fontSize: 12,
<HeartOutlined /> color: "gray",
<span overflow: "hidden",
style={{ fontSize: 12, color: "gray" }}> }}>
1024 {item.nickname}
</span> </span>
<CommentOutlined /> </Flex>
<span <Flex vertical={false} align={"center"}>
style={{ fontSize: 12, color: "gray" }}> <HeartOutlined />
1024 <span
</span> style={{
<EyeOutlined style={{ color: "gray" }} />{" "} fontSize: 12,
<span color: "gray",
style={{ fontSize: 12, color: "gray" }}> }}>
1024 {item.likesCount}
</span> </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>
</Flex> </Flex>
</> </>
} }
/> />
{/*<div>Content</div>*/}
</List.Item> </List.Item>
)} )}
/> />
</InfiniteScroll> </Skeleton>
</ProCard> </ProCard>
</div> </div>
</> </>

View File

@@ -2,7 +2,6 @@
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 {
AntDesignOutlined,
BankOutlined, BankOutlined,
BulbOutlined, BulbOutlined,
EnvironmentOutlined, EnvironmentOutlined,
@@ -13,12 +12,13 @@ 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";
const UserInfo: FunctionComponent = () => { const UserInfo: FunctionComponent = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [userStorage, setUserStorage] = useState([]); const [userStorage, setUserStorage] = useState([]);
// const [userInfo, setUserInfo] = useState<any>({} as any); const [userInfo, setUserInfo] = useState<any>({} as any);
const data = [ const data = [
{ {
title: "Ant Design Title 1", title: "Ant Design Title 1",
@@ -40,14 +40,14 @@ const UserInfo: FunctionComponent = () => {
setLoading(false); setLoading(false);
} }
} }
// const getUserInfo = async () => { const getUserInfo = async () => {
// const res = await getUserInfoApi("9"); const res = await getUserInfoApi("17");
// if (res && res.success && res.data) { if (res && res.success && res.data) {
// setUserInfo(res.data); setUserInfo(res.data);
// } }
// }; };
useEffect(() => { useEffect(() => {
// getUserInfo().then(); getUserInfo().then();
getUserStorage().then(); getUserStorage().then();
}, []); }, []);
return ( return (
@@ -56,18 +56,18 @@ const UserInfo: FunctionComponent = () => {
<div className={styles.user_info_header_avatar}> <div className={styles.user_info_header_avatar}>
<Avatar <Avatar
size={{ xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100 }} size={{ xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100 }}
icon={<AntDesignOutlined />} src={userInfo.avatar}
/> />
<span className={styles.user_info_header_name}></span> <span className={styles.user_info_header_name}>{userInfo.nickName}</span>
<div className={styles.user_info_header_desc}> <div className={styles.user_info_header_desc}>
<div> <div>
<BulbOutlined /> <BulbOutlined /> {userInfo.introduce || "-------"}
</div> </div>
<div> <div>
<EnvironmentOutlined /> <EnvironmentOutlined /> {userInfo.location || "-------"}
</div> </div>
<div> <div>
<BankOutlined /> <BankOutlined /> {userInfo.company || "-------"}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,12 +1,9 @@
/** @format */ /** @format */
import { FunctionComponent, useEffect, useState } from "react"; import { FunctionComponent, useEffect, useState } from "react";
import { ProCard, ProForm, ProFormCascader } from "@ant-design/pro-components"; import { ProCard, ProForm, ProFormCascader } from "@ant-design/pro-components";
import { AntDesignOutlined } from "@ant-design/icons";
import { import {
Avatar, Avatar,
Button, Button,
Descriptions,
DescriptionsProps,
Flex, Flex,
Form, Form,
FormProps, FormProps,
@@ -14,42 +11,26 @@ import {
Select, Select,
Skeleton, Skeleton,
Space, Space,
Tabs, Tabs, Tag
} from "antd"; } from "antd";
import styles from "./index.module.less"; import styles from "./index.module.less";
import TextArea from "antd/es/input/TextArea"; import TextArea from "antd/es/input/TextArea";
import { city } from "@/constant/five-level-address.ts"; import { city } from "@/constant/five-level-address.ts";
import { getUserInfoApi } from "@/api/user";
const UserSetting: FunctionComponent = () => { const UserSetting: FunctionComponent = () => {
const [disable, setDisable] = useState(true); const [disable, setDisable] = useState(true);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const items: DescriptionsProps["items"] = [ const [userInfo, setUserInfo] = useState<any>({} as any);
{ async function getUserInfo() {
key: "1", getUserInfoApi("17").then((res: any) => {
label: "用户名", console.log(res);
children: "Zhou Maomao", if (res && res.success && res.data) {
}, setUserInfo(res.data);
{ setLoading(false);
key: "2", }
label: "账号ID", });
children: "1810000000", }
},
{
key: "3",
label: "注册时间",
children: "Hangzhou, Zhejiang",
},
{
key: "4",
label: "邮箱",
children: "landaiqing@126.com",
},
{
key: "5",
label: "手机号",
children: "13333333333333",
},
];
type FieldType = { type FieldType = {
email?: string; email?: string;
nickname?: string; nickname?: string;
@@ -66,7 +47,9 @@ const UserSetting: FunctionComponent = () => {
const onFinishFailed: FormProps<FieldType>["onFinishFailed"] = (errorInfo) => { const onFinishFailed: FormProps<FieldType>["onFinishFailed"] = (errorInfo) => {
console.log("Failed:", errorInfo); console.log("Failed:", errorInfo);
}; };
useEffect(() => {
getUserInfo().then();
}, []);
const prefixSelector = ( const prefixSelector = (
<Form.Item name="prefix" noStyle> <Form.Item name="prefix" noStyle>
<Select style={{ width: 90 }}> <Select style={{ width: 90 }}>
@@ -87,9 +70,6 @@ const UserSetting: FunctionComponent = () => {
); );
}; };
useEffect(() => { useEffect(() => {
setTimeout(() => {
setLoading(false);
}, 2000);
}, []); }, []);
const TabItems = [ const TabItems = [
{ {
@@ -207,16 +187,31 @@ const UserSetting: FunctionComponent = () => {
<Skeleton loading={loading} active> <Skeleton loading={loading} active>
<Space direction={"vertical"} style={{ width: "100%" }}> <Space direction={"vertical"} style={{ width: "100%" }}>
<ProCard hoverable bordered> <ProCard hoverable bordered>
<Flex vertical={false} align={"center"} justify={"space-between"}> <Flex vertical={false} align={"center"}>
<span style={{ width: 80 }}></span> <span style={{width: 100}}></span>
<Input variant="borderless" value={"******************"} /> <Space.Compact style={{ width: '100%' }}>
<Input.Password value={"123456"} variant="borderless"/>
<Button type="text"></Button>
</Space.Compact>
</Flex> </Flex>
</ProCard> </ProCard>
<ProCard hoverable bordered> <ProCard hoverable bordered>
1333333333333333 <Flex vertical={false} align={"center"}>
<span style={{width: 100}}></span>
<Space.Compact style={{ width: '100%' }}>
<Input.Password value={"123456"} variant="borderless"/>
<Button type="text"></Button>
</Space.Compact>
</Flex>
</ProCard> </ProCard>
<ProCard hoverable bordered> <ProCard hoverable bordered>
landaiqing@126.com <Flex vertical={false} align={"center"}>
<span style={{width: 100}}></span>
<Space.Compact style={{ width: '100%' }}>
<Input.Password value={"123456"} variant="borderless"/>
<Button type="text"></Button>
</Space.Compact>
</Flex>
</ProCard> </ProCard>
</Space> </Space>
</Skeleton> </Skeleton>
@@ -233,14 +228,41 @@ const UserSetting: FunctionComponent = () => {
<div className={styles.user_setting_header}> <div className={styles.user_setting_header}>
<Avatar <Avatar
size={{ xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100 }} size={{ xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100 }}
icon={<AntDesignOutlined />} src={userInfo.avatar}
/> />
<Descriptions <Flex vertical={false} align={"center"} style={{ height: "100px",marginLeft: 40 }}>
style={{ width: "80%", marginLeft: "50px" }} <Flex vertical={true} justify={"flex-start"}>
items={items} <Flex vertical={false} align={"center"}>
column={3} <span style={{ color: "grey" }}></span>
size={"small"}></Descriptions> <span style={{width: 130}}>{userInfo.userName}</span>
</Flex>
<Flex vertical={false} align={"center"} style={{marginTop: 20}}>
<span style={{ color: "grey" }}>ID</span>
<span style={{width: 130}}>{userInfo.id}</span>
</Flex>
</Flex>
<Flex vertical={true} style={{marginLeft: 50}}>
<Flex vertical={false} align={"center"}>
<span style={{ color: "grey" }}> </span>
<span style={{width: 130}}>{userInfo.email || "---------"}</span>
</Flex>
<Flex vertical={false} align={"center"} style={{marginTop: 20}}>
<span style={{ color: "grey" }}></span>
<span style={{width: 130}}>{userInfo.phone || "---------"}</span>
</Flex>
</Flex>
<Flex vertical={true} style={{marginLeft: 50}}>
<Flex vertical={false} align={"center"}>
<span style={{ color: "grey" }}></span>
<span style={{width: 130}}>{userInfo.createdTime}</span>
</Flex>
<Flex vertical={false} align={"center"} style={{marginTop: 20}}>
<span style={{ color: "grey" }}> </span>
{userInfo.status===0 ? <Tag color={"success"}></Tag>:<Tag color={"red"}></Tag>}
</Flex>
</Flex>
</Flex>
</div> </div>
</Skeleton> </Skeleton>
</ProCard> </ProCard>