-
4common/css/app.scss
-
4config/api.js
-
4manifest.json
-
8pages.json
-
83pages/indexEntry/signIn/signIn.vue
-
40pages/tabbar/index/index.vue
-
BINstatic/images/carIcon/sigin.png
-
BINstatic/images/carIcon/siginNo.png
-
BINstatic/images/carIcon/siginOk.png
-
BINstatic/images/icon/arrowDown.png
-
BINstatic/images/icon/arrowLeft.png
-
BINstatic/images/icon/arrowRight.png
-
BINstatic/images/mineIcon/emtryIcon (1).png
-
BINstatic/images/mineIcon/emtryIcon (2).png
-
BINstatic/images/mineIcon/emtryIcon (3).png
-
BINstatic/images/mineIcon/emtryIcon (4).png
-
BINstatic/images/mineIcon/minIcon (1).png
-
BINstatic/images/mineIcon/minIcon (2).png
-
BINstatic/images/mineIcon/minIcon (3).png
-
BINstatic/images/mineIcon/minIcon (4).png
-
BINstatic/images/mineIcon/minIcon (5).png
-
BINstatic/images/mineIcon/minIcon (6).png
-
BINstatic/images/mineIcon/minIcon (7).png
-
BINstatic/images/mineIcon/二维码.png
-
BINstatic/images/mineIcon/扫码.png
-
BINstatic/images/mineIcon/箭头 拷贝 2(1).png
-
BINstatic/images/mineIcon/箭头 拷贝 2.png
-
8uni_modules/zeng-calen/changelog.md
-
456uni_modules/zeng-calen/components/zeng-calen/zeng-calen - 副本.vue
-
490uni_modules/zeng-calen/components/zeng-calen/zeng-calen.vue
-
85uni_modules/zeng-calen/package.json
-
69uni_modules/zeng-calen/readme.md
@ -0,0 +1,83 @@ |
|||||
|
<template> |
||||
|
<view class="pageBg pad"> |
||||
|
<zeng-calen :actDay="actDay" :chooseDayLack="chooseDayLack" @onDayClick='onDayClick' :chooseDay="chooseDay"></zeng-calen> |
||||
|
<view class="btnBg" style="margin: 20rpx 0;">去签到/去签退</view> |
||||
|
<view class="card"> |
||||
|
<view class="h1"><text class="active">签到记录</text></view> |
||||
|
<view class="ul"> |
||||
|
<view class="li" v-for="(item,index) in 4" :key="index"> |
||||
|
<view class="lab">{{ index%2==0? '签退成功':'签到成功'}}</view> |
||||
|
<view class="date">2024-01-29 11:29</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import zengCalen from '@/uni_modules/zeng-calen/components/zeng-calen/zeng-calen' |
||||
|
export default { |
||||
|
components: {zengCalen}, |
||||
|
data() { |
||||
|
return { |
||||
|
actDay: [], //用户选择的日期 |
||||
|
chooseDay: ["2024-01-29", "2024-01-27", "2024-01-19", "2024-01-10"], //已被投标的数据 |
||||
|
chooseDayLack: ["2024-01-29", ], //已被投标的数据 |
||||
|
} |
||||
|
}, |
||||
|
onLoad() { |
||||
|
|
||||
|
}, |
||||
|
methods: { |
||||
|
// 展开日历 |
||||
|
onDayClick(data) { |
||||
|
this.actDay = [data] |
||||
|
return |
||||
|
let choose = data.date //用户点中的数据 |
||||
|
if (this.actDay.includes(choose)) { //如果用户点击的日期已经存在 |
||||
|
// 移除元素下标 |
||||
|
const index = this.actDay.indexOf(choose); |
||||
|
//删除用户点击的日期 |
||||
|
this.actDay.splice(index, 1) |
||||
|
} else if (this.chooseDay.includes(choose)) { //判断是否已经被投标 |
||||
|
uni.showToast({ |
||||
|
title: "这个日期已经被投标了", |
||||
|
icon: "none" |
||||
|
}) |
||||
|
} else { |
||||
|
//添加用户点击的日期 |
||||
|
this.actDay.push(choose) |
||||
|
} |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.pageBg { |
||||
|
padding-bottom: 30rpx; |
||||
|
} |
||||
|
.card { |
||||
|
padding-top: 20rpx; |
||||
|
.ul { |
||||
|
padding: 10rpx 30rpx; |
||||
|
.li { |
||||
|
padding: 30rpx 0; |
||||
|
border-bottom: 1px solid #f4f4f4; |
||||
|
&:last-child { |
||||
|
border: none; |
||||
|
} |
||||
|
.lab { |
||||
|
font-size: 28rpx; |
||||
|
color: #333; |
||||
|
} |
||||
|
.date { |
||||
|
font-size: 24rpx; |
||||
|
color: #999; |
||||
|
margin-top: 16rpx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
</style> |
After Width: 72 | Height: 100 | Size: 2.0 KiB |
After Width: 72 | Height: 100 | Size: 2.5 KiB |
After Width: 72 | Height: 100 | Size: 1.8 KiB |
After Width: 26 | Height: 15 | Size: 600 B |
After Width: 15 | Height: 26 | Size: 562 B |
After Width: 15 | Height: 26 | Size: 587 B |
After Width: 77 | Height: 77 | Size: 4.7 KiB |
After Width: 77 | Height: 77 | Size: 5.3 KiB |
After Width: 77 | Height: 77 | Size: 4.3 KiB |
After Width: 77 | Height: 77 | Size: 4.8 KiB |
After Width: 54 | Height: 51 | Size: 2.1 KiB |
After Width: 54 | Height: 51 | Size: 2.3 KiB |
After Width: 54 | Height: 51 | Size: 2.4 KiB |
After Width: 54 | Height: 51 | Size: 2.2 KiB |
After Width: 54 | Height: 51 | Size: 2.2 KiB |
After Width: 54 | Height: 51 | Size: 1.9 KiB |
After Width: 54 | Height: 51 | Size: 2.4 KiB |
After Width: 36 | Height: 36 | Size: 1.2 KiB |
After Width: 36 | Height: 36 | Size: 626 B |
After Width: 36 | Height: 36 | Size: 638 B |
After Width: 36 | Height: 36 | Size: 516 B |
@ -0,0 +1,8 @@ |
|||||
|
## 1.0.5(2023-05-20) |
||||
|
. |
||||
|
## 1.0.2(2023-04-06) |
||||
|
修复了左右切换的问题 |
||||
|
## 1.0.1(2023-04-05) |
||||
|
[1.0.1] |
||||
|
## 1.0.0(2023-04-05) |
||||
|
1.0.0 |
@ -0,0 +1,456 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
<!-- 日期选择器 --> |
||||
|
<view class="content"> |
||||
|
|
||||
|
<view class="calendar-wrapper"> |
||||
|
<!-- 选择月份 --> |
||||
|
<view class="header" v-if="headerBar"> |
||||
|
|
||||
|
<view class="iconfont iconarrow-left-bold pre" @click="changeMonth('pre')">上个月</view> |
||||
|
<view>{{y+'年'+formatNum(m)+'月'}}</view> |
||||
|
<view class="iconfont iconarrow-left-bold-copy next" @click="changeMonth('next')">下个月</view> |
||||
|
</view> |
||||
|
<!-- 星期栏 --> |
||||
|
<view class="week"> |
||||
|
<view class="week-day" v-for="(item, index) in weekDay" :key="index">{{ item }}</view> |
||||
|
</view> |
||||
|
<!-- 日历数字 --> |
||||
|
<view class="content" :style="{ height: height }"> |
||||
|
<view :style="{ top: positionTop + 'rpx' }" class="days"> |
||||
|
<view class="item" v-for="(item,index) in dates" :key="index"> |
||||
|
<view class="day" @click="selectOne(item, $event)" :class="{ |
||||
|
choose: getActday(`${item.year}-${item.month}-${item.date}`) && item.isCurM,//选中的日期 |
||||
|
chooseMarkDay:getChoose(`${item.year}-${item.month}-${item.date}`), |
||||
|
nolm: !item.isCurM,//不在本月的日 |
||||
|
today: isToday(item.year, item.month, item.date),//当日日期 |
||||
|
isWorkDay: isWorkDay(item.year, item.month, item.date)//周一至周五 |
||||
|
}"> |
||||
|
{{Number(item.date)}} |
||||
|
</view> |
||||
|
<view class="iconfont iconyixuanzhong" |
||||
|
:class="{markDays:getChoose(`${item.year}-${item.month}-${item.date}`)}" |
||||
|
v-if="getChoose(`${item.year}-${item.month}-${item.date}`) && !isMarkDay(item.year, item.month, item.date)&&item.isCurM"> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
// 星期几为第一天(0为星期日) |
||||
|
weekstart: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
// 标记的日期 |
||||
|
markDays: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
} |
||||
|
}, |
||||
|
//是否展示月份切换按钮 |
||||
|
headerBar: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
//过去日期是否不可点击 |
||||
|
disabledAfter: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
//接收用户选择的参数 |
||||
|
actDay: { |
||||
|
type: Array, |
||||
|
default: [], |
||||
|
}, |
||||
|
//接受已经被选择的参数 |
||||
|
chooseDay: { |
||||
|
type: Array, |
||||
|
default: [], |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
weektext: ['日', '一', '二', '三', '四', '五', '六'], |
||||
|
y: new Date().getFullYear(), // 年 |
||||
|
m: new Date().getMonth() + 1, // 月 |
||||
|
d: new Date().getDate(), //日 |
||||
|
dates: [], // 当前月的日期数据 |
||||
|
positionTop: 0, |
||||
|
choose: '', |
||||
|
chooseArr: [], |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
this.dates = this.monthDay(this.y, this.m); |
||||
|
console.log('') |
||||
|
}, |
||||
|
mounted() { |
||||
|
// this.choose = this.getToday().date; |
||||
|
}, |
||||
|
computed: { |
||||
|
// 顶部星期栏 |
||||
|
weekDay() { |
||||
|
return this.weektext.slice(this.weekstart).concat(this.weektext.slice(0, this.weekstart)); |
||||
|
}, |
||||
|
height() { |
||||
|
return (this.dates.length / 7) * 80 + 'rpx'; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
//已被投标的日期 |
||||
|
getChoose(day) { |
||||
|
for (let i = 0; i < this.chooseDay.length; i++) { |
||||
|
if (day == this.chooseDay[i]) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
//用户选择的日期 |
||||
|
getActday(day) { |
||||
|
for (let i = 0; i < this.actDay.length; i++) { |
||||
|
if (day == this.actDay[i] && !this.getChoose(day)) { |
||||
|
console.log("选中了", this.actDay); |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
formatNum(num) { |
||||
|
let res = Number(num); |
||||
|
return res < 10 ? '0' + res : res; |
||||
|
}, |
||||
|
getToday() { |
||||
|
let date = new Date(); |
||||
|
let y = date.getFullYear(); |
||||
|
let m = date.getMonth(); |
||||
|
let d = date.getDate(); |
||||
|
let week = new Date().getDay(); |
||||
|
let weekText = ['日', '一', '二', '三', '四', '五', '六']; |
||||
|
let formatWeek = '星期' + weekText[week]; |
||||
|
let today = { |
||||
|
date: y + '-' + this.formatNum(m + 1) + '-' + this.formatNum(d), |
||||
|
week: formatWeek |
||||
|
}; |
||||
|
return today; |
||||
|
}, |
||||
|
// 获取当前月份数据 |
||||
|
monthDay(y, month) { |
||||
|
let dates = []; |
||||
|
let m = Number(month); |
||||
|
let firstDayOfMonth = new Date(y, m - 1, 1).getDay(); // 当月第一天星期几 |
||||
|
let lastDateOfMonth = new Date(y, m, 0).getDate(); // 当月最后一天 |
||||
|
let lastDayOfLastMonth = new Date(y, m - 2, 0).getDate(); // 上一月的最后一天 |
||||
|
let weekstart = this.weekstart == 7 ? 0 : this.weekstart; |
||||
|
let startDay = (() => { |
||||
|
// 周初有几天是上个月的 |
||||
|
if (firstDayOfMonth == weekstart) { |
||||
|
return 0; |
||||
|
} else if (firstDayOfMonth > weekstart) { |
||||
|
return firstDayOfMonth - weekstart; |
||||
|
} else { |
||||
|
return 7 - weekstart + firstDayOfMonth; |
||||
|
} |
||||
|
})(); |
||||
|
let endDay = 7 - ((startDay + lastDateOfMonth) % 7); // 结束还有几天是下个月的 |
||||
|
for (let i = 1; i <= startDay; i++) { |
||||
|
dates.push({ |
||||
|
date: this.formatNum(lastDayOfLastMonth - startDay + i), |
||||
|
day: weekstart + i - 1 || 7, |
||||
|
month: m - 1 >= 0 ? this.formatNum(m - 1) : 12, |
||||
|
year: m - 1 >= 0 ? y : y - 1 |
||||
|
}); |
||||
|
} |
||||
|
for (let j = 1; j <= lastDateOfMonth; j++) { |
||||
|
dates.push({ |
||||
|
date: this.formatNum(j), |
||||
|
day: (j % 7) + firstDayOfMonth - 1 || 7, |
||||
|
month: this.formatNum(m), |
||||
|
year: y, |
||||
|
isCurM: true, //是否当前月份 |
||||
|
}); |
||||
|
} |
||||
|
for (let k = 1; k <= endDay; k++) { |
||||
|
dates.push({ |
||||
|
date: this.formatNum(k), |
||||
|
day: (lastDateOfMonth + startDay + weekstart + k - 1) % 7 || 7, |
||||
|
month: m + 1 <= 11 ? this.formatNum(m + 1) : 0, |
||||
|
year: m + 1 <= 11 ? y : y + 1 |
||||
|
}); |
||||
|
} |
||||
|
// console.log(dates); //日期 |
||||
|
return dates; |
||||
|
}, |
||||
|
isWorkDay(y, m, d) { |
||||
|
//是否工作日 |
||||
|
let ymd = `${y}/${m}/${d}`; |
||||
|
let formatDY = new Date(ymd.replace(/-/g, '/')); |
||||
|
let week = formatDY.getDay(); |
||||
|
if (week == 0 || week == 6) { |
||||
|
return false; |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
}, |
||||
|
isFutureDay(y, m, d) { |
||||
|
//是否未来日期 |
||||
|
let ymd = `${y}/${m}/${d}`; |
||||
|
let formatDY = new Date(ymd.replace(/-/g, '/')); |
||||
|
let showTime = formatDY.getTime(); |
||||
|
let curTime = new Date().getTime(); |
||||
|
if (showTime > curTime) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
// 标记日期 |
||||
|
isMarkDay(y, m, d) { |
||||
|
let flag = false; |
||||
|
for (let i = 0; i < this.markDays.length; i++) { |
||||
|
let dy = `${y}-${m}-${d}`; |
||||
|
if (this.markDays[i] == dy) { |
||||
|
flag = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
return flag; |
||||
|
}, |
||||
|
isToday(y, m, d) { |
||||
|
let checkD = y + '-' + m + '-' + d; |
||||
|
let today = this.getToday().date; |
||||
|
if (checkD == today) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
// 点击回调 |
||||
|
selectOne(i, event) { |
||||
|
|
||||
|
let date = `${i.year}-${i.month}-${i.date}`; |
||||
|
this.$emit('onDayClick', date); |
||||
|
return |
||||
|
let selectD = new Date(date).getTime(); |
||||
|
let curTime = new Date().getTime(); |
||||
|
let week = new Date(date).getDay(); |
||||
|
let weekText = ['日', '一', '二', '三', '四', '五', '六']; |
||||
|
let formatWeek = '星期' + weekText[week]; |
||||
|
let response = { |
||||
|
date: date, |
||||
|
week: formatWeek |
||||
|
}; |
||||
|
if (!i.isCurM) { |
||||
|
console.log('不在当前月范围内'); |
||||
|
return false; |
||||
|
} |
||||
|
if (selectD < curTime) { |
||||
|
if (this.disabledAfter) { |
||||
|
console.log('过去日期不可选'); |
||||
|
return false; |
||||
|
} else { |
||||
|
this.choose = date; |
||||
|
this.$emit('onDayClick', response); |
||||
|
} |
||||
|
} else { |
||||
|
|
||||
|
this.choose = date; |
||||
|
this.chooseArr.push(date) |
||||
|
this.$emit('onDayClick', response); |
||||
|
} |
||||
|
// console.log(response); |
||||
|
}, |
||||
|
//改变年月 |
||||
|
changYearMonth(y, m) { |
||||
|
this.dates = this.monthDay(y, m); |
||||
|
this.y = y; |
||||
|
this.m = m; |
||||
|
}, |
||||
|
changeMonth(type) { |
||||
|
if (type == 'pre') { |
||||
|
if (this.m + 1 == 2) { |
||||
|
this.m = 12; |
||||
|
this.y = this.y - 1; |
||||
|
} else { |
||||
|
this.m = this.m - 1; |
||||
|
} |
||||
|
} else { |
||||
|
if (this.m + 1 == 13) { |
||||
|
this.m = 1; |
||||
|
this.y = this.y + 1; |
||||
|
} else { |
||||
|
this.m = this.m + 1; |
||||
|
} |
||||
|
} |
||||
|
this.dates = this.monthDay(this.y, this.m); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
.content { |
||||
|
.content_box {} |
||||
|
|
||||
|
// .popup_body { |
||||
|
// height: 800rpx; |
||||
|
// border-radius: 20rpx 20rpx 0 0; |
||||
|
// background-color: #fff; |
||||
|
|
||||
|
// .close_popup { |
||||
|
// display: flex; |
||||
|
// flex-direction: row-reverse; |
||||
|
// padding: 20rpx; |
||||
|
|
||||
|
// .iconfont { |
||||
|
// font-size: 36rpx; |
||||
|
// } |
||||
|
// } |
||||
|
|
||||
|
.calendar-wrapper { |
||||
|
color: #6f6d6d; |
||||
|
font-size: 28rpx; |
||||
|
text-align: center; |
||||
|
background-color: #fff; |
||||
|
padding-bottom: 10rpx; |
||||
|
border-radius: 20rpx; |
||||
|
|
||||
|
.header { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
height: 88rpx; |
||||
|
color: #42464A; |
||||
|
font-size: 32rpx; |
||||
|
font-weight: bold; |
||||
|
border-bottom: 2rpx solid #f2f2f2; |
||||
|
|
||||
|
.pre, |
||||
|
.next { |
||||
|
font-size: 28rpx; |
||||
|
padding: 8rpx 15rpx; |
||||
|
border-radius: 10rpx; |
||||
|
// border: 2rpx solid #dcdfe6; |
||||
|
} |
||||
|
|
||||
|
.pre { |
||||
|
margin-right: 30rpx; |
||||
|
} |
||||
|
|
||||
|
.next { |
||||
|
margin-left: 30rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.week { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
height: 80rpx; |
||||
|
line-height: 80rpx; |
||||
|
border-bottom: 1rpx solid rgba(255, 255, 255, 0.2); |
||||
|
|
||||
|
view { |
||||
|
flex: 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.content { |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
transition: height 0.4s ease; |
||||
|
|
||||
|
.days { |
||||
|
transition: top 0.3s; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
flex-wrap: wrap; |
||||
|
position: relative; |
||||
|
|
||||
|
.item { |
||||
|
position: relative; |
||||
|
display: block; |
||||
|
height: 80rpx; |
||||
|
line-height: 80rpx; |
||||
|
width: calc(100% / 7); |
||||
|
|
||||
|
.day { |
||||
|
font-style: normal; |
||||
|
display: inline-block; |
||||
|
vertical-align: middle; |
||||
|
width: 60rpx; |
||||
|
height: 60rpx; |
||||
|
line-height: 60rpx; |
||||
|
overflow: hidden; |
||||
|
border-radius: 60rpx; |
||||
|
|
||||
|
&.choose { |
||||
|
background-color: #4bcdc4; |
||||
|
color: #fff; |
||||
|
} |
||||
|
|
||||
|
&.chooseMarkDay { |
||||
|
//已被投标的日期 |
||||
|
// background-color: #43a761; |
||||
|
color: #5b5b5b; |
||||
|
} |
||||
|
|
||||
|
&.nolm { |
||||
|
color: #fff; |
||||
|
opacity: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.isWorkDay { |
||||
|
color: #25272a; |
||||
|
} |
||||
|
|
||||
|
.notSigned { |
||||
|
font-style: normal; |
||||
|
width: 8rpx; |
||||
|
height: 8rpx; |
||||
|
background: #fa7268; |
||||
|
border-radius: 10rpx; |
||||
|
position: absolute; |
||||
|
left: 50%; |
||||
|
bottom: 0; |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
|
||||
|
.today { |
||||
|
color: #fff; |
||||
|
background-color: #a0eac1; |
||||
|
} |
||||
|
|
||||
|
.workDay { |
||||
|
font-style: normal; |
||||
|
width: 8rpx; |
||||
|
height: 8rpx; |
||||
|
background: #4d7df9; |
||||
|
border-radius: 10rpx; |
||||
|
position: absolute; |
||||
|
left: 50%; |
||||
|
bottom: 0; |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
|
||||
|
.markDays { |
||||
|
font-style: normal; |
||||
|
position: absolute; |
||||
|
top: 2rpx; |
||||
|
right: 11rpx; |
||||
|
pointer-events: none; |
||||
|
font-size: 80rpx; |
||||
|
color: rgba(160, 234, 193, 0.5); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// } |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,490 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
<!-- 日期选择器 --> |
||||
|
<view class="content"> |
||||
|
|
||||
|
<view class="calendar-wrapper"> |
||||
|
<!-- 选择月份 --> |
||||
|
<view class="header" v-if="headerBar"> |
||||
|
<view class="iconarrow" @click="changeMonth('pre')"> |
||||
|
<image src="@/static/images/icon/arrowLeft.png" mode=""></image> |
||||
|
</view> |
||||
|
<view>{{y+'年'+formatNum(m)+'月'}}</view> |
||||
|
<view class="iconarrow" @click="changeMonth('next')"> |
||||
|
<image src="@/static/images/icon/arrowRight.png" mode=""></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!-- 星期栏 --> |
||||
|
<view class="week"> |
||||
|
<view class="week-day" v-for="(item, index) in weekDay" :key="index">{{ item }}</view> |
||||
|
</view> |
||||
|
<!-- 日历数字 --> |
||||
|
<view class="content" :style="{ height: height }"> |
||||
|
<view :style="{ top: positionTop + 'rpx' }" class="days"> |
||||
|
<view class="item" v-for="(item,index) in dates" :key="index"> |
||||
|
<view class="day" @click="selectOne(item, $event)" :class="{ |
||||
|
choose: getActday(`${item.year}-${item.month}-${item.date}`) && item.isCurM,//选中的日期 |
||||
|
nolm: !item.isCurM,//不在本月的日 |
||||
|
today: isToday(item.year, item.month, item.date),//当日日期 |
||||
|
isWorkDay: isWorkDay(item.year, item.month, item.date)//周一至周五 |
||||
|
}"> |
||||
|
{{Number(item.date)}} |
||||
|
</view> |
||||
|
<view class="dian" v-if="getChoose(`${item.year}-${item.month}-${item.date}`)" :class="{red: getChooseLack(`${item.year}-${item.month}-${item.date}`)}"></view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
// 星期几为第一天(0为星期日) |
||||
|
weekstart: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
}, |
||||
|
// 缺卡的日期 |
||||
|
chooseDayLack: { |
||||
|
type: Array, |
||||
|
default: () => { |
||||
|
return []; |
||||
|
} |
||||
|
}, |
||||
|
//是否展示月份切换按钮 |
||||
|
headerBar: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
//过去日期是否不可点击 |
||||
|
disabledAfter: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
//接收用户选择的参数 |
||||
|
actDay: { |
||||
|
type: Array, |
||||
|
default: [], |
||||
|
}, |
||||
|
//接受已经被选择的参数 |
||||
|
chooseDay: { |
||||
|
type: Array, |
||||
|
default: [], |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
weektext: ['日', '一', '二', '三', '四', '五', '六'], |
||||
|
y: new Date().getFullYear(), // 年 |
||||
|
m: new Date().getMonth() + 1, // 月 |
||||
|
d: new Date().getDate(), //日 |
||||
|
dates: [], // 当前月的日期数据 |
||||
|
positionTop: 0, |
||||
|
choose: '', |
||||
|
chooseArr: [], |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
this.dates = this.monthDay(this.y, this.m); |
||||
|
console.log(this.dates) |
||||
|
}, |
||||
|
mounted() { |
||||
|
// this.choose = this.getToday().date; |
||||
|
}, |
||||
|
computed: { |
||||
|
// 顶部星期栏 |
||||
|
weekDay() { |
||||
|
return this.weektext.slice(this.weekstart).concat(this.weektext.slice(0, this.weekstart)); |
||||
|
}, |
||||
|
height() { |
||||
|
return (this.dates.length / 7) * 80 + 'rpx'; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
//已被投标的日期 |
||||
|
getChoose(day) { |
||||
|
for (let i = 0; i < this.chooseDay.length; i++) { |
||||
|
if (day == this.chooseDay[i]) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
getChooseLack(day) { |
||||
|
for (let i = 0; i < this.chooseDayLack.length; i++) { |
||||
|
if (day == this.chooseDayLack[i]) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
//用户选择的日期 |
||||
|
getActday(day) { |
||||
|
for (let i = 0; i < this.actDay.length; i++) { |
||||
|
if (day == this.actDay[i] && this.getChoose(day)) { |
||||
|
console.log("选中了?", this.actDay); |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
formatNum(num) { |
||||
|
let res = Number(num); |
||||
|
return res < 10 ? '0' + res : res; |
||||
|
}, |
||||
|
getToday() { |
||||
|
let date = new Date(); |
||||
|
let y = date.getFullYear(); |
||||
|
let m = date.getMonth(); |
||||
|
let d = date.getDate(); |
||||
|
let week = new Date().getDay(); |
||||
|
let weekText = ['日', '一', '二', '三', '四', '五', '六']; |
||||
|
let formatWeek = '星期' + weekText[week]; |
||||
|
let today = { |
||||
|
date: y + '-' + this.formatNum(m + 1) + '-' + this.formatNum(d), |
||||
|
week: formatWeek |
||||
|
}; |
||||
|
return today; |
||||
|
}, |
||||
|
// 获取当前月份数据 |
||||
|
monthDay(y, month) { |
||||
|
let dates = []; |
||||
|
let m = Number(month); |
||||
|
let firstDayOfMonth = new Date(y, m - 1, 1).getDay(); // 当月第一天星期几 |
||||
|
let lastDateOfMonth = new Date(y, m, 0).getDate(); // 当月最后一天 |
||||
|
let lastDayOfLastMonth = new Date(y, m - 2, 0).getDate(); // 上一月的最后一天 |
||||
|
let weekstart = this.weekstart == 7 ? 0 : this.weekstart; |
||||
|
let startDay = (() => { |
||||
|
// 周初有几天是上个月的 |
||||
|
if (firstDayOfMonth == weekstart) { |
||||
|
return 0; |
||||
|
} else if (firstDayOfMonth > weekstart) { |
||||
|
return firstDayOfMonth - weekstart; |
||||
|
} else { |
||||
|
return 7 - weekstart + firstDayOfMonth; |
||||
|
} |
||||
|
})(); |
||||
|
let endDay = 7 - ((startDay + lastDateOfMonth) % 7); // 结束还有几天是下个月的 |
||||
|
for (let i = 1; i <= startDay; i++) { |
||||
|
dates.push({ |
||||
|
date: this.formatNum(lastDayOfLastMonth - startDay + i), |
||||
|
day: weekstart + i - 1 || 7, |
||||
|
month: m - 1 >= 0 ? this.formatNum(m - 1) : 12, |
||||
|
year: m - 1 >= 0 ? y : y - 1 |
||||
|
}); |
||||
|
} |
||||
|
for (let j = 1; j <= lastDateOfMonth; j++) { |
||||
|
dates.push({ |
||||
|
date: this.formatNum(j), |
||||
|
day: (j % 7) + firstDayOfMonth - 1 || 7, |
||||
|
month: this.formatNum(m), |
||||
|
year: y, |
||||
|
isCurM: true, //是否当前月份 |
||||
|
}); |
||||
|
} |
||||
|
for (let k = 1; k <= endDay; k++) { |
||||
|
dates.push({ |
||||
|
date: this.formatNum(k), |
||||
|
day: (lastDateOfMonth + startDay + weekstart + k - 1) % 7 || 7, |
||||
|
month: m + 1 <= 11 ? this.formatNum(m + 1) : 0, |
||||
|
year: m + 1 <= 11 ? y : y + 1 |
||||
|
}); |
||||
|
} |
||||
|
// console.log(dates); //日期 |
||||
|
return dates; |
||||
|
}, |
||||
|
isWorkDay(y, m, d) { |
||||
|
//是否工作日 |
||||
|
let ymd = `${y}/${m}/${d}`; |
||||
|
let formatDY = new Date(ymd.replace(/-/g, '/')); |
||||
|
let week = formatDY.getDay(); |
||||
|
if (week == 0 || week == 6) { |
||||
|
return false; |
||||
|
} else { |
||||
|
return true; |
||||
|
} |
||||
|
}, |
||||
|
isFutureDay(y, m, d) { |
||||
|
//是否未来日期 |
||||
|
let ymd = `${y}/${m}/${d}`; |
||||
|
let formatDY = new Date(ymd.replace(/-/g, '/')); |
||||
|
let showTime = formatDY.getTime(); |
||||
|
let curTime = new Date().getTime(); |
||||
|
if (showTime > curTime) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
// 标记日期 |
||||
|
isMarkDay(y, m, d) { |
||||
|
let flag = false; |
||||
|
for (let i = 0; i < this.markDays.length; i++) { |
||||
|
let dy = `${y}-${m}-${d}`; |
||||
|
if (this.markDays[i] == dy) { |
||||
|
flag = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
return flag; |
||||
|
}, |
||||
|
isToday(y, m, d) { |
||||
|
let checkD = y + '-' + m + '-' + d; |
||||
|
let today = this.getToday().date; |
||||
|
if (checkD == today) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
// 点击回调 |
||||
|
selectOne(i, event) { |
||||
|
|
||||
|
let date = `${i.year}-${i.month}-${i.date}`; |
||||
|
let flag = this.getChoose(date) |
||||
|
if(!flag) return this.$u.toast('无预约') |
||||
|
this.$emit('onDayClick', date); |
||||
|
return |
||||
|
let selectD = new Date(date).getTime(); |
||||
|
let curTime = new Date().getTime(); |
||||
|
let week = new Date(date).getDay(); |
||||
|
let weekText = ['日', '一', '二', '三', '四', '五', '六']; |
||||
|
let formatWeek = '星期' + weekText[week]; |
||||
|
let response = { |
||||
|
date: date, |
||||
|
week: formatWeek |
||||
|
}; |
||||
|
if (!i.isCurM) { |
||||
|
console.log('不在当前月范围内'); |
||||
|
return false; |
||||
|
} |
||||
|
if (selectD < curTime) { |
||||
|
if (this.disabledAfter) { |
||||
|
console.log('过去日期不可选'); |
||||
|
return false; |
||||
|
} else { |
||||
|
this.choose = date; |
||||
|
this.$emit('onDayClick', response); |
||||
|
} |
||||
|
} else { |
||||
|
|
||||
|
this.choose = date; |
||||
|
this.chooseArr.push(date) |
||||
|
this.$emit('onDayClick', response); |
||||
|
} |
||||
|
// console.log(response); |
||||
|
}, |
||||
|
//改变年月 |
||||
|
changYearMonth(y, m) { |
||||
|
this.dates = this.monthDay(y, m); |
||||
|
this.y = y; |
||||
|
this.m = m; |
||||
|
}, |
||||
|
changeMonth(type) { |
||||
|
if (type == 'pre') { |
||||
|
if (this.m + 1 == 2) { |
||||
|
this.m = 12; |
||||
|
this.y = this.y - 1; |
||||
|
} else { |
||||
|
this.m = this.m - 1; |
||||
|
} |
||||
|
} else { |
||||
|
if (this.m + 1 == 13) { |
||||
|
this.m = 1; |
||||
|
this.y = this.y + 1; |
||||
|
} else { |
||||
|
this.m = this.m + 1; |
||||
|
} |
||||
|
} |
||||
|
this.dates = this.monthDay(this.y, this.m); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
.content { |
||||
|
.content_box {} |
||||
|
.dian { |
||||
|
position: absolute; |
||||
|
width: 8rpx; |
||||
|
height: 8rpx; |
||||
|
background: #4385FE; |
||||
|
border-radius: 50%; |
||||
|
bottom: 0rpx; |
||||
|
left: 50%; |
||||
|
transform: translateX(-50%); |
||||
|
line-height: 0; |
||||
|
&.red { |
||||
|
background: #EEB65F; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.iconarrow { |
||||
|
width: 60rpx; |
||||
|
height: 60rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
image { |
||||
|
width: 16rpx; |
||||
|
height: 26rpx; |
||||
|
display: block; |
||||
|
} |
||||
|
} |
||||
|
// .popup_body { |
||||
|
// height: 800rpx; |
||||
|
// border-radius: 20rpx 20rpx 0 0; |
||||
|
// background-color: #fff; |
||||
|
|
||||
|
// .close_popup { |
||||
|
// display: flex; |
||||
|
// flex-direction: row-reverse; |
||||
|
// padding: 20rpx; |
||||
|
|
||||
|
// .iconfont { |
||||
|
// font-size: 36rpx; |
||||
|
// } |
||||
|
// } |
||||
|
|
||||
|
.calendar-wrapper { |
||||
|
color: #6f6d6d; |
||||
|
font-size: 28rpx; |
||||
|
text-align: center; |
||||
|
background-color: #fff; |
||||
|
padding-bottom: 10rpx; |
||||
|
border-radius: 20rpx; |
||||
|
|
||||
|
.header { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
height: 88rpx; |
||||
|
color: #42464A; |
||||
|
font-size: 32rpx; |
||||
|
font-weight: bold; |
||||
|
border-bottom: 2rpx solid #f2f2f2; |
||||
|
|
||||
|
.pre, |
||||
|
.next { |
||||
|
font-size: 28rpx; |
||||
|
padding: 8rpx 15rpx; |
||||
|
border-radius: 10rpx; |
||||
|
// border: 2rpx solid #dcdfe6; |
||||
|
} |
||||
|
|
||||
|
.pre { |
||||
|
margin-right: 30rpx; |
||||
|
} |
||||
|
|
||||
|
.next { |
||||
|
margin-left: 30rpx; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.week { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
height: 80rpx; |
||||
|
line-height: 80rpx; |
||||
|
border-bottom: 1rpx solid rgba(255, 255, 255, 0.2); |
||||
|
|
||||
|
view { |
||||
|
flex: 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.content { |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
transition: height 0.4s ease; |
||||
|
|
||||
|
.days { |
||||
|
transition: top 0.3s; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
flex-wrap: wrap; |
||||
|
position: relative; |
||||
|
|
||||
|
.item { |
||||
|
position: relative; |
||||
|
display: block; |
||||
|
height: 80rpx; |
||||
|
line-height: 80rpx; |
||||
|
width: calc(100% / 7); |
||||
|
|
||||
|
.day { |
||||
|
font-style: normal; |
||||
|
display: inline-block; |
||||
|
vertical-align: middle; |
||||
|
width: 60rpx; |
||||
|
height: 60rpx; |
||||
|
line-height: 60rpx; |
||||
|
overflow: hidden; |
||||
|
border-radius: 60rpx; |
||||
|
|
||||
|
&.choose { |
||||
|
background-color: #4385FE; |
||||
|
color: #fff; |
||||
|
} |
||||
|
|
||||
|
&.chooseMarkDay { |
||||
|
//已被投标的日期 |
||||
|
background-color: #43a761; |
||||
|
// color: #5b5b5b; |
||||
|
} |
||||
|
|
||||
|
&.nolm { |
||||
|
color: #fff; |
||||
|
opacity: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.isWorkDay { |
||||
|
color: #25272a; |
||||
|
} |
||||
|
|
||||
|
.notSigned { |
||||
|
font-style: normal; |
||||
|
width: 8rpx; |
||||
|
height: 8rpx; |
||||
|
background: #fa7268; |
||||
|
border-radius: 10rpx; |
||||
|
position: absolute; |
||||
|
left: 50%; |
||||
|
bottom: 0; |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
|
||||
|
.today { |
||||
|
color: #4385FE; |
||||
|
background-color: #D9E7FF; |
||||
|
} |
||||
|
|
||||
|
.workDay { |
||||
|
font-style: normal; |
||||
|
width: 8rpx; |
||||
|
height: 8rpx; |
||||
|
background: #4d7df9; |
||||
|
border-radius: 10rpx; |
||||
|
position: absolute; |
||||
|
left: 50%; |
||||
|
bottom: 0; |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
|
||||
|
.markDays { |
||||
|
font-style: normal; |
||||
|
position: absolute; |
||||
|
top: 2rpx; |
||||
|
right: 11rpx; |
||||
|
pointer-events: none; |
||||
|
font-size: 80rpx; |
||||
|
color: rgba(160, 234, 193, 0.5); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// } |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,85 @@ |
|||||
|
{ |
||||
|
"id": "zeng-calen", |
||||
|
"displayName": "日历组件可选择周与月标记打卡支持左右切换", |
||||
|
"version": "1.0.5", |
||||
|
"description": "zeng-calen日历组件可选择周与月支持左右切换", |
||||
|
"keywords": [ |
||||
|
"日历", |
||||
|
"多选", |
||||
|
"单选", |
||||
|
"日期选择", |
||||
|
"标记打卡" |
||||
|
], |
||||
|
"repository": "", |
||||
|
"engines": { |
||||
|
"HBuilderX": "^3.4.2" |
||||
|
}, |
||||
|
"dcloudext": { |
||||
|
"type": "component-vue", |
||||
|
"sale": { |
||||
|
"regular": { |
||||
|
"price": "0.00" |
||||
|
}, |
||||
|
"sourcecode": { |
||||
|
"price": "0.00" |
||||
|
} |
||||
|
}, |
||||
|
"contact": { |
||||
|
"qq": "" |
||||
|
}, |
||||
|
"declaration": { |
||||
|
"ads": "无", |
||||
|
"data": "插件不采集任何数据", |
||||
|
"permissions": "无" |
||||
|
}, |
||||
|
"npmurl": "" |
||||
|
}, |
||||
|
"uni_modules": { |
||||
|
"dependencies": [], |
||||
|
"encrypt": [], |
||||
|
"platforms": { |
||||
|
"cloud": { |
||||
|
"tcb": "y", |
||||
|
"aliyun": "y" |
||||
|
}, |
||||
|
"client": { |
||||
|
"Vue": { |
||||
|
"vue2": "y", |
||||
|
"vue3": "y" |
||||
|
}, |
||||
|
"App": { |
||||
|
"app-vue": "y", |
||||
|
"app-nvue": "y" |
||||
|
}, |
||||
|
"H5-mobile": { |
||||
|
"Safari": "y", |
||||
|
"Android Browser": "y", |
||||
|
"微信浏览器(Android)": "y", |
||||
|
"QQ浏览器(Android)": "y" |
||||
|
}, |
||||
|
"H5-pc": { |
||||
|
"Chrome": "y", |
||||
|
"IE": "y", |
||||
|
"Edge": "y", |
||||
|
"Firefox": "y", |
||||
|
"Safari": "y" |
||||
|
}, |
||||
|
"小程序": { |
||||
|
"微信": "y", |
||||
|
"阿里": "y", |
||||
|
"百度": "y", |
||||
|
"字节跳动": "y", |
||||
|
"QQ": "y", |
||||
|
"钉钉": "y", |
||||
|
"快手": "y", |
||||
|
"飞书": "y", |
||||
|
"京东": "y" |
||||
|
}, |
||||
|
"快应用": { |
||||
|
"华为": "u", |
||||
|
"联盟": "u" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,69 @@ |
|||||
|
|
||||
|
|
||||
|
### 代码块 |
||||
|
|
||||
|
直接引入就可以使用,代码如下: |
||||
|
```xml |
||||
|
<template> |
||||
|
<view class="content"> |
||||
|
<zeng-calen :actDay="actDay" :chooseDay="chooseDay" @onDayClick='onDayClick'></zeng-calen> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
actDay: [], //用户选择的日期 |
||||
|
chooseDay: ["2023-04-13", "2023-04-15", "2023-04-16", "2023-04-05"], //已被投标的数据 |
||||
|
} |
||||
|
}, |
||||
|
onLoad() { |
||||
|
|
||||
|
}, |
||||
|
methods: { |
||||
|
// 展开日历 |
||||
|
onDayClick(data) { |
||||
|
let choose = data.date //用户点中的数据 |
||||
|
if (this.actDay.includes(choose)) { //如果用户点击的日期已经存在 |
||||
|
// 移除元素下标 |
||||
|
const index = this.actDay.indexOf(choose); |
||||
|
//删除用户点击的日期 |
||||
|
this.actDay.splice(index, 1) |
||||
|
} else if (this.chooseDay.includes(choose)) { //判断是否已经被投标 |
||||
|
uni.showToast({ |
||||
|
title: "这个日期已经被投标了", |
||||
|
icon: "none" |
||||
|
}) |
||||
|
} else { |
||||
|
//添加用户点击的日期 |
||||
|
this.actDay.push(choose) |
||||
|
} |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
|
||||
|
</style> |
||||
|
|
||||
|
``` |
||||
|
### |
||||
|
Calendar Props: |
||||
|
|
||||
|
| 属性名 | 类型 | 默认值 | 说明 | |
||||
|
| :----- | :--: | :-------: | :-------: | |
||||
|
| weekstart | Number | 0 | 星期几为第一天(0为星期日) | |
||||
|
| markDays | Array | null | 已标记的日期 | |
||||
|
| headerBar | Boolean | true | 是否展示月份切换按钮 | |
||||
|
| disabledAfter | Boolean | false | 过去日期是否不可点击 | |
||||
|
| actDay | Array | null | 接收用户选择的参数 | |
||||
|
| chooseDay | Array | null | 接受已经被选择的参数 | |
||||
|
|
||||
|
### |
||||
|
Calendar Events: |
||||
|
|
||||
|
| 事件 | 说明 | |
||||
|
| :----- | :--: | |
||||
|
| onDayClick | 选中的日期 | |