feat: 上传控件初始化,待验证,中文国际化拓展加入antdesign基础语言库

develop2
donghao 10 months ago
parent 01093e14a5
commit 2dff260baa

@ -458,7 +458,9 @@
.gn_form .ant-form-item {
margin-bottom: 16px;
}
.gn_form .ant-select-outlined:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer):hover .ant-select-selector,
.gn_form .ant-select-outlined:not(.ant-select-disabled):not(.ant-select-customize-input):not(
.ant-pagination-size-changer
):hover .ant-select-selector,
.gn_form .ant-picker-outlined:focus-within {
border-color: #154ddd;
}
@ -624,6 +626,13 @@
.gn_proFormUploadDragger_formItem .gn_uploadfile_title a {
color: #154ddd;
}
.gn_dragger_formItem .ant-upload-wrapper .ant-upload {
width: 100%;
}
.gn_dragger_formItem .ant-upload-wrapper .ant-upload-drag-icon {
height: 32px !important;
line-height: 32px !important;
}
.ant-table-wrapper .ant-table-pagination.ant-pagination {
margin: 0;
padding: 24px 0 !important;

@ -742,7 +742,6 @@
}
/* 表单控件 */
.gn_proFormUploadDragger_formItem {
&.ant-upload-wrapper {
line-height: 1;
@ -759,6 +758,17 @@
}
}
}
.gn_dragger_formItem {
.ant-upload-wrapper {
.ant-upload {
width: 100%;
}
.ant-upload-drag-icon {
height: 32px !important;
line-height: 32px !important;
}
}
}
// 分页器
.ant-table-wrapper .ant-table-pagination.ant-pagination {

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-03-27 16:03:20
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-30 14:53:21
* @LastEditTime: 2024-07-16 10:51:55
* @FilePath: \general-ai-manage\src\components\Header\index.tsx
* @Description: layout
*/
@ -32,6 +32,7 @@ const MenuBar: React.FC<MenuBarProps> = ({ menuData, changeMenu }) => {
// 根据路径查找对应的菜单项
const findMenuByPath = (menuData: any, pathname: any) => {
if (menuData) {
for (const item of menuData) {
if (item.path === pathname) {
return item;
@ -44,6 +45,8 @@ const MenuBar: React.FC<MenuBarProps> = ({ menuData, changeMenu }) => {
// }
// }
}
}
return null;
};

@ -6,8 +6,10 @@
* @FilePath: \general-ai-platform-web\src\components\UploadFile\index.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import draggerUpload from './src/draggerUpload';
import proFormUploadDraggerToken from './src/formUploadDraggerToken';
import uploadFileForView from './src/uploadFileForView';
export const DraggerUpload = draggerUpload;
export const FormUploadDraggerToken = proFormUploadDraggerToken;
export const UploadFileForView = uploadFileForView;

@ -0,0 +1,212 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-07-16 13:02:35
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-07-16 17:10:10
* @FilePath: \general-ai-platform-web\src\components\UploadFile\src\draggerUpload.tsx
* @Description:
*
* @
* 1.
* 2.
* 3.
* 4.
* 5.
*
*/
import { apiFileDelete, apiFileUpload } from '@/services/business/file';
import { useIntl } from '@umijs/max';
import { isSuccessApi } from '@/utils/forApi';
import { ProFormItem } from '@ant-design/pro-components';
import { message, Upload } from 'antd';
import React, { useState } from 'react';
import UploadFileForView from './uploadFileForView';
// export const fileType = [
// // 压缩包
// { type: 'ZIP', value: 'application/zip' },
// { type: 'GZIP', value: 'application/gzip' },
// { type: 'TAR', value: 'application/x-tar' },
// { type: 'BZIP2', value: 'application/x-bzip2' },
// { type: '7Z', value: 'application/x-7z-compressed' },
// { type: 'RAR', value: 'application/vnd.rar' },
// { type: 'XZ', value: 'application/x-xz' },
// { type: 'LZMA', value: 'application/x-lzma' },
// { type: 'ISO', value: 'application/x-iso9660-image' },
// { type: 'CAB', value: 'application/vnd.ms-cab-compressed' },
// { type: 'Z', value: 'application/x-compress' },
// // JSON 或者 YAML
// { type: 'JSON', value: 'application/json' },
// { type: 'YAML', value: 'application/x-yaml' },
// { type: 'YML', value: 'application/x-yaml' },
// ];
// const { Dragger } = Upload;
const DraggerUpload: React.FC = (props) => {
const intl = useIntl();
const [fileList, setFileList] = useState<UploadFile[]>(props?.proFieldProps?.initialValue || []);
const [dragOver, setDragOver] = useState(false);
const [previewFile, setPreviewFile] = useState(null);
const defualtOptions = {
accept: props?.proFieldProps?.accept || 'application/json, application/x-yaml', // 默认使用 JSON 或者 yaml 文件类型
max: props?.proFieldProps?.max || 1,
size: props?.proFieldProps?.size || 1024 * 1024 * 200,
};
// const defalutOptions: UploadProps = {
// name: 'file',
// multiple: true,
// action: 'https://660d2bd96ddfa2943b33731c.mockapi.io/api/upload',
// onChange(info) {
// const { status } = info.file;
// if (status !== 'uploading') {
// console.log(info.file, info.fileList);
// }
// if (status === 'done') {
// message.success(`${info.file.name} file uploaded successfully.`);
// } else if (status === 'error') {
// message.error(`${info.file.name} file upload failed.`);
// }
// },
// onDrop(e) {
// console.log('Dropped files', e.dataTransfer.files);
// },
// };
// 文件格式和大小校验
const validateFile = (file: UploadFile) => {
const isValidType = defualtOptions.accept.split(',').includes(file.type);
const isLt2M = file.size < defualtOptions.size;
if (!isValidType) {
message.error('文件格式不对!');
}
if (!isLt2M) {
// TODO 暂时写死200M
message.error('文件大小不得超过200M');
}
return isValidType && isLt2M;
};
const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
setDragOver(true);
};
const handleDragLeave = () => {
setDragOver(false);
};
const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
setDragOver(false);
const files = Array.from(e.dataTransfer.files);
files.forEach((file) => {
const isValid = validateFile(file);
if (isValid && fileList.length < defualtOptions.max) {
setFileList([...fileList, file]);
}
});
};
const handleBeforeUpload = async (file: UploadFile) => {
const isValid = validateFile(file);
if (isValid) {
const formData = new FormData();
formData.append('file', file);
const resp = await apiFileUpload(formData);
if (isSuccessApi(resp)) {
setFileList([
{
uid: file?.uid,
name: file?.name,
status: 'done',
url: '/file/' + resp?.data?.result,
fileId: resp?.data?.result,
},
]);
setPreviewFile(file);
props.afterUploadFile({ resp, file, fileList });
}
console.log(resp, 'apiFileUpload_resp');
}
return false; // Prevent auto-upload
};
const handleRemove = async (file: UploadFile<R<string>>) => {
console.log(file, 'onRemoveFile_file', fileList);
const currFile = fileList.find((item) => item.uid === file.uid);
const resp = await apiFileDelete({ file_md5: currFile?.fileId || file?.uid });
console.log(resp, 'apiFileDelete_resp');
props.afterRemoveFile(resp, file);
setPreviewFile(null);
if (isSuccessApi(resp)) {
message.success(`${file.name} 删除成功`);
setFileList(fileList.filter((item) => item.uid !== file.uid));
} else {
message.error(
resp?.meta?.message ||
intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }),
);
}
};
const customRequest = async ({ file, onSuccess, onError }) => {
const formData = new FormData();
formData.append('file', file);
try {
const response = await fetch('https://your-upload-api-endpoint.com/upload', {
method: 'POST',
body: formData,
});
if (response.ok) {
onSuccess('ok');
message.success('File uploaded successfully');
} else {
throw new Error('Upload failed');
}
} catch (error) {
onError(error);
message.error('Upload failed');
}
};
return (
<ProFormItem name="upload" label={props?.proFieldProps?.label} valuePropName="fileList">
<div
className={`custom-dragger gn_dragger_formItem ${dragOver ? 'drag-over' : ''}`}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
>
<Upload
fileList={fileList}
beforeUpload={handleBeforeUpload}
onRemove={handleRemove}
customRequest={customRequest}
>
{fileList.length < defualtOptions.max && (
<span className="gn_proFormUploadDragger_formItem">
<div className="ant-upload ant-upload-drag">
<span className="ant-upload ant-upload-btn">
<div className="ant-upload-drag-container">
<div className="ant-upload-drag-icon">{props?.proFieldProps?.icon}</div>
<p className="ant-upload-text">{props?.proFieldProps?.title}</p>
<p className="ant-upload-hint">{props?.proFieldProps?.description}</p>
</div>
</span>
</div>
</span>
)}
</Upload>
</div>
{props?.openPreviewFile && <UploadFileForView file={previewFile} />}
</ProFormItem>
);
};
export default DraggerUpload;

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-07 15:25:23
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-28 09:57:42
* @LastEditTime: 2024-07-16 10:52:28
* @FilePath: \general-ai-manage\src\layouts\HomeLayout.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/

