| @@ -181,7 +181,7 @@ export const patchClientRoutes: RuntimeConfig['patchClientRoutes'] = (e) => { | |||
| }; | |||
| export function render(oldRender: () => void) { | |||
| //console.log('render'); | |||
| // console.log('render'); | |||
| const token = getAccessToken(); | |||
| if (!token || token?.length === 0) { | |||
| oldRender(); | |||
| @@ -193,7 +193,6 @@ export function render(oldRender: () => void) { | |||
| oldRender(); | |||
| }) | |||
| .catch(() => { | |||
| setRemoteMenu([]); | |||
| oldRender(); | |||
| }); | |||
| } | |||
| @@ -208,6 +207,7 @@ export const antd: RuntimeAntdConfig = (memo) => { | |||
| colorWarning: themes['warningColor'], | |||
| colorLink: themes['primaryColor'], | |||
| colorText: themes['textColor'], | |||
| controlHeightLG: 46, | |||
| }; | |||
| memo.theme.components ??= {}; | |||
| memo.theme.components.Tabs = {}; | |||
| @@ -0,0 +1,32 @@ | |||
| .menu-icon-selector { | |||
| // grid 布局,每行显示 8 个图标 | |||
| display: grid; | |||
| grid-auto-rows: 1fr; | |||
| grid-template-columns: repeat(4, 1fr); | |||
| &__item { | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| height: 80px; | |||
| cursor: pointer; | |||
| &__icon { | |||
| display: block; | |||
| } | |||
| &__icon--active { | |||
| display: none; | |||
| } | |||
| &:hover &__icon, | |||
| &:active &__icon { | |||
| display: none; | |||
| } | |||
| &:hover &__icon--active, | |||
| &:active &__icon--active { | |||
| display: block; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,62 @@ | |||
| import KFIcon from '@/components/KFIcon'; | |||
| import KFModal from '@/components/KFModal'; | |||
| import iconData from '@/iconfont/iconfont.json'; | |||
| import { type ModalProps } from 'antd'; | |||
| import { useEffect, useState } from 'react'; | |||
| import styles from './index.less'; | |||
| interface MenuIconSelectorProps extends Omit<ModalProps, 'onOk'> { | |||
| selectedIcon?: string; | |||
| onOk: (param: string) => void; | |||
| } | |||
| type IconObject = { | |||
| icon_id: string; | |||
| font_class: string; | |||
| }; | |||
| function MenuIconSelector({ open, selectedIcon, onOk, ...rest }: MenuIconSelectorProps) { | |||
| const [icons, setIcons] = useState<IconObject[]>([]); | |||
| useEffect(() => { | |||
| const glyphs = iconData.glyphs as IconObject[]; | |||
| setIcons(glyphs.filter((item) => !item.font_class.endsWith('-active'))); | |||
| }, []); | |||
| return ( | |||
| <KFModal | |||
| {...rest} | |||
| title="选择图标" | |||
| width={680} | |||
| open={open} | |||
| cancelButtonProps={{ style: { display: 'none' } }} | |||
| okButtonProps={{ style: { display: 'none' } }} | |||
| > | |||
| <div className={styles['menu-icon-selector']}> | |||
| {icons.map((icon) => ( | |||
| <div | |||
| key={icon.icon_id} | |||
| className={styles['menu-icon-selector__item']} | |||
| onClick={() => onOk(icon.font_class)} | |||
| > | |||
| <KFIcon | |||
| className={styles['menu-icon-selector__item__icon']} | |||
| type={ | |||
| selectedIcon === icon.font_class | |||
| ? `icon-${icon.font_class}-active` | |||
| : `icon-${icon.font_class}` | |||
| } | |||
| font={24} | |||
| /> | |||
| <KFIcon | |||
| className={styles['menu-icon-selector__item__icon--active']} | |||
| type={`icon-${icon.font_class}-active`} | |||
| font={24} | |||
| /> | |||
| </div> | |||
| ))} | |||
| </div> | |||
| </KFModal> | |||
| ); | |||
| } | |||
| export default MenuIconSelector; | |||
| @@ -0,0 +1,163 @@ | |||
| { | |||
| "id": "4511326", | |||
| "name": "复杂智能软件-导航", | |||
| "font_family": "iconfont", | |||
| "css_prefix_text": "icon-", | |||
| "description": "", | |||
| "glyphs": [ | |||
| { | |||
| "icon_id": "40233218", | |||
| "name": "操作手册-active", | |||
| "font_class": "manual-icon-active", | |||
| "unicode": "e62c", | |||
| "unicode_decimal": 58924 | |||
| }, | |||
| { | |||
| "icon_id": "40233217", | |||
| "name": "操作手册", | |||
| "font_class": "manual-icon", | |||
| "unicode": "e62d", | |||
| "unicode_decimal": 58925 | |||
| }, | |||
| { | |||
| "icon_id": "40171713", | |||
| "name": "监控运维-active", | |||
| "font_class": "monitor-icon-active", | |||
| "unicode": "e627", | |||
| "unicode_decimal": 58919 | |||
| }, | |||
| { | |||
| "icon_id": "40171711", | |||
| "name": "监控运维", | |||
| "font_class": "monitor-icon", | |||
| "unicode": "e629", | |||
| "unicode_decimal": 58921 | |||
| }, | |||
| { | |||
| "icon_id": "40171710", | |||
| "name": "开发环境-active", | |||
| "font_class": "developmentEnvironment-icon-active", | |||
| "unicode": "e62a", | |||
| "unicode_decimal": 58922 | |||
| }, | |||
| { | |||
| "icon_id": "40171699", | |||
| "name": "开发环境", | |||
| "font_class": "developmentEnvironment-icon", | |||
| "unicode": "e62b", | |||
| "unicode_decimal": 58923 | |||
| }, | |||
| { | |||
| "icon_id": "39969575", | |||
| "name": "系统管理", | |||
| "font_class": "system-icon", | |||
| "unicode": "e618", | |||
| "unicode_decimal": 58904 | |||
| }, | |||
| { | |||
| "icon_id": "39969573", | |||
| "name": "流水线-active", | |||
| "font_class": "workflow-icon-active", | |||
| "unicode": "e61a", | |||
| "unicode_decimal": 58906 | |||
| }, | |||
| { | |||
| "icon_id": "39969569", | |||
| "name": "数据准备-active", | |||
| "font_class": "datasetPreparation-icon-active", | |||
| "unicode": "e61c", | |||
| "unicode_decimal": 58908 | |||
| }, | |||
| { | |||
| "icon_id": "39969568", | |||
| "name": "数据准备", | |||
| "font_class": "datasetPreparation-icon", | |||
| "unicode": "e61d", | |||
| "unicode_decimal": 58909 | |||
| }, | |||
| { | |||
| "icon_id": "39969570", | |||
| "name": "模型在线部署", | |||
| "font_class": "modelDseployment-icon", | |||
| "unicode": "e61e", | |||
| "unicode_decimal": 58910 | |||
| }, | |||
| { | |||
| "icon_id": "39969567", | |||
| "name": "流水线", | |||
| "font_class": "workflow-icon", | |||
| "unicode": "e61f", | |||
| "unicode_decimal": 58911 | |||
| }, | |||
| { | |||
| "icon_id": "39969566", | |||
| "name": "AI资产管理-active", | |||
| "font_class": "aiAsset-icon-active", | |||
| "unicode": "e620", | |||
| "unicode_decimal": 58912 | |||
| }, | |||
| { | |||
| "icon_id": "39969563", | |||
| "name": "AI资产管理", | |||
| "font_class": "aiAsset-icon", | |||
| "unicode": "e621", | |||
| "unicode_decimal": 58913 | |||
| }, | |||
| { | |||
| "icon_id": "39969580", | |||
| "name": "工作空间", | |||
| "font_class": "workspace-icon", | |||
| "unicode": "e611", | |||
| "unicode_decimal": 58897 | |||
| }, | |||
| { | |||
| "icon_id": "39969572", | |||
| "name": "模型开发-active", | |||
| "font_class": "model-icon-active", | |||
| "unicode": "e610", | |||
| "unicode_decimal": 58896 | |||
| }, | |||
| { | |||
| "icon_id": "39969579", | |||
| "name": "系统管理-active", | |||
| "font_class": "system-icon-active", | |||
| "unicode": "e612", | |||
| "unicode_decimal": 58898 | |||
| }, | |||
| { | |||
| "icon_id": "39969578", | |||
| "name": "模型在线部署-active", | |||
| "font_class": "modelDseployment-icon-active", | |||
| "unicode": "e613", | |||
| "unicode_decimal": 58899 | |||
| }, | |||
| { | |||
| "icon_id": "39969565", | |||
| "name": "模型开发", | |||
| "font_class": "model-icon", | |||
| "unicode": "e614", | |||
| "unicode_decimal": 58900 | |||
| }, | |||
| { | |||
| "icon_id": "39969577", | |||
| "name": "应用开发", | |||
| "font_class": "appsDeployment-icon", | |||
| "unicode": "e615", | |||
| "unicode_decimal": 58901 | |||
| }, | |||
| { | |||
| "icon_id": "39969576", | |||
| "name": "工作空间-active", | |||
| "font_class": "workspace-icon-active", | |||
| "unicode": "e616", | |||
| "unicode_decimal": 58902 | |||
| }, | |||
| { | |||
| "icon_id": "39969574", | |||
| "name": "应用开发-active", | |||
| "font_class": "appsDeployment-icon-active", | |||
| "unicode": "e617", | |||
| "unicode_decimal": 58903 | |||
| } | |||
| ] | |||
| } | |||
| @@ -1,7 +1,7 @@ | |||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||
| import IconSelector from '@/components/IconSelector'; | |||
| import KFModal from '@/components/KFModal'; | |||
| import { createIcon } from '@/utils/IconUtil'; | |||
| import MenuIconSelector from '@/components/MenuIconSelector'; | |||
| import { openAntdModal } from '@/utils/modal'; | |||
| import { | |||
| ProForm, | |||
| ProFormDigit, | |||
| @@ -27,31 +27,39 @@ export type MenuFormProps = { | |||
| menuTree: DataNode[]; | |||
| }; | |||
| const formLayout = { | |||
| labelCol: { span: 8 }, | |||
| wrapperCol: { span: 16 }, | |||
| }; | |||
| const formItemLayout = { | |||
| labelCol: { span: 4 }, | |||
| wrapperCol: { span: 20 }, | |||
| }; | |||
| const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| const [form] = Form.useForm(); | |||
| const [menuTypeId, setMenuTypeId] = useState<any>('M'); | |||
| const [menuTypeId, setMenuTypeId] = useState<any>(); | |||
| const [menuIconName, setMenuIconName] = useState<any>(); | |||
| const [iconSelectorOpen, setIconSelectorOpen] = useState<boolean>(false); | |||
| const { menuTree, visibleOptions, statusOptions } = props; | |||
| useEffect(() => { | |||
| form.resetFields(); | |||
| setMenuIconName(props.values.icon); | |||
| setMenuTypeId(props.values.menuType ?? 'M'); | |||
| form.setFieldsValue({ | |||
| menuId: props.values.menuId, | |||
| menuName: props.values.menuName, | |||
| parentId: props.values.parentId, | |||
| orderNum: props.values.orderNum, | |||
| parentId: props.values.parentId ?? 0, | |||
| orderNum: props.values.orderNum ?? 1, | |||
| path: props.values.path, | |||
| component: props.values.component, | |||
| query: props.values.query, | |||
| isFrame: props.values.isFrame, | |||
| isCache: props.values.isCache, | |||
| menuType: props.values.menuType, | |||
| visible: props.values.visible, | |||
| status: props.values.status, | |||
| isFrame: props.values.isFrame ?? '1', | |||
| isCache: props.values.isCache ?? '1', | |||
| menuType: props.values.menuType ?? 'M', | |||
| visible: props.values.visible ?? Object.keys(visibleOptions)[0], | |||
| status: props.values.status ?? Object.keys(statusOptions)[0], | |||
| perms: props.values.perms, | |||
| icon: props.values.icon, | |||
| createBy: props.values.createBy, | |||
| @@ -73,9 +81,20 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| props.onSubmit(values as MenuFormData); | |||
| }; | |||
| const selectIcon = () => { | |||
| const { close } = openAntdModal(MenuIconSelector, { | |||
| selectedIcon: menuIconName, | |||
| onOk: (icon) => { | |||
| setMenuIconName(icon); | |||
| form.setFieldsValue({ icon }); | |||
| close(); | |||
| }, | |||
| }); | |||
| }; | |||
| return ( | |||
| <KFModal | |||
| width={640} | |||
| width={680} | |||
| title={intl.formatMessage({ | |||
| id: 'system.menu.title', | |||
| defaultMessage: '编辑菜单权限', | |||
| @@ -92,6 +111,8 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| submitter={false} | |||
| layout="horizontal" | |||
| onFinish={handleFinish} | |||
| {...formLayout} | |||
| size="large" | |||
| > | |||
| <ProFormDigit | |||
| name="menuId" | |||
| @@ -110,6 +131,7 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| ]} | |||
| /> | |||
| <ProFormTreeSelect | |||
| {...formItemLayout} | |||
| name="parentId" | |||
| label={intl.formatMessage({ | |||
| id: 'system.menu.parent_id', | |||
| @@ -128,11 +150,9 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| ), | |||
| }, | |||
| ]} | |||
| fieldProps={{ | |||
| defaultValue: 0, | |||
| }} | |||
| /> | |||
| <ProFormRadio.Group | |||
| {...formItemLayout} | |||
| name="menuType" | |||
| valueEnum={{ | |||
| M: '目录', | |||
| @@ -151,13 +171,13 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| }, | |||
| ]} | |||
| fieldProps={{ | |||
| defaultValue: 'M', | |||
| onChange: (e) => { | |||
| setMenuTypeId(e.target.value); | |||
| }, | |||
| }} | |||
| /> | |||
| <ProFormSelect | |||
| {...formItemLayout} | |||
| name="icon" | |||
| label={intl.formatMessage({ | |||
| id: 'system.menu.icon', | |||
| @@ -165,10 +185,10 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| })} | |||
| valueEnum={{}} | |||
| hidden={menuTypeId === 'F'} | |||
| addonBefore={createIcon(menuIconName)} | |||
| // addonBefore={createIcon(menuIconName)} | |||
| fieldProps={{ | |||
| onClick: () => { | |||
| setIconSelectorOpen(true); | |||
| selectIcon(); | |||
| }, | |||
| }} | |||
| placeholder="请输入菜单图标" | |||
| @@ -209,9 +229,6 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| message: <FormattedMessage id="请输入显示顺序!" defaultMessage="请输入显示顺序!" />, | |||
| }, | |||
| ]} | |||
| fieldProps={{ | |||
| defaultValue: 1, | |||
| }} | |||
| /> | |||
| <ProFormRadio.Group | |||
| name="isFrame" | |||
| @@ -219,7 +236,6 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| 0: '是', | |||
| 1: '否', | |||
| }} | |||
| initialValue="1" | |||
| label={intl.formatMessage({ | |||
| id: 'system.menu.is_frame', | |||
| defaultMessage: '是否为外链', | |||
| @@ -235,9 +251,6 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| ), | |||
| }, | |||
| ]} | |||
| fieldProps={{ | |||
| defaultValue: '1', | |||
| }} | |||
| /> | |||
| <ProFormText | |||
| name="path" | |||
| @@ -323,9 +336,6 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| message: <FormattedMessage id="请输入是否缓存!" defaultMessage="请输入是否缓存!" />, | |||
| }, | |||
| ]} | |||
| fieldProps={{ | |||
| defaultValue: 0, | |||
| }} | |||
| /> | |||
| <ProFormRadio.Group | |||
| name="visible" | |||
| @@ -343,9 +353,6 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| message: <FormattedMessage id="请输入显示状态!" defaultMessage="请输入显示状态!" />, | |||
| }, | |||
| ]} | |||
| fieldProps={{ | |||
| defaultValue: '0', | |||
| }} | |||
| /> | |||
| <ProFormRadio.Group | |||
| valueEnum={statusOptions} | |||
| @@ -363,27 +370,8 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||
| message: <FormattedMessage id="请输入菜单状态!" defaultMessage="请输入菜单状态!" />, | |||
| }, | |||
| ]} | |||
| fieldProps={{ | |||
| defaultValue: '0', | |||
| }} | |||
| /> | |||
| </ProForm> | |||
| <KFModal | |||
| width={800} | |||
| open={iconSelectorOpen} | |||
| onCancel={() => { | |||
| setIconSelectorOpen(false); | |||
| }} | |||
| footer={null} | |||
| > | |||
| <IconSelector | |||
| onSelect={(name: string) => { | |||
| form.setFieldsValue({ icon: name }); | |||
| setMenuIconName(name); | |||
| setIconSelectorOpen(false); | |||
| }} | |||
| /> | |||
| </KFModal> | |||
| </KFModal> | |||
| ); | |||
| }; | |||