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