大改动
This commit is contained in:
@@ -12,7 +12,7 @@ import axios from 'axios';
|
|||||||
const FootprintPage = () => {
|
const FootprintPage = () => {
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [btnLoading, setBtnLoading] = useState(false)
|
const [btnLoading, setBtnLoading] = useState(false)
|
||||||
const [modalLoading, setModalLoading] = useState(false)
|
const [editLoading, setEditLoading] = useState(false)
|
||||||
|
|
||||||
const [footprintList, setFootprintList] = useState<Footprint[]>([]);
|
const [footprintList, setFootprintList] = useState<Footprint[]>([]);
|
||||||
const [isModelOpen, setIsModelOpen] = useState(false);
|
const [isModelOpen, setIsModelOpen] = useState(false);
|
||||||
@@ -129,7 +129,7 @@ const FootprintPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const editFootprintData = async (id: number) => {
|
const editFootprintData = async (id: number) => {
|
||||||
setModalLoading(true);
|
setEditLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setIsMethod("edit");
|
setIsMethod("edit");
|
||||||
@@ -143,10 +143,10 @@ const FootprintPage = () => {
|
|||||||
setFootprint(data);
|
setFootprint(data);
|
||||||
form.setFieldsValue(data);
|
form.setFieldsValue(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setModalLoading(false);
|
setEditLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
setModalLoading(false);
|
setEditLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
@@ -196,7 +196,7 @@ const FootprintPage = () => {
|
|||||||
|
|
||||||
// 通过详细地址获取纬度
|
// 通过详细地址获取纬度
|
||||||
const getGeocode = async () => {
|
const getGeocode = async () => {
|
||||||
setModalLoading(true)
|
setEditLoading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const address = form.getFieldValue("address")
|
const address = form.getFieldValue("address")
|
||||||
@@ -215,14 +215,14 @@ const FootprintPage = () => {
|
|||||||
// 立即触发校验
|
// 立即触发校验
|
||||||
form.validateFields(['position']);
|
form.validateFields(['position']);
|
||||||
|
|
||||||
setModalLoading(false)
|
setEditLoading(false)
|
||||||
|
|
||||||
return data.geocodes[0].location;
|
return data.geocodes[0].location;
|
||||||
} else {
|
} else {
|
||||||
message.warning('未找到该地址的经纬度');
|
message.warning('未找到该地址的经纬度');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setModalLoading(false)
|
setEditLoading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -266,7 +266,7 @@ const FootprintPage = () => {
|
|||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Modal loading={modalLoading} title={isMethod === "edit" ? "编辑足迹" : "新增足迹"} open={isModelOpen} onCancel={closeModel} destroyOnClose footer={null}>
|
<Modal loading={editLoading} title={isMethod === "edit" ? "编辑足迹" : "新增足迹"} open={isModelOpen} onCancel={closeModel} destroyOnClose footer={null}>
|
||||||
<Form form={form} layout="vertical" initialValues={footprint} size='large' preserve={false} className='mt-6'>
|
<Form form={form} layout="vertical" initialValues={footprint} size='large' preserve={false} className='mt-6'>
|
||||||
<Form.Item label="标题" name="title" rules={[{ required: true, message: '标题不能为空' }]}>
|
<Form.Item label="标题" name="title" rules={[{ required: true, message: '标题不能为空' }]}>
|
||||||
<Input placeholder="请输入标题" />
|
<Input placeholder="请输入标题" />
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { titleSty } from '@/styles/sty';
|
|||||||
const StoragePage = () => {
|
const StoragePage = () => {
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [btnLoading, setBtnLoading] = useState(false);
|
const [btnLoading, setBtnLoading] = useState(false);
|
||||||
const [modalLoading, setModalLoading] = useState(false)
|
const [editLoading, setEditLoading] = useState(false)
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
|
||||||
const [oss, setOss] = useState<Oss>({} as Oss);
|
const [oss, setOss] = useState<Oss>({} as Oss);
|
||||||
@@ -122,7 +122,7 @@ const StoragePage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const editOssData = async (record: Oss) => {
|
const editOssData = async (record: Oss) => {
|
||||||
setModalLoading(true)
|
setEditLoading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setIsModalOpen(true);
|
setIsModalOpen(true);
|
||||||
@@ -131,10 +131,10 @@ const StoragePage = () => {
|
|||||||
setOss(data);
|
setOss(data);
|
||||||
form.setFieldsValue(data);
|
form.setFieldsValue(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setModalLoading(false)
|
setEditLoading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
setModalLoading(false)
|
setEditLoading(false)
|
||||||
};
|
};
|
||||||
|
|
||||||
const delOssData = async (id: number) => {
|
const delOssData = async (id: number) => {
|
||||||
@@ -207,7 +207,7 @@ const StoragePage = () => {
|
|||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
loading={modalLoading}
|
loading={editLoading}
|
||||||
title={oss.id ? "编辑存储配置" : "新增存储配置"}
|
title={oss.id ? "编辑存储配置" : "新增存储配置"}
|
||||||
open={isModalOpen}
|
open={isModalOpen}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -15,34 +15,39 @@ export interface FilterForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const RecordPage = () => {
|
const RecordPage = () => {
|
||||||
const [current, setCurrent] = useState<number>(1);
|
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [recordList, setRecordList] = useState<Record[]>([]);
|
|
||||||
|
|
||||||
|
const [recordList, setRecordList] = useState<Record[]>([]);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const { RangePicker } = DatePicker;
|
const { RangePicker } = DatePicker;
|
||||||
|
|
||||||
const getRecordList = async () => {
|
const getRecordList = async () => {
|
||||||
setLoading(true);
|
try {
|
||||||
const { data } = await getRecordListAPI();
|
const { data } = await getRecordListAPI();
|
||||||
setRecordList(data as Record[]);
|
setRecordList(data as Record[]);
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
getRecordList()
|
getRecordList()
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const delRecordData = async (id: number) => {
|
const delRecordData = async (id: number) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
await delRecordDataAPI(id);
|
try {
|
||||||
await getRecordList();
|
await delRecordDataAPI(id);
|
||||||
form.resetFields()
|
await getRecordList();
|
||||||
setCurrent(1)
|
form.resetFields()
|
||||||
notification.success({ message: '🎉 删除说说成功' })
|
notification.success({ message: '🎉 删除说说成功' })
|
||||||
|
} catch (error) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
@@ -110,15 +115,23 @@ const RecordPage = () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const onSubmit = async (values: FilterForm) => {
|
const onFilterSubmit = async (values: FilterForm) => {
|
||||||
const query = {
|
setLoading(true);
|
||||||
key: values.content,
|
|
||||||
startDate: values.createTime && values.createTime[0].valueOf() + '',
|
try {
|
||||||
endDate: values.createTime && values.createTime[1].valueOf() + ''
|
const query = {
|
||||||
|
key: values.content,
|
||||||
|
startDate: values.createTime && values.createTime[0].valueOf() + '',
|
||||||
|
endDate: values.createTime && values.createTime[1].valueOf() + ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data } = await getRecordListAPI({ query });
|
||||||
|
setRecordList(data as Record[]);
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data } = await getRecordListAPI({ query });
|
setLoading(false);
|
||||||
setRecordList(data as Record[]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -126,7 +139,7 @@ const RecordPage = () => {
|
|||||||
<Title value="说说管理" />
|
<Title value="说说管理" />
|
||||||
|
|
||||||
<Card className='my-2 overflow-scroll'>
|
<Card className='my-2 overflow-scroll'>
|
||||||
<Form form={form} layout="inline" onFinish={onSubmit} autoComplete="off" className='flex-nowrap'>
|
<Form form={form} layout="inline" onFinish={onFilterSubmit} autoComplete="off" className='flex-nowrap'>
|
||||||
<Form.Item label="内容" name="content" className='min-w-[200px]'>
|
<Form.Item label="内容" name="content" className='min-w-[200px]'>
|
||||||
<Input placeholder='请输入关键词' />
|
<Input placeholder='请输入关键词' />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -150,11 +163,7 @@ const RecordPage = () => {
|
|||||||
scroll={{ x: 'max-content' }}
|
scroll={{ x: 'max-content' }}
|
||||||
pagination={{
|
pagination={{
|
||||||
position: ['bottomCenter'],
|
position: ['bottomCenter'],
|
||||||
current,
|
|
||||||
defaultPageSize: 8,
|
defaultPageSize: 8,
|
||||||
onChange(current) {
|
|
||||||
setCurrent(current)
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Table, Button, Form, Input, Popconfirm, message, Card, Modal, Transfer, Spin } from 'antd';
|
import { Table, Button, Form, Input, Popconfirm, message, Card, Modal, Transfer, Spin } from 'antd';
|
||||||
import { getRouteListAPI } from '@/api/Route';
|
import { getRouteListAPI } from '@/api/Route';
|
||||||
import { getRoleListAPI, addRoleDataAPI, editRoleDataAPI, delRoleDataAPI, getRouteListAPI as getRoleRouteListAPI, bindingRouteAPI } from '@/api/Role';
|
import { getRoleListAPI, addRoleDataAPI, editRoleDataAPI, delRoleDataAPI, getRouteListAPI as getRoleRouteListAPI, bindingRouteAPI, getRoleDataAPI } from '@/api/Role';
|
||||||
import { Role } from '@/types/app/role';
|
import { Role } from '@/types/app/role';
|
||||||
import Title from '@/components/Title';
|
import Title from '@/components/Title';
|
||||||
import { ColumnsType } from 'antd/es/table';
|
import { ColumnsType } from 'antd/es/table';
|
||||||
@@ -9,8 +9,11 @@ import "./index.scss"
|
|||||||
|
|
||||||
const RolePage = () => {
|
const RolePage = () => {
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
|
const [btnLoading, setBtnLoading] = useState(false)
|
||||||
|
const [editLoading, setEditLoading] = useState<boolean>(false);
|
||||||
const [bindingLoading, setBindingLoading] = useState<boolean>(false);
|
const [bindingLoading, setBindingLoading] = useState<boolean>(false);
|
||||||
const [addLoading, setAddLoading] = useState(false)
|
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
const [id, setId] = useState(0)
|
const [id, setId] = useState(0)
|
||||||
const [role, setRole] = useState<Role>({} as Role);
|
const [role, setRole] = useState<Role>({} as Role);
|
||||||
@@ -44,7 +47,6 @@ const RolePage = () => {
|
|||||||
// 获取指定角色的路由列表
|
// 获取指定角色的路由列表
|
||||||
const getRoleRouteList = async (id: number) => {
|
const getRoleRouteList = async (id: number) => {
|
||||||
const { data } = await getRoleRouteListAPI(id);
|
const { data } = await getRoleRouteListAPI(id);
|
||||||
|
|
||||||
setTargetKeys(data.map(item => item.id) as number[])
|
setTargetKeys(data.map(item => item.id) as number[])
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -56,75 +58,95 @@ const RolePage = () => {
|
|||||||
|
|
||||||
// 获取角色列表
|
// 获取角色列表
|
||||||
const getRoleList = async () => {
|
const getRoleList = async () => {
|
||||||
setLoading(true);
|
try {
|
||||||
const { data } = await getRoleListAPI();
|
const { data } = await getRoleListAPI();
|
||||||
setRoleList(data as Role[]);
|
setRoleList(data as Role[]);
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
getRoleList()
|
getRoleList()
|
||||||
getRouteList()
|
getRouteList()
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// 绑定路由
|
||||||
const [form] = Form.useForm();
|
|
||||||
|
|
||||||
const bindingRoute = (record: Role) => {
|
const bindingRoute = (record: Role) => {
|
||||||
setIsModalOpen(true)
|
setIsModalOpen(true)
|
||||||
getRoleRouteList(record.id)
|
getRoleRouteList(record.id)
|
||||||
setId(record.id)
|
setId(record.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const editRoleData = (record: Role) => {
|
const editRoleData = async (record: Role) => {
|
||||||
setRole(record);
|
setEditLoading(true);
|
||||||
form.setFieldsValue(record);
|
|
||||||
|
try {
|
||||||
|
const { data } = await getRoleDataAPI(record.id);
|
||||||
|
setRole(data);
|
||||||
|
form.setFieldsValue(data);
|
||||||
|
} catch (error) {
|
||||||
|
setEditLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
setEditLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const delRoleData = async (id: number) => {
|
const delRoleData = async (id: number) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
await delRoleDataAPI(id);
|
|
||||||
message.success('🎉 删除角色成功');
|
try {
|
||||||
getRoleList();
|
await delRoleDataAPI(id);
|
||||||
|
await getRoleList();
|
||||||
|
message.success('🎉 删除角色成功');
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
setLoading(true);
|
setBtnLoading(true)
|
||||||
setAddLoading(true)
|
|
||||||
|
|
||||||
form.validateFields().then(async (values: Role) => {
|
try {
|
||||||
if (role.id) {
|
form.validateFields().then(async (values: Role) => {
|
||||||
await editRoleDataAPI({ ...role, ...values });
|
if (role.id) {
|
||||||
message.success('🎉 编辑角色成功');
|
await editRoleDataAPI({ ...role, ...values });
|
||||||
} else {
|
message.success('🎉 编辑角色成功');
|
||||||
await addRoleDataAPI(values);
|
} else {
|
||||||
message.success('🎉 新增角色成功');
|
await addRoleDataAPI(values);
|
||||||
}
|
message.success('🎉 新增角色成功');
|
||||||
|
}
|
||||||
|
|
||||||
getRoleList();
|
await getRoleList();
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
form.setFieldsValue({ name: '', description: '' })
|
form.setFieldsValue({ name: '', description: '' })
|
||||||
setRole({} as Role);
|
setRole({} as Role);
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setBtnLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
setAddLoading(false)
|
setBtnLoading(false)
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChange: any = (list: number[]) => {
|
// 设置目标路由
|
||||||
setTargetKeys(list);
|
const onChange: any = (list: number[]) => setTargetKeys(list);
|
||||||
};
|
|
||||||
|
|
||||||
// 绑定路由
|
// 绑定路由
|
||||||
const onBindingRouteSubmit = async () => {
|
const onBindingRouteSubmit = async () => {
|
||||||
setBindingLoading(true);
|
setBindingLoading(true);
|
||||||
await bindingRouteAPI(id, targetKeys)
|
|
||||||
setBindingLoading(false)
|
|
||||||
|
|
||||||
message.success('🎉 绑定成功');
|
try {
|
||||||
setIsModalOpen(false)
|
await bindingRouteAPI(id, targetKeys)
|
||||||
|
message.success('🎉 绑定成功');
|
||||||
// 刷新页面
|
// 刷新页面
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
|
} catch (error) {
|
||||||
|
setBindingLoading(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 让n改变 触发Transfer重新渲染
|
// 让n改变 触发Transfer重新渲染
|
||||||
@@ -157,7 +179,7 @@ const RolePage = () => {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Button type="primary" htmlType="submit" loading={addLoading} className="w-full">{role.id ? '编辑角色' : '新增角色'}</Button>
|
<Button type="primary" htmlType="submit" loading={btnLoading} className="w-full">{role.id ? '编辑角色' : '新增角色'}</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -177,7 +199,7 @@ const RolePage = () => {
|
|||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Modal title="角色权限" open={isModalOpen} onCancel={() => [setIsModalOpen(false), setN(n + 1)]} footer={null} className='RolePageModal'>
|
<Modal loading={editLoading} title="角色权限" open={isModalOpen} onCancel={() => [setIsModalOpen(false), setN(n + 1)]} footer={null} className='RolePageModal'>
|
||||||
<div className='flex justify-center py-6'>
|
<div className='flex justify-center py-6'>
|
||||||
<Spin spinning={bindingLoading}>
|
<Spin spinning={bindingLoading}>
|
||||||
<Transfer
|
<Transfer
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Table, Button, Form, Input, Popconfirm, message, Card } from 'antd';
|
import { Table, Button, Form, Input, Popconfirm, message, Card } from 'antd';
|
||||||
import { getRouteListAPI, addRouteDataAPI, editRouteDataAPI, delRouteDataAPI } from '@/api/Route';
|
import { getRouteListAPI, addRouteDataAPI, editRouteDataAPI, delRouteDataAPI, getRouteDataAPI } from '@/api/Route';
|
||||||
import { Route } from '@/types/app/route';
|
import { Route } from '@/types/app/route';
|
||||||
import Title from '@/components/Title';
|
import Title from '@/components/Title';
|
||||||
import { ColumnsType } from 'antd/es/table';
|
import { ColumnsType } from 'antd/es/table';
|
||||||
@@ -9,6 +9,8 @@ const RoutePage = () => {
|
|||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [btnLoading, setBtnLoading] = useState(false)
|
const [btnLoading, setBtnLoading] = useState(false)
|
||||||
|
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
const [route, setRoute] = useState<Route>({} as Route);
|
const [route, setRoute] = useState<Route>({} as Route);
|
||||||
const [list, setList] = useState<Route[]>([]);
|
const [list, setList] = useState<Route[]>([]);
|
||||||
|
|
||||||
@@ -30,50 +32,73 @@ const RoutePage = () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const getRouteList = async () => {
|
const getRouteList = async () => {
|
||||||
setLoading(true);
|
try {
|
||||||
const { data } = await getRouteListAPI();
|
const { data } = await getRouteListAPI();
|
||||||
setList(data as Route[]);
|
setList(data);
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
getRouteList();
|
getRouteList();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [form] = Form.useForm();
|
const editRouteData = async (record: Route) => {
|
||||||
const editRouteData = (record: Route) => {
|
setLoading(true)
|
||||||
setRoute(record);
|
|
||||||
form.setFieldsValue(record);
|
try {
|
||||||
|
const { data } = await getRouteDataAPI(record.id);
|
||||||
|
setRoute(data);
|
||||||
|
form.setFieldsValue(data);
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoading(false)
|
||||||
};
|
};
|
||||||
|
|
||||||
const delRouteData = async (id: number) => {
|
const delRouteData = async (id: number) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
await delRouteDataAPI(id);
|
|
||||||
message.success('🎉 删除路由成功');
|
try {
|
||||||
getRouteList();
|
await delRouteDataAPI(id);
|
||||||
|
await getRouteList();
|
||||||
|
message.success('🎉 删除路由成功');
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setBtnLoading(true)
|
setBtnLoading(true)
|
||||||
|
|
||||||
form.validateFields().then(async (values: Route) => {
|
try {
|
||||||
|
form.validateFields().then(async (values: Route) => {
|
||||||
|
if (route.id) {
|
||||||
|
await editRouteDataAPI({ ...route, ...values });
|
||||||
|
message.success('🎉 编辑路由成功');
|
||||||
|
} else {
|
||||||
|
await addRouteDataAPI(values);
|
||||||
|
message.success('🎉 新增路由成功');
|
||||||
|
}
|
||||||
|
|
||||||
if (route.id) {
|
await getRouteList();
|
||||||
await editRouteDataAPI({ ...route, ...values });
|
form.resetFields();
|
||||||
message.success('🎉 编辑路由成功');
|
form.setFieldsValue({ path: '', description: '' })
|
||||||
} else {
|
setRoute({} as Route);
|
||||||
await addRouteDataAPI(values);
|
});
|
||||||
message.success('🎉 新增路由成功');
|
} catch (error) {
|
||||||
}
|
setLoading(false)
|
||||||
|
setBtnLoading(true)
|
||||||
|
}
|
||||||
|
|
||||||
getRouteList();
|
setLoading(false)
|
||||||
form.resetFields();
|
setBtnLoading(true)
|
||||||
form.setFieldsValue({ path: '', description: '' })
|
|
||||||
setRoute({} as Route);
|
|
||||||
});
|
|
||||||
|
|
||||||
setBtnLoading(false)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -13,18 +13,24 @@ const IconText = ({ icon, text }: { icon: React.FC; text: string }) => (
|
|||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
|
|
||||||
const RssPage = () => {
|
export default () => {
|
||||||
const [list, setList] = useState<Rss[]>([]);
|
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
|
||||||
|
const [list, setList] = useState<Rss[]>([]);
|
||||||
|
|
||||||
const getRssList = async () => {
|
const getRssList = async () => {
|
||||||
setLoading(true);
|
try {
|
||||||
const { data } = await getRssListAPI();
|
const { data } = await getRssListAPI();
|
||||||
setList(data as Rss[]);
|
setList(data);
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
getRssList();
|
getRssList();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -32,8 +38,8 @@ const RssPage = () => {
|
|||||||
<>
|
<>
|
||||||
<Title value='订阅中心' />
|
<Title value='订阅中心' />
|
||||||
|
|
||||||
<Card className='mt-2 min-h-[calc(100vh-180px)]'>
|
<Spin spinning={loading}>
|
||||||
<Spin spinning={loading}>
|
<Card className='mt-2 min-h-[calc(100vh-180px)]'>
|
||||||
<List
|
<List
|
||||||
dataSource={list}
|
dataSource={list}
|
||||||
size="large"
|
size="large"
|
||||||
@@ -62,10 +68,8 @@ const RssPage = () => {
|
|||||||
</List.Item>
|
</List.Item>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Spin>
|
</Card>
|
||||||
</Card>
|
</Spin>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default RssPage;
|
|
||||||
@@ -12,36 +12,43 @@ interface UserForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const UserPage = () => {
|
const UserPage = () => {
|
||||||
const [form] = Form.useForm<UserForm>();
|
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const [form] = Form.useForm<UserForm>();
|
||||||
const store = useUserStore();
|
const store = useUserStore();
|
||||||
|
|
||||||
const getUserData = async () => {
|
const getUserData = async () => {
|
||||||
setLoading(true);
|
try {
|
||||||
|
const { data } = await getUserDataAPI(store.user?.id);
|
||||||
const { data } = await getUserDataAPI(store.user?.id);
|
store.setUser(data);
|
||||||
store.setUser(data);
|
form.setFieldsValue(data);
|
||||||
form.setFieldsValue(data);
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
getUserData();
|
getUserData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onSubmit = async (values: UserForm) => {
|
const onSubmit = async (values: UserForm) => {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
|
||||||
await editUserDataAPI({
|
try {
|
||||||
id: store.user.id, ...values,
|
await editUserDataAPI({
|
||||||
role: undefined
|
id: store.user.id, ...values,
|
||||||
});
|
role: undefined
|
||||||
message.success("🎉 修改用户信息成功");
|
});
|
||||||
store.setUser(values as User);
|
|
||||||
getUserData();
|
|
||||||
|
|
||||||
setLoading(false)
|
await getUserData();
|
||||||
|
message.success("🎉 修改用户信息成功");
|
||||||
|
store.setUser(values as User);
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -88,7 +95,7 @@ const UserPage = () => {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Button type="primary" htmlType="submit" className="w-full" loading={loading}>编辑信息</Button>
|
<Button type="primary" htmlType="submit" className="w-full" loading={loading}>保存</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -35,29 +35,23 @@ const SystemPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async (values: EditUser) => {
|
const handleSubmit = async (values: EditUser) => {
|
||||||
try {
|
setLoading(true)
|
||||||
setLoading(true)
|
|
||||||
|
|
||||||
|
try {
|
||||||
await editAdminPassAPI(values);
|
await editAdminPassAPI(values);
|
||||||
|
|
||||||
confirm({
|
confirm({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
content: '🔒️ 修改成功,请重新登录',
|
content: '🔒️ 修改成功,请重新登录',
|
||||||
okText: '确定',
|
okText: '确定',
|
||||||
onOk: () => {
|
onOk: store.quitLogin,
|
||||||
store.quitLogin();
|
|
||||||
},
|
|
||||||
cancelButtonProps: { style: { display: 'none' } }
|
cancelButtonProps: { style: { display: 'none' } }
|
||||||
});
|
});
|
||||||
|
|
||||||
setLoading(false)
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
|
|
||||||
notification.error({
|
|
||||||
message: '错误',
|
|
||||||
description: '修改密码失败,请重试:' + error
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setLoading(false)
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -97,9 +91,7 @@ const SystemPage = () => {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Button type="primary" htmlType="submit" loading={loading} className="w-full">
|
<Button type="primary" htmlType="submit" loading={loading} className="w-full">保存</Button>
|
||||||
保存
|
|
||||||
</Button>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,66 +6,68 @@ import { editConfigDataAPI, getConfigDataAPI } from '@/api/Project';
|
|||||||
|
|
||||||
const RecordTheme = () => {
|
const RecordTheme = () => {
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
// const [theme, setTheme] = useState<Theme>({} as Theme);
|
|
||||||
|
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
const getLayoutData = async () => {
|
const getLayoutData = async () => {
|
||||||
setLoading(true);
|
try {
|
||||||
|
const { data } = await getConfigDataAPI<Theme>("layout");
|
||||||
|
|
||||||
const { data } = await getConfigDataAPI<Theme>("layout");
|
form.setFieldsValue({
|
||||||
|
record_name: data.record_name,
|
||||||
// setTheme(data);
|
record_info: data.record_info
|
||||||
|
});
|
||||||
form.setFieldsValue({
|
} catch (error) {
|
||||||
record_name: data.record_name,
|
setLoading(false);
|
||||||
record_info: data.record_info
|
}
|
||||||
});
|
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
getLayoutData();
|
getLayoutData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const editThemeData = async (values: { record_name: string, record_info: string }) => {
|
const editThemeData = async (values: { record_name: string, record_info: string }) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
await editConfigDataAPI("layout", values);
|
try {
|
||||||
|
await editConfigDataAPI("layout", values);
|
||||||
|
|
||||||
notification.success({
|
notification.success({
|
||||||
message: '成功',
|
message: '成功',
|
||||||
description: '🎉 修改主题成功',
|
description: '🎉 修改主题成功',
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div>
|
||||||
<Spin spinning={loading} indicator={<LoadingOutlined style={{ fontSize: 24 }} spin />}>
|
<h2 className="text-xl pb-4 pl-10">说说配置</h2>
|
||||||
<h2 className="text-xl pb-4 pl-10">说说配置</h2>
|
|
||||||
|
|
||||||
<div className='w-full lg:w-[500px] md:ml-10'>
|
<div className='w-full lg:w-[500px] md:ml-10'>
|
||||||
<Form form={form} onFinish={editThemeData} layout="vertical">
|
<Form form={form} onFinish={editThemeData} layout="vertical">
|
||||||
<Form.Item name="record_name" label="个人名称">
|
<Form.Item name="record_name" label="个人名称">
|
||||||
<Input size='large' placeholder="请输入个人名称" />
|
<Input size='large' placeholder="请输入个人名称" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item name="record_info" label="个人介绍">
|
<Form.Item name="record_info" label="个人介绍">
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
size='large'
|
size='large'
|
||||||
autoSize={{ minRows: 2, maxRows: 4 }}
|
autoSize={{ minRows: 2, maxRows: 4 }}
|
||||||
placeholder="请输入个人介绍"
|
placeholder="请输入个人介绍"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Button type="primary" size="large" className="w-full mt-4" htmlType="submit" loading={loading}>修改主题</Button>
|
<Button type="primary" size="large" className="w-full mt-4" htmlType="submit" loading={loading}>保存</Button>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
</Spin>
|
</div>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import FileUpload from '@/components/FileUpload';
|
|||||||
|
|
||||||
const SynthesisTheme = () => {
|
const SynthesisTheme = () => {
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
|
|
||||||
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
|
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
|
||||||
const [theme, setTheme] = useState<Theme>({} as Theme);
|
const [theme, setTheme] = useState<Theme>({} as Theme);
|
||||||
|
|
||||||
@@ -20,45 +21,52 @@ const SynthesisTheme = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getLayoutData = async () => {
|
const getLayoutData = async () => {
|
||||||
setLoading(true);
|
try {
|
||||||
|
const { data } = await getConfigDataAPI<Theme>("layout");
|
||||||
|
setTheme(data);
|
||||||
|
|
||||||
const { data } = await getConfigDataAPI<Theme>("layout");
|
form.setFieldsValue({
|
||||||
setTheme(data);
|
light_logo: data.light_logo,
|
||||||
|
dark_logo: data.dark_logo,
|
||||||
form.setFieldsValue({
|
swiper_image: data.swiper_image,
|
||||||
light_logo: data.light_logo,
|
swiper_text: data.swiper_text ? JSON.parse(data.swiper_text).join('\n') : '',
|
||||||
dark_logo: data.dark_logo,
|
social: data.social,
|
||||||
swiper_image: data.swiper_image,
|
covers: data.covers ? JSON.parse(data.covers).join("\n") : '',
|
||||||
swiper_text: data.swiper_text ? JSON.parse(data.swiper_text).join('\n') : '',
|
reco_article: data.reco_article ? JSON.parse(data.reco_article).join("\n") : '',
|
||||||
social: data.social,
|
});
|
||||||
covers: data.covers ? JSON.parse(data.covers).join("\n") : '',
|
} catch (error) {
|
||||||
reco_article: data.reco_article ? JSON.parse(data.reco_article).join("\n") : '',
|
setLoading(false);
|
||||||
});
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
getLayoutData();
|
getLayoutData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const editThemeData = async (values: any) => {
|
const editThemeData = async (values: any) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
const updatedLayout = {
|
try {
|
||||||
...theme,
|
const updatedLayout = {
|
||||||
...values,
|
...theme,
|
||||||
swiper_text: JSON.stringify(values.swiper_text.split('\n')),
|
...values,
|
||||||
covers: JSON.stringify(values.covers.split('\n')),
|
swiper_text: JSON.stringify(values.swiper_text.split('\n')),
|
||||||
reco_article: JSON.stringify(values.reco_article.split('\n')),
|
covers: JSON.stringify(values.covers.split('\n')),
|
||||||
};
|
reco_article: JSON.stringify(values.reco_article.split('\n')),
|
||||||
|
};
|
||||||
|
|
||||||
await editConfigDataAPI("layout", updatedLayout);
|
await editConfigDataAPI("layout", updatedLayout);
|
||||||
|
|
||||||
notification.success({
|
notification.success({
|
||||||
message: '成功',
|
message: '成功',
|
||||||
description: '🎉 修改主题成功',
|
description: '🎉 修改主题成功',
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
@@ -72,117 +80,115 @@ const SynthesisTheme = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div>
|
||||||
<Spin spinning={loading} indicator={<LoadingOutlined style={{ fontSize: 24 }} spin />}>
|
<h2 className="text-xl pb-4 pl-10">综合配置</h2>
|
||||||
<h2 className="text-xl pb-4 pl-10">综合配置</h2>
|
|
||||||
|
|
||||||
<div className='w-full lg:w-[500px] md:ml-10'>
|
<div className='w-full lg:w-[500px] md:ml-10'>
|
||||||
<Form form={form} onFinish={editThemeData} layout="vertical">
|
<Form form={form} onFinish={editThemeData} layout="vertical">
|
||||||
<Divider orientation="left">亮色主题 Logo</Divider>
|
<Divider orientation="left">亮色主题 Logo</Divider>
|
||||||
<Form.Item name="light_logo" label="亮色主题 Logo">
|
<Form.Item name="light_logo" label="亮色主题 Logo">
|
||||||
<Input
|
<Input
|
||||||
prefix={<PictureOutlined />}
|
prefix={<PictureOutlined />}
|
||||||
addonAfter={<UploadBtn />}
|
addonAfter={<UploadBtn />}
|
||||||
size='large'
|
size='large'
|
||||||
placeholder="请输入亮色Logo地址"
|
placeholder="请输入亮色Logo地址"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<img src={form.getFieldValue('light_logo')} alt="" className="w-1/3 mt-4 rounded" />
|
<img src={form.getFieldValue('light_logo')} alt="" className="w-1/3 mt-4 rounded" />
|
||||||
|
|
||||||
<Divider orientation="left">暗色主题 Logo</Divider>
|
<Divider orientation="left">暗色主题 Logo</Divider>
|
||||||
<Form.Item name="dark_logo" label="暗色主题 Logo">
|
<Form.Item name="dark_logo" label="暗色主题 Logo">
|
||||||
<Input
|
<Input
|
||||||
prefix={<PictureOutlined />}
|
prefix={<PictureOutlined />}
|
||||||
addonAfter={<UploadBtn />}
|
addonAfter={<UploadBtn />}
|
||||||
size='large'
|
size='large'
|
||||||
placeholder="请输入暗色Logo地址"
|
placeholder="请输入暗色Logo地址"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<img src={form.getFieldValue('dark_logo')} alt="" className="w-1/3 mt-4 rounded" />
|
<img src={form.getFieldValue('dark_logo')} alt="" className="w-1/3 mt-4 rounded" />
|
||||||
|
|
||||||
<Divider orientation="left">首页背景图</Divider>
|
<Divider orientation="left">首页背景图</Divider>
|
||||||
<Form.Item name="swiper_image" label="首页背景图">
|
<Form.Item name="swiper_image" label="首页背景图">
|
||||||
<Input
|
<Input
|
||||||
prefix={<PictureOutlined />}
|
prefix={<PictureOutlined />}
|
||||||
addonAfter={<UploadBtn />}
|
addonAfter={<UploadBtn />}
|
||||||
size='large'
|
size='large'
|
||||||
placeholder="请输入背景图地址"
|
placeholder="请输入背景图地址"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<img src={form.getFieldValue('swiper_image')} alt="" className="w-1/3 mt-4 rounded" />
|
<img src={form.getFieldValue('swiper_image')} alt="" className="w-1/3 mt-4 rounded" />
|
||||||
|
|
||||||
<Divider orientation="left">打字机文本</Divider>
|
<Divider orientation="left">打字机文本</Divider>
|
||||||
<Form.Item name="swiper_text" label="打字机文本">
|
<Form.Item name="swiper_text" label="打字机文本">
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
autoSize={{ minRows: 2, maxRows: 4 }}
|
autoSize={{ minRows: 2, maxRows: 4 }}
|
||||||
size='large'
|
size='large'
|
||||||
placeholder="请输入打字机文本"
|
placeholder="请输入打字机文本"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Alert message="以换行分隔,每行表示一段文本" type="info" className="mt-2" />
|
<Alert message="以换行分隔,每行表示一段文本" type="info" className="mt-2" />
|
||||||
|
|
||||||
<Divider orientation="left">社交网站</Divider>
|
<Divider orientation="left">社交网站</Divider>
|
||||||
<Form.Item name="social" label="社交网站">
|
<Form.Item name="social" label="社交网站">
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
autoSize={{ minRows: 2, maxRows: 4 }}
|
autoSize={{ minRows: 2, maxRows: 4 }}
|
||||||
size='large'
|
size='large'
|
||||||
placeholder="请输入社交网站"
|
placeholder="请输入社交网站"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Alert message="请务必确保每一项格式正确,否则会导致网站无法访问" type="info" className="mt-2" />
|
<Alert message="请务必确保每一项格式正确,否则会导致网站无法访问" type="info" className="mt-2" />
|
||||||
|
|
||||||
<Divider orientation="left">文章随机封面</Divider>
|
<Divider orientation="left">文章随机封面</Divider>
|
||||||
<Form.Item name="covers" label="文章随机封面">
|
<Form.Item name="covers" label="文章随机封面">
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
autoSize={{ minRows: 2, maxRows: 4 }}
|
autoSize={{ minRows: 2, maxRows: 4 }}
|
||||||
size='large'
|
size='large'
|
||||||
placeholder="请输入文章随机封面"
|
placeholder="请输入文章随机封面"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Alert message="以换行分隔,每行表示一段文本" type="info" className="mt-2" />
|
<Alert message="以换行分隔,每行表示一段文本" type="info" className="mt-2" />
|
||||||
|
|
||||||
<Divider orientation="left">作者推荐文章</Divider>
|
<Divider orientation="left">作者推荐文章</Divider>
|
||||||
<Form.Item name="reco_article" label="作者推荐文章">
|
<Form.Item name="reco_article" label="作者推荐文章">
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
autoSize={{ minRows: 2, maxRows: 4 }}
|
autoSize={{ minRows: 2, maxRows: 4 }}
|
||||||
size='large'
|
size='large'
|
||||||
placeholder="请输入作者推荐文章ID"
|
placeholder="请输入作者推荐文章ID"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Alert message="以换行分隔,每行表示一段文本" type="info" className="mt-2" />
|
<Alert message="以换行分隔,每行表示一段文本" type="info" className="mt-2" />
|
||||||
|
|
||||||
<Divider orientation="left">侧边栏</Divider>
|
<Divider orientation="left">侧边栏</Divider>
|
||||||
<div className='overflow-auto w-full'>
|
<div className='overflow-auto w-full'>
|
||||||
<div className="sidebar w-[750px] flex mb-4">
|
<div className="sidebar w-[750px] flex mb-4">
|
||||||
{['author', 'randomArticle', 'newComments', 'hotArticle'].map((item) => (
|
{['author', 'randomArticle', 'newComments', 'hotArticle'].map((item) => (
|
||||||
<div key={item} className={`item flex flex-col items-center p-4 m-4 border-2 rounded cursor-pointer ${theme.right_sidebar && JSON.parse(theme.right_sidebar).includes(item) ? 'border-primary' : 'border-[#eee]'}`} onClick={() => onSidebar(item)}>
|
<div key={item} className={`item flex flex-col items-center p-4 m-4 border-2 rounded cursor-pointer ${theme.right_sidebar && JSON.parse(theme.right_sidebar).includes(item) ? 'border-primary' : 'border-[#eee]'}`} onClick={() => onSidebar(item)}>
|
||||||
<p className={`text-center ${theme.right_sidebar && JSON.parse(theme.right_sidebar).includes(item) ? 'text-primary' : ''}`}>
|
<p className={`text-center ${theme.right_sidebar && JSON.parse(theme.right_sidebar).includes(item) ? 'text-primary' : ''}`}>
|
||||||
{item === 'author' ? '作者信息模块' : item === 'hotArticle' ? '作者推荐模块' : item === 'randomArticle' ? '随机推荐模块' : '最新评论模块'}
|
{item === 'author' ? '作者信息模块' : item === 'hotArticle' ? '作者推荐模块' : item === 'randomArticle' ? '随机推荐模块' : '最新评论模块'}
|
||||||
</p>
|
</p>
|
||||||
<img src={`${getFile(item)}`} alt="" className="mt-4 rounded" />
|
<img src={`${getFile(item)}`} alt="" className="mt-4 rounded" />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Divider orientation="left">文章布局</Divider>
|
<Divider orientation="left">文章布局</Divider>
|
||||||
<div className='overflow-auto w-full'>
|
<div className='overflow-auto w-full'>
|
||||||
<div className="article flex w-[650px]">
|
<div className="article flex w-[650px]">
|
||||||
{['classics', 'card', 'waterfall'].map((item) => (
|
{['classics', 'card', 'waterfall'].map((item) => (
|
||||||
<div key={item} onClick={() => setTheme({ ...theme, is_article_layout: item })} className={`item flex flex-col items-center p-4 m-4 border-2 rounded cursor-pointer ${theme.is_article_layout === item ? 'border-primary' : 'border-[#eee]'}`}>
|
<div key={item} onClick={() => setTheme({ ...theme, is_article_layout: item })} className={`item flex flex-col items-center p-4 m-4 border-2 rounded cursor-pointer ${theme.is_article_layout === item ? 'border-primary' : 'border-[#eee]'}`}>
|
||||||
<p className={`text-center ${theme.is_article_layout === item ? 'text-primary' : ''}`}>
|
<p className={`text-center ${theme.is_article_layout === item ? 'text-primary' : ''}`}>
|
||||||
{item === 'classics' ? '经典布局' : item === 'card' ? '卡片布局' : '瀑布流布局'}
|
{item === 'classics' ? '经典布局' : item === 'card' ? '卡片布局' : '瀑布流布局'}
|
||||||
</p>
|
</p>
|
||||||
<img src={`${getFile(item)}`} alt="" className="w-[200px] mt-4 rounded" />
|
<img src={`${getFile(item)}`} alt="" className="w-[200px] mt-4 rounded" />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Button type="primary" size="large" className="w-full mt-4" htmlType="submit" loading={loading}>修改主题</Button>
|
<Button type="primary" size="large" className="w-full mt-4" htmlType="submit" loading={loading}>保存</Button>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
</Spin>
|
|
||||||
|
|
||||||
<FileUpload
|
<FileUpload
|
||||||
dir="swiper"
|
dir="swiper"
|
||||||
@@ -190,7 +196,7 @@ const SynthesisTheme = () => {
|
|||||||
onSuccess={(url: string[]) => setTheme({ ...theme, swiper_image: url.join("\n") })}
|
onSuccess={(url: string[]) => setTheme({ ...theme, swiper_image: url.join("\n") })}
|
||||||
onCancel={() => setIsModalOpen(false)}
|
onCancel={() => setIsModalOpen(false)}
|
||||||
/>
|
/>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,25 @@ import { Web } from '@/types/app/project'
|
|||||||
import { useWebStore } from '@/stores';
|
import { useWebStore } from '@/stores';
|
||||||
|
|
||||||
const WebPage = () => {
|
const WebPage = () => {
|
||||||
const [form] = Form.useForm();
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
const web = useWebStore(state => state.web)
|
const web = useWebStore(state => state.web)
|
||||||
const setWeb = useWebStore(state => state.setWeb)
|
const setWeb = useWebStore(state => state.setWeb)
|
||||||
|
|
||||||
const onSubmit = async (values: Web) => {
|
const onSubmit = async (values: Web) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
await editConfigDataAPI("web", values);
|
|
||||||
message.success("🎉 编辑网站成功");
|
|
||||||
|
|
||||||
setWeb(values)
|
try {
|
||||||
form.setFieldsValue(values);
|
await editConfigDataAPI("web", values);
|
||||||
|
message.success("🎉 编辑网站成功");
|
||||||
|
setWeb(values)
|
||||||
|
form.setFieldsValue(values);
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -90,7 +96,7 @@ const WebPage = () => {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Button type="primary" htmlType="submit" loading={loading} block>编辑网站</Button>
|
<Button type="primary" htmlType="submit" loading={loading} block>保存</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ const SetupPage = () => {
|
|||||||
const [active, setActive] = useState("system");
|
const [active, setActive] = useState("system");
|
||||||
|
|
||||||
const iconSty = "w-5 h-8 mr-1"
|
const iconSty = "w-5 h-8 mr-1"
|
||||||
|
|
||||||
const list: Setup[] = [
|
const list: Setup[] = [
|
||||||
{
|
{
|
||||||
title: "系统设置",
|
title: "系统设置",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Table, Button, Image, Form, Input, Tabs, Card, Popconfirm, message } from 'antd';
|
import { Table, Button, Image, Form, Input, Tabs, Card, Popconfirm, message, Spin } from 'antd';
|
||||||
import { getSwiperListAPI, addSwiperDataAPI, editSwiperDataAPI, delSwiperDataAPI } from '@/api/Swiper';
|
import { getSwiperListAPI, addSwiperDataAPI, editSwiperDataAPI, delSwiperDataAPI, getSwiperDataAPI } from '@/api/Swiper';
|
||||||
import { Swiper } from '@/types/app/swiper';
|
import { Swiper } from '@/types/app/swiper';
|
||||||
import Title from '@/components/Title';
|
import Title from '@/components/Title';
|
||||||
import { ColumnsType } from 'antd/es/table';
|
import { ColumnsType } from 'antd/es/table';
|
||||||
@@ -10,6 +10,9 @@ import FileUpload from '@/components/FileUpload';
|
|||||||
const SwiperPage = () => {
|
const SwiperPage = () => {
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [btnLoading, setBtnLoading] = useState(false)
|
const [btnLoading, setBtnLoading] = useState(false)
|
||||||
|
const [editLoading, setEditLoading] = useState(false)
|
||||||
|
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
const [swiper, setSwiper] = useState<Swiper>({} as Swiper);
|
const [swiper, setSwiper] = useState<Swiper>({} as Swiper);
|
||||||
const [list, setList] = useState<Swiper[]>([]);
|
const [list, setList] = useState<Swiper[]>([]);
|
||||||
@@ -39,8 +42,13 @@ const SwiperPage = () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const getSwiperList = async () => {
|
const getSwiperList = async () => {
|
||||||
const { data } = await getSwiperListAPI();
|
try {
|
||||||
setList(data as Swiper[]);
|
const { data } = await getSwiperListAPI();
|
||||||
|
setList(data as Swiper[]);
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,39 +57,56 @@ const SwiperPage = () => {
|
|||||||
getSwiperList();
|
getSwiperList();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [form] = Form.useForm();
|
const editSwiperData = async (record: Swiper) => {
|
||||||
const editSwiperData = (record: Swiper) => {
|
setEditLoading(true);
|
||||||
setSwiper(record);
|
|
||||||
form.setFieldsValue(record);
|
|
||||||
setTab('operate');
|
setTab('operate');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { data } = await getSwiperDataAPI(record.id)
|
||||||
|
setSwiper(data);
|
||||||
|
form.setFieldsValue(record);
|
||||||
|
} catch (error) {
|
||||||
|
setEditLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
setEditLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const delSwiperData = async (id: number) => {
|
const delSwiperData = async (id: number) => {
|
||||||
setLoading(true);
|
setBtnLoading(true);
|
||||||
await delSwiperDataAPI(id);
|
|
||||||
message.success('🎉 删除轮播图成功');
|
try {
|
||||||
getSwiperList();
|
await delSwiperDataAPI(id);
|
||||||
|
await getSwiperList();
|
||||||
|
message.success('🎉 删除轮播图成功');
|
||||||
|
} catch (error) {
|
||||||
|
setBtnLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
setBtnLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
setBtnLoading(true)
|
setBtnLoading(true)
|
||||||
|
|
||||||
form.validateFields().then(async (values: Swiper) => {
|
try {
|
||||||
if (swiper.id) {
|
form.validateFields().then(async (values: Swiper) => {
|
||||||
await editSwiperDataAPI({ ...swiper, ...values });
|
if (swiper.id) {
|
||||||
message.success('🎉 编辑轮播图成功');
|
await editSwiperDataAPI({ ...swiper, ...values });
|
||||||
} else {
|
message.success('🎉 编辑轮播图成功');
|
||||||
await addSwiperDataAPI({ ...swiper, ...values });
|
} else {
|
||||||
message.success('🎉 新增轮播图成功');
|
await addSwiperDataAPI({ ...swiper, ...values });
|
||||||
}
|
message.success('🎉 新增轮播图成功');
|
||||||
|
}
|
||||||
|
|
||||||
getSwiperList();
|
await getSwiperList();
|
||||||
setTab('list');
|
setTab('list');
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
setSwiper({} as Swiper);
|
setSwiper({} as Swiper);
|
||||||
})
|
})
|
||||||
|
} catch (error) {
|
||||||
setBtnLoading(false)
|
setBtnLoading(false)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTabChange = (key: string) => {
|
const handleTabChange = (key: string) => {
|
||||||
@@ -118,7 +143,7 @@ const SwiperPage = () => {
|
|||||||
label: swiper.id ? '编辑轮播图' : '新增轮播图',
|
label: swiper.id ? '编辑轮播图' : '新增轮播图',
|
||||||
key: 'operate',
|
key: 'operate',
|
||||||
children: (
|
children: (
|
||||||
<>
|
<Spin spinning={editLoading}>
|
||||||
<h2 className="text-xl pb-4 text-center">{swiper.id ? '编辑轮播图' : '新增轮播图'}</h2>
|
<h2 className="text-xl pb-4 text-center">{swiper.id ? '编辑轮播图' : '新增轮播图'}</h2>
|
||||||
|
|
||||||
<Form
|
<Form
|
||||||
@@ -149,7 +174,7 @@ const SwiperPage = () => {
|
|||||||
<Button type="primary" htmlType="submit" loading={btnLoading} className="w-full">{swiper.id ? '编辑轮播图' : '新增轮播图'}</Button>
|
<Button type="primary" htmlType="submit" loading={btnLoading} className="w-full">{swiper.id ? '编辑轮播图' : '新增轮播图'}</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</>
|
</Spin>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user