feat:树任务跳转
This commit is contained in:
parent
7ddeb50e3f
commit
779a28a364
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,7 @@
|
||||||
"@testing-library/jest-dom": "^5.16.5",
|
"@testing-library/jest-dom": "^5.16.5",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"antd-mobile": "^5.27.0",
|
"antd-mobile": "^5.28.0",
|
||||||
"antd-mobile-icons": "^0.3.0",
|
"antd-mobile-icons": "^0.3.0",
|
||||||
"axios": "^1.2.2",
|
"axios": "^1.2.2",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import {Button, Divider, TextArea} from "antd-mobile";
|
import {ActionSheet, Button, Dialog, Divider, Tabs, TextArea, Toast} from "antd-mobile";
|
||||||
import {Fragment, useEffect, useMemo, useRef, useState} from "react";
|
import {Fragment, useEffect, useMemo, useRef, useState} from "react";
|
||||||
import "./index.css"
|
import "./index.css"
|
||||||
import {useOutletContext, useSearchParams} from "react-router-dom";
|
import {useOutletContext, useSearchParams} from "react-router-dom";
|
||||||
import {addTaskLog, listTaskLog} from "../../api/detailLogTaskApi";
|
import {addTaskLog, listTaskLog} from "../../api/detailLogTaskApi";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
import {copyTextToClipboard} from "../../utils/copyToClipBoard";
|
||||||
|
|
||||||
export function DetailLogTask() {
|
export function DetailLogTask() {
|
||||||
// 设置标题栏
|
// 设置标题栏
|
||||||
|
@ -13,11 +14,32 @@ export function DetailLogTask() {
|
||||||
setRightDesc(<Fragment/>);
|
setRightDesc(<Fragment/>);
|
||||||
}, [])
|
}, [])
|
||||||
let [params] = useSearchParams();
|
let [params] = useSearchParams();
|
||||||
|
|
||||||
|
// 发送展示日记
|
||||||
|
const [currentShow, setCurrentShow] = useState('need');
|
||||||
const textAreaRef = useRef(null);
|
const textAreaRef = useRef(null);
|
||||||
const [taskLogMap, setTaskLogMap] = useState([]);
|
|
||||||
const [taskLogList, setTaskLogList] = useState([]);
|
const [taskLogList, setTaskLogList] = useState([]);
|
||||||
const [sendValue, setSendValue] = useState([]);
|
const [sendValue, setSendValue] = useState([]);
|
||||||
|
|
||||||
|
// 点击操作面板
|
||||||
|
const [actionSheetVisible, setActionSheetVisible] = useState(false)
|
||||||
|
const [currentTask, setCurrentTask] = useState({});
|
||||||
|
const [actions,setActions] = useState([
|
||||||
|
{ text: '复制', key: 'copy' },
|
||||||
|
{ text: '有效', key: 'edit' },
|
||||||
|
{ text: '创建任务', key: 'addTask'},
|
||||||
|
{
|
||||||
|
text: '删除',
|
||||||
|
key: 'delete',
|
||||||
|
onClick: async () => {
|
||||||
|
const result = await Dialog.confirm({ content: '确定要删除吗?' })
|
||||||
|
if (result) {
|
||||||
|
Toast.show('执行了删除操作')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
const taskLogMapMemory = useMemo(() => {
|
const taskLogMapMemory = useMemo(() => {
|
||||||
return taskLogList.reduce((map, taskLog) => {
|
return taskLogList.reduce((map, taskLog) => {
|
||||||
if (!map.has(dayjs(taskLog.createdDate).format("YYYY-MM-DD"))) {
|
if (!map.has(dayjs(taskLog.createdDate).format("YYYY-MM-DD"))) {
|
||||||
|
@ -42,7 +64,14 @@ export function DetailLogTask() {
|
||||||
textAreaRef.current.focus();
|
textAreaRef.current.focus();
|
||||||
// 获取之前的日志信息,根据日期分组排序,遍历map
|
// 获取之前的日志信息,根据日期分组排序,遍历map
|
||||||
listTaskLog(`{
|
listTaskLog(`{
|
||||||
"sortList":[{"direction":"DESC","property":"createdDate"}]
|
"sortList":[{"direction":"DESC","property":"createdDate"}],
|
||||||
|
"data": {
|
||||||
|
"andList":[{
|
||||||
|
"name":"taskId",
|
||||||
|
"operateType":"=",
|
||||||
|
"value":"${params.get('id')}"
|
||||||
|
}]
|
||||||
|
}
|
||||||
}`).then(res => {
|
}`).then(res => {
|
||||||
console.log({res})
|
console.log({res})
|
||||||
if (res.content.length > 0) {
|
if (res.content.length > 0) {
|
||||||
|
@ -57,9 +86,17 @@ export function DetailLogTask() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
function NoNeed(){
|
||||||
|
return <s>失效</s>
|
||||||
|
}
|
||||||
return <Fragment>
|
return <Fragment>
|
||||||
<div className="log-task-detail">
|
<div className="log-task-detail">
|
||||||
<div className="log-detail">
|
<div className="log-detail">
|
||||||
|
<Tabs defaultActiveKey='need' onChange={(key)=>setCurrentShow(key)}>
|
||||||
|
<Tabs.Tab title='全部' key='all' />
|
||||||
|
<Tabs.Tab title='有效' key='need' />
|
||||||
|
<Tabs.Tab key='noneed' title=<NoNeed/> />
|
||||||
|
</Tabs>
|
||||||
{
|
{
|
||||||
Array.from(taskLogMapMemory.keys()).map(key => {
|
Array.from(taskLogMapMemory.keys()).map(key => {
|
||||||
return (<Fragment>
|
return (<Fragment>
|
||||||
|
@ -72,7 +109,13 @@ export function DetailLogTask() {
|
||||||
</div>}
|
</div>}
|
||||||
{taskLogMapMemory.get(key).map(taskLog => {
|
{taskLogMapMemory.get(key).map(taskLog => {
|
||||||
return <div key={taskLog.id} style={{ display: 'flex', width: "80%", padding: "2px 20px"}}>
|
return <div key={taskLog.id} style={{ display: 'flex', width: "80%", padding: "2px 20px"}}>
|
||||||
<span className="detail-line">{taskLog.description}</span>
|
<span className="detail-line" onClick={()=>{
|
||||||
|
actions[1]={ text: '失效', key: 'edit' }
|
||||||
|
// setActions([...actions])
|
||||||
|
setCurrentTask(taskLog)
|
||||||
|
setActionSheetVisible(true)
|
||||||
|
}}>
|
||||||
|
{taskLog.description}</span>
|
||||||
</div>
|
</div>
|
||||||
})}</Fragment>)
|
})}</Fragment>)
|
||||||
})
|
})
|
||||||
|
@ -96,6 +139,19 @@ export function DetailLogTask() {
|
||||||
onClick={handleSend}
|
onClick={handleSend}
|
||||||
>发送
|
>发送
|
||||||
</Button>
|
</Button>
|
||||||
|
<ActionSheet
|
||||||
|
extra='请选择你要进行的操作'
|
||||||
|
cancelText='取消'
|
||||||
|
visible={actionSheetVisible}
|
||||||
|
actions={actions}
|
||||||
|
onClose={() => setActionSheetVisible(false)}
|
||||||
|
onAction={action => {
|
||||||
|
if (action.key === 'copy') {
|
||||||
|
copyTextToClipboard(currentTask.description)
|
||||||
|
}
|
||||||
|
setActionSheetVisible(false)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -3,40 +3,19 @@ import {getTaskCount} from "../../utils";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import {DATE_FORMAT, dayStartUtcFormat, nextDayStartUtcFormat} from "../../utils/timeFormatUtil";
|
import {DATE_FORMAT, dayStartUtcFormat, nextDayStartUtcFormat} from "../../utils/timeFormatUtil";
|
||||||
import {getDictionary} from "../../utils/dictUtil";
|
import {getDictionary} from "../../utils/dictUtil";
|
||||||
import {Tag} from "antd-mobile";
|
import {Divider, Tag} from "antd-mobile";
|
||||||
import {useNavigate} from "react-router-dom";
|
import {useNavigate} from "react-router-dom";
|
||||||
import {MyRootContext, UPDATE_SEARCH} from "../../components/MyRootContext";
|
import {MyRootContext, UPDATE_SEARCH} from "../../components/MyRootContext";
|
||||||
|
|
||||||
|
|
||||||
const TaskCount = (props) => {
|
const TaskCount = (props) => {
|
||||||
let currentDay = props.currentDay;
|
const {currentDay, taskCount, today, backToToday} = props;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [taskCount, setTaskCount] = React.useState([]);
|
|
||||||
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);
|
||||||
const {dispatch } = useContext(MyRootContext);
|
const {dispatch} = useContext(MyRootContext);
|
||||||
useEffect(() => {
|
|
||||||
console.log("useEffect");
|
|
||||||
if (currentDay) {
|
|
||||||
getTaskCount(dayStartUtcFormat(currentDay),
|
|
||||||
nextDayStartUtcFormat(currentDay))
|
|
||||||
.then(taskCount => {
|
|
||||||
setTaskCount(taskCount)
|
|
||||||
})
|
|
||||||
getDictionary("2").then(state => {
|
|
||||||
setStateMap(state)
|
|
||||||
})
|
|
||||||
getDictionary("1").then(priority => {
|
|
||||||
console.log(priority)
|
|
||||||
setPriorityMap(priority)
|
|
||||||
})
|
|
||||||
}else {
|
|
||||||
setTaskCount([])
|
|
||||||
}
|
|
||||||
|
|
||||||
}, [currentDay])
|
const todoDayDetail = () => {
|
||||||
|
|
||||||
const todoDayDetail = ()=>{
|
|
||||||
let andSearchModel = {}
|
let andSearchModel = {}
|
||||||
let orSearchModel = {andSearchModel}
|
let orSearchModel = {andSearchModel}
|
||||||
if (currentDay) {
|
if (currentDay) {
|
||||||
|
@ -82,49 +61,56 @@ const TaskCount = (props) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log({orSearchModel})
|
console.log({orSearchModel})
|
||||||
dispatch({type:UPDATE_SEARCH,search:{
|
dispatch({
|
||||||
|
type: UPDATE_SEARCH, search: {
|
||||||
"pageSize": 12,
|
"pageSize": 12,
|
||||||
"pageNumber": 1,
|
"pageNumber": 1,
|
||||||
"data": {
|
"data": {
|
||||||
orSearchModel
|
orSearchModel
|
||||||
}
|
}
|
||||||
}})
|
}
|
||||||
|
})
|
||||||
navigate("/home/listTask")
|
navigate("/home/listTask")
|
||||||
}
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("useEffect");
|
||||||
|
getDictionary("2").then(state => {
|
||||||
|
setStateMap(state)
|
||||||
|
})
|
||||||
|
getDictionary("1").then(priority => {
|
||||||
|
console.log(priority)
|
||||||
|
setPriorityMap(priority)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<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>}</h2>
|
{currentDay && <a onClick={todoDayDetail}>详情</a>}
|
||||||
<h3>任务状态</h3>
|
{!dayjs(currentDay).isSame(today, 'date') &&
|
||||||
{
|
<Fragment><Divider direction='vertical'/><a onClick={() => backToToday()}>回到今天</a></Fragment>}
|
||||||
// taskCount.map(task => {
|
</h2>
|
||||||
// // if (dayjs(task.todoDay).isSame(dayjs(currentDay))){
|
{taskCount.filter(taskC => dayjs(taskC.todoDay).isSame(dayjs(currentDay), 'date'))?.map(taskC => {
|
||||||
// // console.log(dict);
|
return <Fragment>
|
||||||
// // return <span key={task.todoDay}>{task.todoDay}</span>
|
<h3>任务状态</h3>
|
||||||
// return Array.from(stateMap.entries()).map(([item,value]) => {
|
{
|
||||||
// console.log("key",item,"value",value,task.state)
|
Object.keys(taskC.state).map(ob => {
|
||||||
// return <Tag color={value.josnValue?.color}>value.itemName</Tag> + task.state[item]
|
return <div style={{marginBottom: "20px"}} key={ob}><Tag color={
|
||||||
// })
|
stateMap.get(ob).jsonValue ? stateMap.get(ob).jsonValue.color : "default"
|
||||||
//
|
}>{stateMap.get(ob).itemName}</Tag> 共
|
||||||
// // return task.priority.map((key,value)=>getDictionary(2).get(key)+value)
|
{taskC.state[ob]} 项代办;</div>;
|
||||||
// // }
|
})}
|
||||||
// })
|
<h3>优先级</h3>
|
||||||
taskCount[0] && Object.keys(taskCount[0].state).map(ob => {
|
{
|
||||||
return <div style={{marginBottom:"20px"}} key={ob}><Tag color={
|
Object.keys(taskC.priority).map(ob => {
|
||||||
stateMap.get(ob).jsonValue?stateMap.get(ob).jsonValue.color:"default"
|
console.log("stateMap.get(ob).jsonValue?.color", priorityMap.get(ob))
|
||||||
}>{stateMap.get(ob).itemName}</Tag> 共
|
return <div style={{marginBottom: "20px"}} key={ob}><Tag
|
||||||
{taskCount[0].state[ob]} 项代办;</div>;
|
color={priorityMap.get(ob).jsonValue.color}>{priorityMap.get(ob).itemName}</Tag> 共
|
||||||
})
|
{taskC.priority[ob]} 项代办;</div>;
|
||||||
}
|
})
|
||||||
<h3>优先级</h3>
|
}
|
||||||
{
|
</Fragment>
|
||||||
taskCount[0] && Object.keys(taskCount[0].priority).map(ob => {
|
})
|
||||||
console.log("stateMap.get(ob).jsonValue?.color", priorityMap.get(ob))
|
|
||||||
return <div style={{marginBottom:"20px"}} key={ob}><Tag
|
|
||||||
color={priorityMap.get(ob).jsonValue.color}>{priorityMap.get(ob).itemName}</Tag> 共
|
|
||||||
{taskCount[0].priority[ob]} 项代办;</div>;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,26 +1,82 @@
|
||||||
import {Calendar} from "antd-mobile";
|
import {Calendar, Tag} from "antd-mobile";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import {TaskCount} from "../TaskCount";
|
import {TaskCount} from "../TaskCount";
|
||||||
import React,{Fragment} from "react";
|
import React, {Fragment, useEffect, useLayoutEffect, useRef} from "react";
|
||||||
|
|
||||||
|
import {
|
||||||
|
dateStartUtcFormat,
|
||||||
|
nextDateStartUtcFormat,
|
||||||
|
} from "../../utils/timeFormatUtil";
|
||||||
|
import {getTaskCount} from "../../utils";
|
||||||
|
import {FrownFill, SmileFill} from "antd-mobile-icons";
|
||||||
|
import {NEW, OVERDUE, UNDER_WAY} from "../../utils/commonConstant";
|
||||||
const ToDoCal = (props) => {
|
const ToDoCal = (props) => {
|
||||||
|
const calRef = useRef(null);
|
||||||
const [currentDay, setCurrentDay] = React.useState(new Date())
|
const [currentDay, setCurrentDay] = React.useState(new Date())
|
||||||
const today = dayjs()
|
const today = new Date()
|
||||||
|
const [allDay,setAllDay] = React.useState([])
|
||||||
|
const [taskCount,setTaskCount] = React.useState([])
|
||||||
|
function listTaskCount(){
|
||||||
|
if (allDay.length === 0){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getTaskCount(dateStartUtcFormat(allDay[0]),
|
||||||
|
nextDateStartUtcFormat(allDay[allDay.length-1]))
|
||||||
|
.then(res => {
|
||||||
|
setTaskCount(res)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
useLayoutEffect(()=>{
|
||||||
|
console.log("useLayoutEffect",allDay)
|
||||||
|
|
||||||
|
listTaskCount();
|
||||||
|
},[])
|
||||||
|
function backToToday(){
|
||||||
|
calRef.current.jumpToToday();
|
||||||
|
setCurrentDay(today)
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Calendar
|
<Calendar
|
||||||
|
ref={calRef}
|
||||||
selectionMode='single'
|
selectionMode='single'
|
||||||
renderLabel={date => {
|
renderLabel={date => {
|
||||||
if (dayjs(date).isSame(today, 'day')) return '今天'
|
allDay.push(date)
|
||||||
if (date.getDay() === 0 || date.getDay() === 6) {
|
|
||||||
return '周末'
|
// 没有任务不显示
|
||||||
}
|
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 <span style={{"color":"red"}}>{dayjs(date).date()}</span>
|
||||||
|
// }}
|
||||||
defaultValue={currentDay}
|
defaultValue={currentDay}
|
||||||
onChange={val => {
|
onChange={val => {
|
||||||
setCurrentDay(val)
|
setCurrentDay(val)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
<TaskCount currentDay={currentDay}/>
|
<TaskCount currentDay={currentDay} taskCount={taskCount} today={today} backToToday={backToToday}/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,79 +1,24 @@
|
||||||
import {Fragment, useEffect, useMemo, useState} from "react";
|
import {Fragment} from "react";
|
||||||
import {Card, Cascader, CascaderView} from "antd-mobile";
|
import {Card, CascaderView, Dialog, Toast} from "antd-mobile";
|
||||||
import {getTaskByPid} from "../../utils";
|
|
||||||
import dayjs from "dayjs";
|
|
||||||
import {DATE_TIME_FORMAT} from "../../utils/timeFormatUtil";
|
|
||||||
import {useChildList} from "../../hooks/useChildList";
|
import {useChildList} from "../../hooks/useChildList";
|
||||||
|
import {useNavigate} from "react-router-dom";
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
// const [valueToOptions, setValueToOptions] = useState([])
|
|
||||||
// const [currentTask, setCurrentTask] = useState({
|
|
||||||
// name:"想做的事情",
|
|
||||||
// description:"想做的事情描述",
|
|
||||||
// expectedStartTime:dayjs().format(DATE_TIME_FORMAT),
|
|
||||||
// expectedEndTime:"",
|
|
||||||
// state:"",
|
|
||||||
// priority:"",
|
|
||||||
// })
|
|
||||||
// const options = useMemo(() => {
|
|
||||||
// function generate(v) {
|
|
||||||
// const options = valueToOptions[v]
|
|
||||||
// if (options === null || options === undefined) {
|
|
||||||
// return undefined
|
|
||||||
// }
|
|
||||||
// // if (options === undefined) {
|
|
||||||
// // return Cascader.optionSkeleton
|
|
||||||
// // }
|
|
||||||
// return options.map(option => ({
|
|
||||||
// ...option,
|
|
||||||
// children: generate(option.value),
|
|
||||||
// }))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return generate('0') ?? []
|
|
||||||
// }, [valueToOptions])
|
|
||||||
//
|
|
||||||
// async function fetchOptionsForValue(v, level) {
|
|
||||||
// if (v in valueToOptions) return
|
|
||||||
// // if (level >= 3) {
|
|
||||||
// // setValueToOptions(prev => ({
|
|
||||||
// // ...prev,
|
|
||||||
// // [v]: null,
|
|
||||||
// // }))
|
|
||||||
// // return
|
|
||||||
// // }
|
|
||||||
// const data = await getTaskByPid(v)
|
|
||||||
// console.log("await getTaskByPid(v)", data.content)
|
|
||||||
// const options =
|
|
||||||
// data.content.length === 0
|
|
||||||
// ? null
|
|
||||||
// : data.content.map(task => ({
|
|
||||||
// value: task.id,
|
|
||||||
// label: task.name,
|
|
||||||
// }))
|
|
||||||
// console.log("await getTaskByPid(v) options", options)
|
|
||||||
// if (options){
|
|
||||||
// setValueToOptions(prev => ({
|
|
||||||
// ...prev,
|
|
||||||
// [v]: options,
|
|
||||||
// }))
|
|
||||||
// }else {
|
|
||||||
// setValueToOptions(prev => ({
|
|
||||||
// ...prev,
|
|
||||||
// [v]: undefined,
|
|
||||||
// }))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// fetchOptionsForValue('0', 0)
|
|
||||||
// }, [])
|
|
||||||
|
|
||||||
const {task, options, changeTaskId,} = useChildList();
|
const {task, options, changeTaskId,} = useChildList();
|
||||||
|
const navigate = useNavigate();
|
||||||
return <Fragment>
|
return <Fragment>
|
||||||
<Card title={task?.name} style={{height: "30vh", borderRadius: "10px"}}>
|
<Card title={task?.name} style={{height: "30vh", borderRadius: "10px"}}
|
||||||
|
onClick={async ()=>{
|
||||||
|
if (task&&task.id) {
|
||||||
|
const result = await Dialog.confirm({ content: '确定要进入详情页吗?' })
|
||||||
|
if (result) {
|
||||||
|
navigate(`/detail/selectTask?id=${task.id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
<p>{task?.description}</p>
|
<p>{task?.description}</p>
|
||||||
|
|
||||||
<p>预计开始时间:{task?.expectedStartTime}</p>
|
<p>预计开始时间:{task?.expectedStartTime}</p>
|
||||||
<p>预计结束时间:{task?.expectedEndTime}</p>
|
<p>预计结束时间:{task?.expectedEndTime}</p>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
const OVERDUE= '10';
|
||||||
|
const COMPLETE = '7';
|
||||||
|
const NEW = '8';
|
||||||
|
const UNDER_WAY = '9';
|
||||||
|
export { OVERDUE, COMPLETE, NEW, UNDER_WAY };
|
|
@ -0,0 +1,39 @@
|
||||||
|
export function copyTextToClipboard(text) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
// 尝试使用现代剪贴板 API
|
||||||
|
navigator.clipboard.writeText(text)
|
||||||
|
.then(() => resolve('文本已成功复制到剪贴板'))
|
||||||
|
.catch((err) => reject(`无法复制文本:${err.message}`));
|
||||||
|
} else {
|
||||||
|
// 回退到旧方法
|
||||||
|
fallbackCopyTextToClipboard(text)
|
||||||
|
.then(message => resolve(message))
|
||||||
|
.catch(err => reject(err));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fallbackCopyTextToClipboard(text) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const textArea = document.createElement("textarea");
|
||||||
|
textArea.value = text;
|
||||||
|
|
||||||
|
// 避免 CSS 样式影响滚动条
|
||||||
|
textArea.style.position = 'fixed';
|
||||||
|
textArea.style.left = '-9999px';
|
||||||
|
document.body.appendChild(textArea);
|
||||||
|
textArea.focus();
|
||||||
|
textArea.select();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const successful = document.execCommand('copy');
|
||||||
|
const msg = successful ? '文本已成功复制到剪贴板' : '无法复制文本';
|
||||||
|
resolve(msg);
|
||||||
|
} catch (err) {
|
||||||
|
reject(`无法复制文本:${err.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.removeChild(textArea);
|
||||||
|
});
|
||||||
|
}
|
|
@ -21,6 +21,22 @@ function dayStartUtcFormat(dayjsString) {
|
||||||
return dayJsObj.set('h', 0).set('m', 0).set('s', 0).set('ms', 0).utc().format()
|
return dayJsObj.set('h', 0).set('m', 0).set('s', 0).set('ms', 0).utc().format()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dateStartUtcFormat(dateObject) {
|
||||||
|
if (!dateObject) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let dayJsObj= dayjs(dateObject);
|
||||||
|
return dayJsObj.set('h', 0).set('m', 0).set('s', 0).set('ms', 0).utc().format()
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextDateStartUtcFormat(dateObject) {
|
||||||
|
if (!dateObject) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let dayJsObj= dayjs(dateObject);
|
||||||
|
return dayJsObj.add(1, "d").set('h', 0).set('m', 0).set('s', 0).set('ms', 0).utc().format()
|
||||||
|
}
|
||||||
|
|
||||||
function nextDayStartUtcFormat(dayjsString) {
|
function nextDayStartUtcFormat(dayjsString) {
|
||||||
if (!dayjsString) {
|
if (!dayjsString) {
|
||||||
return
|
return
|
||||||
|
@ -34,4 +50,7 @@ function nextDayStartUtcFormat(dayjsString) {
|
||||||
return dayJsObj.add(1, "d").set('h', 0).set('m', 0).set('s', 0).set('ms', 0).utc().format()
|
return dayJsObj.add(1, "d").set('h', 0).set('m', 0).set('s', 0).set('ms', 0).utc().format()
|
||||||
}
|
}
|
||||||
|
|
||||||
export {DATE_TIME_FORMAT, DATE_FORMAT,DATE_TIME_FORMAT_SIMPLE,dayStartUtcFormat,nextDayStartUtcFormat}
|
export {DATE_TIME_FORMAT, DATE_FORMAT,DATE_TIME_FORMAT_SIMPLE,
|
||||||
|
dayStartUtcFormat,nextDayStartUtcFormat,
|
||||||
|
dateStartUtcFormat,nextDateStartUtcFormat,
|
||||||
|
}
|
Loading…
Reference in New Issue