feat: 初始化算力中心

develop2
donghao 1 year ago
parent c427830ef6
commit 9f81eed868

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-03-27 14:56:27
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-20 15:20:34
* @LastEditTime: 2024-06-07 13:53:32
* @FilePath: \general-ai-manage\config\routes.ts
* @Description:
*/
@ -19,7 +19,9 @@
* @doc https://umijs.org/docs/guides/routes
*/
// 主页路由模块
/** 主页路由模块 */
// 首页
export const homeRoute = [
{
name: 'home-business-project',
@ -31,6 +33,30 @@ export const homeRoute = [
},
];
// 算力中心
export const computePowerCenterRoute = [
{
name: 'computePower-center',
path: '/home/computePower-center',
component: './ComputePowerCenter',
access: 'canReadMenu',
key: 'ComputePowerCenter001',
level: 1, // 一级菜单
},
];
// 系统日志
// 算力中心
export const logRoute = [
{
name: 'log-index',
path: '/home/log-index',
component: './Log',
access: 'canReadMenu',
key: 'LogIndex001',
level: 1, // 一级菜单
},
];
/**
* @
* @param modelRouteIndex
@ -101,7 +127,7 @@ export const outerMenuRoute = {
layout: false,
access: 'canReadMenu',
component: '@/layouts/HomeLayout',
routes: [...homeRoute, ...modelRoute],
routes: [...homeRoute, ...modelRoute, ...computePowerCenterRoute, ...logRoute],
};
/**

@ -0,0 +1,30 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-25 13:34:56
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-03-11 13:55:06
* @FilePath: \general-ai-platform-web\mock\modelCategory.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
/**模型类别模块 mock */
import { powerGroupListData, powerPoolsListData } from './pools/computePowerData';
import { successMockApiProps } from './typing';
import { fetchMockSuccessFullByOther } from './utils/apiMock';
export default {
// 算力分配类别
'POST /api/v1/compute_power/getPowerGroupList': async (req: Request, res: Response) => {
const resData: successMockApiProps = {
...fetchMockSuccessFullByOther(powerGroupListData),
};
res.send(resData);
},
// 算力分配池
'POST /api/v1/compute_power/getPowerPoolsList': async (req: Request, res: Response) => {
const resData: successMockApiProps = {
...fetchMockSuccessFullByOther(powerPoolsListData),
};
res.send(resData);
},
};

@ -0,0 +1,122 @@
export type ComputePowerPoolItem = {
name: string;
type: number; // 类别
color?: string; //
proportion: number;
pretreatmentEfficiency?: number;
bgColor?: string;
};
const groupList: Record<string, any>[] = [
{
label: 'NVIDIA GeForce 4090',
type: 1,
},
{
label: '瑞芯微 RK3566',
type: 0,
},
{
label: '瑞芯微 RK3566',
type: 0,
},
{
label: 'NVIDIA GeForce 4090',
type: 1,
},
{
label: 'NVIDIA GeForce 4090',
type: 1,
},
];
const poolsData: ComputePowerPoolItem[] = [
{
name: '焊线颜色检测',
type: 9,
proportion: 7,
pretreatmentEfficiency: 20,
color: '#014BE6',
bgColor: 'linear-gradient(180deg, #015DE6 0%, #4881F6 100%)',
},
{
name: '螺纹缺陷检测',
type: 8,
proportion: 8,
pretreatmentEfficiency: 20,
color: '#FAA90B',
bgColor: 'linear-gradient(180deg, #E64601 0%, #F6A648 100%)',
},
{
name: 'PIN间距测量',
type: 7,
proportion: 4,
pretreatmentEfficiency: 15,
color: '#EA1281',
bgColor: 'linear-gradient(180deg, #E60161 0%, #F648E5 100%)',
},
{
name: '螺纹无牙缺陷检测',
type: 6,
proportion: 7,
pretreatmentEfficiency: 20,
color: '#FA8616',
bgColor: 'linear-gradient(180deg, #FA8316 0%, #FAAD16 100%)',
},
{
name: '压板缺陷检测',
type: 5,
proportion: 32,
pretreatmentEfficiency: 38,
color: '#F9DB18',
bgColor: 'linear-gradient(180deg, #FFC56F 0%, #F9E006 100%)',
},
{
name: '划伤缺陷检测',
type: 4,
proportion: 8,
pretreatmentEfficiency: 38,
color: '#1CCCFA',
bgColor: 'linear-gradient(180deg, #6FFFFF 0%, #06BEF9 100%)',
},
{
name: '披锋(毛刺)缺陷检测',
type: 3,
proportion: 12,
pretreatmentEfficiency: 38,
color: '#9E26EE',
bgColor: 'linear-gradient(180deg, #FF2494 0%, #8D27FF 100%)',
},
{
name: '工件尺寸测量',
type: 2,
proportion: 7,
pretreatmentEfficiency: 38,
color: '#6F50F6',
bgColor: 'linear-gradient(180deg, #6B55F6 0%, #8C38F8 100%)',
},
{
name: '打孔不良检测',
type: 1,
proportion: 5,
pretreatmentEfficiency: 38,
color: '#24ED75',
bgColor: 'linear-gradient(180deg, #43EA80 0%, #38F8D4 100%)',
},
{
name: '空闲算力',
type: 0,
proportion: 10,
pretreatmentEfficiency: 0,
color: '#DCDCDC',
bgColor: 'linear-gradient(90deg, #7B7979 0%, #C1C1C1 100%)',
},
];
export const powerGroupListData = {
data: groupList,
};
export const powerPoolsListData = {
data: poolsData,
};

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 660 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.1 MiB

Before

Width:  |  Height:  |  Size: 384 KiB

After

Width:  |  Height:  |  Size: 384 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 290 B

Before

Width:  |  Height:  |  Size: 289 B

After

Width:  |  Height:  |  Size: 289 B

@ -0,0 +1,27 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
>
<path
d="M12 22C14.7614 22 17.2614 20.8807 19.0711 19.0711C20.8807 17.2614 22 14.7614 22 12C22 9.2386 20.8807 6.7386 19.0711 4.92893C17.2614 3.11929 14.7614 2 12 2C9.2386 2 6.7386 3.11929 4.92893 4.92893C3.11929 6.7386 2 9.2386 2 12C2 14.7614 3.11929 17.2614 4.92893 19.0711C6.7386 20.8807 9.2386 22 12 22Z"
stroke="#FAAD14"
stroke-width="2"
stroke-linejoin="round"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12 18.5C12.6904 18.5 13.25 17.9404 13.25 17.25C13.25 16.5597 12.6904 16 12 16C11.3097 16 10.75 16.5597 10.75 17.25C10.75 17.9404 11.3097 18.5 12 18.5Z"
fill="#FAAD14"
/>
<path
d="M12 6V14"
stroke="#FAAD14"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>

After

Width:  |  Height:  |  Size: 869 B

@ -0,0 +1,24 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
>
<path
d="M8.948 8.7975V7.3675C9.08911 7.35702 9.23051 7.35102 9.372 7.3495C13.294 7.2255 15.865 10.7235
15.865 10.7235C15.865 10.7235 13.091 14.5745 10.115 14.5745C9.72158 14.5753 9.33059 14.5128 8.957
14.3895V10.0435C10.485 10.2285 10.794 10.9005 11.704 12.4285L13.744 10.7145C13.744 10.7145 12.252
8.7625 9.744 8.7625C9.47818 8.75656 9.21227 8.76826 8.948 8.7975ZM8.948 4.0625V6.2005L9.372
6.1735C14.822 5.9885 18.382 10.6435 18.382 10.6435C18.382 10.6435 14.302 15.6075 10.052
15.6075C9.68491 15.6063 9.31858 15.5739 8.957 15.5105V16.8355C9.257 16.8705 9.567 16.8975 9.867
16.8975C13.824 16.8975 16.687 14.8745 19.46 12.4895C19.919 12.8605 21.8 13.7525 22.19 14.1415C19.557
16.3495 13.418 18.1255 9.937 18.1255C9.602 18.1255 9.284 18.1075 8.966
18.0725V19.9365H24V4.0625H8.948ZM8.948 14.3885V15.5195C5.291 14.8655 4.275 11.0595 4.275
11.0595C4.275 11.0595 6.033 9.1155 8.948 8.7975V10.0345H8.94C7.412 9.8485 6.21 11.2795 6.21
11.2795C6.21 11.2795 6.89 13.6915 8.949 14.3895M2.456 10.8995C2.456 10.8995 4.62 7.7025 8.956
7.3665V6.2005C4.153 6.5895 0 10.6525 0 10.6525C0 10.6525 2.35 17.4545 8.948 18.0725V16.8355C4.108
16.2355 2.456 10.8995 2.456 10.8995Z"
fill="#76B900"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -30,7 +30,7 @@ const InnerPageBack: React.FC<CommButtonProps> = (props) => {
}
}
return (
<div className="flex items-center innerPageBack_wrap mb-[16px] " onClick={doBack}>
<div className="flex items-center innerPageBack_wrap mb-[16px] cursor-pointer" onClick={doBack}>
<ArrowLeftOutlined style={{ fontSize: `${props.size || 18}px` }} />
{/* <i className="iconfont"></i> */}
<span className="h1 ml-[8px]" style={{ fontSize: `${props.size || 18}px` }}>

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-06-04 15:14:27
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-05 15:37:03
* @LastEditTime: 2024-06-07 17:27:54
* @FilePath: \general-ai-platform-web\src\components\UploadFile\src\FormUploadDraggerToken.tsx
* @Description:
* // TODO 需要支持多文件上传
@ -53,10 +53,11 @@ const FormUploadDraggerToken: React.FC<FormUploadDraggerTokenProps> = (props) =>
if (isSuccessApi(resp)) {
setFileList([
{
uid: resp?.data?.result,
uid: file?.uid,
name: file?.name,
status: 'done',
url: '/file/' + resp?.data?.result,
fileId: resp?.data?.result,
},
]);
props.afterUploadFile({ resp, file, fileList });
@ -79,8 +80,9 @@ const FormUploadDraggerToken: React.FC<FormUploadDraggerTokenProps> = (props) =>
/**
*/
const onRemoveFile = async (file: UploadFile<R<string>>) => {
console.log(file, 'onRemoveFile_file');
const resp = await apiFileDelete({ file_md5: file?.uid });
console.log(file, 'onRemoveFile_file', fileList);
const currFile = fileList.find((item) => item.uid === file.uid);
const resp = await apiFileDelete({ file_md5: currFile?.fileId });
console.log(resp, 'apiFileDelete_resp');
props.afterRemoveFile(resp, file);
if (isSuccessApi(resp)) {
@ -119,7 +121,6 @@ const FormUploadDraggerToken: React.FC<FormUploadDraggerTokenProps> = (props) =>
beforeUpload: beforeUploadFile,
}}
/>
<div style={{ color: '#666666', marginTop: '-8px' }}>{props.nextText}</div>
</>
);
};

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-01 11:20:09
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-17 13:46:58
* @LastEditTime: 2024-06-07 13:53:41
* @FilePath: \uighur-recognition-web2\src\locales\zh-CN\menu.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
@ -61,6 +61,8 @@ export default {
'menu.home-business-project': '企业项目',
'menu.model-manage': '模型管理',
'menu.model-index': '模型列表',
'menu.computePower-center': '算力中心',
'menu.log-index': '系统日志',
'menu.model-runtime-lib': '模型运行库',
'menu.business-info-index': '企业信息',

@ -98,6 +98,9 @@ export const business_model: { [key: string]: string } = {
'business_model.stepForm.project_file.description': '上传业务代码',
'business_model.stepForm.config': '参数配置',
'business_model.stepForm.config.description': '配置业务参数',
'business_model.stepForm.group': '关联节点',
'business_model.stepForm.group.description': '关联相关设备节点',
'business_model.form.modelFkId': '业务模型名称',
'business_model.form.remark': '简介',
'business_model.table.list.isEnable': '部署状态',

@ -1,20 +1,16 @@
import { FormUploadDraggerToken } from '@/components/UploadFile';
import { apiEntityNodes } from '@/services/business/entity';
import { apiModelDeploymentAdd } from '@/services/business/model';
import { isSuccessApi } from '@/utils/forApi';
import {
ProForm,
ProFormInstance,
ProFormList,
ProFormSelect,
ProFormText,
ProFormTextArea,
ProFormUploadDragger,
StepsForm,
} from '@ant-design/pro-components';
import { FormListActionType } from '@ant-design/pro-form/lib';
import { getBaseBusinessModelList } from '@/services/testApi/businessModel';
import { getDeviceGroupTree } from '@/services/testApi/deviceGroup';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Modal, Transfer, Tree, UploadFile, message } from 'antd';
import yaml from 'js-yaml';
import { Modal, Transfer, Tree } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import {
proFormMaxItemStyleProps,
@ -23,22 +19,14 @@ import {
} from '../../../../../config/defaultForm';
// import {beforeUploadFile} from "@/utils/common";
// @ts-ignore
import cookie from 'react-cookies';
export type FormValueType = {
target?: string;
template?: string;
type?: string;
time?: string;
frequency?: string;
} & Partial<API.ModelVersion>;
import { apiModelListSimple } from '@/services/business/model';
import { isArrayAndNotEmpty } from '@/utils/is';
export type CreateFormProps = {
createModalOpen: boolean;
handleModal: () => void;
values: Partial<API.ModelVersion>;
commInfo: Record<string, any>;
reload: any;
currentDefaultFieldsData?: Record<string, any>;
};
const waitTime = (time: number = 100) => {
return new Promise((resolve) => {
@ -51,53 +39,28 @@ const waitTime = (time: number = 100) => {
// params: Array<object>;
// }
const CreateForm: React.FC<CreateFormProps> = (props) => {
const actionFormListRef = useRef<
FormListActionType<{
name: string;
}>
>();
const intl = useIntl();
const [isHasModelFkId, setIsHasModelFkId] = useState<boolean>(false);
const [dataFormList] = useState<any>([]);
const dataFormListRef = useRef(dataFormList);
const [fileList, setFileList] = useState<UploadFile<any>[]>([]);
// state
const [currFormData, setCurrFormData] = useState<Record<string, any>>({});
// 关联模型state
const [modalData, setModalData] = useState<RecordType[]>([]);
const [targetKeys, setTargetKeys] = useState<string[]>([]);
const [modelLinkKeys, setModelLinkKeys] = useState<string[]>([]);
// 关联节点state
const [treeData, setTreeData] = React.useState<DataNode[]>([]);
const [selectKeys, setSelectKeys] = useState([]);
const [deviceTreeList, setDeviceTreeList] = useState<Record<string, any>[]>([]);
const [deviceLinkKeys, setDeviceLinkKeys] = useState([]);
// const [form] = Form.useForm<API.ModelVersion>();
const [current, setCurrent] = useState(0);
const formRef = useRef<ProFormInstance>();
const [filePath, setFilePath] = useState('');
const handleFileChange = ({ file }: { file: UploadFile }) => {
let curFile: any;
switch (file.status) {
case 'uploading':
case 'done':
curFile = [file];
break;
case 'removed':
default:
curFile = [];
break;
}
setFileList([...curFile]);
};
// todo disabled: !v?.defaultVersionFkId,设置 暂时设置为false 创建成功后报error
const getModelData = () => {
getBaseBusinessModelList({ keyword: '', pageNo: 1, pageSize: 100 }).then((res) => {
console.log(66666, res.data);
let result = (res.data?.data || []).map((v: any) => {
// 获取所有模型选项
const loadModelData = async () => {
const resp = await apiModelListSimple();
if (isSuccessApi(resp) && resp?.data) {
console.log('apiModelListSimple_resp', resp.data);
let result = (resp.data?.result || []).map((v: any) => {
console.log(v);
return {
key: v.id,
@ -107,44 +70,76 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
};
});
setModalData(result);
});
// setMockData(tempMockData);
// setTargetKeys(tempTargetKeys);
}
};
// 设备节点树
async function loadDeviceTree() {
const resp = await apiEntityNodes({ entity_id: props.commInfo.id });
if (isSuccessApi(resp)) {
setDeviceTreeList(resp?.data.data);
}
}
const handleChange = (newTargetKeys: string[]) => {
setTargetKeys(newTargetKeys);
console.log(newTargetKeys, 'newTargetKeys');
setModelLinkKeys(newTargetKeys);
};
useEffect(() => {
setTargetKeys([]);
console.log('selectKeys', selectKeys);
setModelLinkKeys([]);
console.log('deviceLinkKeys', deviceLinkKeys);
if (props.createModalOpen) {
getModelData();
getDeviceGroupTree()
.then((resp: API.Response) => {
setTreeData(resp.data.tree);
})
.catch(() => {});
loadModelData();
loadDeviceTree();
} else {
formRef.current?.resetFields();
}
}, [props.createModalOpen]);
// test 测试数据
useEffect(() => {
if (props.currentDefaultFieldsData) {
// 如果是在模型详情新增版本ModelFkId不可编辑
console.log(props.values, isHasModelFkId, 'currentDefaultFieldsData');
setIsHasModelFkId(true);
} else {
setIsHasModelFkId(false);
}
}, []);
// 初始化赋值
setCurrFormData({
name: '晶圆检测工艺00',
comment:
'测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注',
});
}, [props.createModalOpen]);
return (
<div>
<StepsForm<{
name: string;
}>
onFinish={async (values) => {
console.log('All form values:', values, {
...currFormData,
entity_id: props.commInfo.id,
basemodel_ids: modelLinkKeys,
link_node_ids: deviceLinkKeys,
});
// 在这里处理提交数据例如调用API
let resp = await apiModelDeploymentAdd({
...values,
entity_id: props.commInfo.id,
basemodel_ids: isArrayAndNotEmpty(modelLinkKeys) ? modelLinkKeys.join(',') : '',
business_logic: currFormData?.business_logic,
business_conf_file: currFormData?.business_conf_file,
link_node_ids: isArrayAndNotEmpty(deviceLinkKeys) ? deviceLinkKeys.join(',') : '',
});
if (isSuccessApi(resp)) {
message.success(
intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }),
);
props.reload();
props.handleModal();
} else {
message.error(
resp?.meta?.message ||
intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }),
);
}
return true;
}}
stepsProps={proFormStepsFormProps.stepsProps}
current={current}
onCurrentChange={setCurrent}
@ -167,7 +162,6 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
onCancel={() => {
setCurrent(0);
formRef.current?.resetFields();
setFileList([]);
props.handleModal();
}}
open={props.createModalOpen}
@ -202,38 +196,34 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
}}
>
<ProForm.Group>
{/* //TODO 默认填充模型 无需选择 */}
<ProFormSelect
<ProFormText
width={proFormMaxItemStyleProps.width}
name="modelFkId"
label={<FormattedMessage id="business_model.form.modelFkId" defaultMessage="$$$" />}
name="name"
label={<FormattedMessage id="business_model.form.modelFkId" defaultMessage="名称" />}
placeholder={`${intl.formatMessage({
id: 'common.please_select',
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'business_model.form.modelFkId',
defaultMessage: '$$$',
})}`}
required={true}
// initialValue={props.values.modelFkId}
showSearch
debounceTime={1000}
disabled={true}
// request={async (keyWord) => {
// const resp = await getBaseBusinessModelList({
// keyword: keyWord?.keyWords || '',
// });
// return resp.data.list.map((v: any) => {
// return {
// label: v.name,
// value: v.id,
// };
// });
// }}
initialValue={currFormData?.name}
rules={[
{
required: true,
message: (
<FormattedMessage
id="model_index.create.form.rule.required.name"
defaultMessage="name is required"
/>
),
},
]}
/>
<ProFormTextArea
width={proFormMaxItemStyleProps.width}
name="remark"
name="comment"
label={<FormattedMessage id="business_model.form.remark" defaultMessage="简介" />}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
@ -242,8 +232,8 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
id: 'business_model.form.remark',
defaultMessage: '$$$',
})}`}
initialValue={currFormData?.comment}
required={false}
disabled={false}
/>
</ProForm.Group>
</StepsForm.StepForm>
@ -267,12 +257,12 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
return true;
}}
>
{/* //TODO 与UI确定调整尺寸布局 */}
{/* //TODO 此项校验必填 与UI确定调整尺寸布局 */}
<Transfer
dataSource={modalData}
titles={['基础模型库', '已选模型']}
locale={{ itemUnit: '项', itemsUnit: '项', searchPlaceholder: '请输入搜索内容' }}
targetKeys={targetKeys}
targetKeys={modelLinkKeys}
onChange={handleChange}
// onSearch={handleSearch}
style={{ marginBottom: '20px' }}
@ -299,41 +289,37 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
/>
),
}}
onFinish={async (values: any) => {
if ('projectFilePath' in values && values['projectFilePath'].length > 0) {
let projectFilePath = values['projectFilePath'][0]?.response?.data?.path || '';
setFilePath(projectFilePath);
}
return true;
}}
>
<ProFormUploadDragger
label={<span className="font-bold"></span>}
title={
<FormUploadDraggerToken
proFieldProps={{
label: (
<div className="flex">
<span className="font-bold"></span>
<div style={{ color: '#666666' }}>zip.tar.gz</div>
</div>
),
title: (
<div className="gn_uploadfile_title py-[16px] text1 text-center">
<span></span>
<a></a>
</div>
}
description=""
icon={<i className="iconfont icon-shangchuanwenjian text_primary text-[32px]"></i>}
name="projectFilePath"
action="/api/v1/file/uploadFile"
max={1}
fieldProps={{
className: 'gn_proFormUploadDragger_formItem',
name: 'file',
// beforeUpload: beforeUploadFile,
data: { path: `models/${Date.now()}` },
headers: {
'X-CSRFToken': cookie.load('csrftoken'),
token: `Bearer ${localStorage.getItem('access') || ''}`,
},
),
description: '',
icon: <i className="iconfont icon-shangchuanwenjian text_primary text-[32px]"></i>,
name: 'business_logic_arr',
max: 1,
}}
afterUploadFile={({ resp }) => {
setCurrFormData((data) => {
return { ...data, business_logic: resp?.data?.result };
});
}}
afterRemoveFile={() => {
setCurrFormData((data) => {
return { ...data, business_logic: '' };
});
}}
/>
<div style={{ color: '#666666', margin: '-8px 0 16px' }}>
zip.tar.gz
</div>{' '}
</StepsForm.StepForm>
{/* 参数配置 */}
<StepsForm.StepForm<{
@ -351,122 +337,43 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
),
}}
onFinish={async (values: any) => {
setFileList([]);
let formData = formRef.current?.getFieldsValue();
if (formData?.modelFkId) {
await waitTime(500);
formData.modelConfig = { params: values?.params || [] };
if (filePath) {
formData.path = filePath;
}
// postModelVersionCreateModelVersion(formData)
// .then(() => {
// message.success(
// intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }),
// );
// props.handleModal();
// props.reload();
// })
// .catch(() => {
// message.error(intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }));
// return false;
// });
}
console.log(values, 'config_values');
return true;
}}
>
<ProFormUploadDragger
width={proFormMaxItemStyleProps.width}
max={1}
label={<span className="font-bold"></span>}
title={
<FormUploadDraggerToken
proFieldProps={{
label: (
<div className="flex">
<span className="font-bold"></span>
<div style={{ color: '#666666' }}>.json.yaml.yml</div>
</div>
),
title: (
<div className="gn_uploadfile_title py-[16px] text1 text-center">
<span></span>
<a></a>
</div>
}
description=""
icon={<i className="iconfont icon-shangchuanwenjian text_primary text-[32px]"></i>}
value={fileList}
name="dragger"
fieldProps={{
className: 'gn_proFormUploadDragger_formItem',
onChange: handleFileChange,
onRemove: () => {
let index_ids = actionFormListRef.current?.getList()?.map((v, i) => {
return i;
});
actionFormListRef.current?.remove(index_ids || []);
},
beforeUpload: (file) => {
if (
!file.name.endsWith('.yaml') &&
!file.name.endsWith('.yml') &&
!file.name.endsWith('.json')
) {
message.error('请上传yaml或json文件').then(() => {});
return false;
} else {
let parsedData = {};
file
.text()
.then((text) => {
if (file.name.endsWith('.yaml') || file.name.endsWith('.yml')) {
parsedData = yaml.load(text) as Record<string, unknown>;
}
if (file.name.endsWith('.json')) {
parsedData = JSON.parse(text) as Record<string, unknown>;
}
if (Object.keys(parsedData).length > 0) {
dataFormListRef.current = Object.entries(parsedData).map(
([key, value]) => ({
name: key,
default: value,
}),
);
dataFormListRef.current.forEach((v: any, i: number) => {
actionFormListRef.current?.add(v, i);
),
description: '',
icon: <i className="iconfont icon-shangchuanwenjian text_primary text-[32px]"></i>,
name: 'business_conf_file_arr',
max: 1,
}}
afterUploadFile={({ resp }) => {
setCurrFormData((data) => {
return { ...data, business_conf_file: resp?.data?.result };
});
}
return true;
})
.catch(() => {
return false;
}}
afterRemoveFile={() => {
setCurrFormData((data) => {
return { ...data, business_conf_file: '' };
});
}
},
}}
/>
<div style={{ color: '#666666', margin: '-8px 0 16px' }}>
zip.tar.gz
</div>
{/* // TODO label字重与上面统一, 操作按钮需要与输入框对齐 */}
<ProFormList
name="params"
label={
<div>
<span className="font-bold"></span>
<div style={{ color: '#333333', padding: '8px 0 4px' }}>
~
</div>
</div>
}
actionRef={actionFormListRef}
itemContainerRender={(doms) => {
return <ProForm.Group>{doms}</ProForm.Group>;
}}
alwaysShowItemLabel
>
{() => {
return (
<>
<ProFormText width={408} key="name" name="name" label="键名" />
<ProFormText width={408} key="default" name="default" label="默认值" />
</>
);
}}
</ProFormList>
{/* //TODO json
*/}
</StepsForm.StepForm>
{/* 关联节点 */}
<StepsForm.StepForm<{
@ -489,19 +396,21 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
>
<div style={{ paddingBottom: 10, fontWeight: 700 }}>{'节点信息'}</div>
<Tree
fieldNames={{
title: 'name',
key: 'id',
children: 'children',
}}
checkable
defaultExpandAll={true}
defaultCheckedKeys={[]}
autoExpandParent={true}
onCheck={(checkedKeys: any) => {
// form.setFieldsValue({menuIds: checkedKeys})
setSelectKeys(checkedKeys);
setDeviceLinkKeys(checkedKeys);
// formRef3.current?.setFieldValue('groupIds', checkedKeys)
}}
treeData={treeData}
// loadData={({treeNode}) => {
// return treeData
// }}
treeData={deviceTreeList}
/>
</StepsForm.StepForm>
</StepsForm>

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-22 15:23:36
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-06 15:46:51
* @LastEditTime: 2024-06-07 14:44:06
* @FilePath: \general-ai-platform-web\src\pages\Node\BusinessModel\index.tsx
* @Description:
* @
@ -10,14 +10,9 @@
* 2
* 3.
*/
// const BusinessModel: React.FC = () => {
// return <div className="businessModel_page">业务模型</div>;
// };
// export default BusinessModel;
import TableActionCard from '@/components/TableActionCard';
import IsDelete from '@/components/TableActionCard/isDelete';
import { useBusinessInfo } from '@/hooks/useBusinessInfo';
import { apiModelDeploymentList } from '@/services/business/model';
import { isSuccessApi } from '@/utils/forApi';
@ -32,7 +27,10 @@ import CreateForm from './components/createForm';
const BusinessModel: React.FC = () => {
// const intl = useIntl();
const { getStoreBusinessInfo } = useBusinessInfo();
const actionRef = useRef<ActionType>();
const [commInfo] = useState<Record<string, any>>({ ...getStoreBusinessInfo() }); // 通用信息
const [createModalOpen, setCreateModalOpen] = useState<boolean>(false);
// const [categoryFkIdIds, setCategoryFkIdIds] = useState([]);
@ -206,6 +204,7 @@ const BusinessModel: React.FC = () => {
<CreateForm
createModalOpen={createModalOpen}
handleModal={handleCreateModal}
commInfo={commInfo}
reload={reloadList}
/>
</div>

@ -0,0 +1,61 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-03-11 16:48:04
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-07 09:40:10
* @FilePath: \general-ai-platform-web\src\pages\ComputePowerAllocation\components\computePowerCube.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import React, { useEffect, useRef, useState } from 'react';
import { ComputePowerPoolItem } from '../typing';
export type ComputePowerCubeProps = {
// alarmStatusModalOpen: boolean;
// handleModal: () => void;
// values: Partial<API.DeviceCategory>;
list: ComputePowerPoolItem[];
};
const ComputePowerCube: React.FC<ComputePowerCubeProps> = (props) => {
const cubeBoxRefs = useRef(null);
const [listData, setListData] = useState([]);
useEffect(() => {
console.log(cubeBoxRefs.current.clientWidth, 'cubeBoxRefs');
let finalList = [];
const totalWidth = cubeBoxRefs.current?.clientWidth + 6 || 1062;
finalList = props.list.map((item) => {
item.value = Math.floor((item.proportion / 100) * totalWidth);
return item;
});
setListData(() => finalList.reverse());
}, [cubeBoxRefs, props.list]);
return (
<div className="computePowerCube_wrap">
<div className="flex justify-start des_wrap pb-[16px]">
<div className="tip_icon"></div>
<p className="tip_text">
</p>
</div>
<div className="cube_body">
<ul className="flex cube_info" ref={cubeBoxRefs}>
{listData.map((v, k) => {
return (
<li key={k} className="flex items-center justify-center">
<div className="bg_cube" style={{ width: v.value + 'px', background: v.bgColor }}>
{k !== 0 && <div className="bg_line"></div>}
</div>
</li>
);
})}
<li>
<div className="cube_info_line" />
</li>
</ul>
</div>
<div className="bg_body_logo"></div>
</div>
);
};
export default ComputePowerCube;

@ -0,0 +1,26 @@
import { ComputePowerPoolItem } from '../typing';
export type ComputePowerTypeProps = {
// alarmStatusModalOpen: boolean;
// handleModal: () => void;
// values: Partial<API.DeviceCategory>;
info: ComputePowerPoolItem;
};
const ComputePowerType: React.FC<ComputePowerTypeProps> = (props) => {
return (
<div className="flex computePowerType_wrap">
<div className="bg_square_box">
<div className="bg_square" style={{ background: props.info.bgColor }} />
</div>
<div className="flex items-center type_info">
<p className="pf-1">{props.info.name}</p>
<p className="pf-1">{props.info.proportion}%</p>
{!!props.info.pretreatmentEfficiency && (
<p className="pl8px pf-2">: {props.info.pretreatmentEfficiency}/</p>
)}
</div>
</div>
);
};
export default ComputePowerType;

@ -0,0 +1,76 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-03-07 14:01:13
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-07 09:40:25
* @FilePath: \general-ai-platform-web\src\pages\ComputePowerAllocation\components\updatePowerForm.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import type { ProDescriptionsActionType } from '@ant-design/pro-components';
import { ProDescriptions } from '@ant-design/pro-components';
import { Modal } from 'antd';
import { useEffect, useRef, useState } from 'react';
export type UpdatePowerFormProps = {
modalOpen: boolean;
poolsData: Record<string, any>[];
};
const UpdatePowerForm: React.FC<UpdatePowerFormProps> = (props) => {
const actionRef = useRef<ProDescriptionsActionType>();
// const [state, setState] = useState<PicSearcherState>({
// loading: false,
// modalOpen: false,
// popoverVisible: false,
// icons: [],
// fileList: [],
// error: false,
// modelLoaded: false,
// });
const [formList, setFormList] = useState([]);
useEffect(() => {
setFormList(() => props.poolsData);
}, [props.poolsData]);
return (
<Modal width={761} title={'编辑算力配置'} open={props.modalOpen}>
<ProDescriptions
actionRef={actionRef}
editable={{
onSave: async (keypath, newInfo, oriInfo) => {
console.log(keypath, newInfo, oriInfo);
return true;
},
}}
>
{formList.map((item, index) => {
return (
<ProDescriptions.Item
key={index}
label={
<div className="flex items-center">
<span
style={{ width: 12, height: 12, marginRight: 8, background: item.bgColor }}
></span>
<span>{item.name}</span>
</div>
}
formItemProps={{
fieldId: index,
initialValue: item.proportion,
rules: [
{
required: true,
message: '此项为必填项',
},
],
}}
>
{item.proportion}
</ProDescriptions.Item>
);
})}
</ProDescriptions>
</Modal>
);
};
export default UpdatePowerForm;

@ -0,0 +1,168 @@
.pf-1 {
color: #333;
font-family: "PingFang SC";
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 22px;
/* 157.143% */
}
.pf-2 {
color: #666;
font-family: "PingFang SC";
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 22px;
}
.flex {
display: flex;
}
.justify-between {
justify-content: space-between;
}
.items-center {
align-items: center;
}
.flex-wrap {
flex-wrap: wrap;
}
.mr16px {
margin-right: 16px;
}
.mt16px {
margin-top: 16px;
}
.mb16px {
margin-bottom: 16px;
}
.px16px {
padding: 0 16px;
}
.pl8px {
padding-left: 8px;
}
.font-bold {
font-weight: 700;
}
.computePowerAllocation_body {
/* header */
/* banner */
/* footer */
}
.computePowerAllocation_body h3 {
font-weight: bold;
font-size: 16px;
color: #333333;
line-height: 19px;
}
.computePowerAllocation_body .head_info .bg_header_logo {
width: 80px;
height: 80px;
}
.computePowerAllocation_body .head_info .head_info_item {
margin-left: 12px;
}
.computePowerAllocation_body .banner_group {
padding-top: 24px;
}
.computePowerAllocation_body .banner_group > li {
width: 24%;
height: 88px;
background-color: rgba(255, 255, 255, 0.1);
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.1);
border-radius: 8px 8px 8px 8px;
position: relative;
overflow: hidden;
}
.computePowerAllocation_body .banner_group > li .cp_label {
width: 100%;
padding-left: 12px;
}
.computePowerAllocation_body .banner_group > li .cp_bg_logo_icon {
min-width: 24px;
height: 26px;
background: url('/images/computePowerCenter/type1.svg') no-repeat 0 0;
}
.computePowerAllocation_body .banner_group > li .cp_bg_logo_icon_0 {
width: 44px;
height: 16px;
background: url('/images/computePowerCenter/ruiyinweilogo1.svg') no-repeat 0 0;
}
.computePowerAllocation_body .banner_group > li .bg_banner_group_logo {
width: 100%;
height: 88px;
position: absolute;
background: url('/images/computePowerCenter/guoqi.svg') no-repeat 100% 0%;
background-size: cover;
opacity: 0.1;
}
.computePowerAllocation_body .banner_group > li .bg_banner_group_logo_1 {
background: url('/images/computePowerCenter/NVIDIA.svg') no-repeat 100% 0%;
}
.computePowerAllocation_body .computePower_footer li {
margin-right: 16px;
margin-bottom: 8px;
}
.computePowerCube_wrap {
position: relative;
overflow: hidden;
}
.computePowerCube_wrap .tip_icon {
width: 20px;
height: 20px;
background-size: cover;
}
.computePowerCube_wrap .bg_body_logo {
/* width: 358.886px;
height: 343.026px;
bottom: 0;
position: absolute;
left: -48px;
background: url("@/assets/computePower/bgLogo.svg") no-repeat 50% 50%;
opacity: 0.02; */
}
.computePowerCube_wrap .cube_info {
position: relative;
margin: 0 auto;
width: 100%;
border-radius: 2px;
/* background-color: red; */
border: 2px solid rgba(21, 77, 221, 0.4);
}
.computePowerCube_wrap .cube_info > li .bg_cube {
height: 100%;
position: relative;
}
.computePowerCube_wrap .cube_info_line {
position: absolute;
left: 18px;
bottom: 14px;
height: 4px;
width: calc(100% - 36px);
/* height: 401px; */
background: #ffffff;
filter: blur(4px);
}
.computePowerCube_wrap .cube_body {
/* margin-left: 30px; */
width: 100%;
border: 2px solid #b8b8b8;
border-radius: 6px;
}
.computePowerCube_wrap .bg_line {
height: 56px;
width: 2px;
background-color: black;
}
.computePowerType_wrap {
position: relative;
}
.computePowerType_wrap .bg_square_box {
padding-top: 6px;
padding-right: 8px;
}
.computePowerType_wrap .bg_square {
width: 12px;
height: 12px;
}

@ -0,0 +1,193 @@
@web_font1: #333;
@web_font2: #666;
// TODO 整体向tainwind合并
.pf-1 {
color: @web_font1;
font-weight: 400;
font-size: 14px;
font-family: 'PingFang SC';
font-style: normal;
line-height: 22px;
/* 157.143% */
}
.pf-2 {
color: @web_font2;
font-weight: 400;
font-size: 14px;
font-family: 'PingFang SC';
font-style: normal;
line-height: 22px;
}
.flex {
display: flex;
}
.justify-between {
justify-content: space-between;
}
.items-center {
align-items: center;
}
.flex-wrap {
flex-wrap: wrap;
}
.mr16px {
margin-right: 16px;
}
.mt16px {
margin-top: 16px;
}
.mb16px {
margin-bottom: 16px;
}
.px16px {
padding: 0 16px;
}
.pl8px {
padding-left: 8px;
}
.font-bold {
font-weight: 700;
}
.computePowerAllocation_body {
h3 {
color: #333333;
font-weight: bold;
font-size: 16px;
line-height: 19px;
}
/* header */
.head_info {
// font-size: 28px;
.bg_header_logo {
width: 80px;
height: 80px;
}
.head_info_item {
margin-left: 12px;
}
}
/* banner */
.banner_group {
padding-top: 24px;
& > li {
position: relative;
width: 24%;
height: 88px;
overflow: hidden;
background-color: rgba(256, 256, 256, 0.1);
border-radius: 8px 8px 8px 8px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.1);
.cp_label {
width: 100%;
padding-left: 12px;
}
.cp_bg_logo_icon {
min-width: 24px;
height: 26px;
background: url('/images/computePowerCenter/type1.svg') no-repeat 0 0;
}
.cp_bg_logo_icon_0 {
width: 44px;
height: 16px;
background: url('/images/computePowerCenter/ruiyinweilogo1.svg') no-repeat 0 0;
}
.bg_banner_group_logo {
position: absolute;
width: 100%;
height: 88px;
background: url('/images/computePowerCenter/guoqi.svg') no-repeat 100% 0%;
background-size: cover;
opacity: 0.1;
}
.bg_banner_group_logo_1 {
background: url('/images/computePowerCenter/NVIDIA.svg') no-repeat 100% 0%;
}
}
}
/* footer */
.computePower_footer {
li {
margin-right: 16px;
margin-bottom: 8px;
}
}
}
.computePowerCube_wrap {
position: relative;
overflow: hidden;
.tip_icon {
width: 20px;
height: 20px;
// background: url("@/assets/computePower/tipIcon.svg") no-repeat;
background-size: cover;
// tipIcon.svg
}
.bg_body_logo {
/* width: 358.886px;
height: 343.026px;
bottom: 0;
position: absolute;
left: -48px;
background: url("@/assets/computePower/bgLogo.svg") no-repeat 50% 50%;
opacity: 0.02; */
}
.cube_info {
position: relative;
width: 100%;
margin: 0 auto;
/* background-color: red; */
border: 2px solid rgba(21, 77, 221, 0.4);
border-radius: 2px;
& > li {
.bg_cube {
position: relative;
height: 100%;
}
}
}
.cube_info_line {
position: absolute;
bottom: 14px;
left: 18px;
width: calc(100% - 36px);
height: 4px;
/* height: 401px; */
background: rgba(255, 255, 255, 1);
filter: blur(4px);
}
.cube_body {
/* margin-left: 30px; */
width: 100%;
border: 2px solid #b8b8b8;
border-radius: 6px;
}
.bg_line {
width: 2px;
height: 56px;
background-color: black;
}
}
.computePowerType_wrap {
position: relative;
.bg_square_box {
padding-top: 6px;
padding-right: 8px;
}
.bg_square {
width: 12px;
height: 12px;
}
// .type_info{
// line-height: 1
// }
}

@ -0,0 +1,134 @@
/* eslint-disable eqeqeq */
/* eslint-disable react/no-unknown-property */
import { isSuccessApi } from '@/utils/forApi';
import { ProCard } from '@ant-design/pro-components';
import { Image } from 'antd';
import React, { useEffect, useState } from 'react';
// type
import { postPowerGroup, postPowerPoolsList } from '@/services/testApi/computePower';
import ComputePowerCube from './components/computePowerCube';
import ComputePowerType from './components/computePowerType';
import './index.less';
/**
* @
* @returns
*/
const ComputePowerAllocation: React.FC = () => {
const [poolsData, setPoolsData] = useState([]);
const [groupList, setGroupList] = useState([]);
// const [showEdit, setShowEdit] = useState(false);
async function fetchPowerData() {
const resp = await postPowerPoolsList();
if (isSuccessApi(resp) && resp?.data) {
console.log('fetchPowerData_res', resp);
setPoolsData(resp.data);
}
}
async function fetchGroupData() {
const resp = await postPowerGroup();
if (isSuccessApi(resp) && resp?.data) {
console.log('fetchGroupData_res', resp);
setGroupList(resp.data.splice(0, 4));
}
}
// 算力配置
// function editComputePower() {
// setShowEdit(true);
// console.log(111, 'editComputePower');
// }
useEffect(() => {
fetchGroupData();
fetchPowerData();
}, []);
return (
<div className="home_container computePowerCenterIndex_page">
<ProCard
title="算力资源池"
style={{ background: 'white' }}
headStyle={{ padding: 20, borderBottom: '1px solid #E0E0E0' }}
bodyStyle={{
paddingLeft: 20,
paddingRight: 20,
paddingTop: 0,
paddingBottom: 0,
margin: 0,
}}
gutter={24}
wrap
ghost
>
{/* 占比信息 */}
<ul className="computePowerAllocation_body">
<li>
<div className="flex items-center head_info mt16px">
<div className="bg_header_logo">
<Image
width={80}
src={'/images/computePowerCenter/banner.png'}
placeholder={
<Image
preview={false}
src={'/images/computePowerCenter/banner.png'}
width={80}
/>
}
/>
</div>
<div className="head_info_item">
<h6 className="font-bold pf-1"></h6>
<p className="pf-2">999Tops</p>
</div>
</div>
</li>
<li className="mt16px">
<h3></h3>
{/* // TODO 重新设计*/}
<ul className="flex justify-between banner_group">
{groupList.map((v, k) => {
return (
<li key={k} className="flex items-center mb16px">
<div className="flex items-center px16px">
<div className={`cp_bg_logo_icon cp_bg_logo_icon_${v.type}`} />
<span className="cp_label pf-2 two-line">{v.label}</span>
</div>
<div className={`bg_banner_group_logo bg_banner_group_logo_${v.type}`} />
</li>
);
})}
</ul>
</li>
<li className="mt16px">
<h3></h3>
<div className="mt16px">
<ComputePowerCube list={poolsData} />
<ul className="flex flex-wrap items-center computePower_footer mt16px">
{poolsData.map((v, k) => {
return (
<li key={k} className="flex items-center justify-center">
<ComputePowerType info={v} />
</li>
);
})}
</ul>
</div>
{/* <div>
<Button type="primary" onClick={editComputePower}>
</Button>
</div> */}
</li>
</ul>
</ProCard>
{/* <UpdatePowerForm modalOpen={showEdit} poolsData={poolsData}></UpdatePowerForm> */}
</div>
);
};
export default ComputePowerAllocation;

@ -0,0 +1,7 @@
export interface ComputePowerPoolItem {
name: string;
type: number; // 类别
color?: string; //
proportion: number;
PretreatmentEfficiency?: number;
}

@ -0,0 +1,221 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-07 14:02:00
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-07 13:57:07
* @FilePath: \general-ai-manage\src\pages\Log\index.tsx
* @Description:
* @
* 1.
*
*/
import { CommButton } from '@/components/Button';
import { apiModelList } from '@/services/business/model';
import { isSuccessApi } from '@/utils/forApi';
import { ReactComponent as ResetIcon } from '/public/home/reset_icon.svg';
import { ReactComponent as SearchIcon } from '/public/home/search_icon.svg';
import { SearchOutlined } from '@ant-design/icons';
import type { ActionType, ProColumns } from '@ant-design/pro-components';
import { ProCard, ProForm, ProFormText, ProTable } from '@ant-design/pro-components';
import { FormattedMessage } from '@umijs/max';
import React, { useEffect, useRef, useState } from 'react';
import { proTableCommonOptions, proTablePaginationOptions } from '../../../config/defaultTable';
// import './index.less';
const LogIndex: React.FC = () => {
// const access = useAccess();
// eslint-disable-next-line react-hooks/rules-of-hooks
// const intl = useIntl();
const actionRef = useRef<ActionType>();
const [querysData, setQuerysData] = useState<Record<string, any>>({}); // 列表查询参数
// 动态设置每页数量
const [currentPageSize, setCurrentPageSize] = useState<number>(10);
const [form] = ProForm.useForm(); // form 对象
function reloadList() {
actionRef.current?.reload();
}
// const [showDetail, setShowDetail] = useState<boolean>(false);
const columns: ProColumns<Record<string, any>>[] = [
{
title: <FormattedMessage id="model_index.table.list.name" defaultMessage="$$$" />,
dataIndex: 'name',
hideInSearch: true,
key: 'fixedName',
fixed: 'left',
},
{
title: <FormattedMessage id="model_index.table.list.type" defaultMessage="$$$" />,
dataIndex: 'model_type',
hideInSearch: true,
render: (dom, record) => {
let activeName = 'active_primary';
switch (record.model_type) {
case '机器学习':
activeName = 'active3';
break;
default:
activeName = 'active_primary';
break;
}
return (
<div className={`gn_list_type_tag flex items-center justify-center ${activeName}`}>
<span className="dot"></span>
<span>{dom}</span>
</div>
);
},
},
{
title: <FormattedMessage id="model_index.table.list.industry" defaultMessage="$$$" />,
dataIndex: 'classification_name',
hideInSearch: true,
},
{
title: (
<FormattedMessage id="model_index.table.list.defaultVersionFkId" defaultMessage="$$$" />
),
dataIndex: 'default_version',
hideInSearch: true,
},
{
title: <FormattedMessage id="model_index.table.list.updateTime" defaultMessage="$$$" />,
dataIndex: 'update_time',
hideInSearch: true,
valueType: 'dateTime',
},
];
// 筛选查询
useEffect(() => {
if (actionRef) {
reloadList();
}
}, [actionRef, querysData]);
return (
<div className="log_page home_container gn_table_card_wrap">
<ProCard
className="gn_card"
style={{ backgroundColor: 'white' }}
title={
<div className="gn_form gn_table_query_filter">
<ProForm
className="gn_search_from"
form={form}
layout="horizontal"
submitter={{
render: () => (
<div style={{ textAlign: 'center', marginLeft: 12 }}>
<CommButton
type="primary"
htmlType="submit"
prevIcon={<SearchIcon />}
buttonLabel={
<FormattedMessage id="pages.searchTable.search" defaultMessage="查询" />
}
></CommButton>
<CommButton
style={{ marginLeft: 12 }}
htmlType="button"
prevIcon={<ResetIcon />}
buttonLabel={
<FormattedMessage id="pages.searchTable.reset" defaultMessage="重置" />
}
onClick={() => {
form.resetFields(); // 点击重置按钮时重置表单数据
setQuerysData(() => {}); // 清空筛选项
}}
></CommButton>
</div>
),
}}
onFinish={async (values) => {
console.log(values, 'filter_finish_values');
setQuerysData(() => values);
return true;
}}
>
<ProFormText
label={
<FormattedMessage id="model_index.table.list.name" defaultMessage="模型名称" />
}
labelClassName="label_set_1"
fieldProps={{
style: {
width: 280,
},
prefix: <SearchOutlined style={{ color: 'rgba(0,0,0,.25)' }} />,
}}
name="name"
placeholder="请输入模型名称"
/>
</ProForm>
</div>
}
>
{/* // TODO 需要控制表格溢出滚动高度 */}
<ProTable
className="gn_pro_table"
cardProps={{
bodyStyle: {
padding: '0',
},
}}
search={false}
scroll={{ x: proTableCommonOptions.commscrollX }}
options={{ fullScreen: false, setting: false, density: false, reload: false }}
actionRef={actionRef}
rowKey="id"
onDataSourceChange={(data) => {
console.log(data, 'onDataSourceChange_data');
// let CategoryFkIdIds: any = data.map((v) => {
// return v.categoryFkId;
// });
// setCategoryFkIdIds(CategoryFkIdIds);
}}
pagination={{
...proTablePaginationOptions,
pageSize: currentPageSize,
onChange: (pageNo, pageSize) => setCurrentPageSize(pageSize),
}}
columnsState={{
persistenceKey: 'algorithm_model_list',
persistenceType: 'localStorage',
}}
request={async (params = {}, sort) => {
const { current, ...rest } = params;
const reqParams = {
pageNo: current,
desc: false,
orderKey: '',
...rest,
};
if (sort && Object.keys(sort).length) {
reqParams.orderKey = Object.keys(sort)[0];
let sort_select = sort[reqParams.orderKey];
reqParams.desc = sort_select === 'descend';
}
let resp = await apiModelList({ ...reqParams, ...querysData });
if (!isSuccessApi(resp)) {
return { data: [], success: true };
}
return {
data: resp.data.data,
success: resp.success,
total: resp.data.count,
current: current,
pageSize: currentPageSize,
};
}}
columns={columns}
/>
</ProCard>
</div>
);
};
export default LogIndex;

@ -4,16 +4,12 @@ import { isSuccessApi } from '@/utils/forApi';
import {
ProForm,
ProFormInstance,
ProFormList,
ProFormText,
ProFormTextArea,
ProFormUploadDragger,
StepsForm,
} from '@ant-design/pro-components';
import { FormListActionType } from '@ant-design/pro-form/lib';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Modal, UploadFile, message } from 'antd';
import yaml from 'js-yaml';
import { Modal, message } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import {
proFormItemStyleProps,
@ -23,7 +19,6 @@ import {
} from '../../../../../config/defaultForm';
// import {beforeUploadFile} from "@/utils/common";
// @ts-ignore
import { fileApiActionUrl } from '../../../../../config/defaultApi';
export type CreateFormProps = {
createModalOpen: boolean;
@ -42,18 +37,9 @@ const waitTime = (time: number = 100) => {
// params: Array<object>;
// }
const CreateForm: React.FC<CreateFormProps> = (props) => {
const actionFormListRef = useRef<
FormListActionType<{
name: string;
}>
>();
const intl = useIntl();
const [dataFormList] = useState<any>([]);
const dataFormListRef = useRef(dataFormList);
// const [projectFileList, setProjectFileList] = useState<UploadFile<any>[]>([]);
const [configFileList, setConfigFileList] = useState<UploadFile<any>[]>([]);
// const [form] = Form.useForm<Record<string, any>>();
const [currFormData, setCurrFormData] = useState<Record<string, any>>({});
@ -61,29 +47,14 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
const formBaseRef = useRef<ProFormInstance>();
// const [filePath, setFilePath] = useState('');
const handleConfigFileChange = ({ file }: { file: UploadFile }) => {
console.log(configFileList, 'handleFileChange_configFileList');
let curFile: any;
switch (file.status) {
case 'uploading':
case 'done':
curFile = [file];
break;
case 'removed':
default:
curFile = [];
break;
}
setConfigFileList([...curFile]);
};
// test 测试数据
useEffect(() => {
// 初始化赋值
// setCurrFormData({
// version: '1.0.91', // 设备分类的suid 59aa3d0c3162322e190942a9cc9add10
// comment:
// '测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注',
// });
setCurrFormData({
version: '1.0.91', // 设备分类的suid 59aa3d0c3162322e190942a9cc9add10
comment:
'测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注',
});
}, [props.createModalOpen]);
return (
<StepsForm<{
@ -97,7 +68,7 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
model_id: props.modelInfo?.model_id,
config_str: JSON.stringify(values.config_str_arr),
model_file: currFormData?.model_file,
config_file: '',
config_file: currFormData?.config_file,
});
if (isSuccessApi(resp)) {
message.success(
@ -258,7 +229,12 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
>
<FormUploadDraggerToken
proFieldProps={{
label: <span className="font-bold"></span>,
label: (
<div className="flex">
<span className="font-bold"></span>
<div style={{ color: '#666666' }}>zip.tar.gz</div>
</div>
),
title: (
<div className="gn_uploadfile_title py-[16px] text1 text-center">
<span></span>
@ -280,7 +256,6 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
return { ...data, model_file: '' };
});
}}
nextText="请上传格式为zip.tar.gz的模型文件"
/>
</StepsForm.StepForm>
{/* 参数配置 */}
@ -310,7 +285,37 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
return true;
}}
>
<ProFormUploadDragger
<FormUploadDraggerToken
proFieldProps={{
label: (
<div className="flex">
<span className="font-bold"></span>
<div style={{ color: '#666666' }}>.json.yaml.yml</div>
</div>
),
title: (
<div className="gn_uploadfile_title py-[16px] text1 text-center">
<span></span>
<a></a>
</div>
),
description: '',
icon: <i className="iconfont icon-shangchuanwenjian text_primary text-[32px]"></i>,
name: 'config_file_arr',
max: 1,
}}
afterUploadFile={({ resp }) => {
setCurrFormData((data) => {
return { ...data, config_file: resp?.data?.result };
});
}}
afterRemoveFile={() => {
setCurrFormData((data) => {
return { ...data, config_file: '' };
});
}}
/>
{/* <ProFormUploadDragger
width={proFormSmallItemStyleProps.width}
max={1}
label={<span className="font-bold"></span>}
@ -373,10 +378,10 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
/>
<div style={{ color: '#666666', marginTop: '-8px', marginBottom: '16px' }}>
.json.yaml.yml
</div>
</div> */}
{/* // TODO label字重与上面统一, 操作按钮需要与输入框对齐 */}
<ProFormList
{/* // TODO label字重与上面统一, 操作按钮需要与输入框对齐 此处改为预览 */}
{/* <ProFormList
name="config_str_arr"
label={
<div>
@ -400,7 +405,7 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
</>
);
}}
</ProFormList>
</ProFormList> */}
</StepsForm.StepForm>
</StepsForm>
);

@ -5,16 +5,12 @@ import { isSuccessApi } from '@/utils/forApi';
import {
ProForm,
ProFormInstance,
ProFormList,
ProFormText,
ProFormTextArea,
ProFormUploadDragger,
StepsForm,
} from '@ant-design/pro-components';
import { FormListActionType } from '@ant-design/pro-form/lib';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Modal, UploadFile, message } from 'antd';
import yaml from 'js-yaml';
import { Modal, message } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import {
proFormItemStyleProps,
@ -24,8 +20,6 @@ import {
} from '../../../../../config/defaultForm';
// import {beforeUploadFile} from "@/utils/common";
// @ts-ignore
import { isValidJson } from '@/utils/is';
import { fileApiActionUrl } from '../../../../../config/defaultApi';
export type UpdateFormProps = {
updateModalOpen: boolean;
@ -45,18 +39,9 @@ const waitTime = (time: number = 100) => {
// params: Array<object>;
// }
const UpdateForm: React.FC<UpdateFormProps> = (props) => {
const actionFormListRef = useRef<
FormListActionType<{
name: string;
}>
>();
const intl = useIntl();
const [dataFormList] = useState<any>([]);
const dataFormListRef = useRef(dataFormList);
// const [projectFileList, setProjectFileList] = useState<UploadFile<any>[]>([]);
const [configFileList, setConfigFileList] = useState<UploadFile<any>[]>([]);
// const [form] = Form.useForm<Record<string, any>>();
const [currFormData, setCurrFormData] = useState<Record<string, any>>({});
@ -66,21 +51,6 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
const formProjectFileRef = useRef<ProFormInstance>();
// const [filePath, setFilePath] = useState('');
const handleConfigFileChange = ({ file }: { file: UploadFile }) => {
console.log(configFileList, 'handleFileChange_configFileList');
let curFile: any;
switch (file.status) {
case 'uploading':
case 'done':
curFile = [file];
break;
case 'removed':
default:
curFile = [];
break;
}
setConfigFileList([...curFile]);
};
function resetForm() {
setCurrFormData({});
}
@ -283,7 +253,12 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
>
<FormUploadDraggerToken
proFieldProps={{
label: <span className="font-bold"></span>,
label: (
<div className="flex">
<span className="font-bold"></span>
<div style={{ color: '#666666' }}>zip.tar.gz</div>
</div>
),
title: (
<div className="gn_uploadfile_title py-[16px] text1 text-center">
<span></span>
@ -316,7 +291,6 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
return { ...data, model_file: '' };
});
}}
nextText="请上传格式为zip.tar.gz的模型文件"
/>
</StepsForm.StepForm>
{/* 参数配置 */}
@ -346,7 +320,47 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
return true;
}}
>
<ProFormUploadDragger
<FormUploadDraggerToken
proFieldProps={{
label: (
<div className="flex">
<span className="font-bold"></span>
<div style={{ color: '#666666' }}>.json.yaml.yml</div>
</div>
),
title: (
<div className="gn_uploadfile_title py-[16px] text1 text-center">
<span></span>
<a></a>
</div>
),
description: '',
icon: <i className="iconfont icon-shangchuanwenjian text_primary text-[32px]"></i>,
name: 'config_file_arr',
max: 1,
initialValue: currFormData?.config_file_md5
? [
{
uid: currFormData?.config_file_md5,
name: currFormData?.config_file_name || currFormData?.config_file_md5,
status: 'done',
url: '/file/' + currFormData?.config_file_md5,
},
]
: [],
}}
afterUploadFile={({ resp }) => {
setCurrFormData((data) => {
return { ...data, config_file: resp?.data?.result };
});
}}
afterRemoveFile={() => {
setCurrFormData((data) => {
return { ...data, config_file: '' };
});
}}
/>
{/* <ProFormUploadDragger
width={proFormSmallItemStyleProps.width}
max={1}
label={<span className="font-bold"></span>}
@ -409,10 +423,10 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
/>
<div style={{ color: '#666666', marginTop: '-8px', marginBottom: '16px' }}>
.json.yaml.yml
</div>
</div> */}
{/* // TODO label字重与上面统一, 操作按钮需要与输入框对齐 */}
<ProFormList
{/* <ProFormList
name="config_str_arr"
label={
<div>
@ -439,7 +453,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
</>
);
}}
</ProFormList>
</ProFormList> */}
</StepsForm.StepForm>
</StepsForm>
);

@ -27,6 +27,23 @@ export async function apiModelDeploymentAdd(body: any, options?: { [key: string]
},
);
}
// 查询所有基础模型
export async function apiModelListSimple(body: any, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.ENTITY_INDEX_DATA; msg?: string }>(
`/api/v1/model/list/simple`,
{
method: 'POST',
headers: {
// 'Content-Type': 'application/json',
// "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
},
data: body,
...(options || {}),
},
);
}
// 编辑企业部署的业务模型
export async function apiModelDeploymentEdit(body: any, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.ENTITY_INDEX_DATA; msg?: string }>(

@ -0,0 +1,35 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-03-11 14:06:18
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-07 10:23:17
* @FilePath: \general-ai-platform-web\src\services\testApi\computePower.ts
* @Description: mock
*/
// @ts-ignore
/* eslint-disable */
import { request } from '@umijs/max';
/** 算力分配类别 */
export async function postPowerGroup(body: any, options?: { [key: string]: any }) {
return request<API.Response & { msg?: string }>(`/api/v1/compute_power/getPowerGroupList`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 算力分配类别 */
export async function postPowerPoolsList(body: any, options?: { [key: string]: any }) {
return request<API.Response & { msg?: string }>(`/api/v1/compute_power/getPowerPoolsList`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-06-05 13:32:31
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-06 13:13:25
* @LastEditTime: 2024-06-07 16:10:52
* @FilePath: \general-ai-platform-web\src\utils\is.ts
* @Description:
*/
@ -20,3 +20,12 @@ export function isValidJson(jsonString) {
return false;
}
}
/**
* @
* @param obj
* @returns
*/
export function isArrayAndNotEmpty(obj) {
return Array.isArray(obj) && obj.length > 0;
}

Loading…
Cancel
Save