From 55cfe79dabe0776347790da4ea134ac559132001 Mon Sep 17 00:00:00 2001 From: 1708-huayu <57060237+1708-huayu@users.noreply.github.com> Date: Fri, 24 Jan 2025 18:56:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=97=A5=E5=8E=86=E6=BB=91=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/DetailForm/index.js | 102 +++++++++++------- src/components/ParentTask/index.css | 3 + src/components/ParentTask/index.js | 80 +++++++++++++-- src/pages/DetailLogTask/index.js | 6 +- src/pages/ToDoCal/index.jsx | 154 +++++++++++++++++----------- 5 files changed, 234 insertions(+), 111 deletions(-) create mode 100644 src/components/ParentTask/index.css diff --git a/src/components/DetailForm/index.js b/src/components/DetailForm/index.js index 19f6f1d..2265a71 100644 --- a/src/components/DetailForm/index.js +++ b/src/components/DetailForm/index.js @@ -5,7 +5,7 @@ import { Button, Dialog, TextArea, - Space, Tag, Radio + Space, Tag, Radio, Checkbox } from 'antd-mobile' import ParentTask from "../ParentTask"; import "./index.css" @@ -13,25 +13,34 @@ import {addTask, getPTask, getTaskById, updateTask} from "../../utils"; import {useLocation, useNavigate, useOutletContext, useSearchParams} from "react-router-dom"; import dayjs from "dayjs"; import DataPickItemPopup from "../DataPickItemPopup"; +import {getDictionary} from "../../utils/dictUtil"; -const DetailForm= () => { +const DetailForm = () => { // 进入此页面的操作:添加,修改,详情(按钮为添加任务日志) const location = useLocation(); let [params] = useSearchParams(); // 设置标题栏 - const {setTitle,setRightDesc} = useOutletContext(); + const {setTitle, setRightDesc} = useOutletContext(); const [currentPath, setCurrentPath] = React.useState(""); const [updateFiledDisabled, setUpdateFiledDisabled] = React.useState(true); const [pName, setPName] = React.useState(); const [pidArray, setPidArray] = React.useState([]); + const [stateList, setStateList] = React.useState([]); + const [priorityList, setPriorityList] = React.useState([]); // 路由 const navigate = useNavigate(); // 获取form引用 const [form] = Form.useForm(); - const addEditPName=(name)=>{ + const addEditPName = (name) => { setPName(name) } useEffect(() => { + getDictionary("2").then(stateDictionary => { + setStateList(Array.from(stateDictionary.values())); + }) + getDictionary("1").then(priorityDictionary => { + setPriorityList(Array.from(priorityDictionary.values())); + }) window.scrollTo(0, 0); if (location.pathname.endsWith("addTask")) { setTitle("添加任务"); @@ -50,25 +59,27 @@ const DetailForm= () => { initData(params.get('id')); setUpdateFiledDisabled(true); setRightDesc(
- + }) + }}>编辑
) } else { // todo 异常处理 @@ -85,7 +96,7 @@ const DetailForm= () => { console.log({res, parentMessageVOList}); setPName(parentMessageVOList[parentMessageVOList.length - 1].name); setPidArray(parentMessageVOList.map(parent => parent.id)) - form.setFieldValue("pidArray",parentMessageVOList.map(parent => parent.id)) + form.setFieldValue("pidArray", parentMessageVOList.map(parent => parent.id)) }) } @@ -218,33 +229,52 @@ const DetailForm= () => { showCount /> - + - 未开始 - 进行中 - 已完成 - 已逾期 + {/*未开始*/} + {/*进行中*/} + {/*已完成*/} + {/*已逾期*/} + { + stateList.map(stateDict => + + {stateDict.itemName} + + ) + } - + - 紧急重要 - 不紧急重要 - 紧急不重要 - 不紧急不重要 + {/*紧急重要*/} + {/*不紧急重要*/} + {/*紧急不重要*/} + {/*不紧急不重要*/} + { + priorityList.map(stateDict => + + {stateDict.itemName} + + ) + } + labelName={"预计开始时间"}/> + labelName={"预计结束时间"}/> - + labelName={"实际开始时间"}/> + ) diff --git a/src/components/ParentTask/index.css b/src/components/ParentTask/index.css new file mode 100644 index 0000000..0a8413c --- /dev/null +++ b/src/components/ParentTask/index.css @@ -0,0 +1,3 @@ +.adm-cascader-header-title{ + flex: 0.5; +} \ No newline at end of file diff --git a/src/components/ParentTask/index.js b/src/components/ParentTask/index.js index 80073bd..9b2a4cc 100644 --- a/src/components/ParentTask/index.js +++ b/src/components/ParentTask/index.js @@ -1,18 +1,27 @@ -import {Cascader, Input, Toast} from "antd-mobile"; +import {Cascader, Input, SearchBar, Toast} from "antd-mobile"; import React, {useEffect, useMemo, useState} from "react"; import { Form, } from 'antd-mobile' import {getTaskByPid} from "../../utils"; - +import "./index.css" +import {CloseCircleFill} from "antd-mobile-icons"; const ParentTask = (props) => { const [valueToOptions, setValueToOptions] = useState([]) const {form, disabled, pName, pidArray, addEditPName} = props; const [parentValue, setParentValue] = useState(pidArray ?? []) const [visible, setVisible] = useState(false) + const [searchValue, setSearchValue] = useState(""); + const [currentLab, setCurrentLab] = useState(0); + const [selectValue, setSelectValue] = useState([]); + // 当前标签 + // let currentLab=0; + // let selectValue=[]; const options = useMemo(() => { + console.log("useMemo") + function generate(v) { const options = valueToOptions[v] if (options === null) { @@ -21,6 +30,27 @@ const ParentTask = (props) => { if (options === undefined) { return Cascader.optionSkeleton } + // 如果有搜索有值,需要过滤, + // 根据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 { + // 用户切换回之前的标签,暂不处理 + } + } return options.map(option => ({ ...option, children: generate(option.value), @@ -28,7 +58,7 @@ const ParentTask = (props) => { } return generate('0') ?? [] - }, [valueToOptions]) + }, [valueToOptions, searchValue]) async function fetchOptionsForValue(v, level) { if (v in valueToOptions) return @@ -72,13 +102,38 @@ const ParentTask = (props) => { return 0) ? ( + { + form.setFieldsValue({pidArray: []}) + setParentValue([]) + // 阻止冒泡 + e.stopPropagation() + // 阻止所有后续事件处理程序 + // e.nativeEvent.stopImmediatePropagation(); + }} + />) : true + + } onClick={() => { setVisible(true) }} - value={parentValue} - disabled={disabled} > { + console.log("搜索" + value) + setSearchValue(value); + } + }/>} options={options} visible={visible} defaultValue={pidArray} @@ -91,11 +146,13 @@ const ParentTask = (props) => { setParentValue(val[val.length - 1]) form.setFieldValue('pidArray', val) }} - // onSelect={(val, extend) => { - // console.log('onSelect', val, extend.items) - // }} + onTabsChange={index => { + console.log(index); + setCurrentLab(index) + }} onSelect={value => { - console.log("value", value) + console.log("value", value, currentLab) + setSelectValue(value) value.forEach((v, index) => { fetchOptionsForValue(v, index + 1) }) @@ -103,10 +160,11 @@ const ParentTask = (props) => { > {items => { if (items.every(item => item === null)) { - return pName ? ({pName}) : disabled ? + return (pName && form.getFieldValue('pidArray') && form.getFieldValue('pidArray').length > 0) ? ( + {pName}) : disabled ? (主线任务选填) : (主线任务选填) - } else { + } else if (items) { if (addEditPName) { addEditPName(items[items.length - 1].label) } diff --git a/src/pages/DetailLogTask/index.js b/src/pages/DetailLogTask/index.js index f366759..5d2870e 100644 --- a/src/pages/DetailLogTask/index.js +++ b/src/pages/DetailLogTask/index.js @@ -26,7 +26,7 @@ export function DetailLogTask() { const [currentTask, setCurrentTask] = useState({}); const [actions,setActions] = useState([ { text: '复制', key: 'copy' }, - { text: '有效', key: 'edit' }, + { text: '有效', key: 'need' }, { text: '创建任务', key: 'addTask'}, { text: '删除', @@ -48,7 +48,7 @@ export function DetailLogTask() { map.get(dayjs(taskLog.createdDate).format("YYYY-MM-DD"))?.push(taskLog); return map; }, new Map()); - }, [taskLogList]) + }, [taskLogList,currentShow]) const handleSend = () => { addTaskLog({ "description": sendValue, @@ -110,7 +110,7 @@ export function DetailLogTask() { {taskLogMapMemory.get(key).map(taskLog => { return
{ - actions[1]={ text: '失效', key: 'edit' } + actions[1]={ text: '失效', key: 'noneed' } // setActions([...actions]) setCurrentTask(taskLog) setActionSheetVisible(true) diff --git a/src/pages/ToDoCal/index.jsx b/src/pages/ToDoCal/index.jsx index f383f46..9a1e15b 100644 --- a/src/pages/ToDoCal/index.jsx +++ b/src/pages/ToDoCal/index.jsx @@ -1,4 +1,4 @@ -import {Calendar, Cascader, Tag} from "antd-mobile"; +import {Calendar, Cascader, SwipeAction, Tag} from "antd-mobile"; import dayjs from "dayjs"; import {TaskCount} from "../TaskCount"; import React, {Fragment, useEffect, useLayoutEffect, useMemo, useRef, useState} from "react"; @@ -12,6 +12,7 @@ import './index.css' const ToDoCal = (props) => { const today = new Date() const calRef = useRef(null); + const refSwip = useRef(null); const [currentDay, setCurrentDay] = React.useState(new Date()) const [currentMonth, setCurrentMonth] = React.useState(dayjs().set("date", 1).format('YYYY-MM-DD')); // Map key为当前月value为当前月的向 @@ -57,70 +58,101 @@ const ToDoCal = (props) => { return ( - { - // // 没有任务不显示 - // return listTaskMap?.get(currentMonth)?.filter(taskC => dayjs(taskC.todoDay).isSame(dayjs(date), 'date'))?.map(taskC => { - // // 如果有逾期的 红色 - // // Object.keys() 返回一个包含对象自身所有可枚举属性的数组 - // // Object.entries() 返回一个包含对象所有可枚举属性的键值对数组。 - // if (Object.keys(taskC.state).length > 0) { - // console.log("taskC.state", taskC.state) - // if (taskC.state[OVERDUE]) { - // return ; - // } - // // 如果有未完成的任务 warn - // if (taskC.state[NEW] || taskC.state[UNDER_WAY]) { - // return ; - // } - // // 任务全部完成 绿色 - // return ; - // } - // }) - // - // // if (dayjs(date).isSame(today, 'day')) return '今天' - // // if (date.getDay() === 0 || date.getDay() === 6) { - // // return '周末' - // // } - // }} - renderDate={date => { - return listTaskMap?.get(currentMonth)?.filter(taskC => dayjs(taskC.todoDay).isSame(dayjs(date), 'date'))?.map(taskC => { - // 如果有逾期的 红色 - // Object.keys() 返回一个包含对象自身所有可枚举属性的数组 - // Object.entries() 返回一个包含对象所有可枚举属性的键值对数组。 - if (Object.keys(taskC.state).length > 0) { - console.log("taskC.state", taskC.state) - if (taskC.state[OVERDUE]) { + { + console.log(sideType,sideType === 'left',sideType === 'right',currentMonth) + if (sideType === 'left') { + const newMonth = dayjs(currentMonth).subtract(1, 'months') + calRef.current.jumpTo({year: newMonth.year(), month: newMonth.month()+1}) + console.log(newMonth.year(),newMonth.month()+1) + } else if (sideType === 'right') { + const newMonth = dayjs(currentMonth).add(1, 'months') + calRef.current.jumpTo({year: newMonth.year(), month: newMonth.month()+1}) + console.log(newMonth.year(),newMonth.month()+1) + } + refSwip.current?.close() + }} + > + { + // // 没有任务不显示 + // return listTaskMap?.get(currentMonth)?.filter(taskC => dayjs(taskC.todoDay).isSame(dayjs(date), 'date'))?.map(taskC => { + // // 如果有逾期的 红色 + // // Object.keys() 返回一个包含对象自身所有可枚举属性的数组 + // // Object.entries() 返回一个包含对象所有可枚举属性的键值对数组。 + // if (Object.keys(taskC.state).length > 0) { + // console.log("taskC.state", taskC.state) + // if (taskC.state[OVERDUE]) { + // return ; + // } + // // 如果有未完成的任务 warn + // if (taskC.state[NEW] || taskC.state[UNDER_WAY]) { + // return ; + // } + // // 任务全部完成 绿色 + // return ; + // } + // }) + // + // // if (dayjs(date).isSame(today, 'day')) return '今天' + // // if (date.getDay() === 0 || date.getDay() === 6) { + // // return '周末' + // // } + // }} + renderDate={date => { + return listTaskMap?.get(currentMonth)?.filter(taskC => dayjs(taskC.todoDay).isSame(dayjs(date), 'date'))?.map(taskC => { + // 如果有逾期的 红色 + // Object.keys() 返回一个包含对象自身所有可枚举属性的数组 + // Object.entries() 返回一个包含对象所有可枚举属性的键值对数组。 + if (Object.keys(taskC.state).length > 0) { + console.log("taskC.state", taskC.state) + if (taskC.state[OVERDUE]) { + return
{dayjs(date).date()}
; + } + // 如果有未完成的任务 warn + if (taskC.state[NEW] || taskC.state[UNDER_WAY]) { + return
{dayjs(date).date()}
; + } + // 任务全部完成 绿色 return
{dayjs(date).date()}
; } - // 如果有未完成的任务 warn - if (taskC.state[NEW] || taskC.state[UNDER_WAY]) { - return
{dayjs(date).date()}
; - } - // 任务全部完成 绿色 - return
{dayjs(date).date()}
; - } - return {dayjs(date).date()}; - }) - }} - defaultValue={currentDay} - onChange={val => { - setCurrentDay(val) - }} - onPageChange={(year, month) => { - console.log(year, month) - setCurrentMonth(`${year}-${month}-01`) - }} + return {dayjs(date).date()}; + }) + }} + defaultValue={currentDay} + onChange={val => { + setCurrentDay(val) + }} + onPageChange={(year, month) => { + console.log(year, month) + setCurrentMonth(`${year}-${month}-01`) + }} - /> + /> +