uniapp实现多时间段设置

功能说明:

1 点击新增时间,出现一个默认时间段模板,不能提交

2 点击“新增时间文本”,弹出弹窗,选择时间,不允许开始时间和结束时间同时为00:00,

<view class="item_cont">                        
                                <view class="start_item" >
                                    <view class="start_item_title">{{i18nCast('vqSettingStartTime')}}</view>
                                        <picker mode="multiSelector" :value="item.start" 
                                                :start="hours" :end="minutes" :range="rangeOpts" 
                                                @change="handlerTime($event,'start',item)"
                                        >
                                            <view class="uni-input">
                                         
                                                <view class="select_time_txt" v-if="isTimeEmpty(item.start)">{{i18nCast("vqSettingSelectedTimeSlot")}} <text class="icon_right">></text></view>
                                                <view v-else>{{transTimeToStr(item.start)}}</view>
                                            </view>
                                        </picker>
                                </view>
                                <view class="end_item" >
                                    <view class="end_item_title">{{i18nCast('vqSettingEndTime')}}</view>
                                        <picker mode="multiSelector" :value="item.end" 
                                                :start="hours" :end="minutes" :range="rangeOpts" 
                                                @change="handlerTime($event,'end',item)"
                                        >
                                            <view class="uni-input">
                                                <view class="select_time_txt" v-if="isTimeEmpty(item.end)">{{i18nCast("vqSettingSelectedTimeSlot")}} <text class="icon_right">></text></view>
                                                <view v-else>{{transTimeToStr(item.end)}}</view>
                                            </view>
                                        </picker>
                                </view>
                            </view>
                            <view class="del_item" @click="triggerDelItem(item,index)">{{i18nCast('vqSettingdelete')}}</view>

  data(){
        return {
            curTimeItem:{
                start:"",
                end:"",
            },
            rangeOpts:[
                [...hours],
                [...minutes]
            ],
            hours: Array.from({ length: 24 }, (_, i) => i),
            minutes: Array.from({ length: 60 }, (_, i) => i),
        }
    }

   methods:{
        i18nCast,
        ...mapMutations({
			setStoreId:'global/setStoreId',
		}),
        cancelStart(){
            console.log("confirm----")
        },
     
        setPageTitle(){
            this.redirectFromPage=="vq"?setNavigationBarTitleFn(i18nCast("vqSettingNamequeueTime")):setNavigationBarTitleFn(i18nCast('vqSettingOperationTime'))
        },
        init(){
            getSetting({storeId: this.storeId}).then(res=>{
                let {openingPeriods,inventoryPeriods,storeToggle,inventoryPeriodsStore}=res.data;
                this.storeToggle=storeToggle
                //有桌型
                if(storeToggle){
                    this.list=(this.redirectFromPage==="vq"?inventoryPeriods:openingPeriods)||[]
                }else{
                    //无桌型
                    this.list=(this.redirectFromPage==="vq"?inventoryPeriodsStore:openingPeriods)||[]
                }
                console.log("this.list",this.list)
                this.addListKey(this.list)
            }).finally(()=>{
                uni.hideLoading()
                uni.stopPullDownRefresh()
            })
        },
        addListKey(arr){
            if(arr&&arr.length>=0){
                arr.forEach(item=>{
                    this.$set(item,'moveX',0)
                    this.$set(item,'isShowError',false)
                    this.$set(item,'timebName','Time Slot')
                    this.spiltTimeToArr(item)
                })
            }
        },
        isTimeEmpty(str){
            return str.every(item=>item === "")?true:false
        },
        setTimeListFn(timelist){
         
            let params=this.getParams(timelist)
            console.log("params:",params)
            if(this.hasTimeIsZero()){
                uni.showToast({title: i18nCast("vqSettingEmptyTimeErr"),icon:"none"})
            }else{
                this.hasTimeSegmentsOverlap()
                if(this.hasTimeCross||this.hasItemErr()){
                    return
                }else{
                    //正常提交
                    console.log("params:",params)
                    this.submitCore(timelist)
                }
            }
        },
        getParams(timelist){
           
            let arr=timelist.map(({start,end})=>({start:this.transTimeToStr(start),end:this.transTimeToStr(end)})) 
            console.log("getParams--",arr)
            let params={storeId:this.storeId}
            if(this.redirectFromPage==="vq" && arr.length==0){
                params={...params,inventoryType:"single"}
            }
            if(this.storeToggle){
                this.redirectFromPage==="vq"?params={...params,inventoryPeriods:arr}:params={...params,openingPeriods:arr}
            }else{
                this.redirectFromPage==="vq"?params={...params,inventoryPeriodsStore:arr}:params={...params,openingPeriods:arr}
            }
            return params
        },
        submitCore(list){
             let params=this.getParams(list)
             setSetting(params).then(res=>{
                        let iconType=""
                        res.errcode===0?iconType="success":iconType="error"
                        uni.showToast({title: i18nCast('vqSettingSaveSuccess'),icon:iconType})
                        this.init()
                    }).catch(err=>{
                        uni.showToast({title:err.data.errmsg,icon:"none"})
                    })
        },
        save(){                 
            this.setTimeListFn(this.list)
        },
        transformDate(num) {   
            return num = num >= 10 ? num : `0${num}`;
        },
        // 时间段错误统计
        hasItemErr(){
            const errs=this.list.filter(item=>item.isShowError)
           return errs.length>0?true:false
        },
        handlerTime(e,type,item){
          	type==="start"?item.start=e.detail.value:item.end=e.detail.value;
            this.hasTimeSegmentsOverlap()
            this.timeError(item)
        },
        transTimeToStr(timeArr){
            let res=``
            if(timeArr.every(item=>item=="")){
                res=`00:00`
            }else{
                res=`${this.transformDate(timeArr[0])}:${this.transformDate(timeArr[1])}`
            }
            return res
		},
        spiltTimeToArr(item){
                if(item.start&&item.end){
                    let startArr=item.start.split(':')
                    let endArr=item.end.split(':')
                    item.start=[Number(startArr[0]),Number(startArr[1])]
                    item.end=[Number(endArr[0]),Number(endArr[1])]
                }
		},
        timeError(item){
            let startH=item.start[0]
            let startM=item.start[1]
            let endH=item.end[0]
            let endM=item.end[1]

            console.log("startH-===",startH)
            console.log("endH-===",endH)
            //先比较时,
            if(Number(endH)<Number(startH)){
                item.isShowError=true
            }else if(Number(endH)===Number(startH)){
                // 再比较分
                item.isShowError=startM>=endM?true:false
            }else{
                item.isShowError=false
            }
        },
        addTime(item){
            console.log("addtime",item)
            console.log("this.list---prev",this.list)
            let upperTimeNum=this.redirectFromPage==="business"?3:5
            this.list=this.list||[]
            if(this.list.length>=upperTimeNum){
                    uni.showToast({
                    icon: "none",
                    title: i18nCast("vqSettingUpperLimit")
                })
                return
            }else{
                    this.list.push({
                        id:Math.random()*10+100,
                        timebName:i18nCast('vqSettingTimeSections'),
                        start:["",""],
                        end:["",""],
                    })
            }
            console.log("this.list---next",this.list)
        },
        drawStart(e){
            e.preventDefault()
            this.startX=e.touches[0].clientX;
            console.log("this.startx",this.startX)
        },
        drawMove(e,item){
              e.preventDefault()
            item.moveX=e.touches[0].clientX-this.startX;
            if(item.moveX>=0){
                item.moveX=0
            }else{
                if(item.moveX<=-this.delBtnWidth/2){
                    item.moveX=-this.delBtnWidth
                }
            }
        },
        drawEnd(e,item){
              e.preventDefault()
            if(item.moveX<0){
                if(Math.abs(item.moveX)<this.delBtnWidth/2){
                    item.moveX=0
                }else{
                    item.moveX=-this.delBtnWidth
                }
            }
        },
        triggerDelItem(item,index){
            console.log("item:",item)
            this.visible=true;
            this.curTimeItem=item
        },
        //删除
        confirmDel(){
            let list=this.list.filter(item=>item.start!==this.curTimeItem.start)
            console.log("lsit",this.list)
            this.visible=false
            // this.setTimeListFn(list)
            this.submitCore(list)
        },
        hasTimeIsZero(){
            let res=false
            const timeSlots = this.list.map(({start,end})=>({start:this.transTimeToStr(start),end:this.transTimeToStr(end)}));
            if(timeSlots.some(item=>item.start=="00:00"&&item.end=="00:00")){
                res=true
            }
            return res
        },
        convertToMinutes(timeString) {
            const [hours, minutes] = timeString.split(":");
            return parseInt(hours) * 60 + parseInt(minutes);
        },
        hasTimeSegmentsOverlap() {
            let res=false
            const timeArray = this.list.map(({start,end})=>({start:this.transTimeToStr(start),end:this.transTimeToStr(end)}));
            for (let i = 0; i < timeArray.length; i++) {
                const current = timeArray[i];
                for (let j = i + 1; j < timeArray.length; j++) {
                        const compare = timeArray[j];

                        // 将时间字符串转换为分钟数
                        const currentStart = this.convertToMinutes(current.start);
                        const currentEnd = this.convertToMinutes(current.end);
                        const compareStart = this.convertToMinutes(compare.start);
                        const compareEnd = this.convertToMinutes(compare.end);
                        // 检查时间段是否重叠
                        if (
                            (currentStart <= compareStart && compareStart <= currentEnd) ||
                            (currentStart <= compareEnd && compareEnd <= currentEnd) ||
                            (compareStart <= currentStart && currentStart <= compareEnd) ||
                            (compareStart <= currentEnd && currentEnd <= compareEnd)
                        ) {
                            res= true; // 存在交叉时间段
                        }
                }
            }
            // 不存在交叉时间段
            console.log("是否有交叉",res)
            this.hasTimeCross=res
            return res
        }
    }

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你可以使用uni-app的DatePicker组件来实现时间段选择器。首先,在你的页面中引入DatePicker组件: ```html <template> <view> <date-picker @change="handleChange" mode="range"></date-picker> </view> </template> ``` 然后,在对应的script标签中添加对DatePicker组件的引入和相关处理函数: ```javascript import datePicker from "@/components/datePicker.vue"; export default { components: { datePicker }, methods: { handleChange(e) { console.log(e.detail.value); // 处理选择的时间段逻辑 } } } ``` 接下来,创建一个名为datePicker.vue的组件,用于展示时间选择器: ```html template> <view> <picker mode="date" @change="handleStartDateChange" :value="startDate"></picker> <picker mode="date" @change="handleEndDateChange" :value="endDate"></picker> </view> </template> <script> export default { data() { return { startDate: '', endDate: '' } }, methods: { handleStartDateChange(e) { this.startDate = e.detail.value; this.$emit('change', { value: [this.startDate, this.endDate] }); }, handleEndDateChange(e) { this.endDate = e.detail.value; this.$emit('change', { value: [this.startDate, this.endDate] }); } } } </script> ``` 上述代码中,我们使用了两个picker组件分别用于选择起始日期和结束日期,并通过`handleStartDateChange`和`handleEndDateChange`方法来更新选中的起始日期和结束日期。同时,通过`this.$emit('change', ...)`将选择的时间段传递给父组件。 现在你就可以在你的页面中使用这个时间段选择器组件了。当用户选择时间段时,`handleChange`方法会被调用,并且你可以在该方法中处理选择的时间段的逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值