| @@ -1,5 +1,5 @@ | |||||
| # 基础镜像 | # 基础镜像 | ||||
| FROM 172.20.32.187/ci4s/jdk:1.8_u422 | |||||
| FROM 172.20.32.187/ci4s/openjdk:8u162 | |||||
| #FROM 172.20.32.187/ci4s/openjdk-dvc:2024829 | #FROM 172.20.32.187/ci4s/openjdk-dvc:2024829 | ||||
| # author | # author | ||||
| MAINTAINER ruoyi | MAINTAINER ruoyi | ||||
| @@ -22,6 +22,7 @@ export { requestConfig as request } from './requestConfig'; | |||||
| // const isDev = process.env.NODE_ENV === 'development'; | // const isDev = process.env.NODE_ENV === 'development'; | ||||
| import { type GlobalInitialState } from '@/types'; | import { type GlobalInitialState } from '@/types'; | ||||
| import { menuItemRender } from '@/utils/menuRender'; | import { menuItemRender } from '@/utils/menuRender'; | ||||
| import ErrorBoundary from './components/ErrorBoundary'; | |||||
| import { gotoLoginPage } from './utils/ui'; | import { gotoLoginPage } from './utils/ui'; | ||||
| /** | /** | ||||
| @@ -65,6 +66,7 @@ export async function getInitialState(): Promise<GlobalInitialState> { | |||||
| // ProLayout 支持的api https://procomponents.ant.design/components/layout | // ProLayout 支持的api https://procomponents.ant.design/components/layout | ||||
| export const layout: RuntimeConfig['layout'] = ({ initialState }) => { | export const layout: RuntimeConfig['layout'] = ({ initialState }) => { | ||||
| return { | return { | ||||
| ErrorBoundary: ErrorBoundary, | |||||
| rightContentRender: false, | rightContentRender: false, | ||||
| waterMarkProps: { | waterMarkProps: { | ||||
| // content: initialState?.currentUser?.nickName, | // content: initialState?.currentUser?.nickName, | ||||
| @@ -0,0 +1,78 @@ | |||||
| import KFEmpty, { EmptyType } from '@/components/KFEmpty'; | |||||
| import { Button } from 'antd'; | |||||
| import { Component, ReactNode } from 'react'; | |||||
| interface ErrorBoundaryProps { | |||||
| children: ReactNode; | |||||
| fallback?: ReactNode; // Optional fallback UI to show in case of error | |||||
| } | |||||
| interface ErrorBoundaryState { | |||||
| hasError: boolean; | |||||
| error: Error | null; | |||||
| } | |||||
| class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> { | |||||
| constructor(props: ErrorBoundaryProps) { | |||||
| super(props); | |||||
| this.state = { | |||||
| hasError: false, | |||||
| error: null, | |||||
| }; | |||||
| } | |||||
| static getDerivedStateFromError(error: Error): ErrorBoundaryState { | |||||
| // Update state so the next render shows the fallback UI | |||||
| return { hasError: true, error }; | |||||
| } | |||||
| // componentDidCatch(error: Error, errorInfo: ErrorInfo) { | |||||
| // // You can log the error to an error reporting service here | |||||
| // console.error('Error caught by ErrorBoundary:', error.message, errorInfo.componentStack); | |||||
| // } | |||||
| render() { | |||||
| if (this.state.hasError) { | |||||
| return this.props.fallback || <ErrorBoundaryFallback error={this.state.error} />; | |||||
| } | |||||
| return this.props.children; | |||||
| } | |||||
| } | |||||
| function ErrorBoundaryFallback({ error }: { error: Error | null }) { | |||||
| const message = error && error instanceof Error ? error.message : 'Unknown error'; | |||||
| const errorMsg = | |||||
| process.env.NODE_ENV === 'development' ? message : '非常抱歉,程序运行错误,\n我们会尽快修复。'; | |||||
| return ( | |||||
| <KFEmpty | |||||
| style={{ height: '100vh' }} | |||||
| type={EmptyType.NotFound} | |||||
| title="出错了" | |||||
| content={errorMsg} | |||||
| footer={() => { | |||||
| return ( | |||||
| <> | |||||
| <Button | |||||
| type="default" | |||||
| onClick={() => { | |||||
| window.history.pushState({}, '', '/'); | |||||
| window.location.reload(); | |||||
| }} | |||||
| > | |||||
| 返回首页 | |||||
| </Button> | |||||
| <Button | |||||
| type="primary" | |||||
| style={{ marginLeft: 20 }} | |||||
| onClick={() => window.location.reload()} | |||||
| > | |||||
| 刷新 | |||||
| </Button> | |||||
| </> | |||||
| ); | |||||
| }} | |||||
| ></KFEmpty> | |||||
| ); | |||||
| } | |||||
| export default ErrorBoundary; | |||||
| @@ -18,6 +18,7 @@ | |||||
| } | } | ||||
| &__content { | &__content { | ||||
| max-width: 50%; | |||||
| margin-top: 15px; | margin-top: 15px; | ||||
| color: @text-color-secondary; | color: @text-color-secondary; | ||||
| font-size: 15px; | font-size: 15px; | ||||
| @@ -37,7 +37,7 @@ function KFEmpty({ | |||||
| type, | type, | ||||
| title, | title, | ||||
| content, | content, | ||||
| hasFooter = false, | |||||
| hasFooter = true, | |||||
| footer, | footer, | ||||
| buttonTitle = '刷新', | buttonTitle = '刷新', | ||||
| onRefresh, | onRefresh, | ||||
| @@ -1,146 +1,159 @@ | |||||
| import BasicInfo, { BasicInfoData } from '@/components/BasicInfo'; | import BasicInfo, { BasicInfoData } from '@/components/BasicInfo'; | ||||
| import SubAreaTitle from '@/components/SubAreaTitle'; | import SubAreaTitle from '@/components/SubAreaTitle'; | ||||
| import { ResourceData, ResourceType } from '@/pages/Dataset/config'; | |||||
| import { DatasetData, ModelData, ResourceType } from '@/pages/Dataset/config'; | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| type ResourceIntroProps = { | type ResourceIntroProps = { | ||||
| resourceType: ResourceType; | resourceType: ResourceType; | ||||
| info: ResourceData; | |||||
| info: DatasetData | ModelData; | |||||
| }; | }; | ||||
| const formatArray = (arr?: string[]) => { | |||||
| // const formatArray = (arr?: ResourceData[]) => { | |||||
| // if (!arr || arr.length === 0) { | |||||
| // return '--'; | |||||
| // } | |||||
| // return arr.map((item) => item.name).join('\n'); | |||||
| // }; | |||||
| const formatDataset = (arr?: DatasetData[]) => { | |||||
| if (!arr || arr.length === 0) { | if (!arr || arr.length === 0) { | ||||
| return '--'; | |||||
| return undefined; | |||||
| } | } | ||||
| return arr.join('\n'); | |||||
| return arr.map((item) => item.name).join('\n'); | |||||
| }; | }; | ||||
| const formatMap = (map?: Record<string, string>) => { | const formatMap = (map?: Record<string, string>) => { | ||||
| if (!map || Object.keys(map).length === 0) { | if (!map || Object.keys(map).length === 0) { | ||||
| return '--'; | |||||
| return undefined; | |||||
| } | } | ||||
| return Object.entries(map) | return Object.entries(map) | ||||
| .map(([key, value]) => `${key} = ${value}`) | .map(([key, value]) => `${key} = ${value}`) | ||||
| .join('\n'); | .join('\n'); | ||||
| }; | }; | ||||
| function ResourceIntro({ resourceType, info }: ResourceIntroProps) { | |||||
| const datasetDatas: BasicInfoData[] = [ | |||||
| { | |||||
| label: '数据集名称', | |||||
| value: info.name, | |||||
| }, | |||||
| { | |||||
| label: '版本', | |||||
| value: info.version, | |||||
| }, | |||||
| { | |||||
| label: '创建人', | |||||
| value: info.create_by, | |||||
| }, | |||||
| { | |||||
| label: '更新时间', | |||||
| value: info.update_time, | |||||
| }, | |||||
| { | |||||
| label: '数据来源', | |||||
| value: info.dataset_source, | |||||
| }, | |||||
| { | |||||
| label: '处理代码', | |||||
| value: info.processing_code, | |||||
| }, | |||||
| { | |||||
| label: '数据集分类', | |||||
| value: info.data_type, | |||||
| }, | |||||
| { | |||||
| label: '研究方向', | |||||
| value: info.data_tag, | |||||
| }, | |||||
| { | |||||
| label: '数据集描述', | |||||
| value: info.description, | |||||
| }, | |||||
| { | |||||
| label: '版本描述', | |||||
| value: info.version_desc, | |||||
| }, | |||||
| ]; | |||||
| const getDatasetDatas = (data: DatasetData): BasicInfoData[] => [ | |||||
| { | |||||
| label: '数据集名称', | |||||
| value: data.name, | |||||
| }, | |||||
| { | |||||
| label: '版本', | |||||
| value: data.version, | |||||
| }, | |||||
| { | |||||
| label: '创建人', | |||||
| value: data.create_by, | |||||
| }, | |||||
| { | |||||
| label: '更新时间', | |||||
| value: data.update_time, | |||||
| }, | |||||
| { | |||||
| label: '数据来源', | |||||
| value: data.dataset_source, | |||||
| }, | |||||
| { | |||||
| label: '处理代码', | |||||
| value: data.processing_code, | |||||
| }, | |||||
| { | |||||
| label: '数据集分类', | |||||
| value: data.data_type, | |||||
| }, | |||||
| { | |||||
| label: '研究方向', | |||||
| value: data.data_tag, | |||||
| }, | |||||
| { | |||||
| label: '数据集描述', | |||||
| value: data.description, | |||||
| }, | |||||
| { | |||||
| label: '版本描述', | |||||
| value: data.version_desc, | |||||
| }, | |||||
| ]; | |||||
| const modelDatas: BasicInfoData[] = [ | |||||
| { | |||||
| label: '模型名称', | |||||
| value: info.name, | |||||
| }, | |||||
| { | |||||
| label: '版本', | |||||
| value: info.version, | |||||
| }, | |||||
| { | |||||
| label: '创建人', | |||||
| value: info.create_by, | |||||
| }, | |||||
| { | |||||
| label: '更新时间', | |||||
| value: info.update_time, | |||||
| }, | |||||
| { | |||||
| label: '训练镜像', | |||||
| value: info.image, | |||||
| }, | |||||
| { | |||||
| label: '训练代码', | |||||
| value: info.code, | |||||
| }, | |||||
| { | |||||
| label: '训练数据集', | |||||
| value: info.train_datasets, | |||||
| format: formatArray, | |||||
| }, | |||||
| { | |||||
| label: '测试数据集', | |||||
| value: info.test_datasets, | |||||
| format: formatArray, | |||||
| }, | |||||
| { | |||||
| label: '参数', | |||||
| value: info.params, | |||||
| format: formatMap, | |||||
| }, | |||||
| { | |||||
| label: '指标', | |||||
| value: info.metrics, | |||||
| format: formatMap, | |||||
| }, | |||||
| { | |||||
| label: '训练任务', | |||||
| value: info.train_task, | |||||
| }, | |||||
| { | |||||
| label: '模型来源', | |||||
| value: info.model_source, | |||||
| }, | |||||
| { | |||||
| label: '模型框架', | |||||
| value: info.model_type, | |||||
| }, | |||||
| { | |||||
| label: '模型能力', | |||||
| value: info.model_tag, | |||||
| }, | |||||
| { | |||||
| label: '模型描述', | |||||
| value: info.description, | |||||
| }, | |||||
| { | |||||
| label: '版本描述', | |||||
| value: info.version_desc, | |||||
| }, | |||||
| ]; | |||||
| const getModelDatas = (data: ModelData): BasicInfoData[] => [ | |||||
| { | |||||
| label: '模型名称', | |||||
| value: data.name, | |||||
| }, | |||||
| { | |||||
| label: '版本', | |||||
| value: data.version, | |||||
| }, | |||||
| { | |||||
| label: '创建人', | |||||
| value: data.create_by, | |||||
| }, | |||||
| { | |||||
| label: '更新时间', | |||||
| value: data.update_time, | |||||
| }, | |||||
| { | |||||
| label: '训练镜像', | |||||
| value: data.image, | |||||
| }, | |||||
| { | |||||
| label: '训练代码', | |||||
| value: data.code, | |||||
| }, | |||||
| { | |||||
| label: '训练数据集', | |||||
| value: data.train_datasets, | |||||
| format: formatDataset, | |||||
| }, | |||||
| { | |||||
| label: '测试数据集', | |||||
| value: data.test_datasets, | |||||
| format: formatDataset, | |||||
| }, | |||||
| { | |||||
| label: '参数', | |||||
| value: data.params, | |||||
| format: formatMap, | |||||
| }, | |||||
| { | |||||
| label: '指标', | |||||
| value: data.metrics, | |||||
| format: formatMap, | |||||
| }, | |||||
| { | |||||
| label: '训练任务', | |||||
| value: data.train_task, | |||||
| format: (value?: any) => value?.name, | |||||
| externalLink: data.train_task | |||||
| ? `${location.origin}/pipeline/experiment/instance/${data.train_task.task_id}/${data.train_task.ins_id}` | |||||
| : '', | |||||
| }, | |||||
| { | |||||
| label: '模型来源', | |||||
| value: data.model_source, | |||||
| }, | |||||
| { | |||||
| label: '模型框架', | |||||
| value: data.model_type, | |||||
| }, | |||||
| { | |||||
| label: '模型能力', | |||||
| value: data.model_tag, | |||||
| }, | |||||
| { | |||||
| label: '模型描述', | |||||
| value: data.description, | |||||
| }, | |||||
| { | |||||
| label: '版本描述', | |||||
| value: data.version_desc, | |||||
| }, | |||||
| ]; | |||||
| function ResourceIntro({ resourceType, info }: ResourceIntroProps) { | |||||
| const basicDatas: BasicInfoData[] = | const basicDatas: BasicInfoData[] = | ||||
| resourceType === ResourceType.Dataset ? datasetDatas : modelDatas; | |||||
| resourceType === ResourceType.Dataset | |||||
| ? getDatasetDatas(info as DatasetData) | |||||
| : getModelDatas(info as ModelData); | |||||
| return ( | return ( | ||||
| <div className={styles['resource-intro']}> | <div className={styles['resource-intro']}> | ||||
| @@ -128,7 +128,7 @@ export type CategoryData = { | |||||
| }; | }; | ||||
| // 数据集、模型列表数据 | // 数据集、模型列表数据 | ||||
| export type ResourceData = { | |||||
| export interface ResourceData { | |||||
| id: number; | id: number; | ||||
| name: string; | name: string; | ||||
| identifier: string; | identifier: string; | ||||
| @@ -142,25 +142,34 @@ export type ResourceData = { | |||||
| version_desc?: string; | version_desc?: string; | ||||
| usage?: string; | usage?: string; | ||||
| relative_paths?: string; | relative_paths?: string; | ||||
| // 数据集 | |||||
| resourceType: ResourceType.Dataset | ResourceType.Model; | |||||
| } | |||||
| // 数据集数据 | |||||
| export interface DatasetData extends ResourceData { | |||||
| resourceType: ResourceType.Dataset; // 用于区别类型 | |||||
| data_type?: string; // 数据集分类 | data_type?: string; // 数据集分类 | ||||
| data_tag?: string; // 研究方向 | data_tag?: string; // 研究方向 | ||||
| processing_code?: string; // 处理代码 | processing_code?: string; // 处理代码 | ||||
| dataset_source?: string; // 数据来源 | dataset_source?: string; // 数据来源 | ||||
| dataset_version_vos: ResourceFileData[]; | |||||
| // 模型 | |||||
| dataset_version_vos?: ResourceFileData[]; | |||||
| } | |||||
| // 模型数据 | |||||
| export interface ModelData extends ResourceData { | |||||
| resourceType: ResourceType.Model; // 用于区别类型 | |||||
| model_type?: string; // 模型框架 | model_type?: string; // 模型框架 | ||||
| model_tag?: string; // 模型能力 | model_tag?: string; // 模型能力 | ||||
| image?: string; // 训练镜像 | image?: string; // 训练镜像 | ||||
| code?: string; // 训练镜像 | code?: string; // 训练镜像 | ||||
| train_datasets?: string[]; // 训练数据集 | |||||
| test_datasets?: string[]; // 测试数据集 | |||||
| train_datasets?: DatasetData[]; // 训练数据集 | |||||
| test_datasets?: DatasetData[]; // 测试数据集 | |||||
| params?: Record<string, string>; // 参数 | params?: Record<string, string>; // 参数 | ||||
| metrics?: Record<string, string>; // 指标 | metrics?: Record<string, string>; // 指标 | ||||
| train_task?: string; // 训练任务 | |||||
| train_task?: TrainTask; // 训练任务 | |||||
| model_source?: string; // 模型来源 | model_source?: string; // 模型来源 | ||||
| model_version_vos: ResourceFileData[]; | |||||
| }; | |||||
| model_version_vos?: ResourceFileData[]; | |||||
| } | |||||
| // 版本数据 | // 版本数据 | ||||
| export type ResourceVersionData = { | export type ResourceVersionData = { | ||||
| @@ -177,3 +186,10 @@ export type ResourceFileData = { | |||||
| url: string; | url: string; | ||||
| update_time?: string; | update_time?: string; | ||||
| }; | }; | ||||
| // 训练任务 | |||||
| export type TrainTask = { | |||||
| ins_id: number; | |||||
| name: string; | |||||
| task_id: string; | |||||
| }; | |||||
| @@ -1,3 +1,4 @@ | |||||
| import { TrainTask } from '@/pages/Dataset/config'; | |||||
| import { changePropertyName, fittingString } from '@/utils'; | import { changePropertyName, fittingString } from '@/utils'; | ||||
| import { EdgeConfig, GraphData, LayoutConfig, NodeConfig, TreeGraphData, Util } from '@antv/g6'; | import { EdgeConfig, GraphData, LayoutConfig, NodeConfig, TreeGraphData, Util } from '@antv/g6'; | ||||
| // @ts-ignore | // @ts-ignore | ||||
| @@ -31,12 +32,6 @@ export type Rect = { | |||||
| height: number; | height: number; | ||||
| }; | }; | ||||
| export type TrainTask = { | |||||
| ins_id: number; | |||||
| name: string; | |||||
| task_id: string; | |||||
| }; | |||||
| export interface TrainDataset extends NodeConfig { | export interface TrainDataset extends NodeConfig { | ||||
| repo_id: number; | repo_id: number; | ||||
| name: string; | name: string; | ||||
| @@ -110,6 +110,7 @@ public class HttpUtils { | |||||
| * @return 所代表远程资源的响应结果 | * @return 所代表远程资源的响应结果 | ||||
| */ | */ | ||||
| public static String sendGetWithToken(String url, String param, String token) { | public static String sendGetWithToken(String url, String param, String token) { | ||||
| System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2"); | |||||
| String result = ""; | String result = ""; | ||||
| try (CloseableHttpClient httpClient = HttpClients.createDefault()) { | try (CloseableHttpClient httpClient = HttpClients.createDefault()) { | ||||
| URIBuilder uriBuilder = new URIBuilder(url); | URIBuilder uriBuilder = new URIBuilder(url); | ||||