From d1448cb0ef10f358bb7bddb4e1ec268515e0b787 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 15 七月 2025 11:46:57 +0800
Subject: [PATCH] 项目初始化

---
 uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue |  360 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 360 insertions(+), 0 deletions(-)

diff --git a/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue b/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue
new file mode 100644
index 0000000..18d8dcc
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue
@@ -0,0 +1,360 @@
+<template>
+	<u-picker
+		ref="picker"
+		:show="show"
+		:closeOnClickOverlay="closeOnClickOverlay"
+		:columns="columns"
+		:title="title"
+		:itemHeight="itemHeight"
+		:showToolbar="showToolbar"
+		:visibleItemCount="visibleItemCount"
+		:defaultIndex="innerDefaultIndex"
+		:cancelText="cancelText"
+		:confirmText="confirmText"
+		:cancelColor="cancelColor"
+		:confirmColor="confirmColor"
+		@close="close"
+		@cancel="cancel"
+		@confirm="confirm"
+		@change="change"
+	>
+	</u-picker>
+</template>
+
+<script>
+	function times(n, iteratee) {
+	    let index = -1
+	    const result = Array(n < 0 ? 0 : n)
+	    while (++index < n) {
+	        result[index] = iteratee(index)
+	    }
+	    return result
+	}
+	import props from './props.js';
+	import dayjs from '../../libs/util/dayjs.js';
+	/**
+	 * DatetimePicker 鏃堕棿鏃ユ湡閫夋嫨鍣�
+	 * @description 姝ら�夋嫨鍣ㄧ敤浜庢椂闂存棩鏈�
+	 * @tutorial https://www.uviewui.com/components/datetimePicker.html
+	 * @property {Boolean}			show				鐢ㄤ簬鎺у埗閫夋嫨鍣ㄧ殑寮瑰嚭涓庢敹璧� ( 榛樿 false )
+	 * @property {Boolean}			showToolbar			鏄惁鏄剧ず椤堕儴鐨勬搷浣滄爮  ( 榛樿 true )
+	 * @property {String | Number}	value				缁戝畾鍊�
+	 * @property {String}			title				椤堕儴鏍囬
+	 * @property {String}			mode				灞曠ず鏍煎紡 mode=date涓烘棩鏈熼�夋嫨锛宮ode=time涓烘椂闂撮�夋嫨锛宮ode=year-month涓哄勾鏈堥�夋嫨锛宮ode=datetime涓烘棩鏈熸椂闂撮�夋嫨  ( 榛樿 鈥榙atetime )
+	 * @property {Number}			maxDate				鍙�夌殑鏈�澶ф椂闂�  榛樿鍊间负鍚�10骞�
+	 * @property {Number}			minDate				鍙�夌殑鏈�灏忔椂闂�  榛樿鍊间负鍓�10骞�
+	 * @property {Number}			minHour				鍙�夌殑鏈�灏忓皬鏃讹紝浠卪ode=time鏈夋晥   ( 榛樿 0 )
+	 * @property {Number}			maxHour				鍙�夌殑鏈�澶у皬鏃讹紝浠卪ode=time鏈夋晥	  ( 榛樿 23 )
+	 * @property {Number}			minMinute			鍙�夌殑鏈�灏忓垎閽燂紝浠卪ode=time鏈夋晥	  ( 榛樿 0 )
+	 * @property {Number}			maxMinute			鍙�夌殑鏈�澶у垎閽燂紝浠卪ode=time鏈夋晥   ( 榛樿 59 )
+	 * @property {Function}			filter				閫夐」杩囨护鍑芥暟
+	 * @property {Function}			formatter			閫夐」鏍煎紡鍖栧嚱鏁�
+	 * @property {Boolean}			loading				鏄惁鏄剧ず鍔犺浇涓姸鎬�   ( 榛樿 false )
+	 * @property {String | Number}	itemHeight			鍚勫垪涓紝鍗曚釜閫夐」鐨勯珮搴�   ( 榛樿 44 )
+	 * @property {String}			cancelText			鍙栨秷鎸夐挳鐨勬枃瀛�  ( 榛樿 '鍙栨秷' )
+	 * @property {String}			confirmText			纭鎸夐挳鐨勬枃瀛�  ( 榛樿 '纭' )
+	 * @property {String}			cancelColor			鍙栨秷鎸夐挳鐨勯鑹�  ( 榛樿 '#909193' )
+	 * @property {String}			confirmColor		纭鎸夐挳鐨勯鑹�  ( 榛樿 '#3c9cff' )
+	 * @property {String | Number}	visibleItemCount	姣忓垪涓彲瑙侀�夐」鐨勬暟閲�  ( 榛樿 5 )
+	 * @property {Boolean}			closeOnClickOverlay	鏄惁鍏佽鐐瑰嚮閬僵鍏抽棴閫夋嫨鍣�  ( 榛樿 false )
+	 * @property {Array}			defaultIndex		鍚勫垪鐨勯粯璁ょ储寮�
+	 * @event {Function} close 鍏抽棴閫夋嫨鍣ㄦ椂瑙﹀彂
+	 * @event {Function} confirm 鐐瑰嚮纭畾鎸夐挳锛岃繑鍥炲綋鍓嶉�夋嫨鐨勫��
+	 * @event {Function} change 褰撻�夋嫨鍊煎彉鍖栨椂瑙﹀彂
+	 * @event {Function} cancel 鐐瑰嚮鍙栨秷鎸夐挳
+	 * @example  <u-datetime-picker :show="show" :value="value1"  mode="datetime" ></u-datetime-picker>
+	 */
+	export default {
+		name: 'datetime-picker',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+		data() {
+			return {
+				columns: [],
+				innerDefaultIndex: [],
+				innerFormatter: (type, value) => value
+			}
+		},
+		watch: {
+			show(newValue, oldValue) {
+				if (newValue) {
+					this.updateColumnValue(this.innerValue)
+				}
+			},
+			propsChange() {
+				this.init()
+			}
+		},
+		computed: {
+			// 濡傛灉浠ヤ笅杩欎簺鍙橀噺鍙戠敓浜嗗彉鍖栵紝鎰忓懗鐫�闇�瑕侀噸鏂板垵濮嬪寲鍚勫垪鐨勫��
+			propsChange() {
+				return [this.mode, this.maxDate, this.minDate, this.minHour, this.maxHour, this.minMinute, this.maxMinute, this.filter, ]
+			}
+		},
+		mounted() {
+			this.init()
+		},
+		methods: {
+			init() {
+				this.innerValue = this.correctValue(this.value)
+				this.updateColumnValue(this.innerValue)
+			},
+			// 鍦ㄥ井淇″皬绋嬪簭涓紝涓嶆敮鎸佸皢鍑芥暟褰撳仛props鍙傛暟锛屾晠鍙兘閫氳繃ref褰㈠紡璋冪敤
+			setFormatter(e) {
+				this.innerFormatter = e
+			},
+			// 鍏抽棴閫夋嫨鍣�
+			close() {
+				if (this.closeOnClickOverlay) {
+					this.$emit('close')
+				}
+			},
+			// 鐐瑰嚮宸ュ叿鏍忕殑鍙栨秷鎸夐挳
+			cancel() {
+				this.$emit('cancel')
+			},
+			// 鐐瑰嚮宸ュ叿鏍忕殑纭畾鎸夐挳
+			confirm() {
+				this.$emit('confirm', {
+					value: this.innerValue,
+					mode: this.mode
+				})
+				this.$emit('input', this.innerValue)
+			},
+			//鐢ㄦ鍒欐埅鍙栬緭鍑哄��,褰撳嚭鐜板缁勬暟瀛楁椂,鎶涘嚭閿欒
+			intercept(e,type){
+				let judge = e.match(/\d+/g)
+				//鍒ゆ柇鏄惁鎺烘潅鏁板瓧
+				if(judge.length>1){
+					uni.$u.error("璇峰嬁鍦ㄨ繃婊ゆ垨鏍煎紡鍖栧嚱鏁版椂娣诲姞鏁板瓧")
+					return 0
+				}else if(type&&judge[0].length==4){//鍒ゆ柇鏄惁鏄勾浠�
+					return judge[0]
+				}else if(judge[0].length>2){
+					uni.$u.error("璇峰嬁鍦ㄨ繃婊ゆ垨鏍煎紡鍖栧嚱鏁版椂娣诲姞鏁板瓧")
+					return 0
+				}else{
+					return judge[0]
+				}
+			},
+			// 鍒楀彂鐢熷彉鍖栨椂瑙﹀彂
+			change(e) {
+				const { indexs, values } = e
+				let selectValue = ''
+				if(this.mode === 'time') {
+					// 鏍规嵁value鍚勫垪绱㈠紩锛屼粠鍚勫垪鏁扮粍涓紝鍙栧嚭褰撳墠鏃堕棿鐨勯�変腑鍊�
+					selectValue = `${this.intercept(values[0][indexs[0]])}:${this.intercept(values[1][indexs[1]])}`
+				} else {
+					// 灏嗛�夋嫨鐨勫�艰浆涓烘暟鍊硷紝姣斿'03'杞负鏁板�肩殑3锛�'2019'杞负鏁板�肩殑2019
+					const year = parseInt(this.intercept(values[0][indexs[0]],'year'))
+					const month = parseInt(this.intercept(values[1][indexs[1]]))
+					let date = parseInt(values[2] ? this.intercept(values[2][indexs[2]]) : 1)
+					let hour = 0, minute = 0
+					// 姝ゆ湀浠界殑鏈�澶уぉ鏁�
+					const maxDate = dayjs(`${year}-${month}`).daysInMonth()
+					// year-month妯″紡涓嬶紝date涓嶄細鍑虹幇鍦ㄥ垪涓紝璁剧疆涓�1锛屼负浜嗙鍚堝悗杈归渶瑕佸噺1鐨勯渶姹�
+					if (this.mode === 'year-month') {
+					    date = 1
+					}
+					// 涓嶅厑璁歌秴杩噈axDate鍊�
+					date = Math.min(maxDate, date)
+					if (this.mode === 'datetime') {
+					    hour = parseInt(this.intercept(values[3][indexs[3]]))
+					    minute = parseInt(this.intercept(values[4][indexs[4]]))
+					}
+					// 杞负鏃堕棿妯″紡
+					selectValue = Number(new Date(year, month - 1, date, hour, minute))
+				}
+				// 鍙栧嚭鍑嗙‘鐨勫悎娉曞�硷紝闃叉瓒呰秺杈圭晫鐨勬儏鍐�
+				selectValue = this.correctValue(selectValue)
+				this.innerValue = selectValue
+				this.updateColumnValue(selectValue)
+				// 鍙戝嚭change鏃堕棿锛寁alue涓哄綋鍓嶉�変腑鐨勬椂闂存埑
+				this.$emit('change', {
+					value: selectValue,
+					// #ifndef MP-WEIXIN
+					// 寰俊灏忕▼搴忎笉鑳戒紶閫抰his瀹炰緥锛屼細鍥犱负寰幆寮曠敤鑰屾姤閿�
+					picker: this.$refs.picker,
+					// #endif
+					mode: this.mode
+				})
+			},
+			// 鏇存柊鍚勫垪鐨勫�硷紝杩涜琛�0銆佹牸寮忓寲绛夋搷浣�
+			updateColumnValue(value) {
+				this.innerValue = value
+				this.updateColumns()
+				this.updateIndexs(value)
+			},
+			// 鏇存柊绱㈠紩
+			updateIndexs(value) {
+				let values = []
+				const formatter = this.formatter || this.innerFormatter
+				const padZero = uni.$u.padZero
+				if (this.mode === 'time') {
+					// 灏唗ime妯″紡鐨勬椂闂寸敤:鍒嗛殧鎴愭暟缁�
+				    const timeArr = value.split(':')
+					// 浣跨敤formatter鏍煎紡鍖栨柟娉曡繘琛岀閬撳鐞�
+				    values = [formatter('hour', timeArr[0]), formatter('minute', timeArr[1])]
+				} else {
+				    const date = new Date(value)
+				    values = [
+				        formatter('year', `${dayjs(value).year()}`),
+						// 鏈堜唤琛�0
+				        formatter('month', padZero(dayjs(value).month() + 1))
+				    ]
+				    if (this.mode === 'date') {
+						// date妯″紡锛岄渶瑕佹坊鍔犲ぉ鍒�
+				        values.push(formatter('day', padZero(dayjs(value).date())))
+				    }
+				    if (this.mode === 'datetime') {
+						// 鏁扮粍鐨刾ush鏂规硶锛屽彲浠ュ啓鍏ュ涓弬鏁�
+				        values.push(formatter('day', padZero(dayjs(value).date())), formatter('hour', padZero(dayjs(value).hour())), formatter('minute', padZero(dayjs(value).minute())))
+				    }
+				}
+
+				// 鏍规嵁褰撳墠鍚勫垪鐨勬墍鏈夊�硷紝浠庡悇鍒楅粯璁ゅ�间腑鎵惧埌榛樿鍊煎湪鍚勫垪涓殑绱㈠紩
+				const indexs = this.columns.map((column, index) => {
+					// 閫氳繃鍙栧ぇ鍊硷紝鍙互淇濊瘉涓嶄細鍑虹幇鎵句笉鍒扮储寮曠殑-1鎯呭喌
+					return Math.max(0, column.findIndex(item => item === values[index]))
+				})
+				this.innerDefaultIndex = indexs
+			},
+			// 鏇存柊鍚勫垪鐨勫��
+			updateColumns() {
+			    const formatter = this.formatter || this.innerFormatter
+				// 鑾峰彇鍚勫垪鐨勫�硷紝骞朵笖map鍚庯紝瀵瑰悇鍒楃殑鍏蜂綋鍊艰繘琛岃ˉ0鎿嶄綔
+			    const results = this.getOriginColumns().map((column) => column.values.map((value) => formatter(column.type, value)))
+				this.columns = results
+			},
+			getOriginColumns() {
+			    // 鐢熸垚鍚勫垪鐨勫��
+			    const results = this.getRanges().map(({ type, range }) => {
+			        let values = times(range[1] - range[0] + 1, (index) => {
+			            let value = range[0] + index
+			            value = type === 'year' ? `${value}` : uni.$u.padZero(value)
+			            return value
+			        })
+					// 杩涜杩囨护
+			        if (this.filter) {
+			            values = this.filter(type, values)
+			        }
+			        return { type, values }
+			    })
+			    return results
+			},
+			// 閫氳繃鏈�澶у�煎拰鏈�灏忓�肩敓鎴愭暟缁�
+			generateArray(start, end) {
+				return Array.from(new Array(end + 1).keys()).slice(start)
+			},
+			// 寰楀嚭鍚堟硶鐨勬椂闂�
+			correctValue(value) {
+				const isDateMode = this.mode !== 'time'
+				if (isDateMode && !uni.$u.test.date(value)) {
+					// 濡傛灉鏄棩鏈熺被鍨嬶紝浣嗘槸鍙堟病鏈夎缃悎娉曠殑褰撳墠鏃堕棿鐨勮瘽锛屼娇鐢ㄦ渶灏忔椂闂翠负褰撳墠鏃堕棿
+					value = this.minDate
+				} else if (!isDateMode && !value) {
+					// 濡傛灉鏄椂闂寸被鍨嬶紝鑰屽張娌℃湁榛樿鍊肩殑璇濓紝灏辩敤鏈�灏忔椂闂�
+					value = `${uni.$u.padZero(this.minHour)}:${uni.$u.padZero(this.minMinute)}`
+				}
+				// 鏃堕棿绫诲瀷
+				if (!isDateMode) {
+					if (String(value).indexOf(':') === -1) return uni.$u.error('鏃堕棿閿欒锛岃浼犻�掑12:24鐨勬牸寮�')
+					let [hour, minute] = value.split(':')
+					// 瀵规椂闂磋ˉ闆讹紝鍚屾椂鎺у埗鍦ㄦ渶灏忓�煎拰鏈�澶у�间箣闂�
+					hour = uni.$u.padZero(uni.$u.range(this.minHour, this.maxHour, Number(hour)))
+					minute = uni.$u.padZero(uni.$u.range(this.minMinute, this.maxMinute, Number(minute)))
+					return `${ hour }:${ minute }`
+				} else {
+					// 濡傛灉鏄棩鏈熸牸寮忥紝鎺у埗鍦ㄦ渶灏忔棩鏈熷拰鏈�澶ф棩鏈熶箣闂�
+					value = dayjs(value).isBefore(dayjs(this.minDate)) ? this.minDate : value
+					value = dayjs(value).isAfter(dayjs(this.maxDate)) ? this.maxDate : value
+					return value
+				}
+			},
+			// 鑾峰彇姣忓垪鐨勬渶澶у拰鏈�灏忓��
+			getRanges() {
+			    if (this.mode === 'time') {
+			        return [
+			            {
+			                type: 'hour',
+			                range: [this.minHour, this.maxHour],
+			            },
+			            {
+			                type: 'minute',
+			                range: [this.minMinute, this.maxMinute],
+			            },
+			        ];
+			    }
+			    const { maxYear, maxDate, maxMonth, maxHour, maxMinute, } = this.getBoundary('max', this.innerValue);
+			    const { minYear, minDate, minMonth, minHour, minMinute, } = this.getBoundary('min', this.innerValue);
+			    const result = [
+			        {
+			            type: 'year',
+			            range: [minYear, maxYear],
+			        },
+			        {
+			            type: 'month',
+			            range: [minMonth, maxMonth],
+			        },
+			        {
+			            type: 'day',
+			            range: [minDate, maxDate],
+			        },
+			        {
+			            type: 'hour',
+			            range: [minHour, maxHour],
+			        },
+			        {
+			            type: 'minute',
+			            range: [minMinute, maxMinute],
+			        },
+			    ];
+			    if (this.mode === 'date')
+			        result.splice(3, 2);
+			    if (this.mode === 'year-month')
+			        result.splice(2, 3);
+			    return result;
+			},
+			// 鏍规嵁minDate銆乵axDate銆乵inHour銆乵axHour绛夎竟鐣屽�硷紝鍒ゆ柇鍚勫垪鐨勫紑濮嬪拰缁撴潫杈圭晫鍊�
+			getBoundary(type, innerValue) {
+			    const value = new Date(innerValue)
+			    const boundary = new Date(this[`${type}Date`])
+			    const year = dayjs(boundary).year()
+			    let month = 1
+			    let date = 1
+			    let hour = 0
+			    let minute = 0
+			    if (type === 'max') {
+			        month = 12
+					// 鏈堜唤鐨勫ぉ鏁�
+			        date = dayjs(value).daysInMonth()
+			        hour = 23
+			        minute = 59
+			    }
+				// 鑾峰彇杈圭晫鍊硷紝閫昏緫鏄細褰撳勾杈惧埌浜嗚竟鐣屽��(鏈�澶ф垨鏈�灏忓勾)锛屽氨妫�鏌ユ湀鍏佽鐨勬渶澶у拰鏈�灏忓�硷紝浠ユ绫绘帹
+			    if (dayjs(value).year() === year) {
+			        month = dayjs(boundary).month() + 1
+			        if (dayjs(value).month() + 1 === month) {
+			            date = dayjs(boundary).date()
+			            if (dayjs(value).date() === date) {
+			                hour = dayjs(boundary).hour()
+			                if (dayjs(value).hour() === hour) {
+			                    minute = dayjs(boundary).minute()
+			                }
+			            }
+			        }
+			    }
+			    return {
+			        [`${type}Year`]: year,
+			        [`${type}Month`]: month,
+			        [`${type}Date`]: date,
+			        [`${type}Hour`]: hour,
+			        [`${type}Minute`]: minute
+			    }
+			},
+		},
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import '../../libs/css/components.scss';
+</style>

--
Gitblit v1.9.3