|
|
|
|
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 React, { useEffect, useRef, useState } from 'react';
|
|
|
|
|
import {
|
|
|
|
|
proFormMaxItemStyleProps,
|
|
|
|
|
proFormMaxModelWidth,
|
|
|
|
|
proFormStepsFormProps,
|
|
|
|
|
} 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>;
|
|
|
|
|
|
|
|
|
|
export type CreateFormProps = {
|
|
|
|
|
createModalOpen: boolean;
|
|
|
|
|
handleModal: () => void;
|
|
|
|
|
values: Partial<API.ModelVersion>;
|
|
|
|
|
reload: any;
|
|
|
|
|
currentDefaultFieldsData?: Record<string, any>;
|
|
|
|
|
};
|
|
|
|
|
const waitTime = (time: number = 100) => {
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
resolve(true);
|
|
|
|
|
}, time);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
// interface ProjectConfig {
|
|
|
|
|
// 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 [modalData, setModalData] = useState<RecordType[]>([]);
|
|
|
|
|
const [targetKeys, setTargetKeys] = useState<string[]>([]);
|
|
|
|
|
|
|
|
|
|
// 关联节点state
|
|
|
|
|
const [treeData, setTreeData] = React.useState<DataNode[]>([]);
|
|
|
|
|
const [selectKeys, setSelectKeys] = 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: '', page: 1, pageSize: 100 }).then((res) => {
|
|
|
|
|
console.log(66666, res.data);
|
|
|
|
|
let result = (res.data?.results || []).map((v: any) => {
|
|
|
|
|
console.log(v);
|
|
|
|
|
return {
|
|
|
|
|
key: v.id,
|
|
|
|
|
title: v.name,
|
|
|
|
|
chosen: false,
|
|
|
|
|
disabled: false,
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
setModalData(result);
|
|
|
|
|
});
|
|
|
|
|
// setMockData(tempMockData);
|
|
|
|
|
// setTargetKeys(tempTargetKeys);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleChange = (newTargetKeys: string[]) => {
|
|
|
|
|
setTargetKeys(newTargetKeys);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setTargetKeys([]);
|
|
|
|
|
console.log('selectKeys', selectKeys);
|
|
|
|
|
if (props.createModalOpen) {
|
|
|
|
|
getModelData();
|
|
|
|
|
getDeviceGroupTree()
|
|
|
|
|
.then((resp: API.Response) => {
|
|
|
|
|
setTreeData(resp.data.tree);
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {});
|
|
|
|
|
} else {
|
|
|
|
|
formRef.current?.resetFields();
|
|
|
|
|
}
|
|
|
|
|
}, [props.createModalOpen]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (props.currentDefaultFieldsData) {
|
|
|
|
|
// 如果是在模型详情新增版本,ModelFkId不可编辑
|
|
|
|
|
console.log(props.values, isHasModelFkId, 'currentDefaultFieldsData');
|
|
|
|
|
setIsHasModelFkId(true);
|
|
|
|
|
} else {
|
|
|
|
|
setIsHasModelFkId(false);
|
|
|
|
|
}
|
|
|
|
|
}, []);
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<StepsForm<{
|
|
|
|
|
name: string;
|
|
|
|
|
}>
|
|
|
|
|
stepsProps={proFormStepsFormProps.stepsProps}
|
|
|
|
|
current={current}
|
|
|
|
|
onCurrentChange={setCurrent}
|
|
|
|
|
formProps={{
|
|
|
|
|
validateMessages: {
|
|
|
|
|
required: `${intl.formatMessage({
|
|
|
|
|
id: 'common.form.required',
|
|
|
|
|
defaultMessage: '此项为必填项',
|
|
|
|
|
})}`,
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
stepsFormRender={(dom, submitter) => {
|
|
|
|
|
return (
|
|
|
|
|
<Modal
|
|
|
|
|
className="gn_model_steps_form"
|
|
|
|
|
title={
|
|
|
|
|
<FormattedMessage id="business_model.table.list.add.name" defaultMessage="新增" />
|
|
|
|
|
}
|
|
|
|
|
width={proFormMaxModelWidth}
|
|
|
|
|
onCancel={() => {
|
|
|
|
|
setCurrent(0);
|
|
|
|
|
formRef.current?.resetFields();
|
|
|
|
|
setFileList([]);
|
|
|
|
|
props.handleModal();
|
|
|
|
|
}}
|
|
|
|
|
open={props.createModalOpen}
|
|
|
|
|
footer={submitter}
|
|
|
|
|
destroyOnClose
|
|
|
|
|
>
|
|
|
|
|
{dom}
|
|
|
|
|
</Modal>
|
|
|
|
|
);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{/* 基本信息 数据创建 */}
|
|
|
|
|
<StepsForm.StepForm<{
|
|
|
|
|
name: string;
|
|
|
|
|
}>
|
|
|
|
|
className="gn_form"
|
|
|
|
|
name="base"
|
|
|
|
|
formRef={formRef}
|
|
|
|
|
title={<FormattedMessage id="business_model.stepForm.base" defaultMessage="基本信息" />}
|
|
|
|
|
stepProps={{
|
|
|
|
|
description: (
|
|
|
|
|
<FormattedMessage
|
|
|
|
|
id="business_model.stepForm.base.description"
|
|
|
|
|
defaultMessage="填写基础信息"
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
}}
|
|
|
|
|
onFinish={async () => {
|
|
|
|
|
// setFormData(formRef.current?.getFieldsValue());
|
|
|
|
|
await waitTime(500);
|
|
|
|
|
return true;
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<ProForm.Group>
|
|
|
|
|
{/* //TODO 默认填充模型 无需选择 */}
|
|
|
|
|
<ProFormSelect
|
|
|
|
|
width={proFormMaxItemStyleProps.width}
|
|
|
|
|
name="modelFkId"
|
|
|
|
|
label={<FormattedMessage id="business_model.form.modelFkId" defaultMessage="$$$" />}
|
|
|
|
|
placeholder={`${intl.formatMessage({
|
|
|
|
|
id: 'common.please_select',
|
|
|
|
|
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,
|
|
|
|
|
// };
|
|
|
|
|
// });
|
|
|
|
|
// }}
|
|
|
|
|
/>
|
|
|
|
|
<ProFormTextArea
|
|
|
|
|
width={proFormMaxItemStyleProps.width}
|
|
|
|
|
name="remark"
|
|
|
|
|
label={<FormattedMessage id="business_model.form.remark" defaultMessage="简介" />}
|
|
|
|
|
placeholder={`${intl.formatMessage({
|
|
|
|
|
id: 'common.please_input',
|
|
|
|
|
defaultMessage: '$$$',
|
|
|
|
|
})}${intl.formatMessage({
|
|
|
|
|
id: 'business_model.form.remark',
|
|
|
|
|
defaultMessage: '$$$',
|
|
|
|
|
})}`}
|
|
|
|
|
required={false}
|
|
|
|
|
disabled={false}
|
|
|
|
|
/>
|
|
|
|
|
</ProForm.Group>
|
|
|
|
|
</StepsForm.StepForm>
|
|
|
|
|
{/* 关联算法模型 */}
|
|
|
|
|
<StepsForm.StepForm<{
|
|
|
|
|
model: string;
|
|
|
|
|
}>
|
|
|
|
|
name="baseModel"
|
|
|
|
|
title={
|
|
|
|
|
<FormattedMessage id="business_model.stepForm.baseModel" defaultMessage="关联模型" />
|
|
|
|
|
}
|
|
|
|
|
stepProps={{
|
|
|
|
|
description: (
|
|
|
|
|
<FormattedMessage
|
|
|
|
|
id="business_model.stepForm.baseModel.description"
|
|
|
|
|
defaultMessage="关联基础模型"
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
}}
|
|
|
|
|
onFinish={async () => {
|
|
|
|
|
return true;
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{/* //TODO 与UI确定调整尺寸布局 */}
|
|
|
|
|
<Transfer
|
|
|
|
|
dataSource={modalData}
|
|
|
|
|
titles={['基础模型库', '已选模型']}
|
|
|
|
|
locale={{ itemUnit: '项', itemsUnit: '项', searchPlaceholder: '请输入搜索内容' }}
|
|
|
|
|
targetKeys={targetKeys}
|
|
|
|
|
onChange={handleChange}
|
|
|
|
|
// onSearch={handleSearch}
|
|
|
|
|
style={{ marginBottom: '20px' }}
|
|
|
|
|
listStyle={{ width: 410, height: 300 }}
|
|
|
|
|
operationStyle={{ width: 50, alignItems: 'center' }}
|
|
|
|
|
render={(item) => item.title}
|
|
|
|
|
/>
|
|
|
|
|
</StepsForm.StepForm>
|
|
|
|
|
{/* 业务代码 */}
|
|
|
|
|
<StepsForm.StepForm<{
|
|
|
|
|
project_file: string;
|
|
|
|
|
}>
|
|
|
|
|
className="gn_form"
|
|
|
|
|
name="project_file"
|
|
|
|
|
title={
|
|
|
|
|
<FormattedMessage id="business_model.stepForm.project_file" defaultMessage="业务代码" />
|
|
|
|
|
}
|
|
|
|
|
style={{ width: proFormMaxItemStyleProps.width }}
|
|
|
|
|
stepProps={{
|
|
|
|
|
description: (
|
|
|
|
|
<FormattedMessage
|
|
|
|
|
id="business_model.stepForm.project_file.description"
|
|
|
|
|
defaultMessage="上传业务代码"
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
}}
|
|
|
|
|
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>}
|
|
|
|
|
name="projectFilePath"
|
|
|
|
|
action="/api/v1/file/uploadFile"
|
|
|
|
|
max={1}
|
|
|
|
|
fieldProps={{
|
|
|
|
|
name: 'file',
|
|
|
|
|
// beforeUpload: beforeUploadFile,
|
|
|
|
|
data: { path: `models/${Date.now()}` },
|
|
|
|
|
headers: {
|
|
|
|
|
'X-CSRFToken': cookie.load('csrftoken'),
|
|
|
|
|
Authorization: `Bearer ${localStorage.getItem('access') || ''}`,
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<div style={{ color: '#666666' }}>请上传格式为zip.tar.gz的业务代码文件</div>
|
|
|
|
|
</StepsForm.StepForm>
|
|
|
|
|
{/* 参数配置 */}
|
|
|
|
|
<StepsForm.StepForm<{
|
|
|
|
|
config: string;
|
|
|
|
|
}>
|
|
|
|
|
className="gn_form"
|
|
|
|
|
name="config"
|
|
|
|
|
title={<FormattedMessage id="business_model.stepForm.config" defaultMessage="参数配置" />}
|
|
|
|
|
stepProps={{
|
|
|
|
|
description: (
|
|
|
|
|
<FormattedMessage
|
|
|
|
|
id="business_model.stepForm.config.description"
|
|
|
|
|
defaultMessage="配置业务参数"
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
}}
|
|
|
|
|
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.success', defaultMessage: '$$$' }),
|
|
|
|
|
// );
|
|
|
|
|
// props.handleModal();
|
|
|
|
|
// props.reload();
|
|
|
|
|
// })
|
|
|
|
|
// .catch(() => {
|
|
|
|
|
// message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' }));
|
|
|
|
|
// return false;
|
|
|
|
|
// });
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<ProFormUploadDragger
|
|
|
|
|
width={proFormMaxItemStyleProps.width}
|
|
|
|
|
max={1}
|
|
|
|
|
label={<span className="font-bold">上传配置文件</span>}
|
|
|
|
|
value={fileList}
|
|
|
|
|
name="dragger"
|
|
|
|
|
fieldProps={{
|
|
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {
|
|
|
|
|
return false;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
{/* // TODO label字重与上面统一, 操作按钮需要与输入框对齐 */}
|
|
|
|
|
<ProFormList
|
|
|
|
|
name="params"
|
|
|
|
|
label={
|
|
|
|
|
<div>
|
|
|
|
|
<span className="font-bold">模型参数</span>
|
|
|
|
|
<p style={{ color: '#666666' }}>
|
|
|
|
|
暂未上传模型配置文件,可根据业务需求手动添加参数字段~
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
actionRef={actionFormListRef}
|
|
|
|
|
itemContainerRender={(doms) => {
|
|
|
|
|
return <ProForm.Group>{doms}</ProForm.Group>;
|
|
|
|
|
}}
|
|
|
|
|
alwaysShowItemLabel
|
|
|
|
|
>
|
|
|
|
|
{() => {
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<ProFormText key="name" name="name" label="键名" />
|
|
|
|
|
<ProFormText key="default" name="default" label="默认值" />
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}}
|
|
|
|
|
</ProFormList>
|
|
|
|
|
</StepsForm.StepForm>
|
|
|
|
|
{/* 关联节点 */}
|
|
|
|
|
<StepsForm.StepForm<{
|
|
|
|
|
group: string;
|
|
|
|
|
}>
|
|
|
|
|
name="group"
|
|
|
|
|
title={<FormattedMessage id="business_model.stepForm.group" defaultMessage="关联节点" />}
|
|
|
|
|
stepProps={{
|
|
|
|
|
description: (
|
|
|
|
|
<FormattedMessage
|
|
|
|
|
id="business_model.stepForm.group.description"
|
|
|
|
|
defaultMessage="关联相关设备节点"
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
}}
|
|
|
|
|
onFinish={async () => {
|
|
|
|
|
return true;
|
|
|
|
|
}}
|
|
|
|
|
style={{ width: proFormMaxItemStyleProps.width }}
|
|
|
|
|
>
|
|
|
|
|
<div style={{ paddingBottom: 10, fontWeight: 700 }}>{'节点信息'}</div>
|
|
|
|
|
<Tree
|
|
|
|
|
checkable
|
|
|
|
|
defaultExpandAll={true}
|
|
|
|
|
defaultCheckedKeys={[]}
|
|
|
|
|
autoExpandParent={true}
|
|
|
|
|
onCheck={(checkedKeys: any) => {
|
|
|
|
|
// form.setFieldsValue({menuIds: checkedKeys})
|
|
|
|
|
setSelectKeys(checkedKeys);
|
|
|
|
|
// formRef3.current?.setFieldValue('groupIds', checkedKeys)
|
|
|
|
|
}}
|
|
|
|
|
treeData={treeData}
|
|
|
|
|
// loadData={({treeNode}) => {
|
|
|
|
|
// return treeData
|
|
|
|
|
// }}
|
|
|
|
|
/>
|
|
|
|
|
</StepsForm.StepForm>
|
|
|
|
|
</StepsForm>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
export default CreateForm;
|