| @@ -5,6 +5,6 @@ module.exports = { | |||||
| REACT_APP_ENV: true, | REACT_APP_ENV: true, | ||||
| }, | }, | ||||
| rules: { | rules: { | ||||
| "@typescript-eslint/no-use-before-define": "off" | |||||
| } | |||||
| '@typescript-eslint/no-use-before-define': 'off', | |||||
| }, | |||||
| }; | }; | ||||
| @@ -9,7 +9,7 @@ const Settings: ProLayoutProps & { | |||||
| } = { | } = { | ||||
| navTheme: 'light', | navTheme: 'light', | ||||
| // 拂晓蓝 | // 拂晓蓝 | ||||
| colorPrimary: '#1890ff', | |||||
| colorPrimary: '#1664ff', | |||||
| layout: 'mix', | layout: 'mix', | ||||
| contentWidth: 'Fluid', | contentWidth: 'Fluid', | ||||
| fixedHeader: false, | fixedHeader: false, | ||||
| @@ -19,7 +19,7 @@ const Settings: ProLayoutProps & { | |||||
| title: '复杂智能软件', | title: '复杂智能软件', | ||||
| pwa: true, | pwa: true, | ||||
| logo: '/assets/images/left-top-logo.png', | logo: '/assets/images/left-top-logo.png', | ||||
| iconfontUrl: '', | |||||
| iconfontUrl: '', | |||||
| token: { | token: { | ||||
| // 参见ts声明,demo 见文档,通过token 修改样式 | // 参见ts声明,demo 见文档,通过token 修改样式 | ||||
| //https://procomponents.ant.design/components/layout#%E9%80%9A%E8%BF%87-token-%E4%BF%AE%E6%94%B9%E6%A0%B7%E5%BC%8F | //https://procomponents.ant.design/components/layout#%E9%80%9A%E8%BF%87-token-%E4%BF%AE%E6%94%B9%E6%A0%B7%E5%BC%8F | ||||
| @@ -4,19 +4,10 @@ | |||||
| "private": true, | "private": true, | ||||
| "description": "An out-of-box UI solution for enterprise applications", | "description": "An out-of-box UI solution for enterprise applications", | ||||
| "scripts": { | "scripts": { | ||||
| "dev": "npm run start:dev", | |||||
| "analyze": "cross-env ANALYZE=1 max build", | |||||
| "build": "max build", | "build": "max build", | ||||
| "deploy": "npm run build && npm run gh-pages", | "deploy": "npm run build && npm run gh-pages", | ||||
| "preview": "npm run build && max preview --port 8000", | |||||
| "serve": "umi-serve", | |||||
| "start": "cross-env UMI_ENV=dev max dev", | |||||
| "start:dev": "cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev max dev", | |||||
| "start:no-mock": "cross-env MOCK=none UMI_ENV=dev max dev", | |||||
| "start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=dev max dev", | |||||
| "start:test": "cross-env REACT_APP_ENV=test MOCK=none UMI_ENV=dev max dev", | |||||
| "test": "jest", | |||||
| "test:coverage": "npm run jest -- --coverage", | |||||
| "test:update": "npm run jest -- -u", | |||||
| "dev": "npm run start:dev", | |||||
| "docker-hub:build": "docker build -f Dockerfile.hub -t ant-design-pro ./", | "docker-hub:build": "docker build -f Dockerfile.hub -t ant-design-pro ./", | ||||
| "docker-prod:build": "docker-compose -f ./docker/docker-compose.yml build", | "docker-prod:build": "docker-compose -f ./docker/docker-compose.yml build", | ||||
| "docker-prod:dev": "docker-compose -f ./docker/docker-compose.yml up", | "docker-prod:dev": "docker-compose -f ./docker/docker-compose.yml up", | ||||
| @@ -24,7 +15,6 @@ | |||||
| "docker:dev": "docker-compose -f ./docker/docker-compose.dev.yml up", | "docker:dev": "docker-compose -f ./docker/docker-compose.dev.yml up", | ||||
| "docker:push": "npm run docker-hub:build && npm run docker:tag && docker push antdesign/ant-design-pro", | "docker:push": "npm run docker-hub:build && npm run docker:tag && docker push antdesign/ant-design-pro", | ||||
| "docker:tag": "docker tag ant-design-pro antdesign/ant-design-pro", | "docker:tag": "docker tag ant-design-pro antdesign/ant-design-pro", | ||||
| "analyze": "cross-env ANALYZE=1 max build", | |||||
| "gh-pages": "gh-pages -d dist", | "gh-pages": "gh-pages -d dist", | ||||
| "i18n-remove": "pro i18n-remove --locale=zh-CN --write", | "i18n-remove": "pro i18n-remove --locale=zh-CN --write", | ||||
| "postinstall": "max setup", | "postinstall": "max setup", | ||||
| @@ -38,8 +28,18 @@ | |||||
| "openapi": "max openapi", | "openapi": "max openapi", | ||||
| "prepare": "cd .. && husky install", | "prepare": "cd .. && husky install", | ||||
| "prettier": "prettier -c --write \"**/**.{js,jsx,tsx,ts,less,md,json}\"", | "prettier": "prettier -c --write \"**/**.{js,jsx,tsx,ts,less,md,json}\"", | ||||
| "tsc": "tsc --noEmit", | |||||
| "record": "cross-env NODE_ENV=development REACT_APP_ENV=test max record --scene=login" | |||||
| "preview": "npm run build && max preview --port 8000", | |||||
| "record": "cross-env NODE_ENV=development REACT_APP_ENV=test max record --scene=login", | |||||
| "serve": "umi-serve", | |||||
| "start": "cross-env UMI_ENV=dev max dev", | |||||
| "start:dev": "cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev max dev", | |||||
| "start:no-mock": "cross-env MOCK=none UMI_ENV=dev max dev", | |||||
| "start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=dev max dev", | |||||
| "start:test": "cross-env REACT_APP_ENV=test MOCK=none UMI_ENV=dev max dev", | |||||
| "test": "jest", | |||||
| "test:coverage": "npm run jest -- --coverage", | |||||
| "test:update": "npm run jest -- -u", | |||||
| "tsc": "tsc --noEmit" | |||||
| }, | }, | ||||
| "lint-staged": { | "lint-staged": { | ||||
| "**/*.{js,jsx,ts,tsx}": "npm run lint-staged:js", | "**/*.{js,jsx,ts,tsx}": "npm run lint-staged:js", | ||||
| @@ -2,7 +2,6 @@ import RightContent from '@/components/RightContent'; | |||||
| import type { Settings as LayoutSettings } from '@ant-design/pro-components'; | import type { Settings as LayoutSettings } from '@ant-design/pro-components'; | ||||
| import type { RunTimeLayoutConfig } from '@umijs/max'; | import type { RunTimeLayoutConfig } from '@umijs/max'; | ||||
| import { history } from '@umijs/max'; | import { history } from '@umijs/max'; | ||||
| import axios from 'axios'; | |||||
| import defaultSettings from '../config/defaultSettings'; | import defaultSettings from '../config/defaultSettings'; | ||||
| import '../public/fonts/font.css'; | import '../public/fonts/font.css'; | ||||
| import { getAccessToken } from './access'; | import { getAccessToken } from './access'; | ||||
| @@ -17,8 +16,7 @@ import { | |||||
| setRemoteMenu, | setRemoteMenu, | ||||
| } from './services/session'; | } from './services/session'; | ||||
| export { requestConfig as request } from './requestConfig'; | export { requestConfig as request } from './requestConfig'; | ||||
| axios.defaults.baseUrl = 'http://172.20.32.150:8082'; | |||||
| const isDev = process.env.NODE_ENV === 'development'; | |||||
| // const isDev = process.env.NODE_ENV === 'development'; | |||||
| /** | /** | ||||
| * @see https://umijs.org/zh-CN/plugins/plugin-initial-state | * @see https://umijs.org/zh-CN/plugins/plugin-initial-state | ||||
| @@ -34,10 +32,9 @@ export async function getInitialState(): Promise<{ | |||||
| const response = await getUserInfo({ | const response = await getUserInfo({ | ||||
| skipErrorHandler: true, | skipErrorHandler: true, | ||||
| }); | }); | ||||
| if (response.user.avatar === '') { | |||||
| response.user.avatar = | |||||
| 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png'; | |||||
| } | |||||
| response.user.avatar = | |||||
| response.user.avatar || | |||||
| 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png'; | |||||
| return { | return { | ||||
| ...response.user, | ...response.user, | ||||
| permissions: response.permissions, | permissions: response.permissions, | ||||
| @@ -66,7 +63,7 @@ export async function getInitialState(): Promise<{ | |||||
| } | } | ||||
| // ProLayout 支持的api https://procomponents.ant.design/components/layout | // ProLayout 支持的api https://procomponents.ant.design/components/layout | ||||
| export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => { | |||||
| export const layout: RunTimeLayoutConfig = ({ initialState }) => { | |||||
| return { | return { | ||||
| rightContentRender: () => <RightContent />, | rightContentRender: () => <RightContent />, | ||||
| waterMarkProps: { | waterMarkProps: { | ||||
| @@ -155,26 +152,26 @@ export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) = | |||||
| }; | }; | ||||
| }; | }; | ||||
| export async function onRouteChange({ clientRoutes, location }) { | |||||
| export async function onRouteChange({ clientRoutes, location }: any) { | |||||
| const menus = getRemoteMenu(); | const menus = getRemoteMenu(); | ||||
| // console.log('onRouteChange', clientRoutes, location, menus); | |||||
| console.log('onRouteChange', clientRoutes, location, menus); | |||||
| if (menus === null && location.pathname !== PageEnum.LOGIN) { | if (menus === null && location.pathname !== PageEnum.LOGIN) { | ||||
| console.log('refresh'); | console.log('refresh'); | ||||
| history.go(0); | history.go(0); | ||||
| } | } | ||||
| } | } | ||||
| // export function patchRoutes({ routes, routeComponents }) { | |||||
| // console.log('patchRoutes', routes, routeComponents); | |||||
| // } | |||||
| export function patchRoutes({ routes, routeComponents }: any) { | |||||
| console.log('patchRoutes', routes, routeComponents); | |||||
| } | |||||
| export async function patchClientRoutes({ routes }) { | |||||
| // console.log('patchClientRoutes', routes); | |||||
| export async function patchClientRoutes({ routes }: any) { | |||||
| console.log('patchClientRoutes', routes); | |||||
| patchRouteWithRemoteMenus(routes); | patchRouteWithRemoteMenus(routes); | ||||
| } | } | ||||
| export function render(oldRender: () => void) { | export function render(oldRender: () => void) { | ||||
| // console.log('render get routers', oldRender) | |||||
| console.log('render get routers', oldRender); | |||||
| const token = getAccessToken(); | const token = getAccessToken(); | ||||
| if (!token || token?.length === 0) { | if (!token || token?.length === 0) { | ||||
| oldRender(); | oldRender(); | ||||
| @@ -1,7 +1,7 @@ | |||||
| import React from 'react'; | |||||
| import { Tag } from 'antd'; | |||||
| import { ProSchemaValueEnumType } from '@ant-design/pro-components'; | import { ProSchemaValueEnumType } from '@ant-design/pro-components'; | ||||
| import { Tag } from 'antd'; | |||||
| import { DefaultOptionType } from 'antd/es/select'; | import { DefaultOptionType } from 'antd/es/select'; | ||||
| import React from 'react'; | |||||
| /* * | /* * | ||||
| * | * | ||||
| @@ -11,105 +11,101 @@ import { DefaultOptionType } from 'antd/es/select'; | |||||
| * */ | * */ | ||||
| export interface DictValueEnumType extends ProSchemaValueEnumType { | export interface DictValueEnumType extends ProSchemaValueEnumType { | ||||
| id?: string | number; | |||||
| key?: string | number; | |||||
| value: string | number; | |||||
| label: string; | |||||
| listClass?: string; | |||||
| id?: string | number; | |||||
| key?: string | number; | |||||
| value: string | number; | |||||
| label: string; | |||||
| listClass?: string; | |||||
| } | } | ||||
| export interface DictOptionType extends DefaultOptionType { | export interface DictOptionType extends DefaultOptionType { | ||||
| id?: string | number; | |||||
| key?: string | number; | |||||
| text: string; | |||||
| listClass?: string; | |||||
| id?: string | number; | |||||
| key?: string | number; | |||||
| text: string; | |||||
| listClass?: string; | |||||
| } | } | ||||
| export type DictValueEnumObj = Record<string | number, DictValueEnumType>; | export type DictValueEnumObj = Record<string | number, DictValueEnumType>; | ||||
| export type DictTagProps = { | export type DictTagProps = { | ||||
| key?: string; | |||||
| value?: string | number; | |||||
| enums?: DictValueEnumObj; | |||||
| options?: DictOptionType[]; | |||||
| key?: string; | |||||
| value?: string | number; | |||||
| enums?: DictValueEnumObj; | |||||
| options?: DictOptionType[]; | |||||
| }; | }; | ||||
| const DictTag: React.FC<DictTagProps> = (props) => { | const DictTag: React.FC<DictTagProps> = (props) => { | ||||
| function getDictColor(type?: string) { | |||||
| switch (type) { | |||||
| case 'primary': | |||||
| return 'blue'; | |||||
| case 'success': | |||||
| return 'success'; | |||||
| case 'info': | |||||
| return 'green'; | |||||
| case 'warning': | |||||
| return 'warning'; | |||||
| case 'danger': | |||||
| return 'error'; | |||||
| case 'default': | |||||
| default: | |||||
| return 'default'; | |||||
| } | |||||
| function getDictColor(type?: string) { | |||||
| switch (type) { | |||||
| case 'primary': | |||||
| return 'blue'; | |||||
| case 'success': | |||||
| return 'success'; | |||||
| case 'info': | |||||
| return 'green'; | |||||
| case 'warning': | |||||
| return 'warning'; | |||||
| case 'danger': | |||||
| return 'error'; | |||||
| case 'default': | |||||
| default: | |||||
| return 'default'; | |||||
| } | } | ||||
| } | |||||
| function getDictLabelByValue(value: string | number | undefined): string { | |||||
| if (value === undefined) { | |||||
| return ''; | |||||
| } | |||||
| if (props.enums) { | |||||
| const item = props.enums[value]; | |||||
| return item.label; | |||||
| } | |||||
| if (props.options) { | |||||
| if (!Array.isArray(props.options)) { | |||||
| console.log('DictTag options is no array!') | |||||
| return ''; | |||||
| } | |||||
| for (const item of props.options) { | |||||
| if (item.value === value) { | |||||
| return item.text; | |||||
| } | |||||
| } | |||||
| function getDictLabelByValue(value: string | number | undefined): string { | |||||
| if (value === undefined) { | |||||
| return ''; | |||||
| } | |||||
| if (props.enums) { | |||||
| const item = props.enums[value]; | |||||
| return item.label; | |||||
| } | |||||
| if (props.options) { | |||||
| if (!Array.isArray(props.options)) { | |||||
| console.log('DictTag options is no array!'); | |||||
| return ''; | |||||
| } | |||||
| for (const item of props.options) { | |||||
| if (item.value === value) { | |||||
| return item.text; | |||||
| } | } | ||||
| return String(props.value); | |||||
| } | |||||
| } | } | ||||
| return String(props.value); | |||||
| } | |||||
| function getDictListClassByValue(value: string | number | undefined): string { | |||||
| if (value === undefined) { | |||||
| return 'default'; | |||||
| } | |||||
| if (props.enums) { | |||||
| const item = props.enums[value]; | |||||
| return item.listClass || 'default'; | |||||
| } | |||||
| if (props.options) { | |||||
| if (!Array.isArray(props.options)) { | |||||
| console.log('DictTag options is no array!') | |||||
| return 'default'; | |||||
| } | |||||
| for (const item of props.options) { | |||||
| if (item.value === value) { | |||||
| return item.listClass || 'default'; | |||||
| } | |||||
| } | |||||
| function getDictListClassByValue(value: string | number | undefined): string { | |||||
| if (value === undefined) { | |||||
| return 'default'; | |||||
| } | |||||
| if (props.enums) { | |||||
| const item = props.enums[value]; | |||||
| return item.listClass || 'default'; | |||||
| } | |||||
| if (props.options) { | |||||
| if (!Array.isArray(props.options)) { | |||||
| console.log('DictTag options is no array!'); | |||||
| return 'default'; | |||||
| } | |||||
| for (const item of props.options) { | |||||
| if (item.value === value) { | |||||
| return item.listClass || 'default'; | |||||
| } | } | ||||
| return String(props.value); | |||||
| } | |||||
| } | } | ||||
| return String(props.value); | |||||
| } | |||||
| const getTagColor = () => { | |||||
| return getDictColor(getDictListClassByValue(props.value).toLowerCase()); | |||||
| }; | |||||
| const getTagText = (): string => { | |||||
| return getDictLabelByValue(props.value); | |||||
| }; | |||||
| const getTagColor = () => { | |||||
| return getDictColor(getDictListClassByValue(props.value).toLowerCase()); | |||||
| }; | |||||
| return ( | |||||
| <Tag color={getTagColor()}>{getTagText()}</Tag> | |||||
| ) | |||||
| } | |||||
| const getTagText = (): string => { | |||||
| return getDictLabelByValue(props.value); | |||||
| }; | |||||
| return <Tag color={getTagColor()}>{getTagText()}</Tag>; | |||||
| }; | |||||
| export default DictTag; | |||||
| export default DictTag; | |||||
| @@ -1,8 +1,8 @@ | |||||
| import { useEmotionCss } from '@ant-design/use-emotion-css'; | |||||
| import { Dropdown } from 'antd'; | import { Dropdown } from 'antd'; | ||||
| import type { DropDownProps } from 'antd/es/dropdown'; | import type { DropDownProps } from 'antd/es/dropdown'; | ||||
| import React from 'react'; | |||||
| import { useEmotionCss } from '@ant-design/use-emotion-css'; | |||||
| import classNames from 'classnames'; | import classNames from 'classnames'; | ||||
| import React from 'react'; | |||||
| export type HeaderDropdownProps = { | export type HeaderDropdownProps = { | ||||
| overlayClassName?: string; | overlayClassName?: string; | ||||
| @@ -1,8 +1,8 @@ | |||||
| import { useIntl } from '@umijs/max'; | |||||
| import * as React from 'react'; | import * as React from 'react'; | ||||
| import CopyableIcon from './CopyableIcon'; | import CopyableIcon from './CopyableIcon'; | ||||
| import type { ThemeType } from './index'; | |||||
| import type { CategoriesKeys } from './fields'; | import type { CategoriesKeys } from './fields'; | ||||
| import { useIntl } from '@umijs/max'; | |||||
| import type { ThemeType } from './index'; | |||||
| import styles from './style.less'; | import styles from './style.less'; | ||||
| interface CategoryProps { | interface CategoryProps { | ||||
| @@ -13,8 +13,7 @@ interface CategoryProps { | |||||
| onSelect: (type: string, name: string) => any; | onSelect: (type: string, name: string) => any; | ||||
| } | } | ||||
| const Category: React.FC<CategoryProps> = props => { | |||||
| const Category: React.FC<CategoryProps> = (props) => { | |||||
| const { icons, title, newIcons, theme } = props; | const { icons, title, newIcons, theme } = props; | ||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const [justCopied, setJustCopied] = React.useState<string | null>(null); | const [justCopied, setJustCopied] = React.useState<string | null>(null); | ||||
| @@ -40,12 +39,14 @@ const Category: React.FC<CategoryProps> = props => { | |||||
| return ( | return ( | ||||
| <div> | <div> | ||||
| <h4>{intl.formatMessage({ | |||||
| id: `app.docs.components.icon.category.${title}`, | |||||
| defaultMessage: '信息', | |||||
| })}</h4> | |||||
| <h4> | |||||
| {intl.formatMessage({ | |||||
| id: `app.docs.components.icon.category.${title}`, | |||||
| defaultMessage: '信息', | |||||
| })} | |||||
| </h4> | |||||
| <ul className={styles.anticonsList}> | <ul className={styles.anticonsList}> | ||||
| {icons.map(name => ( | |||||
| {icons.map((name) => ( | |||||
| <CopyableIcon | <CopyableIcon | ||||
| key={name} | key={name} | ||||
| name={name} | name={name} | ||||
| @@ -1,7 +1,7 @@ | |||||
| import * as React from 'react'; | |||||
| import * as AntdIcons from '@ant-design/icons'; | |||||
| import { Tooltip } from 'antd'; | import { Tooltip } from 'antd'; | ||||
| import classNames from 'classnames'; | import classNames from 'classnames'; | ||||
| import * as AntdIcons from '@ant-design/icons'; | |||||
| import * as React from 'react'; | |||||
| import type { ThemeType } from './index'; | import type { ThemeType } from './index'; | ||||
| import styles from './style.less'; | import styles from './style.less'; | ||||
| @@ -17,23 +17,20 @@ export interface CopyableIconProps { | |||||
| onSelect: (type: string, text: string) => any; | onSelect: (type: string, text: string) => any; | ||||
| } | } | ||||
| const CopyableIcon: React.FC<CopyableIconProps> = ({ | |||||
| name, | |||||
| justCopied, | |||||
| onSelect, | |||||
| theme, | |||||
| }) => { | |||||
| const CopyableIcon: React.FC<CopyableIconProps> = ({ name, justCopied, onSelect, theme }) => { | |||||
| const className = classNames({ | const className = classNames({ | ||||
| copied: justCopied === name, | copied: justCopied === name, | ||||
| [theme]: !!theme, | [theme]: !!theme, | ||||
| }); | }); | ||||
| return ( | return ( | ||||
| <li className={className} | |||||
| <li | |||||
| className={className} | |||||
| onClick={() => { | onClick={() => { | ||||
| if (onSelect) { | if (onSelect) { | ||||
| onSelect(theme, name); | onSelect(theme, name); | ||||
| } | } | ||||
| }}> | |||||
| }} | |||||
| > | |||||
| <Tooltip title={name}> | <Tooltip title={name}> | ||||
| {React.createElement(allIcons[name], { className: styles.anticon })} | {React.createElement(allIcons[name], { className: styles.anticon })} | ||||
| </Tooltip> | </Tooltip> | ||||
| @@ -1,7 +1,7 @@ | |||||
| import React, { useCallback, useEffect, useState } from 'react'; | |||||
| import { Upload, Tooltip, Popover, Modal, Progress, Spin, Result } from 'antd'; | |||||
| import * as AntdIcons from '@ant-design/icons'; | import * as AntdIcons from '@ant-design/icons'; | ||||
| import { useIntl } from '@umijs/max'; | import { useIntl } from '@umijs/max'; | ||||
| import { Modal, Popover, Progress, Result, Spin, Tooltip, Upload } from 'antd'; | |||||
| import React, { useCallback, useEffect, useState } from 'react'; | |||||
| import './style.less'; | import './style.less'; | ||||
| const allIcons: { [key: string]: any } = AntdIcons; | const allIcons: { [key: string]: any } = AntdIcons; | ||||
| @@ -34,7 +34,7 @@ interface iconObject { | |||||
| const PicSearcher: React.FC = () => { | const PicSearcher: React.FC = () => { | ||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const {formatMessage} = intl; | |||||
| const { formatMessage } = intl; | |||||
| const [state, setState] = useState<PicSearcherState>({ | const [state, setState] = useState<PicSearcherState>({ | ||||
| loading: false, | loading: false, | ||||
| modalOpen: false, | modalOpen: false, | ||||
| @@ -53,15 +53,15 @@ const PicSearcher: React.FC = () => { | |||||
| event_label: icons[0].className, | event_label: icons[0].className, | ||||
| }); | }); | ||||
| } | } | ||||
| icons = icons.map(i => ({ score: i.score, type: i.className.replace(/\s/g, '-') })); | |||||
| setState(prev => ({ ...prev, loading: false, error: false, icons })); | |||||
| icons = icons.map((i) => ({ score: i.score, type: i.className.replace(/\s/g, '-') })); | |||||
| setState((prev) => ({ ...prev, loading: false, error: false, icons })); | |||||
| } catch { | } catch { | ||||
| setState(prev => ({ ...prev, loading: false, error: true })); | |||||
| setState((prev) => ({ ...prev, loading: false, error: true })); | |||||
| } | } | ||||
| }; | }; | ||||
| // eslint-disable-next-line class-methods-use-this | // eslint-disable-next-line class-methods-use-this | ||||
| const toImage = (url: string) => | const toImage = (url: string) => | ||||
| new Promise(resolve => { | |||||
| new Promise((resolve) => { | |||||
| const img = new Image(); | const img = new Image(); | ||||
| img.setAttribute('crossOrigin', 'anonymous'); | img.setAttribute('crossOrigin', 'anonymous'); | ||||
| img.src = url; | img.src = url; | ||||
| @@ -71,11 +71,11 @@ const PicSearcher: React.FC = () => { | |||||
| }); | }); | ||||
| const uploadFile = useCallback((file: File) => { | const uploadFile = useCallback((file: File) => { | ||||
| setState(prev => ({ ...prev, loading: true })); | |||||
| setState((prev) => ({ ...prev, loading: true })); | |||||
| const reader = new FileReader(); | const reader = new FileReader(); | ||||
| reader.onload = () => { | reader.onload = () => { | ||||
| toImage(reader.result as string).then(predict); | toImage(reader.result as string).then(predict); | ||||
| setState(prev => ({ | |||||
| setState((prev) => ({ | |||||
| ...prev, | ...prev, | ||||
| fileList: [{ uid: 1, name: file.name, status: 'done', url: reader.result }], | fileList: [{ uid: 1, name: file.name, status: 'done', url: reader.result }], | ||||
| })); | })); | ||||
| @@ -99,7 +99,7 @@ const PicSearcher: React.FC = () => { | |||||
| } | } | ||||
| }, []); | }, []); | ||||
| const toggleModal = useCallback(() => { | const toggleModal = useCallback(() => { | ||||
| setState(prev => ({ | |||||
| setState((prev) => ({ | |||||
| ...prev, | ...prev, | ||||
| modalOpen: !prev.modalOpen, | modalOpen: !prev.modalOpen, | ||||
| popoverVisible: false, | popoverVisible: false, | ||||
| @@ -115,12 +115,12 @@ const PicSearcher: React.FC = () => { | |||||
| const script = document.createElement('script'); | const script = document.createElement('script'); | ||||
| script.onload = async () => { | script.onload = async () => { | ||||
| await window.antdIconClassifier.load(); | await window.antdIconClassifier.load(); | ||||
| setState(prev => ({ ...prev, modelLoaded: true })); | |||||
| setState((prev) => ({ ...prev, modelLoaded: true })); | |||||
| document.addEventListener('paste', onPaste); | document.addEventListener('paste', onPaste); | ||||
| }; | }; | ||||
| script.src = 'https://cdn.jsdelivr.net/gh/lewis617/antd-icon-classifier@0.0/dist/main.js'; | script.src = 'https://cdn.jsdelivr.net/gh/lewis617/antd-icon-classifier@0.0/dist/main.js'; | ||||
| document.head.appendChild(script); | document.head.appendChild(script); | ||||
| setState(prev => ({ ...prev, popoverVisible: !localStorage.getItem('disableIconTip') })); | |||||
| setState((prev) => ({ ...prev, popoverVisible: !localStorage.getItem('disableIconTip') })); | |||||
| return () => { | return () => { | ||||
| document.removeEventListener('paste', onPaste); | document.removeEventListener('paste', onPaste); | ||||
| }; | }; | ||||
| @@ -129,7 +129,7 @@ const PicSearcher: React.FC = () => { | |||||
| return ( | return ( | ||||
| <div className="iconPicSearcher"> | <div className="iconPicSearcher"> | ||||
| <Popover | <Popover | ||||
| content={formatMessage({id: 'app.docs.components.icon.pic-searcher.intro'})} | |||||
| content={formatMessage({ id: 'app.docs.components.icon.pic-searcher.intro' })} | |||||
| open={state.popoverVisible} | open={state.popoverVisible} | ||||
| > | > | ||||
| <AntdIcons.CameraOutlined className="icon-pic-btn" onClick={toggleModal} /> | <AntdIcons.CameraOutlined className="icon-pic-btn" onClick={toggleModal} /> | ||||
| @@ -148,7 +148,6 @@ const PicSearcher: React.FC = () => { | |||||
| spinning={!state.modelLoaded} | spinning={!state.modelLoaded} | ||||
| tip={formatMessage({ | tip={formatMessage({ | ||||
| id: 'app.docs.components.icon.pic-searcher.modelloading', | id: 'app.docs.components.icon.pic-searcher.modelloading', | ||||
| })} | })} | ||||
| > | > | ||||
| <div style={{ height: 100 }} /> | <div style={{ height: 100 }} /> | ||||
| @@ -158,7 +157,7 @@ const PicSearcher: React.FC = () => { | |||||
| <Dragger | <Dragger | ||||
| accept="image/jpeg, image/png" | accept="image/jpeg, image/png" | ||||
| listType="picture" | listType="picture" | ||||
| customRequest={o => uploadFile(o.file as File)} | |||||
| customRequest={(o) => uploadFile(o.file as File)} | |||||
| fileList={state.fileList} | fileList={state.fileList} | ||||
| showUploadList={{ showPreviewIcon: false, showRemoveIcon: false }} | showUploadList={{ showPreviewIcon: false, showRemoveIcon: false }} | ||||
| > | > | ||||
| @@ -166,21 +165,21 @@ const PicSearcher: React.FC = () => { | |||||
| <AntdIcons.InboxOutlined /> | <AntdIcons.InboxOutlined /> | ||||
| </p> | </p> | ||||
| <p className="ant-upload-text"> | <p className="ant-upload-text"> | ||||
| {formatMessage({id: 'app.docs.components.icon.pic-searcher.upload-text'})} | |||||
| {formatMessage({ id: 'app.docs.components.icon.pic-searcher.upload-text' })} | |||||
| </p> | </p> | ||||
| <p className="ant-upload-hint"> | <p className="ant-upload-hint"> | ||||
| {formatMessage({id: 'app.docs.components.icon.pic-searcher.upload-hint'})} | |||||
| {formatMessage({ id: 'app.docs.components.icon.pic-searcher.upload-hint' })} | |||||
| </p> | </p> | ||||
| </Dragger> | </Dragger> | ||||
| )} | )} | ||||
| <Spin | <Spin | ||||
| spinning={state.loading} | spinning={state.loading} | ||||
| tip={formatMessage({id: 'app.docs.components.icon.pic-searcher.matching'})} | |||||
| tip={formatMessage({ id: 'app.docs.components.icon.pic-searcher.matching' })} | |||||
| > | > | ||||
| <div className="icon-pic-search-result"> | <div className="icon-pic-search-result"> | ||||
| {state.icons.length > 0 && ( | {state.icons.length > 0 && ( | ||||
| <div className="result-tip"> | <div className="result-tip"> | ||||
| {formatMessage({id: 'app.docs.components.icon.pic-searcher.result-tip'})} | |||||
| {formatMessage({ id: 'app.docs.components.icon.pic-searcher.result-tip' })} | |||||
| </div> | </div> | ||||
| )} | )} | ||||
| <table> | <table> | ||||
| @@ -188,25 +187,27 @@ const PicSearcher: React.FC = () => { | |||||
| <thead> | <thead> | ||||
| <tr> | <tr> | ||||
| <th className="col-icon"> | <th className="col-icon"> | ||||
| {formatMessage({id: 'app.docs.components.icon.pic-searcher.th-icon'})} | |||||
| {formatMessage({ id: 'app.docs.components.icon.pic-searcher.th-icon' })} | |||||
| </th> | |||||
| <th> | |||||
| {formatMessage({ id: 'app.docs.components.icon.pic-searcher.th-score' })} | |||||
| </th> | </th> | ||||
| <th>{formatMessage({id: 'app.docs.components.icon.pic-searcher.th-score'})}</th> | |||||
| </tr> | </tr> | ||||
| </thead> | </thead> | ||||
| )} | )} | ||||
| <tbody> | <tbody> | ||||
| {state.icons.map(icon => { | |||||
| {state.icons.map((icon) => { | |||||
| const { type } = icon; | const { type } = icon; | ||||
| const iconName = `${type | const iconName = `${type | ||||
| .split('-') | .split('-') | ||||
| .map(str => `${str[0].toUpperCase()}${str.slice(1)}`) | |||||
| .map((str) => `${str[0].toUpperCase()}${str.slice(1)}`) | |||||
| .join('')}Outlined`; | .join('')}Outlined`; | ||||
| return ( | return ( | ||||
| <tr key={iconName}> | <tr key={iconName}> | ||||
| <td className="col-icon"> | <td className="col-icon"> | ||||
| <Tooltip title={icon.type} placement="right"> | |||||
| {React.createElement(allIcons[iconName])} | |||||
| </Tooltip> | |||||
| <Tooltip title={icon.type} placement="right"> | |||||
| {React.createElement(allIcons[iconName])} | |||||
| </Tooltip> | |||||
| </td> | </td> | ||||
| <td> | <td> | ||||
| <Progress percent={Math.ceil(icon.score * 100)} /> | <Progress percent={Math.ceil(icon.score * 100)} /> | ||||
| @@ -220,7 +221,9 @@ const PicSearcher: React.FC = () => { | |||||
| <Result | <Result | ||||
| status="500" | status="500" | ||||
| title="503" | title="503" | ||||
| subTitle={formatMessage({id: 'app.docs.components.icon.pic-searcher.server-error'})} | |||||
| subTitle={formatMessage({ | |||||
| id: 'app.docs.components.icon.pic-searcher.server-error', | |||||
| })} | |||||
| /> | /> | ||||
| )} | )} | ||||
| </div> | </div> | ||||
| @@ -1,7 +1,7 @@ | |||||
| import * as AntdIcons from '@ant-design/icons/lib/icons'; | import * as AntdIcons from '@ant-design/icons/lib/icons'; | ||||
| const all = Object.keys(AntdIcons) | const all = Object.keys(AntdIcons) | ||||
| .map(n => n.replace(/(Outlined|Filled|TwoTone)$/, '')) | |||||
| .map((n) => n.replace(/(Outlined|Filled|TwoTone)$/, '')) | |||||
| .filter((n, i, arr) => arr.indexOf(n) === i); | .filter((n, i, arr) => arr.indexOf(n) === i); | ||||
| const direction = [ | const direction = [ | ||||
| @@ -206,7 +206,7 @@ const logo = [ | |||||
| const datum = [...direction, ...suggestion, ...editor, ...data, ...logo]; | const datum = [...direction, ...suggestion, ...editor, ...data, ...logo]; | ||||
| const other = all.filter(n => !datum.includes(n)); | |||||
| const other = all.filter((n) => !datum.includes(n)); | |||||
| export const categories = { | export const categories = { | ||||
| direction, | direction, | ||||
| @@ -1,13 +1,13 @@ | |||||
| import * as React from 'react'; | |||||
| import Icon, * as AntdIcons from '@ant-design/icons'; | import Icon, * as AntdIcons from '@ant-design/icons'; | ||||
| import { Radio, Input, Empty } from 'antd'; | |||||
| import { Empty, Input, Radio } from 'antd'; | |||||
| import type { RadioChangeEvent } from 'antd/es/radio/interface'; | import type { RadioChangeEvent } from 'antd/es/radio/interface'; | ||||
| import debounce from 'lodash/debounce'; | import debounce from 'lodash/debounce'; | ||||
| import * as React from 'react'; | |||||
| import Category from './Category'; | import Category from './Category'; | ||||
| import IconPicSearcher from './IconPicSearcher'; | import IconPicSearcher from './IconPicSearcher'; | ||||
| import { FilledIcon, OutlinedIcon, TwoToneIcon } from './themeIcons'; | |||||
| import type { CategoriesKeys } from './fields'; | import type { CategoriesKeys } from './fields'; | ||||
| import { categories } from './fields'; | import { categories } from './fields'; | ||||
| import { FilledIcon, OutlinedIcon, TwoToneIcon } from './themeIcons'; | |||||
| // import { useIntl } from '@umijs/max'; | // import { useIntl } from '@umijs/max'; | ||||
| export enum ThemeType { | export enum ThemeType { | ||||
| @@ -41,13 +41,13 @@ const IconSelector: React.FC<IconSelectorProps> = (props) => { | |||||
| const handleSearchIcon = React.useCallback( | const handleSearchIcon = React.useCallback( | ||||
| debounce((searchKey: string) => { | debounce((searchKey: string) => { | ||||
| setDisplayState(prevState => ({ ...prevState, searchKey })); | |||||
| setDisplayState((prevState) => ({ ...prevState, searchKey })); | |||||
| }), | }), | ||||
| [], | [], | ||||
| ); | ); | ||||
| const handleChangeTheme = React.useCallback((e: RadioChangeEvent) => { | const handleChangeTheme = React.useCallback((e: RadioChangeEvent) => { | ||||
| setDisplayState(prevState => ({ ...prevState, theme: e.target.value as ThemeType })); | |||||
| setDisplayState((prevState) => ({ ...prevState, theme: e.target.value as ThemeType })); | |||||
| }, []); | }, []); | ||||
| const renderCategories = React.useMemo<React.ReactNode | React.ReactNode[]>(() => { | const renderCategories = React.useMemo<React.ReactNode | React.ReactNode[]>(() => { | ||||
| @@ -62,15 +62,19 @@ const IconSelector: React.FC<IconSelectorProps> = (props) => { | |||||
| .replace(new RegExp(`^<([a-zA-Z]*)\\s/>$`, 'gi'), (_, name) => name) | .replace(new RegExp(`^<([a-zA-Z]*)\\s/>$`, 'gi'), (_, name) => name) | ||||
| .replace(/(Filled|Outlined|TwoTone)$/, '') | .replace(/(Filled|Outlined|TwoTone)$/, '') | ||||
| .toLowerCase(); | .toLowerCase(); | ||||
| iconList = iconList.filter((iconName:string) => iconName.toLowerCase().includes(matchKey)); | |||||
| iconList = iconList.filter((iconName: string) => | |||||
| iconName.toLowerCase().includes(matchKey), | |||||
| ); | |||||
| } | } | ||||
| // CopyrightCircle is same as Copyright, don't show it | // CopyrightCircle is same as Copyright, don't show it | ||||
| iconList = iconList.filter((icon:string) => icon !== 'CopyrightCircle'); | |||||
| iconList = iconList.filter((icon: string) => icon !== 'CopyrightCircle'); | |||||
| return { | return { | ||||
| category: key, | category: key, | ||||
| icons: iconList.map((iconName:string) => iconName + theme).filter((iconName:string) => allIcons[iconName]), | |||||
| icons: iconList | |||||
| .map((iconName: string) => iconName + theme) | |||||
| .filter((iconName: string) => allIcons[iconName]), | |||||
| }; | }; | ||||
| }) | }) | ||||
| .filter(({ icons }) => !!icons.length) | .filter(({ icons }) => !!icons.length) | ||||
| @@ -101,16 +105,16 @@ const IconSelector: React.FC<IconSelectorProps> = (props) => { | |||||
| buttonStyle="solid" | buttonStyle="solid" | ||||
| options={[ | options={[ | ||||
| { | { | ||||
| label: <Icon component={OutlinedIcon} />, | |||||
| value: ThemeType.Outlined | |||||
| label: <Icon component={OutlinedIcon} />, | |||||
| value: ThemeType.Outlined, | |||||
| }, | }, | ||||
| { | { | ||||
| label: <Icon component={FilledIcon} />, | label: <Icon component={FilledIcon} />, | ||||
| value: ThemeType.Filled | |||||
| value: ThemeType.Filled, | |||||
| }, | }, | ||||
| { | { | ||||
| label: <Icon component={TwoToneIcon} />, | label: <Icon component={TwoToneIcon} />, | ||||
| value: ThemeType.TwoTone | |||||
| value: ThemeType.TwoTone, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| > | > | ||||
| @@ -128,7 +132,7 @@ const IconSelector: React.FC<IconSelectorProps> = (props) => { | |||||
| // placeholder={messages['app.docs.components.icon.search.placeholder']} | // placeholder={messages['app.docs.components.icon.search.placeholder']} | ||||
| style={{ margin: '0 10px', flex: 1 }} | style={{ margin: '0 10px', flex: 1 }} | ||||
| allowClear | allowClear | ||||
| onChange={e => handleSearchIcon(e.currentTarget.value)} | |||||
| onChange={(e) => handleSearchIcon(e.currentTarget.value)} | |||||
| size="large" | size="large" | ||||
| autoFocus | autoFocus | ||||
| suffix={<IconPicSearcher />} | suffix={<IconPicSearcher />} | ||||
| @@ -139,4 +143,4 @@ const IconSelector: React.FC<IconSelectorProps> = (props) => { | |||||
| ); | ); | ||||
| }; | }; | ||||
| export default IconSelector | |||||
| export default IconSelector; | |||||
| @@ -1,7 +1,6 @@ | |||||
| import * as React from 'react'; | import * as React from 'react'; | ||||
| export const FilledIcon: React.FC = props => { | |||||
| export const FilledIcon: React.FC = (props) => { | |||||
| const path = | const path = | ||||
| 'M864 64H160C107 64 64 107 64 160v' + | 'M864 64H160C107 64 64 107 64 160v' + | ||||
| '704c0 53 43 96 96 96h704c53 0 96-43 96-96V16' + | '704c0 53 43 96 96 96h704c53 0 96-43 96-96V16' + | ||||
| @@ -13,7 +12,7 @@ export const FilledIcon: React.FC = props => { | |||||
| ); | ); | ||||
| }; | }; | ||||
| export const OutlinedIcon: React.FC = props => { | |||||
| export const OutlinedIcon: React.FC = (props) => { | |||||
| const path = | const path = | ||||
| 'M864 64H160C107 64 64 107 64 160v7' + | 'M864 64H160C107 64 64 107 64 160v7' + | ||||
| '04c0 53 43 96 96 96h704c53 0 96-43 96-96V160c' + | '04c0 53 43 96 96 96h704c53 0 96-43 96-96V160c' + | ||||
| @@ -27,7 +26,7 @@ export const OutlinedIcon: React.FC = props => { | |||||
| ); | ); | ||||
| }; | }; | ||||
| export const TwoToneIcon: React.FC = props => { | |||||
| export const TwoToneIcon: React.FC = (props) => { | |||||
| const path = | const path = | ||||
| 'M16 512c0 273.932 222.066 496 496 49' + | 'M16 512c0 273.932 222.066 496 496 49' + | ||||
| '6s496-222.068 496-496S785.932 16 512 16 16 238.' + | '6s496-222.068 496-496S785.932 16 512 16 16 238.' + | ||||
| @@ -1,17 +1,17 @@ | |||||
| import { clearSessionToken } from '@/access'; | |||||
| import { PageEnum } from '@/enums/pagesEnums'; | |||||
| import { setRemoteMenu } from '@/services/session'; | |||||
| import { logout } from '@/services/system/auth'; | |||||
| import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons'; | import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons'; | ||||
| import { setAlpha } from '@ant-design/pro-components'; | |||||
| import { useEmotionCss } from '@ant-design/use-emotion-css'; | import { useEmotionCss } from '@ant-design/use-emotion-css'; | ||||
| import { history, useModel } from '@umijs/max'; | import { history, useModel } from '@umijs/max'; | ||||
| import { Avatar, Spin } from 'antd'; | import { Avatar, Spin } from 'antd'; | ||||
| import { setAlpha } from '@ant-design/pro-components'; | |||||
| import { stringify } from 'querystring'; | import { stringify } from 'querystring'; | ||||
| import type { MenuInfo } from 'rc-menu/lib/interface'; | import type { MenuInfo } from 'rc-menu/lib/interface'; | ||||
| import React, { useCallback } from 'react'; | import React, { useCallback } from 'react'; | ||||
| import { flushSync } from 'react-dom'; | import { flushSync } from 'react-dom'; | ||||
| import HeaderDropdown from '../HeaderDropdown'; | import HeaderDropdown from '../HeaderDropdown'; | ||||
| import { setRemoteMenu } from '@/services/session'; | |||||
| import { PageEnum } from '@/enums/pagesEnums'; | |||||
| import { clearSessionToken } from '@/access'; | |||||
| import { logout } from '@/services/system/auth'; | |||||
| export type GlobalHeaderRightProps = { | export type GlobalHeaderRightProps = { | ||||
| menu?: boolean; | menu?: boolean; | ||||
| @@ -1,4 +1,3 @@ | |||||
| export enum PageEnum { | export enum PageEnum { | ||||
| LOGIN = '/user/login' | |||||
| } | |||||
| LOGIN = '/user/login', | |||||
| } | |||||
| @@ -1 +0,0 @@ | |||||
| @@ -19,8 +19,8 @@ body, | |||||
| .ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed { | .ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed { | ||||
| left: unset; | left: unset; | ||||
| } | } | ||||
| .ant-layout-sider-children{ | |||||
| margin-top: 60px!important; | |||||
| .ant-layout-sider-children { | |||||
| margin-top: 60px !important; | |||||
| } | } | ||||
| canvas { | canvas { | ||||
| display: block; | display: block; | ||||
| @@ -31,67 +31,65 @@ body { | |||||
| -webkit-font-smoothing: antialiased; | -webkit-font-smoothing: antialiased; | ||||
| -moz-osx-font-smoothing: grayscale; | -moz-osx-font-smoothing: grayscale; | ||||
| } | } | ||||
| .ant-pro-layout .ant-pro-layout-content{ | |||||
| .ant-pro-layout .ant-pro-layout-content { | |||||
| padding: 10px; | padding: 10px; | ||||
| } | } | ||||
| .ant-pro-layout .ant-pro-layout-bg-list{ | |||||
| background:#f9fafb; | |||||
| .ant-pro-layout .ant-pro-layout-bg-list { | |||||
| background: #f9fafb; | |||||
| } | } | ||||
| .ant-table-wrapper .ant-table-thead >tr>th{ | |||||
| .ant-table-wrapper .ant-table-thead > tr > th { | |||||
| background-color: #fff; | background-color: #fff; | ||||
| } | } | ||||
| .ant-table-wrapper .ant-table-thead >tr>td{ | |||||
| .ant-table-wrapper .ant-table-thead > tr > td { | |||||
| background-color: #fff; | background-color: #fff; | ||||
| } | } | ||||
| .ant-menu-light .ant-menu-item-selected{ | |||||
| background:rgba(197, 232, 255, 0.8)!important; | |||||
| .ant-menu-light .ant-menu-item-selected { | |||||
| background: rgba(197, 232, 255, 0.8) !important; | |||||
| } | } | ||||
| .ant-pro-base-menu-inline{ | |||||
| .ant-pro-base-menu-inline { | |||||
| // height: 87vh; | // height: 87vh; | ||||
| background:#f2f5f7; | |||||
| border-radius:0px 20px 20px 0px; | |||||
| background: #f2f5f7; | |||||
| border-radius: 0px 20px 20px 0px; | |||||
| } | } | ||||
| .ant-pro-layout .ant-pro-layout-content{ | |||||
| .ant-pro-layout .ant-pro-layout-content { | |||||
| background-color: transparent; | background-color: transparent; | ||||
| } | } | ||||
| .ant-pro-global-header-logo img{ | |||||
| .ant-pro-global-header-logo img { | |||||
| height: 21px; | height: 21px; | ||||
| } | } | ||||
| .ant-pro-layout .ant-layout-sider.ant-pro-sider{ | |||||
| .ant-pro-layout .ant-layout-sider.ant-pro-sider { | |||||
| height: 87vh; | height: 87vh; | ||||
| } | } | ||||
| .ant-pro-layout .ant-pro-layout-container{ | |||||
| .ant-pro-layout .ant-pro-layout-container { | |||||
| height: 98vh; | height: 98vh; | ||||
| } | } | ||||
| .ant-pagination .ant-pagination-item-active a{ | |||||
| background:#1664ff; | |||||
| .ant-pagination .ant-pagination-item-active a { | |||||
| color: #fff; | color: #fff; | ||||
| background: #1664ff; | |||||
| border-color: #1664ff; | border-color: #1664ff; | ||||
| } | } | ||||
| .ant-pagination .ant-pagination-item-active a:hover{ | |||||
| background:rgba(22, 100, 255, 0.8); | |||||
| .ant-pagination .ant-pagination-item-active a:hover { | |||||
| color: #fff; | color: #fff; | ||||
| background: rgba(22, 100, 255, 0.8); | |||||
| border-color: rgba(22, 100, 255, 0.8); | border-color: rgba(22, 100, 255, 0.8); | ||||
| } | } | ||||
| // ::-webkit-scrollbar-button { | // ::-webkit-scrollbar-button { | ||||
| // background: #97a1bd; | // background: #97a1bd; | ||||
| // } | // } | ||||
| ::-webkit-scrollbar{ | |||||
| width:9px; | |||||
| ::-webkit-scrollbar { | |||||
| width: 9px; | |||||
| border-radius: 2px; | border-radius: 2px; | ||||
| } | } | ||||
| ::-webkit-scrollbar-thumb{ | |||||
| ::-webkit-scrollbar-thumb { | |||||
| // background-color: #9aa3bc!important; | // background-color: #9aa3bc!important; | ||||
| width: 7px; | width: 7px; | ||||
| background:rgba(77, 87, 123,0.5)!important; | |||||
| background: rgba(77, 87, 123, 0.5) !important; | |||||
| } | } | ||||
| ::-webkit-scrollbar-track{ | |||||
| ::-webkit-scrollbar-track { | |||||
| // background-color: #eaf1ff!important; | // background-color: #eaf1ff!important; | ||||
| width: 9px; | width: 9px; | ||||
| background:rgba(22, 100, 255,0.06)!important; | |||||
| background: rgba(22, 100, 255, 0.06) !important; | |||||
| } | } | ||||
| ul, | ul, | ||||
| ol { | ol { | ||||
| @@ -114,5 +112,3 @@ ol { | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,26 +1,26 @@ | |||||
| export default { | export default { | ||||
| 'app.docs.components.icon.search.placeholder': 'Search icons here, click icon to copy code', | |||||
| 'app.docs.components.icon.outlined': 'Outlined', | |||||
| 'app.docs.components.icon.filled': 'Filled', | |||||
| 'app.docs.components.icon.two-tone': 'Two Tone', | |||||
| 'app.docs.components.icon.category.direction': 'Directional Icons', | |||||
| 'app.docs.components.icon.category.suggestion': 'Suggested Icons', | |||||
| 'app.docs.components.icon.category.editor': 'Editor Icons', | |||||
| 'app.docs.components.icon.category.data': 'Data Icons', | |||||
| 'app.docs.components.icon.category.other': 'Application Icons', | |||||
| 'app.docs.components.icon.category.logo': 'Brand and Logos', | |||||
| 'app.docs.components.icon.pic-searcher.intro': | |||||
| 'AI Search by image is online, you are welcome to use it! 🎉', | |||||
| 'app.docs.components.icon.pic-searcher.title': 'Search by image', | |||||
| 'app.docs.components.icon.pic-searcher.upload-text': | |||||
| 'Click, drag, or paste file to this area to upload', | |||||
| 'app.docs.components.icon.pic-searcher.upload-hint': | |||||
| 'We will find the best matching icon based on the image provided', | |||||
| 'app.docs.components.icon.pic-searcher.server-error': | |||||
| 'Predict service is temporarily unavailable', | |||||
| 'app.docs.components.icon.pic-searcher.matching': 'Matching...', | |||||
| 'app.docs.components.icon.pic-searcher.modelloading': 'Model is loading...', | |||||
| 'app.docs.components.icon.pic-searcher.result-tip': 'Matched the following icons for you:', | |||||
| 'app.docs.components.icon.pic-searcher.th-icon': 'Icon', | |||||
| 'app.docs.components.icon.pic-searcher.th-score': 'Probability', | |||||
| 'app.docs.components.icon.search.placeholder': 'Search icons here, click icon to copy code', | |||||
| 'app.docs.components.icon.outlined': 'Outlined', | |||||
| 'app.docs.components.icon.filled': 'Filled', | |||||
| 'app.docs.components.icon.two-tone': 'Two Tone', | |||||
| 'app.docs.components.icon.category.direction': 'Directional Icons', | |||||
| 'app.docs.components.icon.category.suggestion': 'Suggested Icons', | |||||
| 'app.docs.components.icon.category.editor': 'Editor Icons', | |||||
| 'app.docs.components.icon.category.data': 'Data Icons', | |||||
| 'app.docs.components.icon.category.other': 'Application Icons', | |||||
| 'app.docs.components.icon.category.logo': 'Brand and Logos', | |||||
| 'app.docs.components.icon.pic-searcher.intro': | |||||
| 'AI Search by image is online, you are welcome to use it! 🎉', | |||||
| 'app.docs.components.icon.pic-searcher.title': 'Search by image', | |||||
| 'app.docs.components.icon.pic-searcher.upload-text': | |||||
| 'Click, drag, or paste file to this area to upload', | |||||
| 'app.docs.components.icon.pic-searcher.upload-hint': | |||||
| 'We will find the best matching icon based on the image provided', | |||||
| 'app.docs.components.icon.pic-searcher.server-error': | |||||
| 'Predict service is temporarily unavailable', | |||||
| 'app.docs.components.icon.pic-searcher.matching': 'Matching...', | |||||
| 'app.docs.components.icon.pic-searcher.modelloading': 'Model is loading...', | |||||
| 'app.docs.components.icon.pic-searcher.result-tip': 'Matched the following icons for you:', | |||||
| 'app.docs.components.icon.pic-searcher.th-icon': 'Icon', | |||||
| 'app.docs.components.icon.pic-searcher.th-score': 'Probability', | |||||
| }; | }; | ||||
| @@ -2,25 +2,25 @@ import app from './zh-CN/app'; | |||||
| import component from './zh-CN/component'; | import component from './zh-CN/component'; | ||||
| import globalHeader from './zh-CN/globalHeader'; | import globalHeader from './zh-CN/globalHeader'; | ||||
| import sysmenu from './zh-CN/menu'; | import sysmenu from './zh-CN/menu'; | ||||
| import job from './zh-CN/monitor/job'; | |||||
| import joblog from './zh-CN/monitor/job-log'; | |||||
| import logininfor from './zh-CN/monitor/logininfor'; | |||||
| import onlineUser from './zh-CN/monitor/onlineUser'; | |||||
| import operlog from './zh-CN/monitor/operlog'; | |||||
| import server from './zh-CN/monitor/server'; | |||||
| import pages from './zh-CN/pages'; | import pages from './zh-CN/pages'; | ||||
| import pwa from './zh-CN/pwa'; | import pwa from './zh-CN/pwa'; | ||||
| import settingDrawer from './zh-CN/settingDrawer'; | import settingDrawer from './zh-CN/settingDrawer'; | ||||
| import settings from './zh-CN/settings'; | import settings from './zh-CN/settings'; | ||||
| import user from './zh-CN/system/user'; | |||||
| import menu from './zh-CN/system/menu'; | |||||
| import config from './zh-CN/system/config'; | |||||
| import dept from './zh-CN/system/dept'; | |||||
| import dict from './zh-CN/system/dict'; | import dict from './zh-CN/system/dict'; | ||||
| import dictData from './zh-CN/system/dict-data'; | import dictData from './zh-CN/system/dict-data'; | ||||
| import role from './zh-CN/system/role'; | |||||
| import dept from './zh-CN/system/dept'; | |||||
| import post from './zh-CN/system/post'; | |||||
| import config from './zh-CN/system/config'; | |||||
| import menu from './zh-CN/system/menu'; | |||||
| import notice from './zh-CN/system/notice'; | import notice from './zh-CN/system/notice'; | ||||
| import operlog from './zh-CN/monitor/operlog'; | |||||
| import logininfor from './zh-CN/monitor/logininfor'; | |||||
| import onlineUser from './zh-CN/monitor/onlineUser'; | |||||
| import job from './zh-CN/monitor/job'; | |||||
| import joblog from './zh-CN/monitor/job-log'; | |||||
| import server from './zh-CN/monitor/server'; | |||||
| import post from './zh-CN/system/post'; | |||||
| import role from './zh-CN/system/role'; | |||||
| import user from './zh-CN/system/user'; | |||||
| export default { | export default { | ||||
| 'navBar.lang': '语言', | 'navBar.lang': '语言', | ||||
| @@ -1,18 +1,18 @@ | |||||
| /** | /** | ||||
| * 定时任务调度日志 | * 定时任务调度日志 | ||||
| * | |||||
| * | |||||
| * @author whiteshader | * @author whiteshader | ||||
| * @date 2023-02-07 | * @date 2023-02-07 | ||||
| */ | */ | ||||
| export default { | export default { | ||||
| 'monitor.job.log.title': '定时任务调度日志', | |||||
| 'monitor.job.log.job_log_id': '任务日志编号', | |||||
| 'monitor.job.log.job_name': '任务名称', | |||||
| 'monitor.job.log.job_group': '任务组名', | |||||
| 'monitor.job.log.invoke_target': '调用方法', | |||||
| 'monitor.job.log.job_message': '日志信息', | |||||
| 'monitor.job.log.status': '执行状态', | |||||
| 'monitor.job.log.exception_info': '异常信息', | |||||
| 'monitor.job.log.create_time': '创建时间', | |||||
| 'monitor.job.log.title': '定时任务调度日志', | |||||
| 'monitor.job.log.job_log_id': '任务日志编号', | |||||
| 'monitor.job.log.job_name': '任务名称', | |||||
| 'monitor.job.log.job_group': '任务组名', | |||||
| 'monitor.job.log.invoke_target': '调用方法', | |||||
| 'monitor.job.log.job_message': '日志信息', | |||||
| 'monitor.job.log.status': '执行状态', | |||||
| 'monitor.job.log.exception_info': '异常信息', | |||||
| 'monitor.job.log.create_time': '创建时间', | |||||
| }; | }; | ||||
| @@ -1,25 +1,25 @@ | |||||
| /** | /** | ||||
| * 定时任务调度 | * 定时任务调度 | ||||
| * | |||||
| * | |||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @date 2023-02-07 | * @date 2023-02-07 | ||||
| */ | */ | ||||
| export default { | export default { | ||||
| 'monitor.job.title': '定时任务调度', | |||||
| 'monitor.job.job_id': '任务编号', | |||||
| 'monitor.job.job_name': '任务名称', | |||||
| 'monitor.job.job_group': '任务组名', | |||||
| 'monitor.job.invoke_target': '调用方法', | |||||
| 'monitor.job.cron_expression': 'cron执行表达式', | |||||
| 'monitor.job.misfire_policy': '执行策略', | |||||
| 'monitor.job.concurrent': '是否并发执行', | |||||
| 'monitor.job.next_valid_time': '下次执行时间', | |||||
| 'monitor.job.status': '状态', | |||||
| 'monitor.job.create_by': '创建者', | |||||
| 'monitor.job.create_time': '创建时间', | |||||
| 'monitor.job.update_by': '更新者', | |||||
| 'monitor.job.update_time': '更新时间', | |||||
| 'monitor.job.remark': '备注信息', | |||||
| 'monitor.job.detail': '任务详情', | |||||
| 'monitor.job.title': '定时任务调度', | |||||
| 'monitor.job.job_id': '任务编号', | |||||
| 'monitor.job.job_name': '任务名称', | |||||
| 'monitor.job.job_group': '任务组名', | |||||
| 'monitor.job.invoke_target': '调用方法', | |||||
| 'monitor.job.cron_expression': 'cron执行表达式', | |||||
| 'monitor.job.misfire_policy': '执行策略', | |||||
| 'monitor.job.concurrent': '是否并发执行', | |||||
| 'monitor.job.next_valid_time': '下次执行时间', | |||||
| 'monitor.job.status': '状态', | |||||
| 'monitor.job.create_by': '创建者', | |||||
| 'monitor.job.create_time': '创建时间', | |||||
| 'monitor.job.update_by': '更新者', | |||||
| 'monitor.job.update_time': '更新时间', | |||||
| 'monitor.job.remark': '备注信息', | |||||
| 'monitor.job.detail': '任务详情', | |||||
| }; | }; | ||||
| @@ -1,13 +1,13 @@ | |||||
| export default { | export default { | ||||
| 'monitor.logininfor.title': '系统访问记录', | |||||
| 'monitor.logininfor.info_id': '访问编号', | |||||
| 'monitor.logininfor.user_name': '用户账号', | |||||
| 'monitor.logininfor.ipaddr': '登录IP地址', | |||||
| 'monitor.logininfor.login_location': '登录地点', | |||||
| 'monitor.logininfor.browser': '浏览器类型', | |||||
| 'monitor.logininfor.os': '操作系统', | |||||
| 'monitor.logininfor.status': '登录状态', | |||||
| 'monitor.logininfor.msg': '提示消息', | |||||
| 'monitor.logininfor.login_time': '访问时间', | |||||
| 'monitor.logininfor.unlock': '解锁', | |||||
| 'monitor.logininfor.title': '系统访问记录', | |||||
| 'monitor.logininfor.info_id': '访问编号', | |||||
| 'monitor.logininfor.user_name': '用户账号', | |||||
| 'monitor.logininfor.ipaddr': '登录IP地址', | |||||
| 'monitor.logininfor.login_location': '登录地点', | |||||
| 'monitor.logininfor.browser': '浏览器类型', | |||||
| 'monitor.logininfor.os': '操作系统', | |||||
| 'monitor.logininfor.status': '登录状态', | |||||
| 'monitor.logininfor.msg': '提示消息', | |||||
| 'monitor.logininfor.login_time': '访问时间', | |||||
| 'monitor.logininfor.unlock': '解锁', | |||||
| }; | }; | ||||
| @@ -1,9 +1,8 @@ | |||||
| /* * | /* * | ||||
| * | * | ||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @datetime 2021/09/16 | * @datetime 2021/09/16 | ||||
| * | |||||
| * | |||||
| * */ | * */ | ||||
| export default { | export default { | ||||
| @@ -1,19 +1,19 @@ | |||||
| export default { | export default { | ||||
| 'monitor.operlog.title': '操作日志记录', | |||||
| 'monitor.operlog.oper_id': '日志主键', | |||||
| 'monitor.operlog.business_type': '业务类型', | |||||
| 'monitor.operlog.method': '方法名称', | |||||
| 'monitor.operlog.request_method': '请求方式', | |||||
| 'monitor.operlog.operator_type': '操作类别', | |||||
| 'monitor.operlog.oper_name': '操作人员', | |||||
| 'monitor.operlog.dept_name': '部门名称', | |||||
| 'monitor.operlog.oper_url': '请求URL', | |||||
| 'monitor.operlog.oper_ip': '主机地址', | |||||
| 'monitor.operlog.oper_location': '操作地点', | |||||
| 'monitor.operlog.oper_param': '请求参数', | |||||
| 'monitor.operlog.json_result': '返回参数', | |||||
| 'monitor.operlog.status': '操作状态', | |||||
| 'monitor.operlog.error_msg': '错误消息', | |||||
| 'monitor.operlog.oper_time': '操作时间', | |||||
| 'monitor.operlog.module': '操作模块', | |||||
| 'monitor.operlog.title': '操作日志记录', | |||||
| 'monitor.operlog.oper_id': '日志主键', | |||||
| 'monitor.operlog.business_type': '业务类型', | |||||
| 'monitor.operlog.method': '方法名称', | |||||
| 'monitor.operlog.request_method': '请求方式', | |||||
| 'monitor.operlog.operator_type': '操作类别', | |||||
| 'monitor.operlog.oper_name': '操作人员', | |||||
| 'monitor.operlog.dept_name': '部门名称', | |||||
| 'monitor.operlog.oper_url': '请求URL', | |||||
| 'monitor.operlog.oper_ip': '主机地址', | |||||
| 'monitor.operlog.oper_location': '操作地点', | |||||
| 'monitor.operlog.oper_param': '请求参数', | |||||
| 'monitor.operlog.json_result': '返回参数', | |||||
| 'monitor.operlog.status': '操作状态', | |||||
| 'monitor.operlog.error_msg': '错误消息', | |||||
| 'monitor.operlog.oper_time': '操作时间', | |||||
| 'monitor.operlog.module': '操作模块', | |||||
| }; | }; | ||||
| @@ -1,9 +1,8 @@ | |||||
| /* * | /* * | ||||
| * | * | ||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @datetime 2021/09/16 | * @datetime 2021/09/16 | ||||
| * | |||||
| * | |||||
| * */ | * */ | ||||
| export default { | export default { | ||||
| @@ -1,14 +1,14 @@ | |||||
| export default { | export default { | ||||
| 'system.config.title': '参数配置', | |||||
| 'system.config.config_id': '参数主键', | |||||
| 'system.config.config_name': '参数名称', | |||||
| 'system.config.config_key': '参数键名', | |||||
| 'system.config.config_value': '参数键值', | |||||
| 'system.config.config_type': '系统内置', | |||||
| 'system.config.create_by': '创建者', | |||||
| 'system.config.create_time': '创建时间', | |||||
| 'system.config.update_by': '更新者', | |||||
| 'system.config.update_time': '更新时间', | |||||
| 'system.config.remark': '备注', | |||||
| 'system.config.refreshCache': '刷新缓存', | |||||
| 'system.config.title': '参数配置', | |||||
| 'system.config.config_id': '参数主键', | |||||
| 'system.config.config_name': '参数名称', | |||||
| 'system.config.config_key': '参数键名', | |||||
| 'system.config.config_value': '参数键值', | |||||
| 'system.config.config_type': '系统内置', | |||||
| 'system.config.create_by': '创建者', | |||||
| 'system.config.create_time': '创建时间', | |||||
| 'system.config.update_by': '更新者', | |||||
| 'system.config.update_time': '更新时间', | |||||
| 'system.config.remark': '备注', | |||||
| 'system.config.refreshCache': '刷新缓存', | |||||
| }; | }; | ||||
| @@ -1,18 +1,18 @@ | |||||
| export default { | export default { | ||||
| 'system.dept.title': '部门', | |||||
| 'system.dept.dept_id': '部门id', | |||||
| 'system.dept.parent_id': '父部门id', | |||||
| 'system.dept.parent_dept': '上级部门', | |||||
| 'system.dept.ancestors': '祖级列表', | |||||
| 'system.dept.dept_name': '部门名称', | |||||
| 'system.dept.order_num': '显示顺序', | |||||
| 'system.dept.leader': '负责人', | |||||
| 'system.dept.phone': '联系电话', | |||||
| 'system.dept.email': '邮箱', | |||||
| 'system.dept.status': '部门状态', | |||||
| 'system.dept.del_flag': '删除标志', | |||||
| 'system.dept.create_by': '创建者', | |||||
| 'system.dept.create_time': '创建时间', | |||||
| 'system.dept.update_by': '更新者', | |||||
| 'system.dept.update_time': '更新时间', | |||||
| 'system.dept.title': '部门', | |||||
| 'system.dept.dept_id': '部门id', | |||||
| 'system.dept.parent_id': '父部门id', | |||||
| 'system.dept.parent_dept': '上级部门', | |||||
| 'system.dept.ancestors': '祖级列表', | |||||
| 'system.dept.dept_name': '部门名称', | |||||
| 'system.dept.order_num': '显示顺序', | |||||
| 'system.dept.leader': '负责人', | |||||
| 'system.dept.phone': '联系电话', | |||||
| 'system.dept.email': '邮箱', | |||||
| 'system.dept.status': '部门状态', | |||||
| 'system.dept.del_flag': '删除标志', | |||||
| 'system.dept.create_by': '创建者', | |||||
| 'system.dept.create_time': '创建时间', | |||||
| 'system.dept.update_by': '更新者', | |||||
| 'system.dept.update_time': '更新时间', | |||||
| }; | }; | ||||
| @@ -1,22 +1,22 @@ | |||||
| export default { | export default { | ||||
| 'system.menu.title': '菜单权限', | |||||
| 'system.menu.menu_id': '菜单编号', | |||||
| 'system.menu.menu_name': '菜单名称', | |||||
| 'system.menu.parent_id': '上级菜单', | |||||
| 'system.menu.order_num': '显示顺序', | |||||
| 'system.menu.path': '路由地址', | |||||
| 'system.menu.component': '组件路径', | |||||
| 'system.menu.query': '路由参数', | |||||
| 'system.menu.is_frame': '是否为外链', | |||||
| 'system.menu.is_cache': '是否缓存', | |||||
| 'system.menu.menu_type': '菜单类型', | |||||
| 'system.menu.visible': '显示状态', | |||||
| 'system.menu.status': '菜单状态', | |||||
| 'system.menu.perms': '权限标识', | |||||
| 'system.menu.icon': '菜单图标', | |||||
| 'system.menu.create_by': '创建者', | |||||
| 'system.menu.create_time': '创建时间', | |||||
| 'system.menu.update_by': '更新者', | |||||
| 'system.menu.update_time': '更新时间', | |||||
| 'system.menu.remark': '备注', | |||||
| 'system.menu.title': '菜单权限', | |||||
| 'system.menu.menu_id': '菜单编号', | |||||
| 'system.menu.menu_name': '菜单名称', | |||||
| 'system.menu.parent_id': '上级菜单', | |||||
| 'system.menu.order_num': '显示顺序', | |||||
| 'system.menu.path': '路由地址', | |||||
| 'system.menu.component': '组件路径', | |||||
| 'system.menu.query': '路由参数', | |||||
| 'system.menu.is_frame': '是否为外链', | |||||
| 'system.menu.is_cache': '是否缓存', | |||||
| 'system.menu.menu_type': '菜单类型', | |||||
| 'system.menu.visible': '显示状态', | |||||
| 'system.menu.status': '菜单状态', | |||||
| 'system.menu.perms': '权限标识', | |||||
| 'system.menu.icon': '菜单图标', | |||||
| 'system.menu.create_by': '创建者', | |||||
| 'system.menu.create_time': '创建时间', | |||||
| 'system.menu.update_by': '更新者', | |||||
| 'system.menu.update_time': '更新时间', | |||||
| 'system.menu.remark': '备注', | |||||
| }; | }; | ||||
| @@ -1,13 +1,13 @@ | |||||
| export default { | export default { | ||||
| 'system.notice.title': '通知公告', | |||||
| 'system.notice.notice_id': '公告编号', | |||||
| 'system.notice.notice_title': '公告标题', | |||||
| 'system.notice.notice_type': '公告类型', | |||||
| 'system.notice.notice_content': '公告内容', | |||||
| 'system.notice.status': '公告状态', | |||||
| 'system.notice.create_by': '创建者', | |||||
| 'system.notice.create_time': '创建时间', | |||||
| 'system.notice.update_by': '更新者', | |||||
| 'system.notice.update_time': '更新时间', | |||||
| 'system.notice.remark': '备注', | |||||
| 'system.notice.title': '通知公告', | |||||
| 'system.notice.notice_id': '公告编号', | |||||
| 'system.notice.notice_title': '公告标题', | |||||
| 'system.notice.notice_type': '公告类型', | |||||
| 'system.notice.notice_content': '公告内容', | |||||
| 'system.notice.status': '公告状态', | |||||
| 'system.notice.create_by': '创建者', | |||||
| 'system.notice.create_time': '创建时间', | |||||
| 'system.notice.update_by': '更新者', | |||||
| 'system.notice.update_time': '更新时间', | |||||
| 'system.notice.remark': '备注', | |||||
| }; | }; | ||||
| @@ -1,13 +1,13 @@ | |||||
| export default { | export default { | ||||
| 'system.post.title': '岗位信息', | |||||
| 'system.post.post_id': '岗位编号', | |||||
| 'system.post.post_code': '岗位编码', | |||||
| 'system.post.post_name': '岗位名称', | |||||
| 'system.post.post_sort': '显示顺序', | |||||
| 'system.post.status': '状态', | |||||
| 'system.post.create_by': '创建者', | |||||
| 'system.post.create_time': '创建时间', | |||||
| 'system.post.update_by': '更新者', | |||||
| 'system.post.update_time': '更新时间', | |||||
| 'system.post.remark': '备注', | |||||
| 'system.post.title': '岗位信息', | |||||
| 'system.post.post_id': '岗位编号', | |||||
| 'system.post.post_code': '岗位编码', | |||||
| 'system.post.post_name': '岗位名称', | |||||
| 'system.post.post_sort': '显示顺序', | |||||
| 'system.post.status': '状态', | |||||
| 'system.post.create_by': '创建者', | |||||
| 'system.post.create_time': '创建时间', | |||||
| 'system.post.update_by': '更新者', | |||||
| 'system.post.update_time': '更新时间', | |||||
| 'system.post.remark': '备注', | |||||
| }; | }; | ||||
| @@ -1,21 +1,21 @@ | |||||
| export default { | export default { | ||||
| 'system.role.title': '角色信息', | |||||
| 'system.role.role_id': '角色编号', | |||||
| 'system.role.role_name': '角色名称', | |||||
| 'system.role.role_key': '权限字符', | |||||
| 'system.role.role_sort': '显示顺序', | |||||
| 'system.role.data_scope': '数据范围', | |||||
| 'system.role.menu_check_strictly': '菜单树选择项是否关联显示', | |||||
| 'system.role.dept_check_strictly': '部门树选择项是否关联显示', | |||||
| 'system.role.status': '角色状态', | |||||
| 'system.role.del_flag': '删除标志', | |||||
| 'system.role.create_by': '创建者', | |||||
| 'system.role.create_time': '创建时间', | |||||
| 'system.role.update_by': '更新者', | |||||
| 'system.role.update_time': '更新时间', | |||||
| 'system.role.remark': '备注', | |||||
| 'system.role.auth': '菜单权限', | |||||
| 'system.role.auth.user': '选择用户', | |||||
| 'system.role.auth.addUser': '添加用户', | |||||
| 'system.role.auth.cancelAll': '批量取消授权', | |||||
| 'system.role.title': '角色信息', | |||||
| 'system.role.role_id': '角色编号', | |||||
| 'system.role.role_name': '角色名称', | |||||
| 'system.role.role_key': '权限字符', | |||||
| 'system.role.role_sort': '显示顺序', | |||||
| 'system.role.data_scope': '数据范围', | |||||
| 'system.role.menu_check_strictly': '菜单树选择项是否关联显示', | |||||
| 'system.role.dept_check_strictly': '部门树选择项是否关联显示', | |||||
| 'system.role.status': '角色状态', | |||||
| 'system.role.del_flag': '删除标志', | |||||
| 'system.role.create_by': '创建者', | |||||
| 'system.role.create_time': '创建时间', | |||||
| 'system.role.update_by': '更新者', | |||||
| 'system.role.update_time': '更新时间', | |||||
| 'system.role.remark': '备注', | |||||
| 'system.role.auth': '菜单权限', | |||||
| 'system.role.auth.user': '选择用户', | |||||
| 'system.role.auth.addUser': '添加用户', | |||||
| 'system.role.auth.cancelAll': '批量取消授权', | |||||
| }; | }; | ||||
| @@ -1,31 +1,31 @@ | |||||
| export default { | export default { | ||||
| 'system.user.title': '用户信息', | |||||
| 'system.user.user_id': '用户编号', | |||||
| 'system.user.dept_name': '部门', | |||||
| 'system.user.user_name': '用户账号', | |||||
| 'system.user.nick_name': '用户昵称', | |||||
| 'system.user.user_type': '用户类型', | |||||
| 'system.user.email': '用户邮箱', | |||||
| 'system.user.phonenumber': '手机号码', | |||||
| 'system.user.sex': '用户性别', | |||||
| 'system.user.avatar': '头像地址', | |||||
| 'system.user.password': '密码', | |||||
| 'system.user.status': '帐号状态', | |||||
| 'system.user.del_flag': '删除标志', | |||||
| 'system.user.login_ip': '最后登录IP', | |||||
| 'system.user.login_date': '最后登录时间', | |||||
| 'system.user.create_by': '创建者', | |||||
| 'system.user.create_time': '创建时间', | |||||
| 'system.user.update_by': '更新者', | |||||
| 'system.user.update_time': '更新时间', | |||||
| 'system.user.remark': '备注', | |||||
| 'system.user.post': '岗位', | |||||
| 'system.user.role': '角色', | |||||
| 'system.user.auth.role': '分配角色', | |||||
| 'system.user.reset.password': '密码重置', | |||||
| 'system.user.modify_info': '编辑用户信息', | |||||
| 'system.user.old_password': '旧密码', | |||||
| 'system.user.new_password': '新密码', | |||||
| 'system.user.confirm_password': '确认密码', | |||||
| 'system.user.modify_avatar': '修改头像', | |||||
| 'system.user.title': '用户信息', | |||||
| 'system.user.user_id': '用户编号', | |||||
| 'system.user.dept_name': '部门', | |||||
| 'system.user.user_name': '用户账号', | |||||
| 'system.user.nick_name': '用户昵称', | |||||
| 'system.user.user_type': '用户类型', | |||||
| 'system.user.email': '用户邮箱', | |||||
| 'system.user.phonenumber': '手机号码', | |||||
| 'system.user.sex': '用户性别', | |||||
| 'system.user.avatar': '头像地址', | |||||
| 'system.user.password': '密码', | |||||
| 'system.user.status': '帐号状态', | |||||
| 'system.user.del_flag': '删除标志', | |||||
| 'system.user.login_ip': '最后登录IP', | |||||
| 'system.user.login_date': '最后登录时间', | |||||
| 'system.user.create_by': '创建者', | |||||
| 'system.user.create_time': '创建时间', | |||||
| 'system.user.update_by': '更新者', | |||||
| 'system.user.update_time': '更新时间', | |||||
| 'system.user.remark': '备注', | |||||
| 'system.user.post': '岗位', | |||||
| 'system.user.role': '角色', | |||||
| 'system.user.auth.role': '分配角色', | |||||
| 'system.user.reset.password': '密码重置', | |||||
| 'system.user.modify_info': '编辑用户信息', | |||||
| 'system.user.old_password': '旧密码', | |||||
| 'system.user.new_password': '新密码', | |||||
| 'system.user.confirm_password': '确认密码', | |||||
| 'system.user.modify_avatar': '修改头像', | |||||
| }; | }; | ||||
| @@ -1,88 +1,95 @@ | |||||
| import React ,{useEffect,useState,useRef}from 'react'; | |||||
| import Styles from './index.less' | |||||
| import { Input, Space ,Button,Tabs,Pagination,Modal, Form,message, Radio,Select,Table,Upload} from 'antd'; | |||||
| import { PlusOutlined,PlusCircleOutlined, DeleteOutlined,UploadOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined ,CopyOutlined} from '@ant-design/icons'; | |||||
| import {getDatasetList,getDatasetById,getDatasetVersionsById,getDatasetVersionIdList,deleteDatasetVersion,addDatasetVersionDetail,exportDataset} from '@/services/dataset/index.js' | |||||
| import { useParams } from 'react-router-dom' | |||||
| import {downLoadZip} from '@/utils/downloadfile' | |||||
| const { Search } = Input; | |||||
| import { getAccessToken } from '@/access'; | |||||
| import { | |||||
| addDatasetVersionDetail, | |||||
| deleteDatasetVersion, | |||||
| getDatasetById, | |||||
| getDatasetVersionIdList, | |||||
| getDatasetVersionsById, | |||||
| } from '@/services/dataset/index.js'; | |||||
| import { downLoadZip } from '@/utils/downloadfile'; | |||||
| import { | |||||
| DeleteOutlined, | |||||
| DownloadOutlined, | |||||
| PlusCircleOutlined, | |||||
| UploadOutlined, | |||||
| } from '@ant-design/icons'; | |||||
| import { Button, Form, Input, Modal, Select, Table, Tabs, Upload, message } from 'antd'; | |||||
| import moment from 'moment'; | import moment from 'moment'; | ||||
| import { getAccessToken } from '@/access'; | |||||
| import { useEffect, useRef, useState } from 'react'; | |||||
| import { useParams } from 'react-router-dom'; | |||||
| import Styles from './index.less'; | |||||
| const { Search } = Input; | |||||
| const { TabPane } = Tabs; | const { TabPane } = Tabs; | ||||
| const Dataset= React.FC = () => { | |||||
| const Dataset = () => { | |||||
| const props = { | const props = { | ||||
| action: '/api/mmp/dataset/upload', | action: '/api/mmp/dataset/upload', | ||||
| // headers: { | // headers: { | ||||
| // 'X-Requested-With': null | // 'X-Requested-With': null | ||||
| // }, | // }, | ||||
| headers: { | headers: { | ||||
| Authorization:getAccessToken(), | |||||
| 'X-Requested-With': null | |||||
| Authorization: getAccessToken(), | |||||
| 'X-Requested-With': null, | |||||
| }, | }, | ||||
| onChange({ file, fileList }) { | onChange({ file, fileList }) { | ||||
| if (file.status !== 'uploading') { | if (file.status !== 'uploading') { | ||||
| console.log(file, fileList); | console.log(file, fileList); | ||||
| setFormList(fileList.map(item=>{ | |||||
| return { | |||||
| ...form.getFieldsValue(), | |||||
| dataset_id:locationParams.id, | |||||
| file_name:item.response.data[0].fileName, | |||||
| file_size:item.response.data[0].fileSize, | |||||
| url:item.response.data[0].url, | |||||
| } | |||||
| })) | |||||
| setFormList( | |||||
| fileList.map((item) => { | |||||
| return { | |||||
| ...form.getFieldsValue(), | |||||
| dataset_id: locationParams.id, | |||||
| file_name: item.response.data[0].fileName, | |||||
| file_size: item.response.data[0].fileSize, | |||||
| url: item.response.data[0].url, | |||||
| }; | |||||
| }), | |||||
| ); | |||||
| } | } | ||||
| }, | }, | ||||
| defaultFileList: [ | |||||
| ], | |||||
| defaultFileList: [], | |||||
| }; | }; | ||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const [formList,setFormList]=useState([]) | |||||
| const [formList, setFormList] = useState([]); | |||||
| const [dialogTitle, setDialogTitle] = useState('新建版本'); | const [dialogTitle, setDialogTitle] = useState('新建版本'); | ||||
| const [isModalOpen,setIsModalOpen]=useState(false) | |||||
| const [datasetDetailObj,setDatasetDetailObj]=useState({ | |||||
| }); | |||||
| const [version,setVersion]=useState('') | |||||
| const [isModalOpen, setIsModalOpen] = useState(false); | |||||
| const [datasetDetailObj, setDatasetDetailObj] = useState({}); | |||||
| const [version, setVersion] = useState(''); | |||||
| const [versionList, setVersionList] = useState([]); | const [versionList, setVersionList] = useState([]); | ||||
| const locationParams =useParams () //新版本获取路由参数接口 | |||||
| console.log(locationParams); | |||||
| const locationParams = useParams(); //新版本获取路由参数接口 | |||||
| const [wordList, setWordList] = useState([]); | const [wordList, setWordList] = useState([]); | ||||
| const getDatasetByDetail=()=>{ | |||||
| getDatasetById(locationParams.id).then(ret=>{ | |||||
| const [activeTabKey, setActiveTabKey] = useState('1'); | |||||
| const getDatasetByDetail = () => { | |||||
| getDatasetById(locationParams.id).then((ret) => { | |||||
| console.log(ret); | console.log(ret); | ||||
| if(ret.code==200){ | |||||
| setDatasetDetailObj(ret.data) | |||||
| } | |||||
| }) | |||||
| } | |||||
| const getDatasetVersionList=()=>{ | |||||
| getDatasetVersionsById(locationParams.id).then(ret=>{ | |||||
| setDatasetDetailObj(ret.data); | |||||
| }); | |||||
| }; | |||||
| const getDatasetVersionList = () => { | |||||
| getDatasetVersionsById(locationParams.id).then((ret) => { | |||||
| console.log(ret); | console.log(ret); | ||||
| if(ret.code==200&&ret.data&&ret.data.length>0){ | |||||
| setVersionList(ret.data.map(item=>{ | |||||
| return { | |||||
| 'label':item, | |||||
| 'value':item | |||||
| } | |||||
| })) | |||||
| if (ret.data && ret.data.length > 0) { | |||||
| setVersionList( | |||||
| ret.data.map((item) => { | |||||
| return { | |||||
| label: item, | |||||
| value: item, | |||||
| }; | |||||
| }), | |||||
| ); | |||||
| } | } | ||||
| }) | |||||
| } | |||||
| useEffect(()=>{ | |||||
| getDatasetByDetail() | |||||
| getDatasetVersionList() | |||||
| return ()=>{ | |||||
| } | |||||
| },[]) | |||||
| }); | |||||
| }; | |||||
| useEffect(() => { | |||||
| getDatasetByDetail(); | |||||
| getDatasetVersionList(); | |||||
| return () => {}; | |||||
| }, []); | |||||
| const showModal = () => { | const showModal = () => { | ||||
| form.resetFields() | |||||
| form.setFieldsValue({name:datasetDetailObj.name}) | |||||
| setDialogTitle('创建新版本') | |||||
| form.resetFields(); | |||||
| form.setFieldsValue({ name: datasetDetailObj.name }); | |||||
| setDialogTitle('创建新版本'); | |||||
| setIsModalOpen(true); | setIsModalOpen(true); | ||||
| }; | }; | ||||
| const handleCancel = () => { | const handleCancel = () => { | ||||
| @@ -91,80 +98,74 @@ const Dataset= React.FC = () => { | |||||
| const handleExport = async () => { | const handleExport = async () => { | ||||
| const hide = message.loading('正在下载'); | const hide = message.loading('正在下载'); | ||||
| hide(); | hide(); | ||||
| downLoadZip(`/api/mmp/dataset/downloadAllFiles`,{dataset_id:locationParams.id,version}) | |||||
| downLoadZip(`/api/mmp/dataset/downloadAllFiles`, { dataset_id: locationParams.id, version }); | |||||
| }; | }; | ||||
| const deleteDataset=()=>{ | |||||
| const deleteDataset = () => { | |||||
| Modal.confirm({ | Modal.confirm({ | ||||
| title: '删除', | title: '删除', | ||||
| content: '确定删除数据集版本?', | content: '确定删除数据集版本?', | ||||
| okText: '确认', | okText: '确认', | ||||
| cancelText: '取消', | cancelText: '取消', | ||||
| onOk: () => { | |||||
| deleteDatasetVersion({dataset_id:locationParams.id,version}).then(ret=>{ | |||||
| if(ret.code==200){ | |||||
| message.success('删除成功') | |||||
| getDatasetVersions({version,dataset_id:locationParams.id}) | |||||
| } | |||||
| else{ | |||||
| message.error(ret.msg) | |||||
| } | |||||
| onOk: () => { | |||||
| deleteDatasetVersion({ dataset_id: locationParams.id, version }).then((ret) => { | |||||
| message.success('删除成功'); | |||||
| getDatasetVersions({ version, dataset_id: locationParams.id }); | |||||
| }); | }); | ||||
| }, | }, | ||||
| }); | }); | ||||
| } | |||||
| const onFinish = (values) => { | |||||
| addDatasetVersionDetail(formList).then(ret=>{ | |||||
| console.log(ret); | |||||
| getDatasetVersionList() | |||||
| setIsModalOpen(false); | |||||
| }) | |||||
| }; | |||||
| const getDatasetVersions=(params)=>{ | |||||
| getDatasetVersionIdList(params).then(ret=>{ | |||||
| }; | |||||
| const onFinish = (values) => { | |||||
| addDatasetVersionDetail(formList).then((ret) => { | |||||
| console.log(ret); | console.log(ret); | ||||
| if(ret.code==200){ | |||||
| setWordList(ret.data) | |||||
| } | |||||
| }) | |||||
| } | |||||
| const handleChange=(value)=>{ | |||||
| getDatasetVersionList(); | |||||
| setIsModalOpen(false); | |||||
| }); | |||||
| }; | |||||
| const getDatasetVersions = (params) => { | |||||
| getDatasetVersionIdList(params).then((res) => { | |||||
| setWordList( | |||||
| res.data.map((v) => ({ | |||||
| ...v, | |||||
| key: v.id, | |||||
| })), | |||||
| ); | |||||
| }); | |||||
| }; | |||||
| const handleChange = (value) => { | |||||
| console.log(value); | console.log(value); | ||||
| if(value){ | |||||
| getDatasetVersions({version:value,dataset_id:locationParams.id}) | |||||
| setVersion(value) | |||||
| } | |||||
| else{ | |||||
| setVersion(null) | |||||
| if (value) { | |||||
| getDatasetVersions({ version: value, dataset_id: locationParams.id }); | |||||
| setVersion(value); | |||||
| } else { | |||||
| setVersion(null); | |||||
| } | } | ||||
| } | |||||
| }; | |||||
| const onFinishFailed = (errorInfo) => { | const onFinishFailed = (errorInfo) => { | ||||
| console.log('Failed:', errorInfo); | console.log('Failed:', errorInfo); | ||||
| }; | }; | ||||
| const downloadAlone=(e,record)=>{ | |||||
| const downloadAlone = (e, record) => { | |||||
| console.log(record); | console.log(record); | ||||
| const hide = message.loading('正在下载'); | const hide = message.loading('正在下载'); | ||||
| hide(); | hide(); | ||||
| downLoadZip(`/api/mmp//dataset/download/${record.id}`) | |||||
| } | |||||
| downLoadZip(`/api/mmp/dataset/download/${record.id}`); | |||||
| }; | |||||
| const columns = [ | const columns = [ | ||||
| // { | |||||
| // title: '序号', | |||||
| // dataIndex: 'index', | |||||
| // key: 'index', | |||||
| // width: 80, | |||||
| // render(text, record, index) { | |||||
| // return ( | |||||
| // <span>{(pageOption.current.page - 1) * 10 + index + 1}</span> | |||||
| // ) | |||||
| // } | |||||
| // // render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`, | |||||
| // }, | |||||
| { | |||||
| title: '序号', | |||||
| dataIndex: 'index', | |||||
| key: 'index', | |||||
| width: 80, | |||||
| render(text, record, index) { | |||||
| return <span>{(pageOption.current.page - 1) * 10 + index + 1}</span>; | |||||
| }, | |||||
| // render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`, | |||||
| }, | |||||
| { | { | ||||
| title: '文件名称', | title: '文件名称', | ||||
| dataIndex: 'file_name', | dataIndex: 'file_name', | ||||
| key: 'file_name', | key: 'file_name', | ||||
| render: (text,record) => <a onClick={(e)=>downloadAlone(e,record)}>{text}</a>, | |||||
| render: (text, record) => <a onClick={(e) => downloadAlone(e, record)}>{text}</a>, | |||||
| }, | }, | ||||
| { | { | ||||
| title: '版本号', | title: '版本号', | ||||
| @@ -182,80 +183,128 @@ const Dataset= React.FC = () => { | |||||
| key: 'update_time', | key: 'update_time', | ||||
| render: (text) => <span>{moment(text).format('YYYY-MM-DD HH:mm:ss')}</span>, | render: (text) => <span>{moment(text).format('YYYY-MM-DD HH:mm:ss')}</span>, | ||||
| }, | }, | ||||
| { | |||||
| title: '操作', | |||||
| dataIndex: 'option', | |||||
| width: '100px', | |||||
| key: 'option', | |||||
| render: (_, record) => [ | |||||
| <Button | |||||
| type="link" | |||||
| size="small" | |||||
| key="download" | |||||
| icon={<DownloadOutlined />} | |||||
| onClick={(e) => downloadAlone(e, record)} | |||||
| > | |||||
| 下载 | |||||
| </Button>, | |||||
| ], | |||||
| }, | |||||
| ]; | ]; | ||||
| const pageOption = useRef({page: 1,size: 10}) | |||||
| const pageOption = useRef({ page: 1, size: 10 }); | |||||
| // 当前页面切换 | // 当前页面切换 | ||||
| const paginationChange = async (current, size) => { | const paginationChange = async (current, size) => { | ||||
| console.log('page', current, size) | |||||
| pageOption.current={ | |||||
| page:current, | |||||
| size:size | |||||
| } | |||||
| console.log('page', current, size); | |||||
| pageOption.current = { | |||||
| page: current, | |||||
| size: size, | |||||
| }; | |||||
| // getList() | // getList() | ||||
| } | |||||
| return (<div className={Styles.datasetBox}> | |||||
| <div className={Styles.datasetIntroTopBox}> | |||||
| <span style={{color:'#1d1d20',fontSize:'20px'}}>{datasetDetailObj.name}</span> | |||||
| <div className={Styles.smallTagBox}> | |||||
| <div className={Styles.tagItem}>{datasetDetailObj.data_tag||'...'}</div> | |||||
| }; | |||||
| return ( | |||||
| <div className={Styles.datasetBox}> | |||||
| <div className={Styles.datasetIntroTopBox}> | |||||
| <span style={{ color: '#1d1d20', fontSize: '20px' }}>{datasetDetailObj.name}</span> | |||||
| <div className={Styles.smallTagBox}> | |||||
| <div className={Styles.tagItem}>{datasetDetailObj.data_tag || '...'}</div> | |||||
| <div className={Styles.tagItem}>{datasetDetailObj.data_type}</div> | <div className={Styles.tagItem}>{datasetDetailObj.data_type}</div> | ||||
| {/* <div className={Styles.tagItem}>English</div> */} | {/* <div className={Styles.tagItem}>English</div> */} | ||||
| </div> | |||||
| </div> | |||||
| <div className={Styles.datasetIntroCneterBox}> | |||||
| <Tabs | |||||
| defaultActiveKey="1" | |||||
| > | |||||
| <TabPane tab="数据集简介" key="1"> | |||||
| <div className={Styles.datasetIntroTitle}>简介</div> | |||||
| <div className={Styles.datasetIntroText}>{datasetDetailObj.description}</div> | |||||
| </TabPane> | |||||
| <TabPane tab="数据集文件/版本" key="2"> | |||||
| <div className={Styles.dataListBox}> | |||||
| <div>数据集文件列表</div> | |||||
| <div className={Styles.dataButtonList}> | |||||
| <div style={{display: 'flex', | |||||
| justifyContent: 'space-between', | |||||
| alignItems: 'center'}}> | |||||
| <span style={{marginRight:'10px'}}>版本号:</span> | |||||
| <Select | |||||
| placeholder="请选择版本号" | |||||
| style={{ | |||||
| width: 160, | |||||
| }} | |||||
| allowClear | |||||
| onChange={handleChange} | |||||
| options={versionList} | |||||
| /> | |||||
| <Button type="primary" className={Styles.plusButton} onClick={showModal} icon = {<PlusCircleOutlined style={{color:'#1664ff'}} />}> | |||||
| 创建新版本 | |||||
| </Button> | |||||
| </div> | |||||
| <div style={{display: 'flex', | |||||
| justifyContent: 'space-between', | |||||
| alignItems: 'center'}}> | |||||
| <Button type="primary" className={Styles.plusButton} style={{margin:'0 20px 0 0' }} onClick={deleteDataset} icon = {<DeleteOutlined style={{color:'#1664ff', }} />}> | |||||
| 删除 | |||||
| </Button> | |||||
| <Button type="primary" disabled={!version} className={Styles.plusButton} style={{margin:'0 20px 0 0' }} onClick={handleExport} icon = {<UploadOutlined style={{color:'#1664ff'}} />}> | |||||
| 下载 | |||||
| </Button> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <Table columns={columns} dataSource={wordList} pagination={false} /> | |||||
| </div> | |||||
| </TabPane> | |||||
| </Tabs> | |||||
| </div> | |||||
| <Modal title={<div style={{display:'flex',alignItems:'center',fontWeight:500}}> | |||||
| <img style={{width:'20px',marginRight:'10px'}} src={`/assets/images/pipeline-edit-icon.png`} alt="" />{dialogTitle} | |||||
| </div>} open={isModalOpen} className={Styles.modal} okButtonProps={{ | |||||
| htmlType: 'submit', | |||||
| form: 'form', | |||||
| }} onCancel={handleCancel}> | |||||
| </div> | |||||
| <div className={Styles.datasetIntroCneterBox}> | |||||
| <Tabs activeKey={activeTabKey} onChange={(key) => setActiveTabKey(key)}> | |||||
| <TabPane tab="数据集简介" key="1"> | |||||
| <div className={Styles.datasetIntroTitle}>简介</div> | |||||
| <div className={Styles.datasetIntroText}>{datasetDetailObj.description}</div> | |||||
| </TabPane> | |||||
| <TabPane tab="数据集文件/版本" key="2"> | |||||
| <div className={Styles.dataListBox}> | |||||
| <div>数据集文件列表</div> | |||||
| <div className={Styles.dataButtonList}> | |||||
| <div | |||||
| style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }} | |||||
| > | |||||
| <span style={{ marginRight: '10px' }}>版本号:</span> | |||||
| <Select | |||||
| placeholder="请选择版本号" | |||||
| style={{ | |||||
| width: 160, | |||||
| }} | |||||
| allowClear | |||||
| onChange={handleChange} | |||||
| options={versionList} | |||||
| /> | |||||
| <Button | |||||
| type="primary" | |||||
| className={Styles.plusButton} | |||||
| onClick={showModal} | |||||
| icon={<PlusCircleOutlined style={{ color: '#1664ff' }} />} | |||||
| > | |||||
| 创建新版本 | |||||
| </Button> | |||||
| </div> | |||||
| <div | |||||
| style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }} | |||||
| > | |||||
| <Button | |||||
| type="primary" | |||||
| className={Styles.plusButton} | |||||
| style={{ margin: '0 20px 0 0' }} | |||||
| onClick={deleteDataset} | |||||
| icon={<DeleteOutlined style={{ color: '#1664ff' }} />} | |||||
| > | |||||
| 删除 | |||||
| </Button> | |||||
| <Button | |||||
| type="primary" | |||||
| disabled={!version} | |||||
| className={Styles.plusButton} | |||||
| style={{ margin: '0 20px 0 0' }} | |||||
| onClick={handleExport} | |||||
| icon={<DownloadOutlined style={{ color: '#1664ff' }} />} | |||||
| > | |||||
| 下载 | |||||
| </Button> | |||||
| </div> | |||||
| </div> | |||||
| <div style={{ marginBottom: '10px', fontSize: '14px' }}> | |||||
| {wordList.length > 0 ? wordList[0].description : null} | |||||
| </div> | |||||
| <Table columns={columns} dataSource={wordList} pagination={false} /> | |||||
| </div> | |||||
| </TabPane> | |||||
| </Tabs> | |||||
| </div> | |||||
| <Modal | |||||
| title={ | |||||
| <div style={{ display: 'flex', alignItems: 'center', fontWeight: 500 }}> | |||||
| <img | |||||
| style={{ width: '20px', marginRight: '10px' }} | |||||
| src={`/assets/images/pipeline-edit-icon.png`} | |||||
| alt="" | |||||
| /> | |||||
| {dialogTitle} | |||||
| </div> | |||||
| } | |||||
| open={isModalOpen} | |||||
| className={Styles.modal} | |||||
| okButtonProps={{ | |||||
| htmlType: 'submit', | |||||
| form: 'form', | |||||
| }} | |||||
| onCancel={handleCancel} | |||||
| > | |||||
| <Form | <Form | ||||
| name="form" | name="form" | ||||
| form={form} | form={form} | ||||
| @@ -271,28 +320,71 @@ const Dataset= React.FC = () => { | |||||
| label="数据集名称" | label="数据集名称" | ||||
| name="name" | name="name" | ||||
| rules={[ | rules={[ | ||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| { | |||||
| required: true, | |||||
| message: '请输入数据集名称', | |||||
| }, | |||||
| ]} | ]} | ||||
| > | > | ||||
| <Input disabled placeholder="请输入数据集名称"/> | |||||
| <Input disabled placeholder="请输入数据集名称" /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | |||||
| <Form.Item | |||||
| label="数据集版本" | label="数据集版本" | ||||
| name="version" | name="version" | ||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请输入数据集版本', | |||||
| }, | |||||
| ]} | |||||
| > | > | ||||
| <Input placeholder="请输入数据集版本"/> | |||||
| <Input placeholder="请输入数据集版本" maxLength={64} showCount allowClear /> | |||||
| </Form.Item> | |||||
| <Form.Item | |||||
| label="版本描述" | |||||
| name="description" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请输入版本描述', | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Input.TextArea | |||||
| placeholder="请输入版本描述" | |||||
| autoSize={{ minRows: 2, maxRows: 6 }} | |||||
| maxLength={256} | |||||
| showCount | |||||
| allowClear | |||||
| /> | |||||
| </Form.Item> | |||||
| <Form.Item | |||||
| label="数据集文件" | |||||
| name="dataset_version_vos" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请上传数据集文件', | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Upload {...props}> | |||||
| <Button | |||||
| style={{ | |||||
| fontSize: '14px', | |||||
| border: '1px solid', | |||||
| borderColor: '#1664ff', | |||||
| background: '#fff', | |||||
| }} | |||||
| icon={<UploadOutlined style={{ color: '#1664ff' }} />} | |||||
| > | |||||
| 上传文件 | |||||
| </Button> | |||||
| </Upload> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item label="数据文件" name="dataset_version_vos"> | |||||
| <Upload {...props}> | |||||
| <Button style={{fontSize:'14px',border:'1px solid',borderColor:'#1664ff',background:'#fff'}} icon={<UploadOutlined style={{color:'#1664ff'}} />}>上传文件</Button> | |||||
| </Upload> | |||||
| </Form.Item> | |||||
| </Form> | </Form> | ||||
| </Modal> | </Modal> | ||||
| </div>) | |||||
| </div> | |||||
| ); | |||||
| }; | }; | ||||
| export default Dataset; | |||||
| export default Dataset; | |||||
| @@ -1,84 +1,74 @@ | |||||
| import React ,{useEffect,useState}from 'react'; | |||||
| import Styles from './index.less' | |||||
| import { Input, Space ,Button,Tabs,Pagination,Modal, Form,message, Radio,} from 'antd'; | |||||
| import { PlusOutlined,PlusCircleOutlined, DeleteOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined ,CopyOutlined} from '@ant-design/icons'; | |||||
| import {getDatasetList} from '@/services/dataset/index.js' | |||||
| import { getDatasetList } from '@/services/dataset/index.js'; | |||||
| import { Form, Input, Tabs } from 'antd'; | |||||
| import React, { useEffect, useState } from 'react'; | |||||
| import { useNavigate } from 'react-router-dom'; | |||||
| import Styles from './index.less'; | |||||
| import PersonalData from './personalData'; | |||||
| import PublicData from './publicData'; | |||||
| const { Search } = Input; | const { Search } = Input; | ||||
| import { useNavigate} from 'react-router-dom'; | |||||
| import moment from 'moment'; | |||||
| const { TabPane } = Tabs; | const { TabPane } = Tabs; | ||||
| import PublicData from './publicData'; | |||||
| import PersonalData from './personalData' | |||||
| const leftdataList=[1,2,3] | |||||
| const leftdataList = [1, 2, 3]; | |||||
| const Dataset= React.FC = () => { | |||||
| const [queryFlow,setQueryFlow]=useState({ | |||||
| page:0, | |||||
| size:10, | |||||
| name:null | |||||
| const Dataset = (React.FC = () => { | |||||
| const [queryFlow, setQueryFlow] = useState({ | |||||
| page: 0, | |||||
| size: 10, | |||||
| name: null, | |||||
| }); | }); | ||||
| const navgite=useNavigate(); | |||||
| const [isModalOpen,setIsModalOpen]=useState(false) | |||||
| const [datasetList,setDatasetList]=useState([]); | |||||
| const [total,setTotal]=useState(0); | |||||
| const navgite = useNavigate(); | |||||
| const [isModalOpen, setIsModalOpen] = useState(false); | |||||
| const [datasetList, setDatasetList] = useState([]); | |||||
| const [total, setTotal] = useState(0); | |||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const [dialogTitle, setDialogTitle] = useState('新建数据'); | const [dialogTitle, setDialogTitle] = useState('新建数据'); | ||||
| const getDatasetlist=()=>{ | |||||
| getDatasetList(queryFlow).then(ret=>{ | |||||
| const getDatasetlist = () => { | |||||
| getDatasetList(queryFlow).then((ret) => { | |||||
| console.log(ret); | console.log(ret); | ||||
| if(ret.code==200){ | |||||
| setDatasetList(ret.data.content) | |||||
| setTotal(ret.data.totalElements) | |||||
| if (ret.code == 200) { | |||||
| setDatasetList(ret.data.content); | |||||
| setTotal(ret.data.totalElements); | |||||
| } | } | ||||
| }) | |||||
| } | |||||
| }); | |||||
| }; | |||||
| const showModal = () => { | const showModal = () => { | ||||
| form.resetFields() | |||||
| setDialogTitle('新建数据集') | |||||
| form.resetFields(); | |||||
| setDialogTitle('新建数据集'); | |||||
| setIsModalOpen(true); | setIsModalOpen(true); | ||||
| }; | }; | ||||
| const handleOk = () => { | const handleOk = () => { | ||||
| console.log(1111); | |||||
| console.log(1111); | |||||
| setIsModalOpen(false); | setIsModalOpen(false); | ||||
| }; | }; | ||||
| const handleCancel = () => { | const handleCancel = () => { | ||||
| setIsModalOpen(false); | setIsModalOpen(false); | ||||
| }; | }; | ||||
| const onFinish = (values) => { | |||||
| }; | |||||
| const routeToIntro=(e,record)=>{ | |||||
| e.stopPropagation() | |||||
| navgite({pathname:'/dataset/datasetIntro' }); | |||||
| } | |||||
| const onFinish = (values) => {}; | |||||
| const routeToIntro = (e, record) => { | |||||
| e.stopPropagation(); | |||||
| navgite({ pathname: '/dataset/datasetIntro' }); | |||||
| }; | |||||
| const onFinishFailed = (errorInfo) => { | const onFinishFailed = (errorInfo) => { | ||||
| console.log('Failed:', errorInfo); | console.log('Failed:', errorInfo); | ||||
| }; | }; | ||||
| useEffect(()=>{ | |||||
| getDatasetlist() | |||||
| return ()=>{ | |||||
| } | |||||
| },[]) | |||||
| return (<div className={Styles.datasetBox}> | |||||
| <div className={Styles.datasetTopBox}> | |||||
| </div> | |||||
| <div className={Styles.datasetAllBox}> | |||||
| <Tabs | |||||
| defaultActiveKey="1" | |||||
| > | |||||
| <TabPane tab="数据广场" key="1"> | |||||
| <PublicData/> | |||||
| </TabPane> | |||||
| <TabPane tab="个人数据" key="2"> | |||||
| <PersonalData/> | |||||
| </TabPane> | |||||
| </Tabs> | |||||
| </div> | |||||
| </div>) | |||||
| }; | |||||
| export default Dataset; | |||||
| useEffect(() => { | |||||
| getDatasetlist(); | |||||
| return () => {}; | |||||
| }, []); | |||||
| return ( | |||||
| <div className={Styles.datasetBox}> | |||||
| <div className={Styles.datasetTopBox}></div> | |||||
| <div className={Styles.datasetAllBox}> | |||||
| <Tabs defaultActiveKey="1"> | |||||
| <TabPane tab="数据广场" key="1"> | |||||
| <PublicData /> | |||||
| </TabPane> | |||||
| <TabPane tab="个人数据" key="2"> | |||||
| <PersonalData /> | |||||
| </TabPane> | |||||
| </Tabs> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| }); | |||||
| export default Dataset; | |||||
| @@ -1,303 +1,297 @@ | |||||
| .datasetTopBox{ | |||||
| .datasetTopBox { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| width: 100%; | |||||
| height: 49px; | |||||
| padding: 0 30px; | |||||
| padding-right: 30px; | |||||
| background-image: url(/assets/images/pipeline-back.png); | |||||
| background-size: 100% 100%; | |||||
| } | |||||
| .datasetIntroTopBox { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| justify-content: space-between; | |||||
| width: 100%; | |||||
| height: 110px; | |||||
| margin-bottom: 10px; | |||||
| padding: 25px 30px; | |||||
| background-image: url(/assets/images/dataset-back.png); | |||||
| background-size: 100% 100%; | |||||
| .smallTagBox { | |||||
| display: flex; | display: flex; | ||||
| align-items: center; | align-items: center; | ||||
| padding-right: 30px; | |||||
| width: 100%; | |||||
| height: 49px; | |||||
| background-size: 100% 100%; | |||||
| background-image: url(/assets/images/pipeline-back.png); | |||||
| padding: 0 30px; | |||||
| color: #1664ff; | |||||
| font-size: 14px; | |||||
| .tagItem { | |||||
| margin-right: 20px; | |||||
| padding: 4px 10px; | |||||
| background: rgba(22, 100, 255, 0.1); | |||||
| border-radius: 4px; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| .datasetIntroTopBox{ | |||||
| .dataListBox { | |||||
| padding: 20px 30px; | |||||
| color: #1d1d20; | |||||
| font-size: 16px; | |||||
| background: #ffffff; | |||||
| border-radius: 10px; | |||||
| box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09); | |||||
| .dataButtonList { | |||||
| display: flex; | display: flex; | ||||
| flex-direction: column; | |||||
| align-items: center; | |||||
| justify-content: space-between; | justify-content: space-between; | ||||
| width: 100%; | |||||
| height: 110px; | |||||
| background-size: 100% 100%; | |||||
| background-image: url(/assets/images/dataset-back.png); | |||||
| margin-bottom: 10px; | |||||
| padding: 25px 30px; | |||||
| .smallTagBox{ | |||||
| display: flex; | |||||
| align-items: center; | |||||
| color:#1664ff; | |||||
| font-size:14px; | |||||
| .tagItem{ | |||||
| padding: 4px 10px; | |||||
| background: rgba(22, 100, 255, 0.1); | |||||
| border-radius:4px; | |||||
| margin-right: 20px; | |||||
| } | |||||
| } | |||||
| } | |||||
| .dataListBox{ | |||||
| padding: 20px 30px; | |||||
| background:#ffffff; | |||||
| border-radius:10px; | |||||
| box-shadow:0px 2px 12px rgba(180, 182, 191, 0.09); | |||||
| color:#1d1d20; | |||||
| font-size:16px; | |||||
| .dataButtonList{ | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| height: 32px; | |||||
| margin: 24px 0 30px 0; | |||||
| color:#575757; | |||||
| font-size:16px; | |||||
| } | |||||
| height: 32px; | |||||
| margin: 24px 0 30px 0; | |||||
| color: #575757; | |||||
| font-size: 16px; | |||||
| } | |||||
| } | } | ||||
| .datasetIntroCneterBox{ | |||||
| height: 77vh; | |||||
| padding: 20px 30px; | |||||
| background:#ffffff; | |||||
| border-radius:10px; | |||||
| box-shadow:0px 2px 12px rgba(180, 182, 191, 0.09); | |||||
| .datasetIntroCneterBox { | |||||
| height: 77vh; | |||||
| padding: 20px 30px; | |||||
| background: #ffffff; | |||||
| border-radius: 10px; | |||||
| box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09); | |||||
| } | } | ||||
| .datasetIntroTitle{ | |||||
| color:#1d1d20; | |||||
| font-size:15px; | |||||
| margin: 37px 0 10px 0; | |||||
| .datasetIntroTitle { | |||||
| margin: 37px 0 10px 0; | |||||
| color: #1d1d20; | |||||
| font-size: 15px; | |||||
| } | } | ||||
| .datasetIntroText{ | |||||
| color:#575757; | |||||
| font-size:14px; | |||||
| margin-bottom: 30px; | |||||
| .datasetIntroText { | |||||
| margin-bottom: 30px; | |||||
| color: #575757; | |||||
| font-size: 14px; | |||||
| } | } | ||||
| .datasetBox{ | |||||
| background:#f9fafb; | |||||
| font-family: 'Alibaba'; | |||||
| :global{ | |||||
| .ant-tabs-top >.ant-tabs-nav{ | |||||
| margin: 0; | |||||
| } | |||||
| .ant-pagination{ | |||||
| text-align: right; | |||||
| } | |||||
| .datasetBox { | |||||
| font-family: 'Alibaba'; | |||||
| background: #f9fafb; | |||||
| :global { | |||||
| .ant-tabs-top > .ant-tabs-nav { | |||||
| margin: 0; | |||||
| } | } | ||||
| .ant-pagination { | |||||
| text-align: right; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| .datasetAllBox{ | |||||
| :global{ | |||||
| .ant-tabs-nav .ant-tabs-nav-wrap{ | |||||
| margin: -48px 0 0 30px; | |||||
| } | |||||
| .datasetAllBox { | |||||
| :global { | |||||
| .ant-tabs-nav .ant-tabs-nav-wrap { | |||||
| margin: -48px 0 0 30px; | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| .plusButton{ | |||||
| margin: 0 18px 0 20px; | |||||
| background:rgba(22, 100, 255, 0.06); | |||||
| border:1px solid; | |||||
| border-color:rgba(22, 100, 255, 0.11); | |||||
| border-radius:4px; | |||||
| color:#1d1d20; | |||||
| font-size:14px; | |||||
| font-family: 'Alibaba'; | |||||
| .plusButton { | |||||
| margin: 0 18px 0 20px; | |||||
| color: #1d1d20; | |||||
| font-size: 14px; | |||||
| font-family: 'Alibaba'; | |||||
| background: rgba(22, 100, 255, 0.06); | |||||
| border: 1px solid; | |||||
| border-color: rgba(22, 100, 255, 0.11); | |||||
| border-radius: 4px; | |||||
| } | } | ||||
| .plusButton:hover{ | |||||
| background:rgba(22, 100, 255, 0.06)!important; | |||||
| border:1px solid!important; | |||||
| border-color:rgba(22, 100, 255, 0.11)!important; | |||||
| color:#1d1d20!important; | |||||
| .plusButton:hover { | |||||
| color: #1d1d20 !important; | |||||
| background: rgba(22, 100, 255, 0.06) !important; | |||||
| border: 1px solid !important; | |||||
| border-color: rgba(22, 100, 255, 0.11) !important; | |||||
| } | } | ||||
| .datasetCneterBox{ | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| height: 85vh; | |||||
| width: 100%; | |||||
| :global{ | |||||
| .ant-btn{ | |||||
| color:#1d1d20; | |||||
| font-size:14px; | |||||
| } | |||||
| .datasetCneterBox { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| width: 100%; | |||||
| height: 85vh; | |||||
| :global { | |||||
| .ant-btn { | |||||
| color: #1d1d20; | |||||
| font-size: 14px; | |||||
| } | } | ||||
| .datasetCneterLeftBox{ | |||||
| width:340px; | |||||
| height:100%; | |||||
| background:#ffffff; | |||||
| box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09); | |||||
| margin-right: 10px; | |||||
| padding-top: 15px; | |||||
| .custTab{ | |||||
| display: flex; | |||||
| border-bottom: 1px solid #e0eaff; | |||||
| height: 32px; | |||||
| .tabItem{ | |||||
| width: 52px; | |||||
| height: 100%; | |||||
| text-align: center; | |||||
| color:#808080; | |||||
| font-size:15px; | |||||
| cursor: pointer; | |||||
| } | |||||
| } | |||||
| .datasetCneterLeftBox { | |||||
| width: 340px; | |||||
| height: 100%; | |||||
| margin-right: 10px; | |||||
| padding-top: 15px; | |||||
| background: #ffffff; | |||||
| box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09); | |||||
| .custTab { | |||||
| display: flex; | |||||
| height: 32px; | |||||
| border-bottom: 1px solid #e0eaff; | |||||
| .tabItem { | |||||
| width: 52px; | |||||
| height: 100%; | |||||
| color: #808080; | |||||
| font-size: 15px; | |||||
| text-align: center; | |||||
| cursor: pointer; | |||||
| } | |||||
| } | |||||
| .leftContentBox { | |||||
| max-height: 80vh; | |||||
| padding: 15px 20px; | |||||
| overflow-x: hidden; | |||||
| overflow-y: auto; | |||||
| .itemTitle { | |||||
| margin-bottom: 15px; | |||||
| color: #1d1d20; | |||||
| font-size: 14px; | |||||
| } | |||||
| .itemBox { | |||||
| display: flex; | |||||
| flex-wrap: wrap; | |||||
| align-content: start; | |||||
| width: 110%; | |||||
| .messageBox { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| width: 92px; | |||||
| height: 62px; | |||||
| margin: 0 12px 20px 0; | |||||
| padding: 11px 0px 7px 0px; | |||||
| color: #1d1d20; | |||||
| font-size: 12px; | |||||
| border: 1px solid; | |||||
| border-color: rgba(22, 100, 255, 0.05); | |||||
| border-radius: 4px; | |||||
| cursor: pointer; | |||||
| .ptIcon { | |||||
| display: block; | |||||
| } | |||||
| .hoverIcon { | |||||
| display: none; | |||||
| } | |||||
| .messageText { | |||||
| width: 65px; | |||||
| overflow: hidden; | |||||
| white-space: nowrap; | |||||
| text-align: center; | |||||
| text-overflow: ellipsis; | |||||
| } | |||||
| } | } | ||||
| .leftContentBox{ | |||||
| max-height: 80vh; | |||||
| overflow-y: auto; | |||||
| overflow-x: hidden; | |||||
| padding: 15px 20px; | |||||
| .itemTitle{ | |||||
| color:#1d1d20; | |||||
| font-size:14px; | |||||
| margin-bottom: 15px; | |||||
| } | |||||
| .itemBox{ | |||||
| width: 110%; | |||||
| display: flex; | |||||
| flex-wrap: wrap; | |||||
| align-content: start; | |||||
| .messageBox{ | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| cursor: pointer; | |||||
| width:92px; | |||||
| height:62px; | |||||
| border:1px solid; | |||||
| border-color:rgba(22, 100, 255, 0.05); | |||||
| border-radius:4px; | |||||
| margin: 0 12px 20px 0; | |||||
| padding: 11px 0px 7px 0px; | |||||
| color:#1d1d20; | |||||
| font-size:12px; | |||||
| .ptIcon{ | |||||
| display: block; | |||||
| } | |||||
| .hoverIcon{ | |||||
| display: none; | |||||
| } | |||||
| .messageText{ | |||||
| width: 65px; | |||||
| text-align: center; | |||||
| overflow: hidden; | |||||
| text-overflow: ellipsis; | |||||
| white-space: nowrap; | |||||
| } | |||||
| } | |||||
| .messageBox:hover{ | |||||
| background:rgba(22, 100, 255, 0.03); | |||||
| border:1px solid; | |||||
| border-color:#1664ff; | |||||
| .ptIcon{ | |||||
| display: none; | |||||
| } | |||||
| .hoverIcon{ | |||||
| display: block; | |||||
| } | |||||
| } | |||||
| .active{ | |||||
| background:rgba(22, 100, 255, 0.03)!important; | |||||
| border:1px solid!important; | |||||
| border-color:#1664ff!important; | |||||
| .ptIcon{ | |||||
| display: none!important; | |||||
| } | |||||
| .hoverIcon{ | |||||
| display: block!important; | |||||
| } | |||||
| } | |||||
| } | |||||
| .messageBox:hover { | |||||
| background: rgba(22, 100, 255, 0.03); | |||||
| border: 1px solid; | |||||
| border-color: #1664ff; | |||||
| .ptIcon { | |||||
| display: none; | |||||
| } | |||||
| .hoverIcon { | |||||
| display: block; | |||||
| } | |||||
| } | } | ||||
| .active { | |||||
| background: rgba(22, 100, 255, 0.03) !important; | |||||
| border: 1px solid !important; | |||||
| border-color: #1664ff !important; | |||||
| .ptIcon { | |||||
| display: none !important; | |||||
| } | |||||
| .hoverIcon { | |||||
| display: block !important; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | |||||
| .datasetCneterRightBox{ | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| padding: 22px 30px 26px 30px; | |||||
| flex: 1; | |||||
| height:100%; | |||||
| background:#ffffff; | |||||
| box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09); | |||||
| .dataSource{ | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| height: 32px; | |||||
| margin-bottom: 30px; | |||||
| color:rgba(29, 29, 32, 0.8); | |||||
| font-size:15px; | |||||
| .datasetCneterRightBox { | |||||
| display: flex; | |||||
| flex: 1; | |||||
| flex-direction: column; | |||||
| height: 100%; | |||||
| padding: 22px 30px 26px 30px; | |||||
| background: #ffffff; | |||||
| box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09); | |||||
| .dataSource { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| height: 32px; | |||||
| margin-bottom: 30px; | |||||
| color: rgba(29, 29, 32, 0.8); | |||||
| font-size: 15px; | |||||
| } | |||||
| .dataContent { | |||||
| display: flex; | |||||
| flex: 1; | |||||
| flex-wrap: wrap; | |||||
| align-content: flex-start; | |||||
| width: 100%; | |||||
| .dataItem { | |||||
| position: relative; | |||||
| width: 32%; | |||||
| height: 66px; | |||||
| margin: 0 15px 18px 0; | |||||
| background: rgba(128, 128, 128, 0.05); | |||||
| border-radius: 8px; | |||||
| box-shadow: 0px 0px 12px rgba(75, 84, 137, 0.05); | |||||
| cursor: pointer; | |||||
| .itemText { | |||||
| position: absolute; | |||||
| top: 10px; | |||||
| left: 20px; | |||||
| color: #1d1d20; | |||||
| font-size: 15px; | |||||
| } | |||||
| .itemTime { | |||||
| position: absolute; | |||||
| bottom: 10px; | |||||
| left: 20px; | |||||
| color: #808080; | |||||
| font-size: 14px; | |||||
| } | } | ||||
| .dataContent{ | |||||
| width: 100%; | |||||
| flex: 1; | |||||
| display: flex; | |||||
| flex-wrap: wrap; | |||||
| align-content: flex-start; | |||||
| .dataItem{ | |||||
| width: 32%; | |||||
| margin: 0 15px 18px 0; | |||||
| height:66px; | |||||
| position: relative; | |||||
| background:rgba(128, 128, 128, 0.05); | |||||
| border-radius:8px; | |||||
| box-shadow:0px 0px 12px rgba(75, 84, 137, 0.05); | |||||
| cursor: pointer; | |||||
| .itemText{ | |||||
| position: absolute; | |||||
| left: 20px; | |||||
| top: 10px; | |||||
| color:#1d1d20; | |||||
| font-size:15px; | |||||
| } | |||||
| .itemTime{ | |||||
| position: absolute; | |||||
| left: 20px; | |||||
| bottom: 10px; | |||||
| color:#808080; | |||||
| font-size:14px; | |||||
| } | |||||
| .itemIcon{ | |||||
| position: absolute; | |||||
| right: 20px; | |||||
| bottom: 10px; | |||||
| color:#808080; | |||||
| font-size:14px; | |||||
| } | |||||
| } | |||||
| .itemIcon { | |||||
| position: absolute; | |||||
| right: 20px; | |||||
| bottom: 10px; | |||||
| color: #808080; | |||||
| font-size: 14px; | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| .modal { | .modal { | ||||
| :global { | |||||
| .ant-modal-content { | |||||
| background:linear-gradient(180deg,#cfdfff 0%,#d4e2ff 9.77%,#ffffff 40%,#ffffff 100%); | |||||
| border-radius:21px; | |||||
| padding: 20px 67px; | |||||
| width: 825px; | |||||
| } | |||||
| .ant-modal-header{ | |||||
| background-color: transparent; | |||||
| margin: 20px 0; | |||||
| } | |||||
| .ant-input{ | |||||
| border-color:#e6e6e6; | |||||
| height: 40px; | |||||
| } | |||||
| .ant-form-item .ant-form-item-label >label{ | |||||
| color:rgba(29, 29, 32, 0.8); | |||||
| } | |||||
| .ant-modal-footer{ | |||||
| margin: 40px 0 30px 0; | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| } | |||||
| .ant-btn{ | |||||
| width:110px; | |||||
| height:40px; | |||||
| font-size:18px; | |||||
| background:rgba(22, 100, 255, 0.06); | |||||
| border-radius:10px; | |||||
| border-color: transparent; | |||||
| } | |||||
| .ant-btn-primary{ | |||||
| background:#1664ff; | |||||
| } | |||||
| :global { | |||||
| .ant-modal-content { | |||||
| width: 825px; | |||||
| padding: 20px 67px; | |||||
| background: linear-gradient(180deg, #cfdfff 0%, #d4e2ff 9.77%, #ffffff 40%, #ffffff 100%); | |||||
| border-radius: 21px; | |||||
| } | |||||
| .ant-modal-header { | |||||
| margin: 20px 0; | |||||
| background-color: transparent; | |||||
| } | |||||
| .ant-input { | |||||
| height: 40px; | |||||
| border-color: #e6e6e6; | |||||
| } | } | ||||
| } | |||||
| .ant-form-item .ant-form-item-label > label { | |||||
| color: rgba(29, 29, 32, 0.8); | |||||
| } | |||||
| .ant-modal-footer { | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| margin: 40px 0 30px 0; | |||||
| } | |||||
| .ant-btn { | |||||
| width: 110px; | |||||
| height: 40px; | |||||
| font-size: 18px; | |||||
| background: rgba(22, 100, 255, 0.06); | |||||
| border-color: transparent; | |||||
| border-radius: 10px; | |||||
| } | |||||
| .ant-btn-primary { | |||||
| background: #1664ff; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,240 +1,302 @@ | |||||
| import React ,{useEffect,useState}from 'react'; | |||||
| import Styles from './index.less' | |||||
| import './index.less' | |||||
| import { Input, Space ,Button,Tabs,Pagination,Modal, Form,message, Radio,Select,Upload } from 'antd'; | |||||
| import { PlusOutlined,PlusCircleOutlined,UploadOutlined , DeleteOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined ,CopyOutlined} from '@ant-design/icons'; | |||||
| import {getDatasetList,addDatesetAndVesion,getAssetIcon} from '@/services/dataset/index.js' | |||||
| import { getDictSelectOption } from "@/services/system/dict"; | |||||
| const { Search } = Input; | |||||
| import { useNavigate} from 'react-router-dom'; | |||||
| import { getAccessToken } from '@/access'; | |||||
| import { addDatesetAndVesion, getAssetIcon, getDatasetList } from '@/services/dataset/index.js'; | |||||
| import { getDictSelectOption } from '@/services/system/dict'; | |||||
| import { PlusCircleOutlined, UploadOutlined } from '@ant-design/icons'; | |||||
| import { Button, Form, Input, Modal, Pagination, Radio, Select, Upload } from 'antd'; | |||||
| import moment from 'moment'; | import moment from 'moment'; | ||||
| import axios from 'axios' | |||||
| import { getAccessToken } from '@/access'; | |||||
| const leftdataList=[1,2,3] | |||||
| const PublicData= React.FC = () => { | |||||
| import React, { useEffect, useState } from 'react'; | |||||
| import { useNavigate } from 'react-router-dom'; | |||||
| import './index.less'; | |||||
| import Styles from './index.less'; | |||||
| const { Search } = Input; | |||||
| const leftdataList = [1, 2, 3]; | |||||
| const PublicData = (React.FC = () => { | |||||
| const props = { | const props = { | ||||
| action: '/api/mmp/dataset/upload', | action: '/api/mmp/dataset/upload', | ||||
| // headers: { | // headers: { | ||||
| // 'X-Requested-With': null | // 'X-Requested-With': null | ||||
| // }, | // }, | ||||
| headers: { | headers: { | ||||
| Authorization:getAccessToken(), | |||||
| 'X-Requested-With': null | |||||
| Authorization: getAccessToken(), | |||||
| 'X-Requested-With': null, | |||||
| }, | }, | ||||
| onChange({ file, fileList }) { | onChange({ file, fileList }) { | ||||
| if (file.status !== 'uploading') { | if (file.status !== 'uploading') { | ||||
| console.log(file, fileList); | console.log(file, fileList); | ||||
| form.setFieldsValue({dataset_version_vos:fileList.map(item=>item.response.data[0])}) | |||||
| form.setFieldsValue({ dataset_version_vos: fileList.map((item) => item.response.data[0]) }); | |||||
| } | } | ||||
| }, | }, | ||||
| defaultFileList: [ | |||||
| ], | |||||
| defaultFileList: [], | |||||
| }; | }; | ||||
| const [queryFlow,setQueryFlow]=useState({ | |||||
| page:0, | |||||
| size:10, | |||||
| name:null, | |||||
| available_range:0, | |||||
| const [queryFlow, setQueryFlow] = useState({ | |||||
| page: 0, | |||||
| size: 10, | |||||
| name: null, | |||||
| available_range: 0, | |||||
| }); | |||||
| const [iconParams, setIconParams] = useState({ | |||||
| name: null, | |||||
| page: 0, | |||||
| size: 10000, | |||||
| }); | }); | ||||
| const [iconParams,setIconParams]=useState({ | |||||
| name:null, | |||||
| page:0, | |||||
| size:10000 | |||||
| }) | |||||
| const [activeType,setActiveType]=useState(null) | |||||
| const [activeTag,setActiveTag]=useState(null) | |||||
| const [datasetTypeList,setDatasetTypeList]=useState([]) | |||||
| const [datasetDirectionList,setDatasetDirectionList]=useState([]) | |||||
| const navgite=useNavigate(); | |||||
| const [clusterOptions,setClusterOptions]=useState([]) | |||||
| const [isModalOpen,setIsModalOpen]=useState(false) | |||||
| const [datasetList,setDatasetList]=useState([]); | |||||
| const [total,setTotal]=useState(0); | |||||
| const [activeType, setActiveType] = useState(null); | |||||
| const [activeTag, setActiveTag] = useState(null); | |||||
| const [datasetTypeList, setDatasetTypeList] = useState([]); | |||||
| const [datasetDirectionList, setDatasetDirectionList] = useState([]); | |||||
| const navgite = useNavigate(); | |||||
| const [clusterOptions, setClusterOptions] = useState([]); | |||||
| const [isModalOpen, setIsModalOpen] = useState(false); | |||||
| const [datasetList, setDatasetList] = useState([]); | |||||
| const [total, setTotal] = useState(0); | |||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const [dialogTitle, setDialogTitle] = useState('新建数据'); | const [dialogTitle, setDialogTitle] = useState('新建数据'); | ||||
| const getDatasetlist=(queryFlow)=>{ | |||||
| getDatasetList(queryFlow).then(ret=>{ | |||||
| const getDatasetlist = (queryFlow) => { | |||||
| getDatasetList(queryFlow).then((ret) => { | |||||
| console.log(ret); | console.log(ret); | ||||
| if(ret.code==200){ | |||||
| setDatasetList(ret.data.content) | |||||
| setTotal(ret.data.totalElements) | |||||
| if (ret.code == 200) { | |||||
| setDatasetList(ret.data.content); | |||||
| setTotal(ret.data.totalElements); | |||||
| } | } | ||||
| }) | |||||
| } | |||||
| }); | |||||
| }; | |||||
| const showModal = () => { | const showModal = () => { | ||||
| form.resetFields() | |||||
| setDialogTitle('新建数据集') | |||||
| form.resetFields(); | |||||
| setDialogTitle('新建数据集'); | |||||
| setIsModalOpen(true); | setIsModalOpen(true); | ||||
| }; | }; | ||||
| const getAssetIconList=(params)=>{ | |||||
| getAssetIcon(params).then(ret=>{ | |||||
| const getAssetIconList = (params) => { | |||||
| getAssetIcon(params).then((ret) => { | |||||
| console.log(ret); | console.log(ret); | ||||
| if(ret.code==200&&ret.data.content&&ret.data.content.length>0){ | |||||
| setDatasetTypeList(ret.data.content.filter(item=>item.category_id==1)) | |||||
| setDatasetDirectionList(ret.data.content.filter(item=>item.category_id==2)) | |||||
| if (ret.code == 200 && ret.data.content && ret.data.content.length > 0) { | |||||
| setDatasetTypeList(ret.data.content.filter((item) => item.category_id == 1)); | |||||
| setDatasetDirectionList(ret.data.content.filter((item) => item.category_id == 2)); | |||||
| } else { | |||||
| setDatasetTypeList([]); | |||||
| setDatasetDirectionList([]); | |||||
| } | } | ||||
| else{ | |||||
| setDatasetTypeList([]) | |||||
| setDatasetDirectionList([]) | |||||
| } | |||||
| }) | |||||
| } | |||||
| const onSearch=(values)=>{ | |||||
| }); | |||||
| }; | |||||
| const onSearch = (values) => { | |||||
| console.log(values); | console.log(values); | ||||
| getAssetIconList({...iconParams,name:values}) | |||||
| } | |||||
| const nameSearch=(values)=>{ | |||||
| getAssetIconList({ ...iconParams, name: values }); | |||||
| }; | |||||
| const nameSearch = (values) => { | |||||
| console.log(values); | console.log(values); | ||||
| getDatasetlist({...queryFlow,name:values}) | |||||
| } | |||||
| getDatasetlist({ ...queryFlow, name: values }); | |||||
| }; | |||||
| const handleOk = () => { | const handleOk = () => { | ||||
| console.log(1111); | |||||
| console.log(1111); | |||||
| setIsModalOpen(false); | setIsModalOpen(false); | ||||
| }; | }; | ||||
| const handleCancel = () => { | const handleCancel = () => { | ||||
| setIsModalOpen(false); | setIsModalOpen(false); | ||||
| }; | }; | ||||
| const chooseDatasetType=(val,item)=>{ | |||||
| console.log(val,item); | |||||
| if(item.path==queryFlow.data_type){ | |||||
| setActiveType('') | |||||
| setQueryFlow({...queryFlow,data_type:null}) | |||||
| getDatasetlist({...queryFlow,data_type:null}) | |||||
| } | |||||
| else{ | |||||
| setActiveType(item.path) | |||||
| setQueryFlow({...queryFlow,data_type:item.path}) | |||||
| getDatasetlist({...queryFlow,data_type:item.path}) | |||||
| const chooseDatasetType = (val, item) => { | |||||
| console.log(val, item); | |||||
| if (item.path == queryFlow.data_type) { | |||||
| setActiveType(''); | |||||
| setQueryFlow({ ...queryFlow, data_type: null }); | |||||
| getDatasetlist({ ...queryFlow, data_type: null }); | |||||
| } else { | |||||
| setActiveType(item.path); | |||||
| setQueryFlow({ ...queryFlow, data_type: item.path }); | |||||
| getDatasetlist({ ...queryFlow, data_type: item.path }); | |||||
| } | } | ||||
| // setQueryFlow({...queryFlow,data_type:item.path},()=>{ | // setQueryFlow({...queryFlow,data_type:item.path},()=>{ | ||||
| // getDatasetlist() | // getDatasetlist() | ||||
| // }) | // }) | ||||
| }; | }; | ||||
| const chooseDatasetTag=(val,item)=>{ | |||||
| console.log(val,item); | |||||
| if(item.path==queryFlow.data_tag){ | |||||
| setActiveTag('') | |||||
| setQueryFlow({...queryFlow,data_tag:null}) | |||||
| getDatasetlist({...queryFlow,data_tag:null}) | |||||
| } | |||||
| else{ | |||||
| setActiveTag(item.path) | |||||
| setQueryFlow({...queryFlow,data_tag:item.path}) | |||||
| getDatasetlist({...queryFlow,data_tag:item.path}) | |||||
| const chooseDatasetTag = (val, item) => { | |||||
| console.log(val, item); | |||||
| if (item.path == queryFlow.data_tag) { | |||||
| setActiveTag(''); | |||||
| setQueryFlow({ ...queryFlow, data_tag: null }); | |||||
| getDatasetlist({ ...queryFlow, data_tag: null }); | |||||
| } else { | |||||
| setActiveTag(item.path); | |||||
| setQueryFlow({ ...queryFlow, data_tag: item.path }); | |||||
| getDatasetlist({ ...queryFlow, data_tag: item.path }); | |||||
| } | } | ||||
| // setQueryFlow({...queryFlow,data_type:item.path},()=>{ | // setQueryFlow({...queryFlow,data_type:item.path},()=>{ | ||||
| // getDatasetlist() | // getDatasetlist() | ||||
| // }) | // }) | ||||
| }; | }; | ||||
| const onFinish = (values) => { | const onFinish = (values) => { | ||||
| addDatesetAndVesion(values).then(ret=>{ | |||||
| console.log(ret); | |||||
| setIsModalOpen(false); | |||||
| getDatasetlist(queryFlow) | |||||
| }) | |||||
| }; | |||||
| const routeToIntro=(e,record)=>{ | |||||
| e.stopPropagation() | |||||
| addDatesetAndVesion(values).then((ret) => { | |||||
| console.log(ret); | |||||
| setIsModalOpen(false); | |||||
| getDatasetlist(queryFlow); | |||||
| }); | |||||
| }; | |||||
| const routeToIntro = (e, record) => { | |||||
| e.stopPropagation(); | |||||
| console.log(record); | console.log(record); | ||||
| navgite({pathname:`/dataset/datasetIntro/${record.id}` }); | |||||
| } | |||||
| navgite({ pathname: `/dataset/datasetIntro/${record.id}` }); | |||||
| }; | |||||
| const onFinishFailed = (errorInfo) => { | const onFinishFailed = (errorInfo) => { | ||||
| console.log('Failed:', errorInfo); | console.log('Failed:', errorInfo); | ||||
| }; | }; | ||||
| useEffect(()=>{ | |||||
| useEffect(() => { | |||||
| getDictSelectOption('available_cluster').then((data) => { | getDictSelectOption('available_cluster').then((data) => { | ||||
| setClusterOptions(data); | setClusterOptions(data); | ||||
| }); | }); | ||||
| getAssetIconList(iconParams) | |||||
| getDatasetlist(queryFlow) | |||||
| return ()=>{ | |||||
| } | |||||
| },[]) | |||||
| return (<> | |||||
| <div className={Styles.datasetCneterBox}> | |||||
| <div className={Styles.datasetCneterLeftBox}> | |||||
| <div className={Styles.leftContentBox}> | |||||
| <Search | |||||
| placeholder="搜索" | |||||
| allowClear | |||||
| onSearch={onSearch} | |||||
| style={{ | |||||
| width: 300, | |||||
| marginBottom:'15px', | |||||
| }} | |||||
| /> | |||||
| <div className={Styles.itemTitle}>分类</div> | |||||
| <div className={Styles.itemBox}> | |||||
| {datasetTypeList&&datasetTypeList.length>0?datasetTypeList.map(item=>{return <div > | |||||
| <div className={[Styles.messageBox, item.path===activeType?Styles.active:null].join(' ')} onClick={(e)=>{chooseDatasetType(e, item)}} > | |||||
| <img className={Styles.ptIcon} style={{width:'22px'}} src={`/assets/images/dataset/${item.path}.png`} alt="" /> | |||||
| <img className={Styles.hoverIcon} style={{width:'22px'}} src={`/assets/images/dataset/${item.path}-hover.png`} alt="" /> | |||||
| <span className={Styles.messageText} >{item.name}</span> | |||||
| getAssetIconList(iconParams); | |||||
| getDatasetlist(queryFlow); | |||||
| return () => {}; | |||||
| }, []); | |||||
| return ( | |||||
| <> | |||||
| <div className={Styles.datasetCneterBox}> | |||||
| <div className={Styles.datasetCneterLeftBox}> | |||||
| <div className={Styles.leftContentBox}> | |||||
| <Search | |||||
| placeholder="搜索" | |||||
| allowClear | |||||
| onSearch={onSearch} | |||||
| style={{ | |||||
| width: 300, | |||||
| marginBottom: '15px', | |||||
| }} | |||||
| /> | |||||
| <div className={Styles.itemTitle}>分类</div> | |||||
| <div className={Styles.itemBox}> | |||||
| {datasetTypeList && datasetTypeList.length > 0 | |||||
| ? datasetTypeList.map((item) => { | |||||
| return ( | |||||
| <div> | |||||
| <div | |||||
| className={[ | |||||
| Styles.messageBox, | |||||
| item.path === activeType ? Styles.active : null, | |||||
| ].join(' ')} | |||||
| onClick={(e) => { | |||||
| chooseDatasetType(e, item); | |||||
| }} | |||||
| > | |||||
| <img | |||||
| className={Styles.ptIcon} | |||||
| style={{ width: '22px' }} | |||||
| src={`/assets/images/dataset/${item.path}.png`} | |||||
| alt="" | |||||
| /> | |||||
| <img | |||||
| className={Styles.hoverIcon} | |||||
| style={{ width: '22px' }} | |||||
| src={`/assets/images/dataset/${item.path}-hover.png`} | |||||
| alt="" | |||||
| /> | |||||
| <span className={Styles.messageText}>{item.name}</span> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| }) | |||||
| : ''} | |||||
| </div> | |||||
| <div className={Styles.itemTitle}>研究方向/应用领域</div> | |||||
| <div className={Styles.itemBox}> | |||||
| {datasetDirectionList && datasetDirectionList.length > 0 | |||||
| ? datasetDirectionList.map((item) => { | |||||
| return ( | |||||
| <div> | |||||
| <div | |||||
| className={[ | |||||
| Styles.messageBox, | |||||
| item.path === activeTag ? Styles.active : null, | |||||
| ].join(' ')} | |||||
| onClick={(e) => { | |||||
| chooseDatasetTag(e, item); | |||||
| }} | |||||
| > | |||||
| <img | |||||
| className={Styles.ptIcon} | |||||
| style={{ width: '22px' }} | |||||
| src={`/assets/images/dataset/${item.path}.png`} | |||||
| alt="" | |||||
| /> | |||||
| <img | |||||
| className={Styles.hoverIcon} | |||||
| style={{ width: '22px' }} | |||||
| src={`/assets/images/dataset/${item.path}-hover.png`} | |||||
| alt="" | |||||
| /> | |||||
| <span className={Styles.messageText}>{item.name}</span> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| }) | |||||
| : ''} | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div>}):''} | |||||
| </div> | |||||
| <div className={Styles.itemTitle}>研究方向/应用领域</div> | |||||
| <div className={Styles.itemBox}> | |||||
| {datasetDirectionList&&datasetDirectionList.length>0?datasetDirectionList.map(item=>{return <div > | |||||
| <div className={[Styles.messageBox, item.path===activeTag?Styles.active:null].join(' ')}onClick={(e)=>{chooseDatasetTag(e, item)}}> | |||||
| <img className={Styles.ptIcon} style={{width:'22px'}} src={`/assets/images/dataset/${item.path}.png`} alt="" /> | |||||
| <img className={Styles.hoverIcon} style={{width:'22px'}} src={`/assets/images/dataset/${item.path}-hover.png`} alt="" /> | |||||
| <span className={Styles.messageText} >{item.name}</span> | |||||
| </div> | |||||
| <div className={Styles.datasetCneterRightBox}> | |||||
| <div className={Styles.dataSource}> | |||||
| <span>数据总数:{total}个</span> | |||||
| <div> | |||||
| <Search | |||||
| placeholder="按数据名称筛选" | |||||
| allowClear | |||||
| onSearch={nameSearch} | |||||
| style={{ | |||||
| width: 300, | |||||
| }} | |||||
| /> | |||||
| <Button | |||||
| type="primary" | |||||
| className={Styles.plusButton} | |||||
| onClick={showModal} | |||||
| icon={<PlusCircleOutlined style={{ color: '#1664ff' }} />} | |||||
| > | |||||
| 新建数据集 | |||||
| </Button> | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div>}):''} | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div className={Styles.datasetCneterRightBox}> | |||||
| <div className={Styles.dataSource}> | |||||
| <span>数据总数:{total}个</span> | |||||
| <div> | |||||
| <Search | |||||
| placeholder="按数据名称筛选" | |||||
| allowClear | |||||
| onSearch={nameSearch} | |||||
| style={{ | |||||
| width: 300, | |||||
| }} | |||||
| /> | |||||
| <Button type="primary" className={Styles.plusButton} onClick={showModal} icon = {<PlusCircleOutlined style={{color:'#1664ff'}} />}> | |||||
| 新建数据集 | |||||
| </Button> | |||||
| <div className={Styles.dataContent}> | |||||
| {datasetList && datasetList.length > 0 | |||||
| ? datasetList.map((item) => { | |||||
| return ( | |||||
| <div className={Styles.dataItem} onClick={(e) => routeToIntro(e, item)}> | |||||
| <div className={Styles.itemText}>{item.name}</div> | |||||
| <div className={Styles.itemTime}> | |||||
| <span>最近更新: {moment(item.update_time).format('YYYY-MM-DD')}</span> | |||||
| </div> | |||||
| <div className={Styles.itemIcon}> | |||||
| <img | |||||
| style={{ width: '17px', marginRight: '3px' }} | |||||
| src={`/assets/images/upload-icon.png`} | |||||
| alt="" | |||||
| /> | |||||
| <span>1582</span> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| }) | |||||
| : ''} | |||||
| {/* <Select.Option value="demo">Demo</Select.Option> */} | |||||
| </div> | |||||
| <Pagination size="small" total={total} showSizeChanger showQuickJumper /> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div className={Styles.dataContent}> | |||||
| {datasetList&&datasetList.length>0?datasetList.map(item=>{return <div className={Styles.dataItem} onClick={(e)=>routeToIntro(e,item)}> | |||||
| <div className={Styles.itemText}>{item.name}</div> | |||||
| <div className={Styles.itemTime}><span>最近更新: {moment(item.update_time).format('YYYY-MM-DD')}</span></div> | |||||
| <div className={Styles.itemIcon}><img style={{width:'17px',marginRight:'3px'}} src={`/assets/images/upload-icon.png`} alt="" /><span>1582</span></div> | |||||
| </div>}):''} | |||||
| {/* <Select.Option value="demo">Demo</Select.Option> */} | |||||
| </div> | |||||
| <Pagination | |||||
| size="small" | |||||
| total={total} | |||||
| showSizeChanger | |||||
| showQuickJumper | |||||
| /> | |||||
| </div> | |||||
| </div> | |||||
| <Modal title={<div style={{display:'flex',alignItems:'center',fontWeight:500}}> | |||||
| <img style={{width:'20px',marginRight:'10px'}} src={`/assets/images/pipeline-edit-icon.png`} alt="" />{dialogTitle} | |||||
| </div>} open={isModalOpen} className={Styles.modal} okButtonProps={{ | |||||
| htmlType: 'submit', | |||||
| form: 'form', | |||||
| }} onCancel={handleCancel}> | |||||
| <Modal | |||||
| title={ | |||||
| <div style={{ display: 'flex', alignItems: 'center', fontWeight: 500 }}> | |||||
| <img | |||||
| style={{ width: '20px', marginRight: '10px' }} | |||||
| src={`/assets/images/pipeline-edit-icon.png`} | |||||
| alt="" | |||||
| /> | |||||
| {dialogTitle} | |||||
| </div> | |||||
| } | |||||
| open={isModalOpen} | |||||
| className={Styles.modal} | |||||
| okButtonProps={{ | |||||
| htmlType: 'submit', | |||||
| form: 'form', | |||||
| }} | |||||
| onCancel={handleCancel} | |||||
| > | |||||
| <Form | <Form | ||||
| name="form" | name="form" | ||||
| form={form} | form={form} | ||||
| @@ -249,94 +311,112 @@ const PublicData= React.FC = () => { | |||||
| <Form.Item | <Form.Item | ||||
| label="数据名称" | label="数据名称" | ||||
| name="name" | name="name" | ||||
| rules={[ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ]} | |||||
| rules={ | |||||
| [ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ] | |||||
| } | |||||
| > | > | ||||
| <Input placeholder="请输入数据名称"/> | |||||
| <Input placeholder="请输入数据名称" /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | <Form.Item | ||||
| label="数据集版本" | label="数据集版本" | ||||
| name="version" | name="version" | ||||
| rules={[ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ]} | |||||
| rules={ | |||||
| [ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ] | |||||
| } | |||||
| > | > | ||||
| <Input placeholder="请输入数据集版本"/> | |||||
| <Input placeholder="请输入数据集版本" /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | <Form.Item | ||||
| label="数据集分类" | label="数据集分类" | ||||
| name="data_type" | name="data_type" | ||||
| rules={[ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ]} | |||||
| rules={ | |||||
| [ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ] | |||||
| } | |||||
| > | > | ||||
| <Select | <Select | ||||
| allowClear | |||||
| placeholder="请选择数据集分类" | |||||
| options={datasetTypeList.map(item=>{return {value:item.id,label:item.name}})} | |||||
| /> | |||||
| </Form.Item> | |||||
| <Form.Item | |||||
| allowClear | |||||
| placeholder="请选择数据集分类" | |||||
| options={datasetTypeList.map((item) => { | |||||
| return { value: item.id, label: item.name }; | |||||
| })} | |||||
| /> | |||||
| </Form.Item> | |||||
| <Form.Item | |||||
| label="研究方向/应用领域" | label="研究方向/应用领域" | ||||
| name="data_tag" | name="data_tag" | ||||
| rules={[ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ]} | |||||
| rules={ | |||||
| [ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ] | |||||
| } | |||||
| > | > | ||||
| <Select | <Select | ||||
| allowClear | |||||
| placeholder="请选择研究方向/应用领域" | |||||
| options={datasetDirectionList.map(item=>{return {value:item.id,label:item.name}})} | |||||
| /> | |||||
| allowClear | |||||
| placeholder="请选择研究方向/应用领域" | |||||
| options={datasetDirectionList.map((item) => { | |||||
| return { value: item.id, label: item.name }; | |||||
| })} | |||||
| /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | |||||
| label="集群版本" | |||||
| name="available_cluster" | |||||
| > | |||||
| <Select | |||||
| allowClear | |||||
| placeholder="请选择集群版本" | |||||
| options={clusterOptions} | |||||
| /> | |||||
| <Form.Item label="集群版本" name="available_cluster"> | |||||
| <Select allowClear placeholder="请选择集群版本" options={clusterOptions} /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | <Form.Item | ||||
| label="数据简介" | label="数据简介" | ||||
| name="description" | name="description" | ||||
| rules={[ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ]} | |||||
| rules={ | |||||
| [ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ] | |||||
| } | |||||
| > | > | ||||
| <Input placeholder="请输入数据简介"/> | |||||
| <Input placeholder="请输入数据简介" /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item label="选择流水线" name="range"> | <Form.Item label="选择流水线" name="range"> | ||||
| <Radio.Group> | |||||
| <Radio value="0">仅自己可见</Radio> | |||||
| <Radio value="1">工作空间可见</Radio> | |||||
| </Radio.Group> | |||||
| </Form.Item> | |||||
| <Form.Item label="数据文件" name="dataset_version_vos"> | |||||
| <Upload {...props}> | |||||
| <Button style={{fontSize:'14px',border:'1px solid',borderColor:'#1664ff',background:'#fff'}} icon={<UploadOutlined style={{color:'#1664ff',fontSize:'14px'}} />}>上传文件</Button> | |||||
| </Upload> | |||||
| </Form.Item> | |||||
| <Radio.Group> | |||||
| <Radio value="0">仅自己可见</Radio> | |||||
| <Radio value="1">工作空间可见</Radio> | |||||
| </Radio.Group> | |||||
| </Form.Item> | |||||
| <Form.Item label="数据文件" name="dataset_version_vos"> | |||||
| <Upload {...props}> | |||||
| <Button | |||||
| style={{ | |||||
| fontSize: '14px', | |||||
| border: '1px solid', | |||||
| borderColor: '#1664ff', | |||||
| background: '#fff', | |||||
| }} | |||||
| icon={<UploadOutlined style={{ color: '#1664ff', fontSize: '14px' }} />} | |||||
| > | |||||
| 上传文件 | |||||
| </Button> | |||||
| </Upload> | |||||
| </Form.Item> | |||||
| </Form> | </Form> | ||||
| </Modal> | </Modal> | ||||
| </>) | |||||
| }; | |||||
| export default PublicData; | |||||
| </> | |||||
| ); | |||||
| }); | |||||
| export default PublicData; | |||||
| @@ -1,195 +1,244 @@ | |||||
| import React ,{useEffect,useState}from 'react'; | |||||
| import Styles from './index.less' | |||||
| import { Input, Space ,Button,Tabs,Pagination,Modal, Form,message, Radio,} from 'antd'; | |||||
| import { PlusOutlined,PlusCircleOutlined, DeleteOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined ,CopyOutlined} from '@ant-design/icons'; | |||||
| import {getDatasetList,getAssetIcon} from '@/services/dataset/index.js' | |||||
| const { Search } = Input; | |||||
| import { useNavigate} from 'react-router-dom'; | |||||
| import { getAssetIcon, getDatasetList } from '@/services/dataset/index.js'; | |||||
| import { Form, Input, Pagination } from 'antd'; | |||||
| import moment from 'moment'; | import moment from 'moment'; | ||||
| const leftdataList=[1,2,3] | |||||
| import React, { useEffect, useState } from 'react'; | |||||
| import { useNavigate } from 'react-router-dom'; | |||||
| import Styles from './index.less'; | |||||
| const { Search } = Input; | |||||
| const leftdataList = [1, 2, 3]; | |||||
| const PublicData= React.FC = () => { | |||||
| const [queryFlow,setQueryFlow]=useState({ | |||||
| page:0, | |||||
| size:10, | |||||
| name:null, | |||||
| available_range:1 | |||||
| const PublicData = (React.FC = () => { | |||||
| const [queryFlow, setQueryFlow] = useState({ | |||||
| page: 0, | |||||
| size: 10, | |||||
| name: null, | |||||
| available_range: 1, | |||||
| }); | }); | ||||
| const [iconParams,setIconParams]=useState({ | |||||
| name:null, | |||||
| page:0, | |||||
| size:10000 | |||||
| }) | |||||
| const navgite=useNavigate(); | |||||
| const [datasetTypeList,setDatasetTypeList]=useState([]) | |||||
| const [datasetDirectionList,setDatasetDirectionList]=useState([]) | |||||
| const [activeType,setActiveType]=useState(null) | |||||
| const [activeTag,setActiveTag]=useState(null) | |||||
| const [isModalOpen,setIsModalOpen]=useState(false) | |||||
| const [datasetList,setDatasetList]=useState([]); | |||||
| const [total,setTotal]=useState(0); | |||||
| const [iconParams, setIconParams] = useState({ | |||||
| name: null, | |||||
| page: 0, | |||||
| size: 10000, | |||||
| }); | |||||
| const navgite = useNavigate(); | |||||
| const [datasetTypeList, setDatasetTypeList] = useState([]); | |||||
| const [datasetDirectionList, setDatasetDirectionList] = useState([]); | |||||
| const [activeType, setActiveType] = useState(null); | |||||
| const [activeTag, setActiveTag] = useState(null); | |||||
| const [isModalOpen, setIsModalOpen] = useState(false); | |||||
| const [datasetList, setDatasetList] = useState([]); | |||||
| const [total, setTotal] = useState(0); | |||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const [dialogTitle, setDialogTitle] = useState('新建数据'); | const [dialogTitle, setDialogTitle] = useState('新建数据'); | ||||
| const getDatasetlist=(queryFlow)=>{ | |||||
| getDatasetList(queryFlow).then(ret=>{ | |||||
| const getDatasetlist = (queryFlow) => { | |||||
| getDatasetList(queryFlow).then((ret) => { | |||||
| console.log(ret); | console.log(ret); | ||||
| if(ret.code==200){ | |||||
| setDatasetList(ret.data.content) | |||||
| setTotal(ret.data.totalElements) | |||||
| if (ret.code == 200) { | |||||
| setDatasetList(ret.data.content); | |||||
| setTotal(ret.data.totalElements); | |||||
| } | } | ||||
| }) | |||||
| } | |||||
| const onSearch=(values)=>{ | |||||
| }); | |||||
| }; | |||||
| const onSearch = (values) => { | |||||
| console.log(values); | console.log(values); | ||||
| getAssetIconList({...iconParams,name:values}) | |||||
| } | |||||
| const getAssetIconList=(params)=>{ | |||||
| getAssetIcon(params).then(ret=>{ | |||||
| getAssetIconList({ ...iconParams, name: values }); | |||||
| }; | |||||
| const getAssetIconList = (params) => { | |||||
| getAssetIcon(params).then((ret) => { | |||||
| console.log(ret); | console.log(ret); | ||||
| if(ret.code==200&&ret.data.content&&ret.data.content.length>0){ | |||||
| setDatasetTypeList(ret.data.content.filter(item=>item.category_id==1)) | |||||
| setDatasetDirectionList(ret.data.content.filter(item=>item.category_id==2)) | |||||
| } | |||||
| else{ | |||||
| setDatasetTypeList([]) | |||||
| setDatasetDirectionList([]) | |||||
| if (ret.code == 200 && ret.data.content && ret.data.content.length > 0) { | |||||
| setDatasetTypeList(ret.data.content.filter((item) => item.category_id == 1)); | |||||
| setDatasetDirectionList(ret.data.content.filter((item) => item.category_id == 2)); | |||||
| } else { | |||||
| setDatasetTypeList([]); | |||||
| setDatasetDirectionList([]); | |||||
| } | } | ||||
| }) | |||||
| } | |||||
| const nameSearch=(values)=>{ | |||||
| }); | |||||
| }; | |||||
| const nameSearch = (values) => { | |||||
| console.log(values); | console.log(values); | ||||
| getDatasetlist({...queryFlow,name:values}) | |||||
| } | |||||
| getDatasetlist({ ...queryFlow, name: values }); | |||||
| }; | |||||
| const showModal = () => { | const showModal = () => { | ||||
| form.resetFields() | |||||
| setDialogTitle('新建数据集') | |||||
| form.resetFields(); | |||||
| setDialogTitle('新建数据集'); | |||||
| setIsModalOpen(true); | setIsModalOpen(true); | ||||
| }; | }; | ||||
| const handleOk = () => { | const handleOk = () => { | ||||
| console.log(1111); | |||||
| console.log(1111); | |||||
| setIsModalOpen(false); | setIsModalOpen(false); | ||||
| }; | }; | ||||
| const handleCancel = () => { | const handleCancel = () => { | ||||
| setIsModalOpen(false); | setIsModalOpen(false); | ||||
| }; | }; | ||||
| const chooseDatasetType=(val,item)=>{ | |||||
| console.log(val,item); | |||||
| if(item.path==queryFlow.data_type){ | |||||
| setActiveType('') | |||||
| setQueryFlow({...queryFlow,data_type:null}) | |||||
| getDatasetlist({...queryFlow,data_type:null}) | |||||
| } | |||||
| else{ | |||||
| setActiveType(item.path) | |||||
| setQueryFlow({...queryFlow,data_type:item.path}) | |||||
| getDatasetlist({...queryFlow,data_type:item.path}) | |||||
| const chooseDatasetType = (val, item) => { | |||||
| console.log(val, item); | |||||
| if (item.path == queryFlow.data_type) { | |||||
| setActiveType(''); | |||||
| setQueryFlow({ ...queryFlow, data_type: null }); | |||||
| getDatasetlist({ ...queryFlow, data_type: null }); | |||||
| } else { | |||||
| setActiveType(item.path); | |||||
| setQueryFlow({ ...queryFlow, data_type: item.path }); | |||||
| getDatasetlist({ ...queryFlow, data_type: item.path }); | |||||
| } | } | ||||
| // setQueryFlow({...queryFlow,data_type:item.path},()=>{ | // setQueryFlow({...queryFlow,data_type:item.path},()=>{ | ||||
| // getDatasetlist() | // getDatasetlist() | ||||
| // }) | // }) | ||||
| }; | }; | ||||
| const chooseDatasetTag=(val,item)=>{ | |||||
| console.log(val,item); | |||||
| if(item.path==queryFlow.data_tag){ | |||||
| setActiveTag('') | |||||
| setQueryFlow({...queryFlow,data_tag:null}) | |||||
| getDatasetlist({...queryFlow,data_tag:null}) | |||||
| } | |||||
| else{ | |||||
| setActiveTag(item.path) | |||||
| setQueryFlow({...queryFlow,data_tag:item.path}) | |||||
| getDatasetlist({...queryFlow,data_tag:item.path}) | |||||
| const chooseDatasetTag = (val, item) => { | |||||
| console.log(val, item); | |||||
| if (item.path == queryFlow.data_tag) { | |||||
| setActiveTag(''); | |||||
| setQueryFlow({ ...queryFlow, data_tag: null }); | |||||
| getDatasetlist({ ...queryFlow, data_tag: null }); | |||||
| } else { | |||||
| setActiveTag(item.path); | |||||
| setQueryFlow({ ...queryFlow, data_tag: item.path }); | |||||
| getDatasetlist({ ...queryFlow, data_tag: item.path }); | |||||
| } | } | ||||
| // setQueryFlow({...queryFlow,data_type:item.path},()=>{ | // setQueryFlow({...queryFlow,data_type:item.path},()=>{ | ||||
| // getDatasetlist() | // getDatasetlist() | ||||
| // }) | // }) | ||||
| }; | }; | ||||
| const routeToIntro=(e,record)=>{ | |||||
| e.stopPropagation() | |||||
| console.log(record); | |||||
| navgite({pathname:`/dataset/datasetIntro/${record.id}` }); | |||||
| } | |||||
| const routeToIntro = (e, record) => { | |||||
| e.stopPropagation(); | |||||
| console.log(record); | |||||
| navgite({ pathname: `/dataset/datasetIntro/${record.id}` }); | |||||
| }; | |||||
| const onFinishFailed = (errorInfo) => { | const onFinishFailed = (errorInfo) => { | ||||
| console.log('Failed:', errorInfo); | console.log('Failed:', errorInfo); | ||||
| }; | }; | ||||
| useEffect(()=>{ | |||||
| getAssetIconList(iconParams) | |||||
| getDatasetlist(queryFlow) | |||||
| return ()=>{ | |||||
| } | |||||
| },[]) | |||||
| return (<> | |||||
| <div className={Styles.datasetCneterBox}> | |||||
| <div className={Styles.datasetCneterLeftBox}> | |||||
| <div className={Styles.leftContentBox}> | |||||
| <Search | |||||
| placeholder="搜索" | |||||
| allowClear | |||||
| onSearch={onSearch} | |||||
| style={{ | |||||
| width: 300, | |||||
| marginBottom:'15px', | |||||
| }} | |||||
| /> | |||||
| <div className={Styles.itemTitle}>分类</div> | |||||
| <div className={Styles.itemBox}> | |||||
| {datasetTypeList&&datasetTypeList.length>0?datasetTypeList.map(item=>{return <div > | |||||
| <div className={[Styles.messageBox, item.path===activeType?Styles.active:null].join(' ')} onClick={(e)=>{chooseDatasetType(e, item)}}> | |||||
| <img className={Styles.ptIcon} style={{width:'22px'}} src={`/assets/images/dataset/${item.path}.png`} alt="" /> | |||||
| <img className={Styles.hoverIcon} style={{width:'22px'}} src={`/assets/images/dataset/${item.path}-hover.png`} alt="" /> | |||||
| <span className={Styles.messageText} >{item.name}</span> | |||||
| useEffect(() => { | |||||
| getAssetIconList(iconParams); | |||||
| getDatasetlist(queryFlow); | |||||
| return () => {}; | |||||
| }, []); | |||||
| return ( | |||||
| <> | |||||
| <div className={Styles.datasetCneterBox}> | |||||
| <div className={Styles.datasetCneterLeftBox}> | |||||
| <div className={Styles.leftContentBox}> | |||||
| <Search | |||||
| placeholder="搜索" | |||||
| allowClear | |||||
| onSearch={onSearch} | |||||
| style={{ | |||||
| width: 300, | |||||
| marginBottom: '15px', | |||||
| }} | |||||
| /> | |||||
| <div className={Styles.itemTitle}>分类</div> | |||||
| <div className={Styles.itemBox}> | |||||
| {datasetTypeList && datasetTypeList.length > 0 | |||||
| ? datasetTypeList.map((item) => { | |||||
| return ( | |||||
| <div> | |||||
| <div | |||||
| className={[ | |||||
| Styles.messageBox, | |||||
| item.path === activeType ? Styles.active : null, | |||||
| ].join(' ')} | |||||
| onClick={(e) => { | |||||
| chooseDatasetType(e, item); | |||||
| }} | |||||
| > | |||||
| <img | |||||
| className={Styles.ptIcon} | |||||
| style={{ width: '22px' }} | |||||
| src={`/assets/images/dataset/${item.path}.png`} | |||||
| alt="" | |||||
| /> | |||||
| <img | |||||
| className={Styles.hoverIcon} | |||||
| style={{ width: '22px' }} | |||||
| src={`/assets/images/dataset/${item.path}-hover.png`} | |||||
| alt="" | |||||
| /> | |||||
| <span className={Styles.messageText}>{item.name}</span> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| }) | |||||
| : ''} | |||||
| </div> | |||||
| <div className={Styles.itemTitle}>研究方向/应用领域</div> | |||||
| <div className={Styles.itemBox}> | |||||
| {datasetDirectionList && datasetDirectionList.length > 0 | |||||
| ? datasetDirectionList.map((item) => { | |||||
| return ( | |||||
| <div> | |||||
| <div | |||||
| className={[ | |||||
| Styles.messageBox, | |||||
| item.path === activeTag ? Styles.active : null, | |||||
| ].join(' ')} | |||||
| onClick={(e) => { | |||||
| chooseDatasetTag(e, item); | |||||
| }} | |||||
| > | |||||
| <img | |||||
| className={Styles.ptIcon} | |||||
| style={{ width: '22px' }} | |||||
| src={`/assets/images/dataset/${item.path}.png`} | |||||
| alt="" | |||||
| /> | |||||
| <img | |||||
| className={Styles.hoverIcon} | |||||
| style={{ width: '22px' }} | |||||
| src={`/assets/images/dataset/${item.path}-hover.png`} | |||||
| alt="" | |||||
| /> | |||||
| <span className={Styles.messageText}>{item.name}</span> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| }) | |||||
| : ''} | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div>}):''} | |||||
| </div> | |||||
| <div className={Styles.itemTitle}>研究方向/应用领域</div> | |||||
| <div className={Styles.itemBox}> | |||||
| {datasetDirectionList&&datasetDirectionList.length>0?datasetDirectionList.map(item=>{return <div > | |||||
| <div className={[Styles.messageBox, item.path===activeTag?Styles.active:null].join(' ')} onClick={(e)=>{chooseDatasetTag(e, item)}}> | |||||
| <img className={Styles.ptIcon} style={{width:'22px'}} src={`/assets/images/dataset/${item.path}.png`} alt="" /> | |||||
| <img className={Styles.hoverIcon} style={{width:'22px'}} src={`/assets/images/dataset/${item.path}-hover.png`} alt="" /> | |||||
| <span className={Styles.messageText} >{item.name}</span> | |||||
| </div> | |||||
| <div className={Styles.datasetCneterRightBox}> | |||||
| <div className={Styles.dataSource}> | |||||
| <span>数据总数:{total}个</span> | |||||
| <div> | |||||
| <Search | |||||
| placeholder="按数据名称筛选" | |||||
| allowClear | |||||
| onSearch={nameSearch} | |||||
| style={{ | |||||
| width: 300, | |||||
| }} | |||||
| /> | |||||
| </div> | |||||
| </div> | </div> | ||||
| </div>}):''} | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div className={Styles.datasetCneterRightBox}> | |||||
| <div className={Styles.dataSource}> | |||||
| <span>数据总数:{total}个</span> | |||||
| <div> | |||||
| <Search | |||||
| placeholder="按数据名称筛选" | |||||
| allowClear | |||||
| onSearch={nameSearch} | |||||
| style={{ | |||||
| width: 300, | |||||
| }} | |||||
| /> | |||||
| <div className={Styles.dataContent}> | |||||
| {datasetList && datasetList.length > 0 | |||||
| ? datasetList.map((item) => { | |||||
| return ( | |||||
| <div className={Styles.dataItem} onClick={(e) => routeToIntro(e, item)}> | |||||
| <div className={Styles.itemText}>{item.name}</div> | |||||
| <div className={Styles.itemTime}> | |||||
| <span>最近更新: {moment(item.update_time).format('YYYY-MM-DD')}</span> | |||||
| </div> | |||||
| <div className={Styles.itemIcon}> | |||||
| <img | |||||
| style={{ width: '17px', marginRight: '3px' }} | |||||
| src={`/assets/images/upload-icon.png`} | |||||
| alt="" | |||||
| /> | |||||
| <span>1582</span> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| }) | |||||
| : ''} | |||||
| {/* <Select.Option value="demo">Demo</Select.Option> */} | |||||
| </div> | |||||
| <Pagination size="small" total={total} showSizeChanger showQuickJumper /> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div className={Styles.dataContent}> | |||||
| {datasetList&&datasetList.length>0?datasetList.map(item=>{return <div className={Styles.dataItem} onClick={(e)=>routeToIntro(e,item)}> | |||||
| <div className={Styles.itemText}>{item.name}</div> | |||||
| <div className={Styles.itemTime}><span>最近更新: {moment(item.update_time).format('YYYY-MM-DD')}</span></div> | |||||
| <div className={Styles.itemIcon}><img style={{width:'17px',marginRight:'3px'}} src={`/assets/images/upload-icon.png`} alt="" /><span>1582</span></div> | |||||
| </div>}):''} | |||||
| {/* <Select.Option value="demo">Demo</Select.Option> */} | |||||
| </div> | |||||
| <Pagination | |||||
| size="small" | |||||
| total={total} | |||||
| showSizeChanger | |||||
| showQuickJumper | |||||
| /> | |||||
| </div> | |||||
| </div> | |||||
| </>) | |||||
| }; | |||||
| export default PublicData; | |||||
| </> | |||||
| ); | |||||
| }); | |||||
| export default PublicData; | |||||
| @@ -1,8 +1,9 @@ | |||||
| import LogGroup from './logGroup'; | |||||
| import { ExperimentStatus } from '../types'; | |||||
| import LogGroup, { type LogGroupProps } from './logGroup'; | |||||
| type LogListProps = { | type LogListProps = { | ||||
| list: any[]; | |||||
| status: string; | |||||
| list: Omit<LogGroupProps, 'status'>[]; | |||||
| status: ExperimentStatus; | |||||
| }; | }; | ||||
| function LogList({ list = [], status }: LogListProps) { | function LogList({ list = [], status }: LogListProps) { | ||||
| @@ -1,61 +1,61 @@ | |||||
| #graph { | #graph { | ||||
| height: 100%; | |||||
| width: 100%; | |||||
| position: relative; | |||||
| } | |||||
| .editPipelinePropsContent{ | |||||
| position: relative; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| } | |||||
| .editPipelinePropsContent { | |||||
| display: flex; | display: flex; | ||||
| align-items: center; | align-items: center; | ||||
| width: 100%; | width: 100%; | ||||
| height:43px; | |||||
| background:#f8fbff; | |||||
| color:#1d1d20; | |||||
| font-size:15px; | |||||
| font-family: 'Alibaba'; | |||||
| padding: 0 20px; | |||||
| height: 43px; | |||||
| margin-bottom: 10px; | margin-bottom: 10px; | ||||
| padding: 0 20px; | |||||
| color: #1d1d20; | |||||
| font-size: 15px; | |||||
| font-family: 'Alibaba'; | |||||
| background: #f8fbff; | |||||
| } | } | ||||
| .centerContainer{ | |||||
| flex: 1; | |||||
| .centerContainer { | |||||
| display: flex; | display: flex; | ||||
| flex: 1; | |||||
| flex-direction: column; | flex-direction: column; | ||||
| } | } | ||||
| .buttonList{ | |||||
| .buttonList { | |||||
| display: flex; | display: flex; | ||||
| align-items: center; | align-items: center; | ||||
| padding: 0 30px; | |||||
| width: 100%; | width: 100%; | ||||
| height:45px; | |||||
| background:#ffffff; | |||||
| box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09); | |||||
| } | |||||
| .detailBox{ | |||||
| color:#1d1d20; | |||||
| font-size:15px; | |||||
| margin-bottom: 15px; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| } | |||||
| .allMessageItem{ | |||||
| height: 45px; | |||||
| padding: 0 30px; | |||||
| background: #ffffff; | |||||
| box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09); | |||||
| } | |||||
| .detailBox { | |||||
| display: flex; | display: flex; | ||||
| align-items: center; | align-items: center; | ||||
| color:rgba(29, 29, 32, 0.8); | |||||
| font-size:15px; | |||||
| margin-right: 30px; | |||||
| margin-bottom: 15px; | |||||
| color: #1d1d20; | |||||
| font-size: 15px; | |||||
| } | } | ||||
| .resultTop{ | |||||
| border-bottom: 1px solid #eee; | |||||
| .allMessageItem { | |||||
| display: flex; | display: flex; | ||||
| justify-content: space-between; | |||||
| align-items: center; | align-items: center; | ||||
| padding: 10px 0; | |||||
| margin-right: 30px; | |||||
| color: rgba(29, 29, 32, 0.8); | |||||
| font-size: 15px; | |||||
| } | } | ||||
| .resultContent{ | |||||
| width: 100%; | |||||
| .resultTop { | |||||
| display: flex; | display: flex; | ||||
| align-items: center; | |||||
| justify-content: space-between; | justify-content: space-between; | ||||
| padding: 10px 0; | |||||
| border-bottom: 1px solid #eee; | |||||
| } | |||||
| .resultContent { | |||||
| display: flex; | |||||
| align-items: center; | align-items: center; | ||||
| padding: 0 20px 0 0; | |||||
| justify-content: space-between; | |||||
| width: 100%; | |||||
| margin-bottom: 10px; | margin-bottom: 10px; | ||||
| } | |||||
| padding: 0 20px 0 0; | |||||
| } | |||||
| @@ -3,34 +3,35 @@ import { getExperimentPodsLog } from '@/services/experiment/index.js'; | |||||
| import { DoubleRightOutlined, DownOutlined, UpOutlined } from '@ant-design/icons'; | import { DoubleRightOutlined, DownOutlined, UpOutlined } from '@ant-design/icons'; | ||||
| import { Button } from 'antd'; | import { Button } from 'antd'; | ||||
| import { useEffect, useState } from 'react'; | import { useEffect, useState } from 'react'; | ||||
| import { ExperimentStatus } from '../types'; | |||||
| import styles from './logGroup.less'; | import styles from './logGroup.less'; | ||||
| type LogGroupProps = { | |||||
| log_type?: string; | |||||
| pod_name?: string; | |||||
| log_content?: string; | |||||
| start_time?: string; | |||||
| status: string; | |||||
| export type LogGroupProps = { | |||||
| log_type: 'normal' | 'resource'; // 日志类型 | |||||
| pod_name?: string; // 分布式名称 | |||||
| log_content?: string; // 日志内容 | |||||
| start_time?: string; // 日志开始时间 | |||||
| status: ExperimentStatus; // 实验状态 | |||||
| }; | }; | ||||
| type Log = { | type Log = { | ||||
| start_time: string; | |||||
| log_content: string; | |||||
| start_time: string; // 日志开始时间 | |||||
| log_content: string; // 日志内容 | |||||
| }; | }; | ||||
| function LogGroup({ | function LogGroup({ | ||||
| log_type = '', | |||||
| log_type = 'normal', | |||||
| pod_name = '', | pod_name = '', | ||||
| log_content = '', | log_content = '', | ||||
| start_time = '', | start_time = '', | ||||
| status = '', | |||||
| status = ExperimentStatus.Pending, | |||||
| }: LogGroupProps) { | }: LogGroupProps) { | ||||
| const [collapse, setCollapse] = useState(true); | const [collapse, setCollapse] = useState(true); | ||||
| const [logList, setLogList, logListRef] = useStateRef<Log[]>([]); | const [logList, setLogList, logListRef] = useStateRef<Log[]>([]); | ||||
| const [completed, setCompleted] = useState(false); | const [completed, setCompleted] = useState(false); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (status === 'Running') { | |||||
| if (status === ExperimentStatus.Running) { | |||||
| const timerId = setInterval(() => { | const timerId = setInterval(() => { | ||||
| requestExperimentPodsLog(); | requestExperimentPodsLog(); | ||||
| }, 5000); | }, 5000); | ||||
| @@ -160,7 +160,12 @@ const Props = forwardRef(({ onParentChange }, ref) => { | |||||
| Object.keys(stagingItem.control_strategy) && | Object.keys(stagingItem.control_strategy) && | ||||
| Object.keys(stagingItem.control_strategy).length > 0 | Object.keys(stagingItem.control_strategy).length > 0 | ||||
| ? Object.keys(stagingItem.control_strategy).map((item) => ( | ? Object.keys(stagingItem.control_strategy).map((item) => ( | ||||
| <Form.Item label={stagingItem.control_strategy[item].label} disabled name={item}> | |||||
| <Form.Item | |||||
| key={item} | |||||
| label={stagingItem.control_strategy[item].label} | |||||
| disabled | |||||
| name={item} | |||||
| > | |||||
| <Input disabled /> | <Input disabled /> | ||||
| </Form.Item> | </Form.Item> | ||||
| )) | )) | ||||
| @@ -178,6 +183,7 @@ const Props = forwardRef(({ onParentChange }, ref) => { | |||||
| Object.keys(stagingItem.in_parameters).length > 0 | Object.keys(stagingItem.in_parameters).length > 0 | ||||
| ? Object.keys(stagingItem.in_parameters).map((item) => ( | ? Object.keys(stagingItem.in_parameters).map((item) => ( | ||||
| <Form.Item | <Form.Item | ||||
| key={item} | |||||
| label={stagingItem.in_parameters[item].label + '(' + item + ')'} | label={stagingItem.in_parameters[item].label + '(' + item + ')'} | ||||
| name={item} | name={item} | ||||
| disabled | disabled | ||||
| @@ -200,6 +206,7 @@ const Props = forwardRef(({ onParentChange }, ref) => { | |||||
| Object.keys(stagingItem.out_parameters).length > 0 | Object.keys(stagingItem.out_parameters).length > 0 | ||||
| ? Object.keys(stagingItem.out_parameters).map((item) => ( | ? Object.keys(stagingItem.out_parameters).map((item) => ( | ||||
| <Form.Item | <Form.Item | ||||
| key={item} | |||||
| label={stagingItem.out_parameters[item].label + '(' + item + ')'} | label={stagingItem.out_parameters[item].label + '(' + item + ')'} | ||||
| disabled | disabled | ||||
| rules={[{ required: stagingItem.out_parameters[item].require ? true : false }]} | rules={[{ required: stagingItem.out_parameters[item].require ? true : false }]} | ||||
| @@ -227,7 +234,7 @@ const Props = forwardRef(({ onParentChange }, ref) => { | |||||
| > | > | ||||
| {resultObj && resultObj.length > 0 | {resultObj && resultObj.length > 0 | ||||
| ? resultObj.map((item) => ( | ? resultObj.map((item) => ( | ||||
| <div> | |||||
| <div key={item.name}> | |||||
| <div className={Styles.resultTop}> | <div className={Styles.resultTop}> | ||||
| <span>{item.name}</span> | <span>{item.name}</span> | ||||
| <div style={{ display: 'flex' }}> | <div style={{ display: 'flex' }}> | ||||
| @@ -249,7 +256,7 @@ const Props = forwardRef(({ onParentChange }, ref) => { | |||||
| </div> | </div> | ||||
| {item.value && item.value.length > 0 | {item.value && item.value.length > 0 | ||||
| ? item.value.map((ele) => ( | ? item.value.map((ele) => ( | ||||
| <div className={Styles.resultContent}> | |||||
| <div className={Styles.resultContent} key={ele.name}> | |||||
| <span>{ele.name}</span> | <span>{ele.name}</span> | ||||
| <span>{ele.size}</span> | <span>{ele.size}</span> | ||||
| </div> | </div> | ||||
| @@ -4,17 +4,6 @@ export interface StatusInfo { | |||||
| icon: string; | icon: string; | ||||
| } | } | ||||
| export enum ExperimentStatus { | |||||
| Running = 'Running', | |||||
| Succeeded = 'Succeeded', | |||||
| Pending = 'Pending', | |||||
| Failed = 'Failed', | |||||
| Error = 'Error', | |||||
| Terminated = 'Terminated', | |||||
| Skipped = 'Skipped', | |||||
| Omitted = 'Omitted', | |||||
| } | |||||
| export const experimentStatusInfo: Record<string, StatusInfo | undefined> = { | export const experimentStatusInfo: Record<string, StatusInfo | undefined> = { | ||||
| Running: { | Running: { | ||||
| label: '运行中', | label: '运行中', | ||||
| @@ -0,0 +1,10 @@ | |||||
| export enum ExperimentStatus { | |||||
| Running = 'Running', | |||||
| Succeeded = 'Succeeded', | |||||
| Pending = 'Pending', | |||||
| Failed = 'Failed', | |||||
| Error = 'Error', | |||||
| Terminated = 'Terminated', | |||||
| Skipped = 'Skipped', | |||||
| Omitted = 'Omitted', | |||||
| } | |||||
| @@ -1,27 +1,24 @@ | |||||
| import React ,{useEffect,useState}from 'react'; | |||||
| import Styles from './index.less' | |||||
| import { Input, Space ,Button,Tabs,Pagination,Modal, Form,message, Radio,} from 'antd'; | |||||
| import { PlusOutlined,PlusCircleOutlined, DeleteOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined ,CopyOutlined} from '@ant-design/icons'; | |||||
| import { Form, Input, Tabs } from 'antd'; | |||||
| import { useEffect, useState } from 'react'; | |||||
| import { useNavigate } from 'react-router-dom'; | |||||
| import Styles from './index.less'; | |||||
| import PersonalData from './personalData'; | |||||
| import PublicData from './publicData'; | |||||
| // import {getModelList} from '@/services/dataset/index.js' | // import {getModelList} from '@/services/dataset/index.js' | ||||
| const { Search } = Input; | const { Search } = Input; | ||||
| import { useNavigate} from 'react-router-dom'; | |||||
| import moment from 'moment'; | |||||
| const { TabPane } = Tabs; | const { TabPane } = Tabs; | ||||
| import PublicData from './publicData'; | |||||
| import PersonalData from './personalData' | |||||
| const leftdataList=[1,2,3] | |||||
| const leftdataList = [1, 2, 3]; | |||||
| const Dataset= React.FC = () => { | |||||
| const [queryFlow,setQueryFlow]=useState({ | |||||
| page:0, | |||||
| size:10, | |||||
| name:null | |||||
| const Dataset = () => { | |||||
| const [queryFlow, setQueryFlow] = useState({ | |||||
| page: 0, | |||||
| size: 10, | |||||
| name: null, | |||||
| }); | }); | ||||
| const navgite=useNavigate(); | |||||
| const [isModalOpen,setIsModalOpen]=useState(false) | |||||
| const [datasetList,setDatasetList]=useState([]); | |||||
| const [total,setTotal]=useState(0); | |||||
| const navgite = useNavigate(); | |||||
| const [isModalOpen, setIsModalOpen] = useState(false); | |||||
| const [datasetList, setDatasetList] = useState([]); | |||||
| const [total, setTotal] = useState(0); | |||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const [dialogTitle, setDialogTitle] = useState('新建数据'); | const [dialogTitle, setDialogTitle] = useState('新建数据'); | ||||
| // const getModelLists=()=>{ | // const getModelLists=()=>{ | ||||
| @@ -35,49 +32,42 @@ const Dataset= React.FC = () => { | |||||
| // } | // } | ||||
| const showModal = () => { | const showModal = () => { | ||||
| form.resetFields() | |||||
| setDialogTitle('新建数据集') | |||||
| form.resetFields(); | |||||
| setDialogTitle('新建数据集'); | |||||
| setIsModalOpen(true); | setIsModalOpen(true); | ||||
| }; | }; | ||||
| const handleOk = () => { | const handleOk = () => { | ||||
| console.log(1111); | |||||
| console.log(1111); | |||||
| setIsModalOpen(false); | setIsModalOpen(false); | ||||
| }; | }; | ||||
| const handleCancel = () => { | const handleCancel = () => { | ||||
| setIsModalOpen(false); | setIsModalOpen(false); | ||||
| }; | }; | ||||
| const onFinish = (values) => { | |||||
| }; | |||||
| const routeToIntro=(e,record)=>{ | |||||
| e.stopPropagation() | |||||
| navgite({pathname:'/dataset/datasetIntro' }); | |||||
| } | |||||
| const onFinish = (values) => {}; | |||||
| const routeToIntro = (e, record) => { | |||||
| e.stopPropagation(); | |||||
| navgite({ pathname: '/dataset/datasetIntro' }); | |||||
| }; | |||||
| const onFinishFailed = (errorInfo) => { | const onFinishFailed = (errorInfo) => { | ||||
| console.log('Failed:', errorInfo); | console.log('Failed:', errorInfo); | ||||
| }; | }; | ||||
| useEffect(()=>{ | |||||
| return ()=>{ | |||||
| } | |||||
| },[]) | |||||
| return (<div className={Styles.datasetBox}> | |||||
| <div className={Styles.datasetTopBox}> | |||||
| </div> | |||||
| <div className={Styles.datasetAllBox}> | |||||
| <Tabs | |||||
| defaultActiveKey="1" | |||||
| > | |||||
| <TabPane tab="模型广场" key="1"> | |||||
| <PublicData/> | |||||
| </TabPane> | |||||
| <TabPane tab="个人模型" key="2"> | |||||
| <PersonalData/> | |||||
| </TabPane> | |||||
| </Tabs> | |||||
| </div> | |||||
| </div>) | |||||
| useEffect(() => { | |||||
| return () => {}; | |||||
| }, []); | |||||
| return ( | |||||
| <div className={Styles.datasetBox}> | |||||
| <div className={Styles.datasetTopBox}></div> | |||||
| <div className={Styles.datasetAllBox}> | |||||
| <Tabs defaultActiveKey="1"> | |||||
| <TabPane tab="模型广场" key="1"> | |||||
| <PublicData /> | |||||
| </TabPane> | |||||
| <TabPane tab="个人模型" key="2"> | |||||
| <PersonalData /> | |||||
| </TabPane> | |||||
| </Tabs> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| }; | }; | ||||
| export default Dataset; | |||||
| export default Dataset; | |||||
| @@ -1,296 +1,293 @@ | |||||
| .datasetTopBox{ | |||||
| .datasetTopBox { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| width: 100%; | |||||
| height: 49px; | |||||
| padding: 0 30px; | |||||
| padding-right: 30px; | |||||
| background-image: url(/assets/images/pipeline-back.png); | |||||
| background-size: 100% 100%; | |||||
| } | |||||
| .datasetIntroTopBox { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| justify-content: space-between; | |||||
| width: 100%; | |||||
| height: 110px; | |||||
| margin-bottom: 10px; | |||||
| padding: 25px 30px; | |||||
| background-image: url(/assets/images/dataset-back.png); | |||||
| background-size: 100% 100%; | |||||
| .smallTagBox { | |||||
| display: flex; | display: flex; | ||||
| align-items: center; | align-items: center; | ||||
| padding-right: 30px; | |||||
| width: 100%; | |||||
| height: 49px; | |||||
| background-size: 100% 100%; | |||||
| background-image: url(/assets/images/pipeline-back.png); | |||||
| padding: 0 30px; | |||||
| color: #1664ff; | |||||
| font-size: 14px; | |||||
| .tagItem { | |||||
| margin-right: 20px; | |||||
| padding: 4px 10px; | |||||
| background: rgba(22, 100, 255, 0.1); | |||||
| border-radius: 4px; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| .datasetIntroTopBox{ | |||||
| .dataListBox { | |||||
| padding: 20px 30px; | |||||
| color: #1d1d20; | |||||
| font-size: 16px; | |||||
| background: #ffffff; | |||||
| border-radius: 10px; | |||||
| box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09); | |||||
| .dataButtonList { | |||||
| display: flex; | display: flex; | ||||
| flex-direction: column; | |||||
| align-items: center; | |||||
| justify-content: space-between; | justify-content: space-between; | ||||
| width: 100%; | |||||
| height: 110px; | |||||
| background-size: 100% 100%; | |||||
| background-image: url(/assets/images/dataset-back.png); | |||||
| margin-bottom: 10px; | |||||
| padding: 25px 30px; | |||||
| .smallTagBox{ | |||||
| display: flex; | |||||
| align-items: center; | |||||
| color:#1664ff; | |||||
| font-size:14px; | |||||
| .tagItem{ | |||||
| padding: 4px 10px; | |||||
| background: rgba(22, 100, 255, 0.1); | |||||
| border-radius:4px; | |||||
| margin-right: 20px; | |||||
| } | |||||
| } | |||||
| } | |||||
| .dataListBox{ | |||||
| padding: 20px 30px; | |||||
| background:#ffffff; | |||||
| border-radius:10px; | |||||
| box-shadow:0px 2px 12px rgba(180, 182, 191, 0.09); | |||||
| color:#1d1d20; | |||||
| font-size:16px; | |||||
| .dataButtonList{ | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| height: 32px; | |||||
| margin: 24px 0 30px 0; | |||||
| color:#575757; | |||||
| font-size:16px; | |||||
| } | |||||
| height: 32px; | |||||
| margin: 24px 0 30px 0; | |||||
| color: #575757; | |||||
| font-size: 16px; | |||||
| } | |||||
| } | } | ||||
| .datasetIntroCneterBox{ | |||||
| height: 77vh; | |||||
| padding: 20px 30px; | |||||
| background:#ffffff; | |||||
| border-radius:10px; | |||||
| box-shadow:0px 2px 12px rgba(180, 182, 191, 0.09); | |||||
| .datasetIntroCneterBox { | |||||
| height: 77vh; | |||||
| padding: 20px 30px; | |||||
| background: #ffffff; | |||||
| border-radius: 10px; | |||||
| box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09); | |||||
| } | } | ||||
| .datasetIntroTitle{ | |||||
| color:#1d1d20; | |||||
| font-size:15px; | |||||
| margin: 37px 0 10px 0; | |||||
| .datasetIntroTitle { | |||||
| margin: 37px 0 10px 0; | |||||
| color: #1d1d20; | |||||
| font-size: 15px; | |||||
| } | } | ||||
| .datasetIntroText{ | |||||
| color:#575757; | |||||
| font-size:14px; | |||||
| margin-bottom: 30px; | |||||
| .datasetIntroText { | |||||
| margin-bottom: 30px; | |||||
| color: #575757; | |||||
| font-size: 14px; | |||||
| } | } | ||||
| .datasetBox{ | |||||
| background:#f9fafb; | |||||
| font-family: 'Alibaba'; | |||||
| :global{ | |||||
| .ant-tabs-top >.ant-tabs-nav{ | |||||
| margin: 0; | |||||
| } | |||||
| .ant-pagination{ | |||||
| text-align: right; | |||||
| } | |||||
| .datasetBox { | |||||
| font-family: 'Alibaba'; | |||||
| background: #f9fafb; | |||||
| :global { | |||||
| .ant-tabs-top > .ant-tabs-nav { | |||||
| margin: 0; | |||||
| } | |||||
| .ant-pagination { | |||||
| text-align: right; | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| .datasetAllBox{ | |||||
| :global{ | |||||
| .ant-tabs-nav .ant-tabs-nav-wrap{ | |||||
| margin: -48px 0 0 30px; | |||||
| } | |||||
| .datasetAllBox { | |||||
| :global { | |||||
| .ant-tabs-nav .ant-tabs-nav-wrap { | |||||
| margin: -48px 0 0 30px; | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| .plusButton{ | |||||
| margin: 0 18px 0 20px; | |||||
| background:rgba(22, 100, 255, 0.06); | |||||
| border:1px solid; | |||||
| border-color:rgba(22, 100, 255, 0.11); | |||||
| border-radius:4px; | |||||
| color:#1d1d20; | |||||
| font-size:14px; | |||||
| font-family: 'Alibaba'; | |||||
| .plusButton { | |||||
| margin: 0 18px 0 20px; | |||||
| color: #1d1d20; | |||||
| font-size: 14px; | |||||
| font-family: 'Alibaba'; | |||||
| background: rgba(22, 100, 255, 0.06); | |||||
| border: 1px solid; | |||||
| border-color: rgba(22, 100, 255, 0.11); | |||||
| border-radius: 4px; | |||||
| } | } | ||||
| .plusButton:hover{ | |||||
| background:rgba(22, 100, 255, 0.06)!important; | |||||
| border:1px solid!important; | |||||
| border-color:rgba(22, 100, 255, 0.11)!important; | |||||
| color:#1d1d20!important; | |||||
| .plusButton:hover { | |||||
| color: #1d1d20 !important; | |||||
| background: rgba(22, 100, 255, 0.06) !important; | |||||
| border: 1px solid !important; | |||||
| border-color: rgba(22, 100, 255, 0.11) !important; | |||||
| } | } | ||||
| .datasetCneterBox{ | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| height: 85vh; | |||||
| width: 100%; | |||||
| .datasetCneterLeftBox{ | |||||
| width:340px; | |||||
| height:100%; | |||||
| background:#ffffff; | |||||
| box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09); | |||||
| margin-right: 10px; | |||||
| padding-top: 15px; | |||||
| .custTab{ | |||||
| display: flex; | |||||
| border-bottom: 1px solid #e0eaff; | |||||
| height: 32px; | |||||
| .tabItem{ | |||||
| width: 52px; | |||||
| height: 100%; | |||||
| text-align: center; | |||||
| color:#808080; | |||||
| font-size:15px; | |||||
| cursor: pointer; | |||||
| } | |||||
| .datasetCneterBox { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| width: 100%; | |||||
| height: 85vh; | |||||
| .datasetCneterLeftBox { | |||||
| width: 340px; | |||||
| height: 100%; | |||||
| margin-right: 10px; | |||||
| padding-top: 15px; | |||||
| background: #ffffff; | |||||
| box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09); | |||||
| .custTab { | |||||
| display: flex; | |||||
| height: 32px; | |||||
| border-bottom: 1px solid #e0eaff; | |||||
| .tabItem { | |||||
| width: 52px; | |||||
| height: 100%; | |||||
| color: #808080; | |||||
| font-size: 15px; | |||||
| text-align: center; | |||||
| cursor: pointer; | |||||
| } | |||||
| } | |||||
| .leftContentBox { | |||||
| max-height: 80vh; | |||||
| padding: 15px 20px; | |||||
| overflow-x: hidden; | |||||
| overflow-y: auto; | |||||
| .itemTitle { | |||||
| margin-bottom: 15px; | |||||
| color: #1d1d20; | |||||
| font-size: 14px; | |||||
| } | |||||
| .itemBox { | |||||
| display: flex; | |||||
| flex-wrap: wrap; | |||||
| align-content: start; | |||||
| width: 110%; | |||||
| .messageBox { | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| width: 92px; | |||||
| height: 62px; | |||||
| margin: 0 12px 20px 0; | |||||
| padding: 11px 0px 7px 0px; | |||||
| color: #1d1d20; | |||||
| font-size: 12px; | |||||
| border: 1px solid; | |||||
| border-color: rgba(22, 100, 255, 0.05); | |||||
| border-radius: 4px; | |||||
| cursor: pointer; | |||||
| .ptIcon { | |||||
| display: block; | |||||
| } | |||||
| .hoverIcon { | |||||
| display: none; | |||||
| } | |||||
| .messageText { | |||||
| width: 65px; | |||||
| overflow: hidden; | |||||
| white-space: nowrap; | |||||
| text-align: center; | |||||
| text-overflow: ellipsis; | |||||
| transition: all 0.2s; | |||||
| } | |||||
| } | |||||
| .messageBox:hover { | |||||
| background: rgba(22, 100, 255, 0.03); | |||||
| border: 1px solid; | |||||
| border-color: #1664ff; | |||||
| .ptIcon { | |||||
| display: none; | |||||
| } | |||||
| .hoverIcon { | |||||
| display: block; | |||||
| } | |||||
| } | } | ||||
| .leftContentBox{ | |||||
| max-height: 80vh; | |||||
| overflow-y: auto; | |||||
| overflow-x: hidden; | |||||
| padding: 15px 20px; | |||||
| .itemTitle{ | |||||
| color:#1d1d20; | |||||
| font-size:14px; | |||||
| margin-bottom: 15px; | |||||
| } | |||||
| .itemBox{ | |||||
| width: 110%; | |||||
| display: flex; | |||||
| flex-wrap: wrap; | |||||
| align-content: start; | |||||
| .messageBox{ | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| cursor: pointer; | |||||
| width:92px; | |||||
| height:62px; | |||||
| border:1px solid; | |||||
| border-color:rgba(22, 100, 255, 0.05); | |||||
| border-radius:4px; | |||||
| margin: 0 12px 20px 0; | |||||
| padding: 11px 0px 7px 0px; | |||||
| color:#1d1d20; | |||||
| font-size:12px; | |||||
| .ptIcon{ | |||||
| display: block; | |||||
| } | |||||
| .hoverIcon{ | |||||
| display: none; | |||||
| } | |||||
| .messageText{ | |||||
| width: 65px; | |||||
| text-align: center; | |||||
| overflow: hidden; | |||||
| text-overflow: ellipsis; | |||||
| white-space: nowrap; | |||||
| transition: all 0.2s; | |||||
| } | |||||
| } | |||||
| .messageBox:hover{ | |||||
| background:rgba(22, 100, 255, 0.03); | |||||
| border:1px solid; | |||||
| border-color:#1664ff; | |||||
| .ptIcon{ | |||||
| display: none; | |||||
| } | |||||
| .hoverIcon{ | |||||
| display: block; | |||||
| } | |||||
| } | |||||
| .active{ | |||||
| background:rgba(22, 100, 255, 0.03)!important; | |||||
| border:1px solid!important; | |||||
| border-color:#1664ff!important; | |||||
| .ptIcon{ | |||||
| display: none!important; | |||||
| } | |||||
| .hoverIcon{ | |||||
| display: block!important; | |||||
| } | |||||
| } | |||||
| } | |||||
| .active { | |||||
| background: rgba(22, 100, 255, 0.03) !important; | |||||
| border: 1px solid !important; | |||||
| border-color: #1664ff !important; | |||||
| .ptIcon { | |||||
| display: none !important; | |||||
| } | |||||
| .hoverIcon { | |||||
| display: block !important; | |||||
| } | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| .datasetCneterRightBox{ | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| padding: 22px 30px 26px 30px; | |||||
| flex: 1; | |||||
| height:100%; | |||||
| background:#ffffff; | |||||
| box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09); | |||||
| .dataSource{ | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| align-items: center; | |||||
| height: 32px; | |||||
| margin-bottom: 30px; | |||||
| color:rgba(29, 29, 32, 0.8); | |||||
| font-size:15px; | |||||
| } | |||||
| .datasetCneterRightBox { | |||||
| display: flex; | |||||
| flex: 1; | |||||
| flex-direction: column; | |||||
| height: 100%; | |||||
| padding: 22px 30px 26px 30px; | |||||
| background: #ffffff; | |||||
| box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09); | |||||
| .dataSource { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| height: 32px; | |||||
| margin-bottom: 30px; | |||||
| color: rgba(29, 29, 32, 0.8); | |||||
| font-size: 15px; | |||||
| } | |||||
| .dataContent { | |||||
| display: flex; | |||||
| flex: 1; | |||||
| flex-wrap: wrap; | |||||
| align-content: flex-start; | |||||
| width: 100%; | |||||
| .dataItem { | |||||
| position: relative; | |||||
| width: 32%; | |||||
| height: 66px; | |||||
| margin: 0 15px 18px 0; | |||||
| background: rgba(128, 128, 128, 0.05); | |||||
| border-radius: 8px; | |||||
| box-shadow: 0px 0px 12px rgba(75, 84, 137, 0.05); | |||||
| cursor: pointer; | |||||
| .itemText { | |||||
| position: absolute; | |||||
| top: 10px; | |||||
| left: 20px; | |||||
| color: #1d1d20; | |||||
| font-size: 15px; | |||||
| } | |||||
| .itemTime { | |||||
| position: absolute; | |||||
| bottom: 10px; | |||||
| left: 20px; | |||||
| color: #808080; | |||||
| font-size: 14px; | |||||
| } | } | ||||
| .dataContent{ | |||||
| width: 100%; | |||||
| flex: 1; | |||||
| display: flex; | |||||
| flex-wrap: wrap; | |||||
| align-content: flex-start; | |||||
| .dataItem{ | |||||
| width: 32%; | |||||
| margin: 0 15px 18px 0; | |||||
| height:66px; | |||||
| position: relative; | |||||
| background:rgba(128, 128, 128, 0.05); | |||||
| border-radius:8px; | |||||
| box-shadow:0px 0px 12px rgba(75, 84, 137, 0.05); | |||||
| cursor: pointer; | |||||
| .itemText{ | |||||
| position: absolute; | |||||
| left: 20px; | |||||
| top: 10px; | |||||
| color:#1d1d20; | |||||
| font-size:15px; | |||||
| } | |||||
| .itemTime{ | |||||
| position: absolute; | |||||
| left: 20px; | |||||
| bottom: 10px; | |||||
| color:#808080; | |||||
| font-size:14px; | |||||
| } | |||||
| .itemIcon{ | |||||
| position: absolute; | |||||
| right: 20px; | |||||
| bottom: 10px; | |||||
| color:#808080; | |||||
| font-size:14px; | |||||
| } | |||||
| } | |||||
| .itemIcon { | |||||
| position: absolute; | |||||
| right: 20px; | |||||
| bottom: 10px; | |||||
| color: #808080; | |||||
| font-size: 14px; | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| } | |||||
| } | } | ||||
| .modal { | .modal { | ||||
| :global { | |||||
| .ant-modal-content { | |||||
| background:linear-gradient(180deg,#cfdfff 0%,#d4e2ff 9.77%,#ffffff 40%,#ffffff 100%); | |||||
| border-radius:21px; | |||||
| padding: 20px 67px; | |||||
| width: 825px; | |||||
| } | |||||
| .ant-modal-header{ | |||||
| background-color: transparent; | |||||
| margin: 20px 0; | |||||
| } | |||||
| .ant-input{ | |||||
| border-color:#e6e6e6; | |||||
| height: 40px; | |||||
| } | |||||
| .ant-form-item .ant-form-item-label >label{ | |||||
| color:rgba(29, 29, 32, 0.8); | |||||
| } | |||||
| .ant-modal-footer{ | |||||
| margin: 40px 0 30px 0; | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| } | |||||
| .ant-btn{ | |||||
| width:110px; | |||||
| height:40px; | |||||
| font-size:18px; | |||||
| background:rgba(22, 100, 255, 0.06); | |||||
| border-radius:10px; | |||||
| border-color: transparent; | |||||
| } | |||||
| .ant-btn-primary{ | |||||
| background:#1664ff; | |||||
| } | |||||
| :global { | |||||
| .ant-modal-content { | |||||
| width: 825px; | |||||
| padding: 20px 67px; | |||||
| background: linear-gradient(180deg, #cfdfff 0%, #d4e2ff 9.77%, #ffffff 40%, #ffffff 100%); | |||||
| border-radius: 21px; | |||||
| } | |||||
| .ant-modal-header { | |||||
| margin: 20px 0; | |||||
| background-color: transparent; | |||||
| } | |||||
| .ant-input { | |||||
| height: 40px; | |||||
| border-color: #e6e6e6; | |||||
| } | } | ||||
| } | |||||
| .ant-form-item .ant-form-item-label > label { | |||||
| color: rgba(29, 29, 32, 0.8); | |||||
| } | |||||
| .ant-modal-footer { | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| margin: 40px 0 30px 0; | |||||
| } | |||||
| .ant-btn { | |||||
| width: 110px; | |||||
| height: 40px; | |||||
| font-size: 18px; | |||||
| background: rgba(22, 100, 255, 0.06); | |||||
| border-color: transparent; | |||||
| border-radius: 10px; | |||||
| } | |||||
| .ant-btn-primary { | |||||
| background: #1664ff; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -7,7 +7,12 @@ import { | |||||
| getModelVersionsById, | getModelVersionsById, | ||||
| } from '@/services/dataset/index.js'; | } from '@/services/dataset/index.js'; | ||||
| import { downLoadZip } from '@/utils/downloadfile'; | import { downLoadZip } from '@/utils/downloadfile'; | ||||
| import { DeleteOutlined, PlusCircleOutlined, UploadOutlined } from '@ant-design/icons'; | |||||
| import { | |||||
| DeleteOutlined, | |||||
| DownloadOutlined, | |||||
| PlusCircleOutlined, | |||||
| UploadOutlined, | |||||
| } from '@ant-design/icons'; | |||||
| import { Button, Form, Input, Modal, Select, Table, Tabs, Upload, message } from 'antd'; | import { Button, Form, Input, Modal, Select, Table, Tabs, Upload, message } from 'antd'; | ||||
| import moment from 'moment'; | import moment from 'moment'; | ||||
| import { useEffect, useRef, useState } from 'react'; | import { useEffect, useRef, useState } from 'react'; | ||||
| @@ -57,15 +62,13 @@ const Dataset = () => { | |||||
| const getModelByDetail = () => { | const getModelByDetail = () => { | ||||
| getModelById(locationParams.id).then((ret) => { | getModelById(locationParams.id).then((ret) => { | ||||
| console.log(ret); | console.log(ret); | ||||
| if (ret.code == 200) { | |||||
| setDatasetDetailObj(ret.data); | |||||
| } | |||||
| setDatasetDetailObj(ret.data); | |||||
| }); | }); | ||||
| }; | }; | ||||
| const getModelVersionsList = () => { | const getModelVersionsList = () => { | ||||
| getModelVersionsById(locationParams.id).then((ret) => { | getModelVersionsById(locationParams.id).then((ret) => { | ||||
| console.log(ret); | console.log(ret); | ||||
| if (ret.code == 200 && ret.data && ret.data.length > 0) { | |||||
| if (ret.data && ret.data.length > 0) { | |||||
| setVersionList( | setVersionList( | ||||
| ret.data.map((item) => { | ret.data.map((item) => { | ||||
| return { | return { | ||||
| @@ -101,12 +104,8 @@ const Dataset = () => { | |||||
| onOk: () => { | onOk: () => { | ||||
| deleteModelVersion({ models_id: locationParams.id, version }).then((ret) => { | deleteModelVersion({ models_id: locationParams.id, version }).then((ret) => { | ||||
| if (ret.code == 200) { | |||||
| message.success('删除成功'); | |||||
| getModelVersions({ version, models_id: locationParams.id }); | |||||
| } else { | |||||
| message.error(ret.msg); | |||||
| } | |||||
| message.success('删除成功'); | |||||
| getModelVersions({ version, models_id: locationParams.id }); | |||||
| }); | }); | ||||
| }, | }, | ||||
| }); | }); | ||||
| @@ -121,9 +120,7 @@ const Dataset = () => { | |||||
| const getModelVersions = (params) => { | const getModelVersions = (params) => { | ||||
| getModelVersionIdList(params).then((ret) => { | getModelVersionIdList(params).then((ret) => { | ||||
| console.log(ret); | console.log(ret); | ||||
| if (ret.code == 200) { | |||||
| setWordList(ret.data); | |||||
| } | |||||
| setWordList(ret.data); | |||||
| }); | }); | ||||
| }; | }; | ||||
| const handleExport = async () => { | const handleExport = async () => { | ||||
| @@ -150,18 +147,16 @@ const Dataset = () => { | |||||
| console.log('Failed:', errorInfo); | console.log('Failed:', errorInfo); | ||||
| }; | }; | ||||
| const columns = [ | const columns = [ | ||||
| // { | |||||
| // title: '序号', | |||||
| // dataIndex: 'index', | |||||
| // key: 'index', | |||||
| // width: 80, | |||||
| // render(text, record, index) { | |||||
| // return ( | |||||
| // <span>{(pageOption.current.page - 1) * 10 + index + 1}</span> | |||||
| // ) | |||||
| // } | |||||
| // // render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`, | |||||
| // }, | |||||
| { | |||||
| title: '序号', | |||||
| dataIndex: 'index', | |||||
| key: 'index', | |||||
| width: 80, | |||||
| render(text, record, index) { | |||||
| return <span>{(pageOption.current.page - 1) * 10 + index + 1}</span>; | |||||
| }, | |||||
| // render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`, | |||||
| }, | |||||
| { | { | ||||
| title: '文件名称', | title: '文件名称', | ||||
| dataIndex: 'file_name', | dataIndex: 'file_name', | ||||
| @@ -184,6 +179,23 @@ const Dataset = () => { | |||||
| key: 'update_time', | key: 'update_time', | ||||
| render: (text) => <span>{moment(text).format('YYYY-MM-DD HH:mm:ss')}</span>, | render: (text) => <span>{moment(text).format('YYYY-MM-DD HH:mm:ss')}</span>, | ||||
| }, | }, | ||||
| { | |||||
| title: '操作', | |||||
| dataIndex: 'option', | |||||
| width: '100px', | |||||
| key: 'option', | |||||
| render: (_, record) => [ | |||||
| <Button | |||||
| type="link" | |||||
| size="small" | |||||
| key="download" | |||||
| icon={<DownloadOutlined />} | |||||
| onClick={(e) => downloadAlone(e, record)} | |||||
| > | |||||
| 下载 | |||||
| </Button>, | |||||
| ], | |||||
| }, | |||||
| ]; | ]; | ||||
| const pageOption = useRef({ page: 1, size: 10 }); | const pageOption = useRef({ page: 1, size: 10 }); | ||||
| @@ -256,12 +268,15 @@ const Dataset = () => { | |||||
| disabled={!version} | disabled={!version} | ||||
| style={{ margin: '0 20px 0 0' }} | style={{ margin: '0 20px 0 0' }} | ||||
| onClick={handleExport} | onClick={handleExport} | ||||
| icon={<UploadOutlined style={{ color: '#1664ff' }} />} | |||||
| icon={<DownloadOutlined style={{ color: '#1664ff' }} />} | |||||
| > | > | ||||
| 下载 | 下载 | ||||
| </Button> | </Button> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div style={{ marginBottom: '10px', fontSize: '14px' }}> | |||||
| {wordList.length > 0 ? wordList[0].description : null} | |||||
| </div> | |||||
| <Table columns={columns} dataSource={wordList} pagination={false} /> | <Table columns={columns} dataSource={wordList} pagination={false} /> | ||||
| </div> | </div> | ||||
| </TabPane> | </TabPane> | ||||
| @@ -300,21 +315,55 @@ const Dataset = () => { | |||||
| <Form.Item | <Form.Item | ||||
| label="模型名称" | label="模型名称" | ||||
| name="name" | name="name" | ||||
| rules={ | |||||
| [ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ] | |||||
| } | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请输入模型名称', | |||||
| }, | |||||
| ]} | |||||
| > | > | ||||
| <Input disabled placeholder="请输入数据集名称" /> | |||||
| <Input disabled placeholder="请输入模型名称" /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item label="模型版本" name="version"> | |||||
| <Input placeholder="请输入数据集版本" /> | |||||
| <Form.Item | |||||
| label="模型版本" | |||||
| name="version" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请输入模型版本', | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Input placeholder="请输入模型版本" maxLength={64} showCount allowClear /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item label="模型文件" name="dataset_version_vos"> | |||||
| <Form.Item | |||||
| label="版本描述" | |||||
| name="description" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请输入版本描述', | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Input.TextArea | |||||
| placeholder="请输入版本描述" | |||||
| autoSize={{ minRows: 2, maxRows: 6 }} | |||||
| maxLength={256} | |||||
| showCount | |||||
| allowClear | |||||
| /> | |||||
| </Form.Item> | |||||
| <Form.Item | |||||
| label="模型文件" | |||||
| name="dataset_version_vos" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: '请上传模型文件', | |||||
| }, | |||||
| ]} | |||||
| > | |||||
| <Upload {...props}> | <Upload {...props}> | ||||
| <Button | <Button | ||||
| style={{ | style={{ | ||||
| @@ -1,14 +1,14 @@ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { Modal, Descriptions, Button } from 'antd'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { getValueEnumLabel } from '@/utils/options'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | import { DictValueEnumObj } from '@/components/DictTag'; | ||||
| import { getValueEnumLabel } from '@/utils/options'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Button, Descriptions, Modal } from 'antd'; | |||||
| import React, { useEffect } from 'react'; | |||||
| /* * | /* * | ||||
| * | * | ||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @datetime 2023/02/07 | * @datetime 2023/02/07 | ||||
| * | |||||
| * | |||||
| * */ | * */ | ||||
| export type OperlogFormValueType = Record<string, unknown> & Partial<API.Monitor.Job>; | export type OperlogFormValueType = Record<string, unknown> & Partial<API.Monitor.Job>; | ||||
| @@ -1,20 +1,20 @@ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { DictOptionType, DictValueEnumObj } from '@/components/DictTag'; | |||||
| import { | import { | ||||
| ProForm, | ProForm, | ||||
| ProFormCaptcha, | |||||
| ProFormDigit, | ProFormDigit, | ||||
| ProFormText, | |||||
| ProFormTextArea, | |||||
| ProFormRadio, | ProFormRadio, | ||||
| ProFormSelect, | ProFormSelect, | ||||
| ProFormCaptcha, | |||||
| ProFormText, | |||||
| ProFormTextArea, | |||||
| } from '@ant-design/pro-components'; | } from '@ant-design/pro-components'; | ||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | import { Form, Modal } from 'antd'; | ||||
| import { useIntl, FormattedMessage } from '@umijs/max'; | |||||
| import { DictOptionType, DictValueEnumObj } from '@/components/DictTag'; | |||||
| import React, { useEffect } from 'react'; | |||||
| /** | /** | ||||
| * 定时任务调度 Edit Form | * 定时任务调度 Edit Form | ||||
| * | |||||
| * | |||||
| * @author whiteshader | * @author whiteshader | ||||
| * @date 2023-02-07 | * @date 2023-02-07 | ||||
| */ | */ | ||||
| @@ -83,7 +83,8 @@ const JobForm: React.FC<JobFormProps> = (props) => { | |||||
| grid={true} | grid={true} | ||||
| submitter={false} | submitter={false} | ||||
| layout="horizontal" | layout="horizontal" | ||||
| onFinish={handleFinish}> | |||||
| onFinish={handleFinish} | |||||
| > | |||||
| <ProFormDigit | <ProFormDigit | ||||
| name="jobId" | name="jobId" | ||||
| label={intl.formatMessage({ | label={intl.formatMessage({ | ||||
| @@ -143,7 +144,12 @@ const JobForm: React.FC<JobFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: <FormattedMessage id="请输入调用目标字符串!" defaultMessage="请输入调用目标字符串!" />, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="请输入调用目标字符串!" | |||||
| defaultMessage="请输入调用目标字符串!" | |||||
| /> | |||||
| ), | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -153,7 +159,7 @@ const JobForm: React.FC<JobFormProps> = (props) => { | |||||
| id: 'monitor.job.cron_expression', | id: 'monitor.job.cron_expression', | ||||
| defaultMessage: 'cron执行表达式', | defaultMessage: 'cron执行表达式', | ||||
| })} | })} | ||||
| captchaTextRender={() => "生成表达式"} | |||||
| captchaTextRender={() => '生成表达式'} | |||||
| onGetCaptcha={() => { | onGetCaptcha={() => { | ||||
| // form.setFieldValue('cronExpression', '0/20 * * * * ?'); | // form.setFieldValue('cronExpression', '0/20 * * * * ?'); | ||||
| return new Promise((resolve, reject) => { | return new Promise((resolve, reject) => { | ||||
| @@ -172,17 +178,22 @@ const JobForm: React.FC<JobFormProps> = (props) => { | |||||
| valueEnum={{ | valueEnum={{ | ||||
| 0: '立即执行', | 0: '立即执行', | ||||
| 1: '执行一次', | 1: '执行一次', | ||||
| 3: '放弃执行' | |||||
| 3: '放弃执行', | |||||
| }} | }} | ||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入计划执行错误策略!" defaultMessage="请输入计划执行错误策略!" />, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="请输入计划执行错误策略!" | |||||
| defaultMessage="请输入计划执行错误策略!" | |||||
| /> | |||||
| ), | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| fieldProps={{ | fieldProps={{ | ||||
| optionType: "button", | |||||
| buttonStyle: "solid" | |||||
| optionType: 'button', | |||||
| buttonStyle: 'solid', | |||||
| }} | }} | ||||
| /> | /> | ||||
| <ProFormRadio.Group | <ProFormRadio.Group | ||||
| @@ -200,12 +211,14 @@ const JobForm: React.FC<JobFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入是否并发执行!" defaultMessage="请输入是否并发执行!" />, | |||||
| message: ( | |||||
| <FormattedMessage id="请输入是否并发执行!" defaultMessage="请输入是否并发执行!" /> | |||||
| ), | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| fieldProps={{ | fieldProps={{ | ||||
| optionType: "button", | |||||
| buttonStyle: "solid" | |||||
| optionType: 'button', | |||||
| buttonStyle: 'solid', | |||||
| }} | }} | ||||
| /> | /> | ||||
| <ProFormRadio.Group | <ProFormRadio.Group | ||||
| @@ -1,19 +1,36 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess, history } from '@umijs/max'; | |||||
| import { Dropdown, FormInstance, Space } from 'antd'; | |||||
| import { Button, message, Modal } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined } from '@ant-design/icons'; | |||||
| import { getJobList, removeJob, addJob, updateJob, exportJob, runJob } from '@/services/monitor/job'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| import { | |||||
| addJob, | |||||
| exportJob, | |||||
| getJobList, | |||||
| removeJob, | |||||
| runJob, | |||||
| updateJob, | |||||
| } from '@/services/monitor/job'; | |||||
| import { getDictSelectOption, getDictValueEnum } from '@/services/system/dict'; | import { getDictSelectOption, getDictValueEnum } from '@/services/system/dict'; | ||||
| import UpdateForm from './edit'; | |||||
| import { | |||||
| DeleteOutlined, | |||||
| DownOutlined, | |||||
| EditOutlined, | |||||
| ExclamationCircleOutlined, | |||||
| PlusOutlined, | |||||
| } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, history, useAccess, useIntl } from '@umijs/max'; | |||||
| import { Button, Dropdown, FormInstance, Modal, Space, message } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import DetailForm from './detail'; | import DetailForm from './detail'; | ||||
| import DictTag from '@/components/DictTag'; | |||||
| import UpdateForm from './edit'; | |||||
| /** | /** | ||||
| * 定时任务调度 List Page | * 定时任务调度 List Page | ||||
| * | |||||
| * | |||||
| * @author whiteshader | * @author whiteshader | ||||
| * @date 2023-02-07 | * @date 2023-02-07 | ||||
| */ | */ | ||||
| @@ -126,7 +143,6 @@ const handleExport = async () => { | |||||
| } | } | ||||
| }; | }; | ||||
| const JobTableList: React.FC = () => { | const JobTableList: React.FC = () => { | ||||
| const formTableRef = useRef<FormInstance>(); | const formTableRef = useRef<FormInstance>(); | ||||
| @@ -184,7 +200,7 @@ const JobTableList: React.FC = () => { | |||||
| valueType: 'text', | valueType: 'text', | ||||
| valueEnum: jobGroupOptions, | valueEnum: jobGroupOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag options={jobGroupOptions} value={record.jobGroup} />); | |||||
| return <DictTag options={jobGroupOptions} value={record.jobGroup} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -203,7 +219,7 @@ const JobTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: statusOptions, | valueEnum: statusOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={statusOptions} value={record.status} />); | |||||
| return <DictTag enums={statusOptions} value={record.status} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -216,7 +232,7 @@ const JobTableList: React.FC = () => { | |||||
| type="link" | type="link" | ||||
| size="small" | size="small" | ||||
| key="edit" | key="edit" | ||||
| icon = <EditOutlined /> | |||||
| icon=<EditOutlined /> | |||||
| hidden={!access.hasPerms('monitor:job:edit')} | hidden={!access.hasPerms('monitor:job:edit')} | ||||
| onClick={() => { | onClick={() => { | ||||
| setModalVisible(true); | setModalVisible(true); | ||||
| @@ -230,7 +246,7 @@ const JobTableList: React.FC = () => { | |||||
| size="small" | size="small" | ||||
| danger | danger | ||||
| key="batchRemove" | key="batchRemove" | ||||
| icon = <DeleteOutlined /> | |||||
| icon=<DeleteOutlined /> | |||||
| hidden={!access.hasPerms('monitor:job:remove')} | hidden={!access.hasPerms('monitor:job:remove')} | ||||
| onClick={async () => { | onClick={async () => { | ||||
| Modal.confirm({ | Modal.confirm({ | ||||
| @@ -282,15 +298,13 @@ const JobTableList: React.FC = () => { | |||||
| } | } | ||||
| }, | }, | ||||
| }); | }); | ||||
| } | |||||
| else if (key === 'detail') { | |||||
| } else if (key === 'detail') { | |||||
| setDetailModalVisible(true); | setDetailModalVisible(true); | ||||
| setCurrentRow(record); | setCurrentRow(record); | ||||
| } | |||||
| else if( key === 'log') { | |||||
| } else if (key === 'log') { | |||||
| history.push(`/monitor/job-log/index/${record.jobId}`); | history.push(`/monitor/job-log/index/${record.jobId}`); | ||||
| } | } | ||||
| } | |||||
| }, | |||||
| }} | }} | ||||
| > | > | ||||
| <a className="ant-dropdown-link" onClick={(e) => e.preventDefault()}> | <a className="ant-dropdown-link" onClick={(e) => e.preventDefault()}> | ||||
| @@ -347,7 +361,7 @@ const JobTableList: React.FC = () => { | |||||
| actionRef.current?.reloadAndRest?.(); | actionRef.current?.reloadAndRest?.(); | ||||
| } | } | ||||
| }, | }, | ||||
| onCancel() { }, | |||||
| onCancel() {}, | |||||
| }); | }); | ||||
| }} | }} | ||||
| > | > | ||||
| @@ -439,7 +453,7 @@ const JobTableList: React.FC = () => { | |||||
| }} | }} | ||||
| open={modalVisible} | open={modalVisible} | ||||
| values={currentRow || {}} | values={currentRow || {}} | ||||
| jobGroupOptions={jobGroupOptions||{}} | |||||
| jobGroupOptions={jobGroupOptions || {}} | |||||
| statusOptions={statusOptions} | statusOptions={statusOptions} | ||||
| /> | /> | ||||
| <DetailForm | <DetailForm | ||||
| @@ -1,14 +1,14 @@ | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import { getValueEnumLabel } from '@/utils/options'; | import { getValueEnumLabel } from '@/utils/options'; | ||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | import { FormattedMessage, useIntl } from '@umijs/max'; | ||||
| import { Descriptions, Modal } from 'antd'; | import { Descriptions, Modal } from 'antd'; | ||||
| import React, { useEffect } from 'react'; | import React, { useEffect } from 'react'; | ||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| /* * | /* * | ||||
| * | * | ||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @datetime 2021/09/16 | * @datetime 2021/09/16 | ||||
| * | |||||
| * | |||||
| * */ | * */ | ||||
| export type JobLogFormValueType = Record<string, unknown> & Partial<API.Monitor.JobLog>; | export type JobLogFormValueType = Record<string, unknown> & Partial<API.Monitor.JobLog>; | ||||
| @@ -22,19 +22,16 @@ export type JobLogFormProps = { | |||||
| }; | }; | ||||
| const JobLogDetailForm: React.FC<JobLogFormProps> = (props) => { | const JobLogDetailForm: React.FC<JobLogFormProps> = (props) => { | ||||
| const { values, statusOptions, jobGroupOptions } = props; | const { values, statusOptions, jobGroupOptions } = props; | ||||
| useEffect(() => { | |||||
| }, []); | |||||
| useEffect(() => {}, []); | |||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const handleOk = () => { | |||||
| }; | |||||
| const handleOk = () => {}; | |||||
| const handleCancel = () => { | const handleCancel = () => { | ||||
| props.onCancel(); | props.onCancel(); | ||||
| }; | }; | ||||
| return ( | return ( | ||||
| <Modal | <Modal | ||||
| width={640} | width={640} | ||||
| @@ -1,19 +1,24 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess, useParams, history } from '@umijs/max'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| import { getJob } from '@/services/monitor/job'; | |||||
| import { exportJobLog, getJobLogList, removeJobLog } from '@/services/monitor/jobLog'; | |||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import { DeleteOutlined, ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, history, useAccess, useIntl, useParams } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | import type { FormInstance } from 'antd'; | ||||
| import { Button, message, Modal } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; | |||||
| import { getJobLogList, removeJobLog, exportJobLog } from '@/services/monitor/jobLog'; | |||||
| import { Button, Modal, message } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import DetailForm from './detail'; | import DetailForm from './detail'; | ||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import { getJob } from '@/services/monitor/job'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| /** | /** | ||||
| * 定时任务调度日志 List Page | * 定时任务调度日志 List Page | ||||
| * | |||||
| * | |||||
| * @author whiteshader | * @author whiteshader | ||||
| * @date 2023-02-07 | * @date 2023-02-07 | ||||
| */ | */ | ||||
| @@ -80,7 +85,6 @@ const handleExport = async () => { | |||||
| } | } | ||||
| }; | }; | ||||
| const JobLogTableList: React.FC = () => { | const JobLogTableList: React.FC = () => { | ||||
| const formTableRef = useRef<FormInstance>(); | const formTableRef = useRef<FormInstance>(); | ||||
| @@ -107,10 +111,10 @@ const JobLogTableList: React.FC = () => { | |||||
| const jobId = params.id || 0; | const jobId = params.id || 0; | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (jobId !== undefined && jobId !== 0) { | if (jobId !== undefined && jobId !== 0) { | ||||
| getJob(Number(jobId)).then(response => { | |||||
| getJob(Number(jobId)).then((response) => { | |||||
| setQueryParams({ | setQueryParams({ | ||||
| jobName: response.data.jobName, | jobName: response.data.jobName, | ||||
| jobGroup: response.data.jobGroup | |||||
| jobGroup: response.data.jobGroup, | |||||
| }); | }); | ||||
| }); | }); | ||||
| } | } | ||||
| @@ -140,7 +144,9 @@ const JobLogTableList: React.FC = () => { | |||||
| valueType: 'text', | valueType: 'text', | ||||
| }, | }, | ||||
| { | { | ||||
| title: <FormattedMessage id="monitor.job.log.invoke_target" defaultMessage="调用目标字符串" />, | |||||
| title: ( | |||||
| <FormattedMessage id="monitor.job.log.invoke_target" defaultMessage="调用目标字符串" /> | |||||
| ), | |||||
| dataIndex: 'invokeTarget', | dataIndex: 'invokeTarget', | ||||
| valueType: 'textarea', | valueType: 'textarea', | ||||
| }, | }, | ||||
| @@ -155,7 +161,7 @@ const JobLogTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: statusOptions, | valueEnum: statusOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={statusOptions} value={record.status} />); | |||||
| return <DictTag enums={statusOptions} value={record.status} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -253,7 +259,7 @@ const JobLogTableList: React.FC = () => { | |||||
| actionRef.current?.reloadAndRest?.(); | actionRef.current?.reloadAndRest?.(); | ||||
| } | } | ||||
| }, | }, | ||||
| onCancel() { }, | |||||
| onCancel() {}, | |||||
| }); | }); | ||||
| }} | }} | ||||
| > | > | ||||
| @@ -1,20 +1,18 @@ | |||||
| import { forceLogout, getOnlineUserList } from '@/services/monitor/online'; | |||||
| import { DeleteOutlined } from '@ant-design/icons'; | |||||
| import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useAccess, useIntl } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | import type { FormInstance } from 'antd'; | ||||
| import { Button, message, Modal } from 'antd'; | import { Button, message, Modal } from 'antd'; | ||||
| import React, { useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess } from '@umijs/max'; | |||||
| import { getOnlineUserList, forceLogout } from '@/services/monitor/online'; | |||||
| import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { DeleteOutlined } from '@ant-design/icons'; | |||||
| import React, { useEffect, useRef } from 'react'; | |||||
| /* * | /* * | ||||
| * | * | ||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @datetime 2023/02/07 | * @datetime 2023/02/07 | ||||
| * | |||||
| * | |||||
| * */ | * */ | ||||
| const handleForceLogout = async (selectedRow: API.Monitor.OnlineUserType) => { | const handleForceLogout = async (selectedRow: API.Monitor.OnlineUserType) => { | ||||
| const hide = message.loading('正在强制下线'); | const hide = message.loading('正在强制下线'); | ||||
| try { | try { | ||||
| @@ -130,32 +128,32 @@ const OnlineUserTableList: React.FC = () => { | |||||
| ]; | ]; | ||||
| return ( | return ( | ||||
| <div style={{ width: '100%', float: 'right' }}> | |||||
| <ProTable<API.Monitor.OnlineUserType> | |||||
| headerTitle={intl.formatMessage({ | |||||
| id: 'pages.searchTable.title', | |||||
| defaultMessage: '信息', | |||||
| })} | |||||
| actionRef={actionRef} | |||||
| formRef={formTableRef} | |||||
| rowKey="tokenId" | |||||
| key="logininforList" | |||||
| search={{ | |||||
| labelWidth: 120, | |||||
| }} | |||||
| request={(params) => | |||||
| getOnlineUserList({ ...params } as API.Monitor.OnlineUserListParams).then((res) => { | |||||
| const result = { | |||||
| data: res.rows, | |||||
| total: res.total, | |||||
| success: true, | |||||
| }; | |||||
| return result; | |||||
| }) | |||||
| } | |||||
| columns={columns} | |||||
| /> | |||||
| </div> | |||||
| <div style={{ width: '100%', float: 'right' }}> | |||||
| <ProTable<API.Monitor.OnlineUserType> | |||||
| headerTitle={intl.formatMessage({ | |||||
| id: 'pages.searchTable.title', | |||||
| defaultMessage: '信息', | |||||
| })} | |||||
| actionRef={actionRef} | |||||
| formRef={formTableRef} | |||||
| rowKey="tokenId" | |||||
| key="logininforList" | |||||
| search={{ | |||||
| labelWidth: 120, | |||||
| }} | |||||
| request={(params) => | |||||
| getOnlineUserList({ ...params } as API.Monitor.OnlineUserListParams).then((res) => { | |||||
| const result = { | |||||
| data: res.rows, | |||||
| total: res.total, | |||||
| success: true, | |||||
| }; | |||||
| return result; | |||||
| }) | |||||
| } | |||||
| columns={columns} | |||||
| /> | |||||
| </div> | |||||
| ); | ); | ||||
| }; | }; | ||||
| @@ -1,46 +1,46 @@ | |||||
| #graph { | #graph { | ||||
| height: 100%; | |||||
| width: 100%; | |||||
| position: relative; | |||||
| } | |||||
| .editPipelinePropsContent{ | |||||
| position: relative; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| } | |||||
| .editPipelinePropsContent { | |||||
| display: flex; | display: flex; | ||||
| align-items: center; | align-items: center; | ||||
| width: 100%; | width: 100%; | ||||
| height:43px; | |||||
| background:#f8fbff; | |||||
| height: 43px; | |||||
| margin-bottom: 10px; | margin-bottom: 10px; | ||||
| color:#1d1d20; | |||||
| font-size:15px; | |||||
| font-family: 'Alibaba'; | |||||
| padding: 0 20px; | padding: 0 20px; | ||||
| color: #1d1d20; | |||||
| font-size: 15px; | |||||
| font-family: 'Alibaba'; | |||||
| background: #f8fbff; | |||||
| } | } | ||||
| .centerContainer{ | |||||
| flex: 1; | |||||
| .centerContainer { | |||||
| display: flex; | display: flex; | ||||
| flex: 1; | |||||
| flex-direction: column; | flex-direction: column; | ||||
| } | } | ||||
| .buttonList{ | |||||
| .buttonList { | |||||
| display: flex; | display: flex; | ||||
| align-items: center; | align-items: center; | ||||
| justify-content: end; | justify-content: end; | ||||
| padding: 0 30px; | |||||
| width: 100%; | width: 100%; | ||||
| height:45px; | |||||
| background:#ffffff; | |||||
| box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09); | |||||
| height: 45px; | |||||
| padding: 0 30px; | |||||
| background: #ffffff; | |||||
| box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09); | |||||
| } | } | ||||
| .rightmenu { | .rightmenu { | ||||
| position: absolute; | position: absolute; | ||||
| top: 0px; | |||||
| left: 0px; | |||||
| width: 120px; | width: 120px; | ||||
| height: 146px; | height: 146px; | ||||
| left: 0px; | |||||
| top: 0px; | |||||
| background-color: #ffffff; | |||||
| font-size: 12px; | |||||
| color: #333333; | |||||
| overflow-y: auto; | overflow-y: auto; | ||||
| color: #333333; | |||||
| font-size: 12px; | |||||
| background-color: #ffffff; | |||||
| } | } | ||||
| .rightmenuItem { | .rightmenuItem { | ||||
| @@ -48,6 +48,6 @@ | |||||
| cursor: pointer; | cursor: pointer; | ||||
| } | } | ||||
| .rightmenuItem:hover { | .rightmenuItem:hover { | ||||
| background-color: rgba(24, 144, 255, 0.3); | |||||
| color: #ffffff; | color: #ffffff; | ||||
| } | |||||
| background-color: rgba(24, 144, 255, 0.3); | |||||
| } | |||||
| @@ -1,62 +1,74 @@ | |||||
| import React ,{ useState,useEffect,useRef }from 'react'; | |||||
| import { Collapse, Divider } from 'antd'; | |||||
| import Styles from './modelMenus.less' | |||||
| import {getComponentAll} from '@/services/pipeline/index.js' | |||||
| import { getComponentAll } from '@/services/pipeline/index.js'; | |||||
| import { Collapse } from 'antd'; | |||||
| import { useEffect, useState } from 'react'; | |||||
| import Styles from './modelMenus.less'; | |||||
| const items = [ | const items = [ | ||||
| { | |||||
| key: '1', | |||||
| label: 'This is panel header 1', | |||||
| children: [1,2,3,4,5], | |||||
| }, | |||||
| { | |||||
| key: '2', | |||||
| label: 'This is panel header 2', | |||||
| children: [1,2,3,4,5], | |||||
| }, | |||||
| { | |||||
| key: '3', | |||||
| label: 'This is panel header 3', | |||||
| children: [1,2,3,4,5], | |||||
| }, | |||||
| ]; | |||||
| const modelMenus = ({onParDragEnd}) => { | |||||
| const [modelMenusList,setModelMenusList]=useState([]) | |||||
| useEffect(()=>{ | |||||
| getComponentAll().then(ret=>{ | |||||
| console.log(ret); | |||||
| if(ret.code==200){ | |||||
| setModelMenusList(ret.data) | |||||
| } | |||||
| }) | |||||
| },[]) | |||||
| const dragEnd=(e,data)=>{ | |||||
| console.log(e,data); | |||||
| onParDragEnd({...data,x:e.clientX,y:e.clientY,label:data.component_label,img:`/assets/images/${data.icon_path}.png`}) | |||||
| } | |||||
| const { Panel } = Collapse; | |||||
| return (<div style={{width:'250px',height:'99%'}} className={Styles.collapse}> | |||||
| <Collapse | |||||
| collapsible="header" | |||||
| defaultActiveKey={['1']} | |||||
| expandIconPosition="end" | |||||
| > | |||||
| { | |||||
| key: '1', | |||||
| label: 'This is panel header 1', | |||||
| children: [1, 2, 3, 4, 5], | |||||
| }, | |||||
| { | |||||
| key: '2', | |||||
| label: 'This is panel header 2', | |||||
| children: [1, 2, 3, 4, 5], | |||||
| }, | |||||
| { | |||||
| key: '3', | |||||
| label: 'This is panel header 3', | |||||
| children: [1, 2, 3, 4, 5], | |||||
| }, | |||||
| ]; | |||||
| const modelMenus = ({ onParDragEnd }) => { | |||||
| const [modelMenusList, setModelMenusList] = useState([]); | |||||
| useEffect(() => { | |||||
| getComponentAll().then((ret) => { | |||||
| console.log(ret); | |||||
| if (ret.code == 200) { | |||||
| setModelMenusList(ret.data); | |||||
| } | |||||
| }); | |||||
| }, []); | |||||
| const dragEnd = (e, data) => { | |||||
| console.log(e, data); | |||||
| onParDragEnd({ | |||||
| ...data, | |||||
| x: e.clientX, | |||||
| y: e.clientY, | |||||
| label: data.component_label, | |||||
| img: `/assets/images/${data.icon_path}.png`, | |||||
| }); | |||||
| }; | |||||
| const { Panel } = Collapse; | |||||
| return ( | |||||
| <div style={{ width: '250px', height: '99%' }} className={Styles.collapse}> | |||||
| <Collapse collapsible="header" defaultActiveKey={['1']} expandIconPosition="end"> | |||||
| {modelMenusList && modelMenusList.length > 0 | {modelMenusList && modelMenusList.length > 0 | ||||
| ? modelMenusList.map(item => ( | |||||
| <Panel | |||||
| header={<div>{item.name}</div>} | |||||
| key={item.key} | |||||
| > | |||||
| {item.value&&item.value.length>0?item.value.map(ele=>(<div draggable="true" onDragEnd={(e)=>{dragEnd(e,ele)}} className={Styles.collapseItem}> | |||||
| <img style={{height:'16px',marginRight:'15px'}} src={`/assets/images/${ele.icon_path}.png`} alt="" /> | |||||
| {ele.component_label} | |||||
| </div>) | |||||
| ):''} | |||||
| </Panel> | |||||
| )) | |||||
| : ""} | |||||
| </Collapse> | |||||
| </div>)}; | |||||
| export default modelMenus; | |||||
| ? modelMenusList.map((item) => ( | |||||
| <Panel header={<div>{item.name}</div>} key={item.key}> | |||||
| {item.value && item.value.length > 0 | |||||
| ? item.value.map((ele) => ( | |||||
| <div | |||||
| draggable="true" | |||||
| onDragEnd={(e) => { | |||||
| dragEnd(e, ele); | |||||
| }} | |||||
| className={Styles.collapseItem} | |||||
| > | |||||
| <img | |||||
| style={{ height: '16px', marginRight: '15px' }} | |||||
| src={`/assets/images/${ele.icon_path}.png`} | |||||
| alt="" | |||||
| /> | |||||
| {ele.component_label} | |||||
| </div> | |||||
| )) | |||||
| : ''} | |||||
| </Panel> | |||||
| )) | |||||
| : ''} | |||||
| </Collapse> | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| export default modelMenus; | |||||
| @@ -1,44 +1,40 @@ | |||||
| .collapseList{ | |||||
| .collapseList { | |||||
| } | } | ||||
| .collapseItem{ | |||||
| display: flex; | |||||
| align-items: center; | |||||
| color:#575757; | |||||
| font-size:14px; | |||||
| height:40px; | |||||
| cursor: pointer; | |||||
| border-radius:4px; | |||||
| padding: 0 16px; | |||||
| .collapseItem { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| height: 40px; | |||||
| padding: 0 16px; | |||||
| color: #575757; | |||||
| font-size: 14px; | |||||
| border-radius: 4px; | |||||
| cursor: pointer; | |||||
| } | } | ||||
| .collapseItem:hover{ | |||||
| background:rgba(22, 100, 255, 0.08); | |||||
| .collapseItem:hover { | |||||
| background: rgba(22, 100, 255, 0.08); | |||||
| } | |||||
| .collapse { | |||||
| :global { | |||||
| .ant-collapse { | |||||
| background-color: #fff; | |||||
| border-color: transparent !important; | |||||
| } | |||||
| .ant-collapse > .ant-collapse-item > .ant-collapse-header { | |||||
| margin-bottom: 5px; | |||||
| background-color: #fff; | |||||
| border-color: transparent; | |||||
| } | |||||
| .ant-collapse > .ant-collapse-item { | |||||
| margin: 0 10px; | |||||
| border-color: rgba(20, 49, 179, 0.12); | |||||
| border-radius: 0px; | |||||
| } | |||||
| .ant-collapse .ant-collapse-content { | |||||
| padding-bottom: 15px; | |||||
| border-top: 1px solid transparent; | |||||
| } | |||||
| .ant-collapse .ant-collapse-content > .ant-collapse-content-box { | |||||
| padding: 0; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| .collapse{ | |||||
| :global { | |||||
| .ant-collapse{ | |||||
| border-color: transparent!important; | |||||
| background-color: #fff; | |||||
| } | |||||
| .ant-collapse>.ant-collapse-item >.ant-collapse-header{ | |||||
| background-color: #fff; | |||||
| border-color: transparent; | |||||
| margin-bottom: 5px; | |||||
| } | |||||
| .ant-collapse>.ant-collapse-item{ | |||||
| border-radius: 0px; | |||||
| border-color:rgba(20, 49, 179, 0.12); | |||||
| margin: 0 10px; | |||||
| } | |||||
| .ant-collapse .ant-collapse-content{ | |||||
| padding-bottom: 15px; | |||||
| border-top: 1px solid transparent; | |||||
| } | |||||
| .ant-collapse .ant-collapse-content>.ant-collapse-content-box{ | |||||
| padding: 0; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,75 +1,93 @@ | |||||
| import React, { useState,useImperativeHandle ,forwardRef } from 'react'; | |||||
| import { Button, Drawer,Form, Input , } from 'antd'; | |||||
| import Styles from './editPipeline.less' | |||||
| import { Drawer, Form, Input } from 'antd'; | |||||
| import { forwardRef, useImperativeHandle, useState } from 'react'; | |||||
| import Styles from './editPipeline.less'; | |||||
| const { TextArea } = Input; | const { TextArea } = Input; | ||||
| const Props = forwardRef(({onParentChange}, ref) =>{ | |||||
| const [form] = Form.useForm(); | |||||
| const [stagingItem,setStagingItem]=useState({}) | |||||
| const [open, setOpen] = useState(false); | |||||
| const afterOpenChange=()=>{ | |||||
| if(!open){ | |||||
| console.log(111,open); | |||||
| console.log(stagingItem,form.getFieldsValue()); | |||||
| for(let i in form.getFieldsValue()){ | |||||
| for(let j in stagingItem.in_parameters){ | |||||
| if(i==j){ | |||||
| console.log(j,i); | |||||
| stagingItem.in_parameters[j].value=form.getFieldsValue()[i] | |||||
| } | |||||
| const Props = forwardRef(({ onParentChange }, ref) => { | |||||
| const [form] = Form.useForm(); | |||||
| const [stagingItem, setStagingItem] = useState({}); | |||||
| const [open, setOpen] = useState(false); | |||||
| const afterOpenChange = () => { | |||||
| if (!open) { | |||||
| console.log(111, open); | |||||
| console.log(stagingItem, form.getFieldsValue()); | |||||
| for (let i in form.getFieldsValue()) { | |||||
| for (let j in stagingItem.in_parameters) { | |||||
| if (i == j) { | |||||
| console.log(j, i); | |||||
| stagingItem.in_parameters[j].value = form.getFieldsValue()[i]; | |||||
| } | } | ||||
| for(let p in stagingItem.out_parameters){ | |||||
| if(i==p){ | |||||
| stagingItem.out_parameters[p].value=form.getFieldsValue()[i] | |||||
| } | |||||
| } | |||||
| for (let p in stagingItem.out_parameters) { | |||||
| if (i == p) { | |||||
| stagingItem.out_parameters[p].value = form.getFieldsValue()[i]; | |||||
| } | } | ||||
| for(let k in stagingItem.control_strategy){ | |||||
| if(i==k){ | |||||
| stagingItem.control_strategy[k].value=form.getFieldsValue()[i] | |||||
| } | |||||
| } | |||||
| for (let k in stagingItem.control_strategy) { | |||||
| if (i == k) { | |||||
| stagingItem.control_strategy[k].value = form.getFieldsValue()[i]; | |||||
| } | } | ||||
| } | } | ||||
| // setStagingItem({...stagingItem,}) | |||||
| console.log((stagingItem.control_strategy)); | |||||
| onParentChange({...stagingItem,control_strategy:JSON.stringify(stagingItem.control_strategy),in_parameters:JSON.stringify(stagingItem.in_parameters),out_parameters:JSON.stringify(stagingItem.out_parameters),...form.getFieldsValue()}) | |||||
| // onParentChange({...stagingItem,...form.getFieldsValue()}) | |||||
| } | } | ||||
| // setStagingItem({...stagingItem,}) | |||||
| console.log(stagingItem.control_strategy); | |||||
| onParentChange({ | |||||
| ...stagingItem, | |||||
| control_strategy: JSON.stringify(stagingItem.control_strategy), | |||||
| in_parameters: JSON.stringify(stagingItem.in_parameters), | |||||
| out_parameters: JSON.stringify(stagingItem.out_parameters), | |||||
| ...form.getFieldsValue(), | |||||
| }); | |||||
| // onParentChange({...stagingItem,...form.getFieldsValue()}) | |||||
| } | } | ||||
| const onClose=()=> { | |||||
| setOpen(false); | |||||
| }; | |||||
| const onFinish = (values) => { | |||||
| console.log('Success:', values); | |||||
| }; | |||||
| const onFinishFailed = (errorInfo) => { | |||||
| console.log('Failed:', errorInfo); | |||||
| }; | |||||
| useImperativeHandle(ref, () => ({ | |||||
| showDrawer (e) { | |||||
| if(e.item&&e.item.getModel()){ | |||||
| // console.log(e.item.getModel().in_parameters); | |||||
| form.resetFields(); | |||||
| form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)}) | |||||
| setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters),control_strategy:JSON.parse(e.item.getModel().control_strategy)}) | |||||
| // form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)}) | |||||
| // setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)}) | |||||
| // setTimeout(() => { | |||||
| // console.log(stagingItem); | |||||
| // }, (500)); | |||||
| setOpen(true); | |||||
| } | |||||
| }, | |||||
| })); | |||||
| }; | |||||
| const onClose = () => { | |||||
| setOpen(false); | |||||
| }; | |||||
| const onFinish = (values) => { | |||||
| console.log('Success:', values); | |||||
| }; | |||||
| const onFinishFailed = (errorInfo) => { | |||||
| console.log('Failed:', errorInfo); | |||||
| }; | |||||
| useImperativeHandle(ref, () => ({ | |||||
| showDrawer(e) { | |||||
| if (e.item && e.item.getModel()) { | |||||
| // console.log(e.item.getModel().in_parameters); | |||||
| form.resetFields(); | |||||
| form.setFieldsValue({ | |||||
| ...e.item.getModel(), | |||||
| in_parameters: JSON.parse(e.item.getModel().in_parameters), | |||||
| out_parameters: JSON.parse(e.item.getModel().out_parameters), | |||||
| control_strategy: JSON.parse(e.item.getModel().control_strategy), | |||||
| }); | |||||
| setStagingItem({ | |||||
| ...e.item.getModel(), | |||||
| in_parameters: JSON.parse(e.item.getModel().in_parameters), | |||||
| out_parameters: JSON.parse(e.item.getModel().out_parameters), | |||||
| control_strategy: JSON.parse(e.item.getModel().control_strategy), | |||||
| }); | |||||
| // form.setFieldsValue({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)}) | |||||
| // setStagingItem({...e.item.getModel(),in_parameters:JSON.parse(e.item.getModel().in_parameters),out_parameters:JSON.parse(e.item.getModel().out_parameters)}) | |||||
| // setTimeout(() => { | |||||
| // console.log(stagingItem); | |||||
| // }, (500)); | |||||
| setOpen(true); | |||||
| } | |||||
| }, | |||||
| })); | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| <Drawer title="编辑任务" placement="right" getContainer={false} closeIcon={false} onClose={onClose} afterOpenChange={afterOpenChange} open={open}> | |||||
| <Form | |||||
| <Drawer | |||||
| title="编辑任务" | |||||
| placement="right" | |||||
| getContainer={false} | |||||
| closeIcon={false} | |||||
| onClose={onClose} | |||||
| afterOpenChange={afterOpenChange} | |||||
| open={open} | |||||
| > | |||||
| <Form | |||||
| name="form" | name="form" | ||||
| form={form} | form={form} | ||||
| layout="vertical" | layout="vertical" | ||||
| @@ -89,10 +107,14 @@ const Props = forwardRef(({onParentChange}, ref) =>{ | |||||
| onFinishFailed={onFinishFailed} | onFinishFailed={onFinishFailed} | ||||
| autoComplete="off" | autoComplete="off" | ||||
| > | > | ||||
| <div className={Styles.editPipelinePropsContent}> | |||||
| <img style={{width:'13px',marginRight:'10px'}} src={'/assets/images/static-message.png'} alt="" /> | |||||
| 基本信息 | |||||
| </div> | |||||
| <div className={Styles.editPipelinePropsContent}> | |||||
| <img | |||||
| style={{ width: '13px', marginRight: '10px' }} | |||||
| src={'/assets/images/static-message.png'} | |||||
| alt="" | |||||
| /> | |||||
| 基本信息 | |||||
| </div> | |||||
| <Form.Item | <Form.Item | ||||
| label="任务名称" | label="任务名称" | ||||
| name="label" | name="label" | ||||
| @@ -108,7 +130,6 @@ const Props = forwardRef(({onParentChange}, ref) =>{ | |||||
| <Form.Item | <Form.Item | ||||
| label="任务ID" | label="任务ID" | ||||
| name="id" | name="id" | ||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| @@ -116,11 +137,15 @@ const Props = forwardRef(({onParentChange}, ref) =>{ | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| > | > | ||||
| <Input disabled/> | |||||
| <Input disabled /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <div className={Styles.editPipelinePropsContent}> | <div className={Styles.editPipelinePropsContent}> | ||||
| <img style={{width:'13px',marginRight:'10px'}} src={'/assets/images/duty-message.png'} alt="" /> | |||||
| 任务信息 | |||||
| <img | |||||
| style={{ width: '13px', marginRight: '10px' }} | |||||
| src={'/assets/images/duty-message.png'} | |||||
| alt="" | |||||
| /> | |||||
| 任务信息 | |||||
| </div> | </div> | ||||
| <Form.Item | <Form.Item | ||||
| label="镜像" | label="镜像" | ||||
| @@ -134,17 +159,11 @@ const Props = forwardRef(({onParentChange}, ref) =>{ | |||||
| > | > | ||||
| <Input /> | <Input /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | |||||
| label="工作目录" | |||||
| name="working_directory" | |||||
| > | |||||
| <Form.Item label="工作目录" name="working_directory"> | |||||
| <Input /> | <Input /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | |||||
| label="启动命令" | |||||
| name="command" | |||||
| > | |||||
| <Form.Item label="启动命令" name="command"> | |||||
| <Input /> | <Input /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | <Form.Item | ||||
| @@ -159,54 +178,63 @@ const Props = forwardRef(({onParentChange}, ref) =>{ | |||||
| > | > | ||||
| <Input /> | <Input /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | |||||
| label="挂载路径" | |||||
| name="mount_path" | |||||
| > | |||||
| <Form.Item label="挂载路径" name="mount_path"> | |||||
| <Input /> | <Input /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | |||||
| label="环境变量" | |||||
| name="env_variables" | |||||
| > | |||||
| <TextArea /> | |||||
| </Form.Item> | |||||
| {stagingItem.control_strategy&&Object.keys(stagingItem.control_strategy)&&Object.keys(stagingItem.control_strategy).length>0?Object.keys(stagingItem.control_strategy).map(item=> | |||||
| <Form.Item | |||||
| label={stagingItem.control_strategy[item].label} | |||||
| name={item} | |||||
| > | |||||
| <Input /> | |||||
| <Form.Item label="环境变量" name="env_variables"> | |||||
| <TextArea /> | |||||
| </Form.Item> | </Form.Item> | ||||
| ):''} | |||||
| {stagingItem.control_strategy && | |||||
| Object.keys(stagingItem.control_strategy) && | |||||
| Object.keys(stagingItem.control_strategy).length > 0 | |||||
| ? Object.keys(stagingItem.control_strategy).map((item) => ( | |||||
| <Form.Item label={stagingItem.control_strategy[item].label} name={item}> | |||||
| <Input /> | |||||
| </Form.Item> | |||||
| )) | |||||
| : ''} | |||||
| <div className={Styles.editPipelinePropsContent}> | <div className={Styles.editPipelinePropsContent}> | ||||
| <img style={{width:'13px',marginRight:'10px'}} src={'/assets/images/duty-message.png'} alt="" /> | |||||
| 输入参数 | |||||
| <img | |||||
| style={{ width: '13px', marginRight: '10px' }} | |||||
| src={'/assets/images/duty-message.png'} | |||||
| alt="" | |||||
| /> | |||||
| 输入参数 | |||||
| </div> | </div> | ||||
| {stagingItem.in_parameters&&Object.keys(stagingItem.in_parameters)&&Object.keys(stagingItem.in_parameters).length>0?Object.keys(stagingItem.in_parameters).map(item=> | |||||
| <Form.Item | |||||
| label={stagingItem.in_parameters[item].label+'('+item+')'} | |||||
| name={item} | |||||
| rules={[{ required: stagingItem.in_parameters[item].require?true:false}]} | |||||
| > | |||||
| <Input /> | |||||
| </Form.Item> | |||||
| ):''} | |||||
| {stagingItem.in_parameters && | |||||
| Object.keys(stagingItem.in_parameters) && | |||||
| Object.keys(stagingItem.in_parameters).length > 0 | |||||
| ? Object.keys(stagingItem.in_parameters).map((item) => ( | |||||
| <Form.Item | |||||
| label={stagingItem.in_parameters[item].label + '(' + item + ')'} | |||||
| name={item} | |||||
| rules={[{ required: stagingItem.in_parameters[item].require ? true : false }]} | |||||
| > | |||||
| <Input /> | |||||
| </Form.Item> | |||||
| )) | |||||
| : ''} | |||||
| <div className={Styles.editPipelinePropsContent}> | <div className={Styles.editPipelinePropsContent}> | ||||
| <img style={{width:'13px',marginRight:'10px'}} src={'/assets/images/duty-message.png'} alt="" /> | |||||
| 输出参数 | |||||
| <img | |||||
| style={{ width: '13px', marginRight: '10px' }} | |||||
| src={'/assets/images/duty-message.png'} | |||||
| alt="" | |||||
| /> | |||||
| 输出参数 | |||||
| </div> | </div> | ||||
| {stagingItem.out_parameters&&Object.keys(stagingItem.out_parameters)&&Object.keys(stagingItem.out_parameters).length>0?Object.keys(stagingItem.out_parameters).map(item=> | |||||
| <Form.Item | |||||
| label={stagingItem.out_parameters[item].label+'('+item+')'} | |||||
| rules={[{ required: stagingItem.out_parameters[item].require?true:false}]} | |||||
| name={item} | |||||
| > | |||||
| <Input /> | |||||
| </Form.Item> | |||||
| ):''} | |||||
| {stagingItem.out_parameters && | |||||
| Object.keys(stagingItem.out_parameters) && | |||||
| Object.keys(stagingItem.out_parameters).length > 0 | |||||
| ? Object.keys(stagingItem.out_parameters).map((item) => ( | |||||
| <Form.Item | |||||
| label={stagingItem.out_parameters[item].label + '(' + item + ')'} | |||||
| rules={[{ required: stagingItem.out_parameters[item].require ? true : false }]} | |||||
| name={item} | |||||
| > | |||||
| <Input /> | |||||
| </Form.Item> | |||||
| )) | |||||
| : ''} | |||||
| </Form> | </Form> | ||||
| </Drawer> | </Drawer> | ||||
| </> | </> | ||||
| @@ -1,250 +1,266 @@ | |||||
| import React ,{ useState,useEffect,useRef }from 'react'; | |||||
| import { Space, Table, Tag,Button,Modal, Form, Input ,message} from 'antd'; | |||||
| import { PlusOutlined,PlusCircleOutlined, DeleteOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined ,CopyOutlined} from '@ant-design/icons'; | |||||
| import {getWorkflow,addWorkflow,removeWorkflow,cloneWorkflow,getWorkflowById,editWorkflow} from '@/services/pipeline/index.js' | |||||
| import Styles from './index.less' | |||||
| import momnet from 'moment' | |||||
| import { useNavigate} from 'react-router-dom'; | |||||
| import { | |||||
| addWorkflow, | |||||
| cloneWorkflow, | |||||
| editWorkflow, | |||||
| getWorkflow, | |||||
| getWorkflowById, | |||||
| removeWorkflow, | |||||
| } from '@/services/pipeline/index.js'; | |||||
| import { CopyOutlined, DeleteOutlined, EditOutlined, PlusCircleOutlined } from '@ant-design/icons'; | |||||
| import { Button, Form, Input, Modal, Space, Table, message } from 'antd'; | |||||
| import momnet from 'moment'; | |||||
| import { useEffect, useRef, useState } from 'react'; | |||||
| import { useNavigate } from 'react-router-dom'; | |||||
| import Styles from './index.less'; | |||||
| const { TextArea } = Input; | const { TextArea } = Input; | ||||
| const Pipeline = React.FC = () => { | |||||
| const [form] = Form.useForm(); | |||||
| const navgite=useNavigate(); | |||||
| const [formId,setFormId]=useState(null) | |||||
| const [dialogTitle,setDialogTitle]=useState('新建流水线') | |||||
| const [pipeList, setPipeList] = useState([]); | |||||
| const [total, setTotal] = useState(0); | |||||
| const [isModalOpen, setIsModalOpen] = useState(false); | |||||
| const editTable=(e,record)=>{ | |||||
| e.stopPropagation() | |||||
| getWorkflowById(record.id).then(ret=>{ | |||||
| if(ret.code==200){ | |||||
| form.resetFields() | |||||
| form.setFieldsValue({...ret.data}) | |||||
| setFormId(ret.data.id) | |||||
| setDialogTitle('编辑流水线') | |||||
| setIsModalOpen(true) | |||||
| const Pipeline = () => { | |||||
| const [form] = Form.useForm(); | |||||
| const navgite = useNavigate(); | |||||
| const [formId, setFormId] = useState(null); | |||||
| const [dialogTitle, setDialogTitle] = useState('新建流水线'); | |||||
| const [pipeList, setPipeList] = useState([]); | |||||
| const [total, setTotal] = useState(0); | |||||
| const [isModalOpen, setIsModalOpen] = useState(false); | |||||
| const editTable = (e, record) => { | |||||
| e.stopPropagation(); | |||||
| getWorkflowById(record.id).then((ret) => { | |||||
| if (ret.code == 200) { | |||||
| form.resetFields(); | |||||
| form.setFieldsValue({ ...ret.data }); | |||||
| setFormId(ret.data.id); | |||||
| setDialogTitle('编辑流水线'); | |||||
| setIsModalOpen(true); | |||||
| } | |||||
| }); | |||||
| }; | |||||
| const routeToEdit = (e, record) => { | |||||
| e.stopPropagation(); | |||||
| navgite({ pathname: `/pipeline/pytorchtext/${record.id}/${record.name}` }); | |||||
| }; | |||||
| const showModal = () => { | |||||
| form.resetFields(); | |||||
| setDialogTitle('新建流水线'); | |||||
| setIsModalOpen(true); | |||||
| }; | |||||
| const handleOk = () => { | |||||
| console.log(1111); | |||||
| setIsModalOpen(false); | |||||
| }; | |||||
| const handleCancel = () => { | |||||
| setIsModalOpen(false); | |||||
| }; | |||||
| const onFinish = (values) => { | |||||
| if (formId) { | |||||
| editWorkflow({ ...values, id: formId }).then((ret) => { | |||||
| message.success('编辑成功'); | |||||
| getList(); | |||||
| setIsModalOpen(false); | |||||
| }); | |||||
| } else { | |||||
| addWorkflow(values).then((ret) => { | |||||
| console.log(ret); | |||||
| if (ret.code == 200) { | |||||
| navgite({ pathname: `/pipeline/pytorchtext/${ret.data.id}/${ret.data.name}` }); | |||||
| } | } | ||||
| }) | |||||
| }); | |||||
| } | } | ||||
| const routeToEdit=(e,record)=>{ | |||||
| e.stopPropagation() | |||||
| navgite({pathname:`/pipeline/pytorchtext/${record.id}/${record.name}` }); | |||||
| } | |||||
| const showModal = () => { | |||||
| form.resetFields() | |||||
| setDialogTitle('新建流水线') | |||||
| setIsModalOpen(true); | |||||
| }; | |||||
| const handleOk = () => { | |||||
| console.log(1111); | |||||
| setIsModalOpen(false); | |||||
| }; | |||||
| const handleCancel = () => { | |||||
| setIsModalOpen(false); | |||||
| }; | |||||
| const onFinish = (values) => { | |||||
| if(formId){ | |||||
| editWorkflow({...values,id:formId}).then(ret=>{ | |||||
| message.success('编辑成功') | |||||
| getList() | |||||
| setIsModalOpen(false) | |||||
| }) | |||||
| } | |||||
| else{ | |||||
| addWorkflow(values).then(ret=>{ | |||||
| console.log(ret); | |||||
| if(ret.code==200){ | |||||
| navgite({pathname:`/pipeline/pytorchtext/${ret.data.id}/${ret.data.name}`,}); | |||||
| } | |||||
| } | |||||
| ) | |||||
| } | |||||
| }; | |||||
| const onFinishFailed = (errorInfo) => { | |||||
| console.log('Failed:', errorInfo); | |||||
| }; | |||||
| const onFinishFailed = (errorInfo) => { | |||||
| console.log('Failed:', errorInfo); | |||||
| }; | |||||
| const pageOption = useRef({ page: 1, size: 10 }); | |||||
| const paginationProps = { | |||||
| showQuickJumper: true, | |||||
| showTotal: () => `共${total}条`, | |||||
| total: total, | |||||
| page: pageOption.current.page, | |||||
| size: pageOption.current.size, | |||||
| onChange: (current, size) => paginationChange(current, size), | |||||
| }; | |||||
| // 当前页面切换 | |||||
| const paginationChange = async (current, size) => { | |||||
| console.log('page', current, size); | |||||
| pageOption.current = { | |||||
| page: current, | |||||
| size: size, | |||||
| }; | }; | ||||
| const pageOption = useRef({page: 1,size: 10}) | |||||
| const paginationProps = { | |||||
| showQuickJumper: true, | |||||
| showTotal: () => `共${total}条`, | |||||
| total: total, | |||||
| page: pageOption.current.page, | |||||
| getList(); | |||||
| }; | |||||
| const getList = () => { | |||||
| let params = { | |||||
| offset: 1, | |||||
| page: pageOption.current.page - 1, | |||||
| size: pageOption.current.size, | size: pageOption.current.size, | ||||
| onChange: (current, size) => paginationChange(current, size) | |||||
| } | |||||
| // 当前页面切换 | |||||
| const paginationChange = async (current, size) => { | |||||
| console.log('page', current, size) | |||||
| pageOption.current={ | |||||
| page:current, | |||||
| size:size | |||||
| }; | |||||
| console.log(params, pageOption); | |||||
| getWorkflow(params).then((ret) => { | |||||
| if (ret.code == 200) { | |||||
| setPipeList(ret.data.content); | |||||
| setTotal(ret.data.totalElements); | |||||
| } | } | ||||
| getList() | |||||
| } | |||||
| const getList=()=>{ | |||||
| let params={ | |||||
| offset:1, | |||||
| page:pageOption.current.page-1, | |||||
| size:pageOption.current.size | |||||
| } | |||||
| console.log(params,pageOption); | |||||
| getWorkflow(params).then(ret=>{ | |||||
| if(ret.code==200){ | |||||
| setPipeList(ret.data.content) | |||||
| setTotal(ret.data.totalElements) | |||||
| } | |||||
| }); | |||||
| }; | |||||
| useEffect(() => { | |||||
| getList(); | |||||
| }, []); | |||||
| const columns = [ | |||||
| { | |||||
| title: '序号', | |||||
| dataIndex: 'index', | |||||
| key: 'index', | |||||
| width: 80, | |||||
| render(text, record, index) { | |||||
| return <span>{(pageOption.current.page - 1) * 10 + index + 1}</span>; | |||||
| }, | |||||
| // render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`, | |||||
| }, | |||||
| { | |||||
| title: '流水线名称', | |||||
| dataIndex: 'name', | |||||
| key: 'name', | |||||
| render: (text, record) => <a onClick={(e) => routeToEdit(e, record)}>{text}</a>, | |||||
| }, | |||||
| { | |||||
| title: '流水线描述', | |||||
| dataIndex: 'description', | |||||
| key: 'description', | |||||
| }, | |||||
| { | |||||
| title: '创建时间', | |||||
| dataIndex: 'create_time', | |||||
| key: 'create_time', | |||||
| render: (text) => <span>{momnet(text).format('YYYY-MM-DD HH:mm:ss')}</span>, | |||||
| }, | |||||
| { | |||||
| title: '修改时间', | |||||
| dataIndex: 'update_time', | |||||
| key: 'update_time', | |||||
| render: (text) => <span>{momnet(text).format('YYYY-MM-DD HH:mm:ss')}</span>, | |||||
| }, | |||||
| { | |||||
| title: '操作', | |||||
| key: 'action', | |||||
| }) | |||||
| } | |||||
| useEffect(()=>{ | |||||
| getList() | |||||
| },[]) | |||||
| const columns = [ | |||||
| { | |||||
| title: '序号', | |||||
| dataIndex: 'index', | |||||
| key: 'index', | |||||
| width: 80, | |||||
| render(text, record, index) { | |||||
| return ( | |||||
| <span>{(pageOption.current.page - 1) * 10 + index + 1}</span> | |||||
| ) | |||||
| } | |||||
| // render: (text, record, index) => `${((curPage-1)*10)+(index+1)}`, | |||||
| }, | |||||
| { | |||||
| title: '流水线名称', | |||||
| dataIndex: 'name', | |||||
| key: 'name', | |||||
| render: (text,record) => <a onClick={(e)=>routeToEdit(e,record)}>{text}</a>, | |||||
| }, | |||||
| { | |||||
| title: '流水线描述', | |||||
| dataIndex: 'description', | |||||
| key: 'description', | |||||
| }, | |||||
| { | |||||
| title: '创建时间', | |||||
| dataIndex: 'create_time', | |||||
| key: 'create_time', | |||||
| render: (text) => <span>{momnet(text).format('YYYY-MM-DD HH:mm:ss')}</span>, | |||||
| }, | |||||
| { | |||||
| title: '修改时间', | |||||
| dataIndex: 'update_time', | |||||
| key: 'update_time', | |||||
| render: (text) => <span>{momnet(text).format('YYYY-MM-DD HH:mm:ss')}</span>, | |||||
| }, | |||||
| { | |||||
| title: '操作', | |||||
| key: 'action', | |||||
| render: (_, record) => ( | |||||
| <Space size="small"> | |||||
| <Button | |||||
| type="link" | |||||
| size="small" | |||||
| key="edit" | |||||
| icon = {< EditOutlined />} | |||||
| onClick={(e) => { | |||||
| editTable(e,record) | |||||
| }} | |||||
| > | |||||
| 编辑 | |||||
| </Button> | |||||
| <Button | |||||
| type="link" | |||||
| size="small" | |||||
| key="clone" | |||||
| icon = {< CopyOutlined />} | |||||
| onClick={async () => { | |||||
| Modal.confirm({ | |||||
| title: '复制', | |||||
| content: '确定复制该条流水线吗?', | |||||
| okText: '确认', | |||||
| cancelText: '取消', | |||||
| onOk: () => { | |||||
| console.log(record); | |||||
| cloneWorkflow(record.id).then(ret=>{ | |||||
| if(ret.code==200){ | |||||
| message.success('复制成功') | |||||
| getList() | |||||
| render: (_, record) => ( | |||||
| <Space size="small"> | |||||
| <Button | |||||
| type="link" | |||||
| size="small" | |||||
| key="edit" | |||||
| icon={<EditOutlined />} | |||||
| onClick={(e) => { | |||||
| editTable(e, record); | |||||
| }} | |||||
| > | |||||
| 编辑 | |||||
| </Button> | |||||
| <Button | |||||
| type="link" | |||||
| size="small" | |||||
| key="clone" | |||||
| icon={<CopyOutlined />} | |||||
| onClick={async () => { | |||||
| Modal.confirm({ | |||||
| title: '复制', | |||||
| content: '确定复制该条流水线吗?', | |||||
| okText: '确认', | |||||
| cancelText: '取消', | |||||
| onOk: () => { | |||||
| console.log(record); | |||||
| cloneWorkflow(record.id).then((ret) => { | |||||
| if (ret.code == 200) { | |||||
| message.success('复制成功'); | |||||
| getList(); | |||||
| } else { | |||||
| message.error('复制失败'); | |||||
| } | } | ||||
| else{ | |||||
| message.error('复制失败') | |||||
| }); | |||||
| // if (success) { | |||||
| // if (actionRef.current) { | |||||
| // actionRef.current.reload(); | |||||
| // } | |||||
| // } | |||||
| }, | |||||
| }); | |||||
| }} | |||||
| > | |||||
| 复制 | |||||
| </Button> | |||||
| <Button | |||||
| type="link" | |||||
| size="small" | |||||
| danger | |||||
| style={{ color: '#f98e1b' }} | |||||
| key="batchRemove" | |||||
| icon={<DeleteOutlined />} | |||||
| onClick={async () => { | |||||
| Modal.confirm({ | |||||
| title: '删除', | |||||
| content: '确定删除该条流水线吗?', | |||||
| okText: '确认', | |||||
| cancelText: '取消', | |||||
| onOk: () => { | |||||
| console.log(record); | |||||
| removeWorkflow(record.id).then((ret) => { | |||||
| if (ret.code == 200) { | |||||
| message.success('删除成功'); | |||||
| getList(); | |||||
| } else { | |||||
| message.error(ret.msg); | |||||
| } | } | ||||
| }); | |||||
| // if (success) { | |||||
| // if (actionRef.current) { | |||||
| // actionRef.current.reload(); | |||||
| // } | |||||
| // } | |||||
| }, | |||||
| }); | |||||
| }} | |||||
| > | |||||
| 复制 | |||||
| </Button> | |||||
| }); | |||||
| // if (success) { | |||||
| // if (actionRef.current) { | |||||
| // actionRef.current.reload(); | |||||
| // } | |||||
| // } | |||||
| }, | |||||
| }); | |||||
| }} | |||||
| > | |||||
| 删除 | |||||
| </Button> | |||||
| </Space> | |||||
| ), | |||||
| }, | |||||
| ]; | |||||
| return ( | |||||
| <div> | |||||
| <div className={Styles.pipelineTopBox}> | |||||
| <Button | <Button | ||||
| type="link" | |||||
| size="small" | |||||
| danger | |||||
| style={{color:'#f98e1b'}} | |||||
| key="batchRemove" | |||||
| icon = {< DeleteOutlined />} | |||||
| onClick={async () => { | |||||
| Modal.confirm({ | |||||
| title: '删除', | |||||
| content: '确定删除该条流水线吗?', | |||||
| okText: '确认', | |||||
| cancelText: '取消', | |||||
| onOk: () => { | |||||
| console.log(record); | |||||
| removeWorkflow(record.id).then(ret=>{ | |||||
| if(ret.code==200){ | |||||
| message.success('删除成功') | |||||
| getList() | |||||
| } | |||||
| else{ | |||||
| message.error(ret.msg) | |||||
| } | |||||
| }); | |||||
| // if (success) { | |||||
| // if (actionRef.current) { | |||||
| // actionRef.current.reload(); | |||||
| // } | |||||
| // } | |||||
| }, | |||||
| }); | |||||
| }} | |||||
| type="primary" | |||||
| className={Styles.plusButton} | |||||
| onClick={showModal} | |||||
| icon={<PlusCircleOutlined style={{ color: '#1664ff' }} />} | |||||
| > | > | ||||
| 删除 | |||||
| </Button> | |||||
| </Space> | |||||
| ), | |||||
| }, | |||||
| ]; | |||||
| return (<div> | |||||
| <div className={Styles.pipelineTopBox}> | |||||
| <Button type="primary" className={Styles.plusButton} onClick={showModal} icon = {<PlusCircleOutlined style={{color:'#1664ff'}} />}> | |||||
| 新建流水线 | 新建流水线 | ||||
| </Button> | </Button> | ||||
| </div> | |||||
| <Table columns={columns} dataSource={pipeList} pagination={paginationProps}/> | |||||
| <Modal title={<div style={{display:'flex',alignItems:'center',fontWeight:500}}> | |||||
| <img style={{width:'20px',marginRight:'10px'}} src={`/assets/images/pipeline-edit-icon.png`} alt="" />{dialogTitle} | |||||
| </div>} open={isModalOpen} className={Styles.modal} okButtonProps={{ | |||||
| htmlType: 'submit', | |||||
| form: 'form', | |||||
| }} onCancel={handleCancel}> | |||||
| </div> | |||||
| <Table columns={columns} dataSource={pipeList} pagination={paginationProps} /> | |||||
| <Modal | |||||
| title={ | |||||
| <div style={{ display: 'flex', alignItems: 'center', fontWeight: 500 }}> | |||||
| <img | |||||
| style={{ width: '20px', marginRight: '10px' }} | |||||
| src={`/assets/images/pipeline-edit-icon.png`} | |||||
| alt="" | |||||
| /> | |||||
| {dialogTitle} | |||||
| </div> | |||||
| } | |||||
| open={isModalOpen} | |||||
| className={Styles.modal} | |||||
| okButtonProps={{ | |||||
| htmlType: 'submit', | |||||
| form: 'form', | |||||
| }} | |||||
| onCancel={handleCancel} | |||||
| > | |||||
| <Form | <Form | ||||
| name="form" | name="form" | ||||
| form={form} | form={form} | ||||
| @@ -259,28 +275,34 @@ const Pipeline = React.FC = () => { | |||||
| <Form.Item | <Form.Item | ||||
| label="流水线名称" | label="流水线名称" | ||||
| name="name" | name="name" | ||||
| rules={[ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ]} | |||||
| rules={ | |||||
| [ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ] | |||||
| } | |||||
| > | > | ||||
| <Input /> | <Input /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <Form.Item | <Form.Item | ||||
| label="流水线描述" | label="流水线描述" | ||||
| name="description" | name="description" | ||||
| rules={[ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ]} | |||||
| rules={ | |||||
| [ | |||||
| // { | |||||
| // required: true, | |||||
| // message: 'Please input your username!', | |||||
| // }, | |||||
| ] | |||||
| } | |||||
| > | > | ||||
| <Input /> | <Input /> | ||||
| </Form.Item> | </Form.Item> | ||||
| </Form> | </Form> | ||||
| </Modal> | </Modal> | ||||
| </div>)}; | |||||
| export default Pipeline; | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| export default Pipeline; | |||||
| @@ -1,65 +1,63 @@ | |||||
| .pipelineTopBox{ | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: flex-end; | |||||
| padding-right: 30px; | |||||
| width: 100%; | |||||
| height: 49px; | |||||
| background-size: 100% 100%; | |||||
| background-image: url(/assets/images/pipeline-back.png); | |||||
| margin-bottom: 10px; | |||||
| .pipelineTopBox { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: flex-end; | |||||
| width: 100%; | |||||
| height: 49px; | |||||
| margin-bottom: 10px; | |||||
| padding-right: 30px; | |||||
| background-image: url(/assets/images/pipeline-back.png); | |||||
| background-size: 100% 100%; | |||||
| } | } | ||||
| .plusButton{ | |||||
| background:rgba(22, 100, 255, 0.06); | |||||
| border:1px solid; | |||||
| border-color:rgba(22, 100, 255, 0.11); | |||||
| border-radius:4px; | |||||
| color:#1d1d20; | |||||
| font-size:14px; | |||||
| font-family: 'Alibaba'; | |||||
| .plusButton { | |||||
| color: #1d1d20; | |||||
| font-size: 14px; | |||||
| font-family: 'Alibaba'; | |||||
| background: rgba(22, 100, 255, 0.06); | |||||
| border: 1px solid; | |||||
| border-color: rgba(22, 100, 255, 0.11); | |||||
| border-radius: 4px; | |||||
| } | } | ||||
| .plusButton:hover{ | |||||
| background:rgba(22, 100, 255, 0.06)!important; | |||||
| border:1px solid!important; | |||||
| border-color:rgba(22, 100, 255, 0.11)!important; | |||||
| color:#1d1d20!important; | |||||
| .plusButton:hover { | |||||
| color: #1d1d20 !important; | |||||
| background: rgba(22, 100, 255, 0.06) !important; | |||||
| border: 1px solid !important; | |||||
| border-color: rgba(22, 100, 255, 0.11) !important; | |||||
| } | } | ||||
| .modal { | .modal { | ||||
| :global { | |||||
| .ant-modal-content { | |||||
| background:linear-gradient(180deg,#cfdfff 0%,#d4e2ff 9.77%,#ffffff 40%,#ffffff 100%); | |||||
| border-radius:21px; | |||||
| padding: 20px 67px; | |||||
| width: 825px; | |||||
| } | |||||
| .ant-modal-header{ | |||||
| background-color: transparent; | |||||
| margin: 20px 0; | |||||
| } | |||||
| .ant-input{ | |||||
| border-color:#e6e6e6; | |||||
| height: 40px; | |||||
| } | |||||
| .ant-form-item .ant-form-item-label >label{ | |||||
| color:rgba(29, 29, 32, 0.8); | |||||
| } | |||||
| .ant-modal-footer{ | |||||
| margin: 40px 0 30px 0; | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| } | |||||
| .ant-btn{ | |||||
| width:110px; | |||||
| height:40px; | |||||
| font-size:18px; | |||||
| background:rgba(22, 100, 255, 0.06); | |||||
| border-radius:10px; | |||||
| border-color: transparent; | |||||
| } | |||||
| .ant-btn-primary{ | |||||
| background:#1664ff; | |||||
| } | |||||
| :global { | |||||
| .ant-modal-content { | |||||
| width: 825px; | |||||
| padding: 20px 67px; | |||||
| background: linear-gradient(180deg, #cfdfff 0%, #d4e2ff 9.77%, #ffffff 40%, #ffffff 100%); | |||||
| border-radius: 21px; | |||||
| } | } | ||||
| .ant-modal-header { | |||||
| margin: 20px 0; | |||||
| background-color: transparent; | |||||
| } | |||||
| .ant-input { | |||||
| height: 40px; | |||||
| border-color: #e6e6e6; | |||||
| } | |||||
| .ant-form-item .ant-form-item-label > label { | |||||
| color: rgba(29, 29, 32, 0.8); | |||||
| } | |||||
| .ant-modal-footer { | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| margin: 40px 0 30px 0; | |||||
| } | |||||
| .ant-btn { | |||||
| width: 110px; | |||||
| height: 40px; | |||||
| font-size: 18px; | |||||
| background: rgba(22, 100, 255, 0.06); | |||||
| border-color: transparent; | |||||
| border-radius: 10px; | |||||
| } | |||||
| .ant-btn-primary { | |||||
| background: #1664ff; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -1,14 +1,14 @@ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import { | import { | ||||
| ProForm, | ProForm, | ||||
| ProFormDigit, | ProFormDigit, | ||||
| ProFormRadio, | |||||
| ProFormText, | ProFormText, | ||||
| ProFormTextArea, | ProFormTextArea, | ||||
| ProFormRadio, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { Form, Modal} from 'antd'; | |||||
| import { useIntl, FormattedMessage } from '@umijs/max'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | |||||
| import React, { useEffect } from 'react'; | |||||
| export type ConfigFormData = Record<string, unknown> & Partial<API.System.Config>; | export type ConfigFormData = Record<string, unknown> & Partial<API.System.Config>; | ||||
| @@ -22,22 +22,22 @@ export type ConfigFormProps = { | |||||
| const ConfigForm: React.FC<ConfigFormProps> = (props) => { | const ConfigForm: React.FC<ConfigFormProps> = (props) => { | ||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const { configTypeOptions } = props; | const { configTypeOptions } = props; | ||||
| useEffect(() => { | useEffect(() => { | ||||
| form.resetFields(); | form.resetFields(); | ||||
| form.setFieldsValue({ | form.setFieldsValue({ | ||||
| configId: props.values.configId, | |||||
| configName: props.values.configName, | |||||
| configKey: props.values.configKey, | |||||
| configValue: props.values.configValue, | |||||
| configType: props.values.configType, | |||||
| createBy: props.values.createBy, | |||||
| createTime: props.values.createTime, | |||||
| updateBy: props.values.updateBy, | |||||
| updateTime: props.values.updateTime, | |||||
| remark: props.values.remark, | |||||
| configId: props.values.configId, | |||||
| configName: props.values.configName, | |||||
| configKey: props.values.configKey, | |||||
| configValue: props.values.configValue, | |||||
| configType: props.values.configType, | |||||
| createBy: props.values.createBy, | |||||
| createTime: props.values.createTime, | |||||
| updateBy: props.values.updateBy, | |||||
| updateTime: props.values.updateTime, | |||||
| remark: props.values.remark, | |||||
| }); | }); | ||||
| }, [form, props]); | }, [form, props]); | ||||
| @@ -65,12 +65,13 @@ const ConfigForm: React.FC<ConfigFormProps> = (props) => { | |||||
| onOk={handleOk} | onOk={handleOk} | ||||
| onCancel={handleCancel} | onCancel={handleCancel} | ||||
| > | > | ||||
| <ProForm | |||||
| <ProForm | |||||
| form={form} | form={form} | ||||
| grid={true} | grid={true} | ||||
| submitter={false} | submitter={false} | ||||
| layout="horizontal" | |||||
| onFinish={handleFinish}> | |||||
| layout="horizontal" | |||||
| onFinish={handleFinish} | |||||
| > | |||||
| <ProFormDigit | <ProFormDigit | ||||
| name="configId" | name="configId" | ||||
| label={intl.formatMessage({ | label={intl.formatMessage({ | ||||
| @@ -84,7 +85,7 @@ const ConfigForm: React.FC<ConfigFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入参数主键!" defaultMessage="请输入参数主键!" />, | |||||
| message: <FormattedMessage id="请输入参数主键!" defaultMessage="请输入参数主键!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -99,7 +100,7 @@ const ConfigForm: React.FC<ConfigFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入参数名称!" defaultMessage="请输入参数名称!" />, | |||||
| message: <FormattedMessage id="请输入参数名称!" defaultMessage="请输入参数名称!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -114,7 +115,7 @@ const ConfigForm: React.FC<ConfigFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入参数键名!" defaultMessage="请输入参数键名!" />, | |||||
| message: <FormattedMessage id="请输入参数键名!" defaultMessage="请输入参数键名!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -129,7 +130,7 @@ const ConfigForm: React.FC<ConfigFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入参数键值!" defaultMessage="请输入参数键值!" />, | |||||
| message: <FormattedMessage id="请输入参数键值!" defaultMessage="请输入参数键值!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -145,7 +146,7 @@ const ConfigForm: React.FC<ConfigFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入系统内置!" defaultMessage="请输入系统内置!" />, | |||||
| message: <FormattedMessage id="请输入系统内置!" defaultMessage="请输入系统内置!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -160,7 +161,7 @@ const ConfigForm: React.FC<ConfigFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入备注!" defaultMessage="请输入备注!" />, | |||||
| message: <FormattedMessage id="请输入备注!" defaultMessage="请输入备注!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -1,14 +1,32 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess } from '@umijs/max'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| import { | |||||
| addConfig, | |||||
| exportConfig, | |||||
| getConfigList, | |||||
| refreshConfigCache, | |||||
| removeConfig, | |||||
| updateConfig, | |||||
| } from '@/services/system/config'; | |||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import { | |||||
| DeleteOutlined, | |||||
| DownloadOutlined, | |||||
| ExclamationCircleOutlined, | |||||
| PlusOutlined, | |||||
| ReloadOutlined, | |||||
| } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useAccess, useIntl } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | import type { FormInstance } from 'antd'; | ||||
| import { Button, message, Modal } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined, ReloadOutlined, DownloadOutlined } from '@ant-design/icons'; | |||||
| import { getConfigList, removeConfig, addConfig, updateConfig, exportConfig, refreshConfigCache } from '@/services/system/config'; | |||||
| import { Button, Modal, message } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import UpdateForm from './edit'; | import UpdateForm from './edit'; | ||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| /** | /** | ||||
| * 添加节点 | * 添加节点 | ||||
| @@ -103,7 +121,7 @@ const handleRemoveOne = async (selectedRow: API.System.Config) => { | |||||
| /** | /** | ||||
| * 导出数据 | * 导出数据 | ||||
| * | * | ||||
| * | |||||
| * | |||||
| */ | */ | ||||
| const handleExport = async () => { | const handleExport = async () => { | ||||
| const hide = message.loading('正在导出'); | const hide = message.loading('正在导出'); | ||||
| @@ -183,7 +201,7 @@ const ConfigTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: configTypeOptions, | valueEnum: configTypeOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={configTypeOptions} value={record.configType} />); | |||||
| return <DictTag enums={configTypeOptions} value={record.configType} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -283,7 +301,7 @@ const ConfigTableList: React.FC = () => { | |||||
| actionRef.current?.reloadAndRest?.(); | actionRef.current?.reloadAndRest?.(); | ||||
| } | } | ||||
| }, | }, | ||||
| onCancel() { }, | |||||
| onCancel() {}, | |||||
| }); | }); | ||||
| }} | }} | ||||
| > | > | ||||
| @@ -1,15 +1,15 @@ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import { | import { | ||||
| ProForm, | ProForm, | ||||
| ProFormDigit, | ProFormDigit, | ||||
| ProFormText, | |||||
| ProFormRadio, | ProFormRadio, | ||||
| ProFormText, | |||||
| ProFormTreeSelect, | ProFormTreeSelect, | ||||
| } from '@ant-design/pro-components'; | } from '@ant-design/pro-components'; | ||||
| import { Form, Modal} from 'antd'; | |||||
| import { useIntl, FormattedMessage } from '@umijs/max'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | |||||
| import { DataNode } from 'antd/es/tree'; | import { DataNode } from 'antd/es/tree'; | ||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import React, { useEffect } from 'react'; | |||||
| export type DeptFormData = Record<string, unknown> & Partial<API.System.Dept>; | export type DeptFormData = Record<string, unknown> & Partial<API.System.Dept>; | ||||
| @@ -76,7 +76,8 @@ const DeptForm: React.FC<DeptFormProps> = (props) => { | |||||
| grid={true} | grid={true} | ||||
| submitter={false} | submitter={false} | ||||
| layout="horizontal" | layout="horizontal" | ||||
| onFinish={handleFinish}> | |||||
| onFinish={handleFinish} | |||||
| > | |||||
| <ProFormDigit | <ProFormDigit | ||||
| name="deptId" | name="deptId" | ||||
| label={intl.formatMessage({ | label={intl.formatMessage({ | ||||
| @@ -107,9 +108,7 @@ const DeptForm: React.FC<DeptFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: ( | |||||
| <FormattedMessage id="请输入用户昵称!" defaultMessage="请选择上级部门!" /> | |||||
| ), | |||||
| message: <FormattedMessage id="请输入用户昵称!" defaultMessage="请选择上级部门!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -1,15 +1,27 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | |||||
| import { Button, message, Modal } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; | |||||
| import { getDeptList, removeDept, addDept, updateDept, exportDept, getDeptListExcludeChild } from '@/services/system/dept'; | |||||
| import UpdateForm from './edit'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| import { | |||||
| addDept, | |||||
| exportDept, | |||||
| getDeptList, | |||||
| getDeptListExcludeChild, | |||||
| removeDept, | |||||
| updateDept, | |||||
| } from '@/services/system/dept'; | |||||
| import { getDictValueEnum } from '@/services/system/dict'; | import { getDictValueEnum } from '@/services/system/dict'; | ||||
| import { buildTreeData } from '@/utils/tree'; | import { buildTreeData } from '@/utils/tree'; | ||||
| import DictTag from '@/components/DictTag'; | |||||
| import { DeleteOutlined, ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useAccess, useIntl } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | |||||
| import { Button, Modal, message } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import UpdateForm from './edit'; | |||||
| /** | /** | ||||
| * 添加节点 | * 添加节点 | ||||
| @@ -104,7 +116,7 @@ const handleRemoveOne = async (selectedRow: API.System.Dept) => { | |||||
| /** | /** | ||||
| * 导出数据 | * 导出数据 | ||||
| * | * | ||||
| * | |||||
| * | |||||
| */ | */ | ||||
| const handleExport = async () => { | const handleExport = async () => { | ||||
| const hide = message.loading('正在导出'); | const hide = message.loading('正在导出'); | ||||
| @@ -120,9 +132,8 @@ const handleExport = async () => { | |||||
| } | } | ||||
| }; | }; | ||||
| const DeptTableList: React.FC = () => { | const DeptTableList: React.FC = () => { | ||||
| const formTableRef = useRef<FormInstance>(); | |||||
| const formTableRef = useRef<FormInstance>(); | |||||
| const [modalVisible, setModalVisible] = useState<boolean>(false); | const [modalVisible, setModalVisible] = useState<boolean>(false); | ||||
| @@ -139,7 +150,7 @@ const DeptTableList: React.FC = () => { | |||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| getDictValueEnum('sys_normal_disable').then((data) => { | |||||
| getDictValueEnum('sys_normal_disable').then((data) => { | |||||
| setStatusOptions(data); | setStatusOptions(data); | ||||
| }); | }); | ||||
| }, []); | }, []); | ||||
| @@ -161,7 +172,7 @@ const DeptTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: statusOptions, | valueEnum: statusOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={statusOptions} value={record.status} />); | |||||
| return <DictTag enums={statusOptions} value={record.status} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -179,7 +190,7 @@ const DeptTableList: React.FC = () => { | |||||
| getDeptListExcludeChild(record.deptId).then((res) => { | getDeptListExcludeChild(record.deptId).then((res) => { | ||||
| if (res.code === 200) { | if (res.code === 200) { | ||||
| let depts = buildTreeData(res.data, 'deptId', 'deptName', '', '', ''); | let depts = buildTreeData(res.data, 'deptId', 'deptName', '', '', ''); | ||||
| if(depts.length === 0) { | |||||
| if (depts.length === 0) { | |||||
| depts = [{ id: 0, title: '无上级', children: undefined, key: 0, value: 0 }]; | depts = [{ id: 0, title: '无上级', children: undefined, key: 0, value: 0 }]; | ||||
| } | } | ||||
| setDeptTree(depts); | setDeptTree(depts); | ||||
| @@ -258,7 +269,7 @@ const DeptTableList: React.FC = () => { | |||||
| </Button>, | </Button>, | ||||
| <Button | <Button | ||||
| type="primary" | type="primary" | ||||
| key="remove" | |||||
| key="remove" | |||||
| hidden={selectedRows?.length === 0 || !access.hasPerms('system:dept:remove')} | hidden={selectedRows?.length === 0 || !access.hasPerms('system:dept:remove')} | ||||
| onClick={async () => { | onClick={async () => { | ||||
| Modal.confirm({ | Modal.confirm({ | ||||
| @@ -273,7 +284,7 @@ const DeptTableList: React.FC = () => { | |||||
| } | } | ||||
| }, | }, | ||||
| onCancel() {}, | onCancel() {}, | ||||
| }); | |||||
| }); | |||||
| }} | }} | ||||
| > | > | ||||
| <DeleteOutlined /> | <DeleteOutlined /> | ||||
| @@ -1,14 +1,14 @@ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import { | import { | ||||
| ProForm, | ProForm, | ||||
| ProFormDigit, | ProFormDigit, | ||||
| ProFormText, | |||||
| ProFormRadio, | ProFormRadio, | ||||
| ProFormText, | |||||
| ProFormTextArea, | ProFormTextArea, | ||||
| } from '@ant-design/pro-components'; | |||||
| import { Form, Modal} from 'antd'; | |||||
| import { useIntl, FormattedMessage } from '@umijs/max'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | |||||
| import React, { useEffect } from 'react'; | |||||
| export type DictTypeFormData = Record<string, unknown> & Partial<API.System.DictType>; | export type DictTypeFormData = Record<string, unknown> & Partial<API.System.DictType>; | ||||
| @@ -28,15 +28,15 @@ const DictTypeForm: React.FC<DictTypeFormProps> = (props) => { | |||||
| useEffect(() => { | useEffect(() => { | ||||
| form.resetFields(); | form.resetFields(); | ||||
| form.setFieldsValue({ | form.setFieldsValue({ | ||||
| dictId: props.values.dictId, | |||||
| dictName: props.values.dictName, | |||||
| dictType: props.values.dictType, | |||||
| status: props.values.status, | |||||
| createBy: props.values.createBy, | |||||
| createTime: props.values.createTime, | |||||
| updateBy: props.values.updateBy, | |||||
| updateTime: props.values.updateTime, | |||||
| remark: props.values.remark, | |||||
| dictId: props.values.dictId, | |||||
| dictName: props.values.dictName, | |||||
| dictType: props.values.dictType, | |||||
| status: props.values.status, | |||||
| createBy: props.values.createBy, | |||||
| createTime: props.values.createTime, | |||||
| updateBy: props.values.updateBy, | |||||
| updateTime: props.values.updateTime, | |||||
| remark: props.values.remark, | |||||
| }); | }); | ||||
| }, [form, props]); | }, [form, props]); | ||||
| @@ -64,12 +64,13 @@ const DictTypeForm: React.FC<DictTypeFormProps> = (props) => { | |||||
| onOk={handleOk} | onOk={handleOk} | ||||
| onCancel={handleCancel} | onCancel={handleCancel} | ||||
| > | > | ||||
| <ProForm | |||||
| <ProForm | |||||
| form={form} | form={form} | ||||
| grid={true} | grid={true} | ||||
| submitter={false} | submitter={false} | ||||
| layout="horizontal" | layout="horizontal" | ||||
| onFinish={handleFinish}> | |||||
| onFinish={handleFinish} | |||||
| > | |||||
| <ProFormDigit | <ProFormDigit | ||||
| name="dictId" | name="dictId" | ||||
| label={intl.formatMessage({ | label={intl.formatMessage({ | ||||
| @@ -1,14 +1,25 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess, history } from '@umijs/max'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| import { | |||||
| addDictType, | |||||
| exportDictType, | |||||
| getDictTypeList, | |||||
| getDictValueEnum, | |||||
| removeDictType, | |||||
| updateDictType, | |||||
| } from '@/services/system/dict'; | |||||
| import { DeleteOutlined, ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, history, useAccess, useIntl } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | import type { FormInstance } from 'antd'; | ||||
| import { Button, message, Modal } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; | |||||
| import { getDictTypeList, removeDictType, addDictType, updateDictType, exportDictType } from '@/services/system/dict'; | |||||
| import { Button, Modal, message } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import UpdateForm from './edit'; | import UpdateForm from './edit'; | ||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| /** | /** | ||||
| * 添加节点 | * 添加节点 | ||||
| @@ -103,7 +114,7 @@ const handleRemoveOne = async (selectedRow: API.System.DictType) => { | |||||
| /** | /** | ||||
| * 导出数据 | * 导出数据 | ||||
| * | * | ||||
| * | |||||
| * | |||||
| */ | */ | ||||
| const handleExport = async () => { | const handleExport = async () => { | ||||
| const hide = message.loading('正在导出'); | const hide = message.loading('正在导出'); | ||||
| @@ -119,9 +130,8 @@ const handleExport = async () => { | |||||
| } | } | ||||
| }; | }; | ||||
| const DictTableList: React.FC = () => { | const DictTableList: React.FC = () => { | ||||
| const formTableRef = useRef<FormInstance>(); | |||||
| const formTableRef = useRef<FormInstance>(); | |||||
| const [modalVisible, setModalVisible] = useState<boolean>(false); | const [modalVisible, setModalVisible] = useState<boolean>(false); | ||||
| @@ -176,7 +186,7 @@ const DictTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: statusOptions, | valueEnum: statusOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={statusOptions} value={record.status} />); | |||||
| return <DictTag enums={statusOptions} value={record.status} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -190,7 +200,7 @@ const DictTableList: React.FC = () => { | |||||
| dataIndex: 'createTime', | dataIndex: 'createTime', | ||||
| valueType: 'dateRange', | valueType: 'dateRange', | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<span>{record.createTime.toString()} </span>); | |||||
| return <span>{record.createTime.toString()} </span>; | |||||
| }, | }, | ||||
| search: { | search: { | ||||
| transform: (value) => { | transform: (value) => { | ||||
| @@ -277,7 +287,7 @@ const DictTableList: React.FC = () => { | |||||
| </Button>, | </Button>, | ||||
| <Button | <Button | ||||
| type="primary" | type="primary" | ||||
| key="remove" | |||||
| key="remove" | |||||
| hidden={selectedRows?.length === 0 || !access.hasPerms('system:dictType:remove')} | hidden={selectedRows?.length === 0 || !access.hasPerms('system:dictType:remove')} | ||||
| onClick={async () => { | onClick={async () => { | ||||
| Modal.confirm({ | Modal.confirm({ | ||||
| @@ -292,7 +302,7 @@ const DictTableList: React.FC = () => { | |||||
| } | } | ||||
| }, | }, | ||||
| onCancel() {}, | onCancel() {}, | ||||
| }); | |||||
| }); | |||||
| }} | }} | ||||
| > | > | ||||
| <DeleteOutlined /> | <DeleteOutlined /> | ||||
| @@ -1,15 +1,15 @@ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import { | import { | ||||
| ProForm, | ProForm, | ||||
| ProFormDigit, | ProFormDigit, | ||||
| ProFormText, | |||||
| ProFormSelect, | |||||
| ProFormRadio, | ProFormRadio, | ||||
| ProFormSelect, | |||||
| ProFormText, | |||||
| ProFormTextArea, | ProFormTextArea, | ||||
| } from '@ant-design/pro-components'; | } from '@ant-design/pro-components'; | ||||
| import { Form, Modal} from 'antd'; | |||||
| import { useIntl, FormattedMessage } from '@umijs/max'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | |||||
| import React, { useEffect } from 'react'; | |||||
| export type DataFormData = Record<string, unknown> & Partial<API.System.DictData>; | export type DataFormData = Record<string, unknown> & Partial<API.System.DictData>; | ||||
| @@ -75,7 +75,8 @@ const DictDataForm: React.FC<DataFormProps> = (props) => { | |||||
| grid={true} | grid={true} | ||||
| submitter={false} | submitter={false} | ||||
| layout="horizontal" | layout="horizontal" | ||||
| onFinish={handleFinish}> | |||||
| onFinish={handleFinish} | |||||
| > | |||||
| <ProFormDigit | <ProFormDigit | ||||
| name="dictCode" | name="dictCode" | ||||
| label={intl.formatMessage({ | label={intl.formatMessage({ | ||||
| @@ -163,12 +164,12 @@ const DictDataForm: React.FC<DataFormProps> = (props) => { | |||||
| colProps={{ md: 12, xl: 24 }} | colProps={{ md: 12, xl: 24 }} | ||||
| placeholder="请输入回显样式" | placeholder="请输入回显样式" | ||||
| valueEnum={{ | valueEnum={{ | ||||
| 'default': '默认', | |||||
| 'primary': '主要', | |||||
| 'success': '成功', | |||||
| 'info': '信息', | |||||
| 'warning': '警告', | |||||
| 'danger': '危险', | |||||
| default: '默认', | |||||
| primary: '主要', | |||||
| success: '成功', | |||||
| info: '信息', | |||||
| warning: '警告', | |||||
| danger: '危险', | |||||
| }} | }} | ||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| @@ -199,8 +200,8 @@ const DictDataForm: React.FC<DataFormProps> = (props) => { | |||||
| defaultMessage: '是否默认', | defaultMessage: '是否默认', | ||||
| })} | })} | ||||
| valueEnum={{ | valueEnum={{ | ||||
| 'Y': '是', | |||||
| 'N': '否', | |||||
| Y: '是', | |||||
| N: '否', | |||||
| }} | }} | ||||
| initialValue={'N'} | initialValue={'N'} | ||||
| colProps={{ md: 12, xl: 24 }} | colProps={{ md: 12, xl: 24 }} | ||||
| @@ -1,14 +1,25 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess, history, useParams } from '@umijs/max'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| import { getDictType, getDictTypeOptionSelect, getDictValueEnum } from '@/services/system/dict'; | |||||
| import { | |||||
| addDictData, | |||||
| exportDictData, | |||||
| getDictDataList, | |||||
| removeDictData, | |||||
| updateDictData, | |||||
| } from '@/services/system/dictdata'; | |||||
| import { DeleteOutlined, ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, history, useAccess, useIntl, useParams } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | import type { FormInstance } from 'antd'; | ||||
| import { Button, message, Modal } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; | |||||
| import { getDictDataList, removeDictData, addDictData, updateDictData, exportDictData } from '@/services/system/dictdata'; | |||||
| import { Button, Modal, message } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import UpdateForm from './edit'; | import UpdateForm from './edit'; | ||||
| import { getDictValueEnum, getDictType, getDictTypeOptionSelect } from '@/services/system/dict'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| /** | /** | ||||
| * 添加节点 | * 添加节点 | ||||
| @@ -123,9 +134,7 @@ export type DictTypeArgs = { | |||||
| id: string; | id: string; | ||||
| }; | }; | ||||
| const DictDataTableList: React.FC = () => { | const DictDataTableList: React.FC = () => { | ||||
| const formTableRef = useRef<FormInstance>(); | const formTableRef = useRef<FormInstance>(); | ||||
| const [dictId, setDictId] = useState<string>(''); | const [dictId, setDictId] = useState<string>(''); | ||||
| @@ -221,7 +230,7 @@ const DictDataTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: statusOptions, | valueEnum: statusOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={statusOptions} value={record.status} />); | |||||
| return <DictTag enums={statusOptions} value={record.status} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -235,7 +244,7 @@ const DictDataTableList: React.FC = () => { | |||||
| dataIndex: 'createTime', | dataIndex: 'createTime', | ||||
| valueType: 'dateRange', | valueType: 'dateRange', | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<span>{record.createTime.toString()} </span>); | |||||
| return <span>{record.createTime.toString()} </span>; | |||||
| }, | }, | ||||
| search: { | search: { | ||||
| transform: (value) => { | transform: (value) => { | ||||
| @@ -314,7 +323,11 @@ const DictDataTableList: React.FC = () => { | |||||
| key="add" | key="add" | ||||
| hidden={!access.hasPerms('system:data:add')} | hidden={!access.hasPerms('system:data:add')} | ||||
| onClick={async () => { | onClick={async () => { | ||||
| setCurrentRow({ dictType: dictType, isDefault: 'N', status: '0' } as API.System.DictData); | |||||
| setCurrentRow({ | |||||
| dictType: dictType, | |||||
| isDefault: 'N', | |||||
| status: '0', | |||||
| } as API.System.DictData); | |||||
| setModalVisible(true); | setModalVisible(true); | ||||
| }} | }} | ||||
| > | > | ||||
| @@ -336,7 +349,7 @@ const DictDataTableList: React.FC = () => { | |||||
| actionRef.current?.reloadAndRest?.(); | actionRef.current?.reloadAndRest?.(); | ||||
| } | } | ||||
| }, | }, | ||||
| onCancel() { }, | |||||
| onCancel() {}, | |||||
| }); | }); | ||||
| }} | }} | ||||
| > | > | ||||
| @@ -356,14 +369,16 @@ const DictDataTableList: React.FC = () => { | |||||
| </Button>, | </Button>, | ||||
| ]} | ]} | ||||
| request={(params) => | request={(params) => | ||||
| getDictDataList({ ...params, dictType } as API.System.DictDataListParams).then((res) => { | |||||
| const result = { | |||||
| data: res.rows, | |||||
| total: res.total, | |||||
| success: true, | |||||
| }; | |||||
| return result; | |||||
| }) | |||||
| getDictDataList({ ...params, dictType } as API.System.DictDataListParams).then( | |||||
| (res) => { | |||||
| const result = { | |||||
| data: res.rows, | |||||
| total: res.total, | |||||
| success: true, | |||||
| }; | |||||
| return result; | |||||
| }, | |||||
| ) | |||||
| } | } | ||||
| columns={columns} | columns={columns} | ||||
| rowSelection={{ | rowSelection={{ | ||||
| @@ -1,14 +1,14 @@ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import { | import { | ||||
| ProForm, | ProForm, | ||||
| ProFormDigit, | ProFormDigit, | ||||
| ProFormText, | |||||
| ProFormRadio, | ProFormRadio, | ||||
| ProFormText, | |||||
| ProFormTimePicker, | ProFormTimePicker, | ||||
| } from '@ant-design/pro-components'; | |||||
| import { Form, Modal} from 'antd'; | |||||
| import { useIntl, FormattedMessage } from '@umijs/max'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | |||||
| import React, { useEffect } from 'react'; | |||||
| export type LogininforFormData = Record<string, unknown> & Partial<API.Monitor.Logininfor>; | export type LogininforFormData = Record<string, unknown> & Partial<API.Monitor.Logininfor>; | ||||
| @@ -22,21 +22,21 @@ export type LogininforFormProps = { | |||||
| const LogininforForm: React.FC<LogininforFormProps> = (props) => { | const LogininforForm: React.FC<LogininforFormProps> = (props) => { | ||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const { statusOptions, } = props; | |||||
| const { statusOptions } = props; | |||||
| useEffect(() => { | useEffect(() => { | ||||
| form.resetFields(); | form.resetFields(); | ||||
| form.setFieldsValue({ | form.setFieldsValue({ | ||||
| infoId: props.values.infoId, | |||||
| userName: props.values.userName, | |||||
| ipaddr: props.values.ipaddr, | |||||
| loginLocation: props.values.loginLocation, | |||||
| browser: props.values.browser, | |||||
| os: props.values.os, | |||||
| status: props.values.status, | |||||
| msg: props.values.msg, | |||||
| loginTime: props.values.loginTime, | |||||
| infoId: props.values.infoId, | |||||
| userName: props.values.userName, | |||||
| ipaddr: props.values.ipaddr, | |||||
| loginLocation: props.values.loginLocation, | |||||
| browser: props.values.browser, | |||||
| os: props.values.os, | |||||
| status: props.values.status, | |||||
| msg: props.values.msg, | |||||
| loginTime: props.values.loginTime, | |||||
| }); | }); | ||||
| }, [form, props]); | }, [form, props]); | ||||
| @@ -65,11 +65,7 @@ const LogininforForm: React.FC<LogininforFormProps> = (props) => { | |||||
| onOk={handleOk} | onOk={handleOk} | ||||
| onCancel={handleCancel} | onCancel={handleCancel} | ||||
| > | > | ||||
| <ProForm | |||||
| form={form} | |||||
| grid={true} | |||||
| layout="horizontal" | |||||
| onFinish={handleFinish}> | |||||
| <ProForm form={form} grid={true} layout="horizontal" onFinish={handleFinish}> | |||||
| <ProFormDigit | <ProFormDigit | ||||
| name="infoId" | name="infoId" | ||||
| label={intl.formatMessage({ | label={intl.formatMessage({ | ||||
| @@ -83,7 +79,7 @@ const LogininforForm: React.FC<LogininforFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入访问编号!" defaultMessage="请输入访问编号!" />, | |||||
| message: <FormattedMessage id="请输入访问编号!" defaultMessage="请输入访问编号!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -98,7 +94,7 @@ const LogininforForm: React.FC<LogininforFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入用户账号!" defaultMessage="请输入用户账号!" />, | |||||
| message: <FormattedMessage id="请输入用户账号!" defaultMessage="请输入用户账号!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -113,7 +109,9 @@ const LogininforForm: React.FC<LogininforFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入登录IP地址!" defaultMessage="请输入登录IP地址!" />, | |||||
| message: ( | |||||
| <FormattedMessage id="请输入登录IP地址!" defaultMessage="请输入登录IP地址!" /> | |||||
| ), | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -128,7 +126,7 @@ const LogininforForm: React.FC<LogininforFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入登录地点!" defaultMessage="请输入登录地点!" />, | |||||
| message: <FormattedMessage id="请输入登录地点!" defaultMessage="请输入登录地点!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -143,7 +141,9 @@ const LogininforForm: React.FC<LogininforFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入浏览器类型!" defaultMessage="请输入浏览器类型!" />, | |||||
| message: ( | |||||
| <FormattedMessage id="请输入浏览器类型!" defaultMessage="请输入浏览器类型!" /> | |||||
| ), | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -158,7 +158,7 @@ const LogininforForm: React.FC<LogininforFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入操作系统!" defaultMessage="请输入操作系统!" />, | |||||
| message: <FormattedMessage id="请输入操作系统!" defaultMessage="请输入操作系统!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -174,7 +174,7 @@ const LogininforForm: React.FC<LogininforFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入登录状态!" defaultMessage="请输入登录状态!" />, | |||||
| message: <FormattedMessage id="请输入登录状态!" defaultMessage="请输入登录状态!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -189,7 +189,7 @@ const LogininforForm: React.FC<LogininforFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入提示消息!" defaultMessage="请输入提示消息!" />, | |||||
| message: <FormattedMessage id="请输入提示消息!" defaultMessage="请输入提示消息!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -204,7 +204,7 @@ const LogininforForm: React.FC<LogininforFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入访问时间!" defaultMessage="请输入访问时间!" />, | |||||
| message: <FormattedMessage id="请输入访问时间!" defaultMessage="请输入访问时间!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -1,13 +1,29 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | |||||
| import { Button, message, Modal } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined, UnlockOutlined } from '@ant-design/icons'; | |||||
| import { getLogininforList, removeLogininfor, exportLogininfor, unlockLogininfor, cleanLogininfor } from '@/services/monitor/logininfor'; | |||||
| import DictTag from '@/components/DictTag'; | import DictTag from '@/components/DictTag'; | ||||
| import { | |||||
| cleanLogininfor, | |||||
| exportLogininfor, | |||||
| getLogininforList, | |||||
| removeLogininfor, | |||||
| unlockLogininfor, | |||||
| } from '@/services/monitor/logininfor'; | |||||
| import { getDictValueEnum } from '@/services/system/dict'; | import { getDictValueEnum } from '@/services/system/dict'; | ||||
| import { | |||||
| DeleteOutlined, | |||||
| ExclamationCircleOutlined, | |||||
| PlusOutlined, | |||||
| UnlockOutlined, | |||||
| } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useAccess, useIntl } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | |||||
| import { Button, Modal, message } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| /** | /** | ||||
| * 删除节点 | * 删除节点 | ||||
| @@ -88,7 +104,6 @@ const handleExport = async () => { | |||||
| } | } | ||||
| }; | }; | ||||
| const LogininforTableList: React.FC = () => { | const LogininforTableList: React.FC = () => { | ||||
| const formTableRef = useRef<FormInstance>(); | const formTableRef = useRef<FormInstance>(); | ||||
| @@ -148,7 +163,7 @@ const LogininforTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: statusOptions, | valueEnum: statusOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={statusOptions} value={record.status} />); | |||||
| return <DictTag enums={statusOptions} value={record.status} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -196,7 +211,7 @@ const LogininforTableList: React.FC = () => { | |||||
| actionRef.current?.reloadAndRest?.(); | actionRef.current?.reloadAndRest?.(); | ||||
| } | } | ||||
| }, | }, | ||||
| onCancel() { }, | |||||
| onCancel() {}, | |||||
| }); | }); | ||||
| }} | }} | ||||
| > | > | ||||
| @@ -220,7 +235,7 @@ const LogininforTableList: React.FC = () => { | |||||
| actionRef.current?.reloadAndRest?.(); | actionRef.current?.reloadAndRest?.(); | ||||
| } | } | ||||
| }, | }, | ||||
| onCancel() { }, | |||||
| onCancel() {}, | |||||
| }); | }); | ||||
| }} | }} | ||||
| > | > | ||||
| @@ -243,7 +258,7 @@ const LogininforTableList: React.FC = () => { | |||||
| actionRef.current?.reloadAndRest?.(); | actionRef.current?.reloadAndRest?.(); | ||||
| } | } | ||||
| }, | }, | ||||
| onCancel() { }, | |||||
| onCancel() {}, | |||||
| }); | }); | ||||
| }} | }} | ||||
| > | > | ||||
| @@ -1,18 +1,18 @@ | |||||
| import React, { useEffect, useState } from 'react'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import IconSelector from '@/components/IconSelector'; | |||||
| import { createIcon } from '@/utils/IconUtil'; | |||||
| import { | import { | ||||
| ProForm, | ProForm, | ||||
| ProFormDigit, | ProFormDigit, | ||||
| ProFormText, | |||||
| ProFormRadio, | ProFormRadio, | ||||
| ProFormTreeSelect, | |||||
| ProFormSelect, | ProFormSelect, | ||||
| ProFormText, | |||||
| ProFormTreeSelect, | |||||
| } from '@ant-design/pro-components'; | } from '@ant-design/pro-components'; | ||||
| import { Form, Modal} from 'antd'; | |||||
| import { useIntl, FormattedMessage } from '@umijs/max'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | |||||
| import { DataNode } from 'antd/es/tree'; | import { DataNode } from 'antd/es/tree'; | ||||
| import { createIcon } from '@/utils/IconUtil'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import IconSelector from '@/components/IconSelector'; | |||||
| import React, { useEffect, useState } from 'react'; | |||||
| export type MenuFormData = Record<string, unknown> & Partial<API.System.Menu>; | export type MenuFormData = Record<string, unknown> & Partial<API.System.Menu>; | ||||
| @@ -27,7 +27,6 @@ export type MenuFormProps = { | |||||
| }; | }; | ||||
| const MenuForm: React.FC<MenuFormProps> = (props) => { | const MenuForm: React.FC<MenuFormProps> = (props) => { | ||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const [menuTypeId, setMenuTypeId] = useState<any>('M'); | const [menuTypeId, setMenuTypeId] = useState<any>('M'); | ||||
| @@ -91,7 +90,8 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||||
| grid={true} | grid={true} | ||||
| submitter={false} | submitter={false} | ||||
| layout="horizontal" | layout="horizontal" | ||||
| onFinish={handleFinish}> | |||||
| onFinish={handleFinish} | |||||
| > | |||||
| <ProFormDigit | <ProFormDigit | ||||
| name="menuId" | name="menuId" | ||||
| label={intl.formatMessage({ | label={intl.formatMessage({ | ||||
| @@ -114,7 +114,7 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||||
| id: 'system.menu.parent_id', | id: 'system.menu.parent_id', | ||||
| defaultMessage: '上级菜单', | defaultMessage: '上级菜单', | ||||
| })} | })} | ||||
| params={{menuTree}} | |||||
| params={{ menuTree }} | |||||
| request={async () => { | request={async () => { | ||||
| return menuTree; | return menuTree; | ||||
| }} | }} | ||||
| @@ -122,11 +122,13 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: <FormattedMessage id="请输入父菜单编号!" defaultMessage="请输入父菜单编号!" />, | |||||
| message: ( | |||||
| <FormattedMessage id="请输入父菜单编号!" defaultMessage="请输入父菜单编号!" /> | |||||
| ), | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| fieldProps = {{ | |||||
| defaultValue: 0 | |||||
| fieldProps={{ | |||||
| defaultValue: 0, | |||||
| }} | }} | ||||
| /> | /> | ||||
| <ProFormRadio.Group | <ProFormRadio.Group | ||||
| @@ -206,8 +208,8 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||||
| message: <FormattedMessage id="请输入显示顺序!" defaultMessage="请输入显示顺序!" />, | message: <FormattedMessage id="请输入显示顺序!" defaultMessage="请输入显示顺序!" />, | ||||
| }, | }, | ||||
| ]} | ]} | ||||
| fieldProps = {{ | |||||
| defaultValue: 1 | |||||
| fieldProps={{ | |||||
| defaultValue: 1, | |||||
| }} | }} | ||||
| /> | /> | ||||
| <ProFormRadio.Group | <ProFormRadio.Group | ||||
| @@ -227,11 +229,13 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入是否为外链!" defaultMessage="请输入是否为外链!" />, | |||||
| message: ( | |||||
| <FormattedMessage id="请输入是否为外链!" defaultMessage="请输入是否为外链!" /> | |||||
| ), | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| fieldProps = {{ | |||||
| defaultValue: '1' | |||||
| fieldProps={{ | |||||
| defaultValue: '1', | |||||
| }} | }} | ||||
| /> | /> | ||||
| <ProFormText | <ProFormText | ||||
| @@ -318,8 +322,8 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||||
| message: <FormattedMessage id="请输入是否缓存!" defaultMessage="请输入是否缓存!" />, | message: <FormattedMessage id="请输入是否缓存!" defaultMessage="请输入是否缓存!" />, | ||||
| }, | }, | ||||
| ]} | ]} | ||||
| fieldProps = {{ | |||||
| defaultValue: 0 | |||||
| fieldProps={{ | |||||
| defaultValue: 0, | |||||
| }} | }} | ||||
| /> | /> | ||||
| <ProFormRadio.Group | <ProFormRadio.Group | ||||
| @@ -338,8 +342,8 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||||
| message: <FormattedMessage id="请输入显示状态!" defaultMessage="请输入显示状态!" />, | message: <FormattedMessage id="请输入显示状态!" defaultMessage="请输入显示状态!" />, | ||||
| }, | }, | ||||
| ]} | ]} | ||||
| fieldProps = {{ | |||||
| defaultValue: '0' | |||||
| fieldProps={{ | |||||
| defaultValue: '0', | |||||
| }} | }} | ||||
| /> | /> | ||||
| <ProFormRadio.Group | <ProFormRadio.Group | ||||
| @@ -358,8 +362,8 @@ const MenuForm: React.FC<MenuFormProps> = (props) => { | |||||
| message: <FormattedMessage id="请输入菜单状态!" defaultMessage="请输入菜单状态!" />, | message: <FormattedMessage id="请输入菜单状态!" defaultMessage="请输入菜单状态!" />, | ||||
| }, | }, | ||||
| ]} | ]} | ||||
| fieldProps = {{ | |||||
| defaultValue: '0' | |||||
| fieldProps={{ | |||||
| defaultValue: '0', | |||||
| }} | }} | ||||
| /> | /> | ||||
| </ProForm> | </ProForm> | ||||
| @@ -1,15 +1,20 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess } from '@umijs/max'; | |||||
| import { Button, message, Modal } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; | |||||
| import { getMenuList, removeMenu, addMenu, updateMenu, exportMenu } from '@/services/system/menu'; | |||||
| import UpdateForm from './edit'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| import { getDictValueEnum } from '@/services/system/dict'; | import { getDictValueEnum } from '@/services/system/dict'; | ||||
| import { addMenu, exportMenu, getMenuList, removeMenu, updateMenu } from '@/services/system/menu'; | |||||
| import { buildTreeData } from '@/utils/tree'; | import { buildTreeData } from '@/utils/tree'; | ||||
| import { DeleteOutlined, ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useAccess, useIntl } from '@umijs/max'; | |||||
| import { Button, Modal, message } from 'antd'; | |||||
| import { DataNode } from 'antd/es/tree'; | import { DataNode } from 'antd/es/tree'; | ||||
| import DictTag from '@/components/DictTag'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import UpdateForm from './edit'; | |||||
| /** | /** | ||||
| * 添加节点 | * 添加节点 | ||||
| @@ -88,7 +93,7 @@ const handleRemoveOne = async (selectedRow: API.System.Menu) => { | |||||
| /** | /** | ||||
| * 导出数据 | * 导出数据 | ||||
| * | * | ||||
| * | |||||
| * | |||||
| */ | */ | ||||
| const handleExport = async () => { | const handleExport = async () => { | ||||
| const hide = message.loading('正在导出'); | const hide = message.loading('正在导出'); | ||||
| @@ -104,9 +109,7 @@ const handleExport = async () => { | |||||
| } | } | ||||
| }; | }; | ||||
| const MenuTableList: React.FC = () => { | const MenuTableList: React.FC = () => { | ||||
| const [modalVisible, setModalVisible] = useState<boolean>(false); | const [modalVisible, setModalVisible] = useState<boolean>(false); | ||||
| const actionRef = useRef<ActionType>(); | const actionRef = useRef<ActionType>(); | ||||
| @@ -123,7 +126,7 @@ const MenuTableList: React.FC = () => { | |||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| getDictValueEnum('sys_show_hide').then((data) => { | |||||
| getDictValueEnum('sys_show_hide').then((data) => { | |||||
| setVisibleOptions(data); | setVisibleOptions(data); | ||||
| }); | }); | ||||
| getDictValueEnum('sys_normal_disable').then((data) => { | getDictValueEnum('sys_normal_disable').then((data) => { | ||||
| @@ -131,7 +134,7 @@ const MenuTableList: React.FC = () => { | |||||
| }); | }); | ||||
| }, []); | }, []); | ||||
| const columns: ProColumns<API.System.Menu>[] = [ | |||||
| const columns: ProColumns<API.System.Menu>[] = [ | |||||
| { | { | ||||
| title: <FormattedMessage id="system.menu.menu_name" defaultMessage="菜单名称" />, | title: <FormattedMessage id="system.menu.menu_name" defaultMessage="菜单名称" />, | ||||
| dataIndex: 'menuName', | dataIndex: 'menuName', | ||||
| @@ -167,7 +170,7 @@ const MenuTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: statusOptions, | valueEnum: statusOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={statusOptions} value={record.status} />); | |||||
| return <DictTag enums={statusOptions} value={record.status} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -245,7 +248,7 @@ const MenuTableList: React.FC = () => { | |||||
| </Button>, | </Button>, | ||||
| <Button | <Button | ||||
| type="primary" | type="primary" | ||||
| key="remove" | |||||
| key="remove" | |||||
| hidden={selectedRows?.length === 0 || !access.hasPerms('system:menu:remove')} | hidden={selectedRows?.length === 0 || !access.hasPerms('system:menu:remove')} | ||||
| onClick={async () => { | onClick={async () => { | ||||
| Modal.confirm({ | Modal.confirm({ | ||||
| @@ -260,7 +263,7 @@ const MenuTableList: React.FC = () => { | |||||
| } | } | ||||
| }, | }, | ||||
| onCancel() {}, | onCancel() {}, | ||||
| }); | |||||
| }); | |||||
| }} | }} | ||||
| > | > | ||||
| <DeleteOutlined /> | <DeleteOutlined /> | ||||
| @@ -1,15 +1,15 @@ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import { | import { | ||||
| ProForm, | ProForm, | ||||
| ProFormDigit, | ProFormDigit, | ||||
| ProFormText, | |||||
| ProFormRadio, | |||||
| ProFormSelect, | ProFormSelect, | ||||
| ProFormText, | |||||
| ProFormTextArea, | ProFormTextArea, | ||||
| ProFormRadio, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { Form, Modal} from 'antd'; | |||||
| import { useIntl, FormattedMessage } from '@umijs/max'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | |||||
| import React, { useEffect } from 'react'; | |||||
| export type NoticeFormData = Record<string, unknown> & Partial<API.System.Notice>; | export type NoticeFormData = Record<string, unknown> & Partial<API.System.Notice>; | ||||
| @@ -24,22 +24,22 @@ export type NoticeFormProps = { | |||||
| const NoticeForm: React.FC<NoticeFormProps> = (props) => { | const NoticeForm: React.FC<NoticeFormProps> = (props) => { | ||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const { noticeTypeOptions,statusOptions, } = props; | |||||
| const { noticeTypeOptions, statusOptions } = props; | |||||
| useEffect(() => { | useEffect(() => { | ||||
| form.resetFields(); | form.resetFields(); | ||||
| form.setFieldsValue({ | form.setFieldsValue({ | ||||
| noticeId: props.values.noticeId, | |||||
| noticeTitle: props.values.noticeTitle, | |||||
| noticeType: props.values.noticeType, | |||||
| noticeContent: props.values.noticeContent, | |||||
| status: props.values.status, | |||||
| createBy: props.values.createBy, | |||||
| createTime: props.values.createTime, | |||||
| updateBy: props.values.updateBy, | |||||
| updateTime: props.values.updateTime, | |||||
| remark: props.values.remark, | |||||
| noticeId: props.values.noticeId, | |||||
| noticeTitle: props.values.noticeTitle, | |||||
| noticeType: props.values.noticeType, | |||||
| noticeContent: props.values.noticeContent, | |||||
| status: props.values.status, | |||||
| createBy: props.values.createBy, | |||||
| createTime: props.values.createTime, | |||||
| updateBy: props.values.updateBy, | |||||
| updateTime: props.values.updateTime, | |||||
| remark: props.values.remark, | |||||
| }); | }); | ||||
| }, [form, props]); | }, [form, props]); | ||||
| @@ -67,12 +67,13 @@ const NoticeForm: React.FC<NoticeFormProps> = (props) => { | |||||
| onOk={handleOk} | onOk={handleOk} | ||||
| onCancel={handleCancel} | onCancel={handleCancel} | ||||
| > | > | ||||
| <ProForm | |||||
| <ProForm | |||||
| form={form} | form={form} | ||||
| grid={true} | grid={true} | ||||
| submitter={false} | submitter={false} | ||||
| layout="horizontal" | |||||
| onFinish={handleFinish}> | |||||
| layout="horizontal" | |||||
| onFinish={handleFinish} | |||||
| > | |||||
| <ProFormDigit | <ProFormDigit | ||||
| name="noticeId" | name="noticeId" | ||||
| label={intl.formatMessage({ | label={intl.formatMessage({ | ||||
| @@ -86,7 +87,7 @@ const NoticeForm: React.FC<NoticeFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入公告编号!" defaultMessage="请输入公告编号!" />, | |||||
| message: <FormattedMessage id="请输入公告编号!" defaultMessage="请输入公告编号!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -100,7 +101,7 @@ const NoticeForm: React.FC<NoticeFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: <FormattedMessage id="请输入公告标题!" defaultMessage="请输入公告标题!" />, | |||||
| message: <FormattedMessage id="请输入公告标题!" defaultMessage="请输入公告标题!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -116,7 +117,7 @@ const NoticeForm: React.FC<NoticeFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: <FormattedMessage id="请输入公告类型!" defaultMessage="请输入公告类型!" />, | |||||
| message: <FormattedMessage id="请输入公告类型!" defaultMessage="请输入公告类型!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -132,7 +133,7 @@ const NoticeForm: React.FC<NoticeFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入公告状态!" defaultMessage="请输入公告状态!" />, | |||||
| message: <FormattedMessage id="请输入公告状态!" defaultMessage="请输入公告状态!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -147,7 +148,7 @@ const NoticeForm: React.FC<NoticeFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入公告内容!" defaultMessage="请输入公告内容!" />, | |||||
| message: <FormattedMessage id="请输入公告内容!" defaultMessage="请输入公告内容!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -162,7 +163,7 @@ const NoticeForm: React.FC<NoticeFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入备注!" defaultMessage="请输入备注!" />, | |||||
| message: <FormattedMessage id="请输入备注!" defaultMessage="请输入备注!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -1,14 +1,25 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess } from '@umijs/max'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import { | |||||
| addNotice, | |||||
| exportNotice, | |||||
| getNoticeList, | |||||
| removeNotice, | |||||
| updateNotice, | |||||
| } from '@/services/system/notice'; | |||||
| import { DeleteOutlined, ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useAccess, useIntl } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | import type { FormInstance } from 'antd'; | ||||
| import { Button, message, Modal } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; | |||||
| import { getNoticeList, removeNotice, addNotice, updateNotice, exportNotice } from '@/services/system/notice'; | |||||
| import { Button, Modal, message } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import UpdateForm from './edit'; | import UpdateForm from './edit'; | ||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| /** | /** | ||||
| * 添加节点 | * 添加节点 | ||||
| @@ -103,7 +114,7 @@ const handleRemoveOne = async (selectedRow: API.System.Notice) => { | |||||
| /** | /** | ||||
| * 导出数据 | * 导出数据 | ||||
| * | * | ||||
| * | |||||
| * | |||||
| */ | */ | ||||
| const handleExport = async () => { | const handleExport = async () => { | ||||
| const hide = message.loading('正在导出'); | const hide = message.loading('正在导出'); | ||||
| @@ -119,9 +130,8 @@ const handleExport = async () => { | |||||
| } | } | ||||
| }; | }; | ||||
| const NoticeTableList: React.FC = () => { | const NoticeTableList: React.FC = () => { | ||||
| const formTableRef = useRef<FormInstance>(); | |||||
| const formTableRef = useRef<FormInstance>(); | |||||
| const [modalVisible, setModalVisible] = useState<boolean>(false); | const [modalVisible, setModalVisible] = useState<boolean>(false); | ||||
| @@ -137,16 +147,16 @@ const NoticeTableList: React.FC = () => { | |||||
| /** 国际化配置 */ | /** 国际化配置 */ | ||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| useEffect(() => { | |||||
| useEffect(() => { | |||||
| getDictValueEnum('sys_notice_type').then((data) => { | getDictValueEnum('sys_notice_type').then((data) => { | ||||
| setNoticeTypeOptions(data); | setNoticeTypeOptions(data); | ||||
| }); | |||||
| }); | |||||
| getDictValueEnum('sys_notice_status').then((data) => { | getDictValueEnum('sys_notice_status').then((data) => { | ||||
| setStatusOptions(data); | setStatusOptions(data); | ||||
| }); | }); | ||||
| }, []); | }, []); | ||||
| const columns: ProColumns<API.System.Notice>[] = [ | |||||
| const columns: ProColumns<API.System.Notice>[] = [ | |||||
| { | { | ||||
| title: <FormattedMessage id="system.notice.notice_id" defaultMessage="公告编号" />, | title: <FormattedMessage id="system.notice.notice_id" defaultMessage="公告编号" />, | ||||
| dataIndex: 'noticeId', | dataIndex: 'noticeId', | ||||
| @@ -176,7 +186,7 @@ const NoticeTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: statusOptions, | valueEnum: statusOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={statusOptions} value={record.status} />); | |||||
| return <DictTag enums={statusOptions} value={record.status} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -190,7 +200,7 @@ const NoticeTableList: React.FC = () => { | |||||
| dataIndex: 'createTime', | dataIndex: 'createTime', | ||||
| valueType: 'dateRange', | valueType: 'dateRange', | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<span>{record.createTime.toString()} </span>); | |||||
| return <span>{record.createTime.toString()} </span>; | |||||
| }, | }, | ||||
| search: { | search: { | ||||
| transform: (value) => { | transform: (value) => { | ||||
| @@ -277,7 +287,7 @@ const NoticeTableList: React.FC = () => { | |||||
| </Button>, | </Button>, | ||||
| <Button | <Button | ||||
| type="primary" | type="primary" | ||||
| key="remove" | |||||
| key="remove" | |||||
| hidden={selectedRows?.length === 0 || !access.hasPerms('system:notice:remove')} | hidden={selectedRows?.length === 0 || !access.hasPerms('system:notice:remove')} | ||||
| onClick={async () => { | onClick={async () => { | ||||
| Modal.confirm({ | Modal.confirm({ | ||||
| @@ -292,7 +302,7 @@ const NoticeTableList: React.FC = () => { | |||||
| } | } | ||||
| }, | }, | ||||
| onCancel() {}, | onCancel() {}, | ||||
| }); | |||||
| }); | |||||
| }} | }} | ||||
| > | > | ||||
| <DeleteOutlined /> | <DeleteOutlined /> | ||||
| @@ -1,8 +1,8 @@ | |||||
| import React from 'react'; | |||||
| import { Descriptions, Modal } from 'antd'; | |||||
| import { useIntl, FormattedMessage } from '@umijs/max'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | import { DictValueEnumObj } from '@/components/DictTag'; | ||||
| import { getValueEnumLabel } from '@/utils/options'; | import { getValueEnumLabel } from '@/utils/options'; | ||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Descriptions, Modal } from 'antd'; | |||||
| import React from 'react'; | |||||
| export type OperlogFormData = Record<string, unknown> & Partial<API.Monitor.Operlog>; | export type OperlogFormData = Record<string, unknown> & Partial<API.Monitor.Operlog>; | ||||
| @@ -17,12 +17,11 @@ export type OperlogFormProps = { | |||||
| }; | }; | ||||
| const OperlogDetailForm: React.FC<OperlogFormProps> = (props) => { | const OperlogDetailForm: React.FC<OperlogFormProps> = (props) => { | ||||
| const { values, businessTypeOptions, operatorTypeOptions, statusOptions, } = props; | |||||
| const { values, businessTypeOptions, operatorTypeOptions, statusOptions } = props; | |||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const handleOk = () => { | const handleOk = () => { | ||||
| console.log("handle ok"); | |||||
| console.log('handle ok'); | |||||
| }; | }; | ||||
| const handleCancel = () => { | const handleCancel = () => { | ||||
| props.onCancel(); | props.onCancel(); | ||||
| @@ -1,14 +1,25 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess } from '@umijs/max'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| import { | |||||
| addOperlog, | |||||
| exportOperlog, | |||||
| getOperlogList, | |||||
| removeOperlog, | |||||
| updateOperlog, | |||||
| } from '@/services/monitor/operlog'; | |||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import { DeleteOutlined, ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useAccess, useIntl } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | import type { FormInstance } from 'antd'; | ||||
| import { Button, message, Modal } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; | |||||
| import { getOperlogList, removeOperlog, addOperlog, updateOperlog, exportOperlog } from '@/services/monitor/operlog'; | |||||
| import { Button, Modal, message } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import UpdateForm from './detail'; | import UpdateForm from './detail'; | ||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| /** | /** | ||||
| * 添加节点 | * 添加节点 | ||||
| @@ -79,12 +90,11 @@ const handleRemove = async (selectedRows: API.Monitor.Operlog[]) => { | |||||
| return false; | return false; | ||||
| } | } | ||||
| }; | }; | ||||
| /** | /** | ||||
| * 导出数据 | * 导出数据 | ||||
| * | * | ||||
| * | |||||
| * | |||||
| */ | */ | ||||
| const handleExport = async () => { | const handleExport = async () => { | ||||
| const hide = message.loading('正在导出'); | const hide = message.loading('正在导出'); | ||||
| @@ -100,7 +110,6 @@ const handleExport = async () => { | |||||
| } | } | ||||
| }; | }; | ||||
| const OperlogTableList: React.FC = () => { | const OperlogTableList: React.FC = () => { | ||||
| const formTableRef = useRef<FormInstance>(); | const formTableRef = useRef<FormInstance>(); | ||||
| @@ -149,7 +158,7 @@ const OperlogTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: businessTypeOptions, | valueEnum: businessTypeOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={businessTypeOptions} value={record.businessType} />); | |||||
| return <DictTag enums={businessTypeOptions} value={record.businessType} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -163,7 +172,7 @@ const OperlogTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: operatorTypeOptions, | valueEnum: operatorTypeOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={operatorTypeOptions} value={record.operatorType} />); | |||||
| return <DictTag enums={operatorTypeOptions} value={record.operatorType} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -187,7 +196,7 @@ const OperlogTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: statusOptions, | valueEnum: statusOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag key="status" enums={statusOptions} value={record.status} />); | |||||
| return <DictTag key="status" enums={statusOptions} value={record.status} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -260,7 +269,7 @@ const OperlogTableList: React.FC = () => { | |||||
| actionRef.current?.reloadAndRest?.(); | actionRef.current?.reloadAndRest?.(); | ||||
| } | } | ||||
| }, | }, | ||||
| onCancel() { }, | |||||
| onCancel() {}, | |||||
| }); | }); | ||||
| }} | }} | ||||
| > | > | ||||
| @@ -1,14 +1,14 @@ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import { | import { | ||||
| ProForm, | ProForm, | ||||
| ProFormDigit, | ProFormDigit, | ||||
| ProFormText, | |||||
| ProFormRadio, | ProFormRadio, | ||||
| ProFormText, | |||||
| ProFormTextArea, | ProFormTextArea, | ||||
| } from '@ant-design/pro-components'; | |||||
| import { Form, Modal} from 'antd'; | |||||
| import { useIntl, FormattedMessage } from '@umijs/max'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | |||||
| import React, { useEffect } from 'react'; | |||||
| export type PostFormData = Record<string, unknown> & Partial<API.System.Post>; | export type PostFormData = Record<string, unknown> & Partial<API.System.Post>; | ||||
| @@ -23,21 +23,21 @@ export type PostFormProps = { | |||||
| const PostForm: React.FC<PostFormProps> = (props) => { | const PostForm: React.FC<PostFormProps> = (props) => { | ||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const { statusOptions, } = props; | |||||
| const { statusOptions } = props; | |||||
| useEffect(() => { | useEffect(() => { | ||||
| form.resetFields(); | form.resetFields(); | ||||
| form.setFieldsValue({ | form.setFieldsValue({ | ||||
| postId: props.values.postId, | |||||
| postCode: props.values.postCode, | |||||
| postName: props.values.postName, | |||||
| postSort: props.values.postSort, | |||||
| status: props.values.status, | |||||
| createBy: props.values.createBy, | |||||
| createTime: props.values.createTime, | |||||
| updateBy: props.values.updateBy, | |||||
| updateTime: props.values.updateTime, | |||||
| remark: props.values.remark, | |||||
| postId: props.values.postId, | |||||
| postCode: props.values.postCode, | |||||
| postName: props.values.postName, | |||||
| postSort: props.values.postSort, | |||||
| status: props.values.status, | |||||
| createBy: props.values.createBy, | |||||
| createTime: props.values.createTime, | |||||
| updateBy: props.values.updateBy, | |||||
| updateTime: props.values.updateTime, | |||||
| remark: props.values.remark, | |||||
| }); | }); | ||||
| }, [form, props]); | }, [form, props]); | ||||
| @@ -65,12 +65,13 @@ const PostForm: React.FC<PostFormProps> = (props) => { | |||||
| onOk={handleOk} | onOk={handleOk} | ||||
| onCancel={handleCancel} | onCancel={handleCancel} | ||||
| > | > | ||||
| <ProForm | |||||
| <ProForm | |||||
| form={form} | form={form} | ||||
| grid={true} | grid={true} | ||||
| submitter={false} | submitter={false} | ||||
| layout="horizontal" | |||||
| onFinish={handleFinish}> | |||||
| layout="horizontal" | |||||
| onFinish={handleFinish} | |||||
| > | |||||
| <ProFormDigit | <ProFormDigit | ||||
| name="postId" | name="postId" | ||||
| label={intl.formatMessage({ | label={intl.formatMessage({ | ||||
| @@ -83,7 +84,7 @@ const PostForm: React.FC<PostFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入岗位编号!" defaultMessage="请输入岗位编号!" />, | |||||
| message: <FormattedMessage id="请输入岗位编号!" defaultMessage="请输入岗位编号!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -97,7 +98,7 @@ const PostForm: React.FC<PostFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: <FormattedMessage id="请输入岗位名称!" defaultMessage="请输入岗位名称!" />, | |||||
| message: <FormattedMessage id="请输入岗位名称!" defaultMessage="请输入岗位名称!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -111,7 +112,7 @@ const PostForm: React.FC<PostFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: <FormattedMessage id="请输入岗位编码!" defaultMessage="请输入岗位编码!" />, | |||||
| message: <FormattedMessage id="请输入岗位编码!" defaultMessage="请输入岗位编码!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -125,7 +126,7 @@ const PostForm: React.FC<PostFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: <FormattedMessage id="请输入显示顺序!" defaultMessage="请输入显示顺序!" />, | |||||
| message: <FormattedMessage id="请输入显示顺序!" defaultMessage="请输入显示顺序!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -140,7 +141,7 @@ const PostForm: React.FC<PostFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: <FormattedMessage id="请输入状态!" defaultMessage="请输入状态!" />, | |||||
| message: <FormattedMessage id="请输入状态!" defaultMessage="请输入状态!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -154,7 +155,7 @@ const PostForm: React.FC<PostFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: <FormattedMessage id="请输入备注!" defaultMessage="请输入备注!" />, | |||||
| message: <FormattedMessage id="请输入备注!" defaultMessage="请输入备注!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -1,14 +1,19 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess } from '@umijs/max'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import { addPost, exportPost, getPostList, removePost, updatePost } from '@/services/system/post'; | |||||
| import { DeleteOutlined, ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useAccess, useIntl } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | import type { FormInstance } from 'antd'; | ||||
| import { Button, message, Modal } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; | |||||
| import { getPostList, removePost, addPost, updatePost, exportPost } from '@/services/system/post'; | |||||
| import { Button, Modal, message } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import UpdateForm from './edit'; | import UpdateForm from './edit'; | ||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import DictTag from '@/components/DictTag'; | |||||
| /** | /** | ||||
| * 添加节点 | * 添加节点 | ||||
| @@ -103,7 +108,7 @@ const handleRemoveOne = async (selectedRow: API.System.Post) => { | |||||
| /** | /** | ||||
| * 导出数据 | * 导出数据 | ||||
| * | * | ||||
| * | |||||
| * | |||||
| */ | */ | ||||
| const handleExport = async () => { | const handleExport = async () => { | ||||
| const hide = message.loading('正在导出'); | const hide = message.loading('正在导出'); | ||||
| @@ -119,9 +124,8 @@ const handleExport = async () => { | |||||
| } | } | ||||
| }; | }; | ||||
| const PostTableList: React.FC = () => { | const PostTableList: React.FC = () => { | ||||
| const formTableRef = useRef<FormInstance>(); | |||||
| const formTableRef = useRef<FormInstance>(); | |||||
| const [modalVisible, setModalVisible] = useState<boolean>(false); | const [modalVisible, setModalVisible] = useState<boolean>(false); | ||||
| @@ -142,7 +146,7 @@ const PostTableList: React.FC = () => { | |||||
| }); | }); | ||||
| }, []); | }, []); | ||||
| const columns: ProColumns<API.System.Post>[] = [ | |||||
| const columns: ProColumns<API.System.Post>[] = [ | |||||
| { | { | ||||
| title: <FormattedMessage id="system.post.post_id" defaultMessage="岗位编号" />, | title: <FormattedMessage id="system.post.post_id" defaultMessage="岗位编号" />, | ||||
| dataIndex: 'postId', | dataIndex: 'postId', | ||||
| @@ -170,7 +174,7 @@ const PostTableList: React.FC = () => { | |||||
| valueType: 'select', | valueType: 'select', | ||||
| valueEnum: statusOptions, | valueEnum: statusOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={statusOptions} value={record.status} />); | |||||
| return <DictTag enums={statusOptions} value={record.status} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -249,7 +253,7 @@ const PostTableList: React.FC = () => { | |||||
| </Button>, | </Button>, | ||||
| <Button | <Button | ||||
| type="primary" | type="primary" | ||||
| key="remove" | |||||
| key="remove" | |||||
| hidden={selectedRows?.length === 0 || !access.hasPerms('system:post:remove')} | hidden={selectedRows?.length === 0 || !access.hasPerms('system:post:remove')} | ||||
| onClick={async () => { | onClick={async () => { | ||||
| Modal.confirm({ | Modal.confirm({ | ||||
| @@ -264,7 +268,7 @@ const PostTableList: React.FC = () => { | |||||
| } | } | ||||
| }, | }, | ||||
| onCancel() {}, | onCancel() {}, | ||||
| }); | |||||
| }); | |||||
| }} | }} | ||||
| > | > | ||||
| <DeleteOutlined /> | <DeleteOutlined /> | ||||
| @@ -1,14 +1,24 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess, history, useParams } from '@umijs/max'; | |||||
| import { Button, Modal, message } from 'antd'; | |||||
| import { ActionType, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined, RollbackOutlined } from '@ant-design/icons'; | |||||
| import { authUserSelectAll, authUserCancel, authUserCancelAll, allocatedUserList, unallocatedUserList } from '@/services/system/role'; | |||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import DictTag from '@/components/DictTag'; | import DictTag from '@/components/DictTag'; | ||||
| import UserSelectorModal from './components/UserSelectorModal'; | |||||
| import { HttpResult } from '@/enums/httpEnum'; | import { HttpResult } from '@/enums/httpEnum'; | ||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import { | |||||
| allocatedUserList, | |||||
| authUserCancel, | |||||
| authUserCancelAll, | |||||
| authUserSelectAll, | |||||
| unallocatedUserList, | |||||
| } from '@/services/system/role'; | |||||
| import { | |||||
| DeleteOutlined, | |||||
| ExclamationCircleOutlined, | |||||
| PlusOutlined, | |||||
| RollbackOutlined, | |||||
| } from '@ant-design/icons'; | |||||
| import { ActionType, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, history, useAccess, useIntl, useParams } from '@umijs/max'; | |||||
| import { Button, Modal, message } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import UserSelectorModal from './components/UserSelectorModal'; | |||||
| /** | /** | ||||
| * 删除节点 | * 删除节点 | ||||
| @@ -16,258 +26,257 @@ import { HttpResult } from '@/enums/httpEnum'; | |||||
| * @param selectedRows | * @param selectedRows | ||||
| */ | */ | ||||
| const cancelAuthUserAll = async (roleId: string, selectedRows: API.System.User[]) => { | const cancelAuthUserAll = async (roleId: string, selectedRows: API.System.User[]) => { | ||||
| const hide = message.loading('正在取消授权'); | |||||
| if (!selectedRows) return true; | |||||
| try { | |||||
| const userIds = selectedRows.map((row) => row.userId).join(','); | |||||
| const resp = await authUserCancelAll({roleId, userIds}); | |||||
| hide(); | |||||
| if (resp.code === 200) { | |||||
| message.success('取消授权成功,即将刷新'); | |||||
| } else { | |||||
| message.error(resp.msg); | |||||
| } | |||||
| return true; | |||||
| } catch (error) { | |||||
| hide(); | |||||
| message.error('取消授权失败,请重试'); | |||||
| return false; | |||||
| } | |||||
| const hide = message.loading('正在取消授权'); | |||||
| if (!selectedRows) return true; | |||||
| try { | |||||
| const userIds = selectedRows.map((row) => row.userId).join(','); | |||||
| const resp = await authUserCancelAll({ roleId, userIds }); | |||||
| hide(); | |||||
| if (resp.code === 200) { | |||||
| message.success('取消授权成功,即将刷新'); | |||||
| } else { | |||||
| message.error(resp.msg); | |||||
| } | |||||
| return true; | |||||
| } catch (error) { | |||||
| hide(); | |||||
| message.error('取消授权失败,请重试'); | |||||
| return false; | |||||
| } | |||||
| }; | }; | ||||
| const cancelAuthUser = async (roleId: string, userId: number) => { | const cancelAuthUser = async (roleId: string, userId: number) => { | ||||
| const hide = message.loading('正在取消授权'); | |||||
| try { | |||||
| const resp = await authUserCancel({ userId, roleId }); | |||||
| hide(); | |||||
| if (resp.code === 200) { | |||||
| message.success('取消授权成功,即将刷新'); | |||||
| } else { | |||||
| message.error(resp.msg); | |||||
| } | |||||
| return true; | |||||
| } catch (error) { | |||||
| hide(); | |||||
| message.error('取消授权失败,请重试'); | |||||
| return false; | |||||
| } | |||||
| const hide = message.loading('正在取消授权'); | |||||
| try { | |||||
| const resp = await authUserCancel({ userId, roleId }); | |||||
| hide(); | |||||
| if (resp.code === 200) { | |||||
| message.success('取消授权成功,即将刷新'); | |||||
| } else { | |||||
| message.error(resp.msg); | |||||
| } | |||||
| return true; | |||||
| } catch (error) { | |||||
| hide(); | |||||
| message.error('取消授权失败,请重试'); | |||||
| return false; | |||||
| } | |||||
| }; | }; | ||||
| const AuthUserTableList: React.FC = () => { | const AuthUserTableList: React.FC = () => { | ||||
| const [modalVisible, setModalVisible] = useState<boolean>(false); | |||||
| const [modalVisible, setModalVisible] = useState<boolean>(false); | |||||
| const actionRef = useRef<ActionType>(); | |||||
| const [selectedRows, setSelectedRows] = useState<API.System.User[]>([]); | |||||
| const [statusOptions, setStatusOptions] = useState<any>([]); | |||||
| const actionRef = useRef<ActionType>(); | |||||
| const [selectedRows, setSelectedRows] = useState<API.System.User[]>([]); | |||||
| const [statusOptions, setStatusOptions] = useState<any>([]); | |||||
| const access = useAccess(); | |||||
| const access = useAccess(); | |||||
| /** 国际化配置 */ | |||||
| const intl = useIntl(); | |||||
| /** 国际化配置 */ | |||||
| const intl = useIntl(); | |||||
| const params = useParams(); | |||||
| if (params.id === undefined) { | |||||
| history.back(); | |||||
| } | |||||
| const roleId = params.id || '0'; | |||||
| const params = useParams(); | |||||
| if (params.id === undefined) { | |||||
| history.back(); | |||||
| } | |||||
| const roleId = params.id || '0'; | |||||
| useEffect(() => { | |||||
| getDictValueEnum('sys_normal_disable').then((data) => { | |||||
| setStatusOptions(data); | |||||
| }); | |||||
| }, []); | |||||
| useEffect(() => { | |||||
| getDictValueEnum('sys_normal_disable').then((data) => { | |||||
| setStatusOptions(data); | |||||
| }); | |||||
| }, []); | |||||
| const columns: ProColumns<API.System.User>[] = [ | |||||
| { | |||||
| title: <FormattedMessage id="system.user.user_id" defaultMessage="用户编号" />, | |||||
| dataIndex: 'deptId', | |||||
| valueType: 'text', | |||||
| }, | |||||
| { | |||||
| title: <FormattedMessage id="system.user.user_name" defaultMessage="用户账号" />, | |||||
| dataIndex: 'userName', | |||||
| valueType: 'text', | |||||
| }, | |||||
| { | |||||
| title: <FormattedMessage id="system.user.nick_name" defaultMessage="用户昵称" />, | |||||
| dataIndex: 'nickName', | |||||
| valueType: 'text', | |||||
| }, | |||||
| { | |||||
| title: <FormattedMessage id="system.user.phonenumber" defaultMessage="手机号码" />, | |||||
| dataIndex: 'phonenumber', | |||||
| valueType: 'text', | |||||
| }, | |||||
| { | |||||
| title: <FormattedMessage id="system.role.create_time" defaultMessage="创建时间" />, | |||||
| dataIndex: 'createTime', | |||||
| valueType: 'dateRange', | |||||
| render: (_, record) => { | |||||
| return (<span>{record.createTime.toString()} </span>); | |||||
| }, | |||||
| hideInSearch: true, | |||||
| }, | |||||
| { | |||||
| title: <FormattedMessage id="system.user.status" defaultMessage="帐号状态" />, | |||||
| dataIndex: 'status', | |||||
| valueType: 'select', | |||||
| valueEnum: statusOptions, | |||||
| render: (_, record) => { | |||||
| return (<DictTag enums={statusOptions} value={record.status} />); | |||||
| }, | |||||
| }, | |||||
| { | |||||
| title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="操作" />, | |||||
| dataIndex: 'option', | |||||
| width: '60px', | |||||
| valueType: 'option', | |||||
| render: (_, record) => [ | |||||
| <Button | |||||
| type="link" | |||||
| size="small" | |||||
| danger | |||||
| icon={<DeleteOutlined />} | |||||
| key="remove" | |||||
| hidden={!access.hasPerms('system:role:remove')} | |||||
| onClick={async () => { | |||||
| Modal.confirm({ | |||||
| title: '删除', | |||||
| content: '确认要取消该用户' + record.userName + '"角色授权吗?', | |||||
| okText: '确认', | |||||
| cancelText: '取消', | |||||
| onOk: async () => { | |||||
| const success = await cancelAuthUser(roleId, record.userId); | |||||
| if (success) { | |||||
| if (actionRef.current) { | |||||
| actionRef.current.reload(); | |||||
| } | |||||
| } | |||||
| }, | |||||
| }); | |||||
| }} | |||||
| > | |||||
| 取消授权 | |||||
| </Button>, | |||||
| ], | |||||
| }, | |||||
| ]; | |||||
| const columns: ProColumns<API.System.User>[] = [ | |||||
| { | |||||
| title: <FormattedMessage id="system.user.user_id" defaultMessage="用户编号" />, | |||||
| dataIndex: 'deptId', | |||||
| valueType: 'text', | |||||
| }, | |||||
| { | |||||
| title: <FormattedMessage id="system.user.user_name" defaultMessage="用户账号" />, | |||||
| dataIndex: 'userName', | |||||
| valueType: 'text', | |||||
| }, | |||||
| { | |||||
| title: <FormattedMessage id="system.user.nick_name" defaultMessage="用户昵称" />, | |||||
| dataIndex: 'nickName', | |||||
| valueType: 'text', | |||||
| }, | |||||
| { | |||||
| title: <FormattedMessage id="system.user.phonenumber" defaultMessage="手机号码" />, | |||||
| dataIndex: 'phonenumber', | |||||
| valueType: 'text', | |||||
| }, | |||||
| { | |||||
| title: <FormattedMessage id="system.role.create_time" defaultMessage="创建时间" />, | |||||
| dataIndex: 'createTime', | |||||
| valueType: 'dateRange', | |||||
| render: (_, record) => { | |||||
| return <span>{record.createTime.toString()} </span>; | |||||
| }, | |||||
| hideInSearch: true, | |||||
| }, | |||||
| { | |||||
| title: <FormattedMessage id="system.user.status" defaultMessage="帐号状态" />, | |||||
| dataIndex: 'status', | |||||
| valueType: 'select', | |||||
| valueEnum: statusOptions, | |||||
| render: (_, record) => { | |||||
| return <DictTag enums={statusOptions} value={record.status} />; | |||||
| }, | |||||
| }, | |||||
| { | |||||
| title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="操作" />, | |||||
| dataIndex: 'option', | |||||
| width: '60px', | |||||
| valueType: 'option', | |||||
| render: (_, record) => [ | |||||
| <Button | |||||
| type="link" | |||||
| size="small" | |||||
| danger | |||||
| icon={<DeleteOutlined />} | |||||
| key="remove" | |||||
| hidden={!access.hasPerms('system:role:remove')} | |||||
| onClick={async () => { | |||||
| Modal.confirm({ | |||||
| title: '删除', | |||||
| content: '确认要取消该用户' + record.userName + '"角色授权吗?', | |||||
| okText: '确认', | |||||
| cancelText: '取消', | |||||
| onOk: async () => { | |||||
| const success = await cancelAuthUser(roleId, record.userId); | |||||
| if (success) { | |||||
| if (actionRef.current) { | |||||
| actionRef.current.reload(); | |||||
| } | |||||
| } | |||||
| }, | |||||
| }); | |||||
| }} | |||||
| > | |||||
| 取消授权 | |||||
| </Button>, | |||||
| ], | |||||
| }, | |||||
| ]; | |||||
| return ( | |||||
| <PageContainer> | |||||
| <div style={{ width: '100%', float: 'right' }}> | |||||
| <ProTable<API.System.User> | |||||
| headerTitle={intl.formatMessage({ | |||||
| id: 'pages.searchTable.title', | |||||
| defaultMessage: '信息', | |||||
| })} | |||||
| actionRef={actionRef} | |||||
| rowKey="userId" | |||||
| key="userList" | |||||
| search={{ | |||||
| labelWidth: 120, | |||||
| }} | |||||
| toolBarRender={() => [ | |||||
| <Button | |||||
| type="primary" | |||||
| key="add" | |||||
| hidden={!access.hasPerms('system:role:add')} | |||||
| onClick={async () => { | |||||
| setModalVisible(true); | |||||
| }} | |||||
| > | |||||
| <PlusOutlined /> <FormattedMessage id="system.role.auth.addUser" defaultMessage="添加用户" /> | |||||
| </Button>, | |||||
| <Button | |||||
| type="primary" | |||||
| key="remove" | |||||
| hidden={selectedRows?.length === 0 || !access.hasPerms('system:role:remove')} | |||||
| onClick={async () => { | |||||
| Modal.confirm({ | |||||
| title: '是否确认删除所选数据项?', | |||||
| icon: <ExclamationCircleOutlined />, | |||||
| content: '请谨慎操作', | |||||
| async onOk() { | |||||
| const success = await cancelAuthUserAll(roleId, selectedRows); | |||||
| if (success) { | |||||
| setSelectedRows([]); | |||||
| actionRef.current?.reloadAndRest?.(); | |||||
| } | |||||
| }, | |||||
| onCancel() { }, | |||||
| }); | |||||
| }} | |||||
| > | |||||
| <DeleteOutlined /> | |||||
| <FormattedMessage id="system.role.auth.cancelAll" defaultMessage="批量取消授权" /> | |||||
| </Button>, | |||||
| <Button | |||||
| type="primary" | |||||
| key="back" | |||||
| onClick={async () => { | |||||
| history.back(); | |||||
| }} | |||||
| > | |||||
| <RollbackOutlined /> | |||||
| <FormattedMessage id="pages.goback" defaultMessage="返回" /> | |||||
| </Button>, | |||||
| ]} | |||||
| request={(params) => | |||||
| allocatedUserList({ ...params, roleId } as API.System.RoleListParams).then((res) => { | |||||
| const result = { | |||||
| data: res.rows, | |||||
| total: res.total, | |||||
| success: true, | |||||
| }; | |||||
| return result; | |||||
| }) | |||||
| } | |||||
| columns={columns} | |||||
| rowSelection={{ | |||||
| onChange: (_, selectedRows) => { | |||||
| setSelectedRows(selectedRows); | |||||
| }, | |||||
| }} | |||||
| /> | |||||
| </div> | |||||
| <UserSelectorModal | |||||
| open={modalVisible} | |||||
| onSubmit={(values: React.Key[]) => { | |||||
| const userIds = values.join(","); | |||||
| if (userIds === "") { | |||||
| message.warning("请选择要分配的用户"); | |||||
| return; | |||||
| } | |||||
| authUserSelectAll({ roleId: roleId, userIds: userIds }).then(resp => { | |||||
| if (resp.code === HttpResult.SUCCESS) { | |||||
| message.success('更新成功!'); | |||||
| if (actionRef.current) { | |||||
| actionRef.current.reload(); | |||||
| } | |||||
| } else { | |||||
| message.warning(resp.msg); | |||||
| } | |||||
| }) | |||||
| setModalVisible(false); | |||||
| }} | |||||
| onCancel={() => { | |||||
| setModalVisible(false); | |||||
| }} | |||||
| params={{roleId}} | |||||
| request={(params) => | |||||
| unallocatedUserList({ ...params } as API.System.RoleListParams).then((res) => { | |||||
| const result = { | |||||
| data: res.rows, | |||||
| total: res.rows.length, | |||||
| success: true, | |||||
| }; | |||||
| return result; | |||||
| }) | |||||
| } | |||||
| /> | |||||
| </PageContainer> | |||||
| ); | |||||
| return ( | |||||
| <PageContainer> | |||||
| <div style={{ width: '100%', float: 'right' }}> | |||||
| <ProTable<API.System.User> | |||||
| headerTitle={intl.formatMessage({ | |||||
| id: 'pages.searchTable.title', | |||||
| defaultMessage: '信息', | |||||
| })} | |||||
| actionRef={actionRef} | |||||
| rowKey="userId" | |||||
| key="userList" | |||||
| search={{ | |||||
| labelWidth: 120, | |||||
| }} | |||||
| toolBarRender={() => [ | |||||
| <Button | |||||
| type="primary" | |||||
| key="add" | |||||
| hidden={!access.hasPerms('system:role:add')} | |||||
| onClick={async () => { | |||||
| setModalVisible(true); | |||||
| }} | |||||
| > | |||||
| <PlusOutlined />{' '} | |||||
| <FormattedMessage id="system.role.auth.addUser" defaultMessage="添加用户" /> | |||||
| </Button>, | |||||
| <Button | |||||
| type="primary" | |||||
| key="remove" | |||||
| hidden={selectedRows?.length === 0 || !access.hasPerms('system:role:remove')} | |||||
| onClick={async () => { | |||||
| Modal.confirm({ | |||||
| title: '是否确认删除所选数据项?', | |||||
| icon: <ExclamationCircleOutlined />, | |||||
| content: '请谨慎操作', | |||||
| async onOk() { | |||||
| const success = await cancelAuthUserAll(roleId, selectedRows); | |||||
| if (success) { | |||||
| setSelectedRows([]); | |||||
| actionRef.current?.reloadAndRest?.(); | |||||
| } | |||||
| }, | |||||
| onCancel() {}, | |||||
| }); | |||||
| }} | |||||
| > | |||||
| <DeleteOutlined /> | |||||
| <FormattedMessage id="system.role.auth.cancelAll" defaultMessage="批量取消授权" /> | |||||
| </Button>, | |||||
| <Button | |||||
| type="primary" | |||||
| key="back" | |||||
| onClick={async () => { | |||||
| history.back(); | |||||
| }} | |||||
| > | |||||
| <RollbackOutlined /> | |||||
| <FormattedMessage id="pages.goback" defaultMessage="返回" /> | |||||
| </Button>, | |||||
| ]} | |||||
| request={(params) => | |||||
| allocatedUserList({ ...params, roleId } as API.System.RoleListParams).then((res) => { | |||||
| const result = { | |||||
| data: res.rows, | |||||
| total: res.total, | |||||
| success: true, | |||||
| }; | |||||
| return result; | |||||
| }) | |||||
| } | |||||
| columns={columns} | |||||
| rowSelection={{ | |||||
| onChange: (_, selectedRows) => { | |||||
| setSelectedRows(selectedRows); | |||||
| }, | |||||
| }} | |||||
| /> | |||||
| </div> | |||||
| <UserSelectorModal | |||||
| open={modalVisible} | |||||
| onSubmit={(values: React.Key[]) => { | |||||
| const userIds = values.join(','); | |||||
| if (userIds === '') { | |||||
| message.warning('请选择要分配的用户'); | |||||
| return; | |||||
| } | |||||
| authUserSelectAll({ roleId: roleId, userIds: userIds }).then((resp) => { | |||||
| if (resp.code === HttpResult.SUCCESS) { | |||||
| message.success('更新成功!'); | |||||
| if (actionRef.current) { | |||||
| actionRef.current.reload(); | |||||
| } | |||||
| } else { | |||||
| message.warning(resp.msg); | |||||
| } | |||||
| }); | |||||
| setModalVisible(false); | |||||
| }} | |||||
| onCancel={() => { | |||||
| setModalVisible(false); | |||||
| }} | |||||
| params={{ roleId }} | |||||
| request={(params) => | |||||
| unallocatedUserList({ ...params } as API.System.RoleListParams).then((res) => { | |||||
| const result = { | |||||
| data: res.rows, | |||||
| total: res.rows.length, | |||||
| success: true, | |||||
| }; | |||||
| return result; | |||||
| }) | |||||
| } | |||||
| /> | |||||
| </PageContainer> | |||||
| ); | |||||
| }; | }; | ||||
| export default AuthUserTableList; | export default AuthUserTableList; | ||||
| @@ -1,233 +1,241 @@ | |||||
| import React, { useEffect, useState } from 'react'; | |||||
| import { Checkbox, Col, Form, Modal, Row, Tree } from 'antd'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Key, ProForm, ProFormDigit, ProFormSelect, ProFormText } from '@ant-design/pro-components'; | import { Key, ProForm, ProFormDigit, ProFormSelect, ProFormText } from '@ant-design/pro-components'; | ||||
| import { DataNode } from 'antd/es/tree'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Checkbox, Col, Form, Modal, Row, Tree } from 'antd'; | |||||
| import { CheckboxValueType } from 'antd/es/checkbox/Group'; | import { CheckboxValueType } from 'antd/es/checkbox/Group'; | ||||
| import { DataNode } from 'antd/es/tree'; | |||||
| import React, { useEffect, useState } from 'react'; | |||||
| /* * | /* * | ||||
| * | * | ||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @datetime 2023/02/06 | * @datetime 2023/02/06 | ||||
| * | |||||
| * | |||||
| * */ | * */ | ||||
| export type FormValueType = any & Partial<API.System.Dept>; | export type FormValueType = any & Partial<API.System.Dept>; | ||||
| export type DataScopeFormProps = { | export type DataScopeFormProps = { | ||||
| onCancel: (flag?: boolean, formVals?: FormValueType) => void; | |||||
| onSubmit: (values: FormValueType) => Promise<void>; | |||||
| open: boolean; | |||||
| values: Partial<API.System.Role>; | |||||
| deptTree: DataNode[]; | |||||
| deptCheckedKeys: string[]; | |||||
| onCancel: (flag?: boolean, formVals?: FormValueType) => void; | |||||
| onSubmit: (values: FormValueType) => Promise<void>; | |||||
| open: boolean; | |||||
| values: Partial<API.System.Role>; | |||||
| deptTree: DataNode[]; | |||||
| deptCheckedKeys: string[]; | |||||
| }; | }; | ||||
| const DataScopeForm: React.FC<DataScopeFormProps> = (props) => { | const DataScopeForm: React.FC<DataScopeFormProps> = (props) => { | ||||
| const [form] = Form.useForm(); | |||||
| const [form] = Form.useForm(); | |||||
| const { deptTree, deptCheckedKeys } = props; | |||||
| const [dataScopeType, setDataScopeType] = useState<string | undefined>('1'); | |||||
| const [deptIds, setDeptIds] = useState<string[] | {checked: string[], halfChecked: string[]}>([]); | |||||
| const [deptTreeExpandKey, setDeptTreeExpandKey] = useState<Key[]>([]); | |||||
| const [checkStrictly, setCheckStrictly] = useState<boolean>(true); | |||||
| const { deptTree, deptCheckedKeys } = props; | |||||
| const [dataScopeType, setDataScopeType] = useState<string | undefined>('1'); | |||||
| const [deptIds, setDeptIds] = useState<string[] | { checked: string[]; halfChecked: string[] }>( | |||||
| [], | |||||
| ); | |||||
| const [deptTreeExpandKey, setDeptTreeExpandKey] = useState<Key[]>([]); | |||||
| const [checkStrictly, setCheckStrictly] = useState<boolean>(true); | |||||
| useEffect(() => { | |||||
| setDeptIds(deptCheckedKeys); | |||||
| form.resetFields(); | |||||
| form.setFieldsValue({ | |||||
| roleId: props.values.roleId, | |||||
| roleName: props.values.roleName, | |||||
| roleKey: props.values.roleKey, | |||||
| dataScope: props.values.dataScope, | |||||
| }); | |||||
| setDataScopeType(props.values.dataScope); | |||||
| }, [props.values]); | |||||
| useEffect(() => { | |||||
| setDeptIds(deptCheckedKeys); | |||||
| form.resetFields(); | |||||
| form.setFieldsValue({ | |||||
| roleId: props.values.roleId, | |||||
| roleName: props.values.roleName, | |||||
| roleKey: props.values.roleKey, | |||||
| dataScope: props.values.dataScope, | |||||
| }); | |||||
| setDataScopeType(props.values.dataScope); | |||||
| }, [props.values]); | |||||
| const intl = useIntl(); | |||||
| const handleOk = () => { | |||||
| form.submit(); | |||||
| }; | |||||
| const handleCancel = () => { | |||||
| props.onCancel(); | |||||
| }; | |||||
| const handleFinish = async (values: Record<string, any>) => { | |||||
| props.onSubmit({ ...values, deptIds } as FormValueType); | |||||
| }; | |||||
| const intl = useIntl(); | |||||
| const handleOk = () => { | |||||
| form.submit(); | |||||
| }; | |||||
| const handleCancel = () => { | |||||
| props.onCancel(); | |||||
| }; | |||||
| const handleFinish = async (values: Record<string, any>) => { | |||||
| props.onSubmit({ ...values, deptIds } as FormValueType); | |||||
| }; | |||||
| const getAllDeptNode = (node: DataNode[]) => { | |||||
| let keys: any[] = []; | |||||
| node.forEach(value => { | |||||
| keys.push(value.key); | |||||
| if(value.children) { | |||||
| keys = keys.concat(getAllDeptNode(value.children)); | |||||
| } | |||||
| }); | |||||
| return keys; | |||||
| } | |||||
| const getAllDeptNode = (node: DataNode[]) => { | |||||
| let keys: any[] = []; | |||||
| node.forEach((value) => { | |||||
| keys.push(value.key); | |||||
| if (value.children) { | |||||
| keys = keys.concat(getAllDeptNode(value.children)); | |||||
| } | |||||
| }); | |||||
| return keys; | |||||
| }; | |||||
| const deptAllNodes = getAllDeptNode(deptTree); | |||||
| const deptAllNodes = getAllDeptNode(deptTree); | |||||
| const onDeptOptionChange = (checkedValues: CheckboxValueType[]) => { | |||||
| if (checkedValues.includes('deptExpand')) { | |||||
| setDeptTreeExpandKey(deptAllNodes); | |||||
| } else { | |||||
| setDeptTreeExpandKey([]); | |||||
| } | |||||
| if (checkedValues.includes('deptNodeAll')) { | |||||
| setDeptIds(deptAllNodes); | |||||
| } else { | |||||
| setDeptIds([]); | |||||
| } | |||||
| const onDeptOptionChange = (checkedValues: CheckboxValueType[]) => { | |||||
| if(checkedValues.includes('deptExpand')) { | |||||
| setDeptTreeExpandKey(deptAllNodes); | |||||
| } else { | |||||
| setDeptTreeExpandKey([]); | |||||
| } | |||||
| if(checkedValues.includes('deptNodeAll')) { | |||||
| setDeptIds(deptAllNodes); | |||||
| } else { | |||||
| setDeptIds([]); | |||||
| } | |||||
| if(checkedValues.includes('deptCheckStrictly')) { | |||||
| setCheckStrictly(false); | |||||
| } else { | |||||
| setCheckStrictly(true); | |||||
| } | |||||
| }; | |||||
| if (checkedValues.includes('deptCheckStrictly')) { | |||||
| setCheckStrictly(false); | |||||
| } else { | |||||
| setCheckStrictly(true); | |||||
| } | |||||
| }; | |||||
| return ( | |||||
| <Modal | |||||
| width={640} | |||||
| title={intl.formatMessage({ | |||||
| id: 'system.user.auth.role', | |||||
| defaultMessage: '分配角色', | |||||
| })} | |||||
| open={props.open} | |||||
| destroyOnClose | |||||
| forceRender | |||||
| onOk={handleOk} | |||||
| onCancel={handleCancel} | |||||
| return ( | |||||
| <Modal | |||||
| width={640} | |||||
| title={intl.formatMessage({ | |||||
| id: 'system.user.auth.role', | |||||
| defaultMessage: '分配角色', | |||||
| })} | |||||
| open={props.open} | |||||
| destroyOnClose | |||||
| forceRender | |||||
| onOk={handleOk} | |||||
| onCancel={handleCancel} | |||||
| > | |||||
| <ProForm | |||||
| form={form} | |||||
| grid={true} | |||||
| layout="horizontal" | |||||
| onFinish={handleFinish} | |||||
| initialValues={{ | |||||
| login_password: '', | |||||
| confirm_password: '', | |||||
| }} | |||||
| > | |||||
| <ProFormDigit | |||||
| name="roleId" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.role.role_id', | |||||
| defaultMessage: '角色编号', | |||||
| })} | |||||
| colProps={{ md: 12, xl: 12 }} | |||||
| placeholder="请输入角色编号" | |||||
| disabled | |||||
| hidden={true} | |||||
| rules={[ | |||||
| { | |||||
| required: false, | |||||
| message: <FormattedMessage id="请输入角色编号!" defaultMessage="请输入角色编号!" />, | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormText | |||||
| name="roleName" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.role.role_name', | |||||
| defaultMessage: '角色名称', | |||||
| })} | |||||
| disabled | |||||
| placeholder="请输入角色名称" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: <FormattedMessage id="请输入角色名称!" defaultMessage="请输入角色名称!" />, | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormText | |||||
| name="roleKey" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.role.role_key', | |||||
| defaultMessage: '权限字符串', | |||||
| })} | |||||
| disabled | |||||
| placeholder="请输入角色权限字符串" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="请输入角色权限字符串!" | |||||
| defaultMessage="请输入角色权限字符串!" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormSelect | |||||
| name="dataScope" | |||||
| label="权限范围" | |||||
| initialValue={'1'} | |||||
| placeholder="请输入用户性别" | |||||
| valueEnum={{ | |||||
| '1': '全部数据权限', | |||||
| '2': '自定数据权限', | |||||
| '3': '本部门数据权限', | |||||
| '4': '本部门及以下数据权限', | |||||
| '5': '仅本人数据权限', | |||||
| }} | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| }, | |||||
| ]} | |||||
| fieldProps={{ | |||||
| onChange: (value) => { | |||||
| setDataScopeType(value); | |||||
| }, | |||||
| }} | |||||
| /> | |||||
| <ProForm.Item | |||||
| name="deptIds" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.role.auth', | |||||
| defaultMessage: '菜单权限', | |||||
| })} | |||||
| required={dataScopeType === '1'} | |||||
| hidden={dataScopeType !== '1'} | |||||
| > | > | ||||
| <ProForm | |||||
| form={form} | |||||
| grid={true} | |||||
| layout="horizontal" | |||||
| onFinish={handleFinish} | |||||
| initialValues={{ | |||||
| login_password: '', | |||||
| confirm_password: '', | |||||
| <Row gutter={[16, 16]}> | |||||
| <Col md={24}> | |||||
| <Checkbox.Group | |||||
| options={[ | |||||
| { label: '展开/折叠', value: 'deptExpand' }, | |||||
| { label: '全选/全不选', value: 'deptNodeAll' }, | |||||
| // { label: '父子联动', value: 'deptCheckStrictly' }, | |||||
| ]} | |||||
| onChange={onDeptOptionChange} | |||||
| /> | |||||
| </Col> | |||||
| <Col md={24}> | |||||
| <Tree | |||||
| checkable={true} | |||||
| checkStrictly={checkStrictly} | |||||
| expandedKeys={deptTreeExpandKey} | |||||
| treeData={deptTree} | |||||
| checkedKeys={deptIds} | |||||
| defaultCheckedKeys={deptCheckedKeys} | |||||
| onCheck={(checkedKeys: any, checkInfo: any) => { | |||||
| console.log(checkedKeys, checkInfo); | |||||
| if (checkStrictly) { | |||||
| return setDeptIds(checkedKeys.checked); | |||||
| } else { | |||||
| return setDeptIds({ | |||||
| checked: checkedKeys, | |||||
| halfChecked: checkInfo.halfCheckedKeys, | |||||
| }); | |||||
| } | |||||
| }} | }} | ||||
| > | |||||
| <ProFormDigit | |||||
| name="roleId" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.role.role_id', | |||||
| defaultMessage: '角色编号', | |||||
| })} | |||||
| colProps={{ md: 12, xl: 12 }} | |||||
| placeholder="请输入角色编号" | |||||
| disabled | |||||
| hidden={true} | |||||
| rules={[ | |||||
| { | |||||
| required: false, | |||||
| message: <FormattedMessage id="请输入角色编号!" defaultMessage="请输入角色编号!" />, | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormText | |||||
| name="roleName" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.role.role_name', | |||||
| defaultMessage: '角色名称', | |||||
| })} | |||||
| disabled | |||||
| placeholder="请输入角色名称" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: <FormattedMessage id="请输入角色名称!" defaultMessage="请输入角色名称!" />, | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormText | |||||
| name="roleKey" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.role.role_key', | |||||
| defaultMessage: '权限字符串', | |||||
| })} | |||||
| disabled | |||||
| placeholder="请输入角色权限字符串" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: <FormattedMessage id="请输入角色权限字符串!" defaultMessage="请输入角色权限字符串!" />, | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormSelect | |||||
| name="dataScope" | |||||
| label='权限范围' | |||||
| initialValue={'1'} | |||||
| placeholder="请输入用户性别" | |||||
| valueEnum={{ | |||||
| "1": "全部数据权限", | |||||
| "2": "自定数据权限", | |||||
| "3": "本部门数据权限", | |||||
| "4": "本部门及以下数据权限", | |||||
| "5": "仅本人数据权限" | |||||
| }} | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| }, | |||||
| ]} | |||||
| fieldProps={{ | |||||
| onChange: (value) => { | |||||
| setDataScopeType(value); | |||||
| }, | |||||
| }} | |||||
| /> | |||||
| <ProForm.Item | |||||
| name="deptIds" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.role.auth', | |||||
| defaultMessage: '菜单权限', | |||||
| })} | |||||
| required={dataScopeType === '1'} | |||||
| hidden={dataScopeType !== '1'} | |||||
| > | |||||
| <Row gutter={[16, 16]}> | |||||
| <Col md={24}> | |||||
| <Checkbox.Group | |||||
| options={[ | |||||
| { label: '展开/折叠', value: 'deptExpand' }, | |||||
| { label: '全选/全不选', value: 'deptNodeAll' }, | |||||
| // { label: '父子联动', value: 'deptCheckStrictly' }, | |||||
| ]} | |||||
| onChange={onDeptOptionChange} /> | |||||
| </Col> | |||||
| <Col md={24}> | |||||
| <Tree | |||||
| checkable={true} | |||||
| checkStrictly={checkStrictly} | |||||
| expandedKeys={deptTreeExpandKey} | |||||
| treeData={deptTree} | |||||
| checkedKeys={deptIds} | |||||
| defaultCheckedKeys={deptCheckedKeys} | |||||
| onCheck={(checkedKeys: any, checkInfo: any) => { | |||||
| console.log(checkedKeys, checkInfo); | |||||
| if(checkStrictly) { | |||||
| return setDeptIds(checkedKeys.checked); | |||||
| } else { | |||||
| return setDeptIds({checked: checkedKeys, halfChecked: checkInfo.halfCheckedKeys}); | |||||
| } | |||||
| }} | |||||
| onExpand={(expandedKeys: Key[]) => { | |||||
| setDeptTreeExpandKey(deptTreeExpandKey.concat(expandedKeys)); | |||||
| }} | |||||
| /> | |||||
| </Col> | |||||
| </Row> | |||||
| </ProForm.Item> | |||||
| </ProForm> | |||||
| </Modal> | |||||
| ); | |||||
| onExpand={(expandedKeys: Key[]) => { | |||||
| setDeptTreeExpandKey(deptTreeExpandKey.concat(expandedKeys)); | |||||
| }} | |||||
| /> | |||||
| </Col> | |||||
| </Row> | |||||
| </ProForm.Item> | |||||
| </ProForm> | |||||
| </Modal> | |||||
| ); | |||||
| }; | }; | ||||
| export default DataScopeForm; | export default DataScopeForm; | ||||
| @@ -1,16 +1,21 @@ | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import { Modal } from 'antd'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { ActionType, ParamsType, ProColumns, ProTable, RequestData } from '@ant-design/pro-components'; | |||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import DictTag from '@/components/DictTag'; | import DictTag from '@/components/DictTag'; | ||||
| import { getDictValueEnum } from '@/services/system/dict'; | |||||
| import { | |||||
| ActionType, | |||||
| ParamsType, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| RequestData, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Modal } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| /* * | /* * | ||||
| * | * | ||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @datetime 2023/02/10 | * @datetime 2023/02/10 | ||||
| * | |||||
| * | |||||
| * */ | * */ | ||||
| export type DataScopeFormProps = { | export type DataScopeFormProps = { | ||||
| @@ -22,7 +27,6 @@ export type DataScopeFormProps = { | |||||
| }; | }; | ||||
| const UserSelectorModal: React.FC<DataScopeFormProps> = (props) => { | const UserSelectorModal: React.FC<DataScopeFormProps> = (props) => { | ||||
| const actionRef = useRef<ActionType>(); | const actionRef = useRef<ActionType>(); | ||||
| const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]); | const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]); | ||||
| const [statusOptions, setStatusOptions] = useState<any>([]); | const [statusOptions, setStatusOptions] = useState<any>([]); | ||||
| @@ -71,7 +75,7 @@ const UserSelectorModal: React.FC<DataScopeFormProps> = (props) => { | |||||
| hideInSearch: true, | hideInSearch: true, | ||||
| valueEnum: statusOptions, | valueEnum: statusOptions, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<DictTag enums={statusOptions} value={record.status} />); | |||||
| return <DictTag enums={statusOptions} value={record.status} />; | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -80,9 +84,9 @@ const UserSelectorModal: React.FC<DataScopeFormProps> = (props) => { | |||||
| valueType: 'dateRange', | valueType: 'dateRange', | ||||
| hideInSearch: true, | hideInSearch: true, | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<span>{record.createTime.toString()} </span>); | |||||
| return <span>{record.createTime.toString()} </span>; | |||||
| }, | }, | ||||
| } | |||||
| }, | |||||
| ]; | ]; | ||||
| return ( | return ( | ||||
| @@ -1,15 +1,15 @@ | |||||
| import React, { useEffect, useState } from 'react'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import { | import { | ||||
| ProForm, | ProForm, | ||||
| ProFormDigit, | ProFormDigit, | ||||
| ProFormText, | |||||
| ProFormRadio, | ProFormRadio, | ||||
| ProFormText, | |||||
| ProFormTextArea, | ProFormTextArea, | ||||
| } from '@ant-design/pro-components'; | } from '@ant-design/pro-components'; | ||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | import { Form, Modal } from 'antd'; | ||||
| import { useIntl, FormattedMessage } from '@umijs/max'; | |||||
| import Tree, { DataNode } from 'antd/es/tree'; | import Tree, { DataNode } from 'antd/es/tree'; | ||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import React, { useEffect, useState } from 'react'; | |||||
| export type RoleFormData = Record<string, unknown> & Partial<API.System.Role>; | export type RoleFormData = Record<string, unknown> & Partial<API.System.Role>; | ||||
| @@ -78,7 +78,8 @@ const RoleForm: React.FC<RoleFormProps> = (props) => { | |||||
| grid={true} | grid={true} | ||||
| layout="horizontal" | layout="horizontal" | ||||
| submitter={false} | submitter={false} | ||||
| onFinish={handleFinish}> | |||||
| onFinish={handleFinish} | |||||
| > | |||||
| <ProFormDigit | <ProFormDigit | ||||
| name="roleId" | name="roleId" | ||||
| label={intl.formatMessage({ | label={intl.formatMessage({ | ||||
| @@ -119,7 +120,12 @@ const RoleForm: React.FC<RoleFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: <FormattedMessage id="请输入角色权限字符串!" defaultMessage="请输入角色权限字符串!" />, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="请输入角色权限字符串!" | |||||
| defaultMessage="请输入角色权限字符串!" | |||||
| /> | |||||
| ), | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -136,8 +142,8 @@ const RoleForm: React.FC<RoleFormProps> = (props) => { | |||||
| message: <FormattedMessage id="请输入显示顺序!" defaultMessage="请输入显示顺序!" />, | message: <FormattedMessage id="请输入显示顺序!" defaultMessage="请输入显示顺序!" />, | ||||
| }, | }, | ||||
| ]} | ]} | ||||
| fieldProps = {{ | |||||
| defaultValue: 1 | |||||
| fieldProps={{ | |||||
| defaultValue: 1, | |||||
| }} | }} | ||||
| /> | /> | ||||
| <ProFormRadio.Group | <ProFormRadio.Group | ||||
| @@ -154,8 +160,8 @@ const RoleForm: React.FC<RoleFormProps> = (props) => { | |||||
| message: <FormattedMessage id="请输入角色状态!" defaultMessage="请输入角色状态!" />, | message: <FormattedMessage id="请输入角色状态!" defaultMessage="请输入角色状态!" />, | ||||
| }, | }, | ||||
| ]} | ]} | ||||
| fieldProps = {{ | |||||
| defaultValue: "0" | |||||
| fieldProps={{ | |||||
| defaultValue: '0', | |||||
| }} | }} | ||||
| /> | /> | ||||
| <ProForm.Item | <ProForm.Item | ||||
| @@ -172,7 +178,7 @@ const RoleForm: React.FC<RoleFormProps> = (props) => { | |||||
| defaultExpandAll={false} | defaultExpandAll={false} | ||||
| treeData={menuTree} | treeData={menuTree} | ||||
| defaultCheckedKeys={menuCheckedKeys} | defaultCheckedKeys={menuCheckedKeys} | ||||
| onCheck={(checkedKeys: any) => { | |||||
| onCheck={(checkedKeys: any) => { | |||||
| return setMenuIds(checkedKeys.checked); | return setMenuIds(checkedKeys.checked); | ||||
| }} | }} | ||||
| /> | /> | ||||
| @@ -1,16 +1,38 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess, history } from '@umijs/max'; | |||||
| import { DataNode } from 'antd/es/tree'; | |||||
| import { Button, message, Modal, Dropdown, FormInstance, Space, Switch } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, EditOutlined, DeleteOutlined, ExclamationCircleOutlined, DownOutlined } from '@ant-design/icons'; | |||||
| import { getRoleList, removeRole, addRole, updateRole, exportRole, getRoleMenuList, changeRoleStatus, updateRoleDataScope, getDeptTreeSelect, getRole } from '@/services/system/role'; | |||||
| import UpdateForm from './edit'; | |||||
| import { getDictValueEnum } from '@/services/system/dict'; | import { getDictValueEnum } from '@/services/system/dict'; | ||||
| import { formatTreeData } from '@/utils/tree'; | |||||
| import { getMenuTree } from '@/services/system/menu'; | import { getMenuTree } from '@/services/system/menu'; | ||||
| import { | |||||
| addRole, | |||||
| changeRoleStatus, | |||||
| exportRole, | |||||
| getDeptTreeSelect, | |||||
| getRole, | |||||
| getRoleList, | |||||
| getRoleMenuList, | |||||
| removeRole, | |||||
| updateRole, | |||||
| updateRoleDataScope, | |||||
| } from '@/services/system/role'; | |||||
| import { formatTreeData } from '@/utils/tree'; | |||||
| import { | |||||
| DeleteOutlined, | |||||
| DownOutlined, | |||||
| EditOutlined, | |||||
| ExclamationCircleOutlined, | |||||
| PlusOutlined, | |||||
| } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, history, useAccess, useIntl } from '@umijs/max'; | |||||
| import { Button, Dropdown, FormInstance, Modal, Space, Switch, message } from 'antd'; | |||||
| import { DataNode } from 'antd/es/tree'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import DataScopeForm from './components/DataScope'; | import DataScopeForm from './components/DataScope'; | ||||
| import UpdateForm from './edit'; | |||||
| const { confirm } = Modal; | const { confirm } = Modal; | ||||
| @@ -107,7 +129,7 @@ const handleRemoveOne = async (selectedRow: API.System.Role) => { | |||||
| /** | /** | ||||
| * 导出数据 | * 导出数据 | ||||
| * | * | ||||
| * | |||||
| * | |||||
| */ | */ | ||||
| const handleExport = async () => { | const handleExport = async () => { | ||||
| const hide = message.loading('正在导出'); | const hide = message.loading('正在导出'); | ||||
| @@ -123,9 +145,7 @@ const handleExport = async () => { | |||||
| } | } | ||||
| }; | }; | ||||
| const RoleTableList: React.FC = () => { | const RoleTableList: React.FC = () => { | ||||
| const [messageApi, contextHolder] = message.useMessage(); | const [messageApi, contextHolder] = message.useMessage(); | ||||
| const formTableRef = useRef<FormInstance>(); | const formTableRef = useRef<FormInstance>(); | ||||
| @@ -152,12 +172,12 @@ const RoleTableList: React.FC = () => { | |||||
| }, []); | }, []); | ||||
| const showChangeStatusConfirm = (record: API.System.Role) => { | const showChangeStatusConfirm = (record: API.System.Role) => { | ||||
| let text = record.status === "1" ? "启用" : "停用"; | |||||
| let text = record.status === '1' ? '启用' : '停用'; | |||||
| const newStatus = record.status === '0' ? '1' : '0'; | const newStatus = record.status === '0' ? '1' : '0'; | ||||
| confirm({ | confirm({ | ||||
| title: `确认要${text}${record.roleName}角色吗?`, | title: `确认要${text}${record.roleName}角色吗?`, | ||||
| onOk() { | onOk() { | ||||
| changeRoleStatus(record.roleId, newStatus).then(resp => { | |||||
| changeRoleStatus(record.roleId, newStatus).then((resp) => { | |||||
| if (resp.code === 200) { | if (resp.code === 200) { | ||||
| messageApi.open({ | messageApi.open({ | ||||
| type: 'success', | type: 'success', | ||||
| @@ -211,7 +231,8 @@ const RoleTableList: React.FC = () => { | |||||
| unCheckedChildren="停用" | unCheckedChildren="停用" | ||||
| defaultChecked | defaultChecked | ||||
| onClick={() => showChangeStatusConfirm(record)} | onClick={() => showChangeStatusConfirm(record)} | ||||
| />) | |||||
| /> | |||||
| ); | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -219,7 +240,7 @@ const RoleTableList: React.FC = () => { | |||||
| dataIndex: 'createTime', | dataIndex: 'createTime', | ||||
| valueType: 'dateRange', | valueType: 'dateRange', | ||||
| render: (_, record) => { | render: (_, record) => { | ||||
| return (<span>{record.createTime.toString()} </span>); | |||||
| return <span>{record.createTime.toString()} </span>; | |||||
| }, | }, | ||||
| search: { | search: { | ||||
| transform: (value) => { | transform: (value) => { | ||||
| @@ -247,9 +268,11 @@ const RoleTableList: React.FC = () => { | |||||
| if (res.code === 200) { | if (res.code === 200) { | ||||
| const treeData = formatTreeData(res.menus); | const treeData = formatTreeData(res.menus); | ||||
| setMenuTree(treeData); | setMenuTree(treeData); | ||||
| setMenuIds(res.checkedKeys.map(item => { | |||||
| return `${item}` | |||||
| })); | |||||
| setMenuIds( | |||||
| res.checkedKeys.map((item) => { | |||||
| return `${item}`; | |||||
| }), | |||||
| ); | |||||
| setModalVisible(true); | setModalVisible(true); | ||||
| setCurrentRow(record); | setCurrentRow(record); | ||||
| } else { | } else { | ||||
| @@ -303,25 +326,26 @@ const RoleTableList: React.FC = () => { | |||||
| ], | ], | ||||
| onClick: ({ key }: any) => { | onClick: ({ key }: any) => { | ||||
| if (key === 'datascope') { | if (key === 'datascope') { | ||||
| getRole(record.roleId).then(resp => { | |||||
| if(resp.code === 200) { | |||||
| getRole(record.roleId).then((resp) => { | |||||
| if (resp.code === 200) { | |||||
| setCurrentRow(resp.data); | setCurrentRow(resp.data); | ||||
| setDataScopeModalOpen(true); | setDataScopeModalOpen(true); | ||||
| } | } | ||||
| }) | |||||
| getDeptTreeSelect(record.roleId).then(resp => { | |||||
| }); | |||||
| getDeptTreeSelect(record.roleId).then((resp) => { | |||||
| if (resp.code === 200) { | if (resp.code === 200) { | ||||
| setMenuTree(formatTreeData(resp.depts)); | setMenuTree(formatTreeData(resp.depts)); | ||||
| setMenuIds(resp.checkedKeys.map((item:number) => { | |||||
| return `${item}` | |||||
| })); | |||||
| setMenuIds( | |||||
| resp.checkedKeys.map((item: number) => { | |||||
| return `${item}`; | |||||
| }), | |||||
| ); | |||||
| } | } | ||||
| }) | |||||
| } | |||||
| else if (key === 'authUser') { | |||||
| }); | |||||
| } else if (key === 'authUser') { | |||||
| history.push(`/system/role-auth/user/${record.roleId}`); | history.push(`/system/role-auth/user/${record.roleId}`); | ||||
| } | } | ||||
| } | |||||
| }, | |||||
| }} | }} | ||||
| > | > | ||||
| <a onClick={(e) => e.preventDefault()}> | <a onClick={(e) => e.preventDefault()}> | ||||
| @@ -388,7 +412,7 @@ const RoleTableList: React.FC = () => { | |||||
| actionRef.current?.reloadAndRest?.(); | actionRef.current?.reloadAndRest?.(); | ||||
| } | } | ||||
| }, | }, | ||||
| onCancel() { }, | |||||
| onCancel() {}, | |||||
| }); | }); | ||||
| }} | }} | ||||
| > | > | ||||
| @@ -1,81 +1,81 @@ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { Form, Modal } from 'antd'; | |||||
| import { useIntl } from '@umijs/max'; | |||||
| import { ProForm, ProFormSelect } from '@ant-design/pro-components'; | import { ProForm, ProFormSelect } from '@ant-design/pro-components'; | ||||
| import { useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | |||||
| import React, { useEffect } from 'react'; | |||||
| /* * | /* * | ||||
| * | * | ||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @datetime 2023/02/06 | * @datetime 2023/02/06 | ||||
| * | |||||
| * | |||||
| * */ | * */ | ||||
| export type FormValueType = any & Partial<API.System.Dept>; | export type FormValueType = any & Partial<API.System.Dept>; | ||||
| export type AuthRoleFormProps = { | export type AuthRoleFormProps = { | ||||
| onCancel: (flag?: boolean, formVals?: FormValueType) => void; | |||||
| onSubmit: (values: FormValueType) => Promise<void>; | |||||
| open: boolean; | |||||
| roleIds: number[]; | |||||
| roles: string[]; | |||||
| onCancel: (flag?: boolean, formVals?: FormValueType) => void; | |||||
| onSubmit: (values: FormValueType) => Promise<void>; | |||||
| open: boolean; | |||||
| roleIds: number[]; | |||||
| roles: string[]; | |||||
| }; | }; | ||||
| const AuthRoleForm: React.FC<AuthRoleFormProps> = (props) => { | const AuthRoleForm: React.FC<AuthRoleFormProps> = (props) => { | ||||
| const [form] = Form.useForm(); | |||||
| const [form] = Form.useForm(); | |||||
| useEffect(() => { | |||||
| form.resetFields(); | |||||
| form.setFieldValue( 'roleIds', props.roleIds); | |||||
| }); | |||||
| useEffect(() => { | |||||
| form.resetFields(); | |||||
| form.setFieldValue('roleIds', props.roleIds); | |||||
| }); | |||||
| const intl = useIntl(); | |||||
| const handleOk = () => { | |||||
| form.submit(); | |||||
| }; | |||||
| const handleCancel = () => { | |||||
| props.onCancel(); | |||||
| }; | |||||
| const handleFinish = async (values: Record<string, any>) => { | |||||
| props.onSubmit(values as FormValueType); | |||||
| }; | |||||
| const intl = useIntl(); | |||||
| const handleOk = () => { | |||||
| form.submit(); | |||||
| }; | |||||
| const handleCancel = () => { | |||||
| props.onCancel(); | |||||
| }; | |||||
| const handleFinish = async (values: Record<string, any>) => { | |||||
| props.onSubmit(values as FormValueType); | |||||
| }; | |||||
| return ( | |||||
| <Modal | |||||
| width={640} | |||||
| title={intl.formatMessage({ | |||||
| id: 'system.user.auth.role', | |||||
| defaultMessage: '分配角色', | |||||
| })} | |||||
| open={props.open} | |||||
| destroyOnClose | |||||
| forceRender | |||||
| onOk={handleOk} | |||||
| onCancel={handleCancel} | |||||
| > | |||||
| <ProForm | |||||
| form={form} | |||||
| grid={true} | |||||
| layout="horizontal" | |||||
| onFinish={handleFinish} | |||||
| initialValues={{ | |||||
| login_password: '', | |||||
| confirm_password: '', | |||||
| }} | |||||
| > | |||||
| <ProFormSelect | |||||
| name="roleIds" | |||||
| mode="multiple" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.user.role', | |||||
| defaultMessage: '角色', | |||||
| })} | |||||
| options={props.roles} | |||||
| placeholder="请选择角色" | |||||
| rules={[{ required: true, message: '请选择角色!' }]} | |||||
| /> | |||||
| </ProForm> | |||||
| </Modal> | |||||
| ); | |||||
| return ( | |||||
| <Modal | |||||
| width={640} | |||||
| title={intl.formatMessage({ | |||||
| id: 'system.user.auth.role', | |||||
| defaultMessage: '分配角色', | |||||
| })} | |||||
| open={props.open} | |||||
| destroyOnClose | |||||
| forceRender | |||||
| onOk={handleOk} | |||||
| onCancel={handleCancel} | |||||
| > | |||||
| <ProForm | |||||
| form={form} | |||||
| grid={true} | |||||
| layout="horizontal" | |||||
| onFinish={handleFinish} | |||||
| initialValues={{ | |||||
| login_password: '', | |||||
| confirm_password: '', | |||||
| }} | |||||
| > | |||||
| <ProFormSelect | |||||
| name="roleIds" | |||||
| mode="multiple" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.user.role', | |||||
| defaultMessage: '角色', | |||||
| })} | |||||
| options={props.roles} | |||||
| placeholder="请选择角色" | |||||
| rules={[{ required: true, message: '请选择角色!' }]} | |||||
| /> | |||||
| </ProForm> | |||||
| </Modal> | |||||
| ); | |||||
| }; | }; | ||||
| export default AuthRoleForm; | export default AuthRoleForm; | ||||
| @@ -1,6 +1,6 @@ | |||||
| import React, { useState, useEffect } from 'react'; | |||||
| import { Tree, message } from 'antd'; | |||||
| import { getDeptTree } from '@/services/system/user'; | import { getDeptTree } from '@/services/system/user'; | ||||
| import { Tree, message } from 'antd'; | |||||
| import React, { useEffect, useState } from 'react'; | |||||
| const { DirectoryTree } = Tree; | const { DirectoryTree } = Tree; | ||||
| @@ -8,10 +8,9 @@ const { DirectoryTree } = Tree; | |||||
| * | * | ||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @datetime 2023/02/06 | * @datetime 2023/02/06 | ||||
| * | |||||
| * | |||||
| * */ | * */ | ||||
| export type TreeProps = { | export type TreeProps = { | ||||
| onSelect: (values: any) => Promise<void>; | onSelect: (values: any) => Promise<void>; | ||||
| }; | }; | ||||
| @@ -1,13 +1,13 @@ | |||||
| import React from 'react'; | |||||
| import { Form, Modal } from 'antd'; | |||||
| import { useIntl } from '@umijs/max'; | |||||
| import { ProForm, ProFormText } from '@ant-design/pro-components'; | import { ProForm, ProFormText } from '@ant-design/pro-components'; | ||||
| import { useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | |||||
| import React from 'react'; | |||||
| /* * | /* * | ||||
| * | * | ||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @datetime 2023/02/06 | * @datetime 2023/02/06 | ||||
| * | |||||
| * | |||||
| * */ | * */ | ||||
| export type FormValueType = any & Partial<API.System.User>; | export type FormValueType = any & Partial<API.System.User>; | ||||
| @@ -82,7 +82,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: "确认密码", | |||||
| message: '确认密码', | |||||
| }, | }, | ||||
| { validator: checkPassword }, | { validator: checkPassword }, | ||||
| ]} | ]} | ||||
| @@ -1,25 +1,24 @@ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import { | import { | ||||
| ProForm, | ProForm, | ||||
| ProFormText, | |||||
| ProFormSelect, | |||||
| ProFormRadio, | ProFormRadio, | ||||
| ProFormSelect, | |||||
| ProFormText, | |||||
| ProFormTextArea, | ProFormTextArea, | ||||
| ProFormTreeSelect, | ProFormTreeSelect, | ||||
| } from '@ant-design/pro-components'; | } from '@ant-design/pro-components'; | ||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, Modal } from 'antd'; | import { Form, Modal } from 'antd'; | ||||
| import { useIntl, FormattedMessage } from '@umijs/max'; | |||||
| import { DataNode } from 'antd/es/tree'; | import { DataNode } from 'antd/es/tree'; | ||||
| import { DictValueEnumObj } from '@/components/DictTag'; | |||||
| import React, { useEffect } from 'react'; | |||||
| /* * | /* * | ||||
| * | * | ||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @datetime 2023/02/06 | * @datetime 2023/02/06 | ||||
| * | |||||
| * | |||||
| * */ | * */ | ||||
| export type UserFormData = Record<string, unknown> & Partial<API.System.User>; | export type UserFormData = Record<string, unknown> & Partial<API.System.User>; | ||||
| export type UserFormProps = { | export type UserFormProps = { | ||||
| @@ -39,7 +38,7 @@ export type UserFormProps = { | |||||
| const UserForm: React.FC<UserFormProps> = (props) => { | const UserForm: React.FC<UserFormProps> = (props) => { | ||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| const userId = Form.useWatch('userId', form); | const userId = Form.useWatch('userId', form); | ||||
| const { sexOptions, statusOptions, } = props; | |||||
| const { sexOptions, statusOptions } = props; | |||||
| const { roles, posts, depts } = props; | const { roles, posts, depts } = props; | ||||
| useEffect(() => { | useEffect(() => { | ||||
| @@ -91,7 +90,8 @@ const UserForm: React.FC<UserFormProps> = (props) => { | |||||
| form={form} | form={form} | ||||
| layout="horizontal" | layout="horizontal" | ||||
| submitter={false} | submitter={false} | ||||
| onFinish={handleFinish}> | |||||
| onFinish={handleFinish} | |||||
| > | |||||
| <ProFormText | <ProFormText | ||||
| name="nickName" | name="nickName" | ||||
| label={intl.formatMessage({ | label={intl.formatMessage({ | ||||
| @@ -103,9 +103,7 @@ const UserForm: React.FC<UserFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: ( | |||||
| <FormattedMessage id="请输入用户昵称!" defaultMessage="请输入用户昵称!" /> | |||||
| ), | |||||
| message: <FormattedMessage id="请输入用户昵称!" defaultMessage="请输入用户昵称!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -123,9 +121,7 @@ const UserForm: React.FC<UserFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| message: ( | |||||
| <FormattedMessage id="请输入用户部门!" defaultMessage="请输入用户部门!" /> | |||||
| ), | |||||
| message: <FormattedMessage id="请输入用户部门!" defaultMessage="请输入用户部门!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -140,9 +136,7 @@ const UserForm: React.FC<UserFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: ( | |||||
| <FormattedMessage id="请输入手机号码!" defaultMessage="请输入手机号码!" /> | |||||
| ), | |||||
| message: <FormattedMessage id="请输入手机号码!" defaultMessage="请输入手机号码!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -157,9 +151,7 @@ const UserForm: React.FC<UserFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: ( | |||||
| <FormattedMessage id="请输入用户邮箱!" defaultMessage="请输入用户邮箱!" /> | |||||
| ), | |||||
| message: <FormattedMessage id="请输入用户邮箱!" defaultMessage="请输入用户邮箱!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -207,9 +199,7 @@ const UserForm: React.FC<UserFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: ( | |||||
| <FormattedMessage id="请输入用户性别!" defaultMessage="请输入用户性别!" /> | |||||
| ), | |||||
| message: <FormattedMessage id="请输入用户性别!" defaultMessage="请输入用户性别!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -226,9 +216,7 @@ const UserForm: React.FC<UserFormProps> = (props) => { | |||||
| rules={[ | rules={[ | ||||
| { | { | ||||
| required: false, | required: false, | ||||
| message: ( | |||||
| <FormattedMessage id="请输入帐号状态!" defaultMessage="请输入帐号状态!" /> | |||||
| ), | |||||
| message: <FormattedMessage id="请输入帐号状态!" defaultMessage="请输入帐号状态!" />, | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| /> | /> | ||||
| @@ -1,20 +1,51 @@ | |||||
| import React, { useState, useRef, useEffect } from 'react'; | |||||
| import { useIntl, FormattedMessage, useAccess } from '@umijs/max'; | |||||
| import { Card, Col, Dropdown, FormInstance, Row, Space, Switch } from 'antd'; | |||||
| import { Button, message, Modal } from 'antd'; | |||||
| import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined, DownOutlined, EditOutlined } from '@ant-design/icons'; | |||||
| import { getUserList, removeUser, addUser, updateUser, exportUser, getUser, changeUserStatus, updateAuthRole, resetUserPwd } from '@/services/system/user'; | |||||
| import UpdateForm from './edit'; | |||||
| import { getDictValueEnum } from '@/services/system/dict'; | import { getDictValueEnum } from '@/services/system/dict'; | ||||
| import { DataNode } from 'antd/es/tree'; | |||||
| import { getDeptTree } from '@/services/system/user'; | |||||
| import DeptTree from './components/DeptTree'; | |||||
| import ResetPwd from './components/ResetPwd'; | |||||
| import { getPostList } from '@/services/system/post'; | import { getPostList } from '@/services/system/post'; | ||||
| import { getRoleList } from '@/services/system/role'; | import { getRoleList } from '@/services/system/role'; | ||||
| import { | |||||
| addUser, | |||||
| changeUserStatus, | |||||
| exportUser, | |||||
| getDeptTree, | |||||
| getUser, | |||||
| getUserList, | |||||
| removeUser, | |||||
| resetUserPwd, | |||||
| updateAuthRole, | |||||
| updateUser, | |||||
| } from '@/services/system/user'; | |||||
| import { | |||||
| DeleteOutlined, | |||||
| DownOutlined, | |||||
| EditOutlined, | |||||
| ExclamationCircleOutlined, | |||||
| PlusOutlined, | |||||
| } from '@ant-design/icons'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| PageContainer, | |||||
| ProColumns, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useAccess, useIntl } from '@umijs/max'; | |||||
| import { | |||||
| Button, | |||||
| Card, | |||||
| Col, | |||||
| Dropdown, | |||||
| FormInstance, | |||||
| Modal, | |||||
| Row, | |||||
| Space, | |||||
| Switch, | |||||
| message, | |||||
| } from 'antd'; | |||||
| import { DataNode } from 'antd/es/tree'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import AuthRoleForm from './components/AuthRole'; | import AuthRoleForm from './components/AuthRole'; | ||||
| import DeptTree from './components/DeptTree'; | |||||
| import ResetPwd from './components/ResetPwd'; | |||||
| import UpdateForm from './edit'; | |||||
| const { confirm } = Modal; | const { confirm } = Modal; | ||||
| @@ -22,7 +53,7 @@ const { confirm } = Modal; | |||||
| * | * | ||||
| * @author whiteshader@163.com | * @author whiteshader@163.com | ||||
| * @datetime 2023/02/06 | * @datetime 2023/02/06 | ||||
| * | |||||
| * | |||||
| * */ | * */ | ||||
| /** | /** | ||||
| @@ -102,7 +133,7 @@ const handleRemoveOne = async (selectedRow: API.System.User) => { | |||||
| /** | /** | ||||
| * 导出数据 | * 导出数据 | ||||
| * | * | ||||
| * | |||||
| * | |||||
| */ | */ | ||||
| const handleExport = async () => { | const handleExport = async () => { | ||||
| const hide = message.loading('正在导出'); | const hide = message.loading('正在导出'); | ||||
| @@ -156,12 +187,12 @@ const UserTableList: React.FC = () => { | |||||
| }, []); | }, []); | ||||
| const showChangeStatusConfirm = (record: API.System.User) => { | const showChangeStatusConfirm = (record: API.System.User) => { | ||||
| let text = record.status === "1" ? "启用" : "停用"; | |||||
| let text = record.status === '1' ? '启用' : '停用'; | |||||
| const newStatus = record.status === '0' ? '1' : '0'; | const newStatus = record.status === '0' ? '1' : '0'; | ||||
| confirm({ | confirm({ | ||||
| title: `确认要${text}${record.userName}用户吗?`, | title: `确认要${text}${record.userName}用户吗?`, | ||||
| onOk() { | onOk() { | ||||
| changeUserStatus(record.userId, newStatus).then(resp => { | |||||
| changeUserStatus(record.userId, newStatus).then((resp) => { | |||||
| if (resp.code === 200) { | if (resp.code === 200) { | ||||
| messageApi.open({ | messageApi.open({ | ||||
| type: 'success', | type: 'success', | ||||
| @@ -178,7 +209,7 @@ const UserTableList: React.FC = () => { | |||||
| }, | }, | ||||
| }); | }); | ||||
| }; | }; | ||||
| const fetchUserInfo = async (userId: number) => { | const fetchUserInfo = async (userId: number) => { | ||||
| const res = await getUser(userId); | const res = await getUser(userId); | ||||
| setPostIds(res.postIds); | setPostIds(res.postIds); | ||||
| @@ -221,7 +252,7 @@ const UserTableList: React.FC = () => { | |||||
| title: <FormattedMessage id="system.user.dept_name" defaultMessage="部门" />, | title: <FormattedMessage id="system.user.dept_name" defaultMessage="部门" />, | ||||
| dataIndex: ['dept', 'deptName'], | dataIndex: ['dept', 'deptName'], | ||||
| valueType: 'text', | valueType: 'text', | ||||
| hideInSearch: true | |||||
| hideInSearch: true, | |||||
| }, | }, | ||||
| { | { | ||||
| title: <FormattedMessage id="system.user.phonenumber" defaultMessage="手机号码" />, | title: <FormattedMessage id="system.user.phonenumber" defaultMessage="手机号码" />, | ||||
| @@ -241,7 +272,8 @@ const UserTableList: React.FC = () => { | |||||
| unCheckedChildren="停用" | unCheckedChildren="停用" | ||||
| defaultChecked | defaultChecked | ||||
| onClick={() => showChangeStatusConfirm(record)} | onClick={() => showChangeStatusConfirm(record)} | ||||
| />) | |||||
| /> | |||||
| ); | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -297,7 +329,9 @@ const UserTableList: React.FC = () => { | |||||
| menu={{ | menu={{ | ||||
| items: [ | items: [ | ||||
| { | { | ||||
| label: <FormattedMessage id="system.user.reset.password" defaultMessage="密码重置" />, | |||||
| label: ( | |||||
| <FormattedMessage id="system.user.reset.password" defaultMessage="密码重置" /> | |||||
| ), | |||||
| key: 'reset', | key: 'reset', | ||||
| disabled: !access.hasPerms('system:user:edit'), | disabled: !access.hasPerms('system:user:edit'), | ||||
| }, | }, | ||||
| @@ -311,13 +345,12 @@ const UserTableList: React.FC = () => { | |||||
| if (key === 'reset') { | if (key === 'reset') { | ||||
| setResetPwdModalVisible(true); | setResetPwdModalVisible(true); | ||||
| setCurrentRow(record); | setCurrentRow(record); | ||||
| } | |||||
| else if (key === 'authRole') { | |||||
| } else if (key === 'authRole') { | |||||
| fetchUserInfo(record.userId); | fetchUserInfo(record.userId); | ||||
| setAuthRoleModalVisible(true); | setAuthRoleModalVisible(true); | ||||
| setCurrentRow(record); | setCurrentRow(record); | ||||
| } | } | ||||
| } | |||||
| }, | |||||
| }} | }} | ||||
| > | > | ||||
| <a onClick={(e) => e.preventDefault()}> | <a onClick={(e) => e.preventDefault()}> | ||||
| @@ -369,7 +402,7 @@ const UserTableList: React.FC = () => { | |||||
| const treeData = await getDeptTree({}); | const treeData = await getDeptTree({}); | ||||
| setDeptTree(treeData); | setDeptTree(treeData); | ||||
| const postResp = await getPostList() | |||||
| const postResp = await getPostList(); | |||||
| if (postResp.code === 200) { | if (postResp.code === 200) { | ||||
| setPostList( | setPostList( | ||||
| postResp.rows.map((item: any) => { | postResp.rows.map((item: any) => { | ||||
| @@ -381,7 +414,7 @@ const UserTableList: React.FC = () => { | |||||
| ); | ); | ||||
| } | } | ||||
| const roleResp = await getRoleList() | |||||
| const roleResp = await getRoleList(); | |||||
| if (roleResp.code === 200) { | if (roleResp.code === 200) { | ||||
| setRoleList( | setRoleList( | ||||
| roleResp.rows.map((item: any) => { | roleResp.rows.map((item: any) => { | ||||
| @@ -396,7 +429,8 @@ const UserTableList: React.FC = () => { | |||||
| setModalVisible(true); | setModalVisible(true); | ||||
| }} | }} | ||||
| > | > | ||||
| <PlusOutlined /> <FormattedMessage id="pages.searchTable.new" defaultMessage="新建" /> | |||||
| <PlusOutlined />{' '} | |||||
| <FormattedMessage id="pages.searchTable.new" defaultMessage="新建" /> | |||||
| </Button>, | </Button>, | ||||
| <Button | <Button | ||||
| type="primary" | type="primary" | ||||
| @@ -414,7 +448,7 @@ const UserTableList: React.FC = () => { | |||||
| actionRef.current?.reloadAndRest?.(); | actionRef.current?.reloadAndRest?.(); | ||||
| } | } | ||||
| }, | }, | ||||
| onCancel() { }, | |||||
| onCancel() {}, | |||||
| }); | }); | ||||
| }} | }} | ||||
| > | > | ||||
| @@ -434,14 +468,16 @@ const UserTableList: React.FC = () => { | |||||
| </Button>, | </Button>, | ||||
| ]} | ]} | ||||
| request={(params) => | request={(params) => | ||||
| getUserList({ ...params, deptId: selectDept.id } as API.System.UserListParams).then((res) => { | |||||
| const result = { | |||||
| data: res.rows, | |||||
| total: res.total, | |||||
| success: true, | |||||
| }; | |||||
| return result; | |||||
| }) | |||||
| getUserList({ ...params, deptId: selectDept.id } as API.System.UserListParams).then( | |||||
| (res) => { | |||||
| const result = { | |||||
| data: res.rows, | |||||
| total: res.total, | |||||
| success: true, | |||||
| }; | |||||
| return result; | |||||
| }, | |||||
| ) | |||||
| } | } | ||||
| columns={columns} | columns={columns} | ||||
| rowSelection={{ | rowSelection={{ | ||||
| @@ -1,8 +1,8 @@ | |||||
| import { ProForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components'; | |||||
| import { history } from '@umijs/max'; | |||||
| import { Button, Col, Form, message, Row } from 'antd'; | import { Button, Col, Form, message, Row } from 'antd'; | ||||
| import React, { Fragment, useEffect } from 'react'; | import React, { Fragment, useEffect } from 'react'; | ||||
| import { history } from '@umijs/max'; | |||||
| import styles from '../style.less'; | import styles from '../style.less'; | ||||
| import { ProForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components'; | |||||
| export type BaseInfoProps = { | export type BaseInfoProps = { | ||||
| values?: any; | values?: any; | ||||
| @@ -55,7 +55,6 @@ const BaseInfo: React.FC<BaseInfoProps> = (props) => { | |||||
| <Row> | <Row> | ||||
| <Col span={12} order={1}> | <Col span={12} order={1}> | ||||
| <ProFormText | <ProFormText | ||||
| name="tableName" | name="tableName" | ||||
| label="表名称" | label="表名称" | ||||
| rules={[ | rules={[ | ||||
| @@ -67,16 +66,12 @@ const BaseInfo: React.FC<BaseInfoProps> = (props) => { | |||||
| /> | /> | ||||
| </Col> | </Col> | ||||
| <Col span={12} order={2}> | <Col span={12} order={2}> | ||||
| <ProFormText | |||||
| name="tableComment" | |||||
| label="表描述" | |||||
| /> | |||||
| <ProFormText name="tableComment" label="表描述" /> | |||||
| </Col> | </Col> | ||||
| </Row> | </Row> | ||||
| <Row> | <Row> | ||||
| <Col span={12} order={1}> | <Col span={12} order={1}> | ||||
| <ProFormText | <ProFormText | ||||
| name="className" | name="className" | ||||
| label="实体类名称" | label="实体类名称" | ||||
| rules={[ | rules={[ | ||||
| @@ -1,10 +1,10 @@ | |||||
| import { EditableProTable, ProColumns } from '@ant-design/pro-components'; | |||||
| import { history } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | |||||
| import { Button, Checkbox, Col, Row, Tag } from 'antd'; | |||||
| import React, { Fragment, useEffect, useRef, useState } from 'react'; | import React, { Fragment, useEffect, useRef, useState } from 'react'; | ||||
| import type { GenCodeType } from '../data'; | import type { GenCodeType } from '../data'; | ||||
| import { Button, Checkbox, Col, Row, Tag } from 'antd'; | |||||
| import type { FormInstance } from 'antd'; | |||||
| import { history } from '@umijs/max'; | |||||
| import styles from '../style.less'; | import styles from '../style.less'; | ||||
| import { EditableProTable, ProColumns } from '@ant-design/pro-components'; | |||||
| export type ColumnInfoProps = { | export type ColumnInfoProps = { | ||||
| parentType?: string; | parentType?: string; | ||||
| @@ -1,10 +1,10 @@ | |||||
| import { ProForm, ProFormRadio, ProFormSelect, ProFormText } from '@ant-design/pro-components'; | |||||
| import { history } from '@umijs/max'; | |||||
| import { Button, Col, Divider, Form, Row, TreeSelect } from 'antd'; | import { Button, Col, Divider, Form, Row, TreeSelect } from 'antd'; | ||||
| import { DataNode } from 'antd/es/tree'; | |||||
| import React, { Fragment, useEffect, useState } from 'react'; | import React, { Fragment, useEffect, useState } from 'react'; | ||||
| import { history } from '@umijs/max'; | |||||
| import type { TableInfo } from '../data'; | import type { TableInfo } from '../data'; | ||||
| import styles from '../style.less'; | import styles from '../style.less'; | ||||
| import { DataNode } from 'antd/es/tree'; | |||||
| import { ProForm, ProFormRadio, ProFormSelect, ProFormText } from '@ant-design/pro-components'; | |||||
| export type GenInfoProps = { | export type GenInfoProps = { | ||||
| values?: any; | values?: any; | ||||
| @@ -140,11 +140,7 @@ const GenInfo: React.FC<GenInfoProps> = (props) => { | |||||
| <ProFormText name="functionName" label="生成功能名" /> | <ProFormText name="functionName" label="生成功能名" /> | ||||
| </Col> | </Col> | ||||
| <Col span={12} order={2}> | <Col span={12} order={2}> | ||||
| <ProForm.Item | |||||
| labelCol={{ span: 20 }} | |||||
| name="parentMenuId" | |||||
| label="父菜单" | |||||
| > | |||||
| <ProForm.Item labelCol={{ span: 20 }} name="parentMenuId" label="父菜单"> | |||||
| <TreeSelect | <TreeSelect | ||||
| style={{ width: '74%' }} | style={{ width: '74%' }} | ||||
| defaultValue={props.values.parentMenuId} | defaultValue={props.values.parentMenuId} | ||||
| @@ -1,9 +1,9 @@ | |||||
| import React, { useEffect } from 'react'; | |||||
| import { useIntl } from '@umijs/max'; | import { useIntl } from '@umijs/max'; | ||||
| import { Modal, Tabs } from 'antd'; | |||||
| import type { TabsProps } from 'antd'; | import type { TabsProps } from 'antd'; | ||||
| import Highlight from 'react-highlight'; | |||||
| import { Modal, Tabs } from 'antd'; | |||||
| import 'highlight.js/styles/base16/material.css'; | import 'highlight.js/styles/base16/material.css'; | ||||
| import React, { useEffect } from 'react'; | |||||
| import Highlight from 'react-highlight'; | |||||
| interface PreviewTableProps { | interface PreviewTableProps { | ||||
| open: boolean; | open: boolean; | ||||
| @@ -17,10 +17,10 @@ const PreviewTableCode: React.FC<PreviewTableProps> = (props) => { | |||||
| const keys = Object.keys(props.data); | const keys = Object.keys(props.data); | ||||
| keys.forEach((key) => { | keys.forEach((key) => { | ||||
| panes.push({ | panes.push({ | ||||
| key: key + '1', | |||||
| label: key.substring(key.lastIndexOf('/') + 1, key.indexOf('.vm')), | |||||
| children: <Highlight className="java">{props.data[key]}</Highlight>, | |||||
| } as TabsProps); | |||||
| key: key + '1', | |||||
| label: key.substring(key.lastIndexOf('/') + 1, key.indexOf('.vm')), | |||||
| children: <Highlight className="java">{props.data[key]}</Highlight>, | |||||
| } as TabsProps); | |||||
| }); | }); | ||||
| useEffect(() => {}, []); | useEffect(() => {}, []); | ||||
| @@ -1,16 +1,16 @@ | |||||
| import { getDictTypeList } from '@/services/system/dict'; | |||||
| import { getMenuTree } from '@/services/system/menu'; | |||||
| import { formatTreeData } from '@/utils/tree'; | |||||
| import { useLocation } from '@umijs/max'; | |||||
| import { Card, Layout, Steps, message } from 'antd'; | |||||
| import queryString from 'query-string'; | |||||
| import React, { useEffect, useState } from 'react'; | import React, { useEffect, useState } from 'react'; | ||||
| import BaseInfo from './components/BaseInfo'; | import BaseInfo from './components/BaseInfo'; | ||||
| import { Card, Layout, message, Steps } from 'antd'; | |||||
| import ColumnInfo from './components/ColumnInfo'; | import ColumnInfo from './components/ColumnInfo'; | ||||
| import GenInfo from './components/GenInfo'; | import GenInfo from './components/GenInfo'; | ||||
| import type { GenCodeType } from './data'; | |||||
| import { getGenCode, updateData } from './service'; | import { getGenCode, updateData } from './service'; | ||||
| import { formatTreeData } from '@/utils/tree'; | |||||
| import styles from './style.less'; | import styles from './style.less'; | ||||
| import type { GenCodeType } from './data'; | |||||
| import { getMenuTree } from '@/services/system/menu'; | |||||
| import { getDictTypeList } from '@/services/system/dict'; | |||||
| import queryString from 'query-string'; | |||||
| import { useLocation } from '@umijs/max'; | |||||
| const { Content } = Layout; | const { Content } = Layout; | ||||
| @@ -163,17 +163,21 @@ const TableList: React.FC = () => { | |||||
| return ( | return ( | ||||
| <Content> | <Content> | ||||
| <Card className={styles.tabsCard} bordered={false}> | <Card className={styles.tabsCard} bordered={false}> | ||||
| <Steps current={currentStep} className={styles.steps} items={[ | |||||
| { | |||||
| title: '基本信息', | |||||
| }, | |||||
| { | |||||
| title: '字段信息', | |||||
| }, | |||||
| { | |||||
| title: '生成信息', | |||||
| }, | |||||
| ]} /> | |||||
| <Steps | |||||
| current={currentStep} | |||||
| className={styles.steps} | |||||
| items={[ | |||||
| { | |||||
| title: '基本信息', | |||||
| }, | |||||
| { | |||||
| title: '字段信息', | |||||
| }, | |||||
| { | |||||
| title: '生成信息', | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| {stepComponent} | {stepComponent} | ||||
| </Card> | </Card> | ||||
| </Content> | </Content> | ||||
| @@ -1,10 +1,10 @@ | |||||
| import { Button, Card, message, Layout } from 'antd'; | |||||
| import { PlusOutlined, RollbackOutlined } from '@ant-design/icons'; | |||||
| import { ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, history } from '@umijs/max'; | |||||
| import { Button, Card, Layout, message } from 'antd'; | |||||
| import React, { useState } from 'react'; | import React, { useState } from 'react'; | ||||
| import { history, FormattedMessage } from '@umijs/max'; | |||||
| import { importTables, queryTableList } from './service'; | |||||
| import type { GenCodeType } from './data.d'; | import type { GenCodeType } from './data.d'; | ||||
| import { ProColumns, ProTable } from '@ant-design/pro-components'; | |||||
| import { PlusOutlined, RollbackOutlined } from '@ant-design/icons'; | |||||
| import { importTables, queryTableList } from './service'; | |||||
| const { Content } = Layout; | const { Content } = Layout; | ||||
| @@ -1,26 +1,26 @@ | |||||
| import { DownloadOutlined, PlusOutlined } from '@ant-design/icons'; | import { DownloadOutlined, PlusOutlined } from '@ant-design/icons'; | ||||
| import { Button, message, Drawer, Modal, Card, Layout } from 'antd'; | |||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| ProColumns, | |||||
| ProDescriptions, | |||||
| ProDescriptionsItemProps, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, history, useAccess } from '@umijs/max'; | |||||
| import type { FormInstance } from 'antd'; | import type { FormInstance } from 'antd'; | ||||
| import React, { useState, useRef } from 'react'; | |||||
| import { history, FormattedMessage, useAccess } from '@umijs/max'; | |||||
| import { Button, Card, Drawer, Layout, Modal, message } from 'antd'; | |||||
| import React, { useRef, useState } from 'react'; | |||||
| import PreviewForm from './components/PreviewCode'; | import PreviewForm from './components/PreviewCode'; | ||||
| import type { GenCodeTableListParams, GenCodeType } from './data.d'; | import type { GenCodeTableListParams, GenCodeType } from './data.d'; | ||||
| import { | import { | ||||
| batchGenCode, | batchGenCode, | ||||
| genCode, | genCode, | ||||
| previewCode, | |||||
| getGenCodeList, | getGenCodeList, | ||||
| previewCode, | |||||
| removeData, | removeData, | ||||
| syncDbInfo, | syncDbInfo, | ||||
| } from './service'; | } from './service'; | ||||
| import { | |||||
| ActionType, | |||||
| FooterToolbar, | |||||
| ProColumns, | |||||
| ProDescriptions, | |||||
| ProDescriptionsItemProps, | |||||
| ProTable, | |||||
| } from '@ant-design/pro-components'; | |||||
| const { Content } = Layout; | const { Content } = Layout; | ||||
| @@ -1,6 +1,6 @@ | |||||
| import { request } from '@umijs/max'; | |||||
| import { downLoadZip } from '@/utils/downloadfile'; | import { downLoadZip } from '@/utils/downloadfile'; | ||||
| import type { GenCodeType, GenCodeTableListParams } from './data.d'; | |||||
| import { request } from '@umijs/max'; | |||||
| import type { GenCodeTableListParams, GenCodeType } from './data.d'; | |||||
| // 查询分页列表 | // 查询分页列表 | ||||
| export async function getGenCodeList(params?: GenCodeTableListParams) { | export async function getGenCodeList(params?: GenCodeTableListParams) { | ||||
| @@ -1,11 +1,10 @@ | |||||
| .avatarHolder { | .avatarHolder { | ||||
| margin-bottom: 16px; | |||||
| text-align: center; | |||||
| position: relative; | position: relative; | ||||
| display: inline-block; | display: inline-block; | ||||
| height: 120px; | height: 120px; | ||||
| margin-bottom: 16px; | |||||
| text-align: center; | |||||
| & > img { | & > img { | ||||
| width: 120px; | width: 120px; | ||||
| height: 120px; | height: 120px; | ||||
| @@ -1,10 +1,10 @@ | |||||
| .avatarPreview { | .avatarPreview { | ||||
| position: absolute; | |||||
| top: 50%; | |||||
| transform: translate(50%, -50%); | |||||
| width: 200px; | |||||
| height: 200px; | |||||
| border-radius: 50%; | |||||
| box-shadow: 0 0 4px #ccc; | |||||
| overflow: hidden; | |||||
| } | |||||
| position: absolute; | |||||
| top: 50%; | |||||
| width: 200px; | |||||
| height: 200px; | |||||
| overflow: hidden; | |||||
| border-radius: 50%; | |||||
| box-shadow: 0 0 4px #ccc; | |||||
| transform: translate(50%, -50%); | |||||
| } | |||||
| @@ -1,10 +1,4 @@ | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import { Modal, Row, Col, Button, Space, Upload, message } from 'antd'; | |||||
| import { useIntl } from '@umijs/max'; | |||||
| import { uploadAvatar } from '@/services/system/user'; | import { uploadAvatar } from '@/services/system/user'; | ||||
| import { Cropper } from 'react-cropper'; | |||||
| import './cropper.css'; | |||||
| import styles from './index.less'; | |||||
| import { | import { | ||||
| MinusOutlined, | MinusOutlined, | ||||
| PlusOutlined, | PlusOutlined, | ||||
| @@ -12,6 +6,12 @@ import { | |||||
| UndoOutlined, | UndoOutlined, | ||||
| UploadOutlined, | UploadOutlined, | ||||
| } from '@ant-design/icons'; | } from '@ant-design/icons'; | ||||
| import { useIntl } from '@umijs/max'; | |||||
| import { Button, Col, Modal, Row, Space, Upload, message } from 'antd'; | |||||
| import React, { useEffect, useRef, useState } from 'react'; | |||||
| import { Cropper } from 'react-cropper'; | |||||
| import './cropper.css'; | |||||
| import styles from './index.less'; | |||||
| /* * | /* * | ||||
| * | * | ||||
| @@ -44,7 +44,7 @@ const AvatarCropperForm: React.FC<AvatarCropperProps> = (props) => { | |||||
| formData.append('avatarfile', blob); | formData.append('avatarfile', blob); | ||||
| uploadAvatar(formData).then((res) => { | uploadAvatar(formData).then((res) => { | ||||
| if (res.code === 200) { | if (res.code === 200) { | ||||
| message.success(res.msg); | |||||
| message.success(res.msg); | |||||
| props.onFinished(true); | props.onFinished(true); | ||||
| } else { | } else { | ||||
| message.warning(res.msg); | message.warning(res.msg); | ||||
| @@ -1,9 +1,8 @@ | |||||
| import React from 'react'; | |||||
| import { Form, message, Row } from 'antd'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { ProForm, ProFormRadio, ProFormText } from '@ant-design/pro-components'; | |||||
| import { updateUserProfile } from '@/services/system/user'; | import { updateUserProfile } from '@/services/system/user'; | ||||
| import { ProForm, ProFormRadio, ProFormText } from '@ant-design/pro-components'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, message, Row } from 'antd'; | |||||
| import React from 'react'; | |||||
| export type BaseInfoProps = { | export type BaseInfoProps = { | ||||
| values: Partial<API.CurrentUser> | undefined; | values: Partial<API.CurrentUser> | undefined; | ||||
| @@ -1,8 +1,8 @@ | |||||
| import React from 'react'; | |||||
| import { Form, message } from 'antd'; | |||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { updateUserPwd } from '@/services/system/user'; | import { updateUserPwd } from '@/services/system/user'; | ||||
| import { ProForm, ProFormText } from '@ant-design/pro-components'; | import { ProForm, ProFormText } from '@ant-design/pro-components'; | ||||
| import { FormattedMessage, useIntl } from '@umijs/max'; | |||||
| import { Form, message } from 'antd'; | |||||
| import React from 'react'; | |||||
| const ResetPassword: React.FC = () => { | const ResetPassword: React.FC = () => { | ||||
| const [form] = Form.useForm(); | const [form] = Form.useForm(); | ||||
| @@ -27,55 +27,53 @@ const ResetPassword: React.FC = () => { | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| <ProForm form={form} onFinish={handleFinish}> | |||||
| <ProFormText.Password | |||||
| name="oldPassword" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.user.old_password', | |||||
| defaultMessage: '旧密码', | |||||
| })} | |||||
| width="xl" | |||||
| placeholder="请输入旧密码" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: <FormattedMessage id="请输入旧密码!" defaultMessage="请输入旧密码!" />, | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormText.Password | |||||
| name="newPassword" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.user.new_password', | |||||
| defaultMessage: '新密码', | |||||
| })} | |||||
| width="xl" | |||||
| placeholder="请输入新密码" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: <FormattedMessage id="请输入新密码!" defaultMessage="请输入新密码!" />, | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormText.Password | |||||
| name="confirmPassword" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.user.confirm_password', | |||||
| defaultMessage: '确认密码', | |||||
| })} | |||||
| width="xl" | |||||
| placeholder="请输入确认密码" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: ( | |||||
| <FormattedMessage id="请输入确认密码!" defaultMessage="请输入确认密码!" /> | |||||
| ), | |||||
| }, | |||||
| { validator: checkPassword }, | |||||
| ]} | |||||
| /> | |||||
| <ProForm form={form} onFinish={handleFinish}> | |||||
| <ProFormText.Password | |||||
| name="oldPassword" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.user.old_password', | |||||
| defaultMessage: '旧密码', | |||||
| })} | |||||
| width="xl" | |||||
| placeholder="请输入旧密码" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: <FormattedMessage id="请输入旧密码!" defaultMessage="请输入旧密码!" />, | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormText.Password | |||||
| name="newPassword" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.user.new_password', | |||||
| defaultMessage: '新密码', | |||||
| })} | |||||
| width="xl" | |||||
| placeholder="请输入新密码" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: <FormattedMessage id="请输入新密码!" defaultMessage="请输入新密码!" />, | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormText.Password | |||||
| name="confirmPassword" | |||||
| label={intl.formatMessage({ | |||||
| id: 'system.user.confirm_password', | |||||
| defaultMessage: '确认密码', | |||||
| })} | |||||
| width="xl" | |||||
| placeholder="请输入确认密码" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: <FormattedMessage id="请输入确认密码!" defaultMessage="请输入确认密码!" />, | |||||
| }, | |||||
| { validator: checkPassword }, | |||||
| ]} | |||||
| /> | |||||
| </ProForm> | </ProForm> | ||||
| </> | </> | ||||
| ); | ); | ||||
| @@ -1,6 +1,6 @@ | |||||
| import Footer from '@/components/Footer'; | |||||
| import { getCaptchaImg, login } from '@/services/system/auth'; | |||||
| import { clearSessionToken, setSessionToken } from '@/access'; | |||||
| import { getFakeCaptcha } from '@/services/ant-design-pro/login'; | import { getFakeCaptcha } from '@/services/ant-design-pro/login'; | ||||
| import { getCaptchaImg, login } from '@/services/system/auth'; | |||||
| import { | import { | ||||
| AlipayCircleOutlined, | AlipayCircleOutlined, | ||||
| LockOutlined, | LockOutlined, | ||||
| @@ -16,13 +16,11 @@ import { | |||||
| ProFormText, | ProFormText, | ||||
| } from '@ant-design/pro-components'; | } from '@ant-design/pro-components'; | ||||
| import { useEmotionCss } from '@ant-design/use-emotion-css'; | import { useEmotionCss } from '@ant-design/use-emotion-css'; | ||||
| import styles from './login.less'; | |||||
| import { FormattedMessage, history, SelectLang, useIntl, useModel, Helmet } from '@umijs/max'; | |||||
| import { Alert, Col, message, Row, Tabs, Image } from 'antd'; | |||||
| import Settings from '../../../../config/defaultSettings'; | |||||
| import { FormattedMessage, SelectLang, history, useIntl, useModel } from '@umijs/max'; | |||||
| import { Alert, Col, Image, Row, message } from 'antd'; | |||||
| import React, { useEffect, useState } from 'react'; | import React, { useEffect, useState } from 'react'; | ||||
| import { flushSync } from 'react-dom'; | import { flushSync } from 'react-dom'; | ||||
| import { clearSessionToken, setSessionToken } from '@/access'; | |||||
| import styles from './login.less'; | |||||
| const ActionIcons = () => { | const ActionIcons = () => { | ||||
| const langClassName = useEmotionCss(({ token }) => { | const langClassName = useEmotionCss(({ token }) => { | ||||
| @@ -86,7 +84,7 @@ const LoginMessage: React.FC<{ | |||||
| }; | }; | ||||
| const Login: React.FC = () => { | const Login: React.FC = () => { | ||||
| const [userLoginState, setUserLoginState] = useState<API.LoginResult>({code: 200}); | |||||
| const [userLoginState, setUserLoginState] = useState<API.LoginResult>({ code: 200 }); | |||||
| const [type, setType] = useState<string>('account'); | const [type, setType] = useState<string>('account'); | ||||
| const { initialState, setInitialState } = useModel('@@initialState'); | const { initialState, setInitialState } = useModel('@@initialState'); | ||||
| const [captchaCode, setCaptchaCode] = useState<string>(''); | const [captchaCode, setCaptchaCode] = useState<string>(''); | ||||
| @@ -96,86 +94,85 @@ const Login: React.FC = () => { | |||||
| return { | return { | ||||
| display: 'flex', | display: 'flex', | ||||
| height: '100vh', | height: '100vh', | ||||
| backgroundColor:"#fff", | |||||
| backgroundColor: '#fff', | |||||
| backgroundSize: '100% 100%', | backgroundSize: '100% 100%', | ||||
| }; | }; | ||||
| }); | }); | ||||
| const containerLeftBox= useEmotionCss(() => { | |||||
| const containerLeftBox = useEmotionCss(() => { | |||||
| return { | return { | ||||
| background:'linear-gradient(180deg,#e2ecff 0%,#f6fafe 100%)', | |||||
| width:'43%', | |||||
| height:'100%', | |||||
| position:'relative' | |||||
| background: 'linear-gradient(180deg,#e2ecff 0%,#f6fafe 100%)', | |||||
| width: '43%', | |||||
| height: '100%', | |||||
| position: 'relative', | |||||
| }; | }; | ||||
| }); | }); | ||||
| const leftTopBoX= useEmotionCss(() => { | |||||
| const leftTopBoX = useEmotionCss(() => { | |||||
| return { | return { | ||||
| display:'flex', | |||||
| position:'absolute', | |||||
| display: 'flex', | |||||
| position: 'absolute', | |||||
| top: '55px', | top: '55px', | ||||
| left: '60px', | left: '60px', | ||||
| fontWeight:'500', | |||||
| color:'#1d1d20', | |||||
| fontSize:'36px', | |||||
| fontWeight: '500', | |||||
| color: '#1d1d20', | |||||
| fontSize: '36px', | |||||
| fontFamily: 'Alibaba', | fontFamily: 'Alibaba', | ||||
| }; | }; | ||||
| }); | }); | ||||
| const centerTitleBoX= useEmotionCss(() => { | |||||
| const centerTitleBoX = useEmotionCss(() => { | |||||
| return { | return { | ||||
| display:'flex', | |||||
| position:'absolute', | |||||
| display: 'flex', | |||||
| position: 'absolute', | |||||
| top: '163px', | top: '163px', | ||||
| left: '50%', | left: '50%', | ||||
| transform:'translateX(-50%)', | |||||
| fontWeight:'500', | |||||
| color:'#111111', | |||||
| fontSize:'45px', | |||||
| fontFamily: 'Alibaba' | |||||
| transform: 'translateX(-50%)', | |||||
| fontWeight: '500', | |||||
| color: '#111111', | |||||
| fontSize: '45px', | |||||
| fontFamily: 'Alibaba', | |||||
| }; | }; | ||||
| }); | }); | ||||
| const centerMessage=useEmotionCss(() => { | |||||
| const centerMessage = useEmotionCss(() => { | |||||
| return { | return { | ||||
| display:'flex', | |||||
| position:'absolute', | |||||
| display: 'flex', | |||||
| position: 'absolute', | |||||
| top: '242px', | top: '242px', | ||||
| left: '50%', | left: '50%', | ||||
| transform:'translateX(-50%)', | |||||
| fontWeight:'500', | |||||
| color:'#606b7a', | |||||
| fontSize:'26px', | |||||
| transform: 'translateX(-50%)', | |||||
| fontWeight: '500', | |||||
| color: '#606b7a', | |||||
| fontSize: '26px', | |||||
| fontFamily: 'Alibaba', | fontFamily: 'Alibaba', | ||||
| letterSpacing:'8px' | |||||
| letterSpacing: '8px', | |||||
| }; | }; | ||||
| }); | }); | ||||
| const containerRightBox = useEmotionCss(() => { | const containerRightBox = useEmotionCss(() => { | ||||
| return { | return { | ||||
| background:'#fff', | |||||
| width:'57%', | |||||
| height:'100%', | |||||
| position:'relative' | |||||
| background: '#fff', | |||||
| width: '57%', | |||||
| height: '100%', | |||||
| position: 'relative', | |||||
| }; | }; | ||||
| }); | }); | ||||
| const rightTopTitle =useEmotionCss(() => { | |||||
| const rightTopTitle = useEmotionCss(() => { | |||||
| return { | return { | ||||
| display:'flex', | |||||
| position:'absolute', | |||||
| alignItems:'center', | |||||
| display: 'flex', | |||||
| position: 'absolute', | |||||
| alignItems: 'center', | |||||
| top: '147px', | top: '147px', | ||||
| left: '230px', | left: '230px', | ||||
| fontFamily: 'Alibaba', | fontFamily: 'Alibaba', | ||||
| }; | }; | ||||
| }); | }); | ||||
| const containerLoginForm=useEmotionCss(() => { | |||||
| const containerLoginForm = useEmotionCss(() => { | |||||
| return { | return { | ||||
| width:'640px', | |||||
| position:'absolute', | |||||
| background:'#ffffff', | |||||
| borderRadius:'10px', | |||||
| boxShadow:'0px 3px 20px rgba(153, 153, 153, 0.16)', | |||||
| padding:'62px 36px 45px 36px', | |||||
| left:'230px', | |||||
| top:'220px' | |||||
| width: '640px', | |||||
| position: 'absolute', | |||||
| background: '#ffffff', | |||||
| borderRadius: '10px', | |||||
| boxShadow: '0px 3px 20px rgba(153, 153, 153, 0.16)', | |||||
| padding: '62px 36px 45px 36px', | |||||
| left: '230px', | |||||
| top: '220px', | |||||
| }; | }; | ||||
| }); | }); | ||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| @@ -244,243 +241,265 @@ const Login: React.FC = () => { | |||||
| <div className={containerClassName}> | <div className={containerClassName}> | ||||
| <div className={containerLeftBox}> | <div className={containerLeftBox}> | ||||
| <div className={leftTopBoX}> | <div className={leftTopBoX}> | ||||
| <img src="/assets/images/left-top-logo.png" style={{height:'42px',marginRight:'10px'}} alt="" /> | |||||
| 复杂智能软件 | |||||
| <img | |||||
| src="/assets/images/left-top-logo.png" | |||||
| style={{ height: '42px', marginRight: '10px' }} | |||||
| alt="" | |||||
| /> | |||||
| 复杂智能软件 | |||||
| </div> | </div> | ||||
| <div className={centerTitleBoX}> | <div className={centerTitleBoX}> | ||||
| <span style={{whiteSpace:'nowrap'}}>复杂智能软件</span> | |||||
| <img src="/assets/images/ai-logo.png" style={{height:'47px',marginTop:'-10px'}} alt="" /> | |||||
| <span style={{ whiteSpace: 'nowrap' }}>复杂智能软件</span> | |||||
| <img | |||||
| src="/assets/images/ai-logo.png" | |||||
| style={{ height: '47px', marginTop: '-10px' }} | |||||
| alt="" | |||||
| /> | |||||
| </div> | </div> | ||||
| <div className={centerMessage}> | <div className={centerMessage}> | ||||
| <span style={{whiteSpace:'nowrap'}}>大语言模型运维 统一管理平台</span> | |||||
| <span style={{ whiteSpace: 'nowrap' }}>大语言模型运维 统一管理平台</span> | |||||
| </div> | </div> | ||||
| <img src="/assets/images/left-back-logo.png" style={{width:'90%',position:'absolute',top:'326px',left: '50%', | |||||
| transform:'translateX(-50%)',}} alt="" /> | |||||
| <img | |||||
| src="/assets/images/left-back-logo.png" | |||||
| style={{ | |||||
| width: '90%', | |||||
| position: 'absolute', | |||||
| top: '326px', | |||||
| left: '50%', | |||||
| transform: 'translateX(-50%)', | |||||
| }} | |||||
| alt="" | |||||
| /> | |||||
| </div> | </div> | ||||
| <div className={containerRightBox}> | <div className={containerRightBox}> | ||||
| <div className={rightTopTitle}> | <div className={rightTopTitle}> | ||||
| <span style={{color:'#111111',fontSize:'36px'}}>hello~</span> | |||||
| <span style={{color:'#606b7a',fontSize:'32px',marginLeft:'10px'}}>欢迎登陆</span> | |||||
| <span style={{color:'#1664ff',fontSize:'32px'}}>复杂智能软件</span> | |||||
| <span style={{ color: '#111111', fontSize: '36px' }}>hello~</span> | |||||
| <span style={{ color: '#606b7a', fontSize: '32px', marginLeft: '10px' }}>欢迎登陆</span> | |||||
| <span style={{ color: '#1664ff', fontSize: '32px' }}>复杂智能软件</span> | |||||
| </div> | </div> | ||||
| <div className={containerLoginForm}> | |||||
| <div style={{color:'#1d1d20',fontSize:'22px',marginLeft:'30px',fontFamily: 'Alibaba',}}>账号登录</div> | |||||
| <LoginForm | |||||
| title="" | |||||
| className={styles.loginForm} | |||||
| initialValues={{ | |||||
| autoLogin: true, | |||||
| }} | |||||
| // actions={[ | |||||
| // <FormattedMessage | |||||
| // key="loginWith" | |||||
| // id="pages.login.loginWith" | |||||
| // defaultMessage="其他登录方式" | |||||
| // />, | |||||
| // <ActionIcons key="icons" />, | |||||
| // ]} | |||||
| onFinish={async (values) => { | |||||
| await handleSubmit(values as API.LoginParams); | |||||
| }} | |||||
| > | |||||
| {code !== 200 && loginType === 'account' && ( | |||||
| <LoginMessage | |||||
| content={intl.formatMessage({ | |||||
| id: 'pages.login.accountLogin.errorMessage', | |||||
| defaultMessage: '账户或密码错误(admin/admin123)', | |||||
| })} | |||||
| /> | |||||
| )} | |||||
| {type === 'account' && ( | |||||
| <> | |||||
| <ProFormText | |||||
| name="username" | |||||
| initialValue="admin" | |||||
| fieldProps={{ | |||||
| size: 'large', | |||||
| prefix: <UserOutlined />, | |||||
| }} | |||||
| placeholder={intl.formatMessage({ | |||||
| id: 'pages.login.username.placeholder', | |||||
| defaultMessage: '用户名: admin', | |||||
| })} | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="pages.login.username.required" | |||||
| defaultMessage="请输入用户名!" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormText.Password | |||||
| name="password" | |||||
| initialValue="admin123" | |||||
| fieldProps={{ | |||||
| size: 'large', | |||||
| prefix: <LockOutlined />, | |||||
| }} | |||||
| placeholder={intl.formatMessage({ | |||||
| id: 'pages.login.password.placeholder', | |||||
| defaultMessage: '密码: admin123', | |||||
| })} | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="pages.login.password.required" | |||||
| defaultMessage="请输入密码!" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <Row> | |||||
| <Col flex={4}> | |||||
| <ProFormText | |||||
| style={{ | |||||
| float: 'right', | |||||
| }} | |||||
| name="code" | |||||
| placeholder={intl.formatMessage({ | |||||
| id: 'pages.login.captcha.placeholder', | |||||
| defaultMessage: '请输入验证', | |||||
| })} | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="pages.searchTable.updateForm.ruleName.nameRules" | |||||
| defaultMessage="请输入验证啊" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| </Col> | |||||
| <Col > | |||||
| <Image | |||||
| src={captchaCode} | |||||
| alt="验证码" | |||||
| style={{ | |||||
| display: 'inline-block', | |||||
| verticalAlign: 'top', | |||||
| cursor: 'pointer', | |||||
| paddingLeft: '22px', | |||||
| width: '170px', | |||||
| height:'66px' | |||||
| }} | |||||
| preview={false} | |||||
| onClick={() => getCaptchaCode()} | |||||
| /> | |||||
| </Col> | |||||
| </Row> | |||||
| </> | |||||
| )} | |||||
| {code !== 200 && loginType === 'mobile' && <LoginMessage content="验证码错误" />} | |||||
| {type === 'mobile' && ( | |||||
| <> | |||||
| <ProFormText | |||||
| fieldProps={{ | |||||
| size: 'large', | |||||
| prefix: <MobileOutlined />, | |||||
| }} | |||||
| name="mobile" | |||||
| placeholder={intl.formatMessage({ | |||||
| id: 'pages.login.phoneNumber.placeholder', | |||||
| defaultMessage: '手机号', | |||||
| })} | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="pages.login.phoneNumber.required" | |||||
| defaultMessage="请输入手机号!" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| { | |||||
| pattern: /^1\d{10}$/, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="pages.login.phoneNumber.invalid" | |||||
| defaultMessage="手机号格式错误!" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormCaptcha | |||||
| fieldProps={{ | |||||
| size: 'large', | |||||
| prefix: <LockOutlined />, | |||||
| }} | |||||
| captchaProps={{ | |||||
| size: 'large', | |||||
| }} | |||||
| placeholder={intl.formatMessage({ | |||||
| id: 'pages.login.captcha.placeholder', | |||||
| defaultMessage: '请输入验证码', | |||||
| })} | |||||
| captchaTextRender={(timing, count) => { | |||||
| if (timing) { | |||||
| return `${count} ${intl.formatMessage({ | |||||
| id: 'pages.getCaptchaSecondText', | |||||
| defaultMessage: '获取验证码', | |||||
| })}`; | |||||
| } | |||||
| return intl.formatMessage({ | |||||
| id: 'pages.login.phoneLogin.getVerificationCode', | |||||
| defaultMessage: '获取验证码', | |||||
| }); | |||||
| }} | |||||
| name="captcha" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="pages.login.captcha.required" | |||||
| defaultMessage="请输入验证码!" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| ]} | |||||
| onGetCaptcha={async (phone) => { | |||||
| const result = await getFakeCaptcha({ | |||||
| phone, | |||||
| }); | |||||
| if (!result) { | |||||
| return; | |||||
| } | |||||
| message.success('获取验证码成功!验证码为:1234'); | |||||
| }} | |||||
| /> | |||||
| </> | |||||
| )} | |||||
| <div className={containerLoginForm}> | |||||
| <div | <div | ||||
| style={{ | style={{ | ||||
| marginBottom: 24, | |||||
| color: '#1d1d20', | |||||
| fontSize: '22px', | |||||
| marginLeft: '30px', | |||||
| fontFamily: 'Alibaba', | |||||
| }} | }} | ||||
| > | > | ||||
| <ProFormCheckbox noStyle name="autoLogin"> | |||||
| <FormattedMessage id="pages.login.rememberMe" defaultMessage="记住密码" /> | |||||
| </ProFormCheckbox> | |||||
| 账号登录 | |||||
| </div> | </div> | ||||
| </LoginForm> | |||||
| </div> | |||||
| <LoginForm | |||||
| title="" | |||||
| className={styles.loginForm} | |||||
| initialValues={{ | |||||
| autoLogin: true, | |||||
| }} | |||||
| // actions={[ | |||||
| // <FormattedMessage | |||||
| // key="loginWith" | |||||
| // id="pages.login.loginWith" | |||||
| // defaultMessage="其他登录方式" | |||||
| // />, | |||||
| // <ActionIcons key="icons" />, | |||||
| // ]} | |||||
| onFinish={async (values) => { | |||||
| await handleSubmit(values as API.LoginParams); | |||||
| }} | |||||
| > | |||||
| {code !== 200 && loginType === 'account' && ( | |||||
| <LoginMessage | |||||
| content={intl.formatMessage({ | |||||
| id: 'pages.login.accountLogin.errorMessage', | |||||
| defaultMessage: '账户或密码错误(admin/admin123)', | |||||
| })} | |||||
| /> | |||||
| )} | |||||
| {type === 'account' && ( | |||||
| <> | |||||
| <ProFormText | |||||
| name="username" | |||||
| initialValue="admin" | |||||
| fieldProps={{ | |||||
| size: 'large', | |||||
| prefix: <UserOutlined />, | |||||
| }} | |||||
| placeholder={intl.formatMessage({ | |||||
| id: 'pages.login.username.placeholder', | |||||
| defaultMessage: '用户名: admin', | |||||
| })} | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="pages.login.username.required" | |||||
| defaultMessage="请输入用户名!" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormText.Password | |||||
| name="password" | |||||
| initialValue="admin123" | |||||
| fieldProps={{ | |||||
| size: 'large', | |||||
| prefix: <LockOutlined />, | |||||
| }} | |||||
| placeholder={intl.formatMessage({ | |||||
| id: 'pages.login.password.placeholder', | |||||
| defaultMessage: '密码: admin123', | |||||
| })} | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="pages.login.password.required" | |||||
| defaultMessage="请输入密码!" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <Row> | |||||
| <Col flex={4}> | |||||
| <ProFormText | |||||
| style={{ | |||||
| float: 'right', | |||||
| }} | |||||
| name="code" | |||||
| placeholder={intl.formatMessage({ | |||||
| id: 'pages.login.captcha.placeholder', | |||||
| defaultMessage: '请输入验证', | |||||
| })} | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="pages.searchTable.updateForm.ruleName.nameRules" | |||||
| defaultMessage="请输入验证啊" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| </Col> | |||||
| <Col> | |||||
| <Image | |||||
| src={captchaCode} | |||||
| alt="验证码" | |||||
| style={{ | |||||
| display: 'inline-block', | |||||
| verticalAlign: 'top', | |||||
| cursor: 'pointer', | |||||
| paddingLeft: '22px', | |||||
| width: '170px', | |||||
| height: '66px', | |||||
| }} | |||||
| preview={false} | |||||
| onClick={() => getCaptchaCode()} | |||||
| /> | |||||
| </Col> | |||||
| </Row> | |||||
| </> | |||||
| )} | |||||
| {code !== 200 && loginType === 'mobile' && <LoginMessage content="验证码错误" />} | |||||
| {type === 'mobile' && ( | |||||
| <> | |||||
| <ProFormText | |||||
| fieldProps={{ | |||||
| size: 'large', | |||||
| prefix: <MobileOutlined />, | |||||
| }} | |||||
| name="mobile" | |||||
| placeholder={intl.formatMessage({ | |||||
| id: 'pages.login.phoneNumber.placeholder', | |||||
| defaultMessage: '手机号', | |||||
| })} | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="pages.login.phoneNumber.required" | |||||
| defaultMessage="请输入手机号!" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| { | |||||
| pattern: /^1\d{10}$/, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="pages.login.phoneNumber.invalid" | |||||
| defaultMessage="手机号格式错误!" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| ]} | |||||
| /> | |||||
| <ProFormCaptcha | |||||
| fieldProps={{ | |||||
| size: 'large', | |||||
| prefix: <LockOutlined />, | |||||
| }} | |||||
| captchaProps={{ | |||||
| size: 'large', | |||||
| }} | |||||
| placeholder={intl.formatMessage({ | |||||
| id: 'pages.login.captcha.placeholder', | |||||
| defaultMessage: '请输入验证码', | |||||
| })} | |||||
| captchaTextRender={(timing, count) => { | |||||
| if (timing) { | |||||
| return `${count} ${intl.formatMessage({ | |||||
| id: 'pages.getCaptchaSecondText', | |||||
| defaultMessage: '获取验证码', | |||||
| })}`; | |||||
| } | |||||
| return intl.formatMessage({ | |||||
| id: 'pages.login.phoneLogin.getVerificationCode', | |||||
| defaultMessage: '获取验证码', | |||||
| }); | |||||
| }} | |||||
| name="captcha" | |||||
| rules={[ | |||||
| { | |||||
| required: true, | |||||
| message: ( | |||||
| <FormattedMessage | |||||
| id="pages.login.captcha.required" | |||||
| defaultMessage="请输入验证码!" | |||||
| /> | |||||
| ), | |||||
| }, | |||||
| ]} | |||||
| onGetCaptcha={async (phone) => { | |||||
| const result = await getFakeCaptcha({ | |||||
| phone, | |||||
| }); | |||||
| if (!result) { | |||||
| return; | |||||
| } | |||||
| message.success('获取验证码成功!验证码为:1234'); | |||||
| }} | |||||
| /> | |||||
| </> | |||||
| )} | |||||
| <div | |||||
| style={{ | |||||
| marginBottom: 24, | |||||
| }} | |||||
| > | |||||
| <ProFormCheckbox noStyle name="autoLogin"> | |||||
| <FormattedMessage id="pages.login.rememberMe" defaultMessage="记住密码" /> | |||||
| </ProFormCheckbox> | |||||
| </div> | |||||
| </LoginForm> | |||||
| </div> | |||||
| </div> | </div> | ||||
| {/* <Helmet> | {/* <Helmet> | ||||
| <title> | <title> | ||||