Refactor TrafficDistributionForm component to improve state management and error handling. Update time range parsing logic for better validation and user feedback. Adjust form submission handling and enhance device selection logic. Modify slider maximum value for daily distribution limits.

This commit is contained in:
超级老白兔
2025-11-04 16:40:53 +08:00
parent 05c5915e7b
commit ac605baa24

View File

@@ -32,15 +32,18 @@ const TrafficDistributionForm: React.FC = () => {
const isEdit = !!id;
const [current, setCurrent] = useState(0);
const [selectedAccounts, setSelectedAccounts] = useState<AccountItem[]>([]);
const [selectedDevices, setSelectedDevices] = useState<DeviceSelectionItem[]>(
[],
);
// 设备组和账号组数据
const [deviceGroups, setDeviceGroups] = useState<any[]>([]);
const [deviceGroupsOptions, setDeviceGroupsOptions] = useState<any[]>([]);
const [accountGroups, setAccountGroups] = useState<any[]>([]);
const [accountGroupsOptions, setAccountGroupsOptions] = useState<any[]>([]);
const [deviceGroups, setDeviceGroups] = useState<DeviceSelectionItem[]>([]);
const [deviceGroupsOptions, setDeviceGroupsOptions] = useState<
DeviceSelectionItem[]
>([]);
const [accountGroups, setAccountGroups] = useState<AccountItem[]>([]);
const [accountGroupsOptions, setAccountGroupsOptions] = useState<
AccountItem[]
>([]);
// 使用 Form 管理字段,配合 useWatch 读取值
const [loading, setLoading] = useState(false);
const [detailLoading, setDetailLoading] = useState(false);
@@ -49,12 +52,9 @@ const TrafficDistributionForm: React.FC = () => {
PoolSelectionItem[]
>([]);
// 编辑时的详情数据(不需要保存整份数据,仅回填表单与本地状态)
// 监听表单字段变化antd v5 推荐)
const maxPerDay = Form.useWatch("maxPerDay", form);
const timeType = Form.useWatch("timeType", form);
// const timeRange = Form.useWatch("timeRange", form);
// 生成默认名称
const generateDefaultName = () => {
@@ -83,7 +83,6 @@ const TrafficDistributionForm: React.FC = () => {
// 设置账号组数据
setAccountGroups(config.accountGroups || []);
setAccountGroupsOptions(config.accountGroupsOptions || []);
setSelectedAccounts(config.accountGroupsOptions || []);
// 设置设备组数据
setDeviceGroups(config.deviceGroups || []);
@@ -94,18 +93,43 @@ const TrafficDistributionForm: React.FC = () => {
// 设置时间范围 - 使用dayjs格式
if (config.timeType === 2 && config.startTime && config.endTime) {
const [startHour, startMinute] = config.startTime
.split(":")
.map(Number);
const [endHour, endMinute] = config.endTime.split(":").map(Number);
try {
const startTimeMatch = config.startTime.match(/^(\d{1,2}):(\d{2})$/);
const endTimeMatch = config.endTime.match(/^(\d{1,2}):(\d{2})$/);
// 使用dayjs创建时间对象
const startTime = dayjs().hour(startHour).minute(startMinute).second(0);
const endTime = dayjs().hour(endHour).minute(endMinute).second(0);
form.setFieldsValue({ timeRange: [startTime, endTime] });
if (startTimeMatch && endTimeMatch) {
const startHour = parseInt(startTimeMatch[1], 10);
const startMinute = parseInt(startTimeMatch[2], 10);
const endHour = parseInt(endTimeMatch[1], 10);
const endMinute = parseInt(endTimeMatch[2], 10);
// 验证时间有效性
if (
startHour >= 0 &&
startHour < 24 &&
startMinute >= 0 &&
startMinute < 60 &&
endHour >= 0 &&
endHour < 24 &&
endMinute >= 0 &&
endMinute < 60
) {
const startTime = dayjs()
.hour(startHour)
.minute(startMinute)
.second(0);
const endTime = dayjs().hour(endHour).minute(endMinute).second(0);
form.setFieldsValue({ timeRange: [startTime, endTime] });
} else {
console.warn("时间格式无效:", config.startTime, config.endTime);
}
} else {
console.warn("时间格式不匹配:", config.startTime, config.endTime);
}
} catch (error) {
console.error("解析时间失败:", error);
}
}
// 设置流量池 - 交由 PoolSelection 控件受控
} catch (error) {
console.error("获取详情失败:", error);
message.error("获取详情失败");
@@ -120,24 +144,21 @@ const TrafficDistributionForm: React.FC = () => {
fetchDetail();
}
}, [isEdit, id, fetchDetail]);
const handleFinish = async () => {
form.submit();
};
const handleFinish2 = async (values?: any) => {
const handleSubmit = async (values?: any) => {
setLoading(true);
try {
// 校验流量池至少选择一个
if (!poolGroupsOptions || poolGroupsOptions.length === 0) {
message.error("请至少选择一个流量池");
setLoading(false);
return;
}
// if (!poolGroupsOptions || poolGroupsOptions.length === 0) {
// message.error("请至少选择一个流量池");
// setLoading(false);
// return;
// }
// 如果没有传递values参数从表单中获取
const formValues = values || form.getFieldsValue();
const formValues = values ?? form.getFieldsValue();
const formData: TrafficDistributionFormData = {
id: id,
id,
type: 5, // 流量分发类型
name: formValues.name,
source: "",
@@ -155,9 +176,9 @@ const TrafficDistributionForm: React.FC = () => {
? formValues.timeRange[1].format("HH:mm")
: "",
deviceGroups: deviceGroupsOptions.map(v => v.id),
deviceGroupsOptions: deviceGroupsOptions,
deviceGroupsOptions,
accountGroups: accountGroupsOptions.map(v => v.id),
accountGroupsOptions: accountGroupsOptions,
accountGroupsOptions,
poolGroups: poolGroupsOptions.map(v => v.id),
enabled: true,
};
@@ -191,7 +212,7 @@ const TrafficDistributionForm: React.FC = () => {
// 验证失败,不进行下一步
});
} else if (current === 1) {
// 第二步:目标设置至少需要选择设备或客服之一
// 第二步:目标设置至少需要选择一个设备
const hasDevice =
Array.isArray(selectedDevices) && selectedDevices.length > 0;
if (!hasDevice) {
@@ -205,7 +226,7 @@ const TrafficDistributionForm: React.FC = () => {
};
const prev = () => setCurrent(cur => cur - 1);
const handPoolAction = params => {
const handlePoolSelect = (params: PoolSelectionItem[]) => {
setPoolGroupsOptions(params);
};
@@ -236,7 +257,7 @@ const TrafficDistributionForm: React.FC = () => {
<Button
type="primary"
size="large"
onClick={handleFinish}
onClick={() => form.submit()}
loading={loading}
>
@@ -257,7 +278,7 @@ const TrafficDistributionForm: React.FC = () => {
timeType: 1,
}}
disabled={detailLoading}
onFinish={handleFinish2}
onFinish={handleSubmit}
style={{ display: current === 0 ? "block" : "none" }}
>
<div className={style.sectionTitle}></div>
@@ -300,7 +321,7 @@ const TrafficDistributionForm: React.FC = () => {
noStyle
rules={[{ required: true, message: "请设置每日最大分配量" }]}
>
<Slider min={1} max={100} className={style.slider} />
<Slider min={1} max={1000} className={style.slider} />
</Form.Item>
<div className={style.sliderDesc}></div>
</Form.Item>
@@ -372,7 +393,7 @@ const TrafficDistributionForm: React.FC = () => {
{current === 2 && (
<PoolSelection
selectedOptions={poolGroupsOptions}
onSelect={handPoolAction}
onSelect={handlePoolSelect}
placeholder="请选择流量池"
showSelectedList={true}
selectedListMaxHeight={300}