You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

490 lines
16 KiB
TypeScript

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;