From 66d2c8d8c97e19fdbd969f97dd3d6a28f27c415f Mon Sep 17 00:00:00 2001
From: quanyawei <401863037@qq.com>
Date: Wed, 01 Nov 2023 16:07:03 +0800
Subject: [PATCH] fix:小程序分享功能和秒级数据
---
uni_modules/uview-ui/components/u-calendar/month.vue | 579 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 579 insertions(+), 0 deletions(-)
diff --git a/uni_modules/uview-ui/components/u-calendar/month.vue b/uni_modules/uview-ui/components/u-calendar/month.vue
new file mode 100644
index 0000000..c20937f
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-calendar/month.vue
@@ -0,0 +1,579 @@
+<template>
+ <view class="u-calendar-month-wrapper" ref="u-calendar-month-wrapper">
+ <view v-for="(item, index) in months" :key="index" :class="[`u-calendar-month-${index}`]"
+ :ref="`u-calendar-month-${index}`" :id="`month-${index}`">
+ <text v-if="index !== 0" class="u-calendar-month__title">{{ item.year }}���{{ item.month }}���</text>
+ <view class="u-calendar-month__days">
+ <view v-if="showMark" class="u-calendar-month__days__month-mark-wrapper">
+ <text class="u-calendar-month__days__month-mark-wrapper__text">{{ item.month }}</text>
+ </view>
+ <view class="u-calendar-month__days__day" v-for="(item1, index1) in item.date" :key="index1"
+ :style="[dayStyle(index, index1, item1)]" @tap="clickHandler(index, index1, item1)"
+ :class="[item1.selected && 'u-calendar-month__days__day__select--selected']">
+ <view class="u-calendar-month__days__day__select" :style="[daySelectStyle(index, index1, item1)]">
+ <text class="u-calendar-month__days__day__select__info"
+ :class="[item1.disabled && 'u-calendar-month__days__day__select__info--disabled']"
+ :style="[textStyle(item1)]">{{ item1.day }}</text>
+ <text v-if="getBottomInfo(index, index1, item1)"
+ class="u-calendar-month__days__day__select__buttom-info"
+ :class="[item1.disabled && 'u-calendar-month__days__day__select__buttom-info--disabled']"
+ :style="[textStyle(item1)]">{{ getBottomInfo(index, index1, item1) }}</text>
+ <text v-if="item1.dot" class="u-calendar-month__days__day__select__dot"></text>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+</template>
+
+<script>
+ // #ifdef APP-NVUE
+ // ������nvue���������������������������������������������������������������������������
+ const dom = uni.requireNativePlugin('dom')
+ // #endif
+ import dayjs from '../../libs/util/dayjs.js';
+ export default {
+ name: 'u-calendar-month',
+ mixins: [uni.$u.mpMixin, uni.$u.mixin],
+ props: {
+ // ���������������������������
+ showMark: {
+ type: Boolean,
+ default: true
+ },
+ // ������������������������������������������������
+ color: {
+ type: String,
+ default: '#3c9cff'
+ },
+ // ������������
+ months: {
+ type: Array,
+ default: () => []
+ },
+ // ������������������
+ mode: {
+ type: String,
+ default: 'single'
+ },
+ // ������������
+ rowHeight: {
+ type: [String, Number],
+ default: 58
+ },
+ // mode=multiple���������������������������������
+ maxCount: {
+ type: [String, Number],
+ default: Infinity
+ },
+ // mode=range������������������������������������������
+ startText: {
+ type: String,
+ default: '������'
+ },
+ // mode=range���������������������������������������������
+ endText: {
+ type: String,
+ default: '������'
+ },
+ // ������������������������mode���multiple���range������������������������
+ defaultDate: {
+ type: [Array, String, Date],
+ default: null
+ },
+ // ���������������������
+ minDate: {
+ type: [String, Number],
+ default: 0
+ },
+ // ������������������
+ maxDate: {
+ type: [String, Number],
+ default: 0
+ },
+ // ������������������maxDate���������������������������
+ maxMonth: {
+ type: [String, Number],
+ default: 2
+ },
+ // ���������������������������������������������������������
+ readonly: {
+ type: Boolean,
+ default: uni.$u.props.calendar.readonly
+ },
+ // ���������������������������������������������������mode = range���������
+ maxRange: {
+ type: [Number, String],
+ default: Infinity
+ },
+ // ���������������������������������������������������������mode = range���������
+ rangePrompt: {
+ type: String,
+ default: ''
+ },
+ // ���������������������������������������������������������������������mode = range���������
+ showRangePrompt: {
+ type: Boolean,
+ default: true
+ },
+ // ������������������������������������������������������mode = range���������
+ allowSameDay: {
+ type: Boolean,
+ default: false
+ }
+ },
+ data() {
+ return {
+ // ���������������������
+ width: 0,
+ // ���������������������item
+ item: {},
+ selected: []
+ }
+ },
+ watch: {
+ selectedChange: {
+ immediate: true,
+ handler(n) {
+ this.setDefaultDate()
+ }
+ }
+ },
+ computed: {
+ // ���������������������������������������������������������������������������������
+ selectedChange() {
+ return [this.minDate, this.maxDate, this.defaultDate]
+ },
+ dayStyle(index1, index2, item) {
+ return (index1, index2, item) => {
+ const style = {}
+ let week = item.week
+ // ������������������������������������2���������
+ const dayWidth = Number(parseFloat(this.width / 7).toFixed(3).slice(0, -1))
+ // ���������������������������
+ // #ifdef APP-NVUE
+ style.width = uni.$u.addUnit(dayWidth)
+ // #endif
+ style.height = uni.$u.addUnit(this.rowHeight)
+ if (index2 === 0) {
+ // ������������������������������������0������������������������������������������������������������������������item������
+ week = (week === 0 ? 7 : week) - 1
+ style.marginLeft = uni.$u.addUnit(week * dayWidth)
+ }
+ if (this.mode === 'range') {
+ // ������������������������������������DCloud���������iOS������������������������������������������bug
+ style.paddingLeft = 0
+ style.paddingRight = 0
+ style.paddingBottom = 0
+ style.paddingTop = 0
+ }
+ return style
+ }
+ },
+ daySelectStyle() {
+ return (index1, index2, item) => {
+ let date = dayjs(item.date).format("YYYY-MM-DD"),
+ style = {}
+ // ������date���������selected������������������������������������������0���������������dateSame���������������������������includes������
+ if (this.selected.some(item => this.dateSame(item, date))) {
+ style.backgroundColor = this.color
+ }
+ if (this.mode === 'single') {
+ if (date === this.selected[0]) {
+ // ���������������nvue������������������������������������������������������������������������������
+ style.borderTopLeftRadius = '3px'
+ style.borderBottomLeftRadius = '3px'
+ style.borderTopRightRadius = '3px'
+ style.borderBottomRightRadius = '3px'
+ }
+ } else if (this.mode === 'range') {
+ if (this.selected.length >= 2) {
+ const len = this.selected.length - 1
+ // ���������������������������������������������������
+ if (this.dateSame(date, this.selected[0])) {
+ style.borderTopLeftRadius = '3px'
+ style.borderBottomLeftRadius = '3px'
+ }
+ // ������������������������������������������������������
+ if (this.dateSame(date, this.selected[len])) {
+ style.borderTopRightRadius = '3px'
+ style.borderBottomRightRadius = '3px'
+ }
+ // ���������������������������������������������������������������������������������������������������������������������������������������
+ if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
+ .selected[len]))) {
+ style.backgroundColor = uni.$u.colorGradient(this.color, '#ffffff', 100)[90]
+ // ������������������������������������������������������������������������mark������������
+ style.opacity = 0.7
+ }
+ } else if (this.selected.length === 1) {
+ // ������������������������������������DCloud���������iOS������������������������������������������bug
+ // ������������������������������nvue���iOS���uni-app���bug���������������������������
+ style.borderTopLeftRadius = '3px'
+ style.borderBottomLeftRadius = '3px'
+ }
+ } else {
+ if (this.selected.some(item => this.dateSame(item, date))) {
+ style.borderTopLeftRadius = '3px'
+ style.borderBottomLeftRadius = '3px'
+ style.borderTopRightRadius = '3px'
+ style.borderBottomRightRadius = '3px'
+ }
+ }
+ return style
+ }
+ },
+ // ���������������������������
+ textStyle() {
+ return (item) => {
+ const date = dayjs(item.date).format("YYYY-MM-DD"),
+ style = {}
+ // ������������������������������������������
+ if (this.selected.some(item => this.dateSame(item, date))) {
+ style.color = '#ffffff'
+ }
+ if (this.mode === 'range') {
+ const len = this.selected.length - 1
+ // ���������������������������������������������������������������������������������������������������������������
+ if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
+ .selected[len]))) {
+ style.color = this.color
+ }
+ }
+ return style
+ }
+ },
+ // ���������������������������
+ getBottomInfo() {
+ return (index1, index2, item) => {
+ const date = dayjs(item.date).format("YYYY-MM-DD")
+ const bottomInfo = item.bottomInfo
+ // ������������������������������������������������������������0���
+ if (this.mode === 'range' && this.selected.length > 0) {
+ if (this.selected.length === 1) {
+ // ������������������������������������������������������������������������������������������������������������������
+ if (this.dateSame(date, this.selected[0])) return this.startText
+ else return bottomInfo
+ } else {
+ const len = this.selected.length - 1
+ // ������������������������������2���������������������������������������������������������������
+ if (this.dateSame(date, this.selected[0]) && this.dateSame(date, this.selected[1]) &&
+ len === 1) {
+ // ���������������2������������������������������������������������������������������item���
+ return `${this.startText}/${this.endText}`
+ } else if (this.dateSame(date, this.selected[0])) {
+ return this.startText
+ } else if (this.dateSame(date, this.selected[len])) {
+ return this.endText
+ } else {
+ return bottomInfo
+ }
+ }
+ } else {
+ return bottomInfo
+ }
+ }
+ }
+ },
+ mounted() {
+ this.init()
+ },
+ methods: {
+ init() {
+ // ���������������������
+ this.$emit('monthSelected', this.selected)
+ this.$nextTick(() => {
+ // ������������������������������������������������������������������������������������������������������������������������������������
+ // ������nvue������$nextTick���������100%���������
+ uni.$u.sleep(10).then(() => {
+ this.getWrapperWidth()
+ this.getMonthRect()
+ })
+ })
+ },
+ // ������������������������������
+ dateSame(date1, date2) {
+ return dayjs(date1).isSame(dayjs(date2))
+ },
+ // ������������������������������������������nvue���������������������������������������css������������������item���������
+ getWrapperWidth() {
+ // #ifdef APP-NVUE
+ dom.getComponentRect(this.$refs['u-calendar-month-wrapper'], res => {
+ this.width = res.size.width
+ })
+ // #endif
+ // #ifndef APP-NVUE
+ this.$uGetRect('.u-calendar-month-wrapper').then(size => {
+ this.width = size.width
+ })
+ // #endif
+ },
+ getMonthRect() {
+ // ������������������������������������������������������scroll-view���������������������������������������������������������
+ const promiseAllArr = this.months.map((item, index) => this.getMonthRectByPromise(
+ `u-calendar-month-${index}`))
+ // ���������������
+ Promise.all(promiseAllArr).then(
+ sizes => {
+ let height = 1
+ const topArr = []
+ for (let i = 0; i < this.months.length; i++) {
+ // ���������months���������������scroll-view���������������������������������������������������
+ topArr[i] = height
+ height += sizes[i].height
+ }
+ // ������������������������������this.months[i].top���������(������������)���������������������month���top������������������������������������������
+ this.$emit('updateMonthTop', topArr)
+ })
+ },
+ // ���������������������������������
+ getMonthRectByPromise(el) {
+ // #ifndef APP-NVUE
+ // $uGetRect���uView���������������������������������������������������������https://www.uviewui.com/js/getRect.html
+ // ���������������������this.$uGetRect���������������uni.$u.getRect������������������������������������
+ return new Promise(resolve => {
+ this.$uGetRect(`.${el}`).then(size => {
+ resolve(size)
+ })
+ })
+ // #endif
+
+ // #ifdef APP-NVUE
+ // nvue������������dom������������������������
+ // ������������promise���������������������������������������then������
+ return new Promise(resolve => {
+ dom.getComponentRect(this.$refs[el][0], res => {
+ resolve(res.size)
+ })
+ })
+ // #endif
+ },
+ // ���������������������
+ clickHandler(index1, index2, item) {
+ if (this.readonly) {
+ return;
+ }
+ this.item = item
+ const date = dayjs(item.date).format("YYYY-MM-DD")
+ if (item.disabled) return
+ // ���������������������������������������������������
+ let selected = uni.$u.deepClone(this.selected)
+ if (this.mode === 'single') {
+ // ���������������������������������������������������������������
+ selected = [date]
+ } else if (this.mode === 'multiple') {
+ if (selected.some(item => this.dateSame(item, date))) {
+ // ���������������������������������������������������������������������������������������������
+ const itemIndex = selected.findIndex(item => item === date)
+ selected.splice(itemIndex, 1)
+ } else {
+ // ������������������������������������������������������������������������������������������������������������
+ if (selected.length < this.maxCount) selected.push(date)
+ }
+ } else {
+ // ������������������
+ if (selected.length === 0 || selected.length >= 2) {
+ // ������������������0������������2���������������������������������������������������������
+ selected = [date]
+ } else if (selected.length === 1) {
+ // ���������������������������������
+ const existsDate = selected[0]
+ // ������������������������������������������������������������������������������������������������
+ if (dayjs(date).isBefore(existsDate)) {
+ selected = [date]
+ } else if (dayjs(date).isAfter(existsDate)) {
+ // ������������������������������������������������������������������������������������������
+ if(dayjs(dayjs(date).subtract(this.maxRange, 'day')).isAfter(dayjs(selected[0])) && this.showRangePrompt) {
+ if(this.rangePrompt) {
+ uni.$u.toast(this.rangePrompt)
+ } else {
+ uni.$u.toast(`������������������������ ${this.maxRange} ���`)
+ }
+ return
+ }
+ // ������������������������������������������������������������������������
+ selected.push(date)
+ const startDate = selected[0]
+ const endDate = selected[1]
+ const arr = []
+ let i = 0
+ do {
+ // ���������������������������������������������������������
+ arr.push(dayjs(startDate).add(i, 'day').format("YYYY-MM-DD"))
+ i++
+ // ���������������������������������������������������������������
+ } while (dayjs(startDate).add(i, 'day').isBefore(dayjs(endDate)))
+ // ������������������������������������computed������������������������������arr������������������������������������������������������������������������
+ arr.push(endDate)
+ selected = arr
+ } else {
+ // ���������������������������������������������������������������������������������������������������������������������
+ if (selected[0] === date && !this.allowSameDay) return
+ selected.push(date)
+ }
+ }
+ }
+ this.setSelected(selected)
+ },
+ // ������������������
+ setDefaultDate() {
+ if (!this.defaultDate) {
+ // ���������������������������������������������������������������������������������
+ const selected = [dayjs().format("YYYY-MM-DD")]
+ return this.setSelected(selected, false)
+ }
+ let defaultDate = []
+ const minDate = this.minDate || dayjs().format("YYYY-MM-DD")
+ const maxDate = this.maxDate || dayjs(minDate).add(this.maxMonth - 1, 'month').format("YYYY-MM-DD")
+ if (this.mode === 'single') {
+ // ���������������������������������������������Date���������
+ if (!uni.$u.test.array(this.defaultDate)) {
+ defaultDate = [dayjs(this.defaultDate).format("YYYY-MM-DD")]
+ } else {
+ defaultDate = [this.defaultDate[0]]
+ }
+ } else {
+ // ���������������������������������
+ if (!uni.$u.test.array(this.defaultDate)) return
+ defaultDate = this.defaultDate
+ }
+ // ���������������������������������������������������������������������������������������������
+ defaultDate = defaultDate.filter(item => {
+ return dayjs(item).isAfter(dayjs(minDate).subtract(1, 'day')) && dayjs(item).isBefore(dayjs(
+ maxDate).add(1, 'day'))
+ })
+ this.setSelected(defaultDate, false)
+ },
+ setSelected(selected, event = true) {
+ this.selected = selected
+ event && this.$emit('monthSelected', this.selected)
+ }
+ }
+ }
+</script>
+
+<style lang="scss" scoped>
+ @import "../../libs/css/components.scss";
+
+ .u-calendar-month-wrapper {
+ margin-top: 4px;
+ }
+
+ .u-calendar-month {
+
+ &__title {
+ font-size: 14px;
+ line-height: 42px;
+ height: 42px;
+ color: $u-main-color;
+ text-align: center;
+ font-weight: bold;
+ }
+
+ &__days {
+ position: relative;
+ @include flex;
+ flex-wrap: wrap;
+
+ &__month-mark-wrapper {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ @include flex;
+ justify-content: center;
+ align-items: center;
+
+ &__text {
+ font-size: 155px;
+ color: rgba(231, 232, 234, 0.83);
+ }
+ }
+
+ &__day {
+ @include flex;
+ padding: 2px;
+ /* #ifndef APP-NVUE */
+ // vue���������css���������������������������������������������������������js������������������������������������������������������
+ width: calc(100% / 7);
+ box-sizing: border-box;
+ /* #endif */
+
+ &__select {
+ flex: 1;
+ @include flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+
+ &__dot {
+ width: 7px;
+ height: 7px;
+ border-radius: 100px;
+ background-color: $u-error;
+ position: absolute;
+ top: 12px;
+ right: 7px;
+ }
+
+ &__buttom-info {
+ color: $u-content-color;
+ text-align: center;
+ position: absolute;
+ bottom: 5px;
+ font-size: 10px;
+ text-align: center;
+ left: 0;
+ right: 0;
+
+ &--selected {
+ color: #ffffff;
+ }
+
+ &--disabled {
+ color: #cacbcd;
+ }
+ }
+
+ &__info {
+ text-align: center;
+ font-size: 16px;
+
+ &--selected {
+ color: #ffffff;
+ }
+
+ &--disabled {
+ color: #cacbcd;
+ }
+ }
+
+ &--selected {
+ background-color: $u-primary;
+ @include flex;
+ justify-content: center;
+ align-items: center;
+ flex: 1;
+ border-radius: 3px;
+ }
+
+ &--range-selected {
+ opacity: 0.3;
+ border-radius: 0;
+ }
+
+ &--range-start-selected {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+
+ &--range-end-selected {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+ }
+ }
+ }
+ }
+</style>
--
Gitblit v1.8.0