微信小程序-日历
import { Block, View, Picker, Text, Image } from '@tarojs/components';
import Taro from '@tarojs/taro';
import withWeapp from '@tarojs/with-weapp';
import { calendarType } from '../../utils/broker.js';
import './index.scss';
@withWeapp('Component')
class _C extends Taro.Component {
state = {
// 当前显示的年
currentYear: new Date().getFullYear(),
// 当前显示的月
currentMonth: new Date().getMonth() + 1,
allArr: [],
// 当天日期
nowData: {},
// 选中日期的数据
chooseData: {},
}
componentWillMount = () => {
this.getDates();
}
getDates = () => {
// 调用函数时,传入new Date()参数,返回值是日期和时间
const time = this.formatTime(new Date());
const next = this.getNextWeekDay(7);
const nextMonday = `${next.year}${this.formatNumber(next.month)}${this.formatNumber(next.days)}`;
const nextS = this.getNextWeekDay(13);
const nextSunday = `${nextS.year}${this.formatNumber(nextS.month)}${this.formatNumber(nextS.days)}`;
this.setData({
nowData: `${time.year}${this.formatNumber(time.month)}${this.formatNumber(time.day)}`,
chooseData: {
date: nextMonday,
},
nextMonday,
nextSunday,
}, () => {
this.getAllArr();
});
}
// 获取下周一(num=7)或者下周日(num=13)的日期
getNextWeekDay(num) {
const time = this.formatTime(new Date());
let days = time.day + num - this.getFirstDateWeek(time.year, time.month, time.day);
const timeDistance = this.getDateLen(time.year, time.month);
let month = new Date().getMonth() + 1;
let year = new Date().getFullYear();
// 下周一跨月
if (days > timeDistance) {
days -= timeDistance;
month += 1;
// 下周一跨年
if (month > 12) {
year += 1;
month -= 12;
}
}
return { year, month, days };
}
getDataList = () => {
// 获取数据
}
// 设置默认选中
setDefaultChoice(List) {
// 默认选中当天
const setDate = this.state.nowData;
for (const item of List) {
if (setDate === item.date) {
this.getNowData(item);
break;
}
}
}
// 初始化今天的日期
formatTime = date => {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
return { year, month, day };
}
// 获取某年某月总共多少天
getDateLen(year, month) {
let actualMonth = month - 1;
let timeDistance = +new Date(year, month) - +new Date(year, actualMonth);
return timeDistance / (1000 * 60 * 60 * 24);
}
// 获取某月几号是周几
getFirstDateWeek(year, month, days = 0) {
const day = new Date(year, month - 1, days || 1).getDay() - 1;
if (day < 0) {
return 6;
}
return day;
}
// 上月 年、月
preMonth(year, month) {
if (month == 1) {
return {
year: --year,
month: 12,
};
} else {
return {
year: year,
month: --month,
};
}
}
// 下月 年、月
nextMonth(year, month) {
if (month == 12) {
return {
year: ++year,
month: 1,
};
} else {
return {
year: year,
month: ++month,
};
}
}
// 整合当月所有数据
getAllArr() {
const { currentYear, currentMonth } = this.state;
// 获取当月中,上月多余数据
const preMonthDateLen = this.getFirstDateWeek(currentYear, currentMonth); // 当月1号是周几 == 上月残余天数)
const preMonthDateArr = []; // 定义空数组
if (preMonthDateLen > 0) {
const { year, month } = this.preMonth(currentYear, currentMonth); // 获取上月 年、月
let day = this.getDateLen(year, month); // 获取上月天数
for (let i = 0; i < preMonthDateLen; i++) {
preMonthDateArr.unshift({ // 尾部追加
monthType: false, // 只是为了增加标识,区分当、上月
month,
year,
day: day,
date: `${year}${this.formatNumber(month)}${this.formatNumber(day)}`,
items: [],
});
day--;
}
}
// 获取当月数据
const currentMonthDateLen = this.getDateLen(currentYear, currentMonth); // 获取当月天数
const currentMonthDateArr = []; // 定义空数组
if (currentMonthDateLen > 0) {
for (let i = 1; i <= currentMonthDateLen; i++) {
const date = `${currentYear}${this.formatNumber(currentMonth)}${this.formatNumber(i)}`;
currentMonthDateArr.push({
monthType: true, // 只是为了增加标识,区分上下月
month: currentMonth,
year: currentYear,
day: i,
date: date,
items: [],
});
}
}
// 获取当月中,下月多余数据,
let nextMonthDateLen = 7 - (preMonthDateLen + currentMonthDateLen) % 7; // 下月多余天数
if (nextMonthDateLen === 7) {
nextMonthDateLen = 0;
}
// 月末的时候能看到下周
nextMonthDateLen += 7;
const nextMonthDateArr = []; // 定义空数组
if (nextMonthDateLen > 0) {
const { year, month } = this.nextMonth(this.state.currentYear, this.state.currentMonth);
for (let i = 1; i <= nextMonthDateLen; i++) {
const date = `${year}${this.formatNumber(month)}${this.formatNumber(i)}`;
nextMonthDateArr.push({
monthType: false,// 只是为了增加标识,区分当、下月
month,
year,
day: i,
date,
items: [],
});
}
}
const allArr = [...preMonthDateArr, ...currentMonthDateArr, ...nextMonthDateArr];
this.getDataList(allArr);
}
// 点击具体日期
getNowData(data) {
this.setState({
chooseData: data,
});
}
// 更换月份
handleTimeChange = e => {
const dataList = e.detail.value.toString().split('-');
const newYear = parseInt(dataList[0], 10);
const newMonth = parseInt(dataList[1], 10);
const { currentYear, currentMonth } = this.state;
if (newYear === currentYear && currentMonth === newMonth) {
return;
}
this.setState({
currentYear: newYear,
currentMonth: newMonth,
chooseData: {},
}, () => {
this.getAllArr();
});
};
// 格式化时间
formatNumber = n => {
n = n.toString();
return n[1] ? n : '0' + n;
}
handleGetClasname = (item, chooseData) => {
// 选中的日期
if (item.date === chooseData.date) {
return 'chooseDay';
}
if (!item.monthType) {
return 'ontInMonth';
}
}
render() {
const { allArr, currentYear, currentMonth, nowData, chooseData } = this.state;
return (
<Block>
<View className="calendar">
<View className='tit'>
<Picker
mode="date"
fields='month'
className='picker'
onChange={this.handleTimeChange}
>
<Text className='current'>{currentYear}年{currentMonth}月</Text>
<Image
src={require('../../statics/images/bluedown.png')}
className="xiala"
/>
</Picker>
</View>
<View className='content'>
<View className='showData'>
<View>一</View>
<View>二</View>
<View>三</View>
<View>四</View>
<View>五</View>
<View style='color: #999999'>六</View>
<View style='color: #999999'>日</View>
</View>
{
allArr.map(item => (
<View
key={item.date}
className='itemData'
onClick={() => this.getNowData(item)}
>
<View className={this.handleGetClasname(item, chooseData)} style={item.items.length ? 'color:rgba(69,69,83,1);' : 'color:rgba(153,153,153,1);'}>
<Text>{item.day}</Text>
{
item.date === nowData &&
<View className='toDay'>今</View>
}
</View>
</View>
))
}
</View>
</View>
</Block >
);
}
}
export default _C;
$morning: rgba(255, 86, 88, 1);
$afterNoon: rgba(3, 186, 185, 1);
.calendar {
width: 100%;
background: #fff;
padding: 0 32px 100px 32px;
.tit {
display: flex;
height: 99px;
line-height: 99px;
.picker {
width: 100%;
.current {
font-size: 28px;
font-weight: bold;
color: rgba(69, 69, 83, 1);
}
.xiala {
width: 16px;
height: 8px;
float: right;
margin-top: 50px;
}
}
}
.content {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
background: rgba(247, 247, 247, 0.8);
margin-bottom: 30px;
color: #999999;
padding: 30px;
}
.itemData {
width: 14%;
height: 70px;
line-height: 70px;
flex-shrink: 0;
font-size: 30px;
color: #2a2a2a;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.chooseDay {
background: rgba(0, 100, 255, 1) !important;
color: #ffffff !important;
width: 100%;
}
.ontInMonth {
background: rgba(229, 229, 229, 0.8);
width: 100%;
}
.toDay {
position: absolute;
color: rgba(50, 150, 250, 1);
font-size: 20px;
font-weight: bold;
font-family: PingFangSC-Regular, PingFang SC;
left: 10px;
bottom: -9px;
}
}
.opinion {
border-top: 2px solid #f2f2f2;
font-size: 28px;
font-weight: 500;
color: rgba(255, 2, 0, 1);
position: relative;
height: 86px;
line-height: 86px;
.leftArrow {
right: 24px;
bottom: 35px;
}
}
.showData {
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 100%;
background: rgba(247, 247, 247, 0.8);
view {
width: 14%;
height: 70px;
line-height: 70px;
text-align: center;
font-size: 28px;
font-weight: bold;
color: rgba(69, 69, 83, 1);
}
}
}
.btnBox {
display: flex;
height: 98px;
line-height: 98px;
font-size: 30px;
font-weight: 400;
position: fixed;
bottom: 0px;
width: 100%;
text-align: center;
.reject {
flex: 1;
color: rgba(40, 40, 40, 1);
background: rgba(251, 251, 251, 1);
}
.adopt {
flex: 1;
color: rgba(255, 255, 255, 1);
background: rgba(0, 100, 255, 1);
}
}
.modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
justify-content: center;
.modal-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.8);
z-index: -1;
.modal-tips {
width: 562px;
margin: 0 auto;
background-color: #fff;
border-radius: 11px;
overflow: hidden;
}
.modal-tips-item {
font-size: 24px;
color: #9a9aa4;
letter-spacing: 1px;
line-height: 33px;
margin-bottom: 33px;
padding: 0 60px;
}
.modal-tips-btn {
background: #0064ff;
border-radius: 100px;
height: 87px;
margin: 78px 60px 60px;
font-size: 30px;
color: #ffffff;
letter-spacing: 2.54px;
text-align: center;
line-height: 87px;
}
}
}
.datas {
margin-top: 16px;
display: flex;
font-size: 32px;
.text {
margin: auto;
text-align: center;
font-weight: bold;
width: 124px;
}
.dataBox {
min-height: 152px;
flex: 1;
background: rgba(247, 247, 247, 1);
position: relative;
.noData {
padding: 32px;
text-align: center;
color: rgba(153, 153, 153, 1);
width: 100%;
line-height: 88px;
}
.timeContent {
padding: 32px 32px 0 32px;
position: relative;
.halfDay {
font-size: 24px;
position: absolute;
right: 32px;
top: 32px;
.completed {
color: rgba(0, 100, 255, 1);
}
.unexecuted {
color: rgba(143, 143, 152, 1);
}
.notSub {
color: rgba(255, 86, 88, 1);
}
}
}
.detail {
padding-bottom: 32px;
position: relative;
.flexBox {
display: flex;
width: 100%;
}
.flexContent {
flex: 1;
}
.statusImg {
width: 30px;
height: 30px;
margin-top: 10px;
margin-right: 16px;
}
.detailStatus {
font-size: 28px;
font-weight: 500;
color: #454553;
.outside {
font-size: 24px;
font-weight: bold;
margin-left: 16px;
color: rgba(241, 158, 160, 1);
}
.undoTitle {
font-size: 24px;
font-weight: bold;
margin-left: 16px;
color: rgba(251, 71, 41, 1);
}
}
.detailTitle {
font-size: 28px;
font-weight: 400;
color: rgba(102, 102, 102, 1);
.detailContent {
color: rgba(69, 69, 83, 1);
font-weight: 500;
word-break: break-all;
}
}
}
.leftArrow {
right: 32px;
bottom: 45px;
}
}
}
.leftArrow {
position: absolute;
width: 8px;
height: 16px;
}
.morning {
.text {
color: $morning;
}
.dataBox {
border-left: 2px solid $morning;
}
.timeContent {
background-color: #fbeded;
}
}
.afterNoon {
margin-bottom: 30px;
.text {
color: $afterNoon;
}
.dataBox {
border-left: 2px solid $afterNoon;
}
.timeContent {
background-color: #edfbf7;
}
}
.plessGo {
font-size: 32px;
font-weight: 400;
color: rgba(153, 153, 153, 1);
line-height: 45px;
text-align: center;
}