feat(scene): 所有工程页对接新增和编辑api

- 实现工程新增和编辑功能
- 优化cover组件,保持组件间的数据同步
master
钟良源 5 months ago
parent 8106ef17f8
commit 15189c6f1c

@ -1,4 +1,4 @@
import React, { useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Button, Input, Table, TableColumnProps } from '@arco-design/web-react'; import { Button, Input, Table, TableColumnProps } from '@arco-design/web-react';
import { IconDelete, IconPlusCircle } from '@arco-design/web-react/icon'; import { IconDelete, IconPlusCircle } from '@arco-design/web-react/icon';
@ -10,8 +10,17 @@ interface TableDataItem {
[key: string]: any; // 允许其他自定义字段 [key: string]: any; // 允许其他自定义字段
} }
const ConfigTable = () => { interface ConfigTableProps {
const [tableData, setTableData] = useState([]); configUrls?: TableDataItem[];
onChange?: (data: TableDataItem[]) => void;
}
const ConfigTable: React.FC<ConfigTableProps> = ({ configUrls = [], onChange }) => {
const [tableData, setTableData] = useState<TableDataItem[]>([]);
useEffect(() => {
setTableData(configUrls);
}, [configUrls]);
const columns: TableColumnProps[] = [ const columns: TableColumnProps[] = [
{ {
@ -54,11 +63,17 @@ const ConfigTable = () => {
}; };
const newData = [...tableData, newRow]; const newData = [...tableData, newRow];
setTableData(newData); setTableData(newData);
if (onChange) {
onChange(newData);
}
}; };
const removeRow = (key: number | string) => { const removeRow = (key: number | string) => {
const newData = tableData.filter((item) => item.key !== key); const newData = tableData.filter((item) => item.key !== key);
setTableData(newData); setTableData(newData);
if (onChange) {
onChange(newData);
}
}; };
const handleSave = (row: TableDataItem) => { const handleSave = (row: TableDataItem) => {
@ -71,6 +86,9 @@ const ConfigTable = () => {
newData.push(row); newData.push(row);
} }
setTableData(newData); setTableData(newData);
if (onChange) {
onChange(newData);
}
}; };
return ( return (

@ -13,9 +13,10 @@ const imageList = [scene01, scene02, scene03, scene04, scene07, scene08];
interface CoverProps { interface CoverProps {
defaultImage?: string; defaultImage?: string;
onImageChange?: (image: string) => void;
} }
const Cover: React.FC<CoverProps> = ({ defaultImage }) => { const Cover: React.FC<CoverProps> = ({ defaultImage, onImageChange }) => {
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const [currentImage, setCurrentImage] = useState(''); const [currentImage, setCurrentImage] = useState('');
@ -26,8 +27,18 @@ const Cover: React.FC<CoverProps> = ({ defaultImage }) => {
else { else {
const imageRandom = Math.floor(Math.random() * imageList.length); const imageRandom = Math.floor(Math.random() * imageList.length);
setCurrentImage(imageList[imageRandom].src); setCurrentImage(imageList[imageRandom].src);
onImageChange(imageList[imageRandom].src);
} }
}, [defaultImage]); }, [defaultImage]);
const handleImageSelect = (imageSrc: string) => {
setCurrentImage(imageSrc);
setVisible(false);
if (onImageChange) {
onImageChange(imageSrc);
}
};
return ( return (
<div className={styles['cover-container']}> <div className={styles['cover-container']}>
<div className={styles['cover-image']}> <div className={styles['cover-image']}>
@ -50,8 +61,7 @@ const Cover: React.FC<CoverProps> = ({ defaultImage }) => {
return ( return (
<List.Item key={index}> <List.Item key={index}>
<Image width={200} src={item.src} preview={false} onClick={() => { <Image width={200} src={item.src} preview={false} onClick={() => {
setCurrentImage(item.src); handleImageSelect(item.src);
setVisible(false);
}}></Image> }}></Image>
</List.Item> </List.Item>
); );

@ -51,7 +51,6 @@ const Engineering: React.FC<EngineeringProps> = ({ dataType, showAdd = true }) =
}; };
const openModalHandle = (type: string, item: any = null) => { const openModalHandle = (type: string, item: any = null) => {
console.log('item:', item);
setShowModal(true); setShowModal(true);
setOperationType(type); setOperationType(type);
setCurrentItem(item); setCurrentItem(item);
@ -186,7 +185,8 @@ const Engineering: React.FC<EngineeringProps> = ({ dataType, showAdd = true }) =
show={showModal} show={showModal}
type={operationType} type={operationType}
item={currentItem} item={currentItem}
onCancel={(status) => setShowModal(status)} onClose={(status) => setShowModal(status)}
onRefresh={() => fetchData(1, 11)}
/> />
</> </>
); );

@ -1,7 +1,8 @@
import React, { useEffect } from 'react'; import React, { useEffect, useState } from 'react';
import { Modal, Form, Input, Checkbox } from '@arco-design/web-react'; import { Modal, Form, Input, Checkbox, Message } from '@arco-design/web-react';
import Cover from '@/pages/scene/cover'; import Cover from '@/pages/scene/cover';
import ConfigTable from '@/pages/scene/configTable'; import ConfigTable from '@/pages/scene/configTable';
import { addScene, editScene } from '@/api/scene';
const FormItem = Form.Item; const FormItem = Form.Item;
@ -9,40 +10,141 @@ interface OperationModalProps {
show: boolean; show: boolean;
type: string; type: string;
item: any; item: any;
onCancel: (status: boolean) => void; onClose: (status: boolean) => void;
onRefresh: () => void;
} }
const OperationModal: React.FC<OperationModalProps> = ({ show, type, item, onCancel }) => { const OperationModal: React.FC<OperationModalProps> = ({ show, type, item, onClose, onRefresh }) => {
const [visible, setVisible] = React.useState(false); const [visible, setVisible] = useState(false);
const [selectedImage, setSelectedImage] = useState('');
const [configUrls, setConfigUrls] = useState([]);
const [form] = Form.useForm();
const transformImageUrl = (image: string) => {
if (!image) return;
if (image.includes('/')) setSelectedImage(image.split('/')[image.split('/').length - 1]);
else setSelectedImage(image);
};
const onOk = async () => {
await form.validate();
const formData = form.getFields();
const params = {
...formData,
logo: selectedImage,
published: formData.published ? 1 : 0,
configUrls: configUrls
};
if (type === 'ADD') {
const res: any = await addScene(params);
if (res.code === 200) {
Message.success('创建成功');
setVisible(false);
onClose(false);
onRefresh();
// 清空表单数据和其他变量数据
form.resetFields();
setSelectedImage('');
setConfigUrls([]);
}
}
else {
const res: any = await editScene(params);
if (res.code === 200) {
Message.success('更新成功');
setVisible(false);
onClose(false);
onRefresh();
// 清空表单数据和其他变量数据
form.resetFields();
setSelectedImage('');
setConfigUrls([]);
}
}
};
useEffect(() => { useEffect(() => {
setVisible(show); setVisible(show);
}, [show]); }, [show]);
useEffect(() => {
transformImageUrl(item?.logo);
form.setFieldsValue({
id: item?.id,
name: item?.name,
description: item?.description,
published: item?.published === 1
});
setConfigUrls(item?.configUrls || []);
}, [item]);
return ( return (
<Modal <Modal
style={{ width: '50%' }} style={{ width: '50%' }}
title={type === 'ADD' ? '创建工程' : '编辑工程'} title={type === 'ADD' ? '创建工程' : '编辑工程'}
visible={visible} visible={visible}
onOk={() => setVisible(false)} onOk={() => onOk()}
onCancel={() => onCancel(false)} onCancel={() => onClose(false)}
autoFocus={false} autoFocus={false}
focusLock={true} focusLock={true}
> >
<Form autoComplete="off"> <Form form={form} autoComplete="off">
<FormItem label="封面图"> <FormItem label="封面图">
<Cover defaultImage={item?.logo} /> <Cover
defaultImage={item?.logo}
onImageChange={(selectedImage) => transformImageUrl(selectedImage)}
/>
</FormItem> </FormItem>
<FormItem label="名称" required> <FormItem
field="name"
label="名称"
required
rules={[
{
validator(value, cb) {
if (!value) {
return cb('请填写工程名称');
}
// 检查是否只包含汉字
const chineseOnlyRegex = /^[\u4e00-\u9fa5]+$/;
if (!chineseOnlyRegex.test(value)) {
return cb('工程名称只能输入汉字');
}
return cb();
}
}
]}
>
<Input placeholder="请输入工程名称" /> <Input placeholder="请输入工程名称" />
</FormItem> </FormItem>
<FormItem label="描述" required> <FormItem
field="description"
label="描述"
required
rules={[
{
validator(value, cb) {
if (!value) {
return cb('请填写工程描述');
}
return cb();
}
}
]}
>
<Input placeholder="请输入工程描述" /> <Input placeholder="请输入工程描述" />
</FormItem> </FormItem>
<FormItem label="大屏"> <FormItem field="configUrls" label="大屏">
<ConfigTable /> <ConfigTable
configUrls={configUrls}
onChange={(data) => setConfigUrls(data)}
/>
</FormItem> </FormItem>
<FormItem label=" "> <FormItem field="published" label=" ">
<Checkbox></Checkbox> <Checkbox></Checkbox>
</FormItem> </FormItem>
</Form> </Form>

Loading…
Cancel
Save