forked from Gitlink/forgeplus-react
上传创客新增任务及列表代码
This commit is contained in:
parent
6156d98af2
commit
97bc41e771
|
@ -16,10 +16,10 @@ export default (props) => {
|
|||
<div className="shop-box">
|
||||
<div className="choose-title">{title}</div>
|
||||
<div className="choose-list">
|
||||
<div className={classNames({ "choose-item-checked": option.code === "", "choose-item": true })} key={"all"} onClick={() => { setOption({ code: "", dicItemName: "" }) }}>全部</div>
|
||||
<div className={classNames({ "choose-item-checked": option.dicItemCode === "", "choose-item": true })} key={"all"} onClick={() => { setOption({ dicItemCode: "", dicItemName: "" }) }}>全部</div>
|
||||
{
|
||||
options.map((item) => {
|
||||
return <div className={classNames({ "choose-item-checked": option.code === item.code, "choose-item": true })} key={item.dicItemName} onClick={() => { setOption(item) }} >{item.dicItemName}</div>
|
||||
return <div className={classNames({ "choose-item-checked": option.dicItemCode === item.dicItemCode, "choose-item": true })} key={item.dicItemCode} onClick={() => { setOption(item) }} >{item.dicItemName}</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -1,21 +1,56 @@
|
|||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Icon, Pagination } from 'antd';
|
||||
import Nodata from '../../../forge/Nodata';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const statusArr = ["草稿", "待审核", "已拒绝", "成果征集中", "成果评选中", "公示中", "协议签订中", "支付中", "已完成"];
|
||||
const classArr = ['', 'list-done', 'list-error', 'list-red', 'list-yellow', '', '', 'list-pay', 'list-gray',];
|
||||
export default (props) => {
|
||||
const { list, itemClick, } = props;
|
||||
const { list, itemClick, curPage, total, changePage } = props;
|
||||
const [page, setPage] = useState(1);
|
||||
useEffect(() => {
|
||||
changePage(page);
|
||||
}, [page]);
|
||||
|
||||
return (
|
||||
list.map(item => {
|
||||
return (
|
||||
<div className="list-box" key={item.id}>
|
||||
<div className="list-title" onClick={() => { itemClick(item.id) }}>
|
||||
{item.achievementName || item.title}
|
||||
</div>
|
||||
<div className="list-other">
|
||||
{item.publisher && <p>发布单位:{item.publisher}</p>}
|
||||
<p>发布时间:{item.publishDate || item.createTime}</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
<React.Fragment>
|
||||
{
|
||||
list.map(item => {
|
||||
return (
|
||||
<div className="list-box" key={item.id}>
|
||||
<div className="list-content">
|
||||
<div className="list-title mb10" onClick={() => { itemClick(item.id) }}>
|
||||
{item.name || item.title}
|
||||
{item.status && <span className={classArr[item.status]}>{statusArr[item.status]}</span>}
|
||||
</div>
|
||||
<div className="list-other">
|
||||
<span className=" mr30"><i className="iconfont icon-dianjiliang mr3 font-12" />{item.visits}</span>
|
||||
<span className=" mr30"><Icon type="user" /><span className="color-orange">{item.papersCount}</span>人参与</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span className="price color-deep-blue ">
|
||||
<span className="font-16">¥</span>
|
||||
<span className="font-24">{item.bounty}</span>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
{list.length > 0 ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
<Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { setPage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>
|
||||
</div> :
|
||||
<Nodata _html="暂无数据" />}
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
|
@ -1,70 +1,60 @@
|
|||
.list-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
margin: 0 1.5rem;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #dedede;
|
||||
}
|
||||
.price {
|
||||
font-weight: 500;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.list-title {
|
||||
font-size: 17px;
|
||||
color: #000;
|
||||
font-size: 1rem;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
}
|
||||
.list-title:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
.list-title span {
|
||||
padding: 3px 5px;
|
||||
margin-left:.5em;
|
||||
padding: 2px 10px;
|
||||
margin-left: 0.5em;
|
||||
background: #f8c753;
|
||||
font-size: 13px;
|
||||
color: #fff;
|
||||
border-radius: 3px;
|
||||
border-radius: 14px;
|
||||
}
|
||||
span.list-yellow {
|
||||
background: #fa6400;
|
||||
}
|
||||
span.list-red {
|
||||
background: #fe0e36;
|
||||
}
|
||||
span.list-orange {
|
||||
background: #ffb121;
|
||||
}
|
||||
span.list-done {
|
||||
background: #35d77e;
|
||||
}
|
||||
span.list-pay {
|
||||
background: #1ad757;
|
||||
}
|
||||
span.list-error {
|
||||
background: #f56c6c;
|
||||
}
|
||||
|
||||
.list-tag {
|
||||
display: inline-block;
|
||||
margin: 5px 10px 5px 0;
|
||||
background: #cfe9ff;
|
||||
color: #0089ff;
|
||||
font-size: 14px;
|
||||
border-radius: 3px;
|
||||
padding: 2px 5px;
|
||||
span.list-gray {
|
||||
background: #bababa;
|
||||
}
|
||||
.list-other > p {
|
||||
display: inline-block;
|
||||
margin: 0 10px 0 0;
|
||||
|
||||
.list-other {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.list-box-action {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 100px;
|
||||
visibility: hidden;
|
||||
}
|
||||
.list-box:hover .list-box-action {
|
||||
visibility: visible;
|
||||
}
|
||||
.list-box-action button {
|
||||
display: inline-block;
|
||||
margin: 0 25px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
color: #0089ff;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
border: 0;
|
||||
border-radius: 25px;
|
||||
box-shadow: 2px 2px 5px 2px #eee;
|
||||
cursor: pointer;
|
||||
color: #888;
|
||||
i {
|
||||
font-size: 14px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ export default (props) => {
|
|||
const { options, changeOptionId, type, defaultValue } = props;
|
||||
|
||||
const [myOptions, setMyOptions] = useState(options);
|
||||
const [option, setOption] = useState(defaultValue || { name: "", type: "" });
|
||||
const [option, setOption] = useState(defaultValue);
|
||||
|
||||
useEffect(() => {
|
||||
changeOptionId(option, type);
|
||||
|
@ -16,11 +16,11 @@ export default (props) => {
|
|||
function itemClick(activeItem) {
|
||||
const newOption = {
|
||||
...activeItem,
|
||||
value: !activeItem.value
|
||||
desc: !activeItem.desc
|
||||
};
|
||||
for(const item of myOptions){
|
||||
if(item.type===activeItem.type){
|
||||
item.value=newOption.value;
|
||||
item.desc=newOption.desc;
|
||||
}
|
||||
}
|
||||
setOption(newOption);
|
||||
|
@ -36,8 +36,8 @@ export default (props) => {
|
|||
{item.name}
|
||||
{
|
||||
item.icon && <span className="caret-up-down">
|
||||
<Icon type="caret-up" className={classNames({ "caret-checked": !item.value })} />
|
||||
<Icon type="caret-down" className={classNames({ "caret-checked": item.value })} />
|
||||
<Icon type="caret-up" className={classNames({ "caret-checked": !item.desc })} />
|
||||
<Icon type="caret-down" className={classNames({ "caret-checked": item.desc })} />
|
||||
</span>}
|
||||
</div>
|
||||
})
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import './index.scss';
|
||||
|
||||
export default (props) => {
|
||||
const { title, options, changeOptionId, type } = props;
|
||||
|
||||
const [option, setOption] = useState({ code: "", dicItemName: "" ,dicItemCode:""});
|
||||
|
||||
useEffect(() => {
|
||||
changeOptionId(option, type);
|
||||
}, [option])
|
||||
|
||||
return (
|
||||
|
||||
<div className="status-list">
|
||||
<div className={classNames({ "status-item-checked": option.dicItemCode === "", "status-item": true })} key={"all"} onClick={() => { setOption({ dicItemCode: "", dicItemName: "" }) }}>全部</div>
|
||||
{
|
||||
options.map((item) => {
|
||||
return <div className={classNames({ "status-item-checked": option.dicItemCode === item.dicItemCode, "status-item": true })} key={item.dicItemCode} onClick={() => { setOption(item) }} >{item.dicItemName}</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
.status-list {
|
||||
padding: 1rem 1.8rem;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
}
|
||||
.status-item {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
padding: 3px 15px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: #4cacff;
|
||||
}
|
||||
}
|
||||
|
||||
.status-item-checked {
|
||||
background: #f7f7f7;
|
||||
color: #4cacff ;
|
||||
}
|
|
@ -26,7 +26,6 @@ const service = axios.create({
|
|||
timeout: 5000 // 请求超时时间
|
||||
});
|
||||
|
||||
|
||||
// request拦截器
|
||||
service.interceptors.request.use(config => {
|
||||
if (cookie.load(TokenKey)) {
|
||||
|
@ -45,7 +44,7 @@ service.interceptors.response.use(
|
|||
if (res.status === 400) {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: '请求错误',
|
||||
description: '验证失败',
|
||||
});
|
||||
return Promise.reject('error');
|
||||
}
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
// 本模块公共样式
|
||||
|
||||
.color-grey3{
|
||||
color: #333;
|
||||
}
|
||||
.color-grey9{
|
||||
color: #999;
|
||||
}
|
||||
.color-orange {
|
||||
color: #ff6800;
|
||||
}
|
||||
.color-deep-blue{
|
||||
color:#1B8FFF;
|
||||
}
|
||||
.centerbox {
|
||||
width: 1200px;
|
||||
margin: 40px auto;
|
||||
|
@ -18,6 +29,7 @@
|
|||
width: 80vw;
|
||||
max-width: 1280px;
|
||||
margin: 40px auto;
|
||||
position: relative;
|
||||
}
|
||||
.center-content {
|
||||
background: #fff;
|
||||
|
@ -61,6 +73,24 @@
|
|||
color: #fff;
|
||||
}
|
||||
|
||||
.head-navigation {
|
||||
position: absolute;
|
||||
top: -2.3em;
|
||||
a:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
// 内容标题左侧样式
|
||||
.center-left-but {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
margin-left: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
// 内容标题右侧样式
|
||||
.center-right-but {
|
||||
display: flex;
|
||||
|
@ -73,18 +103,6 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
// 通用标签样式
|
||||
.list-tag {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
background: #cfe9ff;
|
||||
color: #0089ff;
|
||||
font-size: 14px;
|
||||
border-radius: 3px;
|
||||
padding: 2px 5px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
// 文件预览modal样式
|
||||
.file-modal {
|
||||
width: 800px !important;
|
||||
|
@ -112,6 +130,7 @@
|
|||
max-width: 500px;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
.link{
|
||||
color: #0089ff;
|
||||
cursor: pointer;
|
||||
|
@ -130,6 +149,9 @@
|
|||
}
|
||||
|
||||
.none_panels{
|
||||
=======
|
||||
.none_panels {
|
||||
>>>>>>> 2ed7e0d... 上传创客新增任务及列表代码
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
@ -137,8 +159,7 @@
|
|||
height: 40vh;
|
||||
}
|
||||
|
||||
|
||||
.newFooter .footerInfos>ul {
|
||||
.newFooter .footerInfos > ul {
|
||||
padding: 0 40px;
|
||||
box-sizing: border-box;
|
||||
max-width: 25%;
|
||||
|
|
|
@ -25,6 +25,10 @@ const TaskAdd = Loadable({
|
|||
loading: Loading,
|
||||
});
|
||||
|
||||
const MyTask = Loadable({
|
||||
loader: () => import("./task/myTask"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
class Index extends Component {
|
||||
render() {
|
||||
|
@ -46,6 +50,13 @@ class Index extends Component {
|
|||
)}
|
||||
></Route>
|
||||
|
||||
<Route
|
||||
path="/task/myTask"
|
||||
render={(props) => (
|
||||
<MyTask {...this.props} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
<Route
|
||||
path="/task"
|
||||
render={(props) => (
|
||||
|
|
|
@ -9,14 +9,47 @@ export function getDictionary(id) {
|
|||
});
|
||||
}
|
||||
|
||||
// 获取任务领域
|
||||
export async function getTaskCategory() {
|
||||
let res = await fetch({
|
||||
url: '/api/taskCategory/getTaskCategory',
|
||||
method: 'get',
|
||||
});
|
||||
if (Array.isArray(res.data.rows)) {
|
||||
return res.data.rows;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 列表查询
|
||||
export async function getTaskList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/announcements/',
|
||||
url: '/api/tasks/',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.code === '1') {
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 我的列表查询
|
||||
export async function getMyTaskList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/myTasks/',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
|
@ -30,7 +63,7 @@ export async function getTaskList(params) {
|
|||
// 详情查询
|
||||
export async function getTaskDetail(id) {
|
||||
let res = await fetch({
|
||||
url: '/api/announcements/' + id,
|
||||
url: '/api/tasks/' + id,
|
||||
method: 'get',
|
||||
});
|
||||
if (res.code === '1') {
|
||||
|
@ -46,7 +79,7 @@ export async function getTaskDetail(id) {
|
|||
//新增公告
|
||||
export function addTask(data) {
|
||||
return fetch({
|
||||
url: '/api/announcements/add',
|
||||
url: '/api/tasks/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
|
@ -55,7 +88,7 @@ export function addTask(data) {
|
|||
//删除
|
||||
export function deleteTask(id) {
|
||||
return fetch({
|
||||
url: '/api/announcements/' + id,
|
||||
url: '/api/tasks/' + id,
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
|
@ -63,7 +96,7 @@ export function deleteTask(id) {
|
|||
//更新
|
||||
export function editTask(data) {
|
||||
return fetch({
|
||||
url: '/api/announcements/update',
|
||||
url: '/api/tasks/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Tabs, Pagination, Input, Button } from 'antd';
|
||||
import moment from 'moment';
|
||||
import StatusNav from '../../components/statusNav';
|
||||
import SortBox from '../../components/sortBox';
|
||||
import ItemListTask from '../../components/itemListTask';
|
||||
import Nodata from '../../../forge/Nodata';
|
||||
import { taskTimeArr, taskStatusArr, taskStatusAllArr, sortArr, taskModeIdArr } from '../static';
|
||||
import { getTaskList, getTaskCategory } from '../api';
|
||||
import './index.scss';
|
||||
const Search = Input.Search;
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
const publishStatusArr = taskStatusAllArr.slice(3);
|
||||
const unpublishStatusArr = taskStatusAllArr.slice(0, 3);
|
||||
|
||||
|
||||
export default ({ history, current_user }) => {
|
||||
const [identity, setIdentity] = useState('1');
|
||||
const [type, setType] = useState('1');
|
||||
|
||||
const [status, setStatus] = useState('');
|
||||
const [searchInput, setSearchInput] = useState('');
|
||||
const [orderBy, setOrderBy] = useState('');
|
||||
const [curPage, setCurPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [taskList, setTaskList] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
const params = {
|
||||
status,
|
||||
searchInput,
|
||||
orderBy,
|
||||
curPage,
|
||||
pageSize: 10,
|
||||
};
|
||||
|
||||
getTaskList(params).then(data => {
|
||||
if (data) {
|
||||
setTaskList(data.rows);
|
||||
setTotal(data.total);
|
||||
}
|
||||
})
|
||||
}, [status, searchInput, orderBy, curPage]);
|
||||
|
||||
|
||||
function taskClick(id) {
|
||||
history.push(`/task/taskDetail/${id}`);
|
||||
}
|
||||
|
||||
function goAdd() {
|
||||
history.push("/task/taskAdd");
|
||||
}
|
||||
|
||||
function changeOptionId(option, type) {
|
||||
if(type==='publishStatus'){
|
||||
setStatus(option.dicItemCode);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
<div className="centerbox my-task">
|
||||
<Tabs defaultActiveKey={identity} onChange={(key) => { setIdentity(key) }}>
|
||||
<TabPane tab="我是雇主" key="1">
|
||||
<Tabs className="childTab" defaultActiveKey={type} onChange={(key) => { setType(key) }}>
|
||||
<TabPane tab="我发布的需求" key="1">
|
||||
<StatusNav
|
||||
key={'publishStatus'}
|
||||
type={'publishStatus'}
|
||||
options={publishStatusArr}
|
||||
changeOptionId={changeOptionId}
|
||||
/>
|
||||
|
||||
<ItemListTask
|
||||
list={taskList}
|
||||
itemClick={taskClick}
|
||||
curPage={curPage}
|
||||
total={total}
|
||||
changePage={(page) => { setCurPage(page) }}
|
||||
/>
|
||||
</TabPane>
|
||||
<TabPane tab="需求草稿" key="2">
|
||||
<StatusNav
|
||||
key={'unpublishStatus'}
|
||||
type={'unpublishStatus'}
|
||||
options={unpublishStatusArr}
|
||||
changeOptionId={changeOptionId}
|
||||
/>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</TabPane>
|
||||
|
||||
|
||||
<TabPane tab="我是创客" key="2">
|
||||
|
||||
</TabPane>
|
||||
|
||||
</Tabs>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
.my-task {
|
||||
margin-top: 1.25rem;
|
||||
.ant-tabs-top-bar {
|
||||
background: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
.ant-tabs-tab{
|
||||
height: 4.5rem;
|
||||
line-height: 3rem;
|
||||
font-size: 1.15rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.childTab{
|
||||
background: #fff;
|
||||
.ant-tabs-top-bar {
|
||||
background: #fff;
|
||||
text-align: left;
|
||||
}
|
||||
.ant-tabs-tab{
|
||||
height: 4.5rem;
|
||||
line-height: 3rem;
|
||||
font-size: 1rem;
|
||||
font-weight: normal;
|
||||
}
|
||||
.ant-tabs-ink-bar{
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,91 @@
|
|||
// 公告开始
|
||||
export const taskStatus = [
|
||||
{ code: 0, name: "关闭", dicItemName: '关闭' },
|
||||
{ code: 1, name: "正常", dicItemName: '正常' },
|
||||
{ code: 2, name: "草稿", dicItemName: '草稿' },
|
||||
// 开始
|
||||
export const taskStatusArr = [
|
||||
{ dicItemCode: 999, name: "正在进行中", dicItemName: '正在进行中' },
|
||||
{ dicItemCode: 0, name: "已完成", dicItemName: '已完成' },
|
||||
];
|
||||
|
||||
export const taskType = [
|
||||
{ code: 1, name: "更正", dicItemName: "更正" },
|
||||
{ code: 2, name: "中标", dicItemName: "中标" },
|
||||
{ code: 3, name: "废标", dicItemName: "废标" },
|
||||
export const taskStatusAllArr = [
|
||||
{ dicItemCode: 0, name: "未发布", dicItemName: '未发布' },
|
||||
{ dicItemCode: 1, name: "待审核", dicItemName: '待审核' },
|
||||
{ dicItemCode: 2, name: "已拒绝", dicItemName: '已拒绝' },
|
||||
{ dicItemCode: 3, name: "成果征集中", dicItemName: '成果征集中' },
|
||||
{ dicItemCode: 4, name: "成果评选中", dicItemName: '成果评选中' },
|
||||
{ dicItemCode: 5, name: "公示中", dicItemName: '公示中' },
|
||||
{ dicItemCode: 6, name: "协议签订中", dicItemName: '协议签订中' },
|
||||
{ dicItemCode: 7, name: "支付中", dicItemName: '支付中' },
|
||||
{ dicItemCode: 8, name: "已完成", dicItemName: '已完成' },
|
||||
]
|
||||
|
||||
export const taskTimeArr = [
|
||||
{ dicItemCode: 1, name: "24小时到期", dicItemName: "24小时到期" },
|
||||
{ dicItemCode: 3, name: "3天内到期", dicItemName: "3天内到期" },
|
||||
{ dicItemCode: 7, name: "7天内到期", dicItemName: "7天内到期" },
|
||||
];
|
||||
|
||||
export const taskChecked = [
|
||||
{ code: 0, name: "未通过", dicItemName: "未通过" },
|
||||
{ code: 1, name: "通过", dicItemName: "通过" },
|
||||
{ code: 2, name: "未处理", dicItemName: "未处理" },
|
||||
];
|
||||
//公告结束
|
||||
export const taskModeIdArr = [
|
||||
{ dicItemCode: 1, name: "单人悬赏", dicItemName: "单人悬赏" },
|
||||
{ dicItemCode: 2, name: "多人悬赏", dicItemName: "多人悬赏" },
|
||||
{ dicItemCode: 3, name: "计件悬赏", dicItemName: "计件悬赏" },
|
||||
]
|
||||
|
||||
|
||||
export const sortArr = [{
|
||||
name: '综合',
|
||||
type: 'default',
|
||||
}, {
|
||||
name: '最新',
|
||||
type: 'createdAt',
|
||||
icon: true,
|
||||
desc: false,
|
||||
},
|
||||
{
|
||||
name: '最热',
|
||||
type: 'visits',
|
||||
icon: true,
|
||||
desc: false,
|
||||
},
|
||||
{
|
||||
name: '价格',
|
||||
type: 'bounty',
|
||||
icon: true,
|
||||
desc: false,
|
||||
},];
|
||||
|
||||
|
||||
|
||||
export const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 10 },
|
||||
sm: { span: 6 },
|
||||
lg: { span: 3 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 14 },
|
||||
sm: { span: 18 },
|
||||
lg: { span: 21 },
|
||||
},
|
||||
};
|
||||
|
||||
export const formModalLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 10 },
|
||||
sm: { span: 6 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 14 },
|
||||
sm: { span: 18 },
|
||||
},
|
||||
};
|
||||
|
||||
export const tailFormItemLayout = {
|
||||
wrapperCol: {
|
||||
xs: {
|
||||
span: 20,
|
||||
offset: 4,
|
||||
},
|
||||
sm: {
|
||||
span: 20,
|
||||
offset: 4,
|
||||
},
|
||||
},
|
||||
};
|
|
@ -1,61 +1,122 @@
|
|||
import React, { forwardRef, useCallback, useEffect, useState } from 'react';
|
||||
import { Form, Input, Select, Button, DatePicker } from 'antd';
|
||||
import moment from 'moment';
|
||||
import { Form, Radio, Input, InputNumber, Icon, Button, Modal } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import ReactWEditor from 'wangeditor-for-react';
|
||||
import { Link } from "react-router-dom";
|
||||
import Upload from '../../components/Upload';
|
||||
import { httpUrl } from '../../fetch';
|
||||
import { getDictionary, getTaskDetail, addTask, updateTask } from '../api';
|
||||
import { getTaskDetail, addTask, updateTask, getTaskCategory } from '../api';
|
||||
import {formItemLayout,tailFormItemLayout,formModalLayout}from '../static';
|
||||
import './index.scss';
|
||||
|
||||
const Option = Select.Option;
|
||||
const { TextArea } = Input;
|
||||
const format = "YYYY-MM-DD HH:mm:ss";
|
||||
let actionUrl = '';
|
||||
if (window.location.href.indexOf('localhost') > -1) {
|
||||
actionUrl = httpUrl;
|
||||
}
|
||||
|
||||
export default Form.create()(forwardRef(({current_user, form, showNotification, match, history }, ref) => {
|
||||
export default Form.create()(forwardRef(({ current_user, form, showNotification, match, history }, ref) => {
|
||||
|
||||
const [requireType, setRequireType] = useState([]);
|
||||
const [tagType, setTagType] = useState([]);
|
||||
const [taskCategoryArr, setTaskCategoryArr] = useState([]);
|
||||
const [fileList, setFileList] = useState(null);
|
||||
const [typeCode, setTypeCode] = useState('');
|
||||
const [typeName, setTypeName] = useState('');
|
||||
|
||||
const [publishMode, setPublishMode] = useState(0);
|
||||
const [categoryId, setCategoryId] = useState('7');
|
||||
const [description, setDescription] = useState('');
|
||||
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [num, setNum] = useState(0) // 倒计时
|
||||
const [isSend, setIsSend] = useState(false) // 是否发送验证码
|
||||
|
||||
const id = match.params.requireId;
|
||||
const { getFieldDecorator, validateFields, setFieldsValue, } = form;
|
||||
|
||||
// 根据是否传id判断是新增还是修改
|
||||
useEffect(() => {
|
||||
id && getTaskDetail(id).then(data => {
|
||||
const formValue = {
|
||||
title: data.title,
|
||||
attachments: data.attachments,
|
||||
// typeCode: data.typeCode, //为使用select labelInValue,在代码中初始化值
|
||||
endTime: moment(data.endTime),
|
||||
tag: data.tag,
|
||||
remark: data.remark
|
||||
};
|
||||
setFieldsValue(formValue);
|
||||
setTypeName(data.typeName);
|
||||
setTypeCode(data.typeCode)
|
||||
if (data.attachmentList.length) {
|
||||
for (const item of data.attachmentList) {
|
||||
item.name = item.fileName;
|
||||
item.size = item.fileSize;
|
||||
item.uid = "rc-upload" + item.id
|
||||
let formValue = {
|
||||
taskModeId: 1,
|
||||
collectionMode: 1,
|
||||
publishMode: 0,
|
||||
collectingDays: 30,
|
||||
choosingDays: 15,
|
||||
makePublicDays: 7,
|
||||
signingDays: 15,
|
||||
payingDays: 15,
|
||||
};
|
||||
let categoryId = '7';
|
||||
if (id) {
|
||||
getTaskDetail(id).then(data => {
|
||||
formValue = {
|
||||
name: data.name,
|
||||
contactName: data.contactName,
|
||||
contactPhone: data.contactPhone,
|
||||
uploadFileNumbers: data.uploadFileNumbers,
|
||||
|
||||
bounty: data.bounty,
|
||||
taskModeId: data.taskModeId,
|
||||
collectionMode: data.collectionMode,
|
||||
publishMode: data.publishMode,
|
||||
|
||||
description: data.description,
|
||||
collectingDays: data.collectingDays,
|
||||
choosingDays: data.choosingDays,
|
||||
makePublicDays: data.makePublicDays,
|
||||
signingDays: data.signingDays,
|
||||
payingDays: data.payingDays,
|
||||
};
|
||||
|
||||
categoryId = data.categoryId;
|
||||
if (data.attachmentList.length) {
|
||||
for (const item of data.attachmentList) {
|
||||
item.name = item.fileName;
|
||||
item.size = item.fileSize;
|
||||
item.uid = "rc-upload" + item.id
|
||||
}
|
||||
setFileList(data.attachmentList);
|
||||
}
|
||||
setFileList(data.attachmentList);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
setFieldsValue(formValue);
|
||||
setCategoryId(categoryId);
|
||||
}, [id]);
|
||||
|
||||
// 加载选项数据
|
||||
useEffect(() => {
|
||||
getDictionary('requirement_type').then((res) => {
|
||||
setRequireType(res.data);
|
||||
});
|
||||
getDictionary("tag_type").then((res) => {
|
||||
setTagType(res.data);
|
||||
getTaskCategory().then(data => {
|
||||
if (data) {
|
||||
for (const item of data) {
|
||||
item.dicItemCode = item.id;
|
||||
item.dicItemName = item.name;
|
||||
}
|
||||
setTaskCategoryArr(data);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
||||
/** 倒计时显示*/
|
||||
useEffect(() => {
|
||||
let timer = 0;
|
||||
if (isSend && num !== 0) {
|
||||
timer = setInterval(() => {
|
||||
setNum(n => {
|
||||
if (n === 1) {
|
||||
setIsSend(false)
|
||||
clearInterval(timer)
|
||||
}
|
||||
return n - 1;
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
return () => {
|
||||
// 组件销毁时,清除定时器
|
||||
clearInterval(timer)
|
||||
};
|
||||
}, [isSend]);
|
||||
|
||||
function getCode(){
|
||||
setIsSend(true);
|
||||
setNum(60);
|
||||
}
|
||||
|
||||
// 上传附件后得到的文件数组
|
||||
function UploadFunc(fileList) {
|
||||
setFileList(fileList);
|
||||
|
@ -64,55 +125,50 @@ export default Form.create()(forwardRef(({current_user, form, showNotification,
|
|||
files.push(item.id || item.response.data.id);
|
||||
}
|
||||
setFieldsValue({
|
||||
attachments: files.join()
|
||||
uploadFileNumbers: files.join()
|
||||
});
|
||||
}
|
||||
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget, initialValue) => (
|
||||
(label, name, rules, widget, initialValue, rightComponent) => (
|
||||
<Form.Item label={label}>
|
||||
{getFieldDecorator(name, { rules, initialValue, validateFirst: true, })(widget)}
|
||||
{rightComponent}
|
||||
</Form.Item>
|
||||
), []);
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 12 },
|
||||
sm: { span: 4 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 12 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
};
|
||||
const helperNoLabel = useCallback(
|
||||
(title, name, rules, widget, initialValue) => (
|
||||
<div className="timing_task" key={name}>
|
||||
<div className="mbt10 color-grey-9 lineh-35"><span className="inline-span">{title}</span></div>
|
||||
<Form.Item className="no-label">
|
||||
{getFieldDecorator(name, { rules, initialValue, validateFirst: true, })(widget)}
|
||||
</Form.Item>
|
||||
<span className="days-word color-grey-9 ">天</span>
|
||||
</div>
|
||||
), []);
|
||||
|
||||
const tailFormItemLayout = {
|
||||
wrapperCol: {
|
||||
xs: {
|
||||
span: 20,
|
||||
offset: 4,
|
||||
},
|
||||
sm: {
|
||||
span: 20,
|
||||
offset: 4,
|
||||
},
|
||||
},
|
||||
};
|
||||
function changeHtml(html) {
|
||||
setFieldsValue({
|
||||
description: html
|
||||
});
|
||||
setDescription(html);
|
||||
}
|
||||
|
||||
// 修改
|
||||
// 保存
|
||||
function saveItem() {
|
||||
validateFields((error, values) => {
|
||||
if (!error) {
|
||||
let params = {
|
||||
...values,
|
||||
createUserAccount:current_user.login|| sessionStorage.getItem("SET_Account"), //用户信息
|
||||
createUserName:current_user.username|| sessionStorage.getItem("SET_NAME"), //模拟时使用莫胜吕
|
||||
typeName,
|
||||
typeCode,
|
||||
status: 0, //状态
|
||||
enterpriseName: '神马科技股份有限公司',
|
||||
categoryId,
|
||||
};
|
||||
params.tag = params.tag.join();
|
||||
params.endTime = params.endTime.format(format);
|
||||
let dateSum = params.collectingDays + params.choosingDays + params.makePublicDays + params.signingDays + params.payingDays;
|
||||
if (dateSum > 180) {
|
||||
showNotification("任务天数总和不得超过180天!");
|
||||
return;
|
||||
}
|
||||
if (id) {
|
||||
// 编辑
|
||||
params.id = id;
|
||||
|
@ -139,108 +195,280 @@ export default Form.create()(forwardRef(({current_user, form, showNotification,
|
|||
})
|
||||
}
|
||||
|
||||
function changeTypeName(value) {
|
||||
setTypeCode(value.key);
|
||||
setTypeName(value.label);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="centerbox">
|
||||
<div className="center-content">
|
||||
|
||||
<div className="centerScreen">
|
||||
<div className="center-left-but">{id ? '修改' : '新增'}需求</div>
|
||||
</div>
|
||||
<Form className="achieve-form" {...formItemLayout}>
|
||||
{helper(
|
||||
"需求名称:",
|
||||
"title",
|
||||
[{ required: true, message: "请输入需求名称" }],
|
||||
<Input
|
||||
className="edit-input"
|
||||
placeholder="请输入需求名称"
|
||||
/>
|
||||
)}
|
||||
|
||||
{helper(
|
||||
"需求类型:",
|
||||
"typeCode",
|
||||
[{ required: true, message: "请选择需求类别" }],
|
||||
<Select placeholder="请选择需求类别"
|
||||
className="edit-input"
|
||||
labelInValue
|
||||
onChange={changeTypeName}
|
||||
>
|
||||
{
|
||||
requireType.map(item => {
|
||||
return <Option key={item.id + ''} value={item.id + ''}>{item.dicItemName}</Option>
|
||||
})
|
||||
}
|
||||
</Select>
|
||||
, { key: typeCode, label: typeName })}
|
||||
|
||||
{helper(
|
||||
"结束时间:",
|
||||
"endTime",
|
||||
[{ required: true, message: "请输入结束时间" }],
|
||||
<DatePicker
|
||||
showTime
|
||||
format={format}
|
||||
placeholder="请输入结束时间"
|
||||
/>
|
||||
)}
|
||||
|
||||
<Form.Item label={"需求文件:"} required={true}>
|
||||
<Upload
|
||||
className="commentStyle"
|
||||
load={UploadFunc}
|
||||
size={100}
|
||||
showNotification={showNotification}
|
||||
actionUrl={httpUrl}
|
||||
fileList={fileList}
|
||||
/>
|
||||
|
||||
{/* 用一个隐藏的input实现上传文件的必填校验 */}
|
||||
{getFieldDecorator('attachments', {
|
||||
rules: [{ required: true, message: "请上传需求文件" }], validateFirst: true
|
||||
})(<Input style={{ display: 'none' }} />)}
|
||||
</Form.Item>
|
||||
|
||||
{helper(
|
||||
"标签:",
|
||||
"tag",
|
||||
[{ required: true, message: "请选择需求标签" }],
|
||||
<Select
|
||||
placeholder="请选择需求标签"
|
||||
className="edit-input"
|
||||
mode="tags"
|
||||
tokenSeparators={[',']}
|
||||
>
|
||||
{
|
||||
tagType.map(item => {
|
||||
return <Option key={item.dicItemName}>{item.dicItemName}</Option>
|
||||
})
|
||||
}
|
||||
</Select>
|
||||
)}
|
||||
|
||||
{helper(
|
||||
"需求描述:",
|
||||
"remark",
|
||||
[{ required: true, message: "请输入需求描述" }],
|
||||
<TextArea
|
||||
placeholder="请输入需求描述"
|
||||
autoSize={{ minRows: 3, maxRows: 5 }}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Form.Item {...tailFormItemLayout}>
|
||||
<Button className="mr20" type={"primary"} onClick={saveItem}>保存</Button>
|
||||
<Button onClick={() => { history.go(-1) }}>取消</Button>
|
||||
</Form.Item>
|
||||
|
||||
</Form>
|
||||
<div className="head-navigation">
|
||||
<Link className="color-grey-9" to="/task">创客空间 ></Link>
|
||||
<Link className="color-grey-9" to="/task">任务大厅 ></Link>
|
||||
<span >发布需求 </span>
|
||||
</div>
|
||||
<p className="font-18 font-bd mb15">任务需求提交</p>
|
||||
|
||||
<div className="edu-back-white mb110">
|
||||
<div className="padding30 bor-bottom-greyE">
|
||||
<p className="partTitle">联系方式<span className="color-red font-14">(*必填)</span></p>
|
||||
|
||||
<Form {...formItemLayout}>
|
||||
<Form.Item label='主体信息:'>
|
||||
{"神马科技股份有限公司"}
|
||||
</Form.Item>
|
||||
|
||||
{helper(
|
||||
"联系人:",
|
||||
"contactName",
|
||||
[{ required: true, message: "请输入联系人" }],
|
||||
<Input
|
||||
className="contact-input"
|
||||
placeholder="请输入联系人"
|
||||
/>
|
||||
)}
|
||||
|
||||
{helper(
|
||||
"联系电话:",
|
||||
"contactPhone",
|
||||
[{ required: true, message: "请输入联系电话" }],
|
||||
<Input
|
||||
className="contact-input"
|
||||
placeholder="请输入联系电话"
|
||||
// disabled
|
||||
/>, '', <Icon className="editPhone" type="edit" onClick={() => { setVisible(true) }} />
|
||||
)}
|
||||
|
||||
</Form>
|
||||
</div>
|
||||
|
||||
<div className="padding30 bor-bottom-greyE">
|
||||
<p className="partTitle">需求内容<span className="color-red font-14">(*必填)</span>
|
||||
<span>
|
||||
<a href="http://117.50.100.12:8000/attachments/download/523/%E5%88%9B%E5%AE%A2%E4%BB%BB%E5%8A%A1%E5%88%97%E8%A1%A8_2019-07-26_20-53.xlsx" className="icon icon-attachment font-13 color-blue" length="32" target="_blank">创客任务列表_2019-07-26_20-53.xlsx</a>
|
||||
</span><span className="color-grey-9 ml5 font-12 ">点击下载示例模版</span>
|
||||
</p>
|
||||
|
||||
<div className="pl15">
|
||||
<p className="color-grey3 mb20">选择需求所在领域</p>
|
||||
|
||||
<div className="mb20 clearfix areaDiv" >
|
||||
{
|
||||
taskCategoryArr.map(item => {
|
||||
return <button
|
||||
className={classNames({ "choose-button": true, "active": item.dicItemCode == categoryId })}
|
||||
key={item.dicItemCode}
|
||||
onClick={() => { setCategoryId(item.dicItemCode) }}
|
||||
>{item.dicItemName}</button>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
{helper(
|
||||
"",
|
||||
"name",
|
||||
[{ required: true, message: "请用一句话概括您要做什么?比如:开源项目网站开发,最大限制60个字符" }],
|
||||
<Input
|
||||
placeholder="请用一句话概括您要做什么?比如:开源项目网站开发,最大限制60个字符"
|
||||
/>
|
||||
)}
|
||||
|
||||
<Form.Item >
|
||||
<ReactWEditor
|
||||
value={description}
|
||||
config={
|
||||
{
|
||||
placeholder: "把您的需求内容补充详细一些吧,越清晰具体,任务完成质量越高哟~",
|
||||
uploadImgServer: actionUrl + '/busiAttachments/upload',
|
||||
uploadFileName: 'file',
|
||||
uploadImgHeaders: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
uploadImgHooks: {
|
||||
// 图片上传并返回了结果,想要自己把图片插入到编辑器中
|
||||
customInsert: function (insertImgFn, result) {
|
||||
// insertImgFn 可把图片插入到编辑器,传入图片 src ,执行函数即可
|
||||
if (result && result.data && result.data.id) {
|
||||
insertImgFn(`${actionUrl}/busiAttachments/view/${result.data.id}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
onChange={(html) => {
|
||||
changeHtml(html);
|
||||
}}
|
||||
/>
|
||||
{/* 用一个隐藏的input实现上必填校验 */}
|
||||
{getFieldDecorator('description', {
|
||||
rules: [{ required: true, message: "把您的需求内容补充详细一些吧,越清晰具体,任务完成质量越高哟~" }],
|
||||
validateFirst: true
|
||||
})(<Input style={{ display: 'none' }} />)}
|
||||
</Form.Item>
|
||||
|
||||
<p className="color-grey3 mb10 mt20">
|
||||
<span className="color-orange mr2 ">*</span>
|
||||
注:需求发布之后,将会公开展示在交易中心。不要把与项目、客户相关等隐私信息,以及QQ号、微信号、电话号码等联系方式填写在需求中。
|
||||
</p>
|
||||
|
||||
<Form.Item >
|
||||
<Upload
|
||||
className="commentStyle"
|
||||
load={UploadFunc}
|
||||
size={50}
|
||||
showNotification={showNotification}
|
||||
// actionUrl={httpUrl}
|
||||
actionUrl={'http://117.50.100.12:8001'}
|
||||
fileList={fileList}
|
||||
/>
|
||||
{getFieldDecorator('uploadFileNumbers', {
|
||||
validateFirst: true
|
||||
})(<Input style={{ display: 'none' }} />)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="padding30 ">
|
||||
<p className="partTitle">选择任务周期、价格和发布模式<span className="color-red font-14">(*必填)</span></p>
|
||||
<Form className="gray-form" {...formItemLayout}>
|
||||
{helper(
|
||||
"赏金:",
|
||||
"bounty",
|
||||
[{ required: true, message: "您打算支付多少赏金呢" }],
|
||||
<InputNumber
|
||||
className="number-input"
|
||||
placeholder="您打算支付多少赏金呢"
|
||||
formatter={value => `${value}¥`}
|
||||
/>
|
||||
)}
|
||||
|
||||
{helper(
|
||||
"赏金分配:",
|
||||
"taskModeId",
|
||||
[{ required: true, message: "请选择赏金分配" }],
|
||||
<Radio.Group>
|
||||
<Radio value={1}>单人悬赏,只设置一个中标者</Radio>
|
||||
<Radio value={2}>多人悬赏,设置多分中标分享赏金</Radio>
|
||||
<Radio value={3}>计件悬赏,合格一稿,支付一稿(稿件数量≥2件)</Radio>
|
||||
</Radio.Group>
|
||||
)}
|
||||
|
||||
{helper(
|
||||
"征集方式:",
|
||||
"collectionMode",
|
||||
[{ required: true, message: "请选择赏金分配" }],
|
||||
<Radio.Group>
|
||||
<Radio value={1}>创意征集,应征者以开放讨论的形式参与</Radio>
|
||||
<Radio value={0}>物化成果征集,应征者以各自提交成果物的形式参与</Radio>
|
||||
</Radio.Group>
|
||||
)}
|
||||
|
||||
{helper(
|
||||
"发布方式:",
|
||||
"publishMode",
|
||||
[{ required: true, message: "请选择赏金分配" }],
|
||||
<Radio.Group onChange={(e) => { setPublishMode(e.target.value) }}>
|
||||
<Radio value={0}>自主提交方式,由发布方自行支付赏金,一键自助发布</Radio>
|
||||
<Radio value={1}>统筹任务,由平台支付赏金,需经过平台遴选方能发布</Radio>
|
||||
</Radio.Group>
|
||||
)}
|
||||
|
||||
<div className="task-setting-days">
|
||||
<div className="timing_task">
|
||||
<div className="mbt10 color-grey-9 lineh-35"><span className="inline-span active">发布任务</span></div>
|
||||
<div className="color-grey-9 ">自主提交:立即发布</div>
|
||||
<div className="color-grey-9 ">统筹任务:遴选后发布</div>
|
||||
</div>
|
||||
|
||||
{helperNoLabel(
|
||||
"成果提交",
|
||||
"collectingDays",
|
||||
[{ required: true, message: "请输入天数" }],
|
||||
<InputNumber
|
||||
className="date-input"
|
||||
/>
|
||||
)}
|
||||
{/* <div className="color-grey-9 format-time-days-1 format-time-day-show">2021-06-16 07:10</div> */}
|
||||
{/* <div className="days-error"><span className="color-red none">成果提交时间不能为空</span></div> */}
|
||||
|
||||
{helperNoLabel(
|
||||
"成果评选",
|
||||
"choosingDays",
|
||||
[{ required: true, message: "请输入天数" }],
|
||||
<InputNumber
|
||||
className="date-input"
|
||||
/>
|
||||
)}
|
||||
|
||||
{helperNoLabel(
|
||||
"结果公示",
|
||||
"makePublicDays",
|
||||
[{ required: true, message: "请输入天数" }],
|
||||
<InputNumber
|
||||
className="date-input"
|
||||
/>
|
||||
)}
|
||||
|
||||
{helperNoLabel(
|
||||
"任务协议签订",
|
||||
"signingDays",
|
||||
[{ required: true, message: "请输入天数" }],
|
||||
<InputNumber
|
||||
className="date-input"
|
||||
/>
|
||||
)}
|
||||
|
||||
{helperNoLabel(
|
||||
"支付",
|
||||
"payingDays",
|
||||
[{ required: true, message: "请输入天数" }],
|
||||
<InputNumber
|
||||
className="date-input"
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="timing_task">
|
||||
<div className="mbt10 color-grey-9 lineh-35"><span className="inline-span">任务完成</span></div>
|
||||
<div className="color-grey-9 ">支付确认后,任务完成</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="color-grey3 mb10 ml40 mt20">
|
||||
<span className="color-orange mr2 ">*</span>
|
||||
注:任务天数总和不得超过180天。
|
||||
</p>
|
||||
<Form.Item {...tailFormItemLayout}>
|
||||
<Button className="mr20" type={"primary"} onClick={saveItem}>保存</Button>
|
||||
<Button onClick={() => { history.go(-1) }}>取消</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Modal
|
||||
title="修改联系电话"
|
||||
visible={visible}
|
||||
// onOk={checkItem}
|
||||
onCancel={() => { setVisible(false) }}
|
||||
className="form-edit-modal"
|
||||
>
|
||||
<Form {...formModalLayout}>
|
||||
<Form.Item label={"新手机号码:"} >
|
||||
<Input
|
||||
className="tel-input"
|
||||
placeholder="请输入11位手机号"
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label={"验证码:"} >
|
||||
<Input
|
||||
className="code-input"
|
||||
placeholder="请输入验证码"
|
||||
/>
|
||||
<Button className="ml10" type="primary" disabled={num!==0} onClick={getCode}>{num||'获取验证码'}</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
|
|
@ -1,4 +1,143 @@
|
|||
.achieve-form{
|
||||
padding:24px 40px 0px 40px;
|
||||
.achieve-form {
|
||||
padding: 24px 40px 0px 40px;
|
||||
}
|
||||
|
||||
.partTitle {
|
||||
color: #05101a;
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
|
||||
.partTitle:before {
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
top: 3px;
|
||||
width: 2px;
|
||||
height: 16px;
|
||||
background: #459be6;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.color-red {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.areaDiv {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.choose-button {
|
||||
float: left;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 0px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
padding: 0px 12px;
|
||||
color: #656565;
|
||||
margin: 0px 10px 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.choose-button.active {
|
||||
color: #4cacff !important;
|
||||
border: 1px solid #4cacff;
|
||||
}
|
||||
|
||||
.gray-form {
|
||||
.ant-form-item-required {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.contact-input {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.editPhone {
|
||||
margin-left: 1rem;
|
||||
padding: 0.25em;
|
||||
font-size: 1rem;
|
||||
color: #fff;
|
||||
background: #1484ef;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.number-input {
|
||||
width: 200px;
|
||||
.ant-input-number-input {
|
||||
padding-right: 1em;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.task-setting-days {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.timing_task {
|
||||
flex: 1px;
|
||||
position: relative;
|
||||
line-height: 2;
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background: #efefef;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.inline-span:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
top: -4px;
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
background: #bfbfbf;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.inline-span.active {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
|
||||
&:before {
|
||||
background: #4cacff;
|
||||
}
|
||||
}
|
||||
|
||||
.date-input {
|
||||
margin-right: 0.4rem;
|
||||
}
|
||||
|
||||
.tel-input{
|
||||
width: 290px;
|
||||
}
|
||||
.code-input{
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
.no-label {
|
||||
display: inline-block;
|
||||
.ant-form-explain {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.days-word {
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.ant-modal-footer{
|
||||
text-align: center;
|
||||
}
|
|
@ -1,52 +1,95 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Pagination, Icon, Input, Button } from 'antd';
|
||||
import { Pagination, Input, Button } from 'antd';
|
||||
import moment from 'moment';
|
||||
import ChooseNav from '../../components/chooseNav';
|
||||
import SortBox from '../../components/sortBox';
|
||||
import ItemList from '../../components/itemListTask';
|
||||
import ItemListTask from '../../components/itemListTask';
|
||||
import Nodata from '../../../forge/Nodata';
|
||||
import { taskType, taskStatus } from '../static';
|
||||
import { getTaskList } from '../api';
|
||||
import './index.scss';
|
||||
import { taskTimeArr, taskStatusArr, sortArr, taskModeIdArr } from '../static';
|
||||
import { getTaskList, getTaskCategory } from '../api';
|
||||
const Search = Input.Search;
|
||||
|
||||
|
||||
export default ({ history }) => {
|
||||
|
||||
const [type, setType] = useState(undefined);
|
||||
const [title, setTitle] = useState(undefined);
|
||||
export default ({ history, current_user }) => {
|
||||
console.log(current_user);
|
||||
const [taskCategoryArr, setTaskCategoryArr] = useState([]);
|
||||
const [categoryId, setCategoryId] = useState('');
|
||||
const [taskModeId, setTaskModeId] = useState('');
|
||||
const [expiredStartTime, setExpiredStartTime] = useState('');
|
||||
const [expiredEndTime, setExpiredEndTime] = useState('');
|
||||
const [status, setStatus] = useState('');
|
||||
const [searchInput, setSearchInput] = useState('');
|
||||
const [orderBy, setOrderBy] = useState('');
|
||||
const [curPage, setCurPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [taskList, setAchiveList] = useState([]);
|
||||
const [taskList, setTaskList] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
getTaskCategory().then(data => {
|
||||
if (data) {
|
||||
for (const item of data) {
|
||||
item.dicItemCode = item.id;
|
||||
item.dicItemName = item.name;
|
||||
}
|
||||
setTaskCategoryArr(data);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const params = {
|
||||
categoryId,
|
||||
taskModeId,
|
||||
expiredStartTime,
|
||||
expiredEndTime,
|
||||
status,
|
||||
searchInput,
|
||||
orderBy,
|
||||
curPage,
|
||||
isChecked: 1,
|
||||
pageSize: 10,
|
||||
status: 1,
|
||||
type,
|
||||
title,
|
||||
flag: 1, //后台管理查询:2;前台展示:1
|
||||
};
|
||||
|
||||
getTaskList(params).then(data => {
|
||||
setAchiveList(data.rows);
|
||||
setTotal(data.total);
|
||||
if (data) {
|
||||
setTaskList(data.rows);
|
||||
setTotal(data.total);
|
||||
}
|
||||
})
|
||||
}, [type, title, orderBy, curPage]);
|
||||
}, [categoryId, taskModeId, expiredStartTime, expiredEndTime, status, searchInput, orderBy, curPage]);
|
||||
|
||||
|
||||
function changeOptionId(option, type) {
|
||||
console.log(option);
|
||||
setType(option.code || '');
|
||||
if (type === 'taskCategory') {
|
||||
setCategoryId(option.dicItemCode);
|
||||
} else if (type === 'taskModeId') {
|
||||
setTaskModeId(option.dicItemCode);
|
||||
} else if (type === 'taskTime') {
|
||||
if (option.dicItemCode) {
|
||||
let nowTime = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
|
||||
let nextTime = moment(new Date().setDate(new Date().getDate() + option.dicItemCode)).format('YYYY-MM-DD HH:mm:ss');
|
||||
setExpiredStartTime(nowTime);
|
||||
setExpiredEndTime(nextTime);
|
||||
} else {
|
||||
setExpiredStartTime('');
|
||||
setExpiredEndTime('');
|
||||
}
|
||||
} else if (type === 'taskStatus') {
|
||||
setStatus(option.dicItemCode);
|
||||
}
|
||||
}
|
||||
|
||||
function changeSort(sortType) {
|
||||
// setOrderBy(sortType);
|
||||
setCurPage(1);
|
||||
console.log(sortType);
|
||||
let sortValue = '';
|
||||
if (sortType.type !== 'default') {
|
||||
if (sortType.desc) {
|
||||
sortValue = sortType.type + 'Desc';
|
||||
} else {
|
||||
sortValue = sortType.type + 'Asc';
|
||||
}
|
||||
}
|
||||
setOrderBy(sortValue);
|
||||
setCurPage(1);
|
||||
}
|
||||
|
||||
function taskClick(id) {
|
||||
|
@ -62,18 +105,18 @@ export default ({ history }) => {
|
|||
<div className="centerbox">
|
||||
<div className="nav-content">
|
||||
<ChooseNav
|
||||
key={'taskDomain'}
|
||||
type={'taskDomain'}
|
||||
key={'taskCategory'}
|
||||
type={'taskCategory'}
|
||||
title={'任务领域'}
|
||||
options={taskType}
|
||||
options={taskCategoryArr}
|
||||
changeOptionId={changeOptionId}
|
||||
/>
|
||||
|
||||
<ChooseNav
|
||||
key={'taskModel'}
|
||||
type={'taskModel'}
|
||||
key={'taskModeId'}
|
||||
type={'taskModeId'}
|
||||
title={'任务模式'}
|
||||
options={taskType}
|
||||
options={taskModeIdArr}
|
||||
changeOptionId={changeOptionId}
|
||||
/>
|
||||
|
||||
|
@ -81,7 +124,7 @@ export default ({ history }) => {
|
|||
key={'taskTime'}
|
||||
type={'taskTime'}
|
||||
title={'任务时限'}
|
||||
options={taskType}
|
||||
options={taskTimeArr}
|
||||
changeOptionId={changeOptionId}
|
||||
/>
|
||||
|
||||
|
@ -89,7 +132,7 @@ export default ({ history }) => {
|
|||
key={'taskStatus'}
|
||||
type={'taskStatus'}
|
||||
title={'任务状态'}
|
||||
options={taskStatus}
|
||||
options={taskStatusArr}
|
||||
changeOptionId={changeOptionId}
|
||||
/>
|
||||
</div>
|
||||
|
@ -98,59 +141,36 @@ export default ({ history }) => {
|
|||
<div className="centerScreen" >
|
||||
|
||||
<SortBox
|
||||
options={[{
|
||||
name: '综合',
|
||||
type: 1,
|
||||
}, {
|
||||
name: '最新',
|
||||
type: 2,
|
||||
icon: true,
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
name: '最热',
|
||||
type: 3,
|
||||
icon: true,
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
name: '价格',
|
||||
type: 4,
|
||||
icon: true,
|
||||
value: false,
|
||||
},
|
||||
]}
|
||||
options={sortArr}
|
||||
changeOptionId={changeSort}
|
||||
defaultValue={{
|
||||
name: '综合',
|
||||
type: 'default',
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="center-right-but">
|
||||
<Search
|
||||
maxLength={20}
|
||||
style={{ width: "300px" }}
|
||||
placeholder="请输入任务编号/任务名称"
|
||||
onSearch={(value) => setTitle(value)} />
|
||||
placeholder="请输入任务编号/任务名称关键字"
|
||||
onSearch={(value) => setSearchInput(value)} />
|
||||
|
||||
<Button className="mr20 font-12" type="primary" onClick={goAdd}><i className="iconfont icon-zaibianji font-12 mr3"></i>发布需求</Button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ItemList
|
||||
<ItemListTask
|
||||
list={taskList}
|
||||
itemClick={taskClick}
|
||||
curPage={curPage}
|
||||
total={total}
|
||||
changePage={(page) => { setCurPage(page) }}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
{taskList.length > 0 ? <div className="edu-txt-center mt10">
|
||||
<Pagination
|
||||
showQuickJumper
|
||||
onChange={(page) => { setCurPage(page) }}
|
||||
current={curPage}
|
||||
total={total}
|
||||
showTotal={total => `共 ${total} 条`}
|
||||
/>
|
||||
</div> : <Nodata _html="暂无数据" />}
|
||||
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
.center-right-but{
|
||||
.ant-input-group-addon{
|
||||
border: 0 !important;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue