feat:添加日历

This commit is contained in:
1708-huayu 2025-01-01 21:16:32 +08:00
parent abc20d99c2
commit b3d1fce71f
9 changed files with 187 additions and 82 deletions

View File

@ -10,6 +10,7 @@ import DetailForm from "./components/DetailForm";
import {NavBar} from "antd-mobile";
import DetailNavBar from "./components/DetailNavBar";
import DetailSearchContext from "./pages/DetailSearchContext";
import ToDoCal from "./pages/ToDoCal";
function App() {
return (
@ -20,12 +21,14 @@ function App() {
</div> */}
{/* <div className='body'> */}
<Routes>
{/* <Route path='/' element={<Navigate to="/home" />}>
</Route> */}
<Route path='/' element={<Home/>}>
<Route index path='/home' element={<Index/>}/>
<Route path='/home/todo' element={<ToDoList/>}></Route>
<Route path='/home/me' element={<PersonalCenter/>}></Route>
<Route path='/' element={<Navigate to="/home/listTask" />}>
</Route>
<Route path='/home' element={<Home/>}>
<Route path='treeTask' element={<Index/>}/>
<Route index path='listTask' element={<ToDoList/>}></Route>
<Route path='calTask' element={<ToDoCal/>}/>
<Route path='me' element={<PersonalCenter/>}></Route>
</Route>
<Route path='/detail' element={<DetailNavBar/>}>
<Route path='addTask' element={<DetailForm/>}></Route>

View File

@ -10,14 +10,17 @@ const DetailSearchBar = (props) => {
// const location = useLocation();
// const searchUpdate = location.state?.search;
// 父子传值从搜索框传来的search
const {search,updateSearch} = props;
console.log("DetailSearchBar.search", search)
const {search,updateSearch,pName} = props;
console.log("DetailSearchBar.search", search.data)
const [tags, setTags] = useState([]);
useEffect(() => {
if (search && search.data) {
Promise.all(
search.data.map(async (searchObj) => {
if (searchObj.name === "state") {
console.log("DetailSearchContext.search", searchObj)
if (searchObj.name === "pid") {
return <Tag>{pName}</Tag>
}else if (searchObj.name === "state") {
const dictionary = await getDictionary("2");
const items = searchObj.value.split(',');
const itemPromises = items.map((item) => {
@ -25,6 +28,16 @@ const DetailSearchBar = (props) => {
return dict ? <Tag key={dict.id} color={dict.jsonValue?.color}>{dict.itemName}</Tag> : null;
});
return Promise.all(itemPromises);
}else if (searchObj.name === "priority"){
const dictionary = await getDictionary("1");
const items = searchObj.value.split(',');
const itemPromises = items.map((item) => {
const dict = dictionary.get(item);
return dict ? <Tag key={dict.id} color={dict.jsonValue?.color}>{dict.itemName}</Tag> : null;
});
return Promise.all(itemPromises);
}else if (searchObj.name === "todoDay"){
return <Tag >{searchObj.value}</Tag>;
}
})
).then((results) => {

View File

@ -9,23 +9,22 @@ import {
AddOutline,
} from 'antd-mobile-icons'
import "./index.css"
import DetailForm from "../../components/DetailForm";
const tabs = [
{
key: '/home',
key: '/home/treeTask',
title: '树状任务',
icon: <AppOutline/>,
badge: '1',
},
{
key: '/home/todo',
key: '/home/listTask',
title: '列表任务',
icon: <UnorderedListOutline/>,
badge: '2',
},
{
key: '/home/message',
key: '/home/calTask',
title: '日历任务',
icon: <MessageOutline/>,
badge: '3',

View File

@ -1,30 +1,78 @@
import {Button, Checkbox, DatePicker, Form, Input, Space, Switch, Tag} from "antd-mobile";
import ParentTask from "../../components/ParentTask";
import React from "react";
import React, {useEffect} from "react";
import dayjs from "dayjs";
import {CloseCircleFill} from "antd-mobile-icons";
import {useLocation, useNavigate, useOutletContext} from "react-router-dom";
const now = new Date()
import {getDictionary} from "../../utils/dictUtil";
import {getTaskById} from "../../utils";
const DetailSearchContext = () => {
// 使用Outlet,传值修改标题
const {setTitle} = useOutletContext();
setTitle("搜索查询")
const navigate = useNavigate();
const [form] = Form.useForm();
const [visible, setVisible] = React.useState(false);
const location = useLocation();
console.log("DetailSearchContext", location);
const {search,updateSearch} = location.state;
const {search} = location?.state || undefined;
console.log("DetailSearchContext.search", search)
const [stateList, setStateList] = React.useState([]);
const [priorityList, setPriorityList] = React.useState([]);
// 使用Outlet,传值修改标题
const {setTitle} = useOutletContext();
useEffect(() => {
// 使用Outlet,传值修改标题
setTitle("搜索查询")
initDate()
}, [])
async function initDate() {
let stateDictionary = await getDictionary("2");
let priorityDictionary = await getDictionary("1");
setStateList(Array.from(stateDictionary.values()));
setPriorityList(Array.from(priorityDictionary.values()));
if (!search) {
return
}
let searchMap = new Map(search.data.map(searchObj => [searchObj.name, searchObj]));
if (searchMap.has("pid")) {
let task = await getTaskById(searchMap.get("pid"));
// form.setFieldValue(task.name);
}
if (searchMap.has("state")) {
form.setFieldValue("state", searchMap.get("state").value.split(','))
}
if (searchMap.has("priority")) {
form.setFieldValue("priority", searchMap.get("priority").value.split(','))
}
if (searchMap.has("todoDay")) {
form.setFieldValue("todoDay", searchMap.get("todoDay").value)
}
}
return (
<Form
form={form}
layout='horizontal'
onFinish={(values) => {
// navigate("/home/todo", { state: { search: values } })
// 根据values处理search
// updateSearch()
navigate("/home/todo")
console.log(values)
let searchCondition = [];
const {pidArray, name, priority, state, todoDay} = values;
if (pidArray && pidArray.length !== 0) {
searchCondition.push({"name": "name", "value": pidArray[pidArray.length - 1], "operateType": "="})
}
if (name && name !== "") {
searchCondition.push({"name": "name", "value": name, "operateType": "LIKE"})
}
if (priority && priority.length !== 0) {
searchCondition.push({"name": "priority", "value": priority.join(","), "operateType": "IN"})
}
if (state && state.length !== 0) {
searchCondition.push({"name": "state", "value": state.join(","), "operateType": "IN"})
}
if (todoDay !== undefined) {
searchCondition.push({"name": "todoDay", "value": todoDay, "operateType": "IN"})
}
navigate("/home/listTask", {state: {search: JSON.stringify(searchCondition)}})
}}
footer={
<Button block type='submit' color='primary' size='large'>
@ -40,24 +88,29 @@ const DetailSearchContext = () => {
<Input onChange={console.log} placeholder='任务信息'/>
</Form.Item>
<Form.Item name='state' label='任务状态' required>
<Form.Item name='state' label='任务状态'>
<Checkbox.Group>
<Space direction='vertical'>
<Checkbox value='8'><Tag color='danger'>未开始</Tag></Checkbox>
<Checkbox value='9'><Tag color='warning'>进行中</Tag></Checkbox>
<Checkbox value='7'><Tag color='success'>已完成</Tag></Checkbox>
<Checkbox value='10'><Tag color='success'>未完成</Tag></Checkbox>
<Checkbox value='6'><Tag>已关闭</Tag></Checkbox>
{
stateList.map(stateDict =>
<Checkbox value={stateDict.itemCode}>
<Tag color={stateDict.jsonValue?.color}>{stateDict.itemName}</Tag>
</Checkbox>
)
}
</Space>
</Checkbox.Group>
</Form.Item>
<Form.Item name='priority' label='任务优先级'>
<Checkbox.Group>
<Space direction='vertical'>
<Checkbox value='3'><Tag color='danger'>紧急重要</Tag></Checkbox>
<Checkbox value='2'><Tag color='warning'>不紧急重要</Tag></Checkbox>
<Checkbox value='1'><Tag>紧急不重要</Tag></Checkbox>
<Checkbox value='0'><Tag color='success'>不紧急不重要</Tag></Checkbox>
{
priorityList.map(stateDict =>
<Checkbox value={stateDict.itemCode}>
<Tag color={stateDict.jsonValue?.color}>{stateDict.itemName}</Tag>
</Checkbox>
)
}
</Space>
</Checkbox.Group>
</Form.Item>
@ -103,13 +156,14 @@ const DetailSearchContext = () => {
</Form.Item>
)}
</Form.Item>
<Form.Item
name='delivery'
label='延期任务'
childElementPosition='right'
>
<Switch defaultChecked={true}/>
</Form.Item>
{/*后期嵌套or*/}
{/*<Form.Item*/}
{/* name='allOverdueTasks'*/}
{/* label='所有逾期任务'*/}
{/* childElementPosition='right'*/}
{/*>*/}
{/* <Switch/>*/}
{/*</Form.Item>*/}
</Form>)
}
export default DetailSearchContext;

View File

@ -1,30 +1,33 @@
import React from 'react'
import Bottom from './../Bottom/index'
import './index.css'
import {Outlet} from 'react-router-dom'
import {Outlet, useLocation} from 'react-router-dom'
import DetailSearchBar from "../../components/DetailSearchBar";
export default class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
search:{
"pageSize":10,
const Home = () => {
const location = useLocation();
console.log("Home", location);
const searchUrl = location?.state?.search;
const [pName, setName] = React.useState("");
const [search, setSearch] = React.useState({
"pageSize": 12,
"pageNumber": 1,
"data":[
"data": searchUrl ? JSON.parse(searchUrl) : [
{"name": "state", "value": "8,9", "operateType": "IN"},
{"name": "expectedStartTime", "value": "2024-12-29T16:00:00.000Z", "operateType": ">="},
{"name":"expectedStartTime","value":"2024-12-29T16:00:00.000Z","operateType":"<="}]}
};
}
updateSearch = (values) => {
{"name": "expectedStartTime", "value": "2024-12-29T16:00:00.000Z", "operateType": "<="}
]
})
const updateSearch = (values) => {
this.setState({search: values});
};
render() {
return (
<div className='body'>
<DetailSearchBar search={ this.state.search } updateSearch={this.updateSearch} />
<DetailSearchBar search={search}
updateSearch={updateSearch}
pName={pName}/>
<div style={{marginTop: "40px", marginBottom: "49px", width: "100%"}}>
<Outlet/>
</div>
@ -32,4 +35,5 @@ export default class Home extends React.Component {
</div>
)
}
}
export default Home;

View File

@ -0,0 +1,23 @@
import {Calendar} from "antd-mobile";
import dayjs from "dayjs";
const ToDoCal = (props) => {
const defaultSingle = new Date()
const today = dayjs()
return (
<Calendar
selectionMode='single'
renderLabel={date => {
if (dayjs(date).isSame(today, 'day')) return '今天'
if (date.getDay() === 0 || date.getDay() === 6) {
return '周末'
}
}}
defaultValue={defaultSingle}
onChange={val => {
console.log(val)
}}
/>
)
}
export default ToDoCal;

View File

@ -1,4 +1,4 @@
import { useNavigate } from 'react-router-dom'
import {useLocation, useNavigate} from 'react-router-dom'
// 高阶组件包装useNavigate()功能
// 原因类组件中无法使用useNavigate(),会报错
// React Hook "useNavigate" cannot be called in a class component.
@ -7,8 +7,9 @@ function WidthUseNavigate(WrapComponent) {
WrapComponent.displayName = `widthUseNavigate${getDisplayName(WrapComponent)}`
return function NavigateComponent() {
const navigate = useNavigate()
const location = useLocation()
// 给传入的组件新增一个to方法传给原始组件的props在原始组件中通过this.props.to(参数)使用
return <WrapComponent to={navigate}></WrapComponent>
return <WrapComponent to={navigate} useLocation={location.pathname}></WrapComponent>
}
}

View File

@ -5,7 +5,10 @@ export const getDictionary= async (typeId) => {
if (dict.has(typeId)) {
return dict.get(typeId);
}
let search = encodeURI(`{"data":[{"code":"type_id","value":"${typeId}","operateType":"="}]}`)
let search = encodeURI(`{"data":[
{"code":"type_id","value":"${typeId}","operateType":"="},
{"code":"enable_flag","value":"1","operateType":"="}
]}`)
let todo = await requestUtil.get(`/todo-server/search/dict_items?search=${search}`);
let context = todo.content;
let result;

View File

@ -32,6 +32,11 @@ export const getTaskList= (pageNumber) => {
export const getTaskByPid = (pid) => {
return requestUtil.get('/todo-server/search/task_message_tree?search=%7B%22pageSize%22%3A1000%2C%22pageNumber%22%3A1%2C%22data%22%3A%5B%7B%22name%22%3A%22pid%22%2C%22value%22%3A%22'+pid+'%22%2C%22operateType%22%3A%22%3D%22%7D%5D%7D');
}
export const getTaskById= (id) => {
let request = encodeURI(`{"data":[{"name":"id","value":"${id}","operateType":"="}]}`)
return requestUtil.get('/todo-server/search/task_message_tree?search='+request);
}
export const addTask = async (entity) => {
// 使用 Axios 发送 POST 请求添加数据
return await requestUtil.post('/todo-server' + '/task', entity);