From d8b41fff43a2cee6a8f714ffa807623b15803786 Mon Sep 17 00:00:00 2001
From: quanyawei <401863037@qq.com>
Date: Fri, 20 Oct 2023 15:21:35 +0800
Subject: [PATCH] fix:立行立改Uniapp小程序新建项目

---
 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