2025-01-24 05:56:31 -05:00
|
|
|
|
import {Cascader, Input, SearchBar, Toast} from "antd-mobile";
|
2024-12-29 03:54:01 -05:00
|
|
|
|
import React, {useEffect, useMemo, useState} from "react";
|
2024-12-27 06:06:20 -05:00
|
|
|
|
import {
|
|
|
|
|
Form,
|
|
|
|
|
} from 'antd-mobile'
|
2024-12-29 03:54:01 -05:00
|
|
|
|
import {getTaskByPid} from "../../utils";
|
2025-01-24 05:56:31 -05:00
|
|
|
|
import "./index.css"
|
|
|
|
|
import {CloseCircleFill} from "antd-mobile-icons";
|
2024-12-27 06:06:20 -05:00
|
|
|
|
|
2025-01-23 06:32:24 -05:00
|
|
|
|
const ParentTask = (props) => {
|
2024-12-29 03:54:01 -05:00
|
|
|
|
const [valueToOptions, setValueToOptions] = useState([])
|
2025-01-23 06:32:24 -05:00
|
|
|
|
const {form, disabled, pName, pidArray, addEditPName} = props;
|
|
|
|
|
const [parentValue, setParentValue] = useState(pidArray ?? [])
|
2024-12-27 06:06:20 -05:00
|
|
|
|
const [visible, setVisible] = useState(false)
|
2025-01-24 05:56:31 -05:00
|
|
|
|
const [searchValue, setSearchValue] = useState("");
|
|
|
|
|
const [currentLab, setCurrentLab] = useState(0);
|
|
|
|
|
const [selectValue, setSelectValue] = useState([]);
|
|
|
|
|
// 当前标签
|
|
|
|
|
// let currentLab=0;
|
|
|
|
|
// let selectValue=[];
|
2025-01-11 04:53:51 -05:00
|
|
|
|
|
2024-12-29 03:54:01 -05:00
|
|
|
|
const options = useMemo(() => {
|
2025-01-24 05:56:31 -05:00
|
|
|
|
console.log("useMemo")
|
|
|
|
|
|
2024-12-29 03:54:01 -05:00
|
|
|
|
function generate(v) {
|
|
|
|
|
const options = valueToOptions[v]
|
|
|
|
|
if (options === null) {
|
|
|
|
|
return undefined
|
|
|
|
|
}
|
|
|
|
|
if (options === undefined) {
|
|
|
|
|
return Cascader.optionSkeleton
|
|
|
|
|
}
|
2025-01-24 05:56:31 -05:00
|
|
|
|
// 如果有搜索有值,需要过滤,
|
|
|
|
|
// 根据currentLab查看需要过滤第几层,当前层可能没有值就会停留在上一层
|
|
|
|
|
if (searchValue && searchValue.length > 0) {
|
|
|
|
|
if (selectValue.length <= currentLab + 1) {
|
|
|
|
|
// 可能展示最新的,或没有停留在当前页面,正常是没有选择的时候搜索
|
|
|
|
|
console.log({searchValue}, {currentLab}, {selectValue})
|
|
|
|
|
if (currentLab === 0 && v === '0') {
|
|
|
|
|
return options.filter(option => option.label.includes(searchValue)).map(option => ({
|
|
|
|
|
...option,
|
|
|
|
|
children: generate(option.value),
|
|
|
|
|
}))
|
|
|
|
|
} else if (v === selectValue[currentLab - 1]) {
|
|
|
|
|
return options.filter(option => option.label.includes(searchValue)).map(option => ({
|
|
|
|
|
...option,
|
|
|
|
|
children: generate(option.value),
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 用户切换回之前的标签,暂不处理
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-29 03:54:01 -05:00
|
|
|
|
return options.map(option => ({
|
|
|
|
|
...option,
|
|
|
|
|
children: generate(option.value),
|
|
|
|
|
}))
|
|
|
|
|
}
|
2025-01-23 06:32:24 -05:00
|
|
|
|
|
2024-12-29 03:54:01 -05:00
|
|
|
|
return generate('0') ?? []
|
2025-01-24 05:56:31 -05:00
|
|
|
|
}, [valueToOptions, searchValue])
|
2024-12-29 03:54:01 -05:00
|
|
|
|
|
|
|
|
|
async function fetchOptionsForValue(v, level) {
|
|
|
|
|
if (v in valueToOptions) return
|
|
|
|
|
// if (level >= 3) {
|
|
|
|
|
// setValueToOptions(prev => ({
|
|
|
|
|
// ...prev,
|
|
|
|
|
// [v]: null,
|
|
|
|
|
// }))
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
const data = await getTaskByPid(v)
|
2025-01-23 06:32:24 -05:00
|
|
|
|
console.log("await getTaskByPid(v)", data.content)
|
2024-12-29 03:54:01 -05:00
|
|
|
|
const options =
|
2024-12-31 08:53:20 -05:00
|
|
|
|
data.content.length === 0
|
2024-12-29 03:54:01 -05:00
|
|
|
|
? null
|
2024-12-31 08:53:20 -05:00
|
|
|
|
: data.content.map(task => ({
|
2024-12-29 03:54:01 -05:00
|
|
|
|
value: task.id,
|
|
|
|
|
label: task.name,
|
|
|
|
|
}))
|
2025-01-23 06:32:24 -05:00
|
|
|
|
console.log("await getTaskByPid(v) options", options)
|
2024-12-29 03:54:01 -05:00
|
|
|
|
setValueToOptions(prev => ({
|
|
|
|
|
...prev,
|
|
|
|
|
[v]: options,
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2025-01-23 06:32:24 -05:00
|
|
|
|
initDate()
|
|
|
|
|
}, [props])
|
|
|
|
|
|
|
|
|
|
async function initDate() {
|
|
|
|
|
await fetchOptionsForValue('0', 0)
|
|
|
|
|
if (pidArray && pidArray.length > 0) {
|
|
|
|
|
setParentValue(pidArray)
|
|
|
|
|
for (const taskId of pidArray) {
|
|
|
|
|
await fetchOptionsForValue(taskId, 0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-29 03:54:01 -05:00
|
|
|
|
|
2024-12-27 06:06:20 -05:00
|
|
|
|
return <Form.Item
|
2024-12-29 03:54:01 -05:00
|
|
|
|
name='pidArray'
|
2024-12-27 06:06:20 -05:00
|
|
|
|
label='主线任务'
|
2025-01-24 05:56:31 -05:00
|
|
|
|
value={parentValue}
|
|
|
|
|
disabled={disabled}
|
|
|
|
|
arrow={
|
|
|
|
|
(form.getFieldValue('pidArray') && form.getFieldValue('pidArray').length > 0) ? (
|
|
|
|
|
<CloseCircleFill
|
|
|
|
|
style={{
|
|
|
|
|
color: 'var(--adm-color-light)',
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
}}
|
|
|
|
|
onClick={e => {
|
|
|
|
|
form.setFieldsValue({pidArray: []})
|
|
|
|
|
setParentValue([])
|
|
|
|
|
// 阻止冒泡
|
|
|
|
|
e.stopPropagation()
|
|
|
|
|
// 阻止所有后续事件处理程序
|
|
|
|
|
// e.nativeEvent.stopImmediatePropagation();
|
|
|
|
|
}}
|
|
|
|
|
/>) : true
|
|
|
|
|
|
|
|
|
|
}
|
2024-12-27 06:06:20 -05:00
|
|
|
|
onClick={() => {
|
|
|
|
|
setVisible(true)
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Cascader
|
2025-01-24 05:56:31 -05:00
|
|
|
|
title={<SearchBar placeholder='搜索当前层相关标题' onChange={
|
|
|
|
|
// 获取当前选卡,过滤当前选项
|
|
|
|
|
(value) => {
|
|
|
|
|
console.log("搜索" + value)
|
|
|
|
|
setSearchValue(value);
|
|
|
|
|
}
|
|
|
|
|
}/>}
|
2024-12-27 06:06:20 -05:00
|
|
|
|
options={options}
|
|
|
|
|
visible={visible}
|
2025-01-23 06:32:24 -05:00
|
|
|
|
defaultValue={pidArray}
|
2024-12-27 06:06:20 -05:00
|
|
|
|
onClose={() => {
|
|
|
|
|
setVisible(false)
|
|
|
|
|
}}
|
|
|
|
|
value={parentValue}
|
2025-01-23 06:32:24 -05:00
|
|
|
|
onConfirm={(val) => {
|
2024-12-29 03:54:01 -05:00
|
|
|
|
console.log(val)
|
2025-01-23 06:32:24 -05:00
|
|
|
|
setParentValue(val[val.length - 1])
|
|
|
|
|
form.setFieldValue('pidArray', val)
|
2024-12-29 03:54:01 -05:00
|
|
|
|
}}
|
2025-01-24 05:56:31 -05:00
|
|
|
|
onTabsChange={index => {
|
|
|
|
|
console.log(index);
|
|
|
|
|
setCurrentLab(index)
|
|
|
|
|
}}
|
2024-12-29 03:54:01 -05:00
|
|
|
|
onSelect={value => {
|
2025-01-24 05:56:31 -05:00
|
|
|
|
console.log("value", value, currentLab)
|
|
|
|
|
setSelectValue(value)
|
2024-12-29 03:54:01 -05:00
|
|
|
|
value.forEach((v, index) => {
|
|
|
|
|
fetchOptionsForValue(v, index + 1)
|
|
|
|
|
})
|
2024-12-27 06:06:20 -05:00
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{items => {
|
|
|
|
|
if (items.every(item => item === null)) {
|
2025-01-24 05:56:31 -05:00
|
|
|
|
return (pName && form.getFieldValue('pidArray') && form.getFieldValue('pidArray').length > 0) ? (
|
|
|
|
|
<span>{pName}</span>) : disabled ?
|
2025-01-23 06:32:24 -05:00
|
|
|
|
(<span>主线任务选填</span>) :
|
2025-01-11 04:53:51 -05:00
|
|
|
|
(<span style={{color: "#cccccc"}}>主线任务选填</span>)
|
2025-01-24 05:56:31 -05:00
|
|
|
|
} else if (items) {
|
2025-01-23 06:32:24 -05:00
|
|
|
|
if (addEditPName) {
|
|
|
|
|
addEditPName(items[items.length - 1].label)
|
|
|
|
|
}
|
|
|
|
|
return items[items.length - 1].label
|
2024-12-27 06:06:20 -05:00
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
</Cascader>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
// const [parentValue, setParentValue] = useState("")
|
|
|
|
|
// return <Form.Item
|
|
|
|
|
// name='name'
|
|
|
|
|
// label='主线任务'
|
|
|
|
|
// onClick={async () => {
|
|
|
|
|
// const value = await Cascader.prompt({
|
|
|
|
|
// options: options,
|
|
|
|
|
// placeholder: '请选择',
|
|
|
|
|
// })
|
|
|
|
|
// Toast.show(
|
|
|
|
|
// value ? `你选择了 ${value.join(' - ')}` : '你没有进行选择'
|
|
|
|
|
// )
|
|
|
|
|
// if (value){
|
|
|
|
|
// setParentValue(value.join(' - '))
|
|
|
|
|
// }
|
|
|
|
|
// }}
|
|
|
|
|
// >
|
|
|
|
|
// <Input
|
|
|
|
|
// defaultValue={parentValue}
|
|
|
|
|
// value={parentValue}
|
|
|
|
|
// readOnly={true}
|
|
|
|
|
// placeholder='主线任务名称选填'>
|
|
|
|
|
// {parentValue}
|
|
|
|
|
// </Input>
|
|
|
|
|
// </Form.Item>
|
|
|
|
|
}
|
|
|
|
|
export default ParentTask;
|