diff --git a/src/constants/urls.constants.ts b/src/constants/urls.constants.ts index 260c1d7..84eb783 100644 --- a/src/constants/urls.constants.ts +++ b/src/constants/urls.constants.ts @@ -25,6 +25,10 @@ export const URL_SYS_STATISTICS_CPU = `${URL_SYS_STATISTICS}/cpu` export const URL_SYS_STATISTICS_STORAGE = `${URL_SYS_STATISTICS}/storage` export const URL_SYS_STATISTICS_ONLINE = `${URL_SYS_STATISTICS}/online` export const URL_SYS_STATISTICS_ACTIVE = `${URL_SYS_STATISTICS}/active` +export const URL_SYS_TOOL = '/system/tool' +export const URL_SYS_TOOL_CATEGORY = `${URL_SYS_TOOL}/category` +export const URL_SYS_TOOL_BASE = `${URL_SYS_TOOL}/base` +export const URL_SYS_TOOL_TEMPLATE = `${URL_SYS_TOOL}/template` export const URL_API_V1 = '/api/v1' export const URL_API_V1_AVATAR_RANDOM_BASE64 = `${URL_API_V1}/avatar/base64` diff --git a/src/global.d.ts b/src/global.d.ts index deec261..408aaea 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -464,3 +464,63 @@ interface ActiveInfoVo { interface ActiveInfoGetParam { scope: string } + +interface ToolCategoryVo { + id: string + name: string + enable: boolean + createTime: string + updateTime: string +} + +interface ToolCategoryAddEditParam { + id?: string + name: string + enable: string +} + +interface ToolDataVo { + id: string + data: string + createTime: string + updateTime: string +} + +interface ToolBaseVo { + id: string + name: string + source: ToolDataVo + dist: ToolDataVo + createTime: string + updateTime: string +} + +interface ToolTemplateVo { + id: string + name: string + ver: string + baseId: string + source: ToolDataVo + dist: ToolDataVo + createTime: string + updateTime: string +} + +interface ToolVo { + id: string + name: string + toolId: string + description: string + baseId: string + author: UserInfoVo + ver: string + privately: boolean + keywords: string[] + categories: ToolCategoryVo[] + source: ToolDataVo + dist: ToolDataVo + publish: boolean + review: number + createTime: string + updateTime: string +} diff --git a/src/pages/System/Tools/Base.tsx b/src/pages/System/Tools/Base.tsx new file mode 100644 index 0000000..4870323 --- /dev/null +++ b/src/pages/System/Tools/Base.tsx @@ -0,0 +1,5 @@ +const Base = () => { + return <>3 +} + +export default Base diff --git a/src/pages/System/Tools/Category.tsx b/src/pages/System/Tools/Category.tsx new file mode 100644 index 0000000..6ac6519 --- /dev/null +++ b/src/pages/System/Tools/Category.tsx @@ -0,0 +1,316 @@ +import { + COLOR_PRODUCTION, + DATABASE_DELETE_SUCCESS, + DATABASE_DUPLICATE_KEY, + DATABASE_INSERT_SUCCESS, + DATABASE_SELECT_SUCCESS, + DATABASE_UPDATE_SUCCESS +} from '@/constants/common.constants' +import { utcToLocalTime } from '@/util/datetime' +import { + r_sys_tool_category_add, + r_sys_tool_category_delete, + r_sys_tool_category_get, + r_sys_tool_category_update +} from '@/services/system' +import Card from '@/components/common/Card' +import Permission from '@/components/common/Permission' +import FitFullscreen from '@/components/common/FitFullscreen' +import HideScrollbar from '@/components/common/HideScrollbar' + +const Category = () => { + const [modal, contextHolder] = AntdModal.useModal() + const [form] = AntdForm.useForm() + const formValues = AntdForm.useWatch([], form) + const [newFormValues, setNewFormValues] = useState() + const [categoryData, setCategoryData] = useState([]) + const [isLoading, setIsLoading] = useState(false) + const [isDrawerOpen, setIsDrawerOpen] = useState(false) + const [isDrawerEdit, setIsDrawerEdit] = useState(false) + const [submittable, setSubmittable] = useState(false) + const [isSubmitting, setIsSubmitting] = useState(false) + + const handleOnAddBtnClick = () => { + setIsDrawerEdit(false) + setIsDrawerOpen(true) + form.setFieldValue('id', undefined) + form.setFieldValue('name', newFormValues?.name) + form.setFieldValue('enable', newFormValues?.enable ?? true) + } + + const handleOnEditBtnClick = (value: ToolCategoryVo) => { + return () => { + setIsDrawerEdit(true) + setIsDrawerOpen(true) + form.setFieldValue('id', value.id) + form.setFieldValue('name', value.name) + form.setFieldValue('enable', value.enable) + void form.validateFields() + } + } + + const categoryColumns: _ColumnsType = [ + { + title: 'ID', + dataIndex: 'id', + width: '15%' + }, + { + title: '名称', + dataIndex: 'name' + }, + { + title: '创建时间', + dataIndex: 'createTime', + width: '20%', + align: 'center', + render: (value: string) => utcToLocalTime(value) + }, + { + title: '修改时间', + dataIndex: 'updateTime', + width: '20%', + align: 'center', + render: (value: string) => utcToLocalTime(value) + }, + { + title: '状态', + dataIndex: 'enable', + width: '5%', + align: 'center', + render: (value) => + value ? 启用 : 禁用 + }, + { + title: ( + <> + 操作 (新增) + + ), + dataIndex: 'enable', + width: '15em', + align: 'center', + render: (_, record) => ( + <> + + + + 编辑 + + + + + 删除 + + + + + ) + } + ] + + const handleOnDeleteBtnClick = (value: ToolCategoryVo) => { + return () => { + modal + .confirm({ + title: '确定删除', + content: `确定删除类别 ${value.name} 吗?` + }) + .then( + (confirmed) => { + if (confirmed) { + setIsLoading(true) + + void r_sys_tool_category_delete(value.id) + .then((res) => { + const response = res.data + if (response.code === DATABASE_DELETE_SUCCESS) { + void message.success('删除成功') + setTimeout(() => { + getCategory() + }) + } else { + void message.error('删除失败,请稍后重试') + } + }) + .finally(() => { + setIsLoading(false) + }) + } + }, + () => {} + ) + } + } + + const handleOnDrawerClose = () => { + setIsDrawerOpen(false) + } + + const handleOnSubmit = () => { + if (isSubmitting) { + return + } + setIsSubmitting(true) + + if (isDrawerEdit) { + void r_sys_tool_category_update(formValues) + .then((res) => { + const response = res.data + switch (response.code) { + case DATABASE_UPDATE_SUCCESS: + setIsDrawerOpen(false) + void message.success('更新成功') + getCategory() + break + case DATABASE_DUPLICATE_KEY: + void message.error('已存在相同名称的类别') + break + default: + void message.error('更新失败,请稍后重试') + } + }) + .finally(() => { + setIsSubmitting(false) + }) + } else { + void r_sys_tool_category_add(formValues) + .then((res) => { + const response = res.data + switch (response.code) { + case DATABASE_INSERT_SUCCESS: + setIsDrawerOpen(false) + void message.success('添加成功') + setNewFormValues(undefined) + getCategory() + break + case DATABASE_DUPLICATE_KEY: + void message.error('已存在相同名称的类别') + break + default: + void message.error('添加失败,请稍后重试') + } + }) + .finally(() => { + setIsSubmitting(false) + }) + } + } + + const getCategory = () => { + if (isLoading) { + return + } + setIsLoading(true) + + void r_sys_tool_category_get() + .then((res) => { + const response = res.data + if (response.code === DATABASE_SELECT_SUCCESS) { + setCategoryData(response.data!) + } else { + void message.error('获取失败,请稍后重试') + } + }) + .finally(() => { + setIsLoading(false) + }) + } + + useEffect(() => { + form.validateFields({ validateOnly: true }).then( + () => { + setSubmittable(true) + }, + () => { + setSubmittable(false) + } + ) + + if (!isDrawerEdit && formValues) { + setNewFormValues({ + name: formValues.name, + enable: formValues.enable + }) + } + }, [formValues]) + + useEffect(() => { + getCategory() + }, []) + + const drawerToolbar = ( + + + 取消 + + + 提交 + + + ) + + const addAndEditForm = ( + + + + + + + + + + ) + + return ( + <> + + + + record.id} + loading={isLoading} + pagination={false} + /> + + + + + {addAndEditForm} + + {contextHolder} + + ) +} + +export default Category diff --git a/src/pages/System/Tools/Template.tsx b/src/pages/System/Tools/Template.tsx new file mode 100644 index 0000000..edf5155 --- /dev/null +++ b/src/pages/System/Tools/Template.tsx @@ -0,0 +1,5 @@ +const Template = () => { + return <>2 +} + +export default Template diff --git a/src/pages/System/Tools/index.tsx b/src/pages/System/Tools/index.tsx index 0f205de..170916e 100644 --- a/src/pages/System/Tools/index.tsx +++ b/src/pages/System/Tools/index.tsx @@ -1,5 +1,5 @@ const Tools = () => { - return <> + return <>1 } export default Tools diff --git a/src/pages/SystemFramework.tsx b/src/pages/SystemFramework.tsx index 00d3a17..6084d97 100644 --- a/src/pages/SystemFramework.tsx +++ b/src/pages/SystemFramework.tsx @@ -10,21 +10,32 @@ const SystemFramework = () => {
- - {getSystemRouteJson().map((value) => { - return ( - value.menu && ( - + + + {getSystemRouteJson().map((route) => { + return ( + route.menu && ( + + {route.children?.map((subRoute) => ( + + ))} + + ) ) - ) - })} - + })} + +
diff --git a/src/pages/Tools/Create.tsx b/src/pages/Tools/Create.tsx index fb0e8f5..46cc42b 100644 --- a/src/pages/Tools/Create.tsx +++ b/src/pages/Tools/Create.tsx @@ -6,7 +6,6 @@ import Preview from '@/components/Playground/Output/Preview' import templates from '@/components/Playground/templates.ts' import { useEffect } from 'react' import HideScrollbar from '@/components/common/HideScrollbar.tsx' -import Icon from '@ant-design/icons' const Create = () => { const [form] = AntdForm.useForm<{ @@ -126,36 +125,16 @@ const Create = () => { /> - 关键字 - - - - - } + label={'关键字'} + tooltip={'工具搜索(每个不超过10个字符)'} name={'keyword'} rules={[{ required: true, message: '请输入关键字' }]} > - 类别 - - - - - } + label={'类别'} + tooltip={'工具分类'} name={'category'} rules={[{ required: true }]} > diff --git a/src/pages/ToolsFramework.tsx b/src/pages/ToolsFramework.tsx index b3dcb87..2abb04e 100644 --- a/src/pages/ToolsFramework.tsx +++ b/src/pages/ToolsFramework.tsx @@ -2,23 +2,14 @@ import '@/assets/css/pages/tools-framework.scss' import { tools } from '@/router/tools' import FitFullscreen from '@/components/common/FitFullscreen' import Sidebar from '@/components/common/Sidebar' -import { SidebarScrollElement } from '@/components/common/Sidebar/Scroll' import FullscreenLoadingMask from '@/components/common/FullscreenLoadingMask' const ToolsFramework = () => { - const sidebarScrollRef = useRef(null) - - const handleOnSidebarSwitch = () => { - setTimeout(() => { - sidebarScrollRef.current?.refreshLayout() - }, 300) - } - return ( <>
- + { /> - + {tools.map((tool) => { return tool.menu && diff --git a/src/router/system.tsx b/src/router/system.tsx index 1cdac3d..30f1f8e 100644 --- a/src/router/system.tsx +++ b/src/router/system.tsx @@ -34,11 +34,48 @@ const system: RouteJsonObject[] = [ path: 'tools', absolutePath: '/system/tools', id: 'system-tools', - component: lazy(() => import('@/pages/System/Tools')), name: '工具配置', icon: lazy(() => import('~icons/oxygen/tool')), menu: true, - autoHide: true + autoHide: true, + children: [ + { + path: '', + absolutePath: '/system/tools', + id: 'system-tools-index', + component: lazy(() => import('@/pages/System/Tools')), + name: '工具管理', + menu: true, + autoHide: true + }, + { + path: 'template', + absolutePath: '/system/tools/template', + id: 'system-tools-template', + component: lazy(() => import('@/pages/System/Tools/Template')), + name: '模板管理', + menu: true, + autoHide: true + }, + { + path: 'base', + absolutePath: '/system/tools/base', + id: 'system-tools-base', + component: lazy(() => import('@/pages/System/Tools/Base')), + name: '基板管理', + menu: true, + autoHide: true + }, + { + path: 'category', + absolutePath: '/system/tools/category', + id: 'system-tools-category', + component: lazy(() => import('@/pages/System/Tools/Category')), + name: '类别管理', + menu: true, + autoHide: true + } + ] }, { path: 'user', diff --git a/src/services/system.tsx b/src/services/system.tsx index 8e6cd7f..690bb21 100644 --- a/src/services/system.tsx +++ b/src/services/system.tsx @@ -16,7 +16,8 @@ import { URL_SYS_STATISTICS_ONLINE, URL_SYS_STATISTICS_ACTIVE, URL_SYS_SETTINGS_BASE, - URL_SYS_SETTINGS_SENSITIVE + URL_SYS_SETTINGS_SENSITIVE, + URL_SYS_TOOL_CATEGORY } from '@/constants/urls.constants' import request from '@/services/index' @@ -113,3 +114,14 @@ export const r_sys_statistics_online = (param: OnlineInfoGetParam) => export const r_sys_statistics_active = (param: ActiveInfoGetParam) => request.get(URL_SYS_STATISTICS_ACTIVE, param) + +export const r_sys_tool_category_get = () => request.get(URL_SYS_TOOL_CATEGORY) + +export const r_sys_tool_category_add = (param: ToolCategoryAddEditParam) => + request.post(URL_SYS_TOOL_CATEGORY, param) + +export const r_sys_tool_category_update = (param: ToolCategoryAddEditParam) => + request.put(URL_SYS_TOOL_CATEGORY, param) + +export const r_sys_tool_category_delete = (id: string) => + request.delete(`${URL_SYS_TOOL_CATEGORY}/${id}`) diff --git a/src/util/auth.tsx b/src/util/auth.tsx index 7ff918e..6fc66fc 100644 --- a/src/util/auth.tsx +++ b/src/util/auth.tsx @@ -253,7 +253,14 @@ export const getPermissionPath = (): string[] => { } export const hasPathPermission = (path: string) => { - return getPermissionPath().indexOf(path) !== -1 + let flag = false + getPermissionPath().forEach((value) => { + if (RegExp(value).test(path)) { + flag = true + return + } + }) + return flag } export const getPermission = (): string[] => {