feat:日历渲染
This commit is contained in:
parent
779a28a364
commit
c2eb04b4b0
|
@ -1,5 +1,5 @@
|
||||||
import React, {useState} from "react";
|
import React, {useState} from "react";
|
||||||
import {Form, Calendar, CapsuleTabs, JumboTabs, Picker, PickerView, Popup} from "antd-mobile";
|
import {Form, Calendar, CapsuleTabs, JumboTabs, Picker, PickerView, Popup, CalendarPickerView} from "antd-mobile";
|
||||||
import {basicColumns} from "./constant";
|
import {basicColumns} from "./constant";
|
||||||
import "./index.css"
|
import "./index.css"
|
||||||
import {CloseCircleFill} from "antd-mobile-icons";
|
import {CloseCircleFill} from "antd-mobile-icons";
|
||||||
|
@ -15,7 +15,7 @@ export default function DataPickItemPopup(props) {
|
||||||
return (
|
return (
|
||||||
<Form.Item noStyle
|
<Form.Item noStyle
|
||||||
shouldUpdate={(prevValues, curValues) => {
|
shouldUpdate={(prevValues, curValues) => {
|
||||||
return prevValues.fieldName !== curValues.fieldName
|
return prevValues[fieldName] !== curValues[fieldName]
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({getFieldValue, setFieldsValue}) => (
|
{({getFieldValue, setFieldsValue}) => (
|
||||||
|
@ -32,9 +32,9 @@ export default function DataPickItemPopup(props) {
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
}}
|
}}
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
|
e.stopPropagation()
|
||||||
// 计算属性名:允许你在对象字面量中使用表达式来动态确定属性名。
|
// 计算属性名:允许你在对象字面量中使用表达式来动态确定属性名。
|
||||||
setFieldsValue({[fieldName]: null})
|
setFieldsValue({[fieldName]: null})
|
||||||
e.stopPropagation()
|
|
||||||
}}/>) : true
|
}}/>) : true
|
||||||
}
|
}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -84,7 +84,7 @@ export default function DataPickItemPopup(props) {
|
||||||
>
|
>
|
||||||
<CapsuleTabs.Tab title={dateShowValue}
|
<CapsuleTabs.Tab title={dateShowValue}
|
||||||
key='date' className="tab-content">
|
key='date' className="tab-content">
|
||||||
<Calendar
|
<CalendarPickerView
|
||||||
selectionMode='single'
|
selectionMode='single'
|
||||||
defaultValue={dataPick}
|
defaultValue={dataPick}
|
||||||
onChange={val => {
|
onChange={val => {
|
||||||
|
|
|
@ -8,14 +8,13 @@ import {
|
||||||
Space, Tag, Radio
|
Space, Tag, Radio
|
||||||
} from 'antd-mobile'
|
} from 'antd-mobile'
|
||||||
import ParentTask from "../ParentTask";
|
import ParentTask from "../ParentTask";
|
||||||
import DatePickerItem from "../DataPickerItem"
|
|
||||||
import "./index.css"
|
import "./index.css"
|
||||||
import {addTask, getPTask, getTaskById, updateTask} from "../../utils";
|
import {addTask, getPTask, getTaskById, updateTask} from "../../utils";
|
||||||
import {useLocation, useNavigate, useOutletContext, useSearchParams} from "react-router-dom";
|
import {useLocation, useNavigate, useOutletContext, useSearchParams} from "react-router-dom";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import DataPickItemPopup from "../DataPickItemPopup";
|
import DataPickItemPopup from "../DataPickItemPopup";
|
||||||
|
|
||||||
export default () => {
|
const DetailForm= () => {
|
||||||
// 进入此页面的操作:添加,修改,详情(按钮为添加任务日志)
|
// 进入此页面的操作:添加,修改,详情(按钮为添加任务日志)
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
let [params] = useSearchParams();
|
let [params] = useSearchParams();
|
||||||
|
@ -29,6 +28,9 @@ export default () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
// 获取form引用
|
// 获取form引用
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
const addEditPName=(name)=>{
|
||||||
|
setPName(name)
|
||||||
|
}
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.scrollTo(0, 0);
|
window.scrollTo(0, 0);
|
||||||
if (location.pathname.endsWith("addTask")) {
|
if (location.pathname.endsWith("addTask")) {
|
||||||
|
@ -83,6 +85,7 @@ export default () => {
|
||||||
console.log({res, parentMessageVOList});
|
console.log({res, parentMessageVOList});
|
||||||
setPName(parentMessageVOList[parentMessageVOList.length - 1].name);
|
setPName(parentMessageVOList[parentMessageVOList.length - 1].name);
|
||||||
setPidArray(parentMessageVOList.map(parent => parent.id))
|
setPidArray(parentMessageVOList.map(parent => parent.id))
|
||||||
|
form.setFieldValue("pidArray",parentMessageVOList.map(parent => parent.id))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,6 +139,8 @@ export default () => {
|
||||||
// 清空值
|
// 清空值
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
form.setFieldValue("pidArray", values.pidArray);
|
form.setFieldValue("pidArray", values.pidArray);
|
||||||
|
setPidArray(values.pidArray)
|
||||||
|
window.scrollTo(0, 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -193,7 +198,10 @@ export default () => {
|
||||||
name='code'
|
name='code'
|
||||||
hidden={true}
|
hidden={true}
|
||||||
></Form.Item>
|
></Form.Item>
|
||||||
<ParentTask pName={pName} pidArray={pidArray} disabled={updateFiledDisabled} form={form}/>
|
<ParentTask pName={pName} pidArray={pidArray}
|
||||||
|
disabled={updateFiledDisabled} form={form}
|
||||||
|
addEditPName={setPName}
|
||||||
|
/>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name='name'
|
name='name'
|
||||||
label='任务名称'
|
label='任务名称'
|
||||||
|
@ -241,3 +249,4 @@ export default () => {
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
export default DetailForm;
|
|
@ -9,7 +9,7 @@ import {MyRootContext, UPDATE_SEARCH} from "../MyRootContext";
|
||||||
import {getTaskById} from "../../utils";
|
import {getTaskById} from "../../utils";
|
||||||
|
|
||||||
const DetailSearchBar = (props) => {
|
const DetailSearchBar = (props) => {
|
||||||
const { state, dispatch } = useContext(MyRootContext);
|
const {state, dispatch} = useContext(MyRootContext);
|
||||||
const search = state.search
|
const search = state.search
|
||||||
|
|
||||||
const [tags, setTags] = useState([]);
|
const [tags, setTags] = useState([]);
|
||||||
|
@ -25,11 +25,12 @@ const DetailSearchBar = (props) => {
|
||||||
const priorityDictionary = await getDictionary("1");
|
const priorityDictionary = await getDictionary("1");
|
||||||
// 处理主要条件
|
// 处理主要条件
|
||||||
const tagList = [];
|
const tagList = [];
|
||||||
console.log("search.data.orSearchModel",search.data.orSearchModel)
|
console.log("search.data.orSearchModel", search.data.orSearchModel)
|
||||||
await search.data.orSearchModel?.andList?.forEach((searchObj) => {
|
search.data.orSearchModel?.andList?.forEach((searchObj) => {
|
||||||
if (searchObj.name === "pid") {
|
if (searchObj.name === "pid") {
|
||||||
getTaskById(searchObj.value).then(result=>{
|
getTaskById(searchObj.value).then(result=>{
|
||||||
tagList.push(<Tag key={result[0].name}>{result[0].name}</Tag>)
|
setTags([<Tag key={result.content[0].name}>{result.content[0].name}</Tag>
|
||||||
|
,...tagList])
|
||||||
})
|
})
|
||||||
} else if (searchObj.name === "state") {
|
} else if (searchObj.name === "state") {
|
||||||
const items = searchObj.value.split(',');
|
const items = searchObj.value.split(',');
|
||||||
|
@ -68,8 +69,9 @@ const DetailSearchBar = (props) => {
|
||||||
if (searchObj.name === "state" && searchObj.value === "10") {
|
if (searchObj.name === "state" && searchObj.value === "10") {
|
||||||
const dict = stateDictionary.get(searchObj.value);
|
const dict = stateDictionary.get(searchObj.value);
|
||||||
if (dict && tagList.length > 0) {
|
if (dict && tagList.length > 0) {
|
||||||
tagList.push(<AddOutline key = "add-icon"/>)
|
tagList.push(<AddOutline key="add-icon"/>)
|
||||||
} if (dict) {
|
}
|
||||||
|
if (dict) {
|
||||||
tagList.push(<Tag key={dict.id} color={dict.jsonValue?.color}>
|
tagList.push(<Tag key={dict.id} color={dict.jsonValue?.color}>
|
||||||
{dict.itemName}
|
{dict.itemName}
|
||||||
</Tag>);
|
</Tag>);
|
||||||
|
@ -92,14 +94,16 @@ const DetailSearchBar = (props) => {
|
||||||
{tags}
|
{tags}
|
||||||
</div>
|
</div>
|
||||||
{showCloseOutline && <div className="CloseOutline-CloseOutline" onClick={() => {
|
{showCloseOutline && <div className="CloseOutline-CloseOutline" onClick={() => {
|
||||||
dispatch({type:UPDATE_SEARCH,search:{
|
dispatch({
|
||||||
|
type: UPDATE_SEARCH, search: {
|
||||||
"pageSize": 12,
|
"pageSize": 12,
|
||||||
"pageNumber": 1,
|
"pageNumber": 1,
|
||||||
"data": {
|
"data": {
|
||||||
"andList": [],
|
"andList": [],
|
||||||
"orList": []
|
"orList": []
|
||||||
}
|
}
|
||||||
}});
|
}
|
||||||
|
});
|
||||||
setTags([]);
|
setTags([]);
|
||||||
}}>
|
}}>
|
||||||
<CloseOutline key="close-icon" style={{float: "right"}}/>
|
<CloseOutline key="close-icon" style={{float: "right"}}/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {Cascader,Input, Toast} from "antd-mobile";
|
import {Cascader, Input, Toast} from "antd-mobile";
|
||||||
import React, {useEffect, useMemo, useState} from "react";
|
import React, {useEffect, useMemo, useState} from "react";
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
|
@ -6,10 +6,10 @@ import {
|
||||||
import {getTaskByPid} from "../../utils";
|
import {getTaskByPid} from "../../utils";
|
||||||
|
|
||||||
|
|
||||||
const ParentTask = (props)=>{
|
const ParentTask = (props) => {
|
||||||
const [valueToOptions, setValueToOptions] = useState([])
|
const [valueToOptions, setValueToOptions] = useState([])
|
||||||
const {form,disabled,pName,pidArray} = props;
|
const {form, disabled, pName, pidArray, addEditPName} = props;
|
||||||
const [parentValue, setParentValue] = useState(pidArray??[])
|
const [parentValue, setParentValue] = useState(pidArray ?? [])
|
||||||
const [visible, setVisible] = useState(false)
|
const [visible, setVisible] = useState(false)
|
||||||
|
|
||||||
const options = useMemo(() => {
|
const options = useMemo(() => {
|
||||||
|
@ -26,6 +26,7 @@ const ParentTask = (props)=>{
|
||||||
children: generate(option.value),
|
children: generate(option.value),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
return generate('0') ?? []
|
return generate('0') ?? []
|
||||||
}, [valueToOptions])
|
}, [valueToOptions])
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ const ParentTask = (props)=>{
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
const data = await getTaskByPid(v)
|
const data = await getTaskByPid(v)
|
||||||
console.log("await getTaskByPid(v)",data.content)
|
console.log("await getTaskByPid(v)", data.content)
|
||||||
const options =
|
const options =
|
||||||
data.content.length === 0
|
data.content.length === 0
|
||||||
? null
|
? null
|
||||||
|
@ -47,7 +48,7 @@ const ParentTask = (props)=>{
|
||||||
value: task.id,
|
value: task.id,
|
||||||
label: task.name,
|
label: task.name,
|
||||||
}))
|
}))
|
||||||
console.log("await getTaskByPid(v) options",options)
|
console.log("await getTaskByPid(v) options", options)
|
||||||
setValueToOptions(prev => ({
|
setValueToOptions(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
[v]: options,
|
[v]: options,
|
||||||
|
@ -55,8 +56,18 @@ const ParentTask = (props)=>{
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchOptionsForValue('0', 0)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return <Form.Item
|
return <Form.Item
|
||||||
name='pidArray'
|
name='pidArray'
|
||||||
|
@ -70,20 +81,21 @@ const ParentTask = (props)=>{
|
||||||
<Cascader
|
<Cascader
|
||||||
options={options}
|
options={options}
|
||||||
visible={visible}
|
visible={visible}
|
||||||
|
defaultValue={pidArray}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setVisible(false)
|
setVisible(false)
|
||||||
}}
|
}}
|
||||||
value={parentValue}
|
value={parentValue}
|
||||||
onConfirm={(val)=>{
|
onConfirm={(val) => {
|
||||||
console.log(val)
|
console.log(val)
|
||||||
setParentValue(val[val.length-1])
|
setParentValue(val[val.length - 1])
|
||||||
form.setFieldValue('pidArray',val)
|
form.setFieldValue('pidArray', val)
|
||||||
}}
|
}}
|
||||||
// onSelect={(val, extend) => {
|
// onSelect={(val, extend) => {
|
||||||
// console.log('onSelect', val, extend.items)
|
// console.log('onSelect', val, extend.items)
|
||||||
// }}
|
// }}
|
||||||
onSelect={value => {
|
onSelect={value => {
|
||||||
console.log("value",value)
|
console.log("value", value)
|
||||||
value.forEach((v, index) => {
|
value.forEach((v, index) => {
|
||||||
fetchOptionsForValue(v, index + 1)
|
fetchOptionsForValue(v, index + 1)
|
||||||
})
|
})
|
||||||
|
@ -91,11 +103,14 @@ const ParentTask = (props)=>{
|
||||||
>
|
>
|
||||||
{items => {
|
{items => {
|
||||||
if (items.every(item => item === null)) {
|
if (items.every(item => item === null)) {
|
||||||
return pName?(<span>{pName}</span>): disabled ?
|
return pName ? (<span>{pName}</span>) : disabled ?
|
||||||
(<span>主线任务选填</span>):
|
(<span>主线任务选填</span>) :
|
||||||
(<span style={{color: "#cccccc"}}>主线任务选填</span>)
|
(<span style={{color: "#cccccc"}}>主线任务选填</span>)
|
||||||
} else {
|
} else {
|
||||||
return items[items.length-1].label
|
if (addEditPName) {
|
||||||
|
addEditPName(items[items.length - 1].label)
|
||||||
|
}
|
||||||
|
return items[items.length - 1].label
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
</Cascader>
|
</Cascader>
|
||||||
|
|
|
@ -19,7 +19,7 @@ export function DetailLogTask() {
|
||||||
const [currentShow, setCurrentShow] = useState('need');
|
const [currentShow, setCurrentShow] = useState('need');
|
||||||
const textAreaRef = useRef(null);
|
const textAreaRef = useRef(null);
|
||||||
const [taskLogList, setTaskLogList] = useState([]);
|
const [taskLogList, setTaskLogList] = useState([]);
|
||||||
const [sendValue, setSendValue] = useState([]);
|
const [sendValue, setSendValue] = useState('');
|
||||||
|
|
||||||
// 点击操作面板
|
// 点击操作面板
|
||||||
const [actionSheetVisible, setActionSheetVisible] = useState(false)
|
const [actionSheetVisible, setActionSheetVisible] = useState(false)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {Button, Checkbox, DatePicker, Form, Input, Space, Switch, Tag} from "antd-mobile";
|
import {Button, CalendarPicker, Checkbox, DatePicker, Form, Input, Space, Switch, Tag} from "antd-mobile";
|
||||||
import ParentTask from "../../components/ParentTask";
|
import ParentTask from "../../components/ParentTask";
|
||||||
import React, {useContext, useEffect} from "react";
|
import React, {useContext, useEffect} from "react";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
@ -7,6 +7,7 @@ import {useLocation, useNavigate, useOutletContext} from "react-router-dom";
|
||||||
import {getDictionary} from "../../utils/dictUtil";
|
import {getDictionary} from "../../utils/dictUtil";
|
||||||
import {MyRootContext, UPDATE_SEARCH} from "../../components/MyRootContext";
|
import {MyRootContext, UPDATE_SEARCH} from "../../components/MyRootContext";
|
||||||
import {dayStartUtcFormat, nextDayStartUtcFormat} from "../../utils/timeFormatUtil";
|
import {dayStartUtcFormat, nextDayStartUtcFormat} from "../../utils/timeFormatUtil";
|
||||||
|
import {getPTask} from "../../utils";
|
||||||
|
|
||||||
const DetailSearchContext = () => {
|
const DetailSearchContext = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
@ -16,6 +17,8 @@ const DetailSearchContext = () => {
|
||||||
const search = state.search
|
const search = state.search
|
||||||
const [stateList, setStateList] = React.useState([]);
|
const [stateList, setStateList] = React.useState([]);
|
||||||
const [priorityList, setPriorityList] = React.useState([]);
|
const [priorityList, setPriorityList] = React.useState([]);
|
||||||
|
const [pName, setPName] = React.useState();
|
||||||
|
const [pidArray, setPidArray] = React.useState([]);
|
||||||
// 使用Outlet,传值修改标题
|
// 使用Outlet,传值修改标题
|
||||||
const {setTitle} = useOutletContext();
|
const {setTitle} = useOutletContext();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -24,6 +27,17 @@ const DetailSearchContext = () => {
|
||||||
initDate()
|
initDate()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
function editParentTask(id) {
|
||||||
|
// 获取父任务信息
|
||||||
|
getPTask(id).then(res => {
|
||||||
|
let parentMessageVOList = res[0].parentMessageVOList;
|
||||||
|
console.log({res, parentMessageVOList});
|
||||||
|
setPName(parentMessageVOList[parentMessageVOList.length - 1].name);
|
||||||
|
setPidArray(parentMessageVOList.map(parent => parent.id))
|
||||||
|
form.setFieldValue("pidArray",parentMessageVOList.map(parent => parent.id))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async function initDate() {
|
async function initDate() {
|
||||||
let stateDictionary = await getDictionary("2");
|
let stateDictionary = await getDictionary("2");
|
||||||
let priorityDictionary = await getDictionary("1");
|
let priorityDictionary = await getDictionary("1");
|
||||||
|
@ -36,8 +50,7 @@ const DetailSearchContext = () => {
|
||||||
let searchMap = new Map(
|
let searchMap = new Map(
|
||||||
search.data.orSearchModel.andList.map(searchObj => [searchObj.name, searchObj]));
|
search.data.orSearchModel.andList.map(searchObj => [searchObj.name, searchObj]));
|
||||||
if (searchMap.has("pid")) {
|
if (searchMap.has("pid")) {
|
||||||
|
editParentTask(searchMap.get("pid").value)
|
||||||
// form.setFieldValue(task.name);
|
|
||||||
}
|
}
|
||||||
if (searchMap.has("state")) {
|
if (searchMap.has("state")) {
|
||||||
form.setFieldValue("state", searchMap.get("state").value.split(','))
|
form.setFieldValue("state", searchMap.get("state").value.split(','))
|
||||||
|
@ -76,7 +89,7 @@ const DetailSearchContext = () => {
|
||||||
|
|
||||||
const {pidArray, name, priority, state, todoDay, allOverdueTasks} = values;
|
const {pidArray, name, priority, state, todoDay, allOverdueTasks} = values;
|
||||||
if (pidArray && pidArray.length !== 0) {
|
if (pidArray && pidArray.length !== 0) {
|
||||||
searchCondition.push({"name": "name", "value": pidArray[pidArray.length - 1], "operateType": "="})
|
searchCondition.push({"name": "pid", "value": pidArray[pidArray.length - 1], "operateType": "="})
|
||||||
}
|
}
|
||||||
if (name && name !== "") {
|
if (name && name !== "") {
|
||||||
searchCondition.push({"name": "name", "value": name, "operateType": "%"})
|
searchCondition.push({"name": "name", "value": name, "operateType": "%"})
|
||||||
|
@ -148,7 +161,7 @@ const DetailSearchContext = () => {
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ParentTask form={form}/>
|
<ParentTask pName={pName} pidArray={pidArray} form={form}/>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name='name'
|
name='name'
|
||||||
label='任务信息'
|
label='任务信息'
|
||||||
|
@ -216,16 +229,18 @@ const DetailSearchContext = () => {
|
||||||
setVisible(true)
|
setVisible(true)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DatePicker
|
<CalendarPicker
|
||||||
visible={visible}
|
visible={visible}
|
||||||
|
selectionMode='single'
|
||||||
|
defaultDate={getFieldValue('todoDay')}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setVisible(false)
|
setVisible(false)
|
||||||
}}
|
}}
|
||||||
>
|
onConfirm={(val)=>setFieldsValue({todoDay:val})}
|
||||||
{value =>
|
/>
|
||||||
value ? dayjs(value).format('YYYY-MM-DD') : '请选择日期'
|
{
|
||||||
|
getFieldValue('todoDay') ? dayjs(getFieldValue('todoDay')).format('YYYY-MM-DD') : '请选择日期'
|
||||||
}
|
}
|
||||||
</DatePicker>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {MyRootContext, UPDATE_SEARCH} from "../../components/MyRootContext";
|
||||||
|
|
||||||
|
|
||||||
const TaskCount = (props) => {
|
const TaskCount = (props) => {
|
||||||
const {currentDay, taskCount, today, backToToday} = props;
|
const {currentDay, taskCount, today, backToToday, currentMonth} = props;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [stateMap, setStateMap] = React.useState(new Map);
|
const [stateMap, setStateMap] = React.useState(new Map);
|
||||||
const [priorityMap, setPriorityMap] = React.useState(new Map);
|
const [priorityMap, setPriorityMap] = React.useState(new Map);
|
||||||
|
@ -73,12 +73,10 @@ const TaskCount = (props) => {
|
||||||
navigate("/home/listTask")
|
navigate("/home/listTask")
|
||||||
}
|
}
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("useEffect");
|
|
||||||
getDictionary("2").then(state => {
|
getDictionary("2").then(state => {
|
||||||
setStateMap(state)
|
setStateMap(state)
|
||||||
})
|
})
|
||||||
getDictionary("1").then(priority => {
|
getDictionary("1").then(priority => {
|
||||||
console.log(priority)
|
|
||||||
setPriorityMap(priority)
|
setPriorityMap(priority)
|
||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
@ -87,10 +85,10 @@ const TaskCount = (props) => {
|
||||||
<div style={{margin: "20px"}}>
|
<div style={{margin: "20px"}}>
|
||||||
<h2>TODO日{currentDay && dayjs(currentDay).format(DATE_FORMAT)}代办:
|
<h2>TODO日{currentDay && dayjs(currentDay).format(DATE_FORMAT)}代办:
|
||||||
{currentDay && <a onClick={todoDayDetail}>详情</a>}
|
{currentDay && <a onClick={todoDayDetail}>详情</a>}
|
||||||
{!dayjs(currentDay).isSame(today, 'date') &&
|
{!dayjs(currentMonth).isSame(today, 'months') &&
|
||||||
<Fragment><Divider direction='vertical'/><a onClick={() => backToToday()}>回到今天</a></Fragment>}
|
<Fragment><Divider direction='vertical'/><a onClick={() => backToToday()}>回到当月</a></Fragment>}
|
||||||
</h2>
|
</h2>
|
||||||
{taskCount.filter(taskC => dayjs(taskC.todoDay).isSame(dayjs(currentDay), 'date'))?.map(taskC => {
|
{taskCount?.filter(taskC => dayjs(taskC.todoDay).isSame(dayjs(currentDay), 'date'))?.map(taskC => {
|
||||||
return <Fragment>
|
return <Fragment>
|
||||||
<h3>任务状态</h3>
|
<h3>任务状态</h3>
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
.cal-day-circle {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 20px;
|
||||||
|
border-style: solid;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-content: normal
|
||||||
|
}
|
|
@ -1,82 +1,129 @@
|
||||||
import {Calendar, Tag} from "antd-mobile";
|
import {Calendar, Cascader, Tag} from "antd-mobile";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import {TaskCount} from "../TaskCount";
|
import {TaskCount} from "../TaskCount";
|
||||||
import React, {Fragment, useEffect, useLayoutEffect, useRef} from "react";
|
import React, {Fragment, useEffect, useLayoutEffect, useMemo, useRef, useState} from "react";
|
||||||
|
import {getTaskByPid, getTaskCount} from "../../utils";
|
||||||
import {
|
|
||||||
dateStartUtcFormat,
|
|
||||||
nextDateStartUtcFormat,
|
|
||||||
} from "../../utils/timeFormatUtil";
|
|
||||||
import {getTaskCount} from "../../utils";
|
|
||||||
import {FrownFill, SmileFill} from "antd-mobile-icons";
|
import {FrownFill, SmileFill} from "antd-mobile-icons";
|
||||||
import {NEW, OVERDUE, UNDER_WAY} from "../../utils/commonConstant";
|
import {NEW, OVERDUE, UNDER_WAY} from "../../utils/commonConstant";
|
||||||
|
import {dateStartUtcFormat} from "../../utils/timeFormatUtil";
|
||||||
|
|
||||||
|
import './index.css'
|
||||||
|
|
||||||
const ToDoCal = (props) => {
|
const ToDoCal = (props) => {
|
||||||
|
const today = new Date()
|
||||||
const calRef = useRef(null);
|
const calRef = useRef(null);
|
||||||
const [currentDay, setCurrentDay] = React.useState(new Date())
|
const [currentDay, setCurrentDay] = React.useState(new Date())
|
||||||
const today = new Date()
|
const [currentMonth, setCurrentMonth] = React.useState(dayjs().set("date", 1).format('YYYY-MM-DD'));
|
||||||
const [allDay,setAllDay] = React.useState([])
|
// Map key为当前月value为当前月的向
|
||||||
const [taskCount,setTaskCount] = React.useState([])
|
const [listTaskMap, setListTaskMap] = useState(new Map());
|
||||||
function listTaskCount(){
|
// useLayoutEffect
|
||||||
if (allDay.length === 0){
|
useEffect(() => {
|
||||||
return
|
console.log("getCurrentShowDay", getCurrentShowDay())
|
||||||
}
|
const {startDay, endDay} = getCurrentShowDay();
|
||||||
getTaskCount(dateStartUtcFormat(allDay[0]),
|
listTaskCount(startDay, endDay);
|
||||||
nextDateStartUtcFormat(allDay[allDay.length-1]))
|
}, [currentMonth])
|
||||||
.then(res => {
|
let loading = false
|
||||||
setTaskCount(res)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
useLayoutEffect(()=>{
|
|
||||||
console.log("useLayoutEffect",allDay)
|
|
||||||
|
|
||||||
listTaskCount();
|
async function listTaskCount(start, end) {
|
||||||
},[])
|
if (loading) {
|
||||||
function backToToday(){
|
return;
|
||||||
|
}
|
||||||
|
loading = true;
|
||||||
|
if (listTaskMap.has(currentMonth)) return
|
||||||
|
const res = await getTaskCount(start, end);
|
||||||
|
setListTaskMap(prevState => {
|
||||||
|
const newMap = new Map(prevState);
|
||||||
|
newMap.set(currentMonth, res);
|
||||||
|
return newMap;
|
||||||
|
})
|
||||||
|
loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
获取当前展示的日期
|
||||||
|
*/
|
||||||
|
function getCurrentShowDay() {
|
||||||
|
const firstDay = dayjs(currentMonth).set("date", 1);
|
||||||
|
const startDay = firstDay.subtract(firstDay.day(), 'day');
|
||||||
|
const endDay = startDay.add(6 * 7, 'day');
|
||||||
|
return {startDay: dateStartUtcFormat(startDay), endDay: dateStartUtcFormat(endDay)};
|
||||||
|
}
|
||||||
|
|
||||||
|
function backToToday() {
|
||||||
calRef.current.jumpToToday();
|
calRef.current.jumpToToday();
|
||||||
setCurrentDay(today)
|
setCurrentDay(today)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Calendar
|
<Calendar
|
||||||
ref={calRef}
|
ref={calRef}
|
||||||
selectionMode='single'
|
selectionMode='single'
|
||||||
renderLabel={date => {
|
// renderLabel={date => {
|
||||||
allDay.push(date)
|
// // 没有任务不显示
|
||||||
|
// return listTaskMap?.get(currentMonth)?.filter(taskC => dayjs(taskC.todoDay).isSame(dayjs(date), 'date'))?.map(taskC => {
|
||||||
// 没有任务不显示
|
// // 如果有逾期的 红色
|
||||||
return taskCount.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 <FrownFill color='var(--adm-color-danger)'/>;
|
||||||
|
// }
|
||||||
|
// // 如果有未完成的任务 warn
|
||||||
|
// if (taskC.state[NEW] || taskC.state[UNDER_WAY]) {
|
||||||
|
// return <SmileFill color='var(--adm-color-warning)'/>;
|
||||||
|
// }
|
||||||
|
// // 任务全部完成 绿色
|
||||||
|
// return <SmileFill color='var(--adm-color-success)'/>;
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// // 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.keys() 返回一个包含对象自身所有可枚举属性的数组
|
||||||
// Object.entries() 返回一个包含对象所有可枚举属性的键值对数组。
|
// Object.entries() 返回一个包含对象所有可枚举属性的键值对数组。
|
||||||
if (Object.keys(taskC.state).length>0){
|
if (Object.keys(taskC.state).length > 0) {
|
||||||
console.log("taskC.state",taskC.state)
|
console.log("taskC.state", taskC.state)
|
||||||
if (taskC.state[OVERDUE]){
|
if (taskC.state[OVERDUE]) {
|
||||||
return <FrownFill color='var(--adm-color-danger)'/>;
|
return <div className='cal-day-circle' style={{
|
||||||
|
borderColor: 'var(--adm-color-danger)',
|
||||||
|
}}><span>{dayjs(date).date()}</span></div>;
|
||||||
}
|
}
|
||||||
// 如果有未完成的任务 warn
|
// 如果有未完成的任务 warn
|
||||||
if (taskC.state[NEW]||taskC.state[UNDER_WAY]){
|
if (taskC.state[NEW] || taskC.state[UNDER_WAY]) {
|
||||||
return <SmileFill color='var(--adm-color-warning)'/>;
|
return <div className='cal-day-circle' style={{
|
||||||
|
borderColor: 'var(--adm-color-warning)',
|
||||||
|
}}><span>{dayjs(date).date()}</span></div>;
|
||||||
}
|
}
|
||||||
// 任务全部完成 绿色
|
// 任务全部完成 绿色
|
||||||
return <SmileFill color='var(--adm-color-success)'/>;
|
return <div className='cal-day-circle' style={{
|
||||||
|
borderColor: 'var(--adm-color-success)',
|
||||||
|
}}><span>{dayjs(date).date()}</span></div>;
|
||||||
}
|
}
|
||||||
|
return <span>{dayjs(date).date()}</span>;
|
||||||
})
|
})
|
||||||
|
|
||||||
// if (dayjs(date).isSame(today, 'day')) return '今天'
|
|
||||||
// if (date.getDay() === 0 || date.getDay() === 6) {
|
|
||||||
// return '周末'
|
|
||||||
// }
|
|
||||||
}}
|
}}
|
||||||
// renderDate={date=>{
|
|
||||||
// return <span style={{"color":"red"}}>{dayjs(date).date()}</span>
|
|
||||||
// }}
|
|
||||||
defaultValue={currentDay}
|
defaultValue={currentDay}
|
||||||
onChange={val => {
|
onChange={val => {
|
||||||
setCurrentDay(val)
|
setCurrentDay(val)
|
||||||
}}
|
}}
|
||||||
|
onPageChange={(year, month) => {
|
||||||
|
console.log(year, month)
|
||||||
|
setCurrentMonth(`${year}-${month}-01`)
|
||||||
|
}}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
<TaskCount currentDay={currentDay} taskCount={taskCount} today={today} backToToday={backToToday}/>
|
<TaskCount currentDay={currentDay} taskCount={listTaskMap?.get(currentMonth)} today={today}
|
||||||
|
currentMonth={currentMonth}
|
||||||
|
backToToday={backToToday}/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import {requestUtil} from "./requestUtil";
|
||||||
|
|
||||||
export const getDictionary = async (typeId) => {
|
export const getDictionary = async (typeId) => {
|
||||||
let item1 = localStorage.getItem("huayu-dict-" + typeId);
|
let item1 = localStorage.getItem("huayu-dict-" + typeId);
|
||||||
console.log("item1: ", item1);
|
|
||||||
if (item1) {
|
if (item1) {
|
||||||
return new Map(JSON.parse(item1).map(item => {
|
return new Map(JSON.parse(item1).map(item => {
|
||||||
return [item.itemCode, item]
|
return [item.itemCode, item]
|
||||||
|
|
Loading…
Reference in New Issue