@ -1,3 +1,12 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-19 14:07:32
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-07-16 10:55:09
* @FilePath: \general-ai-platform-web\src\locales\en-US.ts
* @Description:
*/
import locale_en_US from 'antd/es/locale/en_US';
import component from './en-US/component';
import globalHeader from './en-US/globalHeader';
import menu from './en-US/menu';
@ -5,7 +14,6 @@ import pages from './en-US/pages';
import pwa from './en-US/pwa';
import settingDrawer from './en-US/settingDrawer';
import settings from './en-US/settings';
export default {
'navBar.lang': 'Languages',
'layout.user.link.help': 'Help',
@ -14,6 +22,7 @@ export default {
'app.preview.down.block': 'Download this pageNo to your local project',
'app.welcome.link.fetch-blocks': 'Get all block',
'app.welcome.link.block-list': 'Quickly build standard, pages based on `block` development',
...locale_en_US,
...globalHeader,
...menu,
...settingDrawer,

@ -2,10 +2,11 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-01 11:20:09
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-13 10:25:25
* @LastEditTime: 2024-07-16 10:51:00
* @FilePath: \uighur-recognition-web2\src\locales\zh-CN.ts
* @Description:
*/
import locale_zh_CN from 'antd/es/locale/zh_CN'; // ant design 基本语言库
import * as alarms from './zh-CN/alarm';
import * as businessProject from './zh-CN/businessProject';
import common from './zh-CN/common';
@ -29,6 +30,7 @@ export default {
'app.preview.down.block': '下载此页面到本地项目',
'app.welcome.link.fetch-blocks': '获取全部区块',
'app.welcome.link.block-list': '基于 block 开发,快速构建标准页面',
...locale_zh_CN,
...pages,
...globalHeader,
...menu,
@ -42,7 +44,6 @@ export default {
...Object.values(businessProject),
...Object.values(model),
...Object.values(server),
// 待启用
...Object.values(systems),
...Object.values(alarms),

@ -1,5 +1,22 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-19 14:07:32
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-07-16 10:20:29
* @FilePath: \general-ai-platform-web\src\locales\zh-CN\component.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
export default {
'component.tagSelect.expand': '展开',
'component.tagSelect.collapse': '收起',
'component.tagSelect.all': '全部',
'pagination.total': '总共 {total} 条数据',
'pagination.items_per_page': '每页 {size} 条',
'pagination.jump_to': '跳至',
'pagination.page': '页',
'pagination.prev_page': '上一页',
'pagination.next_page': '下一页',
'pagination.prev_5': '向前 5 页',
'pagination.next_5': '向后 5 页',
};

@ -1,4 +1,4 @@
import { FormUploadDraggerToken } from '@/components/UploadFile';
import { DraggerUpload } from '@/components/UploadFile';
import { apiModelVersionAdd } from '@/services/business/model';
import { isSuccessApi } from '@/utils/forApi';
import {
@ -51,11 +51,11 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
// test 测试数据
useEffect(() => {
// 初始化赋值
setCurrFormData({
version: '1.0.91', // 设备分类的suid 59aa3d0c3162322e190942a9cc9add10
comment:
'测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注',
});
// setCurrFormData({
// version: '1.0.91', // 设备分类的suid 59aa3d0c3162322e190942a9cc9add10
// comment:
// '测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注',
// });
}, [props.createModalOpen]);
return (
<StepsForm<{
@ -231,7 +231,7 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
return true;
}}
>
<FormUploadDraggerToken
<DraggerUpload
proFieldProps={{
label: (
<div className="flex">
@ -249,6 +249,8 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
icon: <i className="iconfont icon-shangchuanwenjian text_primary text-[32px]"></i>,
name: 'model_file_arr',
max: 1,
// initialValue: [],
accept: 'application/zip, application/gzip, application/x-tar',
}}
afterUploadFile={({ resp }) => {
setCurrFormData((data) => {
@ -289,7 +291,7 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
return true;
}}
>
<FormUploadDraggerToken
<DraggerUpload
proFieldProps={{
label: (
<div className="flex">
@ -307,6 +309,8 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
icon: <i className="iconfont icon-shangchuanwenjian text_primary text-[32px]"></i>,
name: 'config_file_arr',
max: 1,
// initialValue: [],
// accept: 'application/zip, application/gzip, application/x-tar',
}}
afterUploadFile={({ resp }) => {
setCurrFormData((data) => {
@ -320,95 +324,6 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
}}
openPreviewFile={true}
/>
{/* <ProFormUploadDragger
width={proFormSmallItemStyleProps.width}
max={1}
label={<span className="font-bold"></span>}
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_name"
action={fileApiActionUrl}
fieldProps={{
className: 'gn_proFormUploadDragger_formItem',
onChange: handleConfigFileChange,
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;
});
}
},
}}
/>
<div style={{ color: '#666666', marginTop: '-8px', marginBottom: '16px' }}>
.json.yaml.yml
</div> */}
{/* <ProFormList
name="config_str_arr"
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={268} key="name" name="name" label="键名" />
<ProFormText width={268} key="default" name="default" label="默认值" />
</>
);
}}
</ProFormList> */}
</StepsForm.StepForm>
</StepsForm>
);

@ -1,5 +1,5 @@
// TODO 上传文件限制为1时还可以上传
import { FormUploadDraggerToken } from '@/components/UploadFile';
import { DraggerUpload } from '@/components/UploadFile';
import { apiModelVersionEdit } from '@/services/business/model';
import { isSuccessApi } from '@/utils/forApi';
import {
@ -245,7 +245,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
return true;
}}
>
<FormUploadDraggerToken
<DraggerUpload
proFieldProps={{
label: (
<div className="flex">
@ -273,6 +273,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
},
]
: [],
accept: 'application/zip, application/gzip, application/x-tar',
}}
afterUploadFile={({ resp, file }) => {
console.log(resp, file, 'afterRemoveFile');
@ -314,7 +315,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
return true;
}}
>
<FormUploadDraggerToken
<DraggerUpload
proFieldProps={{
label: (
<div className="flex">
@ -355,99 +356,6 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
}}
openPreviewFile={true}
/>
{/* <ProFormUploadDragger
width={proFormSmallItemStyleProps.width}
max={1}
label={<span className="font-bold"></span>}
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_name"
action={fileApiActionUrl}
fieldProps={{
className: 'gn_proFormUploadDragger_formItem',
onChange: handleConfigFileChange,
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;
});
}
},
}}
/>
<div style={{ color: '#666666', marginTop: '-8px', marginBottom: '16px' }}>
.json.yaml.yml
</div> */}
{/* <ProFormList
name="config_str_arr"
label={
<div>
<span className="font-bold"></span>
<div style={{ color: '#333333', padding: '8px 0 4px' }}>
~
</div>
</div>
}
initialValue={
isValidJson(props.values?.config_str) ? JSON.parse(props.values?.config_str) : []
}
actionRef={actionFormListRef}
itemContainerRender={(doms) => {
return <ProForm.Group>{doms}</ProForm.Group>;
}}
alwaysShowItemLabel
>
{() => {
return (
<>
<ProFormText width={268} key="name" name="name" label="键名" />
<ProFormText width={268} key="default" name="default" label="默认值" />
</>
);
}}
</ProFormList> */}
</StepsForm.StepForm>
</StepsForm>
);

Loading…
Cancel
Save