forgeplus-react/src/military/task/taskAdmin/index.jsx

812 lines
27 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useCallback, useEffect, useState, useMemo } from 'react';
import classNames from 'classnames';
import { Input, Select, Button, Form, DatePicker, Modal, message, Popover } from 'antd';
import { Link } from 'react-router-dom';
import moment from 'moment';
import { paperCheckStatusArr, publishModeArr, taskStatusAllArr, showUserModeArr, main_web_site_url } from '../static';
import { getTaskAdminList, changeShowUserMode, deleteTask, recommendTask, addExpertReview, publishExpertsAndRules,delayTask ,resetTask} from '../api';
import '../index.scss';
import './index.scss';
import { getRules, selectExpertList } from 'src/military/expert/api';
import PaginationTable from '../../../components/pagination-table';
import ExportTable from './exportTable';
const format = "YYYY-MM-DD HH:mm:ss";
const formatDelay = "YYYY-MM-DD";
const Option = Select.Option;
const statusArr = [];
for (const item of taskStatusAllArr) {
statusArr[item.dicItemCode] = item.dicItemName;
}
const checkStatusArr = [];
for (const item of paperCheckStatusArr) {
checkStatusArr[item.dicItemCode] = item.dicItemName;
}
// 管理端 创客任务列表
export default Form.create()(({ form, showNotification, match, history, state }) => {
const { getFieldDecorator, setFieldsValue, getFieldsValue, validateFields } = form;
const { hash} = history && history.location;
const [reload, setReload] = useState();
const [loading, setLoading] = useState(false);
const [statusString, setStatusString] = useState('');
const [publishMode, setPublishMode] = useState('');
const [showUserMode, setShowUserMode] = useState('');
const [isDelete, setIsDelete] = useState('0');
const [recommend, setRecommend] = useState('');
const [sort, setSort] = useState('Desc');
const [order, setOrder] = useState('createdAt');
const [searchObj, setSearchObj] = useState({});
const [curPage, setCurPage] = useState(hashDate(hash) || 1);
const [total, setTotal] = useState(0);
const [taskList, setTaskList] = useState([]);
const [expertReview, setExpertReview] = useState('');
const [downloading,setDownloading] = useState(false);
const [restartVisible,setRestartVisible]= useState(false); //重启任务modal
//查看评审规则、查看选取专家、发布评审任务
const [lookRules, setLookRules] = useState(false);
const [lookExperts, setLookExperts] = useState(false);
const [pulicReview, setPublicReview] = useState(false);
const [rules, setRules] = useState(undefined);
const [selectedExperts, setSelectedExperts] = useState(undefined);
const [publicTaskId, setPublicTaskId] = useState(undefined);
// 加入专家评审的创客id数组
const [reviewTaskId, setReviewTaskId] = useState(undefined);
const [visible, setVisible] = useState(false); //延期任务modal
const [checkedItem, setCheckedItem] = useState('');
useEffect(()=>{
setCurPage(hashDate(hash) || 1);
},[hash])
useEffect(() => {
const params = {
...searchObj,
statusString,
publishMode: publishMode.length > 1 ? '' : publishMode,
showUserMode: showUserMode.length > 1 ? '' : showUserMode,
curPage,
pageSize: 10,
orderBy: order + sort,
isDelete,
recommend,
expertReview: expertReview==='-1'?"":expertReview,
};
setLoading(true);
getTaskAdminList(params).then(data => {
if (data) {
let taskIds = [];
for(const item of data.rows){
item.expertReview && (taskIds[taskIds.length] = item.id)
}
setReviewTaskId(taskIds.toString());
setTaskList(data.rows);
setTotal(data.total);
}
setLoading(false);
})
}, [statusString, order, sort, publishMode, showUserMode, curPage, searchObj, isDelete, reload, recommend, expertReview]);
const helper = useCallback(
(label, name, rules, widget, initialValue) => (
<Form.Item label={label}>
{getFieldDecorator(name, { rules, initialValue, validateFirst: true, })(widget)}
</Form.Item>
), []);
function hashDate(hash) {
return parseInt(hash.split("&")[0].substring(hash.split("&")[0].indexOf("=")+1));
}
function onSearch() {
let values = getFieldsValue(['nameInput', 'endTime', 'startTime', 'enterpriseNameInput']);
if (values.startTime) values.startTime = values.startTime.format(format);
if (values.endTime) values.endTime = values.endTime.format(format);
if (values.checkStatus === '0,1,2') values.checkStatus = '';
setSearchObj(values);
setCurPage1(1);
// window.location.href=`/task/taskAdmin`;
}
function clearSearch() {
setFieldsValue({
startTime: '',
endTime: '',
nameInput: '',
enterpriseNameInput: '',
taskMode: '0,1,2,3,4,5,6,7,8,9',
showUserMode: '0,1,2',
publishMode1: '0,1',
expertReviewStatus: '-1',
showStatus: '0',
isRecommend: 'all',
sortBy: 'createdAt'
});
setStatusString('0,1,2,3,4,5,6,7,8,9');
setShowUserMode('0,1,2');
setPublishMode('0,1');
setExpertReview('-1');
setIsDelete('0');
setRecommend('');
setOrder("createdAt");
setSearchObj({});
}
function delayClick(item,restart) {
setCheckedItem(item);
if(restart){
setVisible(true);
}else{
setRestartVisible(true);
}
}
const columns = useMemo(() => {
return [
{
title: '任务编号',
dataIndex: 'number',
width: "26%"
},
{
title: '任务名称',
dataIndex: 'name',
width: "10%",
render: (text, record) => (
<Popover content = {
<div className='taskPopover'>
<p><span>任务名称:</span>{text}</p>
<p className='mt5'><span>截稿时间:</span>{record.collectingEndTime && record.collectingEndTime.replaceAll('-','/').substring(0,16) || '--'}</p>
<p className='mt5'><span>稿件数:</span>{record.papersCount || '--'}</p>
</div>
}>
<Link className="line_1 primary-link" target="_blank" to={`/task/taskDetail/${record.id}`} >{text}</Link>
</Popover>
),
},
{
title: '发布主体',
dataIndex: 'enterpriseName',
},
{
title: '发布时间',
dataIndex: 'publishedAt',
width: "8%",
render: (text, record) => {
text = text && text.replaceAll('-','/').substring(0,16);
return text || '--'
}
},
{
title: '发布方式',
dataIndex: 'publishMode',
render: (text, record) => {
return <span className={`publishMode mode${text}`}>{publishModeArr[text]}</span>
}
},
{
title: '任务状态',
dataIndex: 'status',
render: (text, record) => {
return record.exceptClosedBoolean ? '已关闭' : statusArr[text]
}
},
{
title: '应征者公示',
dataIndex: 'showUserMode',
render: (text, record) => {
return <Select
className="column-select"
showArrow
placeholder="请选择审核状态"
defaultValue={text}
onChange={(key) => { changeStatus(key, record.id) }}
>
{
showUserModeArr.map(item => {
return <Option key={item.dicItemCode} value={item.dicItemCode}>{item.dicItemName}</Option>
})
}
</Select>
}
},
{
title: '操作',
key: 'action',
dataIndex: 'expertReview',
align: 'center',
render: (text, record) => {
const disabled = record.assignRuleAndExperts || !(record.status == 1 || record.status == 3);
return(
<React.Fragment>
{[3,4,6,7].includes(record.status)&&<Button className="mr5 mb5 f89" onClick={() => { delayClick(record,true) }}>延期</Button>}
{record.status==8&& record.exceptClosedBoolean&&<Button className="mr5 mb5 f89" onClick={() => { delayClick(record)}}>重启</Button>}
<Button className="mr5 mb5 f20" onClick={() => { deleteItem(record.id,isDelete == '0' ? '1':'0') }}>{isDelete == '0' ? '隐藏任务':'恢复任务'}</Button>
<Button className="mr5 mb5 f89" onClick={() => { recommendItem(record.id, record.recommend ? '0' :'1') }}>{record.recommend ? '撤销推荐':'首页推荐'}</Button>
<Button className={`mr5 mb5 c2a3 ${text ? 'bor':'full'} ${disabled && 'disabled'}`} onClick={() => { changeExpertReviewStatus(text ? '-1':'1', record.id) }} disabled={disabled}>{text ? '取消专家评审':'加入专家评审'}</Button>
{/* {
isDelete == '0' ? <Button className="mr5 font-12" type="danger" size="small" onClick={() => { deleteItem(record.id, '1') }}>隐藏任务</Button>
: <Button className="mr5 font-12" type="primary" size="small" onClick={() => { deleteItem(record.id, '0') }}>恢复任务</Button>
}
{
!record.recommend && [3, 4, 5, 6, 7, 8].includes(record.status) && <Button className="mr5 font-12" type="primary" size="small" onClick={() => { recommendItem(record.id, '1') }}>首页推荐</Button>
}
{
record.recommend && <Button className="mr5 font-12" type="danger" size="small" onClick={() => { recommendItem(record.id, '0') }}>撤销推荐</Button>
} */}
{/* <Link className="line_1 color-grey3" to={`/task/taskDetail/${record.taskId}`}>查看</Link> */}
</React.Fragment>
)},
},
]
}, [isDelete, curPage]);
//已选取专家
const columnsExperts = useMemo(() => {
return [
{
title: '编号',
dataIndex: 'index',
width: 80,
align: 'center',
},
{
title: '专家姓名',
dataIndex: 'expertName',
key: 'expertName',
width: 120,
},
{
title: '手机号码',
dataIndex: 'phone',
width: 130,
key: 'phone',
},
{
title: '最高学历',
dataIndex: 'highestDegree',
key: 'highestDegree',
},
{
title: '专业职称',
dataIndex: 'professionalTitle',
},
{
title: '专家类别',
dataIndex: 'expertType',
},
{
title: '评审领域',
dataIndex: 'reviewAreas',
align: 'center',
width: 260,
},
{
title: '专家评估',
dataIndex: 'expertScore',
align: 'center',
render:(text,record)=>{
return record.expertScore || '--';
}
}
];
}, []);
// function resetTaskModal
function recommendItem(id, recommend) {
Modal.confirm({
title: "警告",
content: recommend == '0' ? "确认撤销该推荐吗 ?撤销后首页中将不再展示该任务" : "确认推荐吗?推荐后,用户可以在首页看到推荐任务中点击量前三的任务!",
okText: '确定',
cancelText: '取消',
onOk() {
recommendTask(id, recommend).then(res => {
if (res.message === 'success') {
showNotification('操作成功!');
setReload(Math.random());
}
});
},
});
}
function deleteItem(id, isDelete) {
Modal.confirm({
title: "警告",
content: isDelete == '0' ? "确认恢复该任务吗?恢复后用户可以重新看到该任务!" : "确认隐藏?隐藏后用户无法看到该任务!",
okText: '确定',
cancelText: '取消',
onOk() {
deleteTask(id, isDelete).then(res => {
if (res.message === 'success') {
showNotification('操作成功!');
setReload(Math.random());
}
});
},
});
}
//监听lookRules,lookExperts,pulicReview的变化弹框
useEffect(()=>{
//评审规则
lookRules && rules && Modal.info({
className: 'publishReview',
title: "评审规则",
content:
<React.Fragment>
<div>{rules && rules.rule}</div>
<p>评分标准</p>
<div>
{rules.criterias.map(item=>{return <p key={Math.random()}>{item}</p>})}
</div>
<p>评审时间</p>
<div>{rules.reviewData}</div>
</React.Fragment>
,
});
lookRules && setLookRules(false);
//已选取评审专家
lookExperts && selectedExperts && Modal.info({
className: 'publishReview',
title: "已选取评审专家",
content:
<PaginationTable
dataSource={selectedExperts}
columns={columnsExperts}
scroll={{ y: 395 }}/>,
});
lookExperts && setLookExperts(false);
//发布评审任务
pulicReview && rules && selectedExperts && Modal.confirm({
className: 'publishReview',
title: "发布评审任务",
centered: true,
content:
<React.Fragment>
<div className='tip'>
<i className='iconfont icon-erciqueren_icon'></i>
<span className='publicTitle'>确定发布此评审任务?确定发布后评审规则与评审专家信息将无法重新编辑</span>
</div>
<p>评审规则</p>
<div>{rules && rules.rule}</div>
<p>评分标准</p>
<div>
{rules.criterias.map(item=>{return <p key={Math.random()}>{item}</p>})}
</div>
<p>评审时间</p>
<div>{rules.reviewData}</div>
<p>已选取评审专家</p>
<PaginationTable
dataSource={selectedExperts}
columns={columnsExperts}
scroll={{ y: 230 }}/>
</React.Fragment>
,
okText: '确定',
cancelText: '取消',
onOk() {
publishExpertsAndRules(publicTaskId,1).then(response=>{
if(response && response.message==="发布成功"){
setReload(Math.random());
}
})
},
});
pulicReview && setPublicReview(false);
},[lookRules,lookExperts,pulicReview])
//发布评审任务
function publishTaskReview(record){
if(!record.ruleEditedCount || !record.expertSelectedCount){
message.error("请先编辑评审规则以及选取评选专家再发布此任务");
}else{
getRules({containerId: record.id, containerType: 1, statusString: 3}).then(response=>{
if(response && response.message === "success"){
setRules(response.data);
}
})
selectExpertList({containerId: record.id, containerType: 1, curPage:curPage, pageSize: 10000, curPage: 1,}).then(response=>{
if(response && response.message === "success" && Array.isArray(response.data.rows)){
let index = 1;
for (const item of response.data.rows) {
item.reviewAreas = `${item.reviewAreaOne} ${item.reviewAreaTwo ? `、${item.reviewAreaTwo}`:''} ${item.reviewAreaThree ? `、${item.reviewAreaThree}`:''}`;
item.index = (index++) + (curPage > 1 ? (curPage - 1) * 10 : 0);
}
setPublicTaskId(record.id);
setSelectedExperts(response.data.rows);
setPublicReview(true);
}
});
}
}
//已发布任务 查看评审规则
function viewRules(record){
getRules({containerId: record.id, containerType: 1, statusString: '-1,1,2'}).then(response=>{
if(response && response.message === "success"){
setRules(response.data);
setLookRules(true);
}
});
}
//已发布任务 查看已选专家
function viewExperts(record){
selectExpertList({containerId: record.id, containerType: 1, curPage:curPage, pageSize: 10000, curPage: 1,}).then(response=>{
if(response && response.message === "success" && Array.isArray(response.data.rows)){
let index = 1;
for (const item of response.data.rows) {
item.reviewAreas = `${item.reviewAreaOne} ${item.reviewAreaTwo ? `、${item.reviewAreaTwo}`:''} ${item.reviewAreaThree ? `、${item.reviewAreaThree}`:''}`;
item.index = (index++) + (curPage > 1 ? (curPage - 1) * 10 : 0);
}
setSelectedExperts(response.data.rows);
setLookExperts(true);
}
});
}
function changeStatus(showUserMode, taskId) {
changeShowUserMode({
taskId,
showUserMode
}).then(res => {
if (res && res.message === 'success') {
showNotification('修改成功!');
}
})
}
function changeExpertReviewStatus(expertReviewStatus, taskId) {
addExpertReview(taskId,expertReviewStatus).then(res => {
if (res && res.message === 'success') {
showNotification('操作成功!');
setReload(Math.random());
} else {
showNotification('操作失败');
}
})
}
function setCurPage1(page){
setCurPage(page);
window.location.href=`/managements/task/taskAdmin#page=${page}`;
}
// 改变排序字段
const changeSortName = useCallback((sortType) => {
setOrder(sortType);
setCurPage1(1);
}, []);
// 改变排序
const changeSort = useCallback((sort) => {
setSort(sort);
setCurPage1(1);
}, []);
const changeShow = useCallback((isDelete) => {
setIsDelete(isDelete);
setCurPage1(1);
});
const changeRecommend = useCallback((recommend) => {
if (recommend === 'all') {
setRecommend('');
} else {
setRecommend(recommend);
}
setCurPage1(1);
});
const ExpertDetail = (record)=>{
const unDisabled = record.expertReview && (record.status === 1 || record.status === 3);
return <div className="expert_detail_div">
<div> 专家评审信息: </div>
<div> 评审规则 {record.assignRuleAndExperts ? <Button className='c2a3 bor' onClick={()=>{viewRules(record)}}>查看</Button> : unDisabled ? <Button className="c2a3 bor" href={`/managements/expert/task/review/rules/${1}/${record.id}/?status=${record.status}&name=${record.name}&createdAt=${record.createdAt}&collectingEndTime=${record.collectingEndTime}&choosingDays=${record.choosingDays}`}>编辑</Button> : <Button className='c2a3 disabled'>编辑</Button>}</div>
<div> 专家选取 {record.assignRuleAndExperts ? <Button className='c2a3 bor' onClick={()=>{viewExperts(record)}}>查看</Button> : unDisabled ? <Button className="c2a3 bor" href={`/managements/expert/task/review/select/${1}/${record.id}/?name=${record.name}`}>选择</Button> : <Button className='c2a3 disabled'>选择</Button>}</div>
<div> 评审任务 {record.assignRuleAndExperts ? <Button className='c2a3 disabled'>已发布</Button> : unDisabled ? <Button className='c2a3 full' onClick={()=>{publishTaskReview(record)}}>发布</Button> : <Button className='c2a3 disabled'>发布</Button>}</div>
<div> 评审结果 {record.assignRuleAndExperts ? <Button className="c2a3 bor" href={`/managements/expert/task/review/results/${1}/${record.id}/#status=${record.status}&name=${record.name}&taskModeId=${record.taskModeId}`}>查看</Button>:<Button className='c2a3 disabled'>查看</Button>}</div>
</div>
}
function downloadFile() {
window.open(main_web_site_url + '/admin/tasks.xlsx');
}
function disabledDate(current) {
return current && current < moment(checkedItem.eachPhaseEndTime).endOf('day');
}
function disabledDate2(current) {
return current && current < moment();
}
function delayTime() {
validateFields(['delayedTo'],(err, values) => {
if (!err) {
delayTask({
taskId: checkedItem.id,
params: {
delayedTo: moment(values.delayedTo).format(formatDelay)
},
}).then(res => {
if (res && res.message === 'success') {
showNotification('操作成功');
setReload(Math.random());
setVisible(false);
}
});
}
});
}
function restartTask(){
validateFields(["restartEndTime"],(err, values) => {
if (!err) {
resetTask({
taskId: checkedItem.id,
endTime: moment(values.restartEndTime).format(format)
}).then(res => {
if (res && res.message === 'success') {
showNotification('操作成功');
setReload(Math.random());
setRestartVisible(false);
}
});
}
});
}
return (
<div className="task-manage-all ">
<div className='management-content-head'>
<p className='font-18'>创客任务列表</p>
<div className="search-task" >
{helper(
"任务名称",
"nameInput",
[{ max: 20, message: '长度不能超过20个字符' }],
<Input
placeholder="输入任务名称进行检索"
/>
)}
{helper(
"发布主体名称",
"enterpriseNameInput",
[{ max: 20, message: '长度不能超过20个字符' }],
<Input
placeholder="输入发布主体名称进行检索"
/>
)}
<div className="center-right-but time">
{helper(
"发布时间:",
"startTime",
[],
<DatePicker
showTime
format={format}
placeholder="请选择开始时间"
/>
)}
{helper(
"",
"endTime",
[],
<DatePicker
showTime
format={format}
placeholder="请选择结束时间"
/>
)}
</div>
{helper(
"任务状态",
"taskMode",
[],
<Select
className="column-select"
showArrow
onChange={(value)=>{setStatusString(value);setCurPage1(1);}}
>
<Option key={'0,1,2,3,4,5,6,7,8,9'} >全部</Option>
{
taskStatusAllArr.map(item => {
return <Option key={item.dicItemCode} >{item.dicItemName}</Option>
})
}
</Select>,
'0,1,2,3,4,5,6,7,8,9'
)}
{helper(
"应征者公示",
"showUserMode",
[],
<Select
className="column-select"
showArrow
placeholder="请选择审核状态"
onChange={(value)=>{setShowUserMode(value);setCurPage1(1);}}
>
<Option key={'0,1,2'}>全部</Option>
{
showUserModeArr.map(item => {
return <Option key={item.dicItemCode}>{item.dicItemName}</Option>
})
}
</Select>,
'0,1,2'
)}
{helper(
"发布方式",
"publishMode1",
[],
<Select
className="column-select"
showArrow
onChange={(value)=>{setPublishMode(value);setCurPage1(1);}}
>
<Option key={'0,1'} >全部</Option>
<Option key={'0'} >自主提交</Option>
<Option key={'1'} >统筹任务</Option>
</Select>,
'0,1'
)}
{helper(
"专家评审状态",
"expertReviewStatus",
[],
<Select
className="column-select"
showArrow
onChange={(value)=>{setExpertReview(value);setCurPage1(1);}}
>
<Option key={'-1'} >全部</Option>
<Option key={'1'} >已提交评审</Option>
<Option key={'0'} >未提交评审</Option>
</Select>,
'-1'
)}
{/* <div className='center-right-but search'> */}
{helper(
"显示状态",
"showStatus",
[],
<Select
className="column-select"
showArrow
onChange={changeShow}
>
<Option key={'0'} >正常显示</Option>
<Option key={'1'} >已隐藏</Option>
</Select>,
'0'
)}
{helper(
"是否推荐",
"isRecommend",
[],
<Select
className="column-select"
showArrow
onChange={changeRecommend}
>
<Option key={'all'} >不限</Option>
<Option key={'0'} >未推荐</Option>
<Option key={'1'} >已推荐</Option>
</Select>,
'all'
)}
{helper(
"排序",
"sortBy",
[],
<Select
className="column-select"
showArrow
onChange={changeSortName}
>
<Option key={'createdAt'} >创建时间</Option>
<Option key={'publishedAt'} >发布时间</Option>
</Select>,
'createdAt'
)}
<div className="button-div">
{/* <a href="/admin/tasks.xlsx" class="fr edu-default-btn edu-blueback-btn plr30">导出</a> downloadFile*/}
<Button className="mr10" type="primary" onClick={onSearch}>搜索</Button>
<Button className="mr10" onClick={clearSearch}>清除</Button>
<Button loading={downloading} className="mr10" type="primary" onClick={()=>{setDownloading(true)}}>导出</Button>
</div>
<span className={classNames({ "sort-active": sort === 'Desc', 'sort-icon': true, 'mt5': true })} onClick={() => { changeSort('Desc') }}>
<i className="fa fa-long-arrow-down font-16 "></i>
</span>
<span className={classNames({ "sort-active": sort === 'Asc', 'sort-icon': true, 'mt5': true })} onClick={() => { changeSort('Asc') }}>
<i className="fa fa-long-arrow-up font-16 "></i>
</span>
{/* </div> */}
</div>
</div>
<div className="center-content taskListCont">
<PaginationTable
loading={loading}
rowKey={(row) => row.id}
dataSource={taskList}
columns={columns}
total={total}
current={curPage}
setCurPage={(page)=>{setCurPage1(page)}}
className="expertReviewTable"
expandedRowRender={ExpertDetail}
expandedRowKeys={reviewTaskId}
/>
</div>
<Modal
title="请输入延期截止的具体时间"
visible={visible}
onOk={delayTime}
onCancel={() => { setVisible(false) }}
className="time-edit-modal"
destroyOnClose
>
{helper(
"",
"delayedTo",
[{ required: true, message: "请选择日期" }],
<DatePicker
format={formatDelay}
placeholder="请选择日期"
disabledDate={disabledDate}
/>,
null
)}
</Modal>
<Modal
title="重启任务"
visible={restartVisible}
onOk={restartTask}
onCancel={() => { setRestartVisible(false) }}
// className="time-edit-modal"
destroyOnClose
>
<div>当前任务将恢复至<span className="imoptantText">{statusArr[checkedItem.currentStatus]}</span>,请选择该阶段的截止日期:</div>
{helper(
"",
"restartEndTime",
[{ required: true, message: "请选择时间" }],
<DatePicker
format={format}
placeholder="请选择时间"
disabledDate={disabledDate2}
/>,
moment(moment(new Date()).format(formatDelay)+' 23:59:59')
)}
</Modal>
<ExportTable downloading={downloading} setDownloading={setDownloading}/>
</div>
)
}
)