feat: 文件分享update

This commit is contained in:
landaiqing
2024-07-11 14:56:57 +08:00
parent 32dff4adbb
commit b7a16c3c59
13 changed files with 972 additions and 456 deletions

View File

@@ -1,9 +1,10 @@
.settings_container{
height: 75vh;
}
.settings_header{
display: flex;
flex-direction: row;
justify-content: space-between;
}
.settings_container{
width: 100%;
height: 100%;
}
.settings_header{
display: flex;
flex-direction: row;
justify-content: space-between;
}

View File

@@ -55,7 +55,7 @@ export default () => {
</Select>
</div>
</ProCard>
<ProCard style={{ marginTop: 20, height: "60vh" }} bordered boxShadow>
<ProCard style={{ marginTop: 20, height: "100%" }} bordered boxShadow>
{location.pathname === "/main/setting" || location.pathname === "/main/setting/" ? (
<>
<Empty description={"请选择存储商"} />

View File

@@ -0,0 +1,225 @@
/** @format */
import React, { useEffect, useRef } from "react";
import { AiEditor } from "aieditor";
import "aieditor/dist/style.css";
import { useNavigate } from "react-router-dom";
import "aieditor/dist/style.css";
import styles from "./index.module.less";
import { ProCard } from "@ant-design/pro-components";
import { Button, Card, Form, FormListFieldData, FormProps, Input, Select } from "antd";
import { CloseOutlined, LeftOutlined, MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
import selectOptions from "@/components/Main/Settings/settings.ts";
const ShareAdd: React.FunctionComponent = () => {
const navigate = useNavigate();
const divRef = useRef(null);
const fromRef: any = useRef();
const [isDisabled, setIsDisabled] = React.useState(false);
const onFinish: FormProps["onFinish"] = (values) => {
console.log("Success:", values);
};
useEffect(() => {
if (divRef.current) {
const aiEditor = new AiEditor({
element: divRef.current,
placeholder: "点击输入描述...",
contentRetention: true,
textSelectionBubbleMenu: {
enable: true,
items: ["ai", "Bold", "Italic", "Underline", "Strike", "code", "comment"],
},
onChange: async (value) => {
fromRef.current.setFieldsValue({
content: value.getHtml(),
});
},
});
return () => {
aiEditor.destroy();
};
}
}, []);
return (
<>
<div className={styles.share_add_main}>
<ProCard bordered={true}>
<Button
shape="circle"
icon={<LeftOutlined />}
onClick={() => {
navigate("/main/share/list/1");
}}
/>
</ProCard>
<div className={styles.share_add_content}>
<Form onFinish={onFinish} autoComplete="off" ref={fromRef}>
<Form.Item
label={"标题"}
name="title"
id={"title"}
rules={[{ required: true, message: "请输入标题" }]}>
<Input name="title" maxLength={50} showCount></Input>
</Form.Item>
<Form.Item
label={"图标"}
id={"icon"}
name="icon"
rules={[{ required: true, message: "请输入图标" }]}>
<Input name="icon"></Input>
</Form.Item>
<Form.Item
label={"摘要"}
id={"description"}
name="description"
rules={[{ required: true, message: "请输入摘要" }]}>
<Input name="description" maxLength={100} showCount></Input>
</Form.Item>
<Form.Item label={"介绍"} name={"content"} id={"content"}>
<div
ref={divRef}
style={{ height: "300px", maxWidth: "100%", minWidth: "100%" }}
/>
</Form.Item>
<Form.List
name="tags"
rules={[
{
validator: async (_, tags) => {
if (!tags) {
return Promise.reject(new Error("请至少填写一个标签"));
}
if (tags.length >= 3) {
setIsDisabled(true);
return Promise.reject(
new Error("最多只能添加五个标签"),
);
}
},
},
]}>
{(fields: FormListFieldData[], { add, remove }, { errors }) => (
<>
{fields.map((field: FormListFieldData, index: number) => (
<Form.Item
label={"标签" + (index + 1)}
key={index}
id={"tags"}>
<Form.Item
validateTrigger={["onChange", "onBlur"]}
name={[field.name, "tag"]}
noStyle>
<Input
placeholder="请输入标签"
maxLength={10}
showCount
style={{ width: "20%" }}
/>
</Form.Item>
{fields.length > 0 ? (
<MinusCircleOutlined
className="dynamic-delete-button"
onClick={() => {
setIsDisabled(false);
remove(field.name);
}}
/>
) : null}
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
disabled={isDisabled}
onClick={() => add()}
style={{ width: "100%" }}
icon={<PlusOutlined />}>
</Button>
<Form.ErrorList errors={errors} />
</Form.Item>
</>
)}
</Form.List>
<Form.List name="urls">
{(fields: FormListFieldData[], { add, remove }) => (
<div
style={{
display: "flex",
rowGap: 16,
flexDirection: "column",
}}>
{fields.map((field: FormListFieldData, index: number) => (
<Card
size="small"
title={`链接 ${index + 1}`}
key={index}
extra={
<CloseOutlined
onClick={() => {
remove(field.name);
}}
/>
}>
<Form.Item name={[field.name, "type"]} label="分享类型">
<Select
size="middle"
style={{ width: "20%" }}
showSearch={true}
allowClear={true}
notFoundContent={"未找到哦"}
placeholder={"请选择分享类型"}>
{selectOptions.map(
(storage: any, index: any) => {
return (
<Select.Option
value={storage.value}
key={index}>
{storage.name}
</Select.Option>
);
},
)}
</Select>
</Form.Item>
<Form.Item
name={[field.name, "description"]}
label="资源描述">
<Input name={"description"} />
</Form.Item>
<Form.Item name={[field.name, "url"]} label="资源链接">
<Input name={"url"} />
</Form.Item>
<Form.Item
name={[field.name, "password"]}
label={"提取密码"}>
<Input name={"password"} />
</Form.Item>
</Card>
))}
<Button type="dashed" onClick={() => add()} block>
+
</Button>
</div>
)}
</Form.List>
<Form.Item
style={{
display: "flex",
flexDirection: "row",
justifyContent: "flex-end",
marginTop: "2%",
}}>
<Button type="primary" htmlType="submit">
</Button>
</Form.Item>
</Form>
</div>
</div>
</>
);
};
export default ShareAdd;

View File

@@ -0,0 +1,7 @@
.share_add_main{
display: flex;
flex-direction: column;
.share_add_content{
margin-top: 2%;
}
}

View File

@@ -1,43 +1,130 @@
/** @format */
import React, { useEffect, useRef } from "react";
import { Button } from "antd";
import { LeftOutlined } from "@ant-design/icons";
import React from "react";
import { Avatar, Button, Card, Divider, Flex, Tooltip } from "antd";
import {
ExportOutlined,
InfoCircleOutlined,
LeftOutlined,
WarningOutlined,
} from "@ant-design/icons";
import { useNavigate } from "react-router-dom";
import {AiEditor} from "aieditor";
import "aieditor/dist/style.css"
import "aieditor/dist/style.css";
import { ProCard } from "@ant-design/pro-components";
import styles from "./index.module.less";
import logo from "@/assets/icons/baiduyun.svg";
import { Typography } from "antd";
const { Paragraph } = Typography;
const ShareDetail: React.FunctionComponent = () => {
const navigate = useNavigate();
//定义 ref
const divRef = useRef(null);
//初始化 AiEditor
useEffect(() => {
if (divRef.current) {
const aiEditor = new AiEditor({
editable:false,
element: divRef.current,
placeholder: "点击输入内容...",
content: 'AiEditor 是一个面向 AI 的开源富文本编辑器。 ',
})
return ()=>{
aiEditor.destroy();
}
}
}, [])
return (
<>
<Button
shape="circle"
icon={<LeftOutlined />}
onClick={() => {
navigate("/main/share/list/1");
}}
/>
<div>
<div ref={divRef} style={{ height: 550}}>
</div>
<div>
555
<ProCard bordered={true}>
<Button
shape="circle"
icon={<LeftOutlined />}
onClick={() => {
navigate("/main/share/list/1");
}}
/>
</ProCard>
<div className={styles.share_detail_container}>
<ProCard bordered={true}>
<div style={{ height: 500 }}>
</div>
<Card style={{ borderRadius: "10px", borderColor: "#1677FF" }}>
<Flex vertical={false} align={"center"} justify={"space-between"}>
<span
style={{
fontSize: 18,
color: "#1677FF",
fontWeight: "bolder",
}}>
</span>
<Button icon={<WarningOutlined />} type={"primary"}>
</Button>
</Flex>
<Flex
vertical={false}
align={"center"}
style={{ marginTop: 10 }}
justify={"space-between"}>
<span style={{ fontSize: 16 }}>Windows DefenderRemover</span>
</Flex>
<Flex
vertical={false}
align={"center"}
style={{ marginTop: 10 }}
justify={"space-between"}>
<span
style={{
fontSize: 18,
color: "#1677FF",
fontWeight: "bolder",
}}>
</span>
</Flex>
<Flex
vertical={false}
align={"center"}
style={{ marginTop: 10 }}
justify={"space-between"}>
<Card hoverable={true} style={{ width: 280, height: 140 }}>
<Flex vertical={true}>
<Flex
vertical={false}
justify={"space-between"}
align={"center"}>
<div>
<Avatar src={logo}></Avatar>
<span
style={{
marginLeft: 10,
color: "#1677FF",
fontSize: 16,
}}>
</span>
</div>
<ExportOutlined className={styles.link_btn} />
</Flex>
<Divider></Divider>
<Flex vertical={false}>
<Tooltip
title="DefenderRemove111111111"
placement={"bottom"}>
<span style={{ width: 150, overflowX: "hidden" }}>
DefenderRemove111111111
</span>
</Tooltip>
<span
style={{
width: 130,
marginLeft: 10,
display: "flex",
flexDirection: "row",
}}>
<span style={{ color: "#1677FF" }}></span>{" "}
<Paragraph copyable>12345</Paragraph>
</span>
</Flex>
</Flex>
</Card>
</Flex>
<Flex vertical={false} style={{ marginTop: 10 }}>
<span style={{ color: "grey" }}>
<InfoCircleOutlined />
使24
</span>
</Flex>
</Card>
</ProCard>
</div>
</div>
</>

View File

@@ -0,0 +1,10 @@
.share_detail_container{
margin-top: 10px;
}
.link_btn{
font-size: 20px;
color: grey;
}
.link_btn:hover{
color: #1890ff;
}

View File

@@ -1,13 +1,14 @@
/** @format */
import { ProCard } from "@ant-design/pro-components";
import { Avatar, Button, Divider, List, Skeleton } from "antd";
import { Avatar, Button, Divider, Flex, List, Skeleton, Tag } from "antd";
import { useEffect, useState } from "react";
import styles from "./index.module.less";
import Search from "antd/es/input/Search";
import InfiniteScroll from "react-infinite-scroll-component";
import { useNavigate } from "react-router-dom";
import { LeftOutlined } from "@ant-design/icons";
import { CommentOutlined, EyeOutlined, HeartOutlined, LeftOutlined } from "@ant-design/icons";
import logo from "@/assets/icons/aliyun.svg";
interface DataType {
gender: string;
name: {
@@ -23,11 +24,11 @@ interface DataType {
};
nat: string;
}
export default () => {
const navigate = useNavigate();
const [loading, setLoading] = useState(false);
const [data, setData] = useState<DataType[]>([]);
const loadMoreData = () => {
if (loading) {
return;
@@ -63,7 +64,12 @@ export default () => {
<Search placeholder="搜索" style={{ width: 500, marginLeft: 20 }} />
</div>
<Button></Button>
<Button
onClick={() => {
navigate("/main/share/add");
}}>
</Button>
</div>
</ProCard>
<ProCard bordered={true} boxShadow={true} style={{ marginTop: 20 }}>
@@ -81,16 +87,62 @@ export default () => {
<List.Item.Meta
avatar={<Avatar src={item.picture.large} />}
title={
<a
onClick={() => {
navigate("/main/share/detail/1");
}}>
{item.name.last}
</a>
<>
<a
onClick={() => {
navigate("/main/share/detail/1");
}}>
{item.name.last}
</a>
<Tag
bordered={false}
color="processing"
style={{ marginLeft: 10 }}>
IDM
</Tag>
</>
}
description={
<>
<Flex
vertical={false}
justify={"space-between"}
align={"center"}>
{item.email}
<Flex
vertical={false}
align={"center"}
justify={"space-between"}
style={{ width: "250px" }}>
<Avatar src={logo} size={"small"} />
<span
style={{
fontSize: 12,
color: "gray",
}}>
landaiqing
</span>
<HeartOutlined />
<span
style={{ fontSize: 12, color: "gray" }}>
1024
</span>
<CommentOutlined />
<span
style={{ fontSize: 12, color: "gray" }}>
1024
</span>
<EyeOutlined style={{ color: "gray" }} />{" "}
<span
style={{ fontSize: 12, color: "gray" }}>
1024
</span>
</Flex>
</Flex>
</>
}
description={item.email}
/>
<div>Content</div>
{/*<div>Content</div>*/}
</List.Item>
)}
/>

View File

@@ -1,45 +1,154 @@
/** @format */
import { FunctionComponent } from "react";
import { FunctionComponent, useState } from "react";
import { ProCard } from "@ant-design/pro-components";
import styles from "./index.module.less";
import { Button, Card, Image } from "antd";
import { Avatar, Button, Card, Drawer, Flex, Form, Image, Input, Space } from "antd";
import Search from "antd/es/input/Search";
import Meta from "antd/es/card/Meta";
import { useNavigate } from "react-router-dom";
import background from "@/assets/images/background.png";
import TextArea from "antd/es/input/TextArea";
import { EyeOutlined, UnorderedListOutlined } from "@ant-design/icons";
const MainShare: FunctionComponent = () => {
const navigate = useNavigate();
const [open, setOpen] = useState(false);
const showDrawer = () => {
setOpen(true);
};
const onClose = () => {
setOpen(false);
};
return (
<>
<div className={styles.share_main}>
<ProCard bordered={true} boxShadow={false}>
<ProCard bordered={true} boxShadow={true}>
<div className={styles.share_header}>
<Search placeholder="搜索圈子" style={{ width: 500 }} />
<Button></Button>
<Button onClick={showDrawer}></Button>
</div>
</ProCard>
<ProCard bordered={true} boxShadow={false} style={{ marginTop: 20 }}>
<Card
hoverable
style={{ width: 240 }}
onClick={() => {
navigate("/main/share/list/1");
}}
cover={
<Image
alt="example"
src={background}
style={{ height: 200 }}
preview={false}
width={"100%"}
fallback="data:image/png;base64,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"
/>
}>
<Meta title="Europe Street beat" description="www.instagram.com" />
</Card>
<ProCard bordered={true} boxShadow={true} style={{ marginTop: 20 }}>
<Flex vertical={false} align={"center"}>
<Card
hoverable
style={{ width: "250px" }}
onClick={() => {
navigate("/main/share/list/1");
}}
cover={
<Image
alt="example"
src={background}
style={{ height: 200 }}
preview={false}
width={"100%"}
fallback="data:image/png;base64,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"
/>
}>
<Meta title="工具软件分享" description="分享一些常用的办公软件" />
<Flex
vertical={false}
style={{ marginTop: 10 }}
align={"center"}
justify={"space-between"}>
<Avatar src={background} size={"small"} />{" "}
<span style={{ fontSize: 12, color: "gray" }}>landaiqing</span>
<Flex
vertical={false}
align={"center"}
style={{ width: 100 }}
justify={"space-between"}>
<EyeOutlined style={{ color: "gray" }} />{" "}
<span style={{ fontSize: 12, color: "gray" }}>1024</span>
<UnorderedListOutlined style={{ color: "gray" }} />{" "}
<span style={{ fontSize: 12, color: "gray" }}>999</span>
</Flex>
</Flex>
</Card>
<Card
hoverable
style={{ width: "250px", marginLeft: 20 }}
onClick={() => {
navigate("/main/share/list/1");
}}
cover={
<Image
alt="example"
src={background}
style={{ height: 200 }}
preview={false}
width={"100%"}
fallback="data:image/png;base64,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"
/>
}>
<Meta title="工具软件分享" description="分享一些常用的办公软件" />
<Flex
vertical={false}
style={{ marginTop: 10 }}
align={"center"}
justify={"space-between"}>
<Avatar src={background} size={"small"} />{" "}
<span style={{ fontSize: 12, color: "gray" }}>landaiqing</span>
<Flex
vertical={false}
align={"center"}
style={{ width: 100 }}
justify={"space-between"}>
<EyeOutlined style={{ color: "gray" }} />{" "}
<span style={{ fontSize: 12, color: "gray" }}>1024</span>
<UnorderedListOutlined style={{ color: "gray" }} />{" "}
<span style={{ fontSize: 12, color: "gray" }}>999</span>
</Flex>
</Flex>
</Card>
</Flex>
</ProCard>
</div>
<Drawer
title="创建圈子"
width={"40%"}
onClose={onClose}
open={open}
styles={{
body: {
paddingBottom: 80,
},
}}
extra={
<Space>
<Button onClick={onClose}></Button>
<Button onClick={onClose} type="primary">
</Button>
</Space>
}>
<Form layout="vertical">
<Form.Item
name="name"
label="名称"
rules={[{ required: true, message: "请输入圈子名称!" }]}>
<Input maxLength={30} showCount placeholder="请输入圈子名称!" />
</Form.Item>
<Form.Item
name="icon"
label="图标"
rules={[{ required: true, message: "请输入图标!" }]}>
<Input placeholder="请输入图标!" />
</Form.Item>
<Form.Item
name="description"
label="描述"
rules={[{ required: true, message: "请输入描述!" }]}>
<TextArea rows={4} maxLength={50} showCount placeholder="请输入描述!" />
</Form.Item>
</Form>
</Drawer>
</>
);
};

View File

@@ -1,253 +1,257 @@
/** @format */
import { FunctionComponent, useEffect, useState } from "react";
import { ProCard, ProForm, ProFormCascader } from "@ant-design/pro-components";
import { AntDesignOutlined } from "@ant-design/icons";
import {
Avatar,
Button,
Descriptions,
DescriptionsProps,
Form,
FormProps,
Input,
Select,
Skeleton,
Space,
Tabs,
} from "antd";
import styles from "./index.module.less";
import TextArea from "antd/es/input/TextArea";
import { city } from "@/context/five-level-address.ts";
const UserSetting: FunctionComponent = () => {
const [disable, setDisable] = useState(true);
const [loading, setLoading] = useState(true);
const items: DescriptionsProps["items"] = [
{
key: "1",
label: "用户名",
children: "Zhou Maomao",
},
{
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 = {
email?: string;
nickname?: string;
location?: string;
introduce?: string;
gender?: string;
company?: string;
blog?: string;
};
const onFinish: FormProps<FieldType>["onFinish"] = (values) => {
console.log("Success:", values);
};
const onFinishFailed: FormProps<FieldType>["onFinishFailed"] = (errorInfo) => {
console.log("Failed:", errorInfo);
};
const prefixSelector = (
<Form.Item name="prefix" noStyle>
<Select style={{ width: 90 }}>
<Select.Option value="https://">https://</Select.Option>
<Select.Option value="http://">http://</Select.Option>
</Select>
</Form.Item>
);
const ProFormText = (props: any) => {
return (
<ProForm.Item {...props} style={{ height: "10px" }}>
<ProFormCascader
request={async () => city}
width="md"
name="location"
disabled={disable}></ProFormCascader>
</ProForm.Item>
);
};
useEffect(() => {
setTimeout(() => {
setLoading(false);
}, 2000);
}, []);
const TabItems = [
{
label: <span></span>,
key: "baseInfo",
children: (
<>
<Skeleton loading={loading} active>
<div>
<Form
name="basic"
labelCol={{ span: 3 }}
wrapperCol={{ span: 16 }}
style={{ maxWidth: 600 }}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
initialValues={{ prefix: "https://" }}
autoComplete="off">
<Form.Item<FieldType>
label="邮箱"
name="email"
rules={[
{
type: "email",
message: "请输入正确的邮箱!",
},
{ required: true, message: "请输入邮箱!" },
]}>
<Input allowClear disabled={disable} />
</Form.Item>
<Form.Item<FieldType>
label="昵称"
name="nickname"
rules={[
{
type: "string",
message:
"用户名只能是3到16位字母数字下划线减号",
pattern: /^[a-zA-Z0-9_-]{3,16}$/,
},
{
required: true,
message: "请输入昵称!",
},
]}>
<Input allowClear disabled={disable} />
</Form.Item>
<Form.Item<FieldType>
label="性别"
name="gender"
rules={[{ required: true, message: "请输入性别!" }]}>
<Select disabled={disable}>
<Select.Option value="男"></Select.Option>
<Select.Option value=""></Select.Option>
<Select.Option value="UNKNOWN"></Select.Option>
</Select>
</Form.Item>
<Form.Item<FieldType>
label="地区"
name="location"
rules={[{ required: true, message: "请输入地区!" }]}>
<ProFormText />
</Form.Item>
<Form.Item<FieldType> label="公司" name="company">
<Input allowClear disabled={disable} />
</Form.Item>
<Form.Item<FieldType> label="博客" name="blog">
<Input
addonBefore={prefixSelector}
allowClear
disabled={disable}
/>
</Form.Item>
<Form.Item<FieldType> label="个人简介" name="introduce">
<TextArea
rows={4}
allowClear
maxLength={200}
showCount
placeholder="请输入您的个人简介最多不超过200字。"
disabled={disable}
/>
</Form.Item>
<Form.Item wrapperCol={{ offset: 3, span: 16 }}>
<Space
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
width: "400px",
}}>
<Button
htmlType="button"
onClick={() => {
setDisable(!disable);
}}>
</Button>
<Button type="primary" htmlType="submit" disabled={disable}>
</Button>
</Space>
</Form.Item>
</Form>
</div>
</Skeleton>
</>
),
},
{
label: <span></span>,
key: "security",
children: (
<>
<Skeleton loading={loading} active>
<Space direction={"vertical"} style={{ width: "100%" }}>
<ProCard hoverable bordered>
</ProCard>
<ProCard hoverable bordered>
</ProCard>
<ProCard hoverable bordered>
</ProCard>
</Space>
</Skeleton>
</>
),
},
];
return (
<>
<div className={styles.user_setting_main}>
<ProCard boxShadow>
<Skeleton loading={loading} active avatar>
<div className={styles.user_setting_header}>
<Avatar
size={{ xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100 }}
icon={<AntDesignOutlined />}
/>
<Descriptions
style={{ width: "80%", marginLeft: "50px" }}
items={items}
column={3}
size={"small"}></Descriptions>
</div>
</Skeleton>
</ProCard>
<div className={styles.user_setting_content}>
<ProCard boxShadow>
<Tabs type="card" items={TabItems}></Tabs>
</ProCard>
</div>
</div>
</>
);
};
export default UserSetting;
/** @format */
import { FunctionComponent, useEffect, useState } from "react";
import { ProCard, ProForm, ProFormCascader } from "@ant-design/pro-components";
import { AntDesignOutlined } from "@ant-design/icons";
import {
Avatar,
Button,
Descriptions,
DescriptionsProps,
Flex,
Form,
FormProps,
Input,
Select,
Skeleton,
Space,
Tabs,
} from "antd";
import styles from "./index.module.less";
import TextArea from "antd/es/input/TextArea";
import { city } from "@/context/five-level-address.ts";
const UserSetting: FunctionComponent = () => {
const [disable, setDisable] = useState(true);
const [loading, setLoading] = useState(true);
const items: DescriptionsProps["items"] = [
{
key: "1",
label: "用户名",
children: "Zhou Maomao",
},
{
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 = {
email?: string;
nickname?: string;
location?: string;
introduce?: string;
gender?: string;
company?: string;
blog?: string;
};
const onFinish: FormProps<FieldType>["onFinish"] = (values) => {
console.log("Success:", values);
};
const onFinishFailed: FormProps<FieldType>["onFinishFailed"] = (errorInfo) => {
console.log("Failed:", errorInfo);
};
const prefixSelector = (
<Form.Item name="prefix" noStyle>
<Select style={{ width: 90 }}>
<Select.Option value="https://">https://</Select.Option>
<Select.Option value="http://">http://</Select.Option>
</Select>
</Form.Item>
);
const ProFormText = (props: any) => {
return (
<ProForm.Item {...props} style={{ height: "10px" }}>
<ProFormCascader
request={async () => city}
width="md"
name="location"
disabled={disable}></ProFormCascader>
</ProForm.Item>
);
};
useEffect(() => {
setTimeout(() => {
setLoading(false);
}, 2000);
}, []);
const TabItems = [
{
label: <span></span>,
key: "baseInfo",
children: (
<>
<Skeleton loading={loading} active>
<div>
<Form
name="basic"
labelCol={{ span: 3 }}
wrapperCol={{ span: 16 }}
style={{ maxWidth: 600 }}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
initialValues={{ prefix: "https://" }}
autoComplete="off">
<Form.Item<FieldType>
label="邮箱"
name="email"
rules={[
{
type: "email",
message: "请输入正确的邮箱!",
},
{ required: true, message: "请输入邮箱!" },
]}>
<Input allowClear disabled={disable} />
</Form.Item>
<Form.Item<FieldType>
label="昵称"
name="nickname"
rules={[
{
type: "string",
message:
"用户名只能是3到16位字母数字下划线减号",
pattern: /^[a-zA-Z0-9_-]{3,16}$/,
},
{
required: true,
message: "请输入昵称!",
},
]}>
<Input allowClear disabled={disable} />
</Form.Item>
<Form.Item<FieldType>
label="性别"
name="gender"
rules={[{ required: true, message: "请输入性别!" }]}>
<Select disabled={disable}>
<Select.Option value=""></Select.Option>
<Select.Option value=""></Select.Option>
<Select.Option value="UNKNOWN"></Select.Option>
</Select>
</Form.Item>
<Form.Item<FieldType>
label="地区"
name="location"
rules={[{ required: true, message: "请输入地区!" }]}>
<ProFormText />
</Form.Item>
<Form.Item<FieldType> label="公司" name="company">
<Input allowClear disabled={disable} />
</Form.Item>
<Form.Item<FieldType> label="博客" name="blog">
<Input
addonBefore={prefixSelector}
allowClear
disabled={disable}
/>
</Form.Item>
<Form.Item<FieldType> label="个人简介" name="introduce">
<TextArea
rows={4}
allowClear
maxLength={200}
showCount
placeholder="请输入您的个人简介最多不超过200字。"
disabled={disable}
/>
</Form.Item>
<Form.Item wrapperCol={{ offset: 3, span: 16 }}>
<Space
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
width: "400px",
}}>
<Button
htmlType="button"
onClick={() => {
setDisable(!disable);
}}>
</Button>
<Button type="primary" htmlType="submit" disabled={disable}>
</Button>
</Space>
</Form.Item>
</Form>
</div>
</Skeleton>
</>
),
},
{
label: <span></span>,
key: "security",
children: (
<>
<Skeleton loading={loading} active>
<Space direction={"vertical"} style={{ width: "100%" }}>
<ProCard hoverable bordered>
<Flex vertical={false} align={"center"} justify={"space-between"}>
<span style={{ width: 80 }}></span>
<Input variant="borderless" value={"******************"} />
</Flex>
</ProCard>
<ProCard hoverable bordered>
1333333333333333
</ProCard>
<ProCard hoverable bordered>
landaiqing@126.com
</ProCard>
</Space>
</Skeleton>
</>
),
},
];
return (
<>
<div className={styles.user_setting_main}>
<ProCard boxShadow>
<Skeleton loading={loading} active avatar>
<div className={styles.user_setting_header}>
<Avatar
size={{ xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100 }}
icon={<AntDesignOutlined />}
/>
<Descriptions
style={{ width: "80%", marginLeft: "50px" }}
items={items}
column={3}
size={"small"}></Descriptions>
</div>
</Skeleton>
</ProCard>
<div className={styles.user_setting_content}>
<ProCard boxShadow>
<Tabs type="card" items={TabItems}></Tabs>
</ProCard>
</div>
</div>
</>
);
};
export default UserSetting;

View File

@@ -0,0 +1,11 @@
/** @format */
import { lazy } from "react";
const ShareAdd = lazy(
() =>
new Promise((resolve: any) => {
resolve(import("@/components/Main/Share/components/ShareAdd/ShareAdd.tsx"));
}),
);
export default ShareAdd;

View File

@@ -46,6 +46,7 @@ import qiniuBucket from "@/router/modules/main/bucket/createBuckets/qiniu.ts";
import ucloudBucket from "@/router/modules/main/bucket/createBuckets/ucloud.ts";
import upBucket from "@/router/modules/main/bucket/createBuckets/up.ts";
import wangyiBucket from "@/router/modules/main/bucket/createBuckets/wangyi.ts";
import ShareAdd from "@/router/modules/main/share/modules/shareAdd.tsx";
const routes: RouteObject[] = [
{
@@ -163,6 +164,10 @@ const routes: RouteObject[] = [
path: "/main/share/detail/:id",
Component: ShareDetail,
},
{
path: "/main/share/add",
Component: ShareAdd,
},
{
path: "/main/setting",
Component: MainSetting,

View File

@@ -32,14 +32,14 @@ export default function AuthRoute(props: { children: React.ReactNode }) {
return <Navigate to="/404" />;
}
// if (!isLogin) {
// message
// .open({
// content: "请先登录!",
// type: "warning",
// })
// .then();
// return <Navigate to="/login" />;
// }
if (!isLogin) {
message
.open({
content: "请先登录!",
type: "warning",
})
.then();
return <Navigate to="/login" />;
}
return props.children;
}

View File

@@ -1,117 +1,122 @@
/** @format */
import {
GithubFilled,
InfoCircleFilled,
LogoutOutlined,
QuestionCircleFilled,
} from "@ant-design/icons";
import { DefaultFooter, PageContainer, ProCard, ProLayout } from "@ant-design/pro-components";
import settings from "./settings.tsx";
import { Link, Outlet, useLocation } from "react-router-dom";
import logo from "@/assets/images/logo.png";
import { Suspense } from "react";
import { Dropdown } from "antd";
// import { getUserMenuPermission } from "@/api/user";
export default function Layout() {
const location = useLocation();
return (
<div
id="test-pro-layout"
style={{
height: "100vh",
}}>
<ProLayout
logo={logo}
layout={"mix"}
pure={false}
loading={false}
contentWidth={"Fluid"}
title={"五味子云存储"}
siderWidth={216}
menuItemRender={(menuItemProps, defaultDom) => {
if (menuItemProps.isUrl || !menuItemProps.path) {
return defaultDom;
}
return <Link to={menuItemProps.path}>{defaultDom}</Link>;
}}
{...settings}
menu={{
// request: async () => {
// const res: any = await getUserMenuPermission("17");
// return res.data.routes;
// },
type: "group",
defaultOpenAll: false,
hideMenuWhenCollapsed: false,
collapsedShowTitle: false,
}}
disableMobile={false}
location={{
pathname: location.pathname,
}}
avatarProps={{
src: "https://gw.alipayobjects.com/zos/antfincdn/efFD%24IOql2/weixintupian_20170331104822.jpg",
title: "七妮妮",
size: "large",
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
render: (props, dom) => {
return (
<Dropdown
menu={{
items: [
{
key: "logout",
icon: <LogoutOutlined />,
label: "退出登录",
},
],
}}>
{dom}
</Dropdown>
);
},
}}
actionsRender={(props: any) => {
// eslint-disable-next-line react/prop-types
if (props.isMobile) return [];
return [
<InfoCircleFilled key="InfoCircleFilled" />,
<QuestionCircleFilled key="QuestionCircleFilled" />,
<GithubFilled key="GithubFilled" />,
];
}}
breadcrumbRender={(routers = []) => [
{
path: "/main/home",
title: "主页",
},
...routers,
]}
footerRender={() => (
<DefaultFooter
links={[
{
key: "schisandra",
title: "schisandra",
href: "https://landaiqing.cn",
},
]}
copyright="2024"
/>
)}>
<PageContainer title={false}>
<ProCard>
<div>
<Suspense>
<Outlet />
</Suspense>
</div>
</ProCard>
</PageContainer>
</ProLayout>
</div>
);
}
/** @format */
import {
GithubFilled,
InfoCircleFilled,
LogoutOutlined,
QuestionCircleFilled,
} from "@ant-design/icons";
import {
DefaultFooter,
PageContainer,
ProCard,
ProLayout,
} from "@ant-design/pro-components";
import { Link, Outlet, useLocation } from "react-router-dom";
import logo from "@/assets/images/logo.png";
import { Suspense } from "react";
import { Dropdown } from "antd";
import settings from "@/views/Main/settings.tsx";
// import { getUserMenuPermission } from "@/api/user";
export default function Layout() {
const location = useLocation();
return (
<div
id="pro-layout"
style={{
height: "100vh",
}}>
<ProLayout
logo={logo}
layout={"mix"}
pure={false}
loading={false}
contentWidth={"Fluid"}
title={"五味子云存储"}
siderWidth={216}
menuItemRender={(menuItemProps, defaultDom) => {
if (menuItemProps.isUrl || !menuItemProps.path) {
return defaultDom;
}
return <Link to={menuItemProps.path}>{defaultDom}</Link>;
}}
{...settings}
menu={{
// request: async () => {
// const res: any = await getUserMenuPermission("17");
// return res.data.routes;
// },
type: "group",
defaultOpenAll: false,
hideMenuWhenCollapsed: false,
collapsedShowTitle: false,
}}
disableMobile={false}
location={{
pathname: location.pathname,
}}
avatarProps={{
src: "https://gw.alipayobjects.com/zos/antfincdn/efFD%24IOql2/weixintupian_20170331104822.jpg",
title: "七妮妮",
size: "large",
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
render: (props, dom) => {
return (
<Dropdown
menu={{
items: [
{
key: "logout",
icon: <LogoutOutlined />,
label: "退出登录",
},
],
}}>
{dom}
</Dropdown>
);
},
}}
actionsRender={(props: any) => {
// eslint-disable-next-line react/prop-types
if (props.isMobile) return [];
return [
<InfoCircleFilled key="InfoCircleFilled" />,
<QuestionCircleFilled key="QuestionCircleFilled" />,
<GithubFilled key="GithubFilled" />,
];
}}
breadcrumbRender={(routers = []) => [
{
path: "/main/home",
title: "主页",
},
...routers,
]}
footerRender={() => (
<DefaultFooter
links={[
{
key: "schisandra",
title: "schisandra",
href: "https://landaiqing.cn",
},
]}
copyright="2024"
/>
)}>
<PageContainer title={false}>
<ProCard>
<div>
<Suspense>
<Outlet />
</Suspense>
</div>
</ProCard>
</PageContainer>
</ProLayout>
</div>
);
}