Commit 667a0357 authored by chenshouchao's avatar chenshouchao

feat: 完成提交任务表单校验

parent 9c1ebdf0
...@@ -42,7 +42,7 @@ const getTransitionComponent = (transition: "grow" | "fade") => { ...@@ -42,7 +42,7 @@ const getTransitionComponent = (transition: "grow" | "fade") => {
const MySnackbarProvider = ({ const MySnackbarProvider = ({
vertical = "top", vertical = "top",
horizontal = "center", horizontal = "center",
autoHideDuration = 2000, autoHideDuration = 5000,
snackerClasses, snackerClasses,
ClickAwayListenerProps, ClickAwayListenerProps,
ContentProps, ContentProps,
......
...@@ -80,7 +80,7 @@ export default function MyCheckBox(props: IMyCheckBoxProps) { ...@@ -80,7 +80,7 @@ export default function MyCheckBox(props: IMyCheckBoxProps) {
); );
})} })}
</FormGroup> </FormGroup>
{helperText && <FormHelperText>{helperText}</FormHelperText>} {helperText && error && <FormHelperText>{helperText}</FormHelperText>}
</FormControl> </FormControl>
); );
} }
...@@ -59,7 +59,7 @@ export default function MyRadio(props: IMyRadioProps) { ...@@ -59,7 +59,7 @@ export default function MyRadio(props: IMyRadioProps) {
); );
})} })}
</RadioGroup> </RadioGroup>
{helperText && <FormHelperText>{helperText}</FormHelperText>} {helperText && error && <FormHelperText>{helperText}</FormHelperText>}
</FormControl> </FormControl>
); );
} }
...@@ -3,7 +3,7 @@ import styles from "./index.module.css"; ...@@ -3,7 +3,7 @@ import styles from "./index.module.css";
import MyInput from "@/components/mui/MyInput"; import MyInput from "@/components/mui/MyInput";
import Tooltip from "@mui/material/Tooltip"; import Tooltip from "@mui/material/Tooltip";
import classnames from "classnames"; import classnames from "classnames";
import { useState, useMemo } from "react"; import { useState, useMemo, useImperativeHandle, useCallback } from "react";
import FileSelect from "@/components/FileSelect"; import FileSelect from "@/components/FileSelect";
import moment from "moment"; import moment from "moment";
import MySelect, { optionsTransform } from "../components/MySelect"; import MySelect, { optionsTransform } from "../components/MySelect";
...@@ -18,6 +18,7 @@ import jobSueIcon from "@/assets/project/jobSue.svg"; ...@@ -18,6 +18,7 @@ import jobSueIcon from "@/assets/project/jobSue.svg";
type ConfigFormProps = { type ConfigFormProps = {
templateConfigInfo?: ITemplateConfig; templateConfigInfo?: ITemplateConfig;
setParameter: any; setParameter: any;
onRef?: React.Ref<any>
}; };
const ConfigForm = (props: ConfigFormProps) => { const ConfigForm = (props: ConfigFormProps) => {
...@@ -27,12 +28,36 @@ const ConfigForm = (props: ConfigFormProps) => { ...@@ -27,12 +28,36 @@ const ConfigForm = (props: ConfigFormProps) => {
"YYYY_MM_DD_HH_mm" "YYYY_MM_DD_HH_mm"
)}` )}`
); // 任务名称 ); // 任务名称
const [nameHelp, setNameHelp] = useState({
error: false,
helperText: ''
})
const [outputPath, setOutputPath] = useState<string>("ProjectData"); // 输出路径 const [outputPath, setOutputPath] = useState<string>("ProjectData"); // 输出路径
const [outputPathHelp, setOutputPathHelp] = useState({
error: false,
helperText: ''
})
const getNameAndPath = () => {
return {
name,
outputPath,
nameAndOutputPathCheck: !(checkName(name) || checkOutputPath(outputPath)) // 任务名称、输出路径是否通过校验
}
}
useImperativeHandle(props.onRef, () => {
return {
getNameAndPath: getNameAndPath,
};
});
const [fileSelectOpen, setFileSelectOpen] = useState(false); // 选择输出路径的弹窗显示控制 const [fileSelectOpen, setFileSelectOpen] = useState(false); // 选择输出路径的弹窗显示控制
const onFileSelectConfirm = (path: string) => { const onFileSelectConfirm = (path: string) => {
setFileSelectOpen(false); setFileSelectOpen(false);
setOutputPath(`ProjectData${path === "/" ? "" : path}`); setOutputPath(`ProjectData${path === "/" ? "" : path}`);
checkOutputPath(`ProjectData${path === "/" ? "" : path}`)
}; };
const handleFileSelectOnClose = () => { const handleFileSelectOnClose = () => {
...@@ -45,8 +70,42 @@ const ConfigForm = (props: ConfigFormProps) => { ...@@ -45,8 +70,42 @@ const ConfigForm = (props: ConfigFormProps) => {
const handleNameChange = (e: any) => { const handleNameChange = (e: any) => {
setName(e.target.value); setName(e.target.value);
checkName(e.target.value)
}; };
const checkName = (name: string = '')=>{
const reg = new RegExp(/^[a-zA-Z0-9\u4e00-\u9fa5-_]{3,30}$/)
if (reg.test(name)) {
setNameHelp({
error: false,
helperText: ''
})
return false
} else {
setNameHelp({
error: true,
helperText: '请输入正确任务名称(3~30字符,可包含大小写字母、数字、中文、特殊符号“-”、“_”)'
})
return true
}
}
const checkOutputPath = (outputPath: string = '')=>{
if (outputPath) {
setOutputPathHelp({
error: false,
helperText: ''
})
return false
} else {
setOutputPathHelp({
error: true,
helperText: '请选择输出路径'
})
return true
}
}
const renderTasks: IRenderTasks = useMemo(() => { const renderTasks: IRenderTasks = useMemo(() => {
const result: IRenderTasks = []; const result: IRenderTasks = [];
templateConfigInfo?.tasks.forEach((task, taskIndex) => { templateConfigInfo?.tasks.forEach((task, taskIndex) => {
...@@ -85,66 +144,11 @@ const ConfigForm = (props: ConfigFormProps) => { ...@@ -85,66 +144,11 @@ const ConfigForm = (props: ConfigFormProps) => {
return result; return result;
}, [templateConfigInfo]); }, [templateConfigInfo]);
// const options = [
// {
// key: "1aaaaa",
// value: "a",
// },
// {
// key: "bbbbbb",
// value: "b",
// },
// {
// key: "cccccc",
// value: "c",
// },
// {
// key: "dddddd",
// value: "d",
// },
// {
// key: "bbbbbb",
// value: "e",
// },
// {
// key: "cccccc",
// value: "f",
// },
// {
// key: "dddddd",
// value: "g",
// },
// ];
// path : [a, b]
// const [selectValue, setSelectValue] = useState("b");
// const [selectValue, setSelectValue] = useState<Array<any>>([]);
// const handleSelectChange = (e: any) => {
// console.log(e);
// setSelectValue(e.target.value);
// };
// const handleCheckBoxChange = (e: any) => {
// setSelectValue(e);
// };
// const handleRadioChange = (e: any) => {
// console.log(e);
// setSelectValue(e.target.value);
// };
// const renderFormItem = (domtype) => {
// }
const handleParameterChange = ( const handleParameterChange = (
e: any, e: any,
taskId: string, taskId: string,
parameterName: string parameterName: string
) => { ) => {
console.log(e, taskId, parameterName);
setParameter(e.target.value, taskId, parameterName); setParameter(e.target.value, taskId, parameterName);
}; };
...@@ -180,6 +184,8 @@ const ConfigForm = (props: ConfigFormProps) => { ...@@ -180,6 +184,8 @@ const ConfigForm = (props: ConfigFormProps) => {
value={name} value={name}
onChange={handleNameChange} onChange={handleNameChange}
placeholder="请输入任务名称" placeholder="请输入任务名称"
error={nameHelp.error}
helperText={nameHelp.helperText}
></MyInput> ></MyInput>
</div> </div>
</div> </div>
...@@ -205,6 +211,8 @@ const ConfigForm = (props: ConfigFormProps) => { ...@@ -205,6 +211,8 @@ const ConfigForm = (props: ConfigFormProps) => {
/> />
), ),
}} }}
error={outputPathHelp.error}
helperText={outputPathHelp.helperText}
></MyInput> ></MyInput>
</div> </div>
</div> </div>
...@@ -227,13 +235,16 @@ const ConfigForm = (props: ConfigFormProps) => { ...@@ -227,13 +235,16 @@ const ConfigForm = (props: ConfigFormProps) => {
<span className={styles.backgroundTitleText}>{task.title}</span> <span className={styles.backgroundTitleText}>{task.title}</span>
</div> </div>
<div className={styles.taskConfigBox}> <div className={styles.taskConfigBox}>
{task.parameters.map((parameter, parameterIndex) => { {task.parameters.filter(parameter => parameter.hidden === false).map((parameter, parameterIndex) => {
return ( return (
<div <div
className={styles.parameter} className={styles.parameter}
key={parameter.id || "" + parameterIndex} key={parameter.id || "" + parameterIndex}
> >
<div className={styles.parameterTitle}> <div className={classnames({
[styles.parameterTitle]: true,
[styles.required]: parameter.required,
})}>
{parameter.name} {parameter.name}
<span className={styles.parameterDataType}> <span className={styles.parameterDataType}>
{parameter.dataType} {parameter.dataType}
......
import * as React from "react"; import * as React from "react";
import Box from "@mui/material/Box";
import InputLabel from "@mui/material/InputLabel"; import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem"; import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl"; import FormControl from "@mui/material/FormControl";
...@@ -58,7 +57,6 @@ export default function MySelect(props: IProps) { ...@@ -58,7 +57,6 @@ export default function MySelect(props: IProps) {
} = props; } = props;
return ( return (
<Box sx={{ minWidth: 120 }}>
<FormControl fullWidth variant={variant} error={error}> <FormControl fullWidth variant={variant} error={error}>
{isTitle ? ( {isTitle ? (
<InputLabel id="demo-simple-select-label"> <InputLabel id="demo-simple-select-label">
...@@ -89,8 +87,7 @@ export default function MySelect(props: IProps) { ...@@ -89,8 +87,7 @@ export default function MySelect(props: IProps) {
}) })
: null} : null}
</Select> </Select>
{helperText && <FormHelperText>{helperText}</FormHelperText>} {helperText && error && <FormHelperText>{helperText}</FormHelperText>}
</FormControl> </FormControl>
</Box>
); );
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* @FilePath: /bkunyun/src/views/Project/ProjectSubmitWork/index.tsx * @FilePath: /bkunyun/src/views/Project/ProjectSubmitWork/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
import { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import styles from "./index.module.css"; import styles from "./index.module.css";
import ConfigForm from "./ConfigForm"; import ConfigForm from "./ConfigForm";
import WorkFlow from "./WorkFlow"; import WorkFlow from "./WorkFlow";
...@@ -21,12 +21,16 @@ import { useLocation, useNavigate } from "react-router-dom"; ...@@ -21,12 +21,16 @@ import { useLocation, useNavigate } from "react-router-dom";
import { getCheckResult } from "./util"; import { getCheckResult } from "./util";
import { IResponse } from "@/api/http"; import { IResponse } from "@/api/http";
import { templateConfigJson } from "./mock"; import { templateConfigJson } from "./mock";
import { useMessage } from "@/components/MySnackbar";
const ProjectSubmitWork = () => { const ProjectSubmitWork = () => {
const Message = useMessage()
const [templateConfigInfo, setTemplateConfigInfo] = const [templateConfigInfo, setTemplateConfigInfo] =
useState<ITemplateConfig>(templateConfigJson as ITemplateConfig); useState<ITemplateConfig>(templateConfigJson as ITemplateConfig);
const location: any = useLocation(); const location: any = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
let configFormRef: any = React.createRef();
/** 获取模版数据 */ /** 获取模版数据 */
const { run } = useMyRequest(fetchTemplateConfigInfo, { const { run } = useMyRequest(fetchTemplateConfigInfo, {
...@@ -55,26 +59,6 @@ const ProjectSubmitWork = () => { ...@@ -55,26 +59,6 @@ const ProjectSubmitWork = () => {
const checkResult = getCheckResult(parameter,value) const checkResult = getCheckResult(parameter,value)
parameter.error = checkResult.error parameter.error = checkResult.error
parameter.helperText = checkResult.helperText parameter.helperText = checkResult.helperText
// 表单校验
// if (parameter.required && !value) {
// parameter.error = true
// parameter.helperText = '该选项是必填项'
// } else if (parameter.validators.length > 0) {
// parameter.validators.forEach((validator)=>{
// let error = false
// let helperText = ''
// const reg = new RegExp(validator.regex)
// if (!reg.test(value)) {
// error = true
// helperText = validator.message
// }
// parameter.error = error
// parameter.helperText = helperText
// })
// } else {
// parameter.error = false
// parameter.helperText = ''
// }
} else { } else {
return; return;
} }
...@@ -86,6 +70,31 @@ const ProjectSubmitWork = () => { ...@@ -86,6 +70,31 @@ const ProjectSubmitWork = () => {
setTemplateConfigInfo(result); setTemplateConfigInfo(result);
}; };
const handleSubmitForm = () => {
let check = true
const {name, outputPath, nameAndOutputPathCheck} = configFormRef.current.getNameAndPath()
if (!nameAndOutputPathCheck) {
check = false
}
const result: ITemplateConfig = _.cloneDeep(templateConfigInfo);
result.tasks.forEach((tack) => {
tack.parameters.forEach((parameter) => {
const checkResult = getCheckResult(parameter,parameter.value)
parameter.error = checkResult.error
parameter.helperText = checkResult.helperText
if (checkResult.error) {
check = false
}
});
});
setTemplateConfigInfo(result);
if (check) {
console.log('提交任务')
} else {
Message.error('请完善左侧表单再提交')
}
}
return ( return (
<div className={styles.swBox}> <div className={styles.swBox}>
<div className={styles.swHeader}> <div className={styles.swHeader}>
...@@ -124,12 +133,13 @@ const ProjectSubmitWork = () => { ...@@ -124,12 +133,13 @@ const ProjectSubmitWork = () => {
<div className={styles.swHeaderGoback}></div> <div className={styles.swHeaderGoback}></div>
</div> </div>
<div className={styles.swHeaderRight}> <div className={styles.swHeaderRight}>
<ButtonComponent text="提交任务"></ButtonComponent> <ButtonComponent text="提交任务" click={handleSubmitForm}></ButtonComponent>
</div> </div>
</div> </div>
<div className={styles.swContent}> <div className={styles.swContent}>
<div className={styles.swFormBox}> <div className={styles.swFormBox}>
<ConfigForm <ConfigForm
onRef={configFormRef}
templateConfigInfo={templateConfigInfo} templateConfigInfo={templateConfigInfo}
setParameter={setParameter} setParameter={setParameter}
/> />
......
...@@ -24,13 +24,13 @@ export const templateConfigJson = { ...@@ -24,13 +24,13 @@ export const templateConfigJson = {
name: "in", name: "in",
required: true, required: true,
// domType: "input", // domType: "input",
// domType: "select", domType: "select",
// domType: "multipleselect", // domType: "multipleselect",
// domType: "radio", // domType: "radio",
domType: "checkbox", // domType: "checkbox",
dataType: "stringParameter", dataType: "stringParameter",
// value: "", value: "",
value: [], // value: [],
description: "输入一段字符串", description: "输入一段字符串",
validators: [ validators: [
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment