diff --git a/index.tsx b/index.tsx new file mode 100644 index 0000000..c38144e --- /dev/null +++ b/index.tsx @@ -0,0 +1,434 @@ +import { Input , Badge , Avatar , Menu } from 'antd'; +import { Dispatch, Link, connect } from 'umi'; +import './index.less'; +import { EnterpriseModelState } from '@/models/enterprise'; +import { UsersModelState } from '@/models/user'; +import { useEffect, useState } from 'react'; +import { WorkStandModelState } from '@/models/workStand'; +import { Table , Row , Col , Progress , Pagination , Spin } from 'antd'; +import type { ColumnsType } from 'antd/es/table'; +import { workItemIcon , workItemType , workItemStatus} from '@/constant/project'; +import { StatusTag } from '@/components/Tags/Tags'; +import { toTimeFormat } from '@/utils/util'; +// import { iterationStatusList } from '@/constant/project'; +import styles from './index.less'; +import NoData from '@/components/NoData'; + +interface HomePageProps { + enterprise: EnterpriseModelState; + user:UsersModelState + dispatch:Dispatch, + workStand:WorkStandModelState +} +const Index: React.FC = ({ enterprise ,user , dispatch , workStand }) => { + const { currentUser } = user; + const { identifier:enterIdentifier } = enterprise; + const [ search , setSearch ] = useState(""); + const [ selectKey , setSelectKey ] = useState("assignedme"); + + const [ statictisData , setStatictisData ] = useState([]); + const [ dataSource , setDataSource ] = useState([]); + + const [ workLoading , setWorkLoading ] =useState(true); + const [ workPage , setWorkPage ] = useState(1); + const [ workTotal , setWorkTotal ] = useState(0); + + const [ projectData , setProjectData ] = useState([]); + const [ projectLoading , setProjectLoading ] =useState(true); + const [ projectPage , setProjectPage ] = useState(1); + const [ projectTotal , setProjectTotal ] = useState(0); + + const [ planData , setPlanData ] = useState([]); + const [ planLoading , setPlanLoading ] =useState(true); + const [ planPage , setPlanPage ] = useState(1); + const [ planTotal , setPlanTotal ] = useState(0); + + const [ authoredmeCount , setAuthoredmeCount ] = useState(0); + const [ assignedmeCount , setAssignedmeCount ] = useState(0); + + function getCurrentTime() { + const currentHour = new Date().getHours(); + + if (currentHour >= 6 && currentHour < 9) { + return "早上好!"; + } else if (currentHour >= 9 && currentHour < 12) { + return "上午好!"; + }else if (currentHour >= 12 && currentHour < 14) { + return "中午好!"; + } else if (currentHour >= 14 && currentHour < 18) { + return "下午好!"; + } else if(currentHour >= 18) { + return "晚上好!"; + } + } + + useEffect(()=>{ + if(enterIdentifier){ + getStatistics(); + } + },[enterIdentifier]) + + useEffect(()=>{ + if(enterIdentifier){ + getIteratioins(); + } + },[enterIdentifier,planPage]) + + useEffect(()=>{ + if(enterIdentifier){ + getProjects(); + } + },[enterIdentifier,projectPage]) + + + useEffect(()=>{ + if(enterIdentifier){ + setWorkPage(1); + getWorkItem(1); + } + },[enterIdentifier,selectKey,search]) + + // 获取我的工作台统计信息 + async function getStatistics() { + let res:any = await dispatch({ + type:"workStand/getMyStatistics", + }) + setStatictisData(res?.data); + setAssignedmeCount(res?.data?.assignedmeCount); + setAuthoredmeCount(res?.data?.authoredmeCount); + } + // 获取我的迭代 + async function getIteratioins() { + setPlanLoading(true); + let res:any = await dispatch({ + type:"workStand/getMyIterations", + payload:{ + pageNum:planPage,pageSize:5,statusIds:1 + } + }) + if(res?.code === 200){ + setPlanData(res?.rows); + setPlanTotal(res?.total); + } + setPlanLoading(false); + } + // 获取我的项目 + async function getProjects() { + setProjectLoading(true); + let res:any = await dispatch({ + type:"workStand/getMyProjects", + payload:{ + pageNum:projectPage,pageSize:4,status:1 + } + }) + if(res?.code === 200){ + setProjectData(res?.rows); + setProjectTotal(res?.total); + } + setProjectLoading(false); + } + // 获取我的工作项 + async function getWorkItem(page:number) { + setWorkLoading(true); + let res:any = await dispatch({ + type:"workStand/getMyWorkItem", + payload:{ + participantCategory:selectKey,page,limit:5,category:"opened",keyword:search + } + }) + if(res?.code === 200){ + setDataSource(res?.data?.issues); + setWorkTotal(res?.data?.total_count); + if(selectKey === "assignedme"){ + setAssignedmeCount(res?.data?.opened_count); + }else{ + setAuthoredmeCount(res?.data?.opened_count); + } + } + setWorkLoading(false); + } + + const columns: ColumnsType=[ + { + title: '标题', + dataIndex: 'subject', + key: 'subject', + width: '40%', + ellipsis:{ + showTitle: false + }, + render:(value:string,record:any)=>{ + return( + { + await dispatch({ + type:"project/setCurrent", + payload: { id: record?.pm_project_id } + }) + await dispatch({ + type:'project/setOpen', + payload:{ + open:false, + id:record?.id, + editOpen:true, + pmIssueType:record?.pm_issue_type, + parent:"workStand", + onOk:getWorkItem + } + }) + window.history.pushState({},"0",`/${enterIdentifier}/projects/${record?.pm_project_id}/${workItemType[record?.pm_issue_type]}/${record?.id}`) + }}>{value} + ) + } + },{ + title: '状态', + dataIndex: 'status', + key: 'status', + width: '14%', + ellipsis:{ + showTitle: false + }, + render:(value:any,record:any)=>{ + let type = record?.pm_issue_type === 1? workItemType.demand : record?.pm_issue_type === 2 ? workItemType.task :workItemType.bug; + let connectIssueStatus = workItemStatus[type]; + let text = value; + text.name = connectIssueStatus[value?.id]; + return + } + },{ + title: '优先级', + dataIndex: 'priority', + key: 'priority', + width: '15%', + ellipsis:{ + showTitle: false + }, + render:(value:any)=>{ + return
+ + { value?.name } +
+ } + },{ + title: '负责人', + dataIndex: 'assigners', + key: 'assigners', + width: '18%', + ellipsis:{ + showTitle: false + }, + render:(value:any)=>{ + let list = value.length > 0 ? value.map((i:any)=>{return i?.name}):[]; + // + return list?.length ? list.toString() :"--" + } + },{ + title: '时间', + dataIndex: 'created_at', + key: 'created_at', + ellipsis:{ + showTitle: false + }, + align:"center", + render:(value:any)=>{ + return {toTimeFormat(value)} + } + } + ] + + const planColumns:ColumnsType=[ + { + title: '标题', + dataIndex: 'sprintName', + key: 'sprintName', + ellipsis:{ + showTitle: false + }, + render:(value:string,record:any)=>{ + return( + {value} + ) + } + }, + // { + // title: '状态', + // dataIndex: 'status', + // key: 'status', + // width: '15%', + // ellipsis:{ + // showTitle: false + // }, + // render:(value:any,record:any)=>{ + // const item = iterationStatusList.find(e => e.id === +value) + // return item ? : '' + // } + // }, + { + title: '负责人', + dataIndex: 'sprintAssignee', + key: 'sprintAssignee', + width: '13%', + ellipsis:{ + showTitle: false + }, + render:(value:any)=>{ + return {value?.nickName} + } + },{ + title: '工作进度', + dataIndex: 'sprintIssuesStatistics', + key: 'sprintIssuesStatistics', + width: '25%', + ellipsis:{ + showTitle: false + }, + render:(value:any,record:any)=>{ + let closeCount = +value?.count_closed; + let totalCount = +value?.count_total; + return 工作项进度{closeCount}/{totalCount} + } + },{ + title: '工作进度', + dataIndex: 'sprintIssuesStatistics', + key: 'sprintIssuesStatistics', + width: '25%', + ellipsis:{ + showTitle: false + }, + render:(value:any,record:any)=>{ + let closeCount = +value?.hour_closed; + let totalCount = +value?.hour_total; + + return 工时容量{!(closeCount && totalCount) ? 0 :+(+(closeCount||0) / +(totalCount)).toFixed(2)*100}% + } + } + ] + + return ( +
+
+
+ {/* */} + + {currentUser?.nickName} + {getCurrentTime()}! +
+
    +
  • + +
    + {statictisData?.projectTaskCount} + 我负责的任务 +
    +
  • +
  • + +
    + {statictisData?.projectRequirementCount} + 我负责的需求 +
    +
  • +
  • + +
    + {statictisData?.projectBugCount} + 我负责的缺陷 +
    +
  • + { + statictisData?.productRequirementCount ? +
  • + +
    + {statictisData?.productRequirementCount} + 我创建的产品需求 +
    +
  • + :"" + } +
+
+
+
+ + 我的工作项 + { setSearch(e.target.value) } } + onChange={ (e:any) => { setSearch(e.target.value) } } + suffix={ } + placeholder="搜索..." + /> + {getWorkItem(workPage)}} style={{marginLeft:"auto",cursor:"pointer"}} src={require('@/assets/image/workStand/reset.png')} alt=""/> +
+ {setSelectKey(e.key)}} className={styles.menusStyle}> + 我负责的 + 我创建的 + + {setWorkPage(p);getWorkItem(p)},hideOnSinglePage:true }} + /> + + + +
+
+ + 我的项目 + {getProjects()}} style={{marginLeft:"auto",cursor:"pointer"}} src={require('@/assets/image/workStand/reset.png')} alt=""/> +
+ + { + projectData?.length > 0 ? +
+ { + projectData.map((i:any,key:number)=>{ + return( +
+
+ {i?.projectName} + +
+

工作项 {i?.projectIssuesCount}成员 {i?.projectMemberCount}

+ {i?.projectAssignee?.nickName} +
+ ) + }) + } +
+ : + } +
+ {setProjectPage(p)}}/> +
+
+
+ + +
+
+ + 进行中的迭代 + {getIteratioins()}} style={{marginLeft:"auto",cursor:"pointer"}} src={require('@/assets/image/workStand/reset.png')} alt=""/> +
+
{setPlanPage(p)},hideOnSinglePage:true }} + /> + + + + + ); +}; + +export default connect(({ enterprise , user , workStand }: { enterprise: EnterpriseModelState , user:UsersModelState , workStand:WorkStandModelState }) => ({enterprise,user,workStand}))(Index);