标签:选择 main glob months paginati models white 约数 ret
需求需要在日历上实现多选但不连续的日期,ant design 的日历组件只能单选或者连续选择一段日期
附上代码----主代码部分
import React, { Component } from "react";
import { routerRedux } from "dva/router";
import { connect } from "dva";
import {
Menu,
Icon,
Form,
Select,
Row,
Col,
Card,
Button,
message,
TimePicker,
InputNumber,
} from "antd";
import moment from "moment";
// import ‘./ReserveList1.css‘;
import styles from "./ReserveList1.less";
import PageHeaderWrapper from "@/components/PageHeaderWrapper";
const { Option } = Select;
const FormItem = Form.Item;
// console.log(moment);
const DATE_FORMAT = "YYYY-MM-DD";
const holidayMap = {
// "2019-05-01": "劳动节221",
// "2019-05-02": "劳动节2",
// "2019-05-03": "劳动节3",
// "2019-05-04": "五四青年节",
// "2019-06-07": "端午节1",
// "2019-06-08": "端午节2",
// "2019-06-09": "端午节3",
// "2020-07-09": "已预约",
// "2020-07-10": "已预约",
};
// 后台返回的已预约的日期
let reverMap = [
// { subscribeDate: "2020-07-01" },
// { subscribeDate: "2020-07-02" },
// { subscribeDate: "2020-07-03" },
// { subscribeDate: "2020-07-04" },
];
// 点击已选择的日期
let reverParam = [];
class queryForm extends React.Component {
constructor(props) {
super(props);
this.state = {
options: {
years: [],
months: [],
},
};
}
state = {};
componentDidMount = function() {
let mySelf = this;
reverParam = [];
mySelf.init();
};
init = () => {
let mySelf = this;
mySelf.initOptions();
mySelf.setDefaultOption();
};
initOptions = function() {
let mySelf = this;
let options = mySelf.state.options;
let now = moment();
const yearOfNow = now.year();
let yearsOptions = [];
let monthsOptions = [];
// const startYear = yearOfNow - 20;
const startYear = yearOfNow;
const endYear = yearOfNow + 10;
const startMonth = 1;
const endMonth = 12;
for (let i = startYear; i < endYear; i++) {
let item = {
key: i,
label: i,
};
yearsOptions.push(item);
}
for (let i = startMonth; i <= endMonth; i++) {
let item = {
key: i,
label: i,
};
monthsOptions.push(item);
}
// console.log(platformOptions);
options.years = yearsOptions;
options.months = monthsOptions;
mySelf.setState({
options: options,
});
};
setDefaultOption = () => {
let mySelf = this;
let form = mySelf.props.form;
// let options = mySelf.state.options;
let now = moment();
const yearOfNow = now.year();
const monthOfNow = now.month() + 1;
// console.log(options);
let defaultYearOption = { key: yearOfNow, label: yearOfNow };
let defaultMonthOption = { key: monthOfNow, label: monthOfNow };
// console.log(defaultOption)
let formData = {
year: defaultYearOption,
month: defaultMonthOption,
};
form.setFieldsValue(formData);
};
changeMonth = (pars, nowMonth) => {
let mySelf = this;
let form = mySelf.props.form;
let res = form.getFieldsValue();
let month = Number(res.month.key) + Number(pars);
if (nowMonth == "当月") {
let now = moment();
const yearOfNow = now.year();
const monthOfNow = now.month() + 1;
month = monthOfNow;
let monthOption = { key: month, label: month };
let yearOption = { key: yearOfNow, label: yearOfNow };
// console.log(monthOption);
let formData = {
month: monthOption,
year: yearOption,
};
form.setFieldsValue(formData);
mySelf.props.changeCalendar();
this.setState({
disableNext: false,
disablePre: false,
});
return
}
if (month <= 0 && pars < 0) {
this.setState({
disablePre: true,
});
return;
} else {
this.setState({
disablePre: false,
});
}
if (month >= 13 && pars > 0) {
this.setState({
disableNext: true,
});
return;
} else {
this.setState({
disableNext: false,
});
}
let monthOption = { key: month, label: month };
// console.log(monthOption);
let formData = {
month: monthOption,
};
form.setFieldsValue(formData);
mySelf.props.changeCalendar();
};
render() {
let mySelf = this;
// eslint-disable-next-line
let { getFieldDecorator, getFieldValue } = mySelf.props.form;
let { options, disablePre, disableNext } = mySelf.state;
// console.log(options);
return (
<div>
<Row className="margin-bottom-5">
<Col span={24}>
<Form
layout="inline"
// wrappedComponentRef={(inst) => this.queryForm = inst}
>
<FormItem label="年">
{getFieldDecorator("year", {})(
<Select
labelInValue
size={"default"}
placeholder="year"
style={{ width: 150 }}
onChange={() =>
setTimeout(() => {
mySelf.props.changeCalendar();
}, 0)
}
>
{options.years.map(function(item, index) {
return <Option key={item.key}>{item.label}</Option>;
})}
</Select>
)}
</FormItem>
<FormItem label="月">
{getFieldDecorator("month", {})(
<Select
labelInValue
size={"default"}
placeholder="month"
style={{ width: 150 }}
onChange={() =>
setTimeout(() => {
mySelf.props.changeCalendar();
}, 0)
}
>
{options.months.map(function(item, index) {
return <Option key={item.key}>{item.label}</Option>;
})}
</Select>
)}
</FormItem>
<FormItem>
<Button
type="primary"
size="small"
onClick={() => mySelf.changeMonth(-1)}
disabled={disablePre}
>
上个月
</Button>
<Button
type="primary"
size="small"
onClick={() => mySelf.changeMonth(1)}
className={styles["margin-left-5"]}
disabled={disableNext}
>
下个月
</Button>
<Button
type="primary"
size="small"
onClick={() => mySelf.changeMonth(0,"当月")}
className={styles["margin-left-5"]}
>
今天
</Button>
</FormItem>
</Form>
</Col>
</Row>
</div>
);
}
}
let QueryFormComponent = Form.create()(queryForm);
class queryForm1 extends React.Component {
constructor(props) {
super(props);
this.state = {
subscribeTimeObj: {
subscribeTimeList: [0],
},
disablePre: false,
disableNext: false,
};
}
state = {};
componentDidMount = function() {
let mySelf = this;
};
addSubscribeTimeList = () => {
let s = this.state.subscribeTimeObj.subscribeTimeList;
s[s.length] = s.length;
this.setState({
subscribeTimeObj: Object.assign(
{},
{
subscribeTimeList: s,
}
),
});
};
delSubscribeTimeList = (idx) => {
let s = this.state.subscribeTimeObj.subscribeTimeList;
if (s.length > 1) {
s.splice(idx, 1);
this.setState({
subscribeTimeObj: Object.assign(
{},
{
subscribeTimeList: s,
}
),
});
}
};
render() {
let mySelf = this;
// eslint-disable-next-line
let { getFieldDecorator, getFieldValue } = mySelf.props.form;
let { subscribeTimeObj } = mySelf.state;
// console.log(options);
return (
<div>
<Button
className={styles.timeAddButton}
type="primary"
onClick={() => mySelf.addSubscribeTimeList()}
>
添加
</Button>
<div className={styles.timeSlotWrap}>
{subscribeTimeObj.subscribeTimeList.map((_, idx) => (
<Row key={idx} gutter={{ md: 8 }}>
<Col md={8} sm={8}>
<FormItem
key={"subscribeStartTime" + idx}
label=""
labelCol={{ span: 6 }}
wrapperCol={{ span: 24 }}
>
{getFieldDecorator("data[" + idx + "].subscribeStartTime", {
rules: [{ required: true, message: "请选择开始时间!" }],
})(<TimePicker style={{ width: "100%" }} format={"HH:mm"} />)}
</FormItem>
</Col>
<Col md={8} sm={8}>
<FormItem
key={"subscribeEndTime" + idx}
label=""
labelCol={{ span: 6 }}
wrapperCol={{ span: 24 }}
>
{getFieldDecorator("data[" + idx + "].subscribeEndTime", {
rules: [{ required: true, message: "请选择结束时间!" }],
})(<TimePicker style={{ width: "100%" }} format={"HH:mm"} />)}
</FormItem>
</Col>
<Col md={6} sm={6}>
<FormItem
key={"subscribeCount" + idx}
labelCol={{ span: 6 }}
wrapperCol={{ span: 24 }}
label=""
>
{getFieldDecorator("data[" + idx + "].subscribeCount", {
rules: [{ required: true, message: "请输入数量!" }],
})(
<InputNumber
style={{ width: "100%" }}
min={1}
step={1}
placeholder="可预约数量"
/>
)}
</FormItem>
</Col>
<Col style={{ padding: "9px" }} md={2} sm={2}>
<Icon
onClick={() => mySelf.delSubscribeTimeList(idx)}
type="close"
/>
</Col>
</Row>
))}
</div>
</div>
);
}
}
let QueryFormComponent1 = Form.create()(queryForm1);
@connect(({ reservelist1, loading, global }) => ({
global,
reservelist1,
loading: loading.models.reservelist1,
}))
class LeCalendar extends Component {
constructor(props) {
super(props);
this.state = {
//渲染日历过程中,当前显示月的moment对象
monthDisplay: "",
dates: [[], []],
};
}
componentDidMount = () => {
let mySelf = this;
mySelf.init();
mySelf.generateDates();
};
init = () => {
let mySelf = this;
mySelf.changeCalendar();
let todayDate = moment().format("YYYY-MM-DD");
mySelf.toSetScribeDefaultValue({
pageIndex: 1,
pageSize: 100,
startTime: todayDate,
endTime: "2029-12-31",
});
};
toSetScribeDefaultValue = async (params, cb) => {
const { dispatch, account } = this.props;
await dispatch({
type: "reservelist1/fetch1",
payload: params,
callback: (s, m, data) => {
const {
data: { list },
} = s;
let array = [];
list.forEach((e) => {
array.push({ subscribeDate: e.subscribeDate });
});
// reverMap = Array.from(new Set(array));
reverMap = array;
let mySelf = this;
mySelf.generateDates();
cb && cb(s, m, data);
},
});
};
generateDates = (reserveDate) => {
let mySelf = this;
let dates = [];
//单个日历,显示6周
const weeksNum = 6;
//每周显示7天
const weekDaysNum = 7;
//日历中的今天
const todayDate = moment().format(DATE_FORMAT);
//渲染日历过程中,当前显示月的moment对象
let now = mySelf.state.monthDisplay;
//当前显示的月份
let nowMonth = now.month();
// console.log(nowMonth);
//当月第一天
let firstDayOfMonth = now.clone().startOf("month");
//当月第一天是星期几
let weekOfFirstDay = firstDayOfMonth.isoWeekday();
//日历上的当月显示的第一天
let firstDayOfMonthDisplay = firstDayOfMonth
.clone()
.subtract(weekOfFirstDay - 1, "days");
//渲染日历过程中,使用的当前moment对象
let currentDate = firstDayOfMonthDisplay.clone();
// console.log(firstDayOfMonthDisplay.format(DATE_FORMAT));
const otherMonthClass = "other-month";
const dayOffClass = "day-off";
const holidayClass = "holiday";
const todayClass = "today";
const lastClass = "lastDay";
const reserveClass = "reservation";
const selectClass = "selected";
for (let i = 0; i < weeksNum; i++) {
let weekList = [];
for (let j = 0; j < weekDaysNum; j++) {
let date = currentDate.format(DATE_FORMAT);
let dateDisplay = currentDate.date();
let currentMonth = currentDate.month();
let currentWeekDay = currentDate.isoWeekday();
let classNameList = [];
let classNameStr = "";
let content = "";
let selectText = "";
//今天
if (todayDate === date) {
classNameList.push(todayClass);
}
// //今天以前的日期
// if (todayDate > date) {
// classNameList.push(lastClass);
// }
//已预约的日期
// if (reserveDate === date) {
// classNameList.push(reserveClass);
// }
//非当前月
if (currentMonth !== nowMonth) {
classNameList.push(otherMonthClass);
}
// //周末
// if ([6, 7].includes(currentWeekDay)) {
// classNameList.push(dayOffClass);
// }
// 已预约的日期
let obj = {};
for (let i = 0; i < reverMap.length; i++) {
const element = reverMap[i];
let value = element.subscribeDate;
obj[value] = "已预约";
}
if (obj[date]) {
classNameList.push(holidayClass);
content = obj[date];
}
// 已选择的日期
let objS = {};
for (let i = 0; i < reverParam.length; i++) {
const e = reverParam[i];
let value = e;
objS[value] = "已预约";
}
if (objS[date]) {
classNameList.push(selectClass);
selectText = "已选择";
}
//节假日
// if (holidayMap[date]) {
// classNameList.push(holidayClass);
// content = holidayMap[date];
// }
// //已选中的日期
// if (reserveDate === date) {
// classNameList.push(selectClass);
// }
classNameStr = classNameList.join(" ");
let item = {
momentObj: currentDate,
date: date,
dateDisplay: dateDisplay,
classNameStr: classNameStr,
content: content,
selectText: selectText,
};
weekList.push(item);
currentDate.add(1, "days");
}
dates.push(weekList);
}
mySelf.setState({
dates,
});
// console.log(dates);
};
changeCalendar = () => {
let mySelf = this;
let form = mySelf.queryForm.props.form;
let res = form.getFieldsValue();
let year = Number(res.year.key);
let month = Number(res.month.key) - 1;
let now = moment();
now.year(year).month(month);
mySelf.state.monthDisplay = now;
mySelf.generateDates();
// console.log(firstDayOfMonthDisplay.format(DATE_FORMAT));
console.log(now.format(DATE_FORMAT));
};
tapDate = (value) => {
const todayDate = moment().format(DATE_FORMAT);
if (todayDate > value) {
message.info("只能设置今天及以后的日期");
return;
}
// 已预约的不能再次选择
let reserveList = [];
reverMap.forEach((element) => {
reserveList.push(element.subscribeDate);
});
if (reserveList.includes(value)) {
message.info("已预约的不能再次选择");
return;
}
// 如果日期已选中,取消选中
if (reverParam.includes(value)) {
reverParam.remove(value);
this.generateDates(value);
} else {
reverParam.push(value);
this.generateDates(value);
}
};
confirmAdd = () => {
const { dispatch } = this.props;
let mySelf = this;
let form = mySelf.queryForm1.props.form;
let res = form.getFieldsValue();
form.validateFields((err, fieldsValue) => {
if (err) return;
let params = {
...fieldsValue,
data: fieldsValue.data.map((r) => {
let returnData = {
subscribeTimeSlot:
r.subscribeStartTime.format("HH:mm") +
"-" +
r.subscribeEndTime.format("HH:mm"),
subscribeCount: r.subscribeCount,
};
// !subscribeType && (returnData.subscribeId = getUuid(32));
return returnData;
}),
};
if (reverParam.length == 0) {
message.info("至少选择一天日期!");
return;
}
let reqparams = {
subscribeDays: reverParam,
...params,
};
dispatch({
type: "reservelist1/batchSubscribeDefaultValue",
payload: reqparams,
callback: (s, m, data) => {
if (m == "success") {
message.info("批量初始化成功");
this.props.history.push("/reservemanagement/reservelist");
form.resetFields();
reverParam = [];
// this.props.navigation.dispatch(NavigationActions.navigate({ routeName: ‘SearchOrder‘ }))
}
cb && cb(s, m, data);
},
});
});
};
render() {
// const {
// reserveList1: { data = {} },
// } = this.props;
let mySelf = this;
let { dates } = mySelf.state;
let renderWeekDays = (days) => {
let dom = null;
// console.log(days);
dom = (
<React.Fragment>
{days.map((item, index) => {
if (item.classNameStr == "today holiday") {
item.classNameStr = "todayHoliday";
}
if (item.classNameStr == "other-month holiday") {
item.classNameStr = "otherHoliday";
}
let styleName = "";
// console.log(styles[item.classNameStr]);
let tdDom = (
<td
className={styles["unit"]}
key={index}
onClick={() => this.tapDate(item.date)}
>
{/* <div className={ item.classNameStr + ‘day-cell‘}> */}
<div
className={
styles[item.classNameStr]
? styles[item.classNameStr]
: styles[
item.classNameStr.substring(
item.classNameStr.length - 8
)
]
}
>
<div className="header">
{/* {item.date} */}
{item.dateDisplay}
</div>
<div>{item.content}</div>
<div>{item.selectText}</div>
</div>
</td>
);
return tdDom;
})}
</React.Fragment>
);
return dom;
};
let renderWeeks = (dates) => {
let dom = null;
// console.log(dates);
dom = (
<React.Fragment>
{dates.map((item, index) => {
let trDom = <tr key={index}>{renderWeekDays(item)}</tr>;
return trDom;
})}
</React.Fragment>
);
return dom;
};
return (
<PageHeaderWrapper title="批量预约设置">
{/* <Card bordered={false}>
<div className={styles.tableList}> */}
{/* <div className={styles.tableListForm}>{this.renderForm()}</div>
<div className={styles.tableListOperator}>
<Button
icon="plus"
type="primary"
onClick={() => this.handleModalVisible(true)}
>
新建
</Button>
<Button
icon="plus"
type="primary"
onClick={() => this.toNewPage(true)}
>
批量初始化
</Button>
</div> */}
{/* <StandardTable
loading={loading}
data={data}
columns={this.columns}
onChange={this.handleStandardTableChange}
/> */}
{/* </div>
</Card> */}
<div>
<div className={styles.confirmClass}>
<Button
type="primary"
size={"large"}
onClick={() => this.confirmAdd()}
>
确定添加
</Button>
</div>
<div className={styles.mainSection}>
<div>
<QueryFormComponent
wrappedComponentRef={(inst) => (mySelf.queryForm = inst)}
// confirmAdd={() => mySelf.confirmAdd()}
changeCalendar={() => mySelf.changeCalendar()}
/>
{/* <div className="asda">asdasdasdas</div> */}
<table border="1" className={styles["le-calendar-container"]}>
<thead>
<tr>
<th>一</th>
<th>二</th>
<th>三</th>
<th>四</th>
<th>五</th>
<th>六</th>
<th>日</th>
</tr>
</thead>
<tbody>{renderWeeks(dates)}</tbody>
{/* <tfoot>
<tr>
<td>foot1</td>
<td>foot2</td>
</tr>
</tfoot> */}
</table>
</div>
<QueryFormComponent1
wrappedComponentRef={(inst) => (mySelf.queryForm1 = inst)}
// changeCalendar={() => mySelf.changeCalendar()}
confirmAdd={() => mySelf.confirmAdd()}
/>
{/* <QueryFormComponent1 /> */}
</div>
</div>
</PageHeaderWrapper>
);
}
}
export default LeCalendar;
接口辅助部分
import { store } from ‘@/utils/store‘;
import { getSubscribeTimeSlotList, vehiclePropertiesToSelect, subscribeSetting, subscribeDefaultValue,batchSubscribeDefaultValue,getOrderList } from ‘@/services/api‘;
let currUser = store.getParam(‘currUser‘) || {};
export default {
namespace: ‘reservelist1‘,
state: {
data: {
list: [],
pagination: {}
},
downloadUrl: null,
vehiclePropertytypeSelect: []
},
effects: {
*fetch1({ payload, callback }, { call, put }) {
const response = yield call(getOrderList, {
...payload,
phone: payload.phone || ‘‘,
startTime: payload.startTime || null,
endTime: payload.endTime || null,
orderId: payload.orderId || null,
plateNumber: payload.plateNumber || null,
orderState: payload.orderState || null,
payState: payload.payState || null,
isSubscribe: payload.isSubscribe || null,
vdsResult: payload.vdsResult || null,
parkId: currUser.ParkId || null
}) || {};
// if (callback && typeof callback === ‘function‘) {
// }
let pageSize = payload.pageSize || 10;
let current = payload.pageIndex || 1;
console.log(‘response‘)
console.log(response)
callback(response)
yield put({
type: ‘save1‘,
payload: {
list: response.data ? (response.data.list || []) : [],
pagination: {
total: response.data ? (response.data.totalCount || 0) : 0,
pageSize,
current
},
// downloadUrl: response.data && response.data.totalCount ? getDownloadUrl(‘orderExport‘, {
// ...payload,
// parkId: parkId
// }) : null
}
})
},
*sourceToSelect(_, { call, put }) {
const vehiclePropertytype = yield call(vehiclePropertiesToSelect);
yield put({
type: ‘select‘,
payload: {
vehiclePropertytypeList: vehiclePropertytype && Array.isArray(vehiclePropertytype.data) ? vehiclePropertytype.data : []
}
})
},
*batchSubscribeDefaultValue({ payload, callback }, { call }) {
const res = yield call(batchSubscribeDefaultValue, {
...payload,
parkId: currUser.ParkId || null,
operatorId: currUser.OperatorID || null
});
callback && callback(res && res.code==‘200‘, res.message);
},
// *subscribeSetting({ payload, callback }, { call }) {
// const res = yield call(subscribeSetting, {
// ...payload,
// parkId: currUser.ParkId || null,
// operatorId: currUser.OperatorID || null
// });
// callback && callback(res && res.code==‘200‘, res.message);
// },
*subscribeDefaultValue({ payload, callback }, { call }) {
// let reqUrl = payload.operation ? subscribeSetting : subscribeDefaultValue;
const res = yield call(subscribeDefaultValue, {
...payload,
parkId: currUser.ParkId || null,
operatorId: currUser.OperatorID || null
});
callback && callback(res && res.code==‘200‘, res.message,res.data);
}
},
reducers: {
save1(state, { payload }) {
return {
...state,
data: {
list: ( payload.list || [] ).map((bean, i) => ({
...bean,
key: i
})).slice(),
pagination: payload.pagination
},
// downloadUrl: payload.downloadUrl || null
}
},
select(state, { payload }) {
return {
...state,
vehiclePropertytypeSelect: [
{
VehiclePropertyName: ‘‘,
VehiclePropertyNameLabel: ‘请选择‘,
VehiclePropertyID: ‘0‘
},
...payload.vehiclePropertytypeList
].map(bean => ({
...bean,
VehiclePropertyNameLabel: bean.VehiclePropertyNameLabel || bean.VehiclePropertyName
}))
}
}
},
}
样式部分
@import ‘~antd/lib/style/themes/default.less‘; @import ‘~@/utils/utils.less‘; .tableList { .tableListOperator { margin-bottom: 16px; button { margin-right: 8px; } } } .siteCard { width: 300px !important; border: 1px solid #f0f0f0; border-radius: 2px; } .tableListForm { :global { .ant-form-item { display: flex; margin-right: 0; margin-bottom: 24px; > .ant-form-item-label { width: auto; padding-right: 8px; line-height: 32px; } .ant-form-item-control { line-height: 32px; } } .ant-form-item-control-wrapper { flex: 1; } } .submitButtons { display: block; margin-bottom: 24px; white-space: nowrap; } } .timeSlotWrap { padding: 0 16%; } .timeAddButton { margin: auto; width: 200px; display: block; } @media screen and (max-width: @screen-lg) { .tableListForm :global(.ant-form-item) { margin-right: 24px; } } @media screen and (max-width: @screen-md) { .tableListForm :global(.ant-form-item) { margin-right: 8px; } }
这样就完成了 效果如下

当然,当然还有回显效果,图片没有展示出来。
标签:选择 main glob months paginati models white 约数 ret
原文地址:https://www.cnblogs.com/lzhflzjx/p/13392965.